2024-02-14 10:31:19 +00:00
|
|
|
import { FC, Fragment, useCallback, useEffect, useMemo, useState } from "react";
|
2024-02-16 12:58:21 +00:00
|
|
|
import { useRouter } from "next/router";
|
2024-02-05 14:39:17 +00:00
|
|
|
import { observer } from "mobx-react-lite";
|
|
|
|
// hooks
|
|
|
|
import { useView, useViewDetail } from "hooks/store";
|
|
|
|
import useToast from "hooks/use-toast";
|
|
|
|
// components
|
2024-02-08 18:11:30 +00:00
|
|
|
import {
|
|
|
|
ViewRoot,
|
|
|
|
ViewCreateEditForm,
|
2024-02-12 07:00:59 +00:00
|
|
|
ViewEditDropdown,
|
2024-02-08 18:11:30 +00:00
|
|
|
ViewLayoutRoot,
|
|
|
|
ViewFiltersDropdown,
|
2024-02-12 07:00:59 +00:00
|
|
|
ViewFiltersEditDropdown,
|
2024-02-08 18:11:30 +00:00
|
|
|
ViewDisplayFiltersDropdown,
|
|
|
|
ViewAppliedFiltersRoot,
|
|
|
|
ViewDuplicateConfirmationModal,
|
|
|
|
ViewDeleteConfirmationModal,
|
2024-02-16 12:58:21 +00:00
|
|
|
} from "./";
|
2024-02-05 14:39:17 +00:00
|
|
|
// ui
|
2024-02-16 12:58:21 +00:00
|
|
|
import { Loader } from "@plane/ui";
|
2024-02-05 14:39:17 +00:00
|
|
|
// constants
|
2024-02-16 12:58:21 +00:00
|
|
|
import {
|
|
|
|
ELocalViews,
|
|
|
|
EViewLayouts,
|
|
|
|
EViewPageType,
|
|
|
|
TViewCRUD,
|
|
|
|
viewDefaultFilterParametersByViewTypeAndLayout,
|
|
|
|
} from "constants/view";
|
2024-02-05 14:39:17 +00:00
|
|
|
// types
|
|
|
|
import { TViewOperations } from "./types";
|
2024-02-16 12:58:21 +00:00
|
|
|
import { TViewTypes } from "@plane/types";
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-10 08:45:57 +00:00
|
|
|
type TGlobalViewRoot = {
|
2024-02-05 14:39:17 +00:00
|
|
|
workspaceSlug: string;
|
|
|
|
projectId: string | undefined;
|
|
|
|
viewId: string;
|
2024-02-08 18:11:30 +00:00
|
|
|
viewType: TViewTypes;
|
2024-02-13 13:11:34 +00:00
|
|
|
viewPageType: EViewPageType;
|
2024-02-08 18:11:30 +00:00
|
|
|
baseRoute: string;
|
|
|
|
};
|
|
|
|
|
|
|
|
type TViewOperationsToggle = {
|
2024-02-16 12:58:21 +00:00
|
|
|
type: "DUPLICATE" | "DELETE" | undefined;
|
2024-02-08 18:11:30 +00:00
|
|
|
viewId: string | undefined;
|
2024-02-05 14:39:17 +00:00
|
|
|
};
|
|
|
|
|
2024-02-10 08:45:57 +00:00
|
|
|
export const GlobalViewRoot: FC<TGlobalViewRoot> = observer((props) => {
|
2024-02-16 12:58:21 +00:00
|
|
|
// router
|
|
|
|
const router = useRouter();
|
2024-02-14 10:31:19 +00:00
|
|
|
const { workspaceSlug, projectId, viewId, viewType, viewPageType, baseRoute } = props;
|
2024-02-05 14:39:17 +00:00
|
|
|
// hooks
|
|
|
|
const viewStore = useView(workspaceSlug, projectId, viewType);
|
|
|
|
const viewDetailStore = useViewDetail(workspaceSlug, projectId, viewId, viewType);
|
|
|
|
const { setToastAlert } = useToast();
|
2024-02-08 18:11:30 +00:00
|
|
|
// states
|
|
|
|
const [viewOperationsToggle, setViewOperationsToggle] = useState<TViewOperationsToggle>({
|
|
|
|
type: undefined,
|
|
|
|
viewId: undefined,
|
|
|
|
});
|
2024-02-14 10:31:19 +00:00
|
|
|
const handleViewOperationsToggle = useCallback(
|
|
|
|
(type: TViewOperationsToggle["type"], viewId: string | undefined) => setViewOperationsToggle({ type, viewId }),
|
|
|
|
[]
|
|
|
|
);
|
2024-02-05 14:39:17 +00:00
|
|
|
|
|
|
|
const viewOperations: TViewOperations = useMemo(
|
|
|
|
() => ({
|
2024-02-16 12:58:21 +00:00
|
|
|
localViewCreateEdit: (viewId: string | undefined, status: TViewCRUD) => {
|
|
|
|
viewStore?.localViewHandler(viewId, status);
|
2024-02-07 06:00:06 +00:00
|
|
|
},
|
2024-02-12 07:00:59 +00:00
|
|
|
|
|
|
|
fetch: async () => {
|
|
|
|
try {
|
2024-02-14 14:36:59 +00:00
|
|
|
await viewStore?.fetch(workspaceSlug, projectId);
|
2024-02-12 07:00:59 +00:00
|
|
|
} catch {
|
|
|
|
setToastAlert({
|
|
|
|
type: "error",
|
|
|
|
title: "Error!",
|
|
|
|
message: "Something went wrong. Please try again later or contact the support team.",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2024-02-16 12:58:21 +00:00
|
|
|
create: async () => {
|
2024-02-05 14:39:17 +00:00
|
|
|
try {
|
2024-02-16 12:58:21 +00:00
|
|
|
await viewStore?.create();
|
2024-02-08 18:11:30 +00:00
|
|
|
handleViewOperationsToggle(undefined, undefined);
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "success",
|
|
|
|
title: "Success!",
|
|
|
|
message: "View created successfully.",
|
|
|
|
});
|
2024-02-07 06:00:06 +00:00
|
|
|
} catch {
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "error",
|
|
|
|
title: "Error!",
|
|
|
|
message: "Something went wrong. Please try again later or contact the support team.",
|
|
|
|
});
|
2024-02-07 06:00:06 +00:00
|
|
|
}
|
|
|
|
},
|
2024-02-16 12:58:21 +00:00
|
|
|
update: async () => {
|
|
|
|
try {
|
|
|
|
await viewDetailStore?.saveChanges();
|
|
|
|
handleViewOperationsToggle(undefined, undefined);
|
|
|
|
setToastAlert({
|
|
|
|
type: "success",
|
|
|
|
title: "Success!",
|
|
|
|
message: "View updated successfully.",
|
|
|
|
});
|
|
|
|
} catch {
|
|
|
|
setToastAlert({
|
|
|
|
type: "error",
|
|
|
|
title: "Error!",
|
|
|
|
message: "Something went wrong. Please try again later or contact the support team.",
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
2024-02-08 18:11:30 +00:00
|
|
|
remove: async (viewId: string) => {
|
2024-02-07 06:00:06 +00:00
|
|
|
try {
|
2024-02-16 12:58:21 +00:00
|
|
|
await viewStore?.remove(viewId);
|
2024-02-08 18:11:30 +00:00
|
|
|
handleViewOperationsToggle(undefined, undefined);
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "success",
|
|
|
|
title: "Success!",
|
|
|
|
message: "View removed successfully.",
|
|
|
|
});
|
2024-02-07 06:00:06 +00:00
|
|
|
} catch {
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "error",
|
|
|
|
title: "Error!",
|
|
|
|
message: "Something went wrong. Please try again later or contact the support team.",
|
|
|
|
});
|
2024-02-07 06:00:06 +00:00
|
|
|
}
|
|
|
|
},
|
2024-02-16 12:58:21 +00:00
|
|
|
duplicate: async (viewId: string) => {
|
2024-02-07 06:00:06 +00:00
|
|
|
try {
|
2024-02-16 12:58:21 +00:00
|
|
|
await viewStore?.duplicate(viewId);
|
2024-02-08 18:11:30 +00:00
|
|
|
handleViewOperationsToggle(undefined, undefined);
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "success",
|
|
|
|
title: "Success!",
|
2024-02-16 12:58:21 +00:00
|
|
|
message: "View removed successfully.",
|
2024-02-12 07:00:59 +00:00
|
|
|
});
|
2024-02-05 14:39:17 +00:00
|
|
|
} catch {
|
2024-02-12 07:00:59 +00:00
|
|
|
setToastAlert({
|
|
|
|
type: "error",
|
|
|
|
title: "Error!",
|
|
|
|
message: "Something went wrong. Please try again later or contact the support team.",
|
|
|
|
});
|
2024-02-05 14:39:17 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
}),
|
2024-02-16 12:58:21 +00:00
|
|
|
[viewStore, viewDetailStore, handleViewOperationsToggle, setToastAlert, workspaceSlug, projectId]
|
2024-02-05 14:39:17 +00:00
|
|
|
);
|
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
const applyFIltersFromRouter = () => {
|
|
|
|
if (workspaceSlug && viewId && Object.values(ELocalViews).includes(viewId as ELocalViews)) {
|
|
|
|
const routerQueryParams = { ...router.query };
|
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
|
|
const { ["workspaceSlug"]: _workspaceSlug, ["viewId"]: _viewId, ...filters } = routerQueryParams;
|
|
|
|
|
|
|
|
const acceptedFilters = viewDefaultFilterParametersByViewTypeAndLayout(
|
|
|
|
viewPageType,
|
|
|
|
EViewLayouts.SPREADSHEET,
|
|
|
|
"filters"
|
|
|
|
);
|
|
|
|
|
|
|
|
Object.keys(filters).forEach((key) => {
|
|
|
|
const filterKey: any = key;
|
|
|
|
const filterValue = filters[key]?.toString() || undefined;
|
|
|
|
if (filterKey && filterValue && acceptedFilters.includes(filterKey)) {
|
|
|
|
const _filterValues = filterValue.split(",");
|
|
|
|
_filterValues.forEach((element) => {
|
|
|
|
console.log("filterKey", filterKey);
|
|
|
|
console.log("element", element);
|
|
|
|
viewDetailStore?.setFilters(filterKey, element);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
|
|
};
|
|
|
|
|
2024-02-10 08:45:57 +00:00
|
|
|
// fetch all views
|
2024-02-05 14:39:17 +00:00
|
|
|
useEffect(() => {
|
2024-02-08 18:11:30 +00:00
|
|
|
const fetchViews = async () => {
|
2024-02-14 14:36:59 +00:00
|
|
|
await viewStore?.fetch(
|
|
|
|
workspaceSlug,
|
|
|
|
projectId,
|
2024-02-16 12:58:21 +00:00
|
|
|
viewStore?.viewIds.length > 0 ? "view-mutation-loader" : "view-loader"
|
2024-02-14 14:36:59 +00:00
|
|
|
);
|
2024-02-08 18:11:30 +00:00
|
|
|
};
|
2024-02-09 16:46:17 +00:00
|
|
|
if (workspaceSlug && viewType && viewStore) fetchViews();
|
|
|
|
}, [workspaceSlug, projectId, viewType, viewStore]);
|
2024-02-08 18:11:30 +00:00
|
|
|
|
2024-02-09 16:46:17 +00:00
|
|
|
// fetch view by id
|
|
|
|
useEffect(() => {
|
2024-02-16 12:58:21 +00:00
|
|
|
const fetchViewByViewId = async () => {
|
|
|
|
await viewStore?.fetchById(workspaceSlug, projectId, viewId);
|
|
|
|
// applyFIltersFromRouter();
|
2024-02-09 16:46:17 +00:00
|
|
|
};
|
2024-02-16 12:58:21 +00:00
|
|
|
if (workspaceSlug && viewId && viewType && viewStore) {
|
|
|
|
fetchViewByViewId();
|
|
|
|
}
|
|
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
2024-02-09 16:46:17 +00:00
|
|
|
}, [workspaceSlug, projectId, viewId, viewType, viewStore]);
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
console.log("viewStore? -->", viewStore?.viewMapCEN?.id);
|
|
|
|
|
2024-02-05 14:39:17 +00:00
|
|
|
return (
|
|
|
|
<div className="relative w-full h-full">
|
2024-02-16 12:58:21 +00:00
|
|
|
{viewStore?.loader && viewStore?.loader === "view-loader" ? (
|
|
|
|
<Loader className="relative w-full flex items-center gap-2 pt-2 pb-1 px-5 border-b border-custom-border-300">
|
|
|
|
<div>
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
<div className="border-t-2 rounded-t border-custom-primary-100" />
|
|
|
|
</div>
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
<div className="ml-auto">
|
|
|
|
<Loader.Item height="30px" width="120px" />
|
|
|
|
</div>
|
|
|
|
</Loader>
|
2024-02-05 14:39:17 +00:00
|
|
|
) : (
|
|
|
|
<>
|
2024-02-14 10:31:19 +00:00
|
|
|
<div className="border-b border-custom-border-200 pt-2">
|
2024-02-07 06:00:06 +00:00
|
|
|
<ViewRoot
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewOperations={viewOperations}
|
2024-02-08 18:11:30 +00:00
|
|
|
baseRoute={baseRoute}
|
2024-02-07 06:00:06 +00:00
|
|
|
/>
|
|
|
|
</div>
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
{viewStore?.loader === "view-detail-loader" ? (
|
|
|
|
<Loader className="relative w-full flex items-center gap-2 py-3 px-5 border-b border-custom-border-300">
|
|
|
|
<div className="mr-auto relative flex items-center gap-2">
|
|
|
|
<Loader.Item width="140px" height="30px" />
|
|
|
|
<Loader.Item width="140px" height="30px" />
|
|
|
|
<Loader.Item width="140px" height="30px" />
|
|
|
|
<Loader.Item width="140px" height="30px" />
|
|
|
|
</div>
|
|
|
|
<Loader.Item width="30px" height="30px" />
|
|
|
|
<Loader.Item width="30px" height="30px" />
|
|
|
|
<Loader.Item width="30px" height="30px" />
|
|
|
|
<Loader.Item width="120px" height="30px" />
|
|
|
|
</Loader>
|
|
|
|
) : (
|
|
|
|
<div className="p-5 py-2 border-b border-custom-border-200 relative flex items-start gap-1">
|
|
|
|
<div className="w-full overflow-hidden">
|
|
|
|
<ViewAppliedFiltersRoot
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
propertyVisibleCount={5}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<ViewLayoutRoot
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewPageType={viewPageType}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<ViewFiltersDropdown
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewPageType={viewPageType}
|
|
|
|
displayDropdownText={false}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<ViewDisplayFiltersDropdown
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewPageType={viewPageType}
|
|
|
|
displayDropdownText={false}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-05 14:39:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<ViewEditDropdown
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewOperations={viewOperations}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-09 16:46:17 +00:00
|
|
|
|
2024-02-16 12:58:21 +00:00
|
|
|
<div className="flex-shrink-0">
|
|
|
|
<ViewFiltersEditDropdown
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewId}
|
|
|
|
viewType={viewType}
|
|
|
|
viewOperations={viewOperations}
|
|
|
|
/>
|
|
|
|
</div>
|
2024-02-13 13:11:34 +00:00
|
|
|
</div>
|
2024-02-16 12:58:21 +00:00
|
|
|
)}
|
2024-02-05 14:39:17 +00:00
|
|
|
</>
|
|
|
|
)}
|
2024-02-07 06:00:06 +00:00
|
|
|
|
2024-02-08 18:11:30 +00:00
|
|
|
{/* create edit modal */}
|
2024-02-16 12:58:21 +00:00
|
|
|
{viewStore?.viewMapCEN?.id && (
|
|
|
|
<ViewCreateEditForm
|
|
|
|
workspaceSlug={workspaceSlug}
|
|
|
|
projectId={projectId}
|
|
|
|
viewId={viewStore?.viewMapCEN?.id}
|
|
|
|
viewType={viewType}
|
|
|
|
viewPageType={viewPageType}
|
|
|
|
viewOperations={viewOperations}
|
|
|
|
isLocalView={true}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
|
2024-02-08 18:11:30 +00:00
|
|
|
{viewOperationsToggle.type && viewOperationsToggle.viewId && (
|
|
|
|
<Fragment>
|
|
|
|
{["DUPLICATE"].includes(viewOperationsToggle.type) && (
|
|
|
|
<ViewDuplicateConfirmationModal viewId={viewOperationsToggle.viewId} viewOperations={viewOperations} />
|
|
|
|
)}
|
|
|
|
|
|
|
|
{["DELETE"].includes(viewOperationsToggle.type) && (
|
|
|
|
<ViewDeleteConfirmationModal viewId={viewOperationsToggle.viewId} viewOperations={viewOperations} />
|
|
|
|
)}
|
|
|
|
</Fragment>
|
2024-02-07 06:00:06 +00:00
|
|
|
)}
|
2024-02-05 14:39:17 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
});
|