7
7
Task Actions
8
8
*/
9
9
10
- const LAST_EDITED_THRESH_S = 30 ;
11
- const TASKS_HELP_URL = "https://doc.cocalc.com/tasks.html" ;
12
-
13
10
import { fromJS , Map } from "immutable" ;
14
11
import { throttle } from "lodash" ;
15
12
import { delay } from "awaiting" ;
@@ -26,6 +23,7 @@ import { create_key_handler } from "./keyboard";
26
23
import { toggle_checkbox } from "./desc-rendering" ;
27
24
import { Actions } from "../../app-framework" ;
28
25
import {
26
+ Align ,
29
27
HashtagState ,
30
28
Headings ,
31
29
HeadingsDir ,
@@ -40,6 +38,10 @@ import { TaskStore } from "./store";
40
38
import { SyncDB } from "@cocalc/sync/editor/db" ;
41
39
import { webapp_client } from "../../webapp-client" ;
42
40
import type { Actions as TaskFrameActions } from "@cocalc/frontend/frame-editors/task-editor/actions" ;
41
+ import Fragment from "@cocalc/frontend/misc/fragment-id" ;
42
+
43
+ const LAST_EDITED_THRESH_S = 30 ;
44
+ const TASKS_HELP_URL = "https://doc.cocalc.com/tasks.html" ;
43
45
44
46
export class TaskActions extends Actions < TaskState > {
45
47
public syncdb : SyncDB ;
@@ -53,13 +55,14 @@ export class TaskActions extends Actions<TaskState> {
53
55
private set_save_status ?: ( ) => void ;
54
56
private frameId : string ;
55
57
private frameActions : TaskFrameActions ;
58
+ private virtuosoRef ?;
56
59
57
60
public _init (
58
61
project_id : string ,
59
62
path : string ,
60
63
syncdb : SyncDB ,
61
64
store : TaskStore ,
62
- truePath : string // because above path is auxpath for each frame.
65
+ truePath : string , // because above path is auxpath for each frame.
63
66
) : void {
64
67
this . _update_visible = throttle ( this . __update_visible , 500 ) ;
65
68
this . project_id = project_id ;
@@ -136,7 +139,7 @@ export class TaskActions extends Actions<TaskState> {
136
139
local_task_state ,
137
140
view ,
138
141
counts ,
139
- current_task_id
142
+ current_task_id ,
140
143
) ;
141
144
142
145
if ( obj . visible . size == 0 && view . get ( "search" ) ?. trim ( ) . length == 0 ) {
@@ -148,7 +151,7 @@ export class TaskActions extends Actions<TaskState> {
148
151
local_task_state ,
149
152
view ,
150
153
counts ,
151
- current_task_id
154
+ current_task_id ,
152
155
) ;
153
156
}
154
157
@@ -229,6 +232,21 @@ export class TaskActions extends Actions<TaskState> {
229
232
}
230
233
}
231
234
235
+ clearAllFilters = ( obj ?) => {
236
+ this . set_local_view_state (
237
+ {
238
+ show_deleted : false ,
239
+ show_done : false ,
240
+ show_max : false ,
241
+ selected_hashtags : { } ,
242
+ search : "" ,
243
+ ...obj ,
244
+ } ,
245
+ false ,
246
+ ) ;
247
+ this . __update_visible ( ) ;
248
+ } ;
249
+
232
250
public async save ( ) : Promise < void > {
233
251
if ( this . is_closed ) {
234
252
return ;
@@ -297,7 +315,7 @@ export class TaskActions extends Actions<TaskState> {
297
315
task_id ?: string ,
298
316
obj ?: object ,
299
317
setState : boolean = false ,
300
- save : boolean = true // make new commit to syncdb state
318
+ save : boolean = true , // make new commit to syncdb state
301
319
) : void {
302
320
if ( obj == null || this . is_closed ) {
303
321
return ;
@@ -334,7 +352,7 @@ export class TaskActions extends Actions<TaskState> {
334
352
// **immediately**; this would happen
335
353
// eventually as a result of the syncdb set above.
336
354
let tasks = this . store . get ( "tasks" ) ?? fromJS ( { } ) ;
337
- task = tasks . get ( task_id ) ?? fromJS ( { task_id } ) as any ;
355
+ task = tasks . get ( task_id ) ?? ( fromJS ( { task_id } ) as any ) ;
338
356
if ( task == null ) throw Error ( "bug" ) ;
339
357
for ( let k in obj ) {
340
358
const v = obj [ k ] ;
@@ -405,7 +423,7 @@ export class TaskActions extends Actions<TaskState> {
405
423
const pos_j = tasks . getIn ( [ visible . get ( j ) , "position" ] ) ;
406
424
this . set_task ( task_id , { position : pos_j } , true ) ;
407
425
this . set_task ( visible . get ( j ) , { position : pos_i } , true ) ;
408
- this . scroll_into_view ( ) ;
426
+ this . scrollIntoView ( ) ;
409
427
}
410
428
411
429
public time_travel ( ) : void {
@@ -419,11 +437,14 @@ export class TaskActions extends Actions<TaskState> {
419
437
window . open ( TASKS_HELP_URL , "_blank" ) ?. focus ( ) ;
420
438
}
421
439
422
- public set_current_task ( task_id : string ) : void {
423
- if ( this . getFrameData ( "current_task_id" ) == task_id ) return ;
440
+ set_current_task = ( task_id : string ) : void => {
441
+ if ( this . getFrameData ( "current_task_id" ) == task_id ) {
442
+ return ;
443
+ }
424
444
this . setFrameData ( { current_task_id : task_id } ) ;
425
- this . scroll_into_view ( ) ;
426
- }
445
+ this . scrollIntoView ( ) ;
446
+ this . setFragment ( task_id ) ;
447
+ } ;
427
448
428
449
public set_current_task_delta ( delta : number ) : void {
429
450
const task_id = this . getFrameData ( "current_task_id" ) ;
@@ -492,7 +513,7 @@ export class TaskActions extends Actions<TaskState> {
492
513
this . set_task (
493
514
task_id ,
494
515
{ done : ! this . store . getIn ( [ "tasks" , task_id , "done" ] ) } ,
495
- true
516
+ true ,
496
517
) ;
497
518
}
498
519
}
@@ -523,15 +544,15 @@ export class TaskActions extends Actions<TaskState> {
523
544
524
545
public set_due_date (
525
546
task_id : string | undefined ,
526
- date : number | undefined
547
+ date : number | undefined ,
527
548
) : void {
528
549
this . set_task ( task_id , { due_date : date } ) ;
529
550
}
530
551
531
552
public set_desc (
532
553
task_id : string | undefined ,
533
554
desc : string ,
534
- save : boolean = true
555
+ save : boolean = true ,
535
556
) : void {
536
557
this . set_task ( task_id , { desc } , false , save ) ;
537
558
}
@@ -646,14 +667,57 @@ export class TaskActions extends Actions<TaskState> {
646
667
this . setFrameData ( { focus_find_box : false } ) ;
647
668
}
648
669
649
- async scroll_into_view ( ) : Promise < void > {
650
- await delay ( 50 ) ;
651
- this . setFrameData ( { scroll_into_view : true } ) ;
652
- }
670
+ setVirtuosoRef = ( virtuosoRef ) => {
671
+ this . virtuosoRef = virtuosoRef ;
672
+ } ;
653
673
654
- public scroll_into_view_done ( ) : void {
655
- this . setFrameData ( { scroll_into_view : false } ) ;
656
- }
674
+ // scroll the current_task_id into view, possibly changing filters
675
+ // in order to make it visibile, if necessary.
676
+ scrollIntoView = async ( align : Align = "view" ) => {
677
+ if ( this . virtuosoRef ?. current == null ) {
678
+ return ;
679
+ }
680
+ const current_task_id = this . getFrameData ( "current_task_id" ) ;
681
+ if ( current_task_id == null ) {
682
+ return ;
683
+ }
684
+ let visible = this . getFrameData ( "visible" ) ;
685
+ if ( visible == null ) {
686
+ return ;
687
+ }
688
+ // Figure out the index of current_task_id.
689
+ let index = visible . indexOf ( current_task_id ) ;
690
+ if ( index === - 1 ) {
691
+ const task = this . store . getIn ( [ "tasks" , current_task_id ] ) ;
692
+ if ( task == null ) {
693
+ // no such task anywhere, not even in trash, etc
694
+ return ;
695
+ }
696
+ if (
697
+ this . getFrameData ( "search_desc" ) ?. trim ( ) ||
698
+ task . get ( "deleted" ) ||
699
+ task . get ( "done" )
700
+ ) {
701
+ // active search -- try clearing it.
702
+ this . clearAllFilters ( {
703
+ show_deleted : ! ! task . get ( "deleted" ) ,
704
+ show_done : ! ! task . get ( "done" ) ,
705
+ } ) ;
706
+ visible = this . getFrameData ( "visible" ) ;
707
+ index = visible . indexOf ( current_task_id ) ;
708
+ if ( index == - 1 ) {
709
+ return ;
710
+ }
711
+ } else {
712
+ return ;
713
+ }
714
+ }
715
+ if ( align == "start" || align == "center" || align == "end" ) {
716
+ this . virtuosoRef . current . scrollToIndex ( { index, align } ) ;
717
+ } else {
718
+ this . virtuosoRef . current . scrollIntoView ( { index } ) ;
719
+ }
720
+ } ;
657
721
658
722
public set_show_max ( show_max : number ) : void {
659
723
this . set_local_view_state ( { show_max } , false ) ;
@@ -669,7 +733,7 @@ export class TaskActions extends Actions<TaskState> {
669
733
public toggle_desc_checkbox (
670
734
task_id : string ,
671
735
index : number ,
672
- checked : boolean
736
+ checked : boolean ,
673
737
) : void {
674
738
let desc = this . store . getIn ( [ "tasks" , task_id , "desc" ] ) ;
675
739
if ( desc == null ) {
@@ -738,6 +802,14 @@ export class TaskActions extends Actions<TaskState> {
738
802
. getProjectActions ( this . project_id )
739
803
. open_file ( { path, foreground : true } ) ;
740
804
}
805
+
806
+ setFragment = ( id ?) => {
807
+ if ( ! id ) {
808
+ Fragment . clear ( ) ;
809
+ } else {
810
+ Fragment . set ( { id } ) ;
811
+ }
812
+ } ;
741
813
}
742
814
743
815
function getPositions ( tasks ) : number [ ] {
0 commit comments