You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/integrations/angular/configuration-props.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -394,7 +394,7 @@ resetFilter(): void {
394
394
</dhx-gantt>
395
395
~~~
396
396
397
-
Keep a stable reference when the filter logic has not changed — the wrapper compares by identity and re-renders only when the reference changes.
397
+
Keep a stable reference when the filter logic has not changed - the wrapper compares by identity and re-renders only when the reference changes.
398
398
399
399
## Exported Types And Helpers
400
400
@@ -418,8 +418,8 @@ Useful public exports from the wrapper package:
418
418
419
419
The wrapper exports two task-related types:
420
420
421
-
-**`SerializedTask`**— use for data you own: store state, API responses, initial literals, `batchSave` payloads. Dates can be `Date` objects or strings matching `date_format`.
422
-
-**`Task`** (re-exported from `@dhx/gantt`) — for data gantt owns: inside event handlers, after gantt parses. Dates are `Date` objects. Has `$`-prefixed system properties.
421
+
-**`SerializedTask`**- use for data you own: store state, API responses, initial literals, `batchSave` payloads. Dates can be `Date` objects or strings matching `date_format`.
422
+
-**`Task`** (re-exported from `@dhx/gantt`) - for data gantt owns: inside event handlers, after gantt parses. Dates are `Date` objects. Has `$`-prefixed system properties.
423
423
424
424
`SerializedLink` is the link-side counterpart of `SerializedTask`.
Copy file name to clipboardExpand all lines: docs/integrations/angular/quick-start.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ If you later move the Gantt CSS import (or overrides for internal Gantt classes
64
64
65
65
Create `src/app/demo-data.ts`.
66
66
67
-
The wrapper exports `SerializedTask` and `SerializedLink`— the recommended types for task/link data held outside gantt. Dates can be strings or `Date` objects.
67
+
The wrapper exports `SerializedTask` and `SerializedLink`- the recommended types for task/link data held outside gantt. Dates can be strings or `Date` objects.
The wrapper exports `SerializedTask` and `SerializedLink`— use these to type tasks and links held outside of gantt (store state, API responses, initial data). Dates can be `Date` objects or strings.
71
+
The wrapper exports `SerializedTask` and `SerializedLink`- use these to type tasks and links held outside of gantt (store state, API responses, initial data). Dates can be `Date` objects or strings.
Copy file name to clipboardExpand all lines: docs/integrations/react/configuration-props.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,8 +130,8 @@ The `@dhx/react-gantt` package re-exports several TypeScript types that you can
130
130
131
131
**When to use `SerializedTask` / `SerializedLink` vs `Task` / `Link`:**
132
132
133
-
-**`SerializedTask` / `SerializedLink`**— for data you own: store state, API responses, initial data literals. Date fields accept strings (e.g. ISO dates).
134
-
-**`Task` / `Link`**— for data Gantt owns: inside event handlers, after Gantt parses the data. Date fields are `Date` objects. `Task` includes `$`-prefixed internal properties.
133
+
-**`SerializedTask` / `SerializedLink`**- for data you own: store state, API responses, initial data literals. Date fields accept strings (e.g. ISO dates).
134
+
-**`Task` / `Link`**- for data Gantt owns: inside event handlers, after Gantt parses the data. Date fields are `Date` objects. `Task` includes `$`-prefixed internal properties.
Copy file name to clipboardExpand all lines: docs/integrations/react/state/state-management-basics.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -51,7 +51,7 @@ you need to be sure not to unintentionally overwrite Gantt's internal state.
51
51
52
52
In this pattern, you hold all core collections in state and pass them as props (`tasks`, `links`, `resources`, `resourceAssignments`). Whenever the user modifies tasks or links inside the Gantt (for example, by creating or deleting a task), the Gantt triggers a callback. In this callback, you update your React state with the new or removed data. Once the state is updated, React re-renders the **ReactGantt** component, which in turn reads the updated props from the latest state.
53
53
54
-
When typing your state, use `SerializedTask` for tasks and `SerializedLink` for links. These types represent the user-facing data shape — date fields accept `Date | string`, and there are no internal `$`-prefixed properties. Use `Task` and `Link` only when working with data inside Gantt event handlers, where Gantt has already parsed the data.
54
+
When typing your state, use `SerializedTask` for tasks and `SerializedLink` for links. These types represent the user-facing data shape - date fields accept `Date | string`, and there are no internal `$`-prefixed properties. Use `Task` and `Link` only when working with data inside Gantt event handlers, where Gantt has already parsed the data.
Copy file name to clipboardExpand all lines: docs/integrations/react/state/tanstack-query.md
+9-2Lines changed: 9 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -918,12 +918,19 @@ A complete working project that follows this tutorial is [provided on GitHub](ht
918
918
919
919
## What's next
920
920
921
-
To go further:
921
+
This is the second tutorial in the React Gantt state-management sequence:
922
+
923
+
1.[Zustand](integrations/react/state/zustand.md) - local in-memory state
924
+
2.**TanStack Query** - server-backed state with a JSON file backend (you are here)
925
+
3.[TanStack Query + Supabase](integrations/react/state/tanstack-supabase.md) - real-time multi-user sync over PostgreSQL
926
+
927
+
Ready to swap the JSON backend for a real database with live multi-user sync? Continue with [Using React Gantt with TanStack Query and Supabase](integrations/react/state/tanstack-supabase.md).
928
+
929
+
You can also:
922
930
923
931
- Revisit the concepts behind this example in [](integrations/react/state/state-management-basics.md)
924
932
- Combine store-driven state with advanced configuration and templating in the [React Gantt overview](integrations/react/overview.md)
925
933
- Explore the same pattern with other state managers:
926
-
-[Using React Gantt with Zustand](integrations/react/state/zustand.md)
927
934
-[Using React Gantt with Redux Toolkit](integrations/react/state/redux-toolkit.md)
928
935
-[Using React Gantt with MobX](integrations/react/state/mobx.md)
929
936
-[Using React Gantt with XState](integrations/react/state/xstate.md)
`supabaseClient` is used exclusively for Realtime subscriptions in `GanttComponent.tsx`. All database writes go through `supabaseServer` in the Express layer.
176
176
177
+
:::note
178
+
This starter uses the **anon key** server-side because the demo schema has no Row-Level Security policies and there is no authentication. In production with auth and RLS, the server should hold the **service role key** (kept off the frontend) to bypass RLS for trusted operations.
179
+
:::
180
+
177
181
## TypeScript types
178
182
179
183
`src/types/types.ts` defines the database row shapes and service interfaces:
@@ -278,7 +282,7 @@ export function sanitize<T extends object>(obj: T): T {
278
282
279
283
Every write service calls `sanitize()` before inserting or updating. Add field names to `TEXT_FIELDS` when the schema gains additional user-editable text columns.
280
284
281
-
### taskService — sortorder management
285
+
### taskService - sortorder management
282
286
283
287
`src/services/taskService.ts` is the most complex service because it manages the persistent task order.
284
288
@@ -471,7 +475,72 @@ The `PUT /tasks/:id` handler destructures `target` out of the request body befor
471
475
472
476
## Creating the API layer
473
477
474
-
`src/api.ts` is identical to the base TanStack Query demo - plain `fetch` wrappers that throw on non-2xx responses. One small difference: `updateTask`, `deleteTask`, `updateLink`, and `deleteLink` now return the server response JSON (the updated/deleted row) instead of discarding it. The returned `id` is used by mutations to register pending operations for deduplication.
478
+
`src/api.ts` is similar to the base TanStack Query demo - plain `fetch` wrappers that throw on non-2xx responses. The key difference: every mutation now returns the server response JSON (the updated/deleted row) instead of discarding it. The returned `id` is used by mutations to register pending operations for deduplication.
const res =awaitrequest(`${BASE}/tasks/${id}`, { method: 'DELETE' });
518
+
returnawaitres.json();
519
+
};
520
+
521
+
// createLink, updateLink, deleteLink follow the same pattern against /links
522
+
```
523
+
524
+
Frontend requests hit the same origin as the Vite dev server (`http://localhost:3000`); a proxy in `vite.config.ts` forwards `/data`, `/tasks`, and `/links` to the Express backend on port 3001:
Without this pattern, every local mutation would trigger two refetches: one from `onSuccess` and one from the Realtime echo. With it, local changes invalidate the cache exactly once, and only changes from other clients cause an additional refetch.
639
708
640
709
:::note
641
-
Drag-and-drop reorders update `sortorder` on multiple rows server-side. Only the primary task is registered in `pendingOperationsRef`; the side-effect `sortorder` updates on other tasks produce untracked Realtime events that slip through to `invalidateQueries`. This is harmless —`sortorder` is server-only state, and TanStack Query deduplicates rapid invalidations into a single background refetch.
710
+
Drag-and-drop reorders update `sortorder` on multiple rows server-side. Only the primary task is registered in `pendingOperationsRef`; the side-effect `sortorder` updates on other tasks produce untracked Realtime events that slip through to `invalidateQueries`. This is harmless -`sortorder` is server-only state, and TanStack Query deduplicates rapid invalidations into a single background refetch.
- A single undo entry covers the entire batch, not individual sub-operations.
686
-
- The snapshot recorded is `prevSnapshotRef.current`— the state captured just before `batchSave` fired — so undo always reverts the complete interaction.
755
+
- The snapshot recorded is `prevSnapshotRef.current`- the state captured just before `batchSave` fired - so undo always reverts the complete interaction.
687
756
- The Gantt calls `batchSave` once per user gesture even if that gesture produces multiple database writes.
688
757
689
758
For more about `batchSave` see [Data Binding & State Management Basics](integrations/react/state/state-management-basics.md).
690
759
691
760
### Persistence-aware undo/redo
692
761
693
-
In the base TanStack Query tutorial, `handleUndo` and `handleRedo` write a snapshot into the client cache with `setQueryData` and that is it — changes are not persisted until the user makes the next manual edit.
762
+
In the base TanStack Query tutorial, `handleUndo` and `handleRedo` write a snapshot into the client cache with `setQueryData` and that is it - changes are not persisted until the user makes the next manual edit.
694
763
695
764
In this demo, undo/redo must also persist the rollback to Supabase so that other connected clients see it. This is done with `applySnapshotDiff`:
0 commit comments