@tuturuuu/ui 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -93,6 +93,7 @@ export function useTaskRealtimeSync({
93
93
  const endDateRef = useRef(endDate);
94
94
  const estimationPointsRef = useRef(estimationPoints);
95
95
  const selectedListIdRef = useRef(selectedListId);
96
+ const taskRequestTokenRef = useRef(0);
96
97
  const relationsRequestTokenRef = useRef(0);
97
98
 
98
99
  nameRef.current = name;
@@ -105,7 +106,7 @@ export function useTaskRealtimeSync({
105
106
  const realtimeActive =
106
107
  !isCreateMode && isOpen && realtimeEnabled && !!taskId && !disabled;
107
108
 
108
- const fetchTaskRelations = useCallback(async () => {
109
+ const fetchLatestTask = useCallback(async () => {
109
110
  if (!taskId) return null;
110
111
 
111
112
  try {
@@ -127,25 +128,96 @@ export function useTaskRealtimeSync({
127
128
  staleTime: 0,
128
129
  });
129
130
 
130
- const relationshipProjectIds =
131
- routeTask.task.project_ids ??
132
- routeTask.task.projects?.map((project) => project.id) ??
133
- [];
134
-
135
- const filteredProjects = (routeTask.task.projects ?? []).filter(
136
- (project) => relationshipProjectIds.includes(project.id)
137
- );
138
-
139
- return {
140
- labels: routeTask.task.labels ?? [],
141
- assignees: routeTask.task.assignees ?? [],
142
- projects: filteredProjects,
143
- };
131
+ return routeTask.task;
144
132
  } catch {
145
133
  return null;
146
134
  }
147
135
  }, [queryClient, taskId, taskWorkspaceId, wsId]);
148
136
 
137
+ const applyLatestTaskFields = useCallback(async () => {
138
+ if (!realtimeActive || !taskId) return;
139
+
140
+ taskRequestTokenRef.current += 1;
141
+ const token = taskRequestTokenRef.current;
142
+ const task = await fetchLatestTask();
143
+
144
+ if (token !== taskRequestTokenRef.current || !task || task.id !== taskId) {
145
+ return;
146
+ }
147
+
148
+ if (
149
+ hasOwn(task, 'name') &&
150
+ typeof task.name === 'string' &&
151
+ !pendingNameRef.current &&
152
+ task.name !== nameRef.current
153
+ ) {
154
+ setName(task.name);
155
+ }
156
+
157
+ if (hasOwn(task, 'priority') && task.priority !== priorityRef.current) {
158
+ setPriority(task.priority ?? null);
159
+ }
160
+
161
+ if (hasOwn(task, 'start_date')) {
162
+ const nextStartDate = toDate(task.start_date);
163
+ if (!datesMatch(startDateRef.current, nextStartDate)) {
164
+ setStartDate(nextStartDate);
165
+ }
166
+ }
167
+
168
+ if (hasOwn(task, 'end_date')) {
169
+ const nextEndDate = toDate(task.end_date);
170
+ if (!datesMatch(endDateRef.current, nextEndDate)) {
171
+ setEndDate(nextEndDate);
172
+ }
173
+ }
174
+
175
+ if (
176
+ hasOwn(task, 'estimation_points') &&
177
+ task.estimation_points !== estimationPointsRef.current
178
+ ) {
179
+ setEstimationPoints(task.estimation_points ?? null);
180
+ }
181
+
182
+ if (
183
+ hasOwn(task, 'list_id') &&
184
+ typeof task.list_id === 'string' &&
185
+ task.list_id !== selectedListIdRef.current
186
+ ) {
187
+ setSelectedListId(task.list_id);
188
+ }
189
+ }, [
190
+ fetchLatestTask,
191
+ pendingNameRef,
192
+ realtimeActive,
193
+ setEndDate,
194
+ setEstimationPoints,
195
+ setName,
196
+ setPriority,
197
+ setSelectedListId,
198
+ setStartDate,
199
+ taskId,
200
+ ]);
201
+
202
+ const fetchTaskRelations = useCallback(async () => {
203
+ const task = await fetchLatestTask();
204
+
205
+ if (!task) return null;
206
+
207
+ const relationshipProjectIds =
208
+ task.project_ids ?? task.projects?.map((project) => project.id) ?? [];
209
+
210
+ const filteredProjects = (task.projects ?? []).filter((project) =>
211
+ relationshipProjectIds.includes(project.id)
212
+ );
213
+
214
+ return {
215
+ labels: task.labels ?? [],
216
+ assignees: task.assignees ?? [],
217
+ projects: filteredProjects,
218
+ };
219
+ }, [fetchLatestTask]);
220
+
149
221
  const applyLatestRelations = useCallback(async () => {
150
222
  if (!realtimeActive) return;
151
223
 
@@ -175,62 +247,9 @@ export function useTaskRealtimeSync({
175
247
  )
176
248
  return;
177
249
 
178
- if (
179
- hasOwn(updatedTask, 'name') &&
180
- typeof updatedTask.name === 'string' &&
181
- !pendingNameRef.current &&
182
- updatedTask.name !== nameRef.current
183
- ) {
184
- setName(updatedTask.name);
185
- }
186
-
187
- if (
188
- hasOwn(updatedTask, 'priority') &&
189
- updatedTask.priority !== priorityRef.current
190
- ) {
191
- setPriority(updatedTask.priority ?? null);
192
- }
193
-
194
- if (hasOwn(updatedTask, 'start_date')) {
195
- const nextStartDate = toDate(updatedTask.start_date);
196
- if (!datesMatch(startDateRef.current, nextStartDate)) {
197
- setStartDate(nextStartDate);
198
- }
199
- }
200
-
201
- if (hasOwn(updatedTask, 'end_date')) {
202
- const nextEndDate = toDate(updatedTask.end_date);
203
- if (!datesMatch(endDateRef.current, nextEndDate)) {
204
- setEndDate(nextEndDate);
205
- }
206
- }
207
-
208
- if (
209
- hasOwn(updatedTask, 'estimation_points') &&
210
- updatedTask.estimation_points !== estimationPointsRef.current
211
- ) {
212
- setEstimationPoints(updatedTask.estimation_points ?? null);
213
- }
214
-
215
- if (
216
- hasOwn(updatedTask, 'list_id') &&
217
- typeof updatedTask.list_id === 'string' &&
218
- updatedTask.list_id !== selectedListIdRef.current
219
- ) {
220
- setSelectedListId(updatedTask.list_id);
221
- }
250
+ void applyLatestTaskFields();
222
251
  },
223
- [
224
- pendingNameRef,
225
- realtimeActive,
226
- setEndDate,
227
- setEstimationPoints,
228
- setName,
229
- setPriority,
230
- setSelectedListId,
231
- setStartDate,
232
- taskId,
233
- ]
252
+ [applyLatestTaskFields, realtimeActive, taskId]
234
253
  );
235
254
 
236
255
  const handleTaskRelationsChange = useCallback(