diff --git a/web/app/[workspaceSlug]/(projects)/workspace-views/[globalViewId]/page.tsx b/web/app/[workspaceSlug]/(projects)/workspace-views/[globalViewId]/page.tsx index 554e82b104..95fb113cdd 100644 --- a/web/app/[workspaceSlug]/(projects)/workspace-views/[globalViewId]/page.tsx +++ b/web/app/[workspaceSlug]/(projects)/workspace-views/[globalViewId]/page.tsx @@ -34,7 +34,7 @@ const GlobalViewIssuesPage = observer(() => {
{globalViewId && } - +
diff --git a/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx b/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx index d51f614609..6f1c5156b3 100644 --- a/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx +++ b/web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx @@ -6,6 +6,7 @@ import useSWR from "swr"; import { IIssueDisplayFilterOptions } from "@plane/types"; // hooks // components +import { EmptyState } from "@/components/common"; import { SpreadsheetView } from "@/components/issues/issue-layouts"; import { AllIssueQuickActions } from "@/components/issues/issue-layouts/quick-action-dropdowns"; import { SpreadsheetLayoutLoader } from "@/components/ui"; @@ -20,17 +21,25 @@ import { import { EUserProjectRoles } from "@/constants/project"; // hooks import { useGlobalView, useIssues, useUser } from "@/hooks/store"; +import { useAppRouter } from "@/hooks/use-app-router"; import { IssuesStoreContext } from "@/hooks/use-issue-layout-store"; import { useIssuesActions } from "@/hooks/use-issues-actions"; import { useWorkspaceIssueProperties } from "@/hooks/use-workspace-issue-properties"; // store +import emptyView from "@/public/empty-state/view.svg"; import { IssuePeekOverview } from "../../peek-overview"; import { IssueLayoutHOC } from "../issue-layout-HOC"; import { TRenderQuickActions } from "../list/list-view-types"; -export const AllIssueLayoutRoot: React.FC = observer(() => { +type Props = { + isDefaultView: boolean; +}; + +export const AllIssueLayoutRoot: React.FC = observer((props: Props) => { + const { isDefaultView } = props; // router const { workspaceSlug, globalViewId } = useParams(); + const router = useAppRouter(); const searchParams = useSearchParams(); const routeFilters: { [key: string]: string; @@ -50,7 +59,9 @@ export const AllIssueLayoutRoot: React.FC = observer(() => { const { membership: { currentWorkspaceAllProjectsRole }, } = useUser(); - const { fetchAllGlobalViews } = useGlobalView(); + const { fetchAllGlobalViews, getViewDetailsById } = useGlobalView(); + + const viewDetails = getViewDetailsById(globalViewId?.toString()); // filter init from the query params const routerFilterParams = () => { @@ -86,7 +97,7 @@ export const AllIssueLayoutRoot: React.FC = observer(() => { if (workspaceSlug && globalViewId) fetchNextIssues(workspaceSlug.toString(), globalViewId.toString()); }, [fetchNextIssues, workspaceSlug, globalViewId]); - useSWR( + const { isLoading } = useSWR( workspaceSlug ? `WORKSPACE_GLOBAL_VIEWS_${workspaceSlug}` : null, async () => { if (workspaceSlug) { @@ -162,6 +173,21 @@ export const AllIssueLayoutRoot: React.FC = observer(() => { [canEditProperties, removeIssue, updateIssue, archiveIssue] ); + // when the call is not loading and the view does not exist and the view is not a default view, show empty state + if (!isLoading && !viewDetails && !isDefaultView) { + return ( + router.push(`/${workspaceSlug}/workspace-views/all-issues`), + }} + /> + ); + } + if (getIssueLoader() === "init-loader" || !globalViewId || !groupedIssueIds) { return ; } diff --git a/web/core/store/estimates/project-estimate.store.ts b/web/core/store/estimates/project-estimate.store.ts index 12d896dcb5..5c0607e2f7 100644 --- a/web/core/store/estimates/project-estimate.store.ts +++ b/web/core/store/estimates/project-estimate.store.ts @@ -5,7 +5,7 @@ import update from "lodash/update"; import { action, computed, makeObservable, observable, runInAction } from "mobx"; import { computedFn } from "mobx-utils"; // types -import { IEstimate as IEstimateType, IEstimateFormData } from "@plane/types"; +import { IEstimate as IEstimateType, IEstimateFormData, TEstimateSystemKeys } from "@plane/types"; // plane web services import estimateService from "@/plane-web/services/project/estimate.service"; // plane web store @@ -163,7 +163,12 @@ export class ProjectEstimateStore implements IProjectEstimateStore { if (estimates && estimates.length > 0) { runInAction(() => { estimates.forEach((estimate) => { - if (estimate.id) set(this.estimates, [estimate.id], new Estimate(this.store, estimate)); + if (estimate.id) + set( + this.estimates, + [estimate.id], + new Estimate(this.store, { ...estimate, type: estimate.type?.toLowerCase() as TEstimateSystemKeys }) + ); }); }); } @@ -198,7 +203,12 @@ export class ProjectEstimateStore implements IProjectEstimateStore { if (estimates && estimates.length > 0) { runInAction(() => { estimates.forEach((estimate) => { - if (estimate.id) set(this.estimates, [estimate.id], new Estimate(this.store, estimate)); + if (estimate.id) + set( + this.estimates, + [estimate.id], + new Estimate(this.store, { ...estimate, type: estimate.type?.toLowerCase() as TEstimateSystemKeys }) + ); }); }); } @@ -235,7 +245,11 @@ export class ProjectEstimateStore implements IProjectEstimateStore { if (estimate.id) update(this.estimates, [estimate.id], (estimateStore) => { if (estimateStore) estimateStore.updateEstimate(estimate); - else return new Estimate(this.store, estimate); + else + return new Estimate(this.store, { + ...estimate, + type: estimate.type?.toLowerCase() as TEstimateSystemKeys, + }); }); }); } @@ -272,7 +286,12 @@ export class ProjectEstimateStore implements IProjectEstimateStore { // estimate: estimate.id, // }); runInAction(() => { - if (estimate.id) set(this.estimates, [estimate.id], new Estimate(this.store, estimate)); + if (estimate.id) + set( + this.estimates, + [estimate.id], + new Estimate(this.store, { ...estimate, type: estimate.type?.toLowerCase() as TEstimateSystemKeys }) + ); }); }