Skip to content

Commit

Permalink
Merge pull request #1405 from Shelf-nu/1404-bug-disselecting-category…
Browse files Browse the repository at this point in the history
…-in-assetedit-doesnt-clear-params-and-doesnt-revalidate-to-show-the-correct-fields

fix: asset form category selector
  • Loading branch information
DonKoko authored Nov 8, 2024
2 parents ff7f689 + ffe0e84 commit 293e92d
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,9 @@ function CustodyEnumField({
placeholder="Select custodian"
defaultValue={value as string}
onChange={(selectedId) => {
handleChange(selectedId);
if (selectedId !== undefined) {
handleChange(selectedId);
}
}}
closeOnSelect={true}
triggerWrapperClassName="w-full text-gray-700"
Expand Down Expand Up @@ -710,7 +712,9 @@ function CategoryEnumField({
placeholder="Select category"
defaultValue={value as string}
onChange={(selectedId) => {
handleChange(selectedId);
if (selectedId !== undefined) {
handleChange(selectedId);
}
}}
closeOnSelect={true}
triggerWrapperClassName="w-full text-gray-700"
Expand Down Expand Up @@ -811,7 +815,9 @@ function LocationEnumField({
placeholder="Select location"
defaultValue={value as string}
onChange={(selectedId) => {
handleChange(selectedId);
if (selectedId !== undefined) {
handleChange(selectedId);
}
}}
closeOnSelect={true}
triggerWrapperClassName="w-full text-gray-700"
Expand Down Expand Up @@ -910,7 +916,9 @@ function KitEnumField({
placeholder="Select kit"
defaultValue={value as string}
onChange={(selectedId) => {
handleChange(selectedId);
if (selectedId !== undefined) {
handleChange(selectedId);
}
}}
closeOnSelect={true}
triggerWrapperClassName="w-full text-gray-700"
Expand Down
3 changes: 2 additions & 1 deletion app/components/assets/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ export const AssetForm = ({
countKey="totalCategories"
closeOnSelect
selectionMode="set"
allowClear
allowClear={true}
extraContent={
<Button
to="/categories/new"
Expand Down Expand Up @@ -319,6 +319,7 @@ export const AssetForm = ({
/>
<DynamicSelect
disabled={disabled}
selectionMode="set"
fieldName="newLocationId"
defaultValue={location || undefined}
model={{ name: "location", queryKey: "name" }}
Expand Down
22 changes: 12 additions & 10 deletions app/components/dynamic-select/dynamic-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ type Props = ModelFilterProps & {
placeholder?: string;
closeOnSelect?: boolean;
excludeItems?: string[];
onChange?: ((value: string) => void) | null;
/**
/** Allow undefined for deselection cases */
onChange?: ((value: string | undefined) => void) | null /**
* Allow item to unselect on clicking again
*/
*/;
allowClear?: boolean;
hidden?: boolean;
};
Expand Down Expand Up @@ -110,14 +110,16 @@ export default function DynamicSelect({
);

function handleItemChange(id: string) {
if (allowClear && selectedValue === id) {
setSelectedValue(undefined);
} else {
setSelectedValue(id);
handleSelectItemChange(id);
}
const isDeselecting = allowClear && selectedValue === id;

// Update local state
setSelectedValue(isDeselecting ? undefined : id);

// Always update URL params and parent state
handleSelectItemChange(id);

onChange && onChange(id);
// Notify parent with the new value
onChange?.(isDeselecting ? undefined : id);

if (closeOnSelect) {
setIsPopoverOpen(false);
Expand Down
6 changes: 4 additions & 2 deletions app/components/forms/categories-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,10 @@ export default function CategoriesInput({
className="flex-1"
excludeItems={categories}
onChange={(value) => {
categories[i] = value;
setCategories([...categories]);
if (value !== undefined) {
categories[i] = value;
setCategories([...categories]);
}
}}
/>

Expand Down
43 changes: 33 additions & 10 deletions app/hooks/use-model-filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ export function useModelFilters({
hasAllData,
]);

/**
* Handles selection/deselection of items and updates URL params according to selectionMode
* @param value - The value being selected/deselected
*/
const handleSelectItemChange = useCallback(
(value: string) => {
if (selectionMode === "none") {
Expand All @@ -149,25 +153,44 @@ export function useModelFilters({
return;
}

if (selectedItems.includes(value)) {
setSelectedItems((prev) => prev.filter((item) => item !== value));
setSearchParams((prev) => {
prev.delete(model.name, value);
return prev;
});
} else {
setSelectedItems((prev) => [...prev, value]);
const isDeselecting = selectedItems.includes(value);

if (selectionMode === "set") {
// In set mode, we either set a new value or remove it completely
setSelectedItems(isDeselecting ? [] : [value]);
setSearchParams(
(prev) => {
if (selectionMode === "append") {
prev.append(model.name, value);
if (isDeselecting) {
prev.delete(model.name);
} else {
prev.set(model.name, value);
}
return prev;
},
{ preventScrollReset: true }
);
} else if (selectionMode === "append") {
// In append mode, we maintain multiple values
setSelectedItems((prev) =>
isDeselecting
? prev.filter((item) => item !== value)
: [...prev, value]
);
setSearchParams(
(prev) => {
if (isDeselecting) {
prev.delete(model.name, value);
} else {
prev.append(model.name, value);
}
return prev;
},
{ preventScrollReset: true }
);
}

if (onSelectionChange) {
onSelectionChange(isDeselecting ? [] : [value]);
}
},
[
Expand Down
5 changes: 4 additions & 1 deletion app/routes/_layout+/assets.new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,14 @@ export default function NewAssetPage() {
const title = useAtomValue(dynamicTitleAtom);
const [searchParams] = useSearchParams();
const qrId = searchParams.get("qrId");

// Get category from URL params or use the default passed prop
const categoryFromUrl = searchParams.get("category");
return (
<>
<Header title={title ? title : "Untitled Asset"} />
<div>
<AssetForm qrId={qrId} />
<AssetForm qrId={qrId} category={categoryFromUrl || undefined} />
</div>
</>
);
Expand Down

0 comments on commit 293e92d

Please sign in to comment.