Skip to content

Commit 13cc8b0

Browse files
chore: workspace view loading state improvement (#6423)
1 parent 9addcde commit 13cc8b0

File tree

3 files changed

+37
-17
lines changed

3 files changed

+37
-17
lines changed

web/app/[workspaceSlug]/(projects)/workspace-views/[globalViewId]/page.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"use client";
22

3+
import { useState } from "react";
34
import { observer } from "mobx-react";
45
import { useParams } from "next/navigation";
56
// components
@@ -16,19 +17,25 @@ const GlobalViewIssuesPage = observer(() => {
1617
const { globalViewId } = useParams();
1718
// store hooks
1819
const { currentWorkspace } = useWorkspace();
20+
// states
21+
const [isLoading, setIsLoading] = useState(false);
1922

2023
// derived values
2124
const defaultView = DEFAULT_GLOBAL_VIEWS_LIST.find((view) => view.key === globalViewId);
2225
const pageTitle = currentWorkspace?.name ? `${currentWorkspace?.name} - All Views` : undefined;
2326

27+
// handlers
28+
const toggleLoading = (value: boolean) => setIsLoading(value);
2429
return (
2530
<>
2631
<PageHead title={pageTitle} />
2732
<div className="h-full overflow-hidden bg-custom-background-100">
2833
<div className="flex h-full w-full flex-col border-b border-custom-border-300">
2934
<GlobalViewsHeader />
30-
{globalViewId && <GlobalViewsAppliedFiltersRoot globalViewId={globalViewId.toString()} />}
31-
<AllIssueLayoutRoot isDefaultView={!!defaultView} />
35+
{globalViewId && (
36+
<GlobalViewsAppliedFiltersRoot globalViewId={globalViewId.toString()} isLoading={isLoading} />
37+
)}
38+
<AllIssueLayoutRoot isDefaultView={!!defaultView} isLoading={isLoading} toggleLoading={toggleLoading} />
3239
</div>
3340
</div>
3441
</>

web/core/components/issues/issue-layouts/filters/applied-filters/roots/global-view-root.tsx

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { EIssueFilterType, EIssuesStoreType } from "@plane/constants";
1010
import { IIssueFilterOptions, TStaticViewTypes } from "@plane/types";
1111
//ui
1212
// components
13-
import { Header, EHeaderVariant } from "@plane/ui";
13+
import { Header, EHeaderVariant, Loader } from "@plane/ui";
1414
import { AppliedFiltersList } from "@/components/issues";
1515
import { UpdateViewComponent } from "@/components/views/update-view-component";
1616
import { CreateUpdateWorkspaceViewModal } from "@/components/workspace";
@@ -27,10 +27,11 @@ import { getAreFiltersEqual } from "../../../utils";
2727

2828
type Props = {
2929
globalViewId: string;
30+
isLoading?: boolean;
3031
};
3132

3233
export const GlobalViewsAppliedFiltersRoot = observer((props: Props) => {
33-
const { globalViewId } = props;
34+
const { globalViewId, isLoading = false } = props;
3435
// router
3536
const { workspaceSlug } = useParams();
3637
// store hooks
@@ -154,14 +155,22 @@ export const GlobalViewsAppliedFiltersRoot = observer((props: Props) => {
154155
}}
155156
/>
156157

157-
<AppliedFiltersList
158-
labels={workspaceLabels ?? undefined}
159-
appliedFilters={appliedFilters ?? {}}
160-
handleClearAllFilters={handleClearAllFilters}
161-
handleRemoveFilter={handleRemoveFilter}
162-
disableEditing={isLocked}
163-
alwaysAllowEditing
164-
/>
158+
{isLoading ? (
159+
<Loader className="flex flex-wrap items-stretch gap-2 bg-custom-background-100 truncate my-auto">
160+
<Loader.Item height="36px" width="150px" />
161+
<Loader.Item height="36px" width="100px" />
162+
<Loader.Item height="36px" width="300px" />
163+
</Loader>
164+
) : (
165+
<AppliedFiltersList
166+
labels={workspaceLabels ?? undefined}
167+
appliedFilters={appliedFilters ?? {}}
168+
handleClearAllFilters={handleClearAllFilters}
169+
handleRemoveFilter={handleRemoveFilter}
170+
disableEditing={isLocked}
171+
alwaysAllowEditing
172+
/>
173+
)}
165174

166175
{!isDefaultView ? (
167176
<UpdateViewComponent

web/core/components/issues/issue-layouts/roots/all-issue-layout-root.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ import { TRenderQuickActions } from "../list/list-view-types";
2929

3030
type Props = {
3131
isDefaultView: boolean;
32+
isLoading?: boolean;
33+
toggleLoading: (value: boolean) => void;
3234
};
3335

3436
export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
35-
const { isDefaultView } = props;
37+
const { isDefaultView, isLoading = false, toggleLoading } = props;
3638
// router
3739
const { workspaceSlug, globalViewId } = useParams();
3840
const router = useAppRouter();
@@ -92,7 +94,7 @@ export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
9294
if (workspaceSlug && globalViewId) fetchNextIssues(workspaceSlug.toString(), globalViewId.toString());
9395
}, [fetchNextIssues, workspaceSlug, globalViewId]);
9496

95-
const { isLoading } = useSWR(
97+
const { isLoading: globalViewsLoading } = useSWR(
9698
workspaceSlug ? `WORKSPACE_GLOBAL_VIEWS_${workspaceSlug}` : null,
9799
async () => {
98100
if (workspaceSlug) {
@@ -102,11 +104,12 @@ export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
102104
{ revalidateIfStale: false, revalidateOnFocus: false }
103105
);
104106

105-
useSWR(
107+
const { isLoading: issuesLoading } = useSWR(
106108
workspaceSlug && globalViewId ? `WORKSPACE_GLOBAL_VIEW_ISSUES_${workspaceSlug}_${globalViewId}` : null,
107109
async () => {
108110
if (workspaceSlug && globalViewId) {
109111
clear();
112+
toggleLoading(true);
110113
await fetchFilters(workspaceSlug.toString(), globalViewId.toString());
111114
await fetchIssues(
112115
workspaceSlug.toString(),
@@ -118,6 +121,7 @@ export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
118121
}
119122
);
120123
routerFilterParams();
124+
toggleLoading(false);
121125
}
122126
},
123127
{ revalidateIfStale: false, revalidateOnFocus: false }
@@ -171,7 +175,7 @@ export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
171175
);
172176

173177
// when the call is not loading and the view does not exist and the view is not a default view, show empty state
174-
if (!isLoading && !viewDetails && !isDefaultView) {
178+
if (!isLoading && !globalViewsLoading && !issuesLoading && !viewDetails && !isDefaultView) {
175179
return (
176180
<EmptyState
177181
image={emptyView}
@@ -185,7 +189,7 @@ export const AllIssueLayoutRoot: React.FC<Props> = observer((props: Props) => {
185189
);
186190
}
187191

188-
if (getIssueLoader() === "init-loader" || !globalViewId || !groupedIssueIds) {
192+
if ((isLoading && issuesLoading && getIssueLoader() === "init-loader") || !globalViewId || !groupedIssueIds) {
189193
return <SpreadsheetLayoutLoader />;
190194
}
191195

0 commit comments

Comments
 (0)