From 4abfa7ddb10d5eabd539ae4dc775d349fab1c538 Mon Sep 17 00:00:00 2001 From: kate-deriv <121025168+kate-deriv@users.noreply.github.com> Date: Fri, 24 May 2024 16:23:34 +0300 Subject: [PATCH] DTRA-1279/ Kate/ Feat: add Date picker (#62) * feat: add second action sheet * feat: add date range formatting and refactored existing code * feat: add range selection filtration * refactor: chip and time filter * fix: empty posituions after filtration * refactor: do clean up * chore: rename variables --- .../src/AppV2/Components/Chip/chip.scss | 45 ++------------ .../trader/src/AppV2/Components/Chip/chip.tsx | 26 ++------ .../Components/DatePicker/date-picker.scss | 15 +++++ .../Components/DatePicker/date-picker.tsx | 53 ++++++++++++++++ .../src/AppV2/Components/DatePicker/index.ts | 4 ++ .../EmptyPositions/empty-positions.scss | 4 ++ .../EmptyPositions/empty-positions.tsx | 2 +- .../Filter/contract-type-filter.tsx | 4 +- .../Filter/custom-time-filter-button.tsx | 25 ++++++++ .../src/AppV2/Components/Filter/filter.scss | 33 ++++++++++ .../AppV2/Components/Filter/time-filter.tsx | 62 ++++++++++++++----- .../Positions/positions-content.tsx | 16 ++++- .../AppV2/Containers/Positions/positions.scss | 12 +--- 13 files changed, 209 insertions(+), 92 deletions(-) create mode 100644 packages/trader/src/AppV2/Components/DatePicker/date-picker.scss create mode 100644 packages/trader/src/AppV2/Components/DatePicker/date-picker.tsx create mode 100644 packages/trader/src/AppV2/Components/DatePicker/index.ts create mode 100644 packages/trader/src/AppV2/Components/Filter/custom-time-filter-button.tsx diff --git a/packages/trader/src/AppV2/Components/Chip/chip.scss b/packages/trader/src/AppV2/Components/Chip/chip.scss index c093730835eb..74be670a031a 100644 --- a/packages/trader/src/AppV2/Components/Chip/chip.scss +++ b/packages/trader/src/AppV2/Components/Chip/chip.scss @@ -7,6 +7,9 @@ border-color: var(--component-chip-border-color); border-radius: var(--component-chip-border-radius); background-color: var(--core-color-solid-slate-50); + padding-inline: var(--component-chip-spacing-padding-lg); + height: var(--component-chip-height-md); + gap: var(--component-chip-spacing-padding-sm); &:hover { background-color: var(--component-chip-bg-hover); @@ -67,48 +70,8 @@ } } - &__disabled { - &--true { - & > svg { - fill: var(--component-chip-icon-disabled) !important; - } - - & > p { - color: var(--component-chip-label-color-disabled) !important; - } - } - } - - &__size { - &--sm { - padding-inline: var(--component-chip-spacing-padding-md); - height: var(--component-chip-height-sm); - gap: var(--component-chip-spacing-padding-xs); - } - &--md { - padding-inline: var(--component-chip-spacing-padding-lg); - height: var(--component-chip-height-md); - gap: var(--component-chip-spacing-padding-sm); - } - &--lg { - padding-inline: var(--component-chip-spacing-padding-xl); - height: var(--component-chip-height-lg); - gap: var(--component-chip-spacing-padding-md); - } - } - &__custom-right-padding { - &__size { - &--sm { - padding-inline: var(--component-chip-spacing-padding-md) var(--component-chip-spacing-padding-xs); - } - &--md { - padding-inline: var(--component-chip-spacing-padding-lg) var(--component-chip-spacing-padding-sm); - } - &--lg { - padding-inline: var(--component-chip-spacing-padding-xl) var(--component-chip-spacing-padding-md); - } - } + padding-inline: var(--component-chip-spacing-padding-lg) var(--component-chip-spacing-padding-sm); } } diff --git a/packages/trader/src/AppV2/Components/Chip/chip.tsx b/packages/trader/src/AppV2/Components/Chip/chip.tsx index 2c174debf5ae..01bb389074e9 100644 --- a/packages/trader/src/AppV2/Components/Chip/chip.tsx +++ b/packages/trader/src/AppV2/Components/Chip/chip.tsx @@ -1,16 +1,10 @@ import React from 'react'; -import { StandaloneChevronDownRegularIcon } from '@deriv/quill-icons'; +import { LabelPairedChevronDownSmRegularIcon } from '@deriv/quill-icons'; import './chip.scss'; import clsx from 'clsx'; -import { CaptionText, Text } from '@deriv-com/quill-ui'; +import { Text } from '@deriv-com/quill-ui'; import { TRegularSizes } from '@deriv-com/quill-ui/dist/types'; -export const LabelTextSizes: Record = { - sm: , - md: , - lg: , -}; - type BaseChipProps = Omit, 'label'> & { label?: React.ReactNode; disabled?: boolean; @@ -25,24 +19,14 @@ const Chip = React.forwardRef( ({ size = 'md', label, dropdown = false, className, selected, isDropdownOpen = false, onClick, ...rest }, ref) => ( +); + +export default CustomDateFilterButton; diff --git a/packages/trader/src/AppV2/Components/Filter/filter.scss b/packages/trader/src/AppV2/Components/Filter/filter.scss index 9c8444e21dfb..50487a926c16 100644 --- a/packages/trader/src/AppV2/Components/Filter/filter.scss +++ b/packages/trader/src/AppV2/Components/Filter/filter.scss @@ -5,8 +5,41 @@ height: var(--core-size-2000); padding-block: var(--core-spacing-400); + label { + flex-grow: 1; + } + &__wrapper { padding-block: var(--core-spacing-800); + + .quill-radio-button { + padding-block: var(--core-spacing-400); + width: 100%; + + &__label { + font-size: var(--core-fontSize-100); + flex-grow: 1; + margin: 0; + } + } } } } + +.custom-time-filter { + &__wrapper { + display: flex; + gap: var(--core-spacing-400); + margin-block: var(--core-spacing-400); + width: 100%; + } + + &__label { + flex-grow: 1; + } + + &__icon { + width: var(--core-size-1200); + height: var(--core-size-1200); + } +} diff --git a/packages/trader/src/AppV2/Components/Filter/time-filter.tsx b/packages/trader/src/AppV2/Components/Filter/time-filter.tsx index 37f021bd1ad0..25aa16b6ce02 100644 --- a/packages/trader/src/AppV2/Components/Filter/time-filter.tsx +++ b/packages/trader/src/AppV2/Components/Filter/time-filter.tsx @@ -3,19 +3,16 @@ import Chip from 'AppV2/Components/Chip'; import { toMoment } from '@deriv/shared'; import { ActionSheet, RadioGroup } from '@deriv-com/quill-ui'; import { Localize } from '@deriv/translations'; +import CustomDateFilterButton from './custom-time-filter-button'; +import DateRangePicker from 'AppV2/Components/DatePicker'; type TTimeFilter = { + handleDateChange: (values: { to?: moment.Moment; from?: moment.Moment; is_batch?: boolean }) => void; chosenTimeFilter?: string; - setChosenTimeFilter: React.Dispatch>; - handleDateChange: ( - date_values: { from?: moment.Moment; to: moment.Moment; is_batch: boolean }, - { - date_range, - }?: { - // TODO: refactor type - date_range: any; - } - ) => void; + setChosenTimeFilter: React.Dispatch>; + selectedRangeDateString?: string; + setSelectedDateRangeString: React.Dispatch>; + setNoMatchesFound: React.Dispatch>; }; // TODO: replace strings with numbers when types in Quill be changed @@ -24,6 +21,7 @@ const timeFilterList = [ value: '0', label: , }, + // TODO: Fix today and yesterday { value: '1', label: , @@ -50,8 +48,16 @@ const timeFilterList = [ }, ]; -const TimeFilter = ({ chosenTimeFilter, setChosenTimeFilter, handleDateChange }: TTimeFilter) => { +const TimeFilter = ({ + handleDateChange, + chosenTimeFilter, + setChosenTimeFilter, + selectedRangeDateString, + setSelectedDateRangeString, + setNoMatchesFound, +}: TTimeFilter) => { const [isDropdownOpen, setIsDropdownOpen] = React.useState(false); + const [showDatePicker, setShowDatePicker] = React.useState(false); const defaultCheckedTime = '0'; @@ -72,6 +78,7 @@ const TimeFilter = ({ chosenTimeFilter, setChosenTimeFilter, handleDateChange }: const onReset = () => { setChosenTimeFilter(''); + setSelectedDateRangeString(''); setIsDropdownOpen(false); handleDateChange({ from: Number(defaultCheckedTime) @@ -80,9 +87,11 @@ const TimeFilter = ({ chosenTimeFilter, setChosenTimeFilter, handleDateChange }: to: toMoment().endOf('day'), is_batch: true, }); + setNoMatchesFound(false); }; const chipLabelFormatting = () => + selectedRangeDateString || timeFilterList.find(item => item.value === (chosenTimeFilter || defaultCheckedTime))?.label; return ( @@ -92,19 +101,32 @@ const TimeFilter = ({ chosenTimeFilter, setChosenTimeFilter, handleDateChange }: dropdown isDropdownOpen={isDropdownOpen} onClick={() => setIsDropdownOpen(!isDropdownOpen)} - selected={!!chosenTimeFilter} + selected={!!(selectedRangeDateString || chosenTimeFilter)} + size='sm' /> setIsDropdownOpen(false)} position='left'> } /> - + {timeFilterList.map(({ value, label }) => ( - + ))} - {/* TODO: Replace with real component*/} -
Custom
+
+ {showDatePicker && ( + setShowDatePicker(false)} + setSelectedDateRangeString={setSelectedDateRangeString} + handleDateChange={handleDateChange} + /> + )} ); }; diff --git a/packages/trader/src/AppV2/Containers/Positions/positions-content.tsx b/packages/trader/src/AppV2/Containers/Positions/positions-content.tsx index 8cfe9b4b9e7e..62ad9a955f0b 100644 --- a/packages/trader/src/AppV2/Containers/Positions/positions-content.tsx +++ b/packages/trader/src/AppV2/Containers/Positions/positions-content.tsx @@ -21,8 +21,9 @@ export type TClosedPosition = { const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsDemo }: TPositionsContentProps) => { const [contractTypeFilter, setContractTypeFilter] = React.useState([]); - const [chosenTimeFilter, setChosenTimeFilter] = React.useState(''); + const [chosenTimeFilter, setChosenTimeFilter] = React.useState(); const [filteredPositions, setFilteredPositions] = React.useState<(TPortfolioPosition | TClosedPosition)[]>([]); + const [selectedRangeDateString, setSelectedDateRangeString] = React.useState(); const [noMatchesFound, setNoMatchesFound] = React.useState(false); const { common, client, portfolio } = useStore(); @@ -41,7 +42,7 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD () => (isClosedTab ? closedPositions : active_positions), [active_positions, isClosedTab, closedPositions] ); - const hasNoPositions = isClosedTab ? is_empty : is_active_empty; + const hasNoPositions = isClosedTab ? is_empty && !chosenTimeFilter && !selectedRangeDateString : is_active_empty; const shouldShowEmptyMessage = hasNoPositions || noMatchesFound; const shouldShowContractCards = isClosedTab || (filteredPositions.length && (filteredPositions[0]?.contract_info as TContractInfo)?.status); @@ -65,6 +66,14 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD } }; + React.useEffect(() => { + if (!positions.length && isClosedTab && (selectedRangeDateString || chosenTimeFilter)) { + setNoMatchesFound(true); + } else { + setNoMatchesFound(false); + } + }, [selectedRangeDateString, chosenTimeFilter, positions, isClosedTab]); + if (isLoading || (!shouldShowContractCards && !shouldShowEmptyMessage)) return ; return (
@@ -76,6 +85,9 @@ const PositionsContent = observer(({ hasButtonsDemo, isClosedTab, setHasButtonsD chosenTimeFilter={chosenTimeFilter} setChosenTimeFilter={setChosenTimeFilter} handleDateChange={handleDateChange} + selectedRangeDateString={selectedRangeDateString} + setSelectedDateRangeString={setSelectedDateRangeString} + setNoMatchesFound={setNoMatchesFound} /> )}