mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-29 10:40:12 +00:00
feat(boards): make super basic drag & drop work
This commit is contained in:
parent
d9af59e619
commit
963701ac7f
9 changed files with 69 additions and 8 deletions
|
|
@ -1,6 +1,10 @@
|
|||
<!--[cdkDropListData]="panelCfg()"-->
|
||||
|
||||
<div
|
||||
class="task-items"
|
||||
cdkDropList
|
||||
[cdkDropListData]="panelCfg()"
|
||||
(cdkDropListDropped)="drop($event)"
|
||||
>
|
||||
@for (task of tasks(); track task.id) {
|
||||
<planner-task
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
max-height: 100%;
|
||||
padding: 0 8px;
|
||||
min-height: 60px;
|
||||
border: 1px dashed transparent;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.empty {
|
||||
|
|
|
|||
|
|
@ -5,14 +5,16 @@ import {
|
|||
inject,
|
||||
input,
|
||||
} from '@angular/core';
|
||||
import { CdkDrag, CdkDropList } from '@angular/cdk/drag-drop';
|
||||
import { CdkDrag, CdkDragDrop, CdkDropList } from '@angular/cdk/drag-drop';
|
||||
import { PlannerTaskComponent } from '../../planner/planner-task/planner-task.component';
|
||||
import { BoardPanelCfg } from '../boards.model';
|
||||
import { BoardPanelCfg, BoarFieldsToRemove } from '../boards.model';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { selectAllTasks } from '../../tasks/store/task.selectors';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { AddTaskInlineComponent } from '../../planner/add-task-inline/add-task-inline.component';
|
||||
import { T } from '../../../t.const';
|
||||
import { TaskCopy } from '../../tasks/task.model';
|
||||
import { TaskService } from '../../tasks/task.service';
|
||||
|
||||
@Component({
|
||||
selector: 'board-task-list',
|
||||
|
|
@ -23,10 +25,11 @@ import { T } from '../../../t.const';
|
|||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BoardTaskListComponent {
|
||||
// tasks = input.required<TaskCopy[]>();
|
||||
panelCfg = input.required<BoardPanelCfg>();
|
||||
fieldsToRemove = input.required<BoarFieldsToRemove>();
|
||||
|
||||
store = inject(Store);
|
||||
taskService = inject(TaskService);
|
||||
|
||||
allTasks$ = this.store.select(selectAllTasks);
|
||||
allTasks = toSignal(this.allTasks$, {
|
||||
|
|
@ -51,4 +54,22 @@ export class BoardTaskListComponent {
|
|||
});
|
||||
});
|
||||
protected readonly T = T;
|
||||
|
||||
drop(ev: CdkDragDrop<BoardPanelCfg, string, TaskCopy>): void {
|
||||
const panelCfg = ev.container.data;
|
||||
const task = ev.item.data;
|
||||
const fieldsToRemove = this.fieldsToRemove();
|
||||
let newTagIds: string[] = [];
|
||||
if (fieldsToRemove.tagIds?.length) {
|
||||
newTagIds = task.tagIds.filter((tagId) => !fieldsToRemove.tagIds!.includes(tagId));
|
||||
}
|
||||
if (panelCfg.tagIds) {
|
||||
newTagIds = newTagIds.concat(panelCfg.tagIds);
|
||||
}
|
||||
|
||||
this.taskService.updateTags(task, newTagIds);
|
||||
// const allTasks = this.tasks();
|
||||
|
||||
console.log(ev, panelCfg, task);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@
|
|||
<mat-icon>more_vert</mat-icon>
|
||||
</button>
|
||||
</header>
|
||||
<board-task-list [panelCfg]="panel"></board-task-list>
|
||||
<board-task-list
|
||||
[panelCfg]="panel"
|
||||
[fieldsToRemove]="fieldsToRemove()"
|
||||
></board-task-list>
|
||||
</div>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||
import { BoardCfg } from '../boards.model';
|
||||
import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';
|
||||
import { BoardCfg, BoarFieldsToRemove } from '../boards.model';
|
||||
import { BoardTaskListComponent } from '../board-task-list/board-task-list.component';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
|
|
@ -19,4 +19,15 @@ import { MatIcon } from '@angular/material/icon';
|
|||
})
|
||||
export class BoardComponent {
|
||||
boardCfg = input.required<BoardCfg>();
|
||||
fieldsToRemove = computed<BoarFieldsToRemove>(() => {
|
||||
const tagIdsToRemove: string[] = [];
|
||||
this.boardCfg().panels.forEach((panel) => {
|
||||
if (panel.tagIds) {
|
||||
tagIdsToRemove.push(...panel.tagIds);
|
||||
}
|
||||
});
|
||||
return {
|
||||
tagIds: tagIdsToRemove,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
<mat-tab-group
|
||||
mat-stretch-tabs="false"
|
||||
dynamicHeight="true"
|
||||
cdkScrollable
|
||||
>
|
||||
@for (board of boards(); track board.id) {
|
||||
<mat-tab [label]="board.title">
|
||||
<board [boardCfg]="board"></board>
|
||||
<board
|
||||
[boardCfg]="board"
|
||||
cdkDropListGroup
|
||||
></board>
|
||||
</mat-tab>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,22 @@ import { T } from '../../t.const';
|
|||
import { MatIcon } from '@angular/material/icon';
|
||||
import { DEFAULT_BOARDS } from './boards.const';
|
||||
import { BoardComponent } from './board/board.component';
|
||||
import { CdkScrollable } from '@angular/cdk/overlay';
|
||||
import { CdkDropListGroup } from '@angular/cdk/drag-drop';
|
||||
|
||||
@Component({
|
||||
selector: 'boards',
|
||||
standalone: true,
|
||||
imports: [MatTabGroup, MatTab, MatIcon, MatTabContent, MatTabLabel, BoardComponent],
|
||||
imports: [
|
||||
MatTabGroup,
|
||||
MatTab,
|
||||
MatIcon,
|
||||
MatTabContent,
|
||||
MatTabLabel,
|
||||
BoardComponent,
|
||||
CdkScrollable,
|
||||
CdkDropListGroup,
|
||||
],
|
||||
templateUrl: './boards.component.html',
|
||||
styleUrl: './boards.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ export interface BoardSrcCfg {
|
|||
filterTaskState?: number[];
|
||||
}
|
||||
|
||||
export interface BoarFieldsToRemove {
|
||||
tagIds?: string[];
|
||||
}
|
||||
|
||||
export interface BoardPanelCfg extends BoardSrcCfg {
|
||||
id: string;
|
||||
title: string;
|
||||
|
|
|
|||
|
|
@ -205,6 +205,7 @@ mat-icon.mat-icon[svgicon] {
|
|||
|
||||
.cdk-drop-list-receiving {
|
||||
outline: 1px dashed $c-primary;
|
||||
border-color: $c-primary;
|
||||
border-radius: 6px;
|
||||
cursor: grabbing;
|
||||
//border: 2px solid green;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue