From 0e11e89233d2cc8543c61ac34a906065c1cf1e9f Mon Sep 17 00:00:00 2001 From: Sebastian Rindom Date: Wed, 9 Oct 2024 16:50:47 +0200 Subject: [PATCH] fix: hover states on filters and chip groups (#9511) * fix: hover states on filters and chip groups * fix: create FilterChip component --- .../common/chip-group/chip-group.tsx | 2 +- .../data-table-filter/date-filter.tsx | 78 ++----------- .../data-table-filter/filter-chip.tsx | 97 ++++++++++++++++ .../data-table-filter/number-filter.tsx | 98 +++------------- .../data-table-filter/select-filter.tsx | 108 +++--------------- .../data-table-filter/string-filter.tsx | 93 ++------------- .../location-service-zone-manage-areas.tsx | 2 +- 7 files changed, 146 insertions(+), 332 deletions(-) create mode 100644 packages/admin/dashboard/src/components/table/data-table/data-table-filter/filter-chip.tsx diff --git a/packages/admin/dashboard/src/components/common/chip-group/chip-group.tsx b/packages/admin/dashboard/src/components/common/chip-group/chip-group.tsx index fef85505db..48ed2ef3d8 100644 --- a/packages/admin/dashboard/src/components/common/chip-group/chip-group.tsx +++ b/packages/admin/dashboard/src/components/common/chip-group/chip-group.tsx @@ -76,7 +76,7 @@ const Chip = ({ index, className, children }: ChipProps) => { return (
  • (displayValue) + const handleRemove = () => { selectedParams.delete() removeFilter(key) @@ -105,6 +108,7 @@ export const DateFilter = ({ const handleOpenChange = (open: boolean) => { setOpen(open) + setPreviousValue(displayValue) if (timeoutId) { clearTimeout(timeoutId) @@ -119,7 +123,8 @@ export const DateFilter = ({ return ( - void -} - -const DateDisplay = ({ - label, - value, - readonly, - onRemove, -}: DateDisplayProps) => { - const handleRemove = (e: MouseEvent) => { - e.stopPropagation() - onRemove() - } - - return ( - -
    -
    - - {label} - -
    - {value && ( -
    -
    - - {value} - -
    -
    - )} - {!readonly && value && ( -
    - -
    - )} -
    -
    - ) -} - const today = new Date() today.setHours(0, 0, 0, 0) diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/filter-chip.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/filter-chip.tsx new file mode 100644 index 0000000000..8545555929 --- /dev/null +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/filter-chip.tsx @@ -0,0 +1,97 @@ +import { XMarkMini } from "@medusajs/icons" +import { Text, clx } from "@medusajs/ui" +import { useTranslation } from "react-i18next" +import { MouseEvent } from "react" +import * as Popover from "@radix-ui/react-popover" + +export type FilterChipProps = { + hadPreviousValue?: boolean + label: string + value?: string + readonly?: boolean + hasOperator?: boolean + onRemove: () => void +} + +const FilterChip = ({ + hadPreviousValue, + label, + value, + readonly, + hasOperator, + onRemove, +}: FilterChipProps) => { + const { t } = useTranslation() + + const handleRemove = (e: MouseEvent) => { + e.stopPropagation() + onRemove() + } + + return ( +
    + {!hadPreviousValue && ( + + )} +
    + + {label} + +
    +
    + {hasOperator && !!(value || hadPreviousValue) && ( +
    + + {t("general.is")} + +
    + )} + {!!(value || hadPreviousValue) && ( + + + {value || "\u00A0"} + + + )} +
    + {!readonly && !!(value || hadPreviousValue) && ( + + )} +
    + ) +} + +export default FilterChip diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/number-filter.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/number-filter.tsx index f725ece90c..66520a284f 100644 --- a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/number-filter.tsx +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/number-filter.tsx @@ -1,11 +1,10 @@ -import { EllipseMiniSolid, XMarkMini } from "@medusajs/icons" -import { Input, Label, Text, clx } from "@medusajs/ui" +import { EllipseMiniSolid } from "@medusajs/icons" +import { Input, Label, clx } from "@medusajs/ui" import * as Popover from "@radix-ui/react-popover" import * as RadioGroup from "@radix-ui/react-radio-group" import { debounce } from "lodash" import { ChangeEvent, - MouseEvent, useCallback, useEffect, useState, @@ -15,6 +14,8 @@ import { useTranslation } from "react-i18next" import { useSelectedParams } from "../hooks" import { useDataTableFilterContext } from "./context" import { IFilter } from "./types" +import { TFunction } from "i18next" +import FilterChip from "./filter-chip" type NumberFilterProps = IFilter @@ -40,6 +41,9 @@ export const NumberFilter = ({ }) const currentValue = selectedParams.get() + const [previousValue, setPreviousValue] = useState( + currentValue + ) const [operator, setOperator] = useState( getOperator(currentValue) @@ -99,6 +103,7 @@ export const NumberFilter = ({ const handleOpenChange = (open: boolean) => { setOpen(open) + setPreviousValue(currentValue) if (timeoutId) { clearTimeout(timeoutId) @@ -131,11 +136,16 @@ export const NumberFilter = ({ const LT_KEY = `${key}-lt` const EQ_KEY = key + const displayValue = parseDisplayValue(currentValue, t) + const previousDisplayValue = parseDisplayValue(previousValue, t) + return ( - @@ -242,23 +252,7 @@ export const NumberFilter = ({ ) } -const NumberDisplay = ({ - label, - value, - readonly, - onRemove, -}: { - label: string - value?: string[] - readonly?: boolean - onRemove: () => void -}) => { - const { t } = useTranslation() - const handleRemove = (e: MouseEvent) => { - e.stopPropagation() - onRemove() - } - +const parseDisplayValue = (value: string[] | null | undefined, t: TFunction) => { const parsed = JSON.parse(value?.join(",") || "{}") let displayValue = "" @@ -283,65 +277,7 @@ const NumberDisplay = ({ displayValue = parsed.toString() } - return ( - -
    -
    - - {label} - -
    - {!!value && ( -
    - - {t("general.is")} - -
    - )} - {value && ( -
    -
    - - {displayValue} - -
    -
    - )} - {!readonly && value && ( -
    - -
    - )} -
    -
    - ) + return displayValue } const parseValue = (value: string[] | null | undefined) => { diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/select-filter.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/select-filter.tsx index 64e4bc19cf..9244823e20 100644 --- a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/select-filter.tsx +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/select-filter.tsx @@ -1,13 +1,14 @@ import { CheckMini, EllipseMiniSolid, XMarkMini } from "@medusajs/icons" -import { Text, clx } from "@medusajs/ui" +import { clx } from "@medusajs/ui" import * as Popover from "@radix-ui/react-popover" import { Command } from "cmdk" -import { MouseEvent, useState } from "react" +import { useState } from "react" import { useTranslation } from "react-i18next" import { useSelectedParams } from "../hooks" import { useDataTableFilterContext } from "./context" import { IFilter } from "./types" +import FilterChip from "./filter-chip" interface SelectFilterProps extends IFilter { options: { label: string; value: unknown }[] @@ -40,6 +41,8 @@ export const SelectFilter = ({ .map((v) => options.find((o) => o.value === v)?.label) .filter(Boolean) as string[] + const [previousValue, setPreviousValue] = useState(labelValues) + const handleRemove = () => { selectedParams.delete() removeFilter(key) @@ -50,6 +53,8 @@ export const SelectFilter = ({ const handleOpenChange = (open: boolean) => { setOpen(open) + setPreviousValue(labelValues) + if (timeoutId) { clearTimeout(timeoutId) } @@ -79,12 +84,17 @@ export const SelectFilter = ({ } } + const normalizedValues = labelValues ? (Array.isArray(labelValues) ? labelValues : [labelValues]) : null + const normalizedPrev = previousValue ? (Array.isArray(previousValue) ? previousValue : [previousValue]) : null + return ( - {!readonly && ( @@ -179,93 +189,3 @@ export const SelectFilter = ({ ) } - -type SelectDisplayProps = { - label: string - readonly?: boolean - value?: string | string[] - onRemove: () => void -} - -export const SelectDisplay = ({ - label, - value, - onRemove, - readonly, -}: SelectDisplayProps) => { - const { t } = useTranslation() - const v = value ? (Array.isArray(value) ? value : [value]) : null - const count = v?.length || 0 - - const handleRemove = (e: MouseEvent) => { - e.stopPropagation() - onRemove() - } - - return ( - -
    -
    0, - } - )} - > - - {label} - -
    -
    - {count > 0 && ( -
    - - {t("general.is")} - -
    - )} - {count > 0 && ( -
    - - {v?.join(", ")} - -
    - )} -
    - {!readonly && v && v.length > 0 && ( -
    - -
    - )} -
    -
    - ) -} diff --git a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/string-filter.tsx b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/string-filter.tsx index c1f9dadee0..6832729acc 100644 --- a/packages/admin/dashboard/src/components/table/data-table/data-table-filter/string-filter.tsx +++ b/packages/admin/dashboard/src/components/table/data-table/data-table-filter/string-filter.tsx @@ -1,12 +1,11 @@ -import { XMarkMini } from "@medusajs/icons" -import { Input, Label, Text, clx } from "@medusajs/ui" +import { Input, Label, clx } from "@medusajs/ui" import * as Popover from "@radix-ui/react-popover" import { debounce } from "lodash" import { ChangeEvent, useCallback, useEffect, useState } from "react" -import { useTranslation } from "react-i18next" import { useSelectedParams } from "../hooks" import { useDataTableFilterContext } from "./context" import { IFilter } from "./types" +import FilterChip from "./filter-chip" type StringFilterProps = IFilter @@ -25,6 +24,8 @@ export const StringFilter = ({ const query = selectedParams.get() + const [previousValue, setPreviousValue] = useState(query?.[0]) + // eslint-disable-next-line react-hooks/exhaustive-deps const debouncedOnChange = useCallback( debounce((e: ChangeEvent) => { @@ -49,6 +50,7 @@ export const StringFilter = ({ const handleOpenChange = (open: boolean) => { setOpen(open) + setPreviousValue(query?.[0]) if (timeoutId) { clearTimeout(timeoutId) @@ -68,7 +70,9 @@ export const StringFilter = ({ return ( - ) } - -const StringDisplay = ({ - label, - value, - readonly, - onRemove, -}: { - label: string - value?: string - readonly?: boolean - onRemove: () => void -}) => { - const { t } = useTranslation() - - return ( - -
    -
    - - {label} - -
    -
    - {!!value && ( -
    - - {t("general.is")} - -
    - )} - {!!value && ( -
    - - {value} - -
    - )} -
    - {!readonly && !!value && ( -
    - -
    - )} -
    -
    - ) -} diff --git a/packages/admin/dashboard/src/routes/locations/location-service-zone-manage-areas/location-service-zone-manage-areas.tsx b/packages/admin/dashboard/src/routes/locations/location-service-zone-manage-areas/location-service-zone-manage-areas.tsx index 7a1127fa1b..922454b15f 100644 --- a/packages/admin/dashboard/src/routes/locations/location-service-zone-manage-areas/location-service-zone-manage-areas.tsx +++ b/packages/admin/dashboard/src/routes/locations/location-service-zone-manage-areas/location-service-zone-manage-areas.tsx @@ -9,7 +9,7 @@ export const LocationServiceZoneManageAreas = () => { const { stock_location, isPending, isFetching, isError, error } = useStockLocation(location_id!, { - fields: "*fulfillment_sets.service_zones.geo_zones", + fields: "*fulfillment_sets.service_zones.geo_zones,fulfillment_sets.service_zones.name", }) const zone = stock_location?.fulfillment_sets