diff --git a/app/components/assets/assets-index/advanced-asset-index-filters-and-sorting.tsx b/app/components/assets/assets-index/advanced-asset-index-filters-and-sorting.tsx index b68d025e6..85f537d21 100644 --- a/app/components/assets/assets-index/advanced-asset-index-filters-and-sorting.tsx +++ b/app/components/assets/assets-index/advanced-asset-index-filters-and-sorting.tsx @@ -213,7 +213,6 @@ function AdvancedFilter() { /> - {/* Only show operator and value fields if a column is selected */} {filter.name && ( <>
@@ -226,6 +225,11 @@ function AdvancedFilter() { return newFilters; }); }} + disabled={ + filter.isNew + ? { reason: "Please select a column" } + : false + } />
@@ -241,6 +245,7 @@ function AdvancedFilter() { applyFilters={applyFilters} fieldName={getFieldName(index)} zormError={getError(index)} + disabled={filter.isNew} />
diff --git a/app/components/assets/assets-index/advanced-filters/helpers.ts b/app/components/assets/assets-index/advanced-filters/helpers.ts index 759d8115b..9497d00e3 100644 --- a/app/components/assets/assets-index/advanced-filters/helpers.ts +++ b/app/components/assets/assets-index/advanced-filters/helpers.ts @@ -180,7 +180,13 @@ export function getAvailableColumns( // Get columns that are visible and not already used const availableColumns = columns.filter( (column) => - column.visible && !usedColumns.find((f) => f.name === column.name) + column.visible && + !usedColumns.find((f) => { + if (operation === "filter" && "isNew" in f) { + return f.name === column.name && !f.isNew; + } + return f.name === column.name; + }) ); // Apply operation-specific filtering diff --git a/app/components/assets/assets-index/advanced-filters/operator-selector.tsx b/app/components/assets/assets-index/advanced-filters/operator-selector.tsx index 9b9abcf7f..40afa229a 100644 --- a/app/components/assets/assets-index/advanced-filters/operator-selector.tsx +++ b/app/components/assets/assets-index/advanced-filters/operator-selector.tsx @@ -5,6 +5,7 @@ import { PopoverPortal, PopoverTrigger, } from "@radix-ui/react-popover"; +import type { DisabledProp } from "~/components/shared/button"; import { Button } from "~/components/shared/button"; import { tw } from "~/utils/tw"; import type { Filter, FilterDefinition, FilterOperator } from "./schema"; @@ -58,9 +59,11 @@ export const operatorsPerType: FilterDefinition = { export function OperatorSelector({ filter, setFilter, + disabled, }: { filter: Filter; setFilter: (filter: Filter["operator"]) => void; + disabled?: DisabledProp; }) { const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -79,6 +82,7 @@ export function OperatorSelector({ variant="secondary" title={operatorsMap[operator][1]} className="w-[50px] font-normal" + disabled={disabled} > {operatorsMap[operator][0]} diff --git a/app/components/assets/assets-index/advanced-filters/value-field.tsx b/app/components/assets/assets-index/advanced-filters/value-field.tsx index c0cfe9b72..9aa362570 100644 --- a/app/components/assets/assets-index/advanced-filters/value-field.tsx +++ b/app/components/assets/assets-index/advanced-filters/value-field.tsx @@ -29,12 +29,14 @@ export function ValueField({ applyFilters, fieldName, // From zorm zormError, // From zorm + disabled, }: { filter: Filter; setFilter: (value: Filter["value"]) => void; applyFilters: () => void; fieldName: string; zormError?: string; + disabled?: boolean; }) { const data = useLoaderData(); const customFields = useMemo(() => data?.customFields || [], [data]); @@ -128,16 +130,18 @@ export function ValueField({ inputClassName: "px-4 py-2 text-[14px] leading-5", hideLabel: true, label: filter.name, + disabled, }; const submitOnEnter = (e: React.KeyboardEvent) => { - if (e.key === "Enter") { + if (e.key === "Enter" && !disabled) { applyFilters(); } }; /** Generates placeholder for text input fields, based on the operator */ function placeholder(operator: Filter["operator"]) { + if (disabled) return "Select a column first"; return ["contains", "containsAll", "containsAny", "matchesAny"].includes( operator ) @@ -205,7 +209,7 @@ export function ValueField({ type="number" value={filter.value as number} onChange={handleChange} - placeholder="Enter number" + placeholder={placeholder(filter.operator)} min={0} onKeyUp={submitOnEnter} error={error} @@ -221,6 +225,7 @@ export function ValueField({ value={filter.value as boolean} handleBooleanChange={handleBooleanChange} name={fieldName} + disabled={disabled} /> @@ -234,6 +239,7 @@ export function ValueField({ setFilter={setFilter} applyFilters={applyFilters} name={fieldName} + disabled={disabled} /> @@ -248,6 +254,7 @@ export function ValueField({ handleChange={setFilter} multiSelect={filter.operator === "containsAny"} name={fieldName} + disabled={disabled} /> @@ -288,10 +295,12 @@ function BooleanField({ name, value, handleBooleanChange, + disabled = false, }: { name: string; value: boolean | string; handleBooleanChange: (value: "true" | "false") => void; + disabled?: boolean; }) { const [isPopoverOpen, setIsPopoverOpen] = useState(false); @@ -300,14 +309,20 @@ function BooleanField({ return ( <> - + !disabled && setIsPopoverOpen(open)} + > @@ -353,6 +368,7 @@ interface EnumFieldProps { handleChange: (value: string) => void; multiSelect?: boolean; name?: string; + disabled?: boolean; } /** @@ -364,13 +380,16 @@ function EnumField({ handleChange, multiSelect = false, name, + disabled = false, }: EnumFieldProps) { const [isPopoverOpen, setIsPopoverOpen] = useState(false); // Convert the value into an array for multi-select mode const selectedValues = multiSelect ? value.split(", ") : [value]; - const displayValue = multiSelect + const displayValue = disabled + ? "Select a column first" + : multiSelect ? selectedValues .map((v) => options.find((opt) => opt.id === v)?.label ?? v) .join(", ") @@ -402,11 +421,15 @@ function EnumField({ value={multiSelect ? displayValue : value} name={name} /> - + !disabled && setIsPopoverOpen(open)} + >