diff --git a/apps/remix/app/components/general/webhook-multiselect-combobox.tsx b/apps/remix/app/components/general/webhook-multiselect-combobox.tsx
index d9f7bea62..fb2219c2a 100644
--- a/apps/remix/app/components/general/webhook-multiselect-combobox.tsx
+++ b/apps/remix/app/components/general/webhook-multiselect-combobox.tsx
@@ -1,96 +1,43 @@
-import { useEffect, useState } from 'react';
-
-import { Plural, Trans } from '@lingui/react/macro';
import { WebhookTriggerEvents } from '@prisma/client';
-import { Check, ChevronsUpDown } from 'lucide-react';
import { toFriendlyWebhookEventName } from '@documenso/lib/universal/webhook/to-friendly-webhook-event-name';
-import { cn } from '@documenso/ui/lib/utils';
-import { Button } from '@documenso/ui/primitives/button';
-import {
- Command,
- CommandEmpty,
- CommandGroup,
- CommandInput,
- CommandItem,
-} from '@documenso/ui/primitives/command';
-import { Popover, PopoverContent, PopoverTrigger } from '@documenso/ui/primitives/popover';
-
-import { truncateTitle } from '~/utils/truncate-title';
+import { MultipleSelector } from '@documenso/ui/primitives/multiselect';
type WebhookMultiSelectComboboxProps = {
listValues: string[];
onChange: (_values: string[]) => void;
};
+const triggerEvents = Object.values(WebhookTriggerEvents).map((value) => ({
+ value,
+ label: toFriendlyWebhookEventName(value),
+}));
+
export const WebhookMultiSelectCombobox = ({
listValues,
onChange,
}: WebhookMultiSelectComboboxProps) => {
- const [isOpen, setIsOpen] = useState(false);
- const [selectedValues, setSelectedValues] = useState([]);
-
- const triggerEvents = Object.values(WebhookTriggerEvents);
-
- useEffect(() => {
- setSelectedValues(listValues);
- }, [listValues]);
-
- const allEvents = [...new Set([...triggerEvents, ...selectedValues])];
-
- const handleSelect = (currentValue: string) => {
- let newSelectedValues;
-
- if (selectedValues.includes(currentValue)) {
- newSelectedValues = selectedValues.filter((value) => value !== currentValue);
- } else {
- newSelectedValues = [...selectedValues, currentValue];
- }
-
- setSelectedValues(newSelectedValues);
- onChange(newSelectedValues);
- setIsOpen(false);
+ const handleOnChange = (options: { value: string; label: string }[]) => {
+ onChange(options.map((option) => option.value));
};
+ const mappedValues = listValues.map((value) => ({
+ value,
+ label: toFriendlyWebhookEventName(value),
+ }));
+
return (
-
-
-
-
-
-
- toFriendlyWebhookEventName(v)).join(', '),
- 15,
- )}
- />
-
- No value found.
-
-
- {allEvents.map((value: string, i: number) => (
- handleSelect(value)}>
-
- {toFriendlyWebhookEventName(value)}
-
- ))}
-
-
-
-
+ No triggers available
}
+ />
);
};
diff --git a/packages/ui/primitives/multiselect.tsx b/packages/ui/primitives/multiselect.tsx
new file mode 100644
index 000000000..03ae7c7cb
--- /dev/null
+++ b/packages/ui/primitives/multiselect.tsx
@@ -0,0 +1,587 @@
+import * as React from 'react';
+import { forwardRef, useEffect } from 'react';
+
+import { Command as CommandPrimitive, useCommandState } from 'cmdk';
+import { X } from 'lucide-react';
+
+import { cn } from '../lib/utils';
+import { Command, CommandGroup, CommandItem, CommandList } from './command';
+
+export interface Option {
+ value: string;
+ label: string;
+ disable?: boolean;
+ fixed?: boolean;
+ [key: string]: string | boolean | undefined;
+}
+interface GroupOption {
+ [key: string]: Option[];
+}
+
+interface MultipleSelectorProps {
+ value?: Option[];
+ defaultOptions?: Option[];
+ options?: Option[];
+ placeholder?: string;
+ loadingIndicator?: React.ReactNode;
+ emptyIndicator?: React.ReactNode;
+ delay?: number;
+ triggerSearchOnFocus?: boolean;
+ onSearch?: (value: string) => Promise