Skip to content

Commit

Permalink
feat(): update task swimlane
Browse files Browse the repository at this point in the history
  • Loading branch information
develite98 committed Nov 7, 2023
1 parent 828d89b commit 23cfb55
Show file tree
Hide file tree
Showing 22 changed files with 320 additions and 133 deletions.
25 changes: 11 additions & 14 deletions apps/mix-cms/src/app/components/messenger/messenger.component.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
<div class="messenger-box">
<div class="messenger-box__header">
<span class="messenger-box__header-title"> Global Message </span>
<!-- <button [appearance]="'outline'"
[size]="'s'"
(click)="toggleMinimize()"
tuiButton>
{{ minimize ? 'Show' : 'Close'}}
</button> -->
</div>

<div #messageContainer
class="messenger-box__content">
<div #messageContainer class="messenger-box__content">
<span class="messenger-box__date">{{ date | date }}</span>
<ng-container *ngFor="let message of displayMessages">
<mix-messenger-message [fromAnother]="message.fromAnother"
[message]="message"></mix-messenger-message>
<mix-messenger-message
[fromAnother]="message.fromAnother"
[message]="message"
></mix-messenger-message>
</ng-container>
</div>

<div class="messenger-box__chat-zone">
<tui-text-area [expandable]="false"
[formControl]="message"
[maxLength]="100"
(keydown.enter)="submitMessage($event)">
<tui-text-area
[expandable]="false"
[formControl]="message"
[maxLength]="100"
(keydown.enter)="submitMessage($event)"
>
Press enter to send message
</tui-text-area>
<mix-emoji-picker (emojiSelect)="emojiSelect($event)"></mix-emoji-picker>
Expand Down
2 changes: 2 additions & 0 deletions apps/mix-cms/src/assets/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ html {
--text-size-l: 1.125rem;
--text-size-xl: 1.25rem;
--text-size-xxl: 1.5rem;

--blue-02: #008aa8;
}

html[mode='dark'] {
Expand Down
2 changes: 2 additions & 0 deletions apps/mix-kanban/src/assets/styles/variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ html {
--text-size-l: 1.125rem;
--text-size-xl: 1.25rem;
--text-size-xxl: 1.5rem;

--blue-02: #008aa8;
}

html[mode='dark'] {
Expand Down
32 changes: 16 additions & 16 deletions libs/mix-lib/src/model/core/mix-task.model.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,3 @@
export interface MixTask {
title: string;
id: number;
createdDateTime: Date;
description?: string;
taskStatus: 'New' | 'ReadyForTest' | 'InProgress' | 'Done';
assignee: string;
}

export enum TaskType {
STORY = 'Story',
TASK = 'Task',
BUG = 'Bug',
}

export enum TaskStatus {
BACKLOG = 'Backlog',
SELECTED = 'Selected',
Expand All @@ -22,11 +7,18 @@ export enum TaskStatus {

export const TaskStatusDisplay = {
[TaskStatus.BACKLOG]: 'Backlog',
[TaskStatus.SELECTED]: 'Selected for Development',
[TaskStatus.SELECTED]: 'Ready for Dev',
[TaskStatus.IN_PROGRESS]: 'In progress',
[TaskStatus.DONE]: 'Done',
};

export const TaskStatusColors = {
[TaskStatus.BACKLOG]: 'rgb(112, 114, 143)',
[TaskStatus.SELECTED]: 'rgb(228, 64, 87)',
[TaskStatus.IN_PROGRESS]: 'rgb(228, 124, 64)',
[TaskStatus.DONE]: 'rgb(168, 228, 64)',
};

export enum TaskPriority {
LOWEST = 'Lowest',
LOW = 'Low',
Expand All @@ -51,6 +43,13 @@ export const TaskPriorityIcon = {
[TaskPriority.LOWEST]: 'arrow_downward',
};

export enum TaskType {
STORY = 'Story',
TASK = 'Task',
BUG = 'Bug',
SWIMLANE = 'Swimlane',
}

export const TaskTypeIcons = {
[TaskType.BUG]: 'assets/images/tasks/bug.svg',
[TaskType.TASK]: 'assets/images/tasks/task.svg',
Expand All @@ -74,4 +73,5 @@ export interface MixTaskNew {
userIds: string[];
projectId?: string;
priority: number;
parentTaskId?: number;
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
<div class="task-create"
[formGroup]="taskForm">
<div class="task-create" [formGroup]="taskForm">
<div class="text-l">Create Task</div>

<div class="mt-4 mb-1 text-sub text-500">Task Type</div>
<mix-select [items]="typeItems"
[labelProcess]="typeLabel"
formControlName="type"></mix-select>
<ng-container *ngIf="parentTask">
<div class="mt-4 mb-1 text-sub text-500">Task Type</div>
<mix-select
[items]="typeItems"
[labelProcess]="typeLabel"
formControlName="type"
></mix-select>

<div class="mt-3 mb-1 text-sub text-500">Task Priority</div>
<mix-select [items]="prorityItems"
[labelProcess]="priorityLabel"
formControlName="taskPriority"></mix-select>
<div class="mt-3 mb-1 text-sub text-500">Task Priority</div>
<mix-select
[items]="prorityItems"
[labelProcess]="priorityLabel"
formControlName="taskPriority"
></mix-select>
</ng-container>

<div class="mt-3 mb-1 text-sub text-500">Short Summary</div>
<mix-input formControlName="title"
placeHolder="Quick description about your task"></mix-input>
<mix-input
formControlName="title"
placeHolder="Quick description about your task"
></mix-input>

<div class="mt-3 mb-1 text-sub text-500">Description</div>
<mix-rich-text-editor formControlName="description"></mix-rich-text-editor>

<div class="mt-3 mb-1 text-sub text-500">Reporter</div>
<mix-user-select formControlName="reporter"></mix-user-select>

<div *ngIf="loadingState$ | async as state"
class="mt-4 d-flex justify-content-end align-items-center gap-2">
<mix-button [loading]="state === 'Loading'"
(click)="createTask()">Create</mix-button>
<mix-button type="outline"
[disabled]="state === 'Loading'"
(click)="dialogRef.close()">Cancel</mix-button>
<div
*ngIf="loadingState$ | async as state"
class="mt-4 d-flex justify-content-end align-items-center gap-2"
>
<mix-button [loading]="state === 'Loading'" (click)="createTask()"
>Create</mix-button
>
<mix-button
type="outline"
[disabled]="state === 'Loading'"
(click)="dialogRef.close()"
>Cancel</mix-button
>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export class TaskCreateComponent extends BaseComponent {
public taskStore = inject(TaskStore);
public dialogRef = inject(DialogRef);
public toast = inject(HotToastService);
public parentTask?: MixTaskNew;

public typeLabel = (type: TaskType) => type;
public typeItems = [TaskType.BUG, TaskType.STORY, TaskType.TASK];
Expand All @@ -66,8 +67,18 @@ export class TaskCreateComponent extends BaseComponent {
taskStatus: new FormControl(TaskStatus.BACKLOG),
reporter: new FormControl(),
priority: new FormControl(999),
parentTaskId: new FormControl(),
});

public ngOnInit() {
this.parentTask = this.dialogRef.data?.['parentTask'];
if (this.parentTask) {
this.taskForm.controls.parentTaskId.patchValue(this.parentTask.id);
} else {
this.taskForm.controls.type.patchValue(TaskType.SWIMLANE);
}
}

public createTask() {
if (FormHelper.validateForm(this.taskForm)) {
this.taskService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ export class TaskDetailModalComponent extends BaseComponent implements OnInit {
.saveTask(value as MixTaskNew)
.pipe(this.observerLoadingState())
.subscribe({
next: (result) => {
next: () => {
this.toast.success('Success update your task');
this.taskStore.addTask(result as unknown as MixTaskNew, 'Update');
if (close )this.dialogRef.close();
this.taskStore.addTask(value as unknown as MixTaskNew, 'Update');
if (close) this.dialogRef.close();
},
error: () => {
this.toast.error('Something error, please try again');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<div class="task-list">
<div class="title text-uppercase text-truncate">
{{ TaskStatusDisplay[status] }} {{ tasks.length }}
</div>

<div class="items"
[cdkDropListData]="tasks"
[id]="status"
(cdkDropListDropped)="drop($event)"
cdkDropList>
<mix-task-card *ngFor="let task of tasks"
[cdkDragData]="task"
[task]="task"
cdkDrag>
<div
class="items"
[cdkDropListData]="tasks"
[id]="status"
(cdkDropListDropped)="drop($event)"
cdkDropList
>
<mix-task-card
*ngFor="let task of tasks"
[cdkDragData]="task"
[task]="task"
cdkDrag
>
</mix-task-card>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@
.items {
flex-grow: 1;
}

.title {
margin-top: 8px;
margin-bottom: 14px;
padding-left: 8px;
}
}

.cdk-drag-preview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,14 @@ import {
ViewEncapsulation,
inject,
} from '@angular/core';
import {
MixTask,
MixTaskNew,
TaskStatus,
TaskStatusDisplay,
} from '@mixcore/lib/model';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { MixTaskNew, TaskStatus } from '@mixcore/lib/model';
import { HotToastService } from '@ngneat/hot-toast';
import { Observable, combineLatest, forkJoin } from 'rxjs';
import { TaskCardComponent } from '../task-card/task-card.component';
import { TaskFilterStore } from '../../store/filter.store';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { TaskStore } from '../../store/task.store';
import { TaskService } from '../../store/task.service';
import { HotToastService } from '@ngneat/hot-toast';
import { TaskStore } from '../../store/task.store';
import { TaskCardComponent } from '../task-card/task-card.component';

@Component({
selector: 'mix-task-dnd-list',
Expand All @@ -43,8 +38,7 @@ export class TaskDndListComponent implements OnInit {
public taskService = inject(TaskService);
public toast = inject(HotToastService);

public TaskStatusDisplay = TaskStatusDisplay;

@Input() public parentTaskId?: number;
@Input() public status!: TaskStatus;
@Input() public listTasks!: Observable<MixTaskNew[]>;
public tasks: MixTaskNew[] = [];
Expand Down Expand Up @@ -96,7 +90,12 @@ export class TaskDndListComponent implements OnInit {

private updateListPosition(newList: MixTaskNew[]) {
const requests = newList.map((issue, idx) => {
const newIssueWithNewPosition = { ...issue, priority: idx + 1 };
const newIssueWithNewPosition = {
...issue,
priority: idx + 1,
parentTaskId: this.parentTaskId,
};

this.taskStore.addTask(newIssueWithNewPosition, 'Update');
return this.taskService.saveTask(newIssueWithNewPosition);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<mix-task-parent-card
[task]="parentTask"
[open]="open()"
(expandClick)="toggleExpand()"
></mix-task-parent-card>

<div class="task-group" cdkDropListGroup *ngIf="open()">
<mix-task-dnd-list
*ngFor="let status of taskStatuses"
class="task-dnd-list"
[listTasks]="store.getTaskByStatus(status, parentTask.id)"
[status]="status"
[parentTaskId]="parentTask.id"
>
</mix-task-dnd-list>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.task-group {
display: flex;
width: 100%;
gap: 12px;
}

.task-dnd-list {
display: block;
min-height: 160px;
min-width: var(--task-min-col-w);
width: var(--task-col-w);
background-color: var(--task-list-bg);
border-radius: 0.125rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { CommonModule } from '@angular/common';
import { Component, Input, inject, signal } from '@angular/core';
import { MixTaskNew, TaskStatus, TaskStatusDisplay } from '@mixcore/lib/model';
import { TaskStore } from '../../store/task.store';
import { TaskDndListComponent } from '../task-dnd-list/task-dnd-list.component';
import { TaskParentCardComponent } from '../task-parent-card/task-parent-card.component';

@Component({
selector: 'mix-task-group-list',
standalone: true,
imports: [CommonModule, TaskDndListComponent, TaskParentCardComponent],
templateUrl: './task-group-list.component.html',
styleUrls: ['./task-group-list.component.scss'],
})
export class TaskGroupListComponent {
@Input() public parentTask!: MixTaskNew;
@Input() public showHeader = false;
@Input() public taskStatuses: TaskStatus[] = [];

public TaskStatusDisplay = TaskStatusDisplay;
public store = inject(TaskStore);
public open = signal(true);

public toggleExpand() {
this.open.set(!this.open());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<div class="w-100 task-parent-card text-m" [class.--open]="open">
<mix-button [size]="'xs'" [type]="'icon'" (click)="expandClick.emit()"
><span class="mix-icon expand-icon text-xxl">expand_more</span>
</mix-button>

<span>
{{ task.title }}
</span>

<mix-button class="ms-2" [size]="'xs'" [iconBtn]="true" (click)="addTask()">
<span class="mix-icon text-xxl">add</span>
</mix-button>
</div>
Loading

0 comments on commit 23cfb55

Please sign in to comment.