diff --git a/apps/studio/components/grid/components/header/filter/FilterPopover.tsx b/apps/studio/components/grid/components/header/filter/FilterPopover.tsx index 7aa07a06982..9caaed755ce 100644 --- a/apps/studio/components/grid/components/header/filter/FilterPopover.tsx +++ b/apps/studio/components/grid/components/header/filter/FilterPopover.tsx @@ -1,11 +1,18 @@ import { useUrlState } from 'hooks' import update from 'immutability-helper' import { isEqual } from 'lodash' +import { FilterIcon, Plus } from 'lucide-react' import { KeyboardEvent, useCallback, useMemo, useState } from 'react' -import { Button, IconFilter, IconPlus, Popover } from 'ui' import { formatFilterURLParams } from 'components/grid/SupabaseGrid.utils' import type { Filter, SupaTable } from 'components/grid/types' +import { + Button, + PopoverContent_Shadcn_, + PopoverSeparator_Shadcn_, + PopoverTrigger_Shadcn_, + Popover_Shadcn_, +} from 'ui' import { FilterOperatorOptions } from './Filter.constants' import FilterRow from './FilterRow' @@ -16,38 +23,54 @@ export interface FilterPopoverProps { } const FilterPopover = ({ table, filters, setParams }: FilterPopoverProps) => { + const [open, setOpen] = useState(false) + const btnText = (filters || []).length > 0 ? `Filtered by ${filters.length} rule${filters.length > 1 ? 's' : ''}` : 'Filter' + const onApplyFilters = (appliedFilters: Filter[]) => { + setParams((prevParams) => { + return { + ...prevParams, + filter: appliedFilters.map((filter) => { + const selectedOperator = FilterOperatorOptions.find( + (option) => option.value === filter.operator + ) + + return `${filter.column}:${selectedOperator?.abbrev}:${filter.value}` + }), + } + }) + } + return ( - } - > - - + + + + + + + + ) } export default FilterPopover -export interface FilterOverlayProps extends FilterPopoverProps {} +interface FilterOverlayProps { + table: SupaTable + filters: string[] + onApplyFilters: (filter: Filter[]) => void +} -const FilterOverlay = ({ table, filters: filtersFromUrl, setParams }: FilterOverlayProps) => { +const FilterOverlay = ({ table, filters: filtersFromUrl, onApplyFilters }: FilterOverlayProps) => { const initialFilters = useMemo( () => formatFilterURLParams((filtersFromUrl as string[]) ?? []), [filtersFromUrl] @@ -87,25 +110,8 @@ const FilterOverlay = ({ table, filters: filtersFromUrl, setParams }: FilterOver ) }, []) - function onApplyFilter() { - setParams((prevParams) => { - return { - ...prevParams, - filter: filters.map((filter) => { - const selectedOperator = FilterOperatorOptions.find( - (option) => option.value === filter.operator - ) - - return `${filter.column}:${selectedOperator?.abbrev}:${filter.value}` - }), - } - }) - } - function handleEnterKeyDown(event: KeyboardEvent) { - if (event.key === 'Enter') { - onApplyFilter() - } + if (event.key === 'Enter') onApplyFilters(filters) } return ( @@ -129,12 +135,16 @@ const FilterOverlay = ({ table, filters: filtersFromUrl, setParams }: FilterOver )} - +
- -
diff --git a/apps/studio/components/grid/components/header/filter/FilterRow.tsx b/apps/studio/components/grid/components/header/filter/FilterRow.tsx index bf20b15603c..79e4867d38a 100644 --- a/apps/studio/components/grid/components/header/filter/FilterRow.tsx +++ b/apps/studio/components/grid/components/header/filter/FilterRow.tsx @@ -4,6 +4,7 @@ import { Button, IconChevronDown, IconX, Input } from 'ui' import { DropdownControl } from 'components/grid/components/common' import type { Filter, FilterOperator, SupaTable } from 'components/grid/types' import { FilterOperatorOptions } from './Filter.constants' +import { X } from 'lucide-react' export interface FilterRowProps { table: SupaTable @@ -29,7 +30,7 @@ const FilterRow = ({ table, filter, filterIdx, onChange, onDelete, onKeyDown }: : 'Enter a value' return ( -
+
diff --git a/apps/studio/components/grid/components/header/sort/SortPopover.tsx b/apps/studio/components/grid/components/header/sort/SortPopover.tsx index 80c3ef223ac..c157e7e03f7 100644 --- a/apps/studio/components/grid/components/header/sort/SortPopover.tsx +++ b/apps/studio/components/grid/components/header/sort/SortPopover.tsx @@ -1,12 +1,19 @@ import { useUrlState } from 'hooks' import update from 'immutability-helper' import { isEqual } from 'lodash' +import { ChevronDown, List } from 'lucide-react' import { useCallback, useMemo, useState } from 'react' -import { Button, IconChevronDown, IconList, Popover } from 'ui' -import { DropdownControl } from 'components/grid/components/common' import { formatSortURLParams } from 'components/grid/SupabaseGrid.utils' +import { DropdownControl } from 'components/grid/components/common' import type { Sort, SupaTable } from 'components/grid/types' +import { + Button, + PopoverContent_Shadcn_, + PopoverSeparator_Shadcn_, + PopoverTrigger_Shadcn_, + Popover_Shadcn_, +} from 'ui' import SortRow from './SortRow' export interface SortPopoverProps { @@ -16,38 +23,48 @@ export interface SortPopoverProps { } const SortPopover = ({ table, sorts, setParams }: SortPopoverProps) => { + const [open, setOpen] = useState(false) + const btnText = (sorts || []).length > 0 ? `Sorted by ${sorts.length} rule${sorts.length > 1 ? 's' : ''}` : 'Sort' + const onApplySorts = (appliedSorts: Sort[]) => { + setParams((prevParams) => { + return { + ...prevParams, + sort: appliedSorts.map((sort) => `${sort.column}:${sort.ascending ? 'asc' : 'desc'}`), + } + }) + } + return ( - } - > - - + + + + + + + + ) } export default SortPopover -export interface SortOverlayProps extends SortPopoverProps {} +export interface SortOverlayProps { + table: SupaTable + sorts: string[] + onApplySorts: (sorts: Sort[]) => void +} -const SortOverlay = ({ table, sorts: sortsFromUrl, setParams }: SortOverlayProps) => { +const SortOverlay = ({ table, sorts: sortsFromUrl, onApplySorts }: SortOverlayProps) => { const initialSorts = useMemo( () => formatSortURLParams((sortsFromUrl as string[]) ?? []), [sortsFromUrl] @@ -68,15 +85,6 @@ const SortOverlay = ({ table, sorts: sortsFromUrl, setParams }: SortOverlayProps setSorts([...sorts, { column: columnName as string, ascending: true }]) } - function onApplySort() { - setParams((prevParams) => { - return { - ...prevParams, - sort: sorts.map((sort) => `${sort.column}:${sort.ascending ? 'asc' : 'desc'}`), - } - }) - } - const onDeleteSort = useCallback((column: string) => { setSorts((currentSorts) => currentSorts.filter((sort) => sort.column !== column)) }, []) @@ -125,7 +133,7 @@ const SortOverlay = ({ table, sorts: sortsFromUrl, setParams }: SortOverlayProps
)} - +
{columns && columns.length > 0 ? ( ) : (

All columns have been added

)}
-
diff --git a/apps/studio/styles/grid.scss b/apps/studio/styles/grid.scss index a89bea20d98..dd28b121f6e 100644 --- a/apps/studio/styles/grid.scss +++ b/apps/studio/styles/grid.scss @@ -562,30 +562,6 @@ @apply block; } -/* - header/filter/FilterDropdown -*/ - -.sb-grid-filter-popover { - @apply overflow-visible; -} - -.sb-grid-filter-popover__misc { - @apply py-2; -} - -.sb-grid-filter-popover__misc__text { - @apply block; -} - -/* -header/filter/FilterRow -*/ - -.sb-grid-filter-row { - @apply flex w-full items-center justify-between space-x-1; -} - /* header/sort/SortDropdown */ diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 95d157c16d3..6af504ed2ca 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -120,6 +120,7 @@ export { PopoverTrigger as PopoverTrigger_Shadcn_, PopoverContent as PopoverContent_Shadcn_, PopoverAnchor as PopoverAnchor_Shadcn_, + PopoverSeparator as PopoverSeparator_Shadcn_, } from './src/components/shadcn/ui/popover' export { diff --git a/packages/ui/src/components/shadcn/ui/popover.tsx b/packages/ui/src/components/shadcn/ui/popover.tsx index 1c689228715..444fb8b0f28 100644 --- a/packages/ui/src/components/shadcn/ui/popover.tsx +++ b/packages/ui/src/components/shadcn/ui/popover.tsx @@ -53,4 +53,11 @@ const PopoverContent = React.forwardRef< ) PopoverContent.displayName = 'PopoverContent' -export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor } +const PopoverSeparator = React.forwardRef>( + ({ className, children, ...props }, ref) => ( +
+ ) +) +PopoverSeparator.displayName = 'PopoverSeparator' + +export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverSeparator }