1
1
import { useMutation } from '@tanstack/vue-query'
2
2
import { taskPriorityIncrement } from '~/constants/config'
3
- import type { Task , TaskHighlights } from '~/types/tasks'
3
+ import type { RadicleIssue , RadiclePatch } from '~/types/httpd'
4
+ import type { Issue , Patch , Task , TaskHighlights } from '~/types/tasks'
4
5
5
6
interface TaskPositionUpdate {
6
7
task : Task
@@ -17,7 +18,7 @@ export const useTasksStore = defineStore('tasks', () => {
17
18
refetchAllTasks,
18
19
refetchSpecificTasks,
19
20
updateTaskLabels,
20
- } = useTasksFetch ( )
21
+ } = useFetchedTasks ( )
21
22
const route = useRoute ( 'node-rid' )
22
23
const permissions = usePermissions ( )
23
24
const board = useBoardStore ( )
@@ -273,8 +274,180 @@ export const useTasksStore = defineStore('tasks', () => {
273
274
}
274
275
} )
275
276
277
+ function useFetchedTasks ( ) {
278
+ const { $httpd } = useNuxtApp ( )
279
+ const route = useRoute ( 'node-rid' )
280
+
281
+ async function fetchIssueById ( id : string ) : Promise < Issue > {
282
+ const radicleIssue = await $httpd ( '/projects/{rid}/issues/{issue}' , {
283
+ path : { rid : route . params . rid , issue : id } ,
284
+ } )
285
+ const issue = transformRadicleIssueToIssue ( radicleIssue as RadicleIssue )
286
+
287
+ return issue
288
+ }
289
+
290
+ async function fetchAllIssues ( ) : Promise < Issue [ ] > {
291
+ const issueStatuses = [ 'open' , 'closed' ] satisfies RadicleIssue [ 'state' ] [ 'status' ] [ ]
292
+
293
+ const radicleIssuesByStatus = await Promise . all (
294
+ issueStatuses . map (
295
+ async ( status ) =>
296
+ await $httpd ( '/projects/{rid}/issues' , {
297
+ path : {
298
+ rid : route . params . rid ,
299
+ } ,
300
+ // @ts -expect-error - wrong type definition
301
+ query : { perPage : 1000 , state : status } ,
302
+ } ) ,
303
+ ) ,
304
+ )
305
+
306
+ const radicleIssues = radicleIssuesByStatus . flat ( )
307
+ const issues = radicleIssues . map ( ( issue ) =>
308
+ transformRadicleIssueToIssue ( issue as RadicleIssue ) ,
309
+ )
310
+
311
+ return issues
312
+ }
313
+
314
+ async function fetchPatchById ( id : string ) : Promise < Patch > {
315
+ const radiclePatch = await $httpd ( '/projects/{rid}/patches/{patch}' , {
316
+ path : { rid : route . params . rid , patch : id } ,
317
+ } )
318
+ const patch = transformRadiclePatchToPatch ( radiclePatch as RadiclePatch )
319
+
320
+ return patch
321
+ }
322
+
323
+ async function fetchAllPatches ( ) : Promise < Patch [ ] > {
324
+ const patchStatuses = [
325
+ 'draft' ,
326
+ 'open' ,
327
+ 'archived' ,
328
+ 'merged' ,
329
+ ] satisfies RadiclePatch [ 'state' ] [ 'status' ] [ ]
330
+
331
+ const radiclePatchesByStatus = await Promise . all (
332
+ patchStatuses . map (
333
+ async ( status ) =>
334
+ await $httpd ( '/projects/{rid}/patches' , {
335
+ path : {
336
+ rid : route . params . rid ,
337
+ } ,
338
+ // @ts -expect-error - wrong type definition
339
+ query : { perPage : 1000 , state : status } ,
340
+ } ) ,
341
+ ) ,
342
+ )
343
+
344
+ const radiclePatches = radiclePatchesByStatus . flat ( )
345
+ const patches = radiclePatches . map ( ( patch ) =>
346
+ transformRadiclePatchToPatch ( patch as RadiclePatch ) ,
347
+ )
348
+
349
+ return patches
350
+ }
351
+
352
+ async function updateTaskLabels ( task : Task , labels : string [ ] ) {
353
+ const { kind } = task . rpb
354
+
355
+ switch ( kind ) {
356
+ case 'issue' :
357
+ return await $httpd ( `/projects/{rid}/issues/{issue}` , {
358
+ path : { rid : route . params . rid , issue : task . id } ,
359
+ method : 'PATCH' ,
360
+ body : {
361
+ type : 'label' ,
362
+ labels,
363
+ } ,
364
+ } )
365
+ case 'patch' :
366
+ return await $httpd ( `/projects/{rid}/patches/{patch}` , {
367
+ path : { rid : route . params . rid , patch : task . id } ,
368
+ method : 'PATCH' ,
369
+ body : {
370
+ type : 'label' ,
371
+ labels,
372
+ } ,
373
+ } )
374
+ default :
375
+ return assertUnreachable ( kind )
376
+ }
377
+ }
378
+
379
+ const {
380
+ data : tasks ,
381
+ status : tasksStatus ,
382
+ refresh : refetchAllTasks ,
383
+ } = useAsyncData (
384
+ 'tasks' ,
385
+ async ( ) => {
386
+ const issuesAndPatches = await Promise . all ( [ fetchAllIssues ( ) , fetchAllPatches ( ) ] )
387
+ const tasks = issuesAndPatches . flat ( )
388
+
389
+ return tasks
390
+ } ,
391
+ { deep : false } ,
392
+ )
393
+ const areTasksPending = computed ( ( ) => tasksStatus . value === 'pending' )
394
+
395
+ async function refetchTask ( task : Task ) : Promise < void > {
396
+ if ( ! tasks . value ) {
397
+ return
398
+ }
399
+
400
+ let refetchedTask : Task
401
+ const { kind } = task . rpb
402
+
403
+ switch ( kind ) {
404
+ case 'issue' :
405
+ refetchedTask = await fetchIssueById ( task . id )
406
+ break
407
+ case 'patch' :
408
+ refetchedTask = await fetchPatchById ( task . id )
409
+ break
410
+ default :
411
+ assertUnreachable ( kind )
412
+ }
413
+
414
+ const taskIndex = tasks . value . indexOf ( task )
415
+ if ( taskIndex === undefined || taskIndex === - 1 ) {
416
+ return
417
+ }
418
+
419
+ tasks . value = tasks . value . with ( taskIndex , refetchedTask )
420
+ }
421
+
422
+ async function refetchSpecificTasks ( tasksToRefetch : Task [ ] ) : Promise < void > {
423
+ await Promise . all (
424
+ tasksToRefetch . map ( async ( task ) => {
425
+ await refetchTask ( task )
426
+ } ) ,
427
+ )
428
+ }
429
+
430
+ async function fetchIssueByIdAndAddToTasks ( id : string ) : Promise < void > {
431
+ if ( tasks . value === null ) {
432
+ return
433
+ }
434
+
435
+ const issue = await fetchIssueById ( id )
436
+ tasks . value = [ ...tasks . value , issue ]
437
+ }
438
+
439
+ return {
440
+ tasks,
441
+ areTasksPending,
442
+ refetchAllTasks,
443
+ refetchSpecificTasks,
444
+ updateTaskLabels,
445
+ fetchIssueByIdAndAddToTasks,
446
+ }
447
+ }
448
+
276
449
function useFilteredTasks ( ) {
277
- const { tasks } = useTasksFetch ( )
450
+ const { tasks } = useFetchedTasks ( )
278
451
const board = useBoardStore ( )
279
452
280
453
const twoWeeksAgo = new Date ( )
0 commit comments