diff --git a/packages/types/src/views.d.ts b/packages/types/src/views.d.ts index 9415f7488..6ce598168 100644 --- a/packages/types/src/views.d.ts +++ b/packages/types/src/views.d.ts @@ -1,3 +1,4 @@ +import { EViewAccess } from "@/constants/views"; import { TLogoProps } from "./common"; import { IIssueDisplayFilterOptions, @@ -7,7 +8,7 @@ import { export interface IProjectView { id: string; - access: string; + access: EViewAccess; created_at: Date; updated_at: Date; is_favorite: boolean; @@ -23,4 +24,6 @@ export interface IProjectView { project: string; workspace: string; logo_props: TLogoProps | undefined; + is_locked: boolean; + owned_by: string; } diff --git a/packages/types/src/workspace-views.d.ts b/packages/types/src/workspace-views.d.ts index e270f4f69..5bc900767 100644 --- a/packages/types/src/workspace-views.d.ts +++ b/packages/types/src/workspace-views.d.ts @@ -1,3 +1,4 @@ +import { EViewAccess } from "@/constants/views"; import { IWorkspaceViewProps, IIssueDisplayFilterOptions, @@ -7,7 +8,7 @@ import { export interface IWorkspaceView { id: string; - access: string; + access: EViewAccess; created_at: Date; updated_at: Date; is_favorite: boolean; @@ -22,6 +23,8 @@ export interface IWorkspaceView { query_data: IWorkspaceViewProps; project: string; workspace: string; + is_locked: boolean; + owned_by: string; workspace_detail?: { id: string; name: string; diff --git a/packages/ui/src/dropdown/common/button.tsx b/packages/ui/src/dropdown/common/button.tsx index c0a4627e9..39d9cd538 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 f17a431a1..5448f7b7f 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,14 +59,15 @@ export const DropdownOptions: React.FC {({ selected }) => ( <> {renderItem ? ( - <>{renderItem({ value: option.data[option.value], selected })} + <>{renderItem({ value: keyExtractor(option), selected })} ) : ( <> - {value} + {option.value} {selected && } )} diff --git a/packages/ui/src/dropdown/dropdown.d.ts b/packages/ui/src/dropdown/dropdown.d.ts index 1f109add6..8264bda21 100644 --- a/packages/ui/src/dropdown/dropdown.d.ts +++ b/packages/ui/src/dropdown/dropdown.d.ts @@ -10,7 +10,7 @@ export interface IDropdown { disabled?: boolean; // button props - buttonContent?: (isOpen: boolean) => React.ReactNode; + buttonContent?: (isOpen: boolean, value: string | string[] | undefined) => React.ReactNode; buttonContainerClassName?: string; buttonClassName?: string; @@ -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 08bc58638..3b5135117 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 045296873..06987e10f 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]), @@ -136,7 +138,7 @@ export const Dropdown: FC = (props) => {
= (props) => { value={value} renderItem={renderItem} loader={loader} + handleClose={handleClose} />
diff --git a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx index 8f2d23820..7629812fd 100644 --- a/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx +++ b/web/app/[workspaceSlug]/(projects)/projects/(detail)/[projectId]/views/(detail)/[viewId]/header.tsx @@ -4,10 +4,11 @@ import { useCallback } from "react"; import { observer } from "mobx-react"; import Link from "next/link"; import { useParams } from "next/navigation"; +import { Earth, Lock } from "lucide-react"; // types import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOptions } from "@plane/types"; // ui -import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon } from "@plane/ui"; +import { Breadcrumbs, Button, CustomMenu, PhotoFilterIcon, Tooltip } from "@plane/ui"; // components import { BreadcrumbLink, Logo } from "@/components/common"; import { DisplayFiltersSelection, FiltersDropdown, FilterSelection, LayoutSelection } from "@/components/issues"; @@ -19,6 +20,7 @@ import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT, } from "@/constants/issue"; import { EUserProjectRoles } from "@/constants/project"; +import { EViewAccess } from "@/constants/views"; // helpers import { calculateTotalFilters } from "@/helpers/filter.helper"; import { truncateText } from "@/helpers/string.helper"; @@ -205,54 +207,64 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => { } /> + +
+ + {viewDetails?.access === EViewAccess.PUBLIC ? : } + +
- handleLayoutChange(layout)} - selectedLayout={activeLayout} - /> + {!viewDetails?.is_locked && ( + <> + handleLayoutChange(layout)} + selectedLayout={activeLayout} + /> - - - - - - + + + + + + + + )} {canUserCreateIssue && (
- <> - - - - - - - + {!isLocked && ( + <> + + + + + + + + )} {isAuthorizedUser && ( - - )} -
+ {!isDefaultView && ( + + )} + + ); }); diff --git a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx index 291c031b3..c99343bb7 100644 --- a/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx +++ b/web/core/components/issues/issue-layouts/filters/applied-filters/roots/project-view-root.tsx @@ -1,18 +1,22 @@ "use client"; +import { useState } from "react"; +import cloneDeep from "lodash/cloneDeep"; import isEmpty from "lodash/isEmpty"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; -import { IIssueFilterOptions } from "@plane/types"; -// hooks -import { Button } from "@plane/ui"; -import { AppliedFiltersList } from "@/components/issues"; -import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; -import { useIssues, useLabel, useProjectState, useProjectView } from "@/hooks/store"; -import { getAreFiltersEqual } from "../../../utils"; -// components -// ui // types +import { IIssueFilterOptions } from "@plane/types"; +// components +import { AppliedFiltersList } from "@/components/issues"; +import { CreateUpdateProjectViewModal } from "@/components/views"; +import { UpdateViewComponent } from "@/components/views/update-view-component"; +// constants +import { EIssueFilterType, EIssuesStoreType } from "@/constants/issue"; +import { EUserWorkspaceRoles } from "@/constants/workspace"; +// hooks +import { useIssues, useLabel, useProjectView, useUser } from "@/hooks/store"; +import { getAreFiltersEqual } from "../../../utils"; export const ProjectViewAppliedFiltersRoot: React.FC = observer(() => { // router @@ -22,8 +26,13 @@ export const ProjectViewAppliedFiltersRoot: React.FC = observer(() => { issuesFilter: { issueFilters, updateFilters }, } = useIssues(EIssuesStoreType.PROJECT_VIEW); const { projectLabels } = useLabel(); - const { projectStates } = useProjectState(); const { viewMap, updateView } = useProjectView(); + const { + data, + membership: { currentWorkspaceRole }, + } = useUser(); + + const [isModalOpen, setIsModalOpen] = useState(false); // derived values const viewDetails = viewId ? viewMap[viewId.toString()] : null; const userFilters = issueFilters?.filters; @@ -81,46 +90,56 @@ export const ProjectViewAppliedFiltersRoot: React.FC = observer(() => { }; const areFiltersEqual = getAreFiltersEqual(appliedFilters, issueFilters, viewDetails); - + const viewFilters = { + filters: cloneDeep(appliedFilters ?? {}), + display_filters: cloneDeep(issueFilters?.displayFilters), + display_properties: cloneDeep(issueFilters?.displayProperties), + }; // return if no filters are applied if (isEmpty(appliedFilters) && areFiltersEqual) return null; const handleUpdateView = () => { if (!workspaceSlug || !projectId || !viewId || !viewDetails) return; - updateView(workspaceSlug.toString(), projectId.toString(), viewId.toString(), { - filters: { - ...(appliedFilters ?? {}), - }, - display_filters: { - ...issueFilters?.displayFilters, - }, - display_properties: { - ...issueFilters?.displayProperties, - }, - }); + updateView(workspaceSlug.toString(), projectId.toString(), viewId.toString(), viewFilters); }; + const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER; + + const isLocked = !!viewDetails?.is_locked; + const isOwner = viewDetails?.owned_by === data?.id; + return (
+ setIsModalOpen(false)} + workspaceSlug={workspaceSlug.toString()} + projectId={projectId.toString()} + preLoadedData={{ + name: `${viewDetails?.name} 2`, + description: viewDetails?.description, + logo_props: viewDetails?.logo_props, + ...viewFilters, + }} + />
- - {!areFiltersEqual && ( -
- -
- )} +
); }); diff --git a/web/core/components/issues/issue-layouts/utils.tsx b/web/core/components/issues/issue-layouts/utils.tsx index 6314d5beb..7840bb462 100644 --- a/web/core/components/issues/issue-layouts/utils.tsx +++ b/web/core/components/issues/issue-layouts/utils.tsx @@ -4,6 +4,7 @@ import { extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tre import clone from "lodash/clone"; import concat from "lodash/concat"; import isEqual from "lodash/isEqual"; +import isNil from "lodash/isNil"; import pull from "lodash/pull"; import uniq from "lodash/uniq"; import scrollIntoView from "smooth-scroll-into-view-if-needed"; @@ -21,6 +22,7 @@ import { IIssueFilters, IProjectView, TGroupedIssues, + IWorkspaceView, } from "@plane/types"; // ui import { Avatar, CycleGroupIcon, DiceIcon, PriorityIcon, StateGroupIcon } from "@plane/ui"; @@ -570,11 +572,24 @@ export const handleGroupDragDrop = async ( export const getAreFiltersEqual = ( appliedFilters: IIssueFilterOptions | undefined, issueFilters: IIssueFilters | undefined, - viewDetails: IProjectView | null -) => - isEqual(appliedFilters ?? {}, viewDetails?.filters ?? {}) && - isEqual(issueFilters?.displayFilters ?? {}, viewDetails?.display_filters ?? {}) && - isEqual(issueFilters?.displayProperties ?? {}, viewDetails?.display_properties ?? {}); + viewDetails: IProjectView | IWorkspaceView | null +) => { + if (isNil(appliedFilters) || isNil(issueFilters) || isNil(viewDetails)) return true; + + return ( + isEqual(appliedFilters, viewDetails.filters) && + isEqual(issueFilters.displayFilters, viewDetails.display_filters) && + isEqual(removeNillKeys(issueFilters.displayProperties), removeNillKeys(viewDetails.display_properties)) + ); +}; + +/** + * method that removes Null or undefined Keys from object + * @param obj + * @returns + */ +export const removeNillKeys = (obj: T) => + Object.fromEntries(Object.entries(obj ?? {}).filter(([key, value]) => key && !isNil(value))); /** * This Method returns if the the grouped values are subGrouped diff --git a/web/core/components/pages/editor/header/extra-options.tsx b/web/core/components/pages/editor/header/extra-options.tsx index bd022eed2..06c0579e4 100644 --- a/web/core/components/pages/editor/header/extra-options.tsx +++ b/web/core/components/pages/editor/header/extra-options.tsx @@ -2,13 +2,14 @@ import { useState } from "react"; import { observer } from "mobx-react"; -import { Lock, Sparkle } from "lucide-react"; +import { Sparkle } from "lucide-react"; // editor import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor"; // ui import { ArchiveIcon } from "@plane/ui"; // components import { GptAssistantPopover } from "@/components/core"; +import { LockedComponent } from "@/components/icons/locked-component"; import { PageInfoPopover, PageOptionsDropdown } from "@/components/pages"; // helpers import { renderFormattedDate } from "@/helpers/date-time.helper"; @@ -40,12 +41,7 @@ export const PageExtraOptions: React.FC = observer((props) => { return (
- {is_locked && ( -
- - Locked -
- )} + {is_locked && } {archived_at && (
diff --git a/web/core/components/views/form.tsx b/web/core/components/views/form.tsx index 9a43cd2a9..4371481df 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; @@ -190,7 +191,7 @@ export const ProjectViewForm: React.FC = observer((props) => { /> )} /> - {errors?.name?.message} + {errors?.name?.message?.toString()}
@@ -211,7 +212,17 @@ export const ProjectViewForm: React.FC = observer((props) => { )} />
-
+
+ ( + onChange(selectedValue)} + value={value} + /> + )} + /> ) => void; + handleUpdateView: () => void; + lockedTooltipContent?: string; +}; + +export const UpdateViewComponent = (props: Props) => { + const { + isLocked, + areFiltersEqual, + isOwner, + isAuthorizedUser, + setIsModalOpen, + handleUpdateView, + lockedTooltipContent, + } = props; + + const [isUpdating, setIsUpdating] = useState(false); + + useEffect(() => { + if (areFiltersEqual) { + setIsUpdating(false); + } + }, [areFiltersEqual]); + + // Change state while updating view to have a feedback + const updateButton = isUpdating ? ( + + ) : ( + + ); + + return ( +
+ {isLocked ? ( + + ) : ( + !areFiltersEqual && + isAuthorizedUser && ( + <> + + {isOwner && <>{updateButton}} + + ) + )} +
+ ); +}; diff --git a/web/core/components/views/view-list-item-action.tsx b/web/core/components/views/view-list-item-action.tsx index 66f9a0622..b7d37e3d7 100644 --- a/web/core/components/views/view-list-item-action.tsx +++ b/web/core/components/views/view-list-item-action.tsx @@ -1,14 +1,16 @@ import React, { FC, useState } from "react"; import { observer } from "mobx-react"; import { useParams } from "next/navigation"; +import { Earth, Lock } from "lucide-react"; // types import { IProjectView } from "@plane/types"; // ui -import { FavoriteStar } from "@plane/ui"; +import { Tooltip, FavoriteStar } from "@plane/ui"; // components import { DeleteProjectViewModal, CreateUpdateProjectViewModal, ViewQuickActions } from "@/components/views"; // constants import { EUserProjectRoles } from "@/constants/project"; +import { EViewAccess } from "@/constants/views"; // helpers import { calculateTotalFilters } from "@/helpers/filter.helper"; // hooks @@ -39,6 +41,8 @@ export const ViewListItemAction: FC = observer((props) => { const totalFilters = calculateTotalFilters(view.filters ?? {}); + const access = view.access; + // handlers const handleAddToFavorites = () => { if (!workspaceSlug || !projectId) return; @@ -70,8 +74,14 @@ export const ViewListItemAction: FC = observer((props) => { {totalFilters} {totalFilters === 1 ? "filter" : "filters"}

+
+ + {access === EViewAccess.PUBLIC ? : } + +
+ {/* created by */} - {createdByDetails && } + {} {isEditingAllowed && ( = observer((props) => { }, ]; + const isSelected = viewId === globalViewId; + const isPrivateView = view.access === EViewAccess.PRIVATE; + + let customButton = ( +
+ + {view.name} + + {isPrivateView && ( + + )} +
+ ); + + if (!isSelected) { + customButton = ( + + {customButton} + + ); + } + return ( <> setUpdateViewModal(false)} /> @@ -85,38 +114,7 @@ export const WorkspaceViewQuickActions: React.FC = observer((props) => { - - {viewId === globalViewId ? ( - - {view.name} - - ) : ( - - - {view.name} - - - )} - - } - placement="bottom-end" - menuItemsClassName="z-20" - closeOnSelect - > + {MENU_ITEMS.map((item) => { if (item.shouldRender === false) return null; return ( diff --git a/web/core/constants/issue.ts b/web/core/constants/issue.ts index 95a761e54..0e2a04b78 100644 --- a/web/core/constants/issue.ts +++ b/web/core/constants/issue.ts @@ -138,17 +138,34 @@ export const ISSUE_EXTRA_OPTIONS: { { key: "show_empty_groups", title: "Show empty groups" }, // filter on front-end ]; +export const ISSUE_LAYOUT_MAP = { + [EIssueLayoutTypes.LIST]: { key: EIssueLayoutTypes.LIST, title: "List Layout", label: "List", icon: List }, + [EIssueLayoutTypes.KANBAN]: { key: EIssueLayoutTypes.KANBAN, title: "Kanban Layout", label: "Kanban", icon: Kanban }, + [EIssueLayoutTypes.CALENDAR]: { + key: EIssueLayoutTypes.CALENDAR, + title: "Calendar Layout", + label: "Calendar", + icon: Calendar, + }, + [EIssueLayoutTypes.SPREADSHEET]: { + key: EIssueLayoutTypes.SPREADSHEET, + title: "Spreadsheet Layout", + label: "Spreadsheet", + icon: Sheet, + }, + [EIssueLayoutTypes.GANTT]: { + key: EIssueLayoutTypes.GANTT, + title: "Gantt Chart Layout", + label: "Gantt", + icon: GanttChartSquare, + }, +}; + export const ISSUE_LAYOUTS: { key: EIssueLayoutTypes; title: string; icon: any; -}[] = [ - { key: EIssueLayoutTypes.LIST, title: "List Layout", icon: List }, - { key: EIssueLayoutTypes.KANBAN, title: "Kanban Layout", icon: Kanban }, - { key: EIssueLayoutTypes.CALENDAR, title: "Calendar Layout", icon: Calendar }, - { key: EIssueLayoutTypes.SPREADSHEET, title: "Spreadsheet Layout", icon: Sheet }, - { key: EIssueLayoutTypes.GANTT, title: "Gantt Chart Layout", icon: GanttChartSquare }, -]; +}[] = Object.values(ISSUE_LAYOUT_MAP); export interface ILayoutDisplayFiltersOptions { filters: (keyof IIssueFilterOptions)[]; diff --git a/web/core/constants/views.ts b/web/core/constants/views.ts new file mode 100644 index 000000000..aab38da3f --- /dev/null +++ b/web/core/constants/views.ts @@ -0,0 +1,4 @@ +export enum EViewAccess { + PRIVATE, + PUBLIC, +} diff --git a/web/core/store/issue/project-views/filter.store.ts b/web/core/store/issue/project-views/filter.store.ts index 40169e89c..a82bfd8f8 100644 --- a/web/core/store/issue/project-views/filter.store.ts +++ b/web/core/store/issue/project-views/filter.store.ts @@ -240,10 +240,6 @@ export class ProjectViewIssuesFilter extends IssueFilterHelperStore implements I ); } - await this.issueFilterService.patchView(workspaceSlug, projectId, viewId, { - display_filters: _filters.displayFilters, - }); - break; } case EIssueFilterType.DISPLAY_PROPERTIES: { @@ -260,9 +256,6 @@ export class ProjectViewIssuesFilter extends IssueFilterHelperStore implements I }); }); - await this.issueFilterService.patchView(workspaceSlug, projectId, viewId, { - display_properties: _filters.displayProperties, - }); break; } case EIssueFilterType.KANBAN_FILTERS: { diff --git a/web/core/store/issue/workspace/filter.store.ts b/web/core/store/issue/workspace/filter.store.ts index 7bf2d9cd9..8ac69e7fd 100644 --- a/web/core/store/issue/workspace/filter.store.ts +++ b/web/core/store/issue/workspace/filter.store.ts @@ -249,11 +249,6 @@ export class WorkspaceIssuesFilter extends IssueFilterHelperStore implements IWo this.handleIssuesLocalFilters.set(EIssuesStoreType.GLOBAL, type, workspaceSlug, undefined, viewId, { display_filters: _filters.displayFilters, }); - else - await this.issueFilterService.updateView(workspaceSlug, viewId, { - display_filters: _filters.displayFilters, - }); - break; } case EIssueFilterType.DISPLAY_PROPERTIES: { @@ -268,15 +263,11 @@ export class WorkspaceIssuesFilter extends IssueFilterHelperStore implements IWo updatedDisplayProperties[_key as keyof IIssueDisplayProperties] ); }); + if (["all-issues", "assigned", "created", "subscribed"].includes(viewId)) + this.handleIssuesLocalFilters.set(EIssuesStoreType.GLOBAL, type, workspaceSlug, undefined, viewId, { + display_properties: _filters.displayProperties, + }); }); - if (["all-issues", "assigned", "created", "subscribed"].includes(viewId)) - this.handleIssuesLocalFilters.set(EIssuesStoreType.GLOBAL, type, workspaceSlug, undefined, viewId, { - display_properties: _filters.displayProperties, - }); - else - await this.issueFilterService.updateView(workspaceSlug, viewId, { - display_properties: _filters.displayProperties, - }); break; }