chore: stabilising the views

This commit is contained in:
gurusainath 2024-02-13 12:28:05 +05:30
parent badb190c25
commit 608eea67f7
19 changed files with 132 additions and 205 deletions

View File

@ -1,10 +1,9 @@
import { FC } from "react"; import { FC } from "react";
import { ImagePlus, X } from "lucide-react"; import { ImagePlus, X } from "lucide-react";
// hooks // hooks
import { useViewFilter } from "hooks/store"; import { useViewDetail, useViewFilter } from "hooks/store";
// types // types
import { TViewFilters, TViewTypes } from "@plane/types"; import { TViewFilters, TViewTypes } from "@plane/types";
import { TViewOperations } from "../types";
type TViewAppliedFiltersItem = { type TViewAppliedFiltersItem = {
workspaceSlug: string; workspaceSlug: string;
@ -13,18 +12,18 @@ type TViewAppliedFiltersItem = {
viewType: TViewTypes; viewType: TViewTypes;
filterKey: keyof TViewFilters; filterKey: keyof TViewFilters;
propertyId: string; propertyId: string;
viewOperations: TViewOperations;
}; };
export const ViewAppliedFiltersItem: FC<TViewAppliedFiltersItem> = (props) => { export const ViewAppliedFiltersItem: FC<TViewAppliedFiltersItem> = (props) => {
const { workspaceSlug, projectId, filterKey, propertyId, viewOperations } = props; const { workspaceSlug, projectId, viewId, viewType, filterKey, propertyId } = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const viewFilterHelper = useViewFilter(workspaceSlug, projectId); const viewFilterHelper = useViewFilter(workspaceSlug, projectId);
const propertyDetail = viewFilterHelper?.propertyDetails(filterKey, propertyId) || undefined; const propertyDetail = viewFilterHelper?.propertyDetails(filterKey, propertyId) || undefined;
const removeFilterOption = () => { const removeFilterOption = () => {
viewOperations?.setFilters(filterKey, propertyId); viewDetailStore?.setFilters(filterKey, propertyId);
}; };
return ( return (

View File

@ -8,7 +8,6 @@ import { useViewDetail, useViewFilter } from "hooks/store";
import { ViewAppliedFiltersItem } from "./filter-item"; import { ViewAppliedFiltersItem } from "./filter-item";
// types // types
import { TViewFilters, TViewTypes } from "@plane/types"; import { TViewFilters, TViewTypes } from "@plane/types";
import { TViewOperations } from "../types";
type TViewAppliedFilters = { type TViewAppliedFilters = {
workspaceSlug: string; workspaceSlug: string;
@ -16,12 +15,11 @@ type TViewAppliedFilters = {
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
filterKey: keyof TViewFilters; filterKey: keyof TViewFilters;
viewOperations: TViewOperations;
propertyVisibleCount?: number | undefined; propertyVisibleCount?: number | undefined;
}; };
export const ViewAppliedFilters: FC<TViewAppliedFilters> = observer((props) => { export const ViewAppliedFilters: FC<TViewAppliedFilters> = observer((props) => {
const { workspaceSlug, projectId, viewId, viewType, filterKey, viewOperations, propertyVisibleCount } = props; const { workspaceSlug, projectId, viewId, viewType, filterKey, propertyVisibleCount } = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const viewFilterStore = useViewFilter(workspaceSlug, projectId); const viewFilterStore = useViewFilter(workspaceSlug, projectId);
@ -58,7 +56,6 @@ export const ViewAppliedFilters: FC<TViewAppliedFilters> = observer((props) => {
viewType={viewType} viewType={viewType}
filterKey={filterKey} filterKey={filterKey}
propertyId={propertyId} propertyId={propertyId}
viewOperations={viewOperations}
/> />
</Fragment> </Fragment>
))} ))}

View File

@ -8,37 +8,27 @@ import { useViewDetail } from "hooks/store";
import { ViewAppliedFilters } from "./filter"; import { ViewAppliedFilters } from "./filter";
// types // types
import { TViewTypes, TViewFilters } from "@plane/types"; import { TViewTypes, TViewFilters } from "@plane/types";
import { TViewOperations } from "../types";
type TViewAppliedFiltersRoot = { type TViewAppliedFiltersRoot = {
workspaceSlug: string; workspaceSlug: string;
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
propertyVisibleCount?: number | undefined; propertyVisibleCount?: number | undefined;
showClearAll?: boolean; showClearAll?: boolean;
}; };
export const ViewAppliedFiltersRoot: FC<TViewAppliedFiltersRoot> = observer((props) => { export const ViewAppliedFiltersRoot: FC<TViewAppliedFiltersRoot> = observer((props) => {
const { const { workspaceSlug, projectId, viewId, viewType, propertyVisibleCount = undefined, showClearAll = false } = props;
workspaceSlug,
projectId,
viewId,
viewType,
viewOperations,
propertyVisibleCount = undefined,
showClearAll = false,
} = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const filterKeys = const filterKeys =
viewDetailStore?.appliedFilters && !isEmpty(viewDetailStore?.appliedFilters?.filters) viewDetailStore?.filtersToUpdate && !isEmpty(viewDetailStore?.filtersToUpdate?.filters)
? Object.keys(viewDetailStore?.appliedFilters?.filters) ? Object.keys(viewDetailStore?.filtersToUpdate?.filters)
: undefined; : undefined;
const clearAllFilters = () => viewOperations?.setFilters(undefined, "clear_all"); const clearAllFilters = () => viewDetailStore?.setFilters(undefined, "clear_all");
if (!filterKeys || !viewDetailStore?.isFiltersApplied) if (!filterKeys || !viewDetailStore?.isFiltersApplied)
return ( return (
@ -58,7 +48,6 @@ export const ViewAppliedFiltersRoot: FC<TViewAppliedFiltersRoot> = observer((pro
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
filterKey={filterKey} filterKey={filterKey}
viewOperations={viewOperations}
propertyVisibleCount={propertyVisibleCount} propertyVisibleCount={propertyVisibleCount}
/> />
</Fragment> </Fragment>

View File

@ -11,7 +11,6 @@ import { ViewDisplayPropertiesRoot } from "../";
// ui // ui
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
// types // types
import { TViewOperations } from "../types";
import { TViewTypes } from "@plane/types"; import { TViewTypes } from "@plane/types";
type TViewDisplayFiltersDropdown = { type TViewDisplayFiltersDropdown = {
@ -19,7 +18,6 @@ type TViewDisplayFiltersDropdown = {
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
children?: ReactNode; children?: ReactNode;
displayDropdownText?: boolean; displayDropdownText?: boolean;
dropdownPlacement?: Placement; dropdownPlacement?: Placement;
@ -31,7 +29,6 @@ export const ViewDisplayFiltersDropdown: FC<TViewDisplayFiltersDropdown> = obser
projectId, projectId,
viewId, viewId,
viewType, viewType,
viewOperations,
children, children,
displayDropdownText = true, displayDropdownText = true,
dropdownPlacement = "bottom-start", dropdownPlacement = "bottom-start",
@ -121,7 +118,6 @@ export const ViewDisplayFiltersDropdown: FC<TViewDisplayFiltersDropdown> = obser
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
/> />
</div> </div>

View File

@ -4,25 +4,23 @@ import { observer } from "mobx-react-lite";
import { useViewDetail } from "hooks/store"; import { useViewDetail } from "hooks/store";
// types // types
import { TViewDisplayProperties, TViewTypes } from "@plane/types"; import { TViewDisplayProperties, TViewTypes } from "@plane/types";
import { TViewOperations } from "../types";
type TViewDisplayPropertySelection = { type TViewDisplayPropertySelection = {
workspaceSlug: string; workspaceSlug: string;
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
property: keyof TViewDisplayProperties; property: keyof TViewDisplayProperties;
}; };
export const ViewDisplayPropertySelection: FC<TViewDisplayPropertySelection> = observer((props) => { export const ViewDisplayPropertySelection: FC<TViewDisplayPropertySelection> = observer((props) => {
const { workspaceSlug, projectId, viewId, viewType, viewOperations, property } = props; const { workspaceSlug, projectId, viewId, viewType, property } = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const propertyIsSelected = viewDetailStore?.appliedFilters?.display_properties?.[property]; const propertyIsSelected = viewDetailStore?.appliedFilters?.display_properties?.[property];
const handlePropertySelection = () => viewOperations?.setDisplayProperties(property); const handlePropertySelection = () => viewDetailStore?.setDisplayProperties(property);
return ( return (
<div <div

View File

@ -4,18 +4,16 @@ import { observer } from "mobx-react-lite";
import { ViewDisplayPropertySelection } from "../"; import { ViewDisplayPropertySelection } from "../";
// types // types
import { TViewDisplayProperties, TViewTypes } from "@plane/types"; import { TViewDisplayProperties, TViewTypes } from "@plane/types";
import { TViewOperations } from "../types";
type TViewDisplayPropertiesRoot = { type TViewDisplayPropertiesRoot = {
workspaceSlug: string; workspaceSlug: string;
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
}; };
export const ViewDisplayPropertiesRoot: FC<TViewDisplayPropertiesRoot> = observer((props) => { export const ViewDisplayPropertiesRoot: FC<TViewDisplayPropertiesRoot> = observer((props) => {
const { workspaceSlug, projectId, viewId, viewType, viewOperations } = props; const { workspaceSlug, projectId, viewId, viewType } = props;
const displayProperties: Partial<keyof TViewDisplayProperties>[] = [ const displayProperties: Partial<keyof TViewDisplayProperties>[] = [
"key", "key",
@ -40,7 +38,6 @@ export const ViewDisplayPropertiesRoot: FC<TViewDisplayPropertiesRoot> = observe
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
property={property} property={property}
/> />
</Fragment> </Fragment>

View File

@ -11,7 +11,6 @@ import { ViewFiltersRoot } from "../";
// ui // ui
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
// types // types
import { TViewOperations } from "../types";
import { TViewTypes } from "@plane/types"; import { TViewTypes } from "@plane/types";
type TViewFiltersDropdown = { type TViewFiltersDropdown = {
@ -19,7 +18,6 @@ type TViewFiltersDropdown = {
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
children?: ReactNode; children?: ReactNode;
displayDropdownText?: boolean; displayDropdownText?: boolean;
dropdownPlacement?: Placement; dropdownPlacement?: Placement;
@ -31,7 +29,6 @@ export const ViewFiltersDropdown: FC<TViewFiltersDropdown> = observer((props) =>
projectId, projectId,
viewId, viewId,
viewType, viewType,
viewOperations,
children, children,
displayDropdownText = true, displayDropdownText = true,
dropdownPlacement = "bottom-start", dropdownPlacement = "bottom-start",
@ -133,7 +130,6 @@ export const ViewFiltersDropdown: FC<TViewFiltersDropdown> = observer((props) =>
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
dateCustomFilterToggle={dateCustomFilterToggle} dateCustomFilterToggle={dateCustomFilterToggle}
setDateCustomFilterToggle={setDateCustomFilterToggle} setDateCustomFilterToggle={setDateCustomFilterToggle}
/> />

View File

@ -50,20 +50,22 @@ export const ViewFiltersEditDropdown: FC<TViewFiltersEditDropdown> = observer((p
// dropdown options // dropdown options
const dropdownOptions: TViewFilterEditDropdownOptions[] = useMemo( const dropdownOptions: TViewFilterEditDropdownOptions[] = useMemo(
() => [ () => [
{ // {
icon: PhotoFilterIcon, // icon: PhotoFilterIcon,
key: "save_as_new", // key: "save_as_new",
label: "Save as new view", // label: "Save as new view",
onClick: () => viewOperations.update(), // onClick: () => {
}, // viewOperations.localViewCreateEdit(undefined, viewDetailStore?.filtersToUpdate);
// },
// },
{ {
icon: RotateCcw, icon: RotateCcw,
key: "reset_changes", key: "reset_changes",
label: "Reset changes", label: "Reset changes",
onClick: () => viewOperations.resetChanges(), onClick: () => viewDetailStore?.resetChanges(),
}, },
], ],
[viewOperations] [viewOperations, viewDetailStore]
); );
if (!viewDetailStore?.isFiltersUpdateEnabled) return <></>; if (!viewDetailStore?.isFiltersUpdateEnabled) return <></>;

View File

@ -6,7 +6,6 @@ import { useViewDetail, useViewFilter } from "hooks/store";
import { ViewFiltersItem, ViewFilterSelection } from "../"; import { ViewFiltersItem, ViewFilterSelection } from "../";
import { DateFilterModal } from "components/core"; import { DateFilterModal } from "components/core";
// types // types
import { TViewOperations } from "../types";
import { TViewFilters, TViewTypes } from "@plane/types"; import { TViewFilters, TViewTypes } from "@plane/types";
type TViewFiltersItemRoot = { type TViewFiltersItemRoot = {
@ -14,23 +13,14 @@ type TViewFiltersItemRoot = {
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
filterKey: keyof TViewFilters; filterKey: keyof TViewFilters;
dateCustomFilterToggle: string | undefined; dateCustomFilterToggle: string | undefined;
setDateCustomFilterToggle: (value: string | undefined) => void; setDateCustomFilterToggle: (value: string | undefined) => void;
}; };
export const ViewFiltersItemRoot: FC<TViewFiltersItemRoot> = observer((props) => { export const ViewFiltersItemRoot: FC<TViewFiltersItemRoot> = observer((props) => {
const { const { workspaceSlug, projectId, viewId, viewType, filterKey, dateCustomFilterToggle, setDateCustomFilterToggle } =
workspaceSlug, props;
projectId,
viewId,
viewType,
viewOperations,
filterKey,
dateCustomFilterToggle,
setDateCustomFilterToggle,
} = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const viewFilterHelper = useViewFilter(workspaceSlug, projectId); const viewFilterHelper = useViewFilter(workspaceSlug, projectId);
@ -47,15 +37,15 @@ export const ViewFiltersItemRoot: FC<TViewFiltersItemRoot> = observer((props) =>
const _propertyIds = viewDetailStore?.appliedFilters?.filters?.[filterKey] || []; const _propertyIds = viewDetailStore?.appliedFilters?.filters?.[filterKey] || [];
const selectedDates = _propertyIds.filter((id) => id.includes("-")); const selectedDates = _propertyIds.filter((id) => id.includes("-"));
if (selectedDates.length > 0) if (selectedDates.length > 0)
selectedDates.forEach((date: string) => viewOperations?.setFilters(filterKey, date)); selectedDates.forEach((date: string) => viewDetailStore?.setFilters(filterKey, date));
else setDateCustomFilterToggle(filterKey); else setDateCustomFilterToggle(filterKey);
} else viewOperations?.setFilters(filterKey, _propertyId); } else viewDetailStore?.setFilters(filterKey, _propertyId);
} else viewOperations?.setFilters(filterKey, _propertyId); } else viewDetailStore?.setFilters(filterKey, _propertyId);
}; };
const handleCustomDateSelection = (selectedDates: string[]) => { const handleCustomDateSelection = (selectedDates: string[]) => {
selectedDates.forEach((date: string) => { selectedDates.forEach((date: string) => {
viewOperations?.setFilters(filterKey, date); viewDetailStore?.setFilters(filterKey, date);
setDateCustomFilterToggle(undefined); setDateCustomFilterToggle(undefined);
}); });
}; };

View File

@ -9,7 +9,6 @@ import { useViewDetail } from "hooks/store";
// components // components
import { ViewFiltersItemRoot } from "../"; import { ViewFiltersItemRoot } from "../";
// types // types
import { TViewOperations } from "../types";
import { TViewFilters, TViewTypes } from "@plane/types"; import { TViewFilters, TViewTypes } from "@plane/types";
import { VIEW_DEFAULT_FILTER_PARAMETERS } from "constants/view"; import { VIEW_DEFAULT_FILTER_PARAMETERS } from "constants/view";
@ -18,21 +17,12 @@ type TViewFiltersRoot = {
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
dateCustomFilterToggle: string | undefined; dateCustomFilterToggle: string | undefined;
setDateCustomFilterToggle: (value: string | undefined) => void; setDateCustomFilterToggle: (value: string | undefined) => void;
}; };
export const ViewFiltersRoot: FC<TViewFiltersRoot> = observer((props) => { export const ViewFiltersRoot: FC<TViewFiltersRoot> = observer((props) => {
const { const { workspaceSlug, projectId, viewId, viewType, dateCustomFilterToggle, setDateCustomFilterToggle } = props;
workspaceSlug,
projectId,
viewId,
viewType,
viewOperations,
dateCustomFilterToggle,
setDateCustomFilterToggle,
} = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
// state // state
@ -70,7 +60,6 @@ export const ViewFiltersRoot: FC<TViewFiltersRoot> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
filterKey={filterKey} filterKey={filterKey}
dateCustomFilterToggle={dateCustomFilterToggle} dateCustomFilterToggle={dateCustomFilterToggle}
setDateCustomFilterToggle={setDateCustomFilterToggle} setDateCustomFilterToggle={setDateCustomFilterToggle}

View File

@ -7,14 +7,12 @@ import { useViewDetail } from "hooks/store";
import { Tooltip } from "@plane/ui"; import { Tooltip } from "@plane/ui";
// types // types
import { TViewLayouts, TViewTypes } from "@plane/types"; import { TViewLayouts, TViewTypes } from "@plane/types";
import { TViewOperations } from "./types";
type TViewLayoutRoot = { type TViewLayoutRoot = {
workspaceSlug: string; workspaceSlug: string;
projectId: string | undefined; projectId: string | undefined;
viewId: string; viewId: string;
viewType: TViewTypes; viewType: TViewTypes;
viewOperations: TViewOperations;
}; };
const LAYOUTS_DATA: { key: TViewLayouts; title: string; icon: LucideIcon }[] = [ const LAYOUTS_DATA: { key: TViewLayouts; title: string; icon: LucideIcon }[] = [
@ -26,10 +24,11 @@ const LAYOUTS_DATA: { key: TViewLayouts; title: string; icon: LucideIcon }[] = [
]; ];
export const ViewLayoutRoot: FC<TViewLayoutRoot> = observer((props) => { export const ViewLayoutRoot: FC<TViewLayoutRoot> = observer((props) => {
const { workspaceSlug, projectId, viewId, viewType, viewOperations } = props; const { workspaceSlug, projectId, viewId, viewType } = props;
// hooks // hooks
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
if (!viewDetailStore) return <></>;
return ( return (
<div className="relative flex gap-0.5 items-center bg-custom-background-80 rounded p-1 shadow-custom-shadow-2xs"> <div className="relative flex gap-0.5 items-center bg-custom-background-80 rounded p-1 shadow-custom-shadow-2xs">
{LAYOUTS_DATA.map((layout) => ( {LAYOUTS_DATA.map((layout) => (
@ -43,7 +42,7 @@ export const ViewLayoutRoot: FC<TViewLayoutRoot> = observer((props) => {
: `hover:bg-custom-background-100` : `hover:bg-custom-background-100`
} }
`} `}
onClick={() => viewOperations.setDisplayFilters({ layout: layout.key })} onClick={() => viewDetailStore.setDisplayFilters({ layout: layout.key })}
> >
<layout.icon size={12} /> <layout.icon size={12} />
</div> </div>

View File

@ -1,7 +1,9 @@
import { FC, Fragment, useEffect, useMemo, useState } from "react"; import { FC, Fragment, useEffect, useMemo, useState } from "react";
import Link from "next/link"; import Link from "next/link";
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import { CheckCircle, Pencil } from "lucide-react"; import { CheckCircle } from "lucide-react";
import { v4 as uuidV4 } from "uuid";
import cloneDeep from "lodash/cloneDeep";
// hooks // hooks
import { useView, useViewDetail } from "hooks/store"; import { useView, useViewDetail } from "hooks/store";
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
@ -24,7 +26,7 @@ import { Spinner } from "@plane/ui";
import { viewLocalPayload } from "constants/view"; import { viewLocalPayload } from "constants/view";
// types // types
import { TViewOperations } from "./types"; import { TViewOperations } from "./types";
import { TView, TViewFilters, TViewDisplayFilters, TViewDisplayProperties, TViewTypes } from "@plane/types"; import { TView, TViewTypes } from "@plane/types";
type TGlobalViewRoot = { type TGlobalViewRoot = {
workspaceSlug: string; workspaceSlug: string;
@ -63,11 +65,19 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
const viewOperations: TViewOperations = useMemo( const viewOperations: TViewOperations = useMemo(
() => ({ () => ({
localViewCreateEdit: (viewId: string | undefined) => { localViewCreateEdit: (viewId: string | undefined, currentView = undefined) => {
if (viewId === undefined) { if (viewId === undefined) {
const viewPayload = viewLocalPayload; if (currentView !== undefined) {
handleViewOperationsToggle("CREATE", viewPayload.id); // creating new view
viewStore?.localViewCreate(viewPayload as TView); const currentViewPayload = cloneDeep({ ...currentView, id: uuidV4() });
handleViewOperationsToggle("CREATE", currentViewPayload.id);
viewStore?.localViewCreate(currentViewPayload as TView);
} else {
// if current view is available, create a new view with the same data
const viewPayload = viewLocalPayload;
handleViewOperationsToggle("CREATE", viewPayload.id);
viewStore?.localViewCreate(viewPayload as TView);
}
} else { } else {
handleViewOperationsToggle("EDIT", viewId); handleViewOperationsToggle("EDIT", viewId);
viewDetailCreateEditStore?.setIsEditable(true); viewDetailCreateEditStore?.setIsEditable(true);
@ -75,35 +85,9 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
}, },
localViewCreateEditClear: async (viewId: string | undefined) => { localViewCreateEditClear: async (viewId: string | undefined) => {
if (viewDetailCreateEditStore?.is_create && viewId) viewStore?.remove(viewId); if (viewDetailCreateEditStore?.is_create && viewId) viewStore?.remove(viewId);
if (viewDetailCreateEditStore?.is_editable && viewId) viewDetailCreateEditStore.resetChanges();
handleViewOperationsToggle(undefined, undefined); handleViewOperationsToggle(undefined, undefined);
}, },
resetChanges: () => viewDetailStore?.resetChanges(),
setName: (name: string) => {
if (viewOperationsToggle.type && ["CREATE", "EDIT"].includes(viewOperationsToggle.type))
viewDetailCreateEditStore?.setName(name);
else viewDetailStore?.setName(name);
},
setDescription: (name: string) => {
if (viewOperationsToggle.type && ["CREATE", "EDIT"].includes(viewOperationsToggle.type))
viewDetailCreateEditStore?.setDescription(name);
else viewDetailStore?.setDescription(name);
},
setFilters: (filterKey: keyof TViewFilters | undefined, filterValue: "clear_all" | string) => {
if (viewOperationsToggle.type && ["CREATE", "EDIT"].includes(viewOperationsToggle.type))
viewDetailCreateEditStore?.setFilters(filterKey, filterValue);
else viewDetailStore?.setFilters(filterKey, filterValue);
},
setDisplayFilters: (display_filters: Partial<TViewDisplayFilters>) => {
if (viewOperationsToggle.type && ["CREATE", "EDIT"].includes(viewOperationsToggle.type))
viewDetailCreateEditStore?.setDisplayFilters(display_filters);
else viewDetailStore?.setDisplayFilters(display_filters);
},
setDisplayProperties: (displayPropertyKey: keyof TViewDisplayProperties) => {
if (viewOperationsToggle.type && ["CREATE", "EDIT"].includes(viewOperationsToggle.type))
viewDetailCreateEditStore?.setDisplayProperties(displayPropertyKey);
else viewDetailStore?.setDisplayProperties(displayPropertyKey);
},
fetch: async () => { fetch: async () => {
try { try {
@ -168,7 +152,7 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
} }
}, },
}), }),
[viewStore, viewDetailStore, setToastAlert, viewOperationsToggle, viewDetailCreateEditStore] [viewStore, viewDetailStore, setToastAlert, viewDetailCreateEditStore]
); );
// fetch all views // fetch all views
@ -243,19 +227,12 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
propertyVisibleCount={5} propertyVisibleCount={5}
/> />
</div> </div>
<div className="flex-shrink-0"> <div className="flex-shrink-0">
<ViewLayoutRoot <ViewLayoutRoot workspaceSlug={workspaceSlug} projectId={projectId} viewId={viewId} viewType={viewType} />
workspaceSlug={workspaceSlug}
projectId={projectId}
viewId={viewId}
viewType={viewType}
viewOperations={viewOperations}
/>
</div> </div>
<div className="flex-shrink-0"> <div className="flex-shrink-0">
@ -264,7 +241,6 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
displayDropdownText={false} displayDropdownText={false}
/> />
</div> </div>
@ -275,12 +251,16 @@ export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
displayDropdownText={false} displayDropdownText={false}
/> />
</div> </div>
<ViewEditDropdown viewId={viewId} viewOperations={viewOperations} /> <ViewEditDropdown
workspaceSlug={workspaceSlug}
projectId={projectId}
viewId={viewId}
viewOperations={viewOperations}
/>
<ViewFiltersEditDropdown <ViewFiltersEditDropdown
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}

View File

@ -1,17 +1,10 @@
import { LucideIcon } from "lucide-react"; import { LucideIcon } from "lucide-react";
// types // types
import { TView, TViewFilters, TViewDisplayFilters, TViewDisplayProperties } from "@plane/types"; import { TView, TUpdateView } from "@plane/types";
export type TViewOperations = { export type TViewOperations = {
localViewCreateEdit: (viewId: string | undefined) => void; localViewCreateEdit: (viewId: string | undefined, currentView?: TUpdateView | undefined) => void;
localViewCreateEditClear: (viewId: string | undefined) => Promise<void>; localViewCreateEditClear: (viewId: string | undefined) => Promise<void>;
resetChanges: () => void;
setName: (name: string) => void;
setDescription: (description: string) => void;
setFilters: (filterKey: keyof TViewFilters | undefined, filterValue: "clear_all" | string) => void;
setDisplayFilters: (display_filters: Partial<TViewDisplayFilters>) => void;
setDisplayProperties: (displayPropertyKey: keyof TViewDisplayProperties) => void;
fetch: () => Promise<void>; fetch: () => Promise<void>;
create: (data: Partial<TView>) => Promise<void>; create: (data: Partial<TView>) => Promise<void>;

View File

@ -23,7 +23,7 @@ type TViewCreateEditForm = {
export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => { export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
const { workspaceSlug, projectId, viewId, viewType, viewOperations } = props; const { workspaceSlug, projectId, viewId, viewType, viewOperations } = props;
// hooks // hooks
const currentViewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType); const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
const { getProjectById } = useProject(); const { getProjectById } = useProject();
// states // states
const [modalToggle, setModalToggle] = useState(false); const [modalToggle, setModalToggle] = useState(false);
@ -43,12 +43,12 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
const onContinue = async () => { const onContinue = async () => {
setLoader(true); setLoader(true);
if (currentViewDetailStore?.is_create) { if (viewDetailStore?.is_create) {
const payload = currentViewDetailStore?.filtersToUpdate; const payload = viewDetailStore?.filtersToUpdate;
await viewOperations.create(payload); await viewOperations.create(payload);
modalClose(); modalClose();
} else { } else {
const payload = currentViewDetailStore?.filtersToUpdate; const payload = viewDetailStore?.filtersToUpdate;
if (!payload) return; if (!payload) return;
await viewOperations.update(); await viewOperations.update();
modalClose(); modalClose();
@ -58,7 +58,7 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
const projectDetails = projectId ? getProjectById(projectId) : undefined; const projectDetails = projectId ? getProjectById(projectId) : undefined;
if (!currentViewDetailStore?.id) return <></>; if (!viewDetailStore) return <></>;
return ( return (
<Transition.Root show={modalToggle} as={Fragment}> <Transition.Root show={modalToggle} as={Fragment}>
<Dialog as="div" className="relative z-20" onClose={modalClose}> <Dialog as="div" className="relative z-20" onClose={modalClose}>
@ -110,9 +110,9 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
id="name" id="name"
name="name" name="name"
type="text" type="text"
value={currentViewDetailStore?.filtersToUpdate?.name || ""} value={viewDetailStore?.filtersToUpdate?.name || ""}
onChange={(e) => { onChange={(e) => {
viewOperations?.setName(e.target.value); viewDetailStore?.setName(e.target.value);
}} }}
placeholder="What do you want to call this view?" placeholder="What do you want to call this view?"
className="h-[46px] w-full border border-onboarding-border-100 pr-12 placeholder:text-onboarding-text-400" className="h-[46px] w-full border border-onboarding-border-100 pr-12 placeholder:text-onboarding-text-400"
@ -126,7 +126,6 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
dropdownPlacement="right" dropdownPlacement="right"
> >
<div className="cursor-pointer relative rounded p-1.5 px-2 flex items-center gap-1 border border-custom-border-100 bg-custom-background-80"> <div className="cursor-pointer relative rounded p-1.5 px-2 flex items-center gap-1 border border-custom-border-100 bg-custom-background-80">
@ -136,17 +135,19 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
<div className="text-xs">Filters</div> <div className="text-xs">Filters</div>
</div> </div>
</ViewFiltersDropdown> </ViewFiltersDropdown>
<div {viewDetailStore?.isFiltersApplied && (
className="cursor-pointer relative rounded p-1.5 px-2 flex items-center gap-1 border border-dashed border-custom-border-100 bg-custom-background-80" <div
onClick={() => { className="cursor-pointer relative rounded p-1.5 px-2 flex items-center gap-1 border border-dashed border-custom-border-100 bg-custom-background-80"
viewOperations.setFilters(undefined, "clear_all"); onClick={() => {
}} viewDetailStore.setFilters(undefined, "clear_all");
> }}
<div className="text-xs">Clear all filters</div> >
<div className="flex-shrink-0 relative flex justify-center items-center w-4 h-4 overflow-hidden"> <div className="text-xs">Clear all filters</div>
<X className="w-3 h-3" /> <div className="flex-shrink-0 relative flex justify-center items-center w-4 h-4 overflow-hidden">
<X className="w-3 h-3" />
</div>
</div> </div>
</div> )}
</div> </div>
<div className="p-3 px-5 relative bg-custom-background-90 max-h-36 overflow-hidden overflow-y-auto"> <div className="p-3 px-5 relative bg-custom-background-90 max-h-36 overflow-hidden overflow-y-auto">
@ -155,7 +156,6 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
projectId={projectId} projectId={projectId}
viewId={viewId} viewId={viewId}
viewType={viewType} viewType={viewType}
viewOperations={viewOperations}
propertyVisibleCount={undefined} propertyVisibleCount={undefined}
/> />
</div> </div>
@ -165,7 +165,7 @@ export const ViewCreateEditForm: FC<TViewCreateEditForm> = observer((props) => {
Cancel Cancel
</Button> </Button>
<Button variant="primary" onClick={onContinue} disabled={loader}> <Button variant="primary" onClick={onContinue} disabled={loader}>
{loader ? `Saving...` : `${currentViewDetailStore?.is_create ? `Create` : `Update`} View`} {loader ? `Saving...` : `${viewDetailStore?.is_create ? `Create` : `Update`} View`}
</Button> </Button>
</div> </div>
</Dialog.Panel> </Dialog.Panel>

View File

@ -7,6 +7,8 @@ import { Copy, Eye, Globe2, Link2, Pencil, Trash } from "lucide-react";
import { TViewEditDropdownOptions, TViewOperations } from "../types"; import { TViewEditDropdownOptions, TViewOperations } from "../types";
type TViewEditDropdown = { type TViewEditDropdown = {
workspaceSlug: string;
projectId: string | undefined;
viewId: string; viewId: string;
viewOperations: TViewOperations; viewOperations: TViewOperations;
}; };
@ -47,49 +49,49 @@ export const ViewEditDropdown: FC<TViewEditDropdown> = observer((props) => {
onClick: () => viewOperations.localViewCreateEdit(viewId), onClick: () => viewOperations.localViewCreateEdit(viewId),
children: undefined, children: undefined,
}, },
{ // {
icon: Eye, // icon: Eye,
key: "accessability", // key: "accessability",
label: "Change Accessability", // label: "Change Accessability",
onClick: () => {}, // onClick: () => {},
children: [ // children: [
{ // {
icon: Eye, // icon: Eye,
key: "private", // key: "private",
label: "Private", // label: "Private",
onClick: () => viewOperations.create({}), // onClick: () => viewOperations.create({}),
children: undefined, // children: undefined,
}, // },
{ // {
icon: Globe2, // icon: Globe2,
key: "public", // key: "public",
label: "Public", // label: "Public",
onClick: () => viewOperations.create({}), // onClick: () => viewOperations.create({}),
children: undefined, // children: undefined,
}, // },
], // ],
}, // },
{ // {
icon: Copy, // icon: Copy,
key: "duplicate", // key: "duplicate",
label: "Duplicate view", // label: "Duplicate view",
onClick: () => viewOperations.remove(viewId), // onClick: () => viewOperations.remove(viewId),
children: undefined, // children: undefined,
}, // },
{ // {
icon: Link2, // icon: Link2,
key: "copy_link", // key: "copy_link",
label: "Copy view link", // label: "Copy view link",
onClick: () => viewOperations.remove(viewId), // onClick: () => viewOperations.remove(viewId),
children: undefined, // children: undefined,
}, // },
{ // {
icon: Trash, // icon: Trash,
key: "delete", // key: "delete",
label: "Delete view", // label: "Delete view",
onClick: () => viewOperations.remove(viewId), // onClick: () => viewOperations.remove(viewId),
children: undefined, // children: undefined,
}, // },
], ],
[viewOperations, viewId] [viewOperations, viewId]
); );

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
// layouts // layouts
import { AppLayout } from "layouts/app-layout"; import { AppLayout } from "layouts/app-layout";
// components // components
import { AllIssuesViewRoot } from "components/view"; import { GlobalViewRoot } from "components/view";
// types // types
import { NextPageWithLayout } from "lib/types"; import { NextPageWithLayout } from "lib/types";
// constants // constants
@ -33,7 +33,7 @@ const ProjectPrivateViewPage: NextPageWithLayout = () => {
return ( return (
<div className="h-full overflow-hidden bg-custom-background-100"> <div className="h-full overflow-hidden bg-custom-background-100">
<div className="flex h-full w-full flex-col border-b border-custom-border-300"> <div className="flex h-full w-full flex-col border-b border-custom-border-300">
<AllIssuesViewRoot <GlobalViewRoot
workspaceSlug={workspaceSlug.toString()} workspaceSlug={workspaceSlug.toString()}
projectId={projectId.toString()} projectId={projectId.toString()}
viewId={viewId.toString()} viewId={viewId.toString()}

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
// layouts // layouts
import { AppLayout } from "layouts/app-layout"; import { AppLayout } from "layouts/app-layout";
// components // components
import { AllIssuesViewRoot } from "components/view"; import { GlobalViewRoot } from "components/view";
// types // types
import { NextPageWithLayout } from "lib/types"; import { NextPageWithLayout } from "lib/types";
// constants // constants
@ -33,7 +33,7 @@ const ProjectPrivateViewPage: NextPageWithLayout = () => {
return ( return (
<div className="h-full overflow-hidden bg-custom-background-100"> <div className="h-full overflow-hidden bg-custom-background-100">
<div className="flex h-full w-full flex-col border-b border-custom-border-300"> <div className="flex h-full w-full flex-col border-b border-custom-border-300">
<AllIssuesViewRoot <GlobalViewRoot
workspaceSlug={workspaceSlug.toString()} workspaceSlug={workspaceSlug.toString()}
projectId={projectId.toString()} projectId={projectId.toString()}
viewId={viewId.toString()} viewId={viewId.toString()}

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
// layouts // layouts
import { AppLayout } from "layouts/app-layout"; import { AppLayout } from "layouts/app-layout";
// components // components
import { AllIssuesViewRoot } from "components/view"; import { GlobalViewRoot } from "components/view";
// types // types
import { NextPageWithLayout } from "lib/types"; import { NextPageWithLayout } from "lib/types";
// constants // constants
@ -33,7 +33,7 @@ const ProjectPublicViewPage: NextPageWithLayout = () => {
return ( return (
<div className="w-full h-full overflow-hidden bg-custom-background-100 relative flex flex-col"> <div className="w-full h-full overflow-hidden bg-custom-background-100 relative flex flex-col">
<div className="flex-shrink-0 w-full"> <div className="flex-shrink-0 w-full">
<AllIssuesViewRoot <GlobalViewRoot
workspaceSlug={workspaceSlug.toString()} workspaceSlug={workspaceSlug.toString()}
projectId={undefined} projectId={undefined}
viewId={viewId.toString()} viewId={viewId.toString()}

View File

@ -3,7 +3,7 @@ import { useRouter } from "next/router";
// layouts // layouts
import { AppLayout } from "layouts/app-layout"; import { AppLayout } from "layouts/app-layout";
// components // components
import { AllIssuesViewRoot } from "components/view"; import { GlobalViewRoot } from "components/view";
// types // types
import { NextPageWithLayout } from "lib/types"; import { NextPageWithLayout } from "lib/types";
// constants // constants
@ -33,7 +33,7 @@ const WorkspacePrivateViewPage: NextPageWithLayout = () => {
return ( return (
<div className="h-full overflow-hidden bg-custom-background-100"> <div className="h-full overflow-hidden bg-custom-background-100">
<div className="flex h-full w-full flex-col border-b border-custom-border-300"> <div className="flex h-full w-full flex-col border-b border-custom-border-300">
<AllIssuesViewRoot <GlobalViewRoot
workspaceSlug={workspaceSlug.toString()} workspaceSlug={workspaceSlug.toString()}
projectId={undefined} projectId={undefined}
viewId={viewId.toString()} viewId={viewId.toString()}