-
+
0) {
+ errorMessage = (parsed as { message?: string }[])
+ .map((e) => e.message)
+ .filter(Boolean)
+ .join("; ");
+ } else {
+ errorMessage = err.message;
+ }
+ } catch {
+ errorMessage = err.message;
+ }
+ }
+ setSubmitError(errorMessage);
} finally {
setIsSubmitting(false);
}
diff --git a/apps/web/src/components/timeline/TimelineContext.tsx b/apps/web/src/components/timeline/TimelineContext.tsx
index f5563da..70bc80d 100644
--- a/apps/web/src/components/timeline/TimelineContext.tsx
+++ b/apps/web/src/components/timeline/TimelineContext.tsx
@@ -203,6 +203,7 @@ export interface TimelineContextValue {
// ─ Loading
isLoading: boolean;
isInitialLoading: boolean;
+ isEntriesError: boolean;
totalAllocCount: number;
activeFilterCount: number;
@@ -328,6 +329,7 @@ export function TimelineProvider({
) as {
data: TimelineEntriesView | undefined;
isLoading: boolean;
+ isError: boolean;
refetch: () => Promise
;
};
@@ -344,11 +346,12 @@ export function TimelineProvider({
) as {
data: TimelineEntriesView | undefined;
isLoading: boolean;
+ isError: boolean;
refetch: () => Promise;
};
const entriesViewQuery = isSelfServiceTimeline ? selfEntriesViewQuery : staffEntriesViewQuery;
- const { data: entriesView, isLoading, refetch: refetchEntriesView } = entriesViewQuery;
+ const { data: entriesView, isLoading, isError: isEntriesError, refetch: refetchEntriesView } = entriesViewQuery;
const assignments = entriesView?.assignments ?? [];
const demands = entriesView?.demands ?? [];
@@ -774,6 +777,7 @@ export function TimelineProvider({
blinkOverbookedDays,
isLoading,
isInitialLoading,
+ isEntriesError,
totalAllocCount,
activeFilterCount,
}),
@@ -800,6 +804,7 @@ export function TimelineProvider({
blinkOverbookedDays,
isLoading,
isInitialLoading,
+ isEntriesError,
totalAllocCount,
activeFilterCount,
],
diff --git a/apps/web/src/components/timeline/TimelineView.tsx b/apps/web/src/components/timeline/TimelineView.tsx
index fea127b..7c496e3 100644
--- a/apps/web/src/components/timeline/TimelineView.tsx
+++ b/apps/web/src/components/timeline/TimelineView.tsx
@@ -332,6 +332,7 @@ function TimelineViewContent({
today,
isLoading,
isInitialLoading,
+ isEntriesError,
totalAllocCount,
} = ctx;
@@ -708,7 +709,11 @@ function TimelineViewContent({
onScroll={handleContainerScroll}
className="app-surface relative z-0 flex-1 overflow-auto"
>
- {isInitialLoading ? (
+ {isEntriesError ? (
+
+ Failed to load timeline data. Please try refreshing the page.
+
+ ) : isInitialLoading ? (
Loading timeline...