Skip to content

Commit fee5781

Browse files
committed
feat(boards): make project and scheduled or not work
1 parent fbd3f5e commit fee5781

File tree

9 files changed

+201
-23
lines changed

9 files changed

+201
-23
lines changed

src/app/features/boards/board-task-list/board-task-list.component.ts

+107-14
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,17 @@ import {
77
} from '@angular/core';
88
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
99
import { PlannerTaskComponent } from '../../planner/planner-task/planner-task.component';
10-
import { BoardPanelCfg, BoardPanelCfgTaskDoneState } from '../boards.model';
11-
import { Store } from '@ngrx/store';
12-
import { selectAllTasks } from '../../tasks/store/task.selectors';
10+
import {
11+
BoardPanelCfg,
12+
BoardPanelCfgScheduledState,
13+
BoardPanelCfgTaskDoneState,
14+
} from '../boards.model';
15+
import { select, Store } from '@ngrx/store';
16+
import {
17+
selectAllTasks,
18+
selectTaskById,
19+
selectTaskByIdWithSubTaskData,
20+
} from '../../tasks/store/task.selectors';
1321
import { toSignal } from '@angular/core/rxjs-interop';
1422
import { AddTaskInlineComponent } from '../../planner/add-task-inline/add-task-inline.component';
1523
import { T } from '../../../t.const';
@@ -18,7 +26,11 @@ import { TaskService } from '../../tasks/task.service';
1826
import { BoardsActions } from '../store/boards.actions';
1927
import { moveItemInArray } from '../../../util/move-item-in-array';
2028
import { unique } from '../../../util/unique';
21-
import { updateTask } from '../../tasks/store/task.actions';
29+
import {
30+
moveToOtherProject,
31+
unScheduleTask,
32+
updateTask,
33+
} from '../../tasks/store/task.actions';
2234
import { AsyncPipe } from '@angular/common';
2335
import { LocalDateStrPipe } from '../../../ui/pipes/local-date-str.pipe';
2436
import { MatIcon } from '@angular/material/icon';
@@ -28,6 +40,8 @@ import { PlannerService } from '../../planner/planner.service';
2840
import { DialogScheduleTaskComponent } from '../../planner/dialog-schedule-task/dialog-schedule-task.component';
2941
import { MatDialog } from '@angular/material/dialog';
3042
import { fastArrayCompare } from '../../../util/fast-array-compare';
43+
import { first, take } from 'rxjs/operators';
44+
import { PlannerActions } from '../../planner/store/planner.actions';
3145

3246
@Component({
3347
selector: 'board-task-list',
@@ -61,9 +75,13 @@ export class BoardTaskListComponent {
6175
allTasks = toSignal(this.allTasks$, {
6276
initialValue: [],
6377
});
78+
plannedTaskDayMap = toSignal(this.plannerService.plannedTaskDayMap$, {
79+
initialValue: {},
80+
});
6481

6582
additionalTaskFields = computed(() => {
6683
const panelCfg = this.panelCfg();
84+
6785
return {
6886
...(panelCfg.includedTagIds ? { tagIds: panelCfg.includedTagIds } : {}),
6987
// ...(panelCfg.projectId ? { projectId: panelCfg.projectId } : {}),
@@ -73,11 +91,16 @@ export class BoardTaskListComponent {
7391
...(panelCfg.taskDoneState === BoardPanelCfgTaskDoneState.UnDone
7492
? { isDone: false }
7593
: {}),
94+
...(panelCfg.projectId && panelCfg.projectId.length
95+
? { projectId: panelCfg.projectId }
96+
: {}),
97+
// TODO scheduledState
7698
};
7799
});
78100

79101
tasks = computed(() => {
80102
const panelCfg = this.panelCfg();
103+
const plannedTaskDayMap = this.plannedTaskDayMap();
81104
const orderedTasks: TaskCopy[] = [];
82105
const nonOrderedTasks: TaskCopy[] = [];
83106

@@ -102,6 +125,21 @@ export class BoardTaskListComponent {
102125
isTaskIncluded = isTaskIncluded && !task.isDone;
103126
}
104127

128+
if (panelCfg.projectId) {
129+
// TODO check parentId case thoroughly
130+
isTaskIncluded = isTaskIncluded && task.projectId === panelCfg.projectId;
131+
}
132+
133+
console.log(task.plannedAt, task);
134+
135+
if (panelCfg.scheduledState === BoardPanelCfgScheduledState.Scheduled) {
136+
isTaskIncluded = isTaskIncluded && (task.plannedAt || plannedTaskDayMap[task.id]);
137+
}
138+
139+
if (panelCfg.scheduledState === BoardPanelCfgScheduledState.NotScheduled) {
140+
isTaskIncluded = isTaskIncluded && !task.plannedAt && !plannedTaskDayMap[task.id];
141+
}
142+
105143
return isTaskIncluded;
106144
});
107145

@@ -116,7 +154,7 @@ export class BoardTaskListComponent {
116154
return [...orderedTasks, ...nonOrderedTasks].filter((t) => !!t);
117155
});
118156

119-
drop(ev: CdkDragDrop<BoardPanelCfg, string, TaskCopy>): void {
157+
async drop(ev: CdkDragDrop<BoardPanelCfg, string, TaskCopy>): Promise<void> {
120158
const panelCfg = ev.container.data;
121159
const task = ev.item.data;
122160
const prevTaskIds = this.tasks().map((t) => t.id);
@@ -135,37 +173,58 @@ export class BoardTaskListComponent {
135173
newTagIds = newTagIds.filter((tagId) => !panelCfg.excludedTagIds!.includes(tagId));
136174
}
137175

176+
const updates: Partial<TaskCopy> = {};
177+
138178
// conditional updates
139179
if (!fastArrayCompare(task.tagIds, newTagIds)) {
140180
this.taskService.updateTags(task, unique(newTagIds));
141181
}
142182
if (panelCfg.taskDoneState === BoardPanelCfgTaskDoneState.Done && !task.isDone) {
143-
this.store.dispatch(
144-
updateTask({ task: { id: task.id, changes: { isDone: true } } }),
145-
);
183+
updates.isDone = true;
146184
} else if (
147185
panelCfg.taskDoneState === BoardPanelCfgTaskDoneState.UnDone &&
148186
task.isDone
149187
) {
188+
updates.isDone = false;
189+
}
190+
191+
if (panelCfg.projectId?.length && task.projectId !== panelCfg.projectId) {
192+
const taskWithSubTasks = await this.store
193+
.pipe(
194+
select(selectTaskByIdWithSubTaskData, { id: task.parentId || task.id }),
195+
take(1),
196+
)
197+
.toPromise();
198+
150199
this.store.dispatch(
151-
updateTask({ task: { id: task.id, changes: { isDone: false } } }),
200+
moveToOtherProject({
201+
task: taskWithSubTasks,
202+
targetProjectId: panelCfg.projectId,
203+
}),
152204
);
153205
}
206+
207+
if (Object.keys(updates).length > 0) {
208+
this.store.dispatch(updateTask({ task: { id: task.id, changes: updates } }));
209+
}
210+
154211
this.store.dispatch(
155212
BoardsActions.updatePanelCfgTaskIds({
156213
panelId: panelCfg.id,
157214
taskIds,
158215
}),
159216
);
217+
218+
this._checkToScheduledTask(panelCfg, task.id);
160219
}
161220

162-
afterTaskAdd({
221+
async afterTaskAdd({
163222
taskId,
164223
isAddToBottom,
165224
}: {
166225
taskId: string;
167226
isAddToBottom: boolean;
168-
}): void {
227+
}): Promise<void> {
169228
const panelCfg = this.panelCfg();
170229
this.store.dispatch(
171230
BoardsActions.updatePanelCfgTaskIds({
@@ -175,14 +234,48 @@ export class BoardTaskListComponent {
175234
: [taskId, ...panelCfg.taskIds],
176235
}),
177236
);
237+
238+
this._checkToScheduledTask(panelCfg, taskId);
178239
}
179240

180-
scheduleTask(task: TaskCopy, ev: MouseEvent): void {
181-
ev.preventDefault();
182-
ev.stopPropagation();
241+
scheduleTask(task: TaskCopy, ev?: MouseEvent): void {
242+
ev?.preventDefault();
243+
ev?.stopPropagation();
183244
this._matDialog.open(DialogScheduleTaskComponent, {
184245
restoreFocus: true,
185246
data: { task },
186247
});
187248
}
249+
250+
private async _checkToScheduledTask(
251+
panelCfg: BoardPanelCfg,
252+
taskId: string,
253+
): Promise<void> {
254+
if (panelCfg.scheduledState === BoardPanelCfgScheduledState.Scheduled) {
255+
const task = await this.store
256+
.select(selectTaskById, { id: taskId })
257+
.pipe(first())
258+
.toPromise();
259+
if (!this.plannedTaskDayMap()[taskId] && !task.plannedAt) {
260+
this.scheduleTask(task);
261+
}
262+
}
263+
if (panelCfg.scheduledState === BoardPanelCfgScheduledState.NotScheduled) {
264+
const task = await this.store
265+
.select(selectTaskById, { id: taskId })
266+
.pipe(first())
267+
.toPromise();
268+
if (this.plannedTaskDayMap()[taskId]) {
269+
this.store.dispatch(PlannerActions.removeTaskFromDays({ taskId }));
270+
} else if (task.reminderId) {
271+
this.store.dispatch(
272+
unScheduleTask({
273+
id: taskId,
274+
reminderId: task.reminderId,
275+
isSkipToast: false,
276+
}),
277+
);
278+
}
279+
}
280+
}
188281
}

src/app/features/boards/boards-form.const.ts

+47-1
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import { LimitedFormlyFieldConfig } from '../config/global-config.model';
2-
import { BoardCfg, BoardPanelCfg, BoardPanelCfgTaskDoneState } from './boards.model';
2+
import {
3+
BoardCfg,
4+
BoardPanelCfg,
5+
BoardPanelCfgScheduledState,
6+
BoardPanelCfgTaskDoneState,
7+
} from './boards.model';
38
import { nanoid } from 'nanoid';
49
import { T } from '../../t.const';
510

611
const getNewPanel = (): BoardPanelCfg => ({
712
id: nanoid(),
813
title: '',
914
taskIds: [],
15+
1016
taskDoneState: BoardPanelCfgTaskDoneState.All,
1117
excludedTagIds: [],
1218
includedTagIds: [],
19+
scheduledState: BoardPanelCfgScheduledState.All,
20+
projectId: '',
1321
});
1422

1523
export const BOARDS_FORM: LimitedFormlyFieldConfig<BoardCfg>[] = [
@@ -96,6 +104,44 @@ export const BOARDS_FORM: LimitedFormlyFieldConfig<BoardCfg>[] = [
96104
],
97105
},
98106
},
107+
{
108+
key: 'scheduledState',
109+
type: 'radio',
110+
props: {
111+
// label: T.F.BOARDS.FORM.TASK_DONE_STATE,
112+
label: 'Scheduled State',
113+
required: true,
114+
defaultValue: BoardPanelCfgScheduledState.All,
115+
options: [
116+
{
117+
value: BoardPanelCfgScheduledState.All,
118+
// label: T.F.BOARDS.FORM.TASK_DONE_STATE_ALL,
119+
label: 'All',
120+
},
121+
{
122+
value: BoardPanelCfgScheduledState.Scheduled,
123+
// label: T.F.BOARDS.FORM.TASK_DONE_STATE_DONE,
124+
label: 'Scheduled',
125+
},
126+
{
127+
value: BoardPanelCfgScheduledState.NotScheduled,
128+
// label: T.F.BOARDS.FORM.TASK_DONE_STATE_UNDONE,
129+
label: 'Not Scheduled',
130+
},
131+
],
132+
},
133+
},
134+
{
135+
key: 'projectId',
136+
type: 'project-select',
137+
props: {
138+
// label: T.GCF.MISC.DEFAULT_PROJECT,
139+
label: 'Project',
140+
defaultValue: '',
141+
// nullLabel: T.F,
142+
nullLabel: 'All Projects',
143+
},
144+
},
99145
],
100146
},
101147
},

src/app/features/boards/boards.const.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { BoardCfg, BoardPanelCfgTaskDoneState } from './boards.model';
1+
import {
2+
BoardCfg,
3+
BoardPanelCfgScheduledState,
4+
BoardPanelCfgTaskDoneState,
5+
} from './boards.model';
26
import { IMPORTANT_TAG, IN_PROGRESS_TAG, URGENT_TAG } from '../tag/tag.const';
37
import { T } from '../../t.const';
48

@@ -16,6 +20,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
1620
excludedTagIds: [],
1721
taskIds: [],
1822
taskDoneState: BoardPanelCfgTaskDoneState.All,
23+
scheduledState: BoardPanelCfgScheduledState.All,
1924
},
2025
{
2126
id: 'NOT_URGENT_AND_IMPORTANT',
@@ -24,6 +29,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
2429
excludedTagIds: [URGENT_TAG.id],
2530
taskIds: [],
2631
taskDoneState: BoardPanelCfgTaskDoneState.All,
32+
scheduledState: BoardPanelCfgScheduledState.All,
2733
},
2834
{
2935
id: 'URGENT_AND_NOT_IMPORTANT',
@@ -32,6 +38,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
3238
excludedTagIds: [IMPORTANT_TAG.id],
3339
taskIds: [],
3440
taskDoneState: BoardPanelCfgTaskDoneState.All,
41+
scheduledState: BoardPanelCfgScheduledState.All,
3542
},
3643
{
3744
id: 'NOT_URGENT_AND_NOT_IMPORTANT',
@@ -40,6 +47,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
4047
excludedTagIds: [IMPORTANT_TAG.id, URGENT_TAG.id],
4148
taskIds: [],
4249
taskDoneState: BoardPanelCfgTaskDoneState.All,
50+
scheduledState: BoardPanelCfgScheduledState.All,
4351
},
4452
],
4553
},
@@ -55,6 +63,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
5563
includedTagIds: [],
5664
excludedTagIds: [IN_PROGRESS_TAG.id],
5765
taskIds: [],
66+
scheduledState: BoardPanelCfgScheduledState.All,
5867
},
5968
{
6069
id: 'IN_PROGRESS',
@@ -63,6 +72,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
6372
includedTagIds: [IN_PROGRESS_TAG.id],
6473
excludedTagIds: [],
6574
taskIds: [],
75+
scheduledState: BoardPanelCfgScheduledState.All,
6676
},
6777
{
6878
id: 'DONE',
@@ -71,6 +81,7 @@ export const DEFAULT_BOARDS: BoardCfg[] = [
7181
includedTagIds: [],
7282
excludedTagIds: [IN_PROGRESS_TAG.id],
7383
taskIds: [],
84+
scheduledState: BoardPanelCfgScheduledState.All,
7485
},
7586
],
7687
},

src/app/features/boards/boards.model.ts

+8
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,19 @@ export enum BoardPanelCfgTaskDoneState {
44
UnDone = 3,
55
}
66

7+
export enum BoardPanelCfgScheduledState {
8+
All = 1,
9+
Scheduled = 2,
10+
NotScheduled = 3,
11+
}
12+
713
export interface BoardSrcCfg {
814
// projectId?: string;
915
includedTagIds: string[];
1016
excludedTagIds: string[];
17+
projectId?: string;
1118
taskDoneState: BoardPanelCfgTaskDoneState;
19+
scheduledState: BoardPanelCfgScheduledState;
1220
}
1321

1422
export interface BoarFieldsToRemove {

0 commit comments

Comments
 (0)