From 724a99a2fc0c944dbe39e2f5b0a0a348cdf8aa5e Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Fri, 22 May 2026 17:31:26 +0300 Subject: [PATCH 1/2] chore: add the dropdown service to the api repo --- .../portal/src/services/api.ts | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/apps/edr-freight-web/portal/src/services/api.ts b/apps/edr-freight-web/portal/src/services/api.ts index 999bf6ced..e368ed675 100644 --- a/apps/edr-freight-web/portal/src/services/api.ts +++ b/apps/edr-freight-web/portal/src/services/api.ts @@ -12,6 +12,15 @@ import { bookingsService } from "./bookings.service"; import { consignmentsService } from "./consignments.service"; import { trackingService } from "./tracking.service"; import { fileUploadSettingsService } from "./fileUploadSettings.service"; +import { dropdownSettingsService } from "./dropdownSettings.service"; +import { + CreateDropdownOptionDto, + CreateDropdownSettingDto, + DropdownOption, + DropdownSetting, + UpdateDropdownOptionDto, + UpdateDropdownSettingDto, +} from "@/types/dropdownSettings"; // --------------------------------------------------------------------------- // API definition @@ -135,4 +144,69 @@ export const api = { ({ fieldId }) => fileUploadSettingsService.removeField(fieldId), ), }, + + dropdownSettings: { + list: endpoint( + "dropdown-settings", + "list", + dropdownSettingsService.list, + ), + + getById: endpoint<{ id: string }, DropdownSetting>( + "dropdown-settings", + "getById", + ({ id }) => dropdownSettingsService.getById(id), + ), + + getByCode: endpoint<{ code: string }, DropdownSetting>( + "dropdown-settings", + "getByCode", + ({ code }) => dropdownSettingsService.getByCode(code), + ), + + create: endpoint( + "dropdown-settings", + "create", + (payload) => dropdownSettingsService.create(payload), + ), + + update: endpoint< + { id: string; dto: UpdateDropdownSettingDto }, + DropdownSetting + >("dropdown-settings", "update", ({ id, dto }) => + dropdownSettingsService.update(id, dto), + ), + + remove: endpoint<{ id: string }, void>( + "dropdown-settings", + "remove", + ({ id }) => dropdownSettingsService.remove(id), + ), + replaceOptions: endpoint< + { id: string; options: CreateDropdownOptionDto[] }, + DropdownOption[] + >("dropdown-settings", "replaceOptions", ({ id, options }) => + dropdownSettingsService.replaceOptions(id, options), + ), + + addOption: endpoint< + { id: string; dto: CreateDropdownOptionDto }, + DropdownOption + >("dropdown-settings", "addOption", ({ id, dto }) => + dropdownSettingsService.addOption(id, dto), + ), + + updateOption: endpoint< + { optionId: string; dto: UpdateDropdownOptionDto }, + DropdownOption + >("dropdown-settings", "updateOption", ({ optionId, dto }) => + dropdownSettingsService.updateOption(optionId, dto), + ), + + removeOption: endpoint<{ optionId: string }, void>( + "dropdown-settings", + "removeOption", + ({ optionId }) => dropdownSettingsService.removeOption(optionId), + ), + }, }; From bf4d9550f16303a1dc77f4e98f6b6296f7298367 Mon Sep 17 00:00:00 2001 From: ghost2023 Date: Fri, 22 May 2026 17:32:35 +0300 Subject: [PATCH 2/2] feat: implemented dynamic select --- .../dynamic-select/DynamicSelect.tsx | 99 +++++++++++++++++++ .../src/components/dynamic-select/index.ts | 2 + 2 files changed, 101 insertions(+) create mode 100644 apps/edr-freight-web/portal/src/components/dynamic-select/DynamicSelect.tsx create mode 100644 apps/edr-freight-web/portal/src/components/dynamic-select/index.ts diff --git a/apps/edr-freight-web/portal/src/components/dynamic-select/DynamicSelect.tsx b/apps/edr-freight-web/portal/src/components/dynamic-select/DynamicSelect.tsx new file mode 100644 index 000000000..2003457f0 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/dynamic-select/DynamicSelect.tsx @@ -0,0 +1,99 @@ +import { useQuery } from "@tanstack/react-query"; +import { cn } from "@/lib/utils"; +import { api } from "@/services/api"; +import { Loader2, AlertCircle } from "lucide-react"; +import * as React from "react"; + +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@edr/ui-common"; + +export interface DynamicSelectProps { + code: string; + placeholder?: string; + value?: string; + onValueChange?: (value: string) => void; + disabled?: boolean; + className?: string; +} + +export function DynamicSelect({ + code, + placeholder, + value, + onValueChange, + disabled, + className, +}: DynamicSelectProps) { + const { data, isLoading, isError } = useQuery( + api.dropdownSettings.getByCode.queryOptions({ input: { code } }), + ); + + if (isLoading) { + return ( +
+ + Loading... +
+ ); + } + + if (isError || !data) { + return ( +
+ + Failed to load options +
+ ); + } + + const options = [...data.children].sort((a, b) => a.order - b.order); + + return ( + + ); +} diff --git a/apps/edr-freight-web/portal/src/components/dynamic-select/index.ts b/apps/edr-freight-web/portal/src/components/dynamic-select/index.ts new file mode 100644 index 000000000..4e6c58b62 --- /dev/null +++ b/apps/edr-freight-web/portal/src/components/dynamic-select/index.ts @@ -0,0 +1,2 @@ +export { DynamicSelect } from "./DynamicSelect"; +export type { DynamicSelectProps } from "./DynamicSelect";