From 32b4019a6912e7ed07ec8748788bbabc394bf1ab Mon Sep 17 00:00:00 2001 From: rahulramesha Date: Wed, 19 Jun 2024 16:32:31 +0530 Subject: [PATCH] add Layout options while creating a new view --- packages/types/src/views.d.ts | 3 +++ packages/ui/src/dropdown/common/button.tsx | 2 +- packages/ui/src/dropdown/common/options.tsx | 6 +++-- packages/ui/src/dropdown/dropdown.d.ts | 8 ++++--- packages/ui/src/dropdown/multi-select.tsx | 10 ++++---- packages/ui/src/dropdown/single-select.tsx | 13 +++++++---- web/core/components/dropdowns/layout.tsx | 26 +++++++++++++++++++++ web/core/components/views/form.tsx | 21 +++++++++++++---- web/core/constants/issue.ts | 16 +++++++------ 9 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 web/core/components/dropdowns/layout.tsx diff --git a/packages/types/src/views.d.ts b/packages/types/src/views.d.ts index 9415f7488f..fae52f8188 100644 --- a/packages/types/src/views.d.ts +++ b/packages/types/src/views.d.ts @@ -13,6 +13,9 @@ export interface IProjectView { is_favorite: boolean; created_by: string; updated_by: string; + isLocked: boolean | null; + isPrivate: boolean | null; + isPublished: boolean | null; name: string; description: string; filters: IIssueFilterOptions; diff --git a/packages/ui/src/dropdown/common/button.tsx b/packages/ui/src/dropdown/common/button.tsx index c0a4627e9f..39d9cd5383 100644 --- a/packages/ui/src/dropdown/common/button.tsx +++ b/packages/ui/src/dropdown/common/button.tsx @@ -31,7 +31,7 @@ export const DropdownButton: React.FC - {buttonContent ? <>{buttonContent(isOpen)} : {value}} + {buttonContent ? <>{buttonContent(isOpen, value)} : {value}} ); diff --git a/packages/ui/src/dropdown/common/options.tsx b/packages/ui/src/dropdown/common/options.tsx index f17a431a14..dac14359bf 100644 --- a/packages/ui/src/dropdown/common/options.tsx +++ b/packages/ui/src/dropdown/common/options.tsx @@ -22,6 +22,7 @@ export const DropdownOptions: React.FC ( cn( "flex w-full cursor-pointer select-none items-center justify-between gap-2 truncate rounded px-1 py-1.5", @@ -58,6 +59,7 @@ export const DropdownOptions: React.FC {({ selected }) => ( <> @@ -65,7 +67,7 @@ export const DropdownOptions: React.FC{renderItem({ value: option.data[option.value], selected })} ) : ( <> - {value} + {option.value} {selected && } )} diff --git a/packages/ui/src/dropdown/dropdown.d.ts b/packages/ui/src/dropdown/dropdown.d.ts index 1f109add6f..e55a4f8ce8 100644 --- a/packages/ui/src/dropdown/dropdown.d.ts +++ b/packages/ui/src/dropdown/dropdown.d.ts @@ -24,8 +24,8 @@ export interface IDropdown { // options props keyExtractor: (option: TDropdownOption) => string; optionsContainerClassName?: string; - queryArray: string[]; - sortByKey: string; + queryArray?: string[]; + sortByKey?: string; firstItem?: (optionValue: string) => boolean; renderItem?: ({ value, selected }: { value: string; selected: boolean }) => React.ReactNode; loader?: React.ReactNode; @@ -52,7 +52,7 @@ export interface ISingleSelectDropdown extends IDropdown { export interface IDropdownButton { isOpen: boolean; - buttonContent?: (isOpen: boolean) => React.ReactNode; + buttonContent?: (isOpen: boolean, value: string | string[] | undefined) => React.ReactNode; buttonClassName?: string; buttonContainerClassName?: string; handleOnClick: (e: React.MouseEvent) => void; @@ -79,6 +79,8 @@ export interface IDropdownOptions { inputContainerClassName?: string; disableSearch?: boolean; + handleClose?: () => void; + keyExtractor: (option: TDropdownOption) => string; renderItem: (({ value, selected }: { value: string; selected: boolean }) => React.ReactNode) | undefined; options: TDropdownOption[] | undefined; diff --git a/packages/ui/src/dropdown/multi-select.tsx b/packages/ui/src/dropdown/multi-select.tsx index 08bc586386..3b51351173 100644 --- a/packages/ui/src/dropdown/multi-select.tsx +++ b/packages/ui/src/dropdown/multi-select.tsx @@ -90,10 +90,12 @@ export const MultiSelectDropdown: FC = (props) => { const sortedOptions = useMemo(() => { if (!options) return undefined; - const filteredOptions = (options || []).filter((options) => { - const queryString = queryArray.map((query) => options.data[query]).join(" "); - return queryString.toLowerCase().includes(query.toLowerCase()); - }); + const filteredOptions = queryArray + ? (options || []).filter((options) => { + const queryString = queryArray.map((query) => options.data[query]).join(" "); + return queryString.toLowerCase().includes(query.toLowerCase()); + }) + : options; if (disableSorting) return filteredOptions; diff --git a/packages/ui/src/dropdown/single-select.tsx b/packages/ui/src/dropdown/single-select.tsx index 045296873f..4a5a5e1141 100644 --- a/packages/ui/src/dropdown/single-select.tsx +++ b/packages/ui/src/dropdown/single-select.tsx @@ -90,12 +90,14 @@ export const Dropdown: FC = (props) => { const sortedOptions = useMemo(() => { if (!options) return undefined; - const filteredOptions = (options || []).filter((options) => { - const queryString = queryArray.map((query) => options.data[query]).join(" "); - return queryString.toLowerCase().includes(query.toLowerCase()); - }); + const filteredOptions = queryArray + ? (options || []).filter((options) => { + const queryString = queryArray.map((query) => options.data[query]).join(" "); + return queryString.toLowerCase().includes(query.toLowerCase()); + }) + : options; - if (disableSorting) return filteredOptions; + if (disableSorting || !sortByKey) return filteredOptions; return sortBy(filteredOptions, [ (option) => firstItem && firstItem(option.data[option.value]), @@ -157,6 +159,7 @@ export const Dropdown: FC = (props) => { value={value} renderItem={renderItem} loader={loader} + handleClose={handleClose} /> diff --git a/web/core/components/dropdowns/layout.tsx b/web/core/components/dropdowns/layout.tsx new file mode 100644 index 0000000000..ec66329cf9 --- /dev/null +++ b/web/core/components/dropdowns/layout.tsx @@ -0,0 +1,26 @@ +import { observer } from "mobx-react"; +import { Dropdown } from "@plane/ui"; +import { EIssueLayoutTypes, ISSUE_LAYOUT_MAP } from "@/constants/issue"; + +type TLayoutDropDown = { + onChange: (value: EIssueLayoutTypes) => void; + value: EIssueLayoutTypes; +}; +export const LayoutDropDown = observer((props: TLayoutDropDown) => { + const { onChange, value = EIssueLayoutTypes.LIST } = props; + + const options = Object.values(ISSUE_LAYOUT_MAP).map((issueLayout) => ({ + data: issueLayout.key, + value: issueLayout.key, + })); + + return ( + void} + value={value?.toString()} + keyExtractor={(option) => option.value} + options={options} + disableSearch + /> + ); +}); diff --git a/web/core/components/views/form.tsx b/web/core/components/views/form.tsx index 9a43cd2a9c..b950eb78c3 100644 --- a/web/core/components/views/form.tsx +++ b/web/core/components/views/form.tsx @@ -11,11 +11,12 @@ import { Button, EmojiIconPicker, EmojiIconPickerTypes, Input, PhotoFilterIcon, import { Logo } from "@/components/common"; import { AppliedFiltersList, FilterSelection, FiltersDropdown } from "@/components/issues"; // constants -import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { EIssueLayoutTypes, ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; // helpers import { convertHexEmojiToDecimal } from "@/helpers/emoji.helper"; // hooks import { useLabel, useMember, useProject, useProjectState } from "@/hooks/store"; +import { LayoutDropDown } from "../dropdowns/layout"; type Props = { data?: IProjectView | null; @@ -48,7 +49,7 @@ export const ProjectViewForm: React.FC = observer((props) => { reset, setValue, watch, - } = useForm({ + } = useForm({ defaultValues, }); @@ -90,13 +91,13 @@ export const ProjectViewForm: React.FC = observer((props) => { }); }; - const handleCreateUpdateView = async (formData: IProjectView) => { + const handleCreateUpdateView = async (formData: IProjectView & { layout: EIssueLayoutTypes }) => { await handleFormSubmit({ name: formData.name, description: formData.description, logo_props: formData.logo_props, filters: formData.filters, - display_filters: formData.display_filters, + display_filters: { ...formData.display_filters, layout: formData.layout }, display_properties: formData.display_properties, } as IProjectView); @@ -211,6 +212,18 @@ export const ProjectViewForm: React.FC = observer((props) => { )} /> +
+ ( + onChange(selectedValue)} + value={value} + /> + )} + /> +