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)}
+ >
- {boolValue ? "Yes" : "No"} {" "}
+
+ {disabled ? "Select a column first" : boolValue ? "Yes" : "No"}
+ {" "}
@@ -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)}
+ >
{displayValue}
@@ -458,6 +481,7 @@ function StatusEnumField({
handleChange,
multiSelect,
name,
+ disabled = false,
}: Omit) {
const options: EnumOption[] = Object.values(AssetStatus).map((status) => ({
id: status,
@@ -471,6 +495,7 @@ function StatusEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
);
}
@@ -484,6 +509,7 @@ function CustomFieldEnumField({
fieldName,
multiSelect,
name,
+ disabled,
}: Omit & { fieldName: string }) {
const data = useLoaderData();
const customFields = useMemo(
@@ -506,6 +532,7 @@ function CustomFieldEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
);
}
@@ -519,6 +546,7 @@ function CustodyEnumField({
handleChange,
multiSelect,
name,
+ disabled,
}: Omit) {
const data = useLoaderData();
@@ -550,6 +578,7 @@ function CustodyEnumField({
id: "without-custody",
name: "Without custody",
},
+ disabled,
};
if (multiSelect) {
@@ -561,6 +590,7 @@ function CustodyEnumField({
) {
const data = useLoaderData();
@@ -666,6 +697,7 @@ function CategoryEnumField({
id: "uncategorized",
name: "Uncategorized",
},
+ disabled,
};
// For multi-select (containsAny operator), use DynamicDropdown
@@ -686,7 +718,9 @@ function CategoryEnumField({
selectedIds.length <= 0 && "text-gray-500"
)}
>
- {selectedIds.length > 0
+ {disabled
+ ? "Select a column first"
+ : selectedIds.length > 0
? selectedIds
.map((id) => {
const category = data.categories?.find(
@@ -719,7 +753,7 @@ function CategoryEnumField({
{
if (selectedId !== undefined) {
@@ -740,6 +774,7 @@ function LocationEnumField({
handleChange,
multiSelect,
name,
+ disabled = false,
}: Omit) {
const data = useLoaderData();
@@ -774,6 +809,7 @@ function LocationEnumField({
id: "without-location",
name: "Without location",
},
+ disabled,
};
// For multi-select (containsAny operator), use DynamicDropdown
@@ -794,7 +830,9 @@ function LocationEnumField({
selectedIds.length <= 0 && "text-gray-500"
)}
>
- {selectedIds.length > 0
+ {disabled
+ ? "Select column first"
+ : selectedIds.length > 0
? selectedIds
.map((id) => {
const location = data.locations?.find(
@@ -827,7 +865,7 @@ function LocationEnumField({
{
if (selectedId !== undefined) {
@@ -848,6 +886,7 @@ function KitEnumField({
handleChange,
multiSelect,
name,
+ disabled,
}: Omit) {
const data = useLoaderData();
@@ -882,6 +921,7 @@ function KitEnumField({
id: "without-kit",
name: "Without kit",
},
+ disabled,
};
// For multi-select (containsAny operator), use DynamicDropdown
@@ -902,7 +942,9 @@ function KitEnumField({
selectedIds.length <= 0 && "text-gray-500"
)}
>
- {selectedIds.length > 0 && data.kits && data.kits.length > 0
+ {disabled
+ ? "Select a column first"
+ : selectedIds.length > 0 && data.kits && data.kits.length > 0
? selectedIds
.map((id) => {
const kit = data.kits?.find((kit) => kit.id === id);
@@ -933,7 +975,7 @@ function KitEnumField({
{
if (selectedId !== undefined) {
@@ -958,6 +1000,7 @@ function ValueEnumField({
multiSelect,
name,
error,
+ disabled = false,
}: {
fieldName: string;
value: string;
@@ -965,6 +1008,7 @@ function ValueEnumField({
multiSelect?: boolean;
name?: string;
error?: string;
+ disabled?: boolean;
}) {
if (fieldName === "status") {
return (
@@ -974,6 +1018,7 @@ function ValueEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -988,6 +1033,7 @@ function ValueEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -1003,6 +1049,7 @@ function ValueEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -1017,6 +1064,7 @@ function ValueEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -1031,6 +1079,7 @@ function ValueEnumField({
handleChange={handleChange}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -1046,6 +1095,7 @@ function ValueEnumField({
fieldName={fieldName}
multiSelect={multiSelect}
name={name}
+ disabled={disabled}
/>
{error && {error}
}
>
@@ -1061,6 +1111,7 @@ type DateFieldProps = {
filter: Filter;
setFilter: (value: Filter["value"]) => void;
applyFilters: () => void;
+ disabled?: boolean;
};
/**
@@ -1073,6 +1124,7 @@ export function DateField({
setFilter,
applyFilters,
error,
+ disabled = false,
}: DateFieldProps) {
const { timeZone } = useHints();
const [localValue, setLocalValue] = useState<[string, string]>(["", ""]);
@@ -1161,8 +1213,20 @@ export function DateField({
hideLabel: true,
label: filter.name,
onKeyUp: submitOnEnter,
+ disabled,
};
+ if (disabled) {
+ return (
+
+ );
+ }
+
if (filter.operator === "between") {
return (
@@ -1211,6 +1275,7 @@ export function DateField({
onChange={handleDateChange(0)}
error={combinedError}
name={name}
+ disabled={disabled}
/>
);
}