src/app/dialogs/create-label-dialog/create-edit-label-dialog.component.ts
This dialog creates or edits a label.
See CreateEditLabelDialogData for parameters.
selector | app-create-edit-label-dialog-component |
styleUrls | ./create-edit-label-dialog.component.scss |
templateUrl | ./create-edit-label-dialog.component.html |
Properties |
Methods |
constructor(dialog: MatDialogRef<CreateEditLabelDialogComponent | Label>, dataService: DataService, data: CreateEditLabelDialogData, notify: UserNotifyService)
|
|||||||||||||||
Parameters :
|
onConfirmClick |
onConfirmClick(name: string, description?: string)
|
When the user confirms their changes, attempt to mutate and return with the label data.
Returns :
void
|
onLabelCancelClick |
onLabelCancelClick()
|
When the user cancels label creation or editing, close and return with null.
Returns :
void
|
randomizeColor |
randomizeColor()
|
Randomizes the label color.
Returns :
void
|
allComponentsList |
Type : ListId
|
Source list of all components. |
color |
Type : string
|
Default value : '#000000'
|
Color state. |
componentList |
Type : NodeId[] | ListId
|
Default value : []
|
Component list to be edited. For new labels, this is a list of node IDs. For existing labels, this is a ListId. |
Public data |
Type : CreateEditLabelDialogData
|
Decorators :
@Inject(MAT_DIALOG_DATA)
|
loading |
Default value : false
|
If true, the label that is to be edited is still loading. |
validationLabelDescription |
Default value : new FormControl('', CCIMSValidators.contentValidator)
|
Validator for the label description. |
validationLabelName |
Default value : new FormControl('', [Validators.required, Validators.maxLength(30)])
|
Validator for the label name. |
import {Component, Inject, OnInit} from '@angular/core';
import {FormControl, Validators} from '@angular/forms';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {UserNotifyService} from '@app/user-notify/user-notify.service';
import {CCIMSValidators} from '@app/utils/validators';
import {encodeNodeId, ListId, ListType, NodeId} from '@app/data-dgql/id';
import DataService from '@app/data-dgql';
import {ComponentFilter, Label} from '../../../generated/graphql-dgql';
/** Parameters for the create/edit label dialog component. */
export interface CreateEditLabelDialogData {
/** The raw project id. */
projectId: NodeId;
/** If set, will edit an existing label instead of creating a new one. */
editExisting?: NodeId;
/** If set, will select all components of this issue */
issueId?: NodeId[];
}
/**
* This dialog creates or edits a label.
*
* See {@link CreateEditLabelDialogData} for parameters.
*/
@Component({
selector: 'app-create-edit-label-dialog-component',
templateUrl: './create-edit-label-dialog.component.html',
styleUrls: ['./create-edit-label-dialog.component.scss']
})
export class CreateEditLabelDialogComponent implements OnInit {
/** Validator for the label name. */
validationLabelName = new FormControl('', [Validators.required, Validators.maxLength(30)]);
/** Validator for the label description. */
validationLabelDescription = new FormControl('', CCIMSValidators.contentValidator);
/** Color state. */
color = '#000000';
/** If true, the label that is to be edited is still loading. */
loading = false;
/** Component list to be edited. For new labels, this is a list of node IDs. For existing labels, this is a ListId. */
componentList: NodeId[] | ListId = [];
/** Source list of all components. */
allComponentsList: ListId;
constructor(
private dialog: MatDialogRef<CreateEditLabelDialogComponent, Label>,
private dataService: DataService,
@Inject(MAT_DIALOG_DATA) public data: CreateEditLabelDialogData,
private notify: UserNotifyService
) {}
ngOnInit() {
if (this.data.editExisting) {
this.componentList = {
node: this.data.editExisting,
type: ListType.Components
};
this.loading = true;
const node = this.dataService.getNode<Label>(this.data.editExisting);
// reload data from source
node.invalidate();
node.load();
node
.dataAsPromise()
.then((data) => {
this.validationLabelName.setValue(data.name);
this.color = data.color;
this.validationLabelDescription.setValue(data.description);
})
.catch(() => {
this.notify.notifyError('Could not load label data for editing');
this.dialog.close(null);
})
.finally(() => {
this.loading = false;
});
} else {
this.randomizeColor();
if (this.data.issueId) {
this.componentList = this.data.issueId;
}
}
this.allComponentsList = {
node: this.data.projectId,
type: ListType.Components
};
}
/** @ignore used for set editor */
makeComponentFilter(search): ComponentFilter {
return {name: search};
}
/** @ignore used for set editor */
applyComponentChangeset = async (additions: NodeId[], deletions: NodeId[]): Promise<void> => {
if (Array.isArray(this.componentList)) {
const keySet = new Set(this.componentList.map((id) => encodeNodeId(id)));
for (const item of additions) {
if (!keySet.has(encodeNodeId(item))) {
this.componentList.push(item);
keySet.add(encodeNodeId(item));
}
}
for (const item of deletions) {
if (keySet.has(encodeNodeId(item))) {
this.componentList.splice(this.componentList.indexOf(item), 1);
keySet.delete(encodeNodeId(item));
}
}
} else {
for (const item of additions) {
await this.dataService.mutations.addLabelToComponent(Math.random().toString(), this.data.editExisting, item);
}
for (const item of deletions) {
await this.dataService.mutations.removeLabelFromComponent(Math.random().toString(), this.data.editExisting, item);
}
}
};
/** When the user cancels label creation or editing, close and return with null. */
onLabelCancelClick(): void {
this.dialog.close(null);
}
/** When the user confirms their changes, attempt to mutate and return with the label data. */
onConfirmClick(name: string, description?: string): void {
this.loading = true;
if (this.data.editExisting) {
this.dataService.mutations
.updateLabel(Math.random().toString(), this.data.editExisting, name, this.color, description)
.then(() => {
this.dialog.close({
id: this.data.editExisting.id,
name,
color: this.color,
description
} as Label);
})
.catch((error) => {
this.notify.notifyError('Failed to update label!', error);
})
.finally(() => {
this.loading = false;
});
} else {
this.dataService.mutations
.createLabel(Math.random().toString(), this.componentList as NodeId[], name, this.color, description)
.then((created) => {
this.dialog.close(created as Label);
})
.catch((error) => {
this.notify.notifyError('Failed to create label!', error);
})
.finally(() => {
this.loading = false;
});
}
}
/** Randomizes the label color. */
randomizeColor(): void {
const r = `00${(Math.random() * 0xff).toString(16)}`.slice(-2);
const g = `00${(Math.random() * 0xff).toString(16)}`.slice(-2);
const b = `00${(Math.random() * 0xff).toString(16)}`.slice(-2);
this.color = '#' + r + g + b;
}
}
<h1 mat-dialog-title>
<ng-container *ngIf="data.editExisting"> Update label </ng-container>
<ng-container *ngIf="!data.editExisting"> Create a new label </ng-container>
</h1>
<div mat-dialog-content>
<app-set-editor
class="component-selector"
[makeFilter]="makeComponentFilter"
[scoreKeys]="['name']"
[listSet]="componentList"
[listAll]="allComponentsList"
[applyChangeset]="applyComponentChangeset"
#list
>
<span title>Components</span>
<span if-empty style="color: red">Assign the label to a component</span>
<ng-container *appItem="let item">
<div>{{ item.name }}</div>
</ng-container>
</app-set-editor>
<mat-form-field class="new-label-input" appearance="outline">
<mat-label>Label Name</mat-label>
<input #labelName required matInput [formControl]="validationLabelName" />
<mat-error *ngIf="validationLabelName.invalid">Invalid name</mat-error>
</mat-form-field>
<mat-form-field class="new-label-input" appearance="outline">
<mat-label>Description</mat-label>
<input #labelDescription matInput [formControl]="validationLabelDescription" />
</mat-form-field>
<mat-form-field class="new-label-input" floatLabel="always" appearance="outline">
<mat-label>Color</mat-label>
<input
matInput
readonly
[style.background]="color"
autocomplete="off"
[(colorPicker)]="this.color"
[cpAlphaChannel]="'disabled'"
[cpPosition]="'bottom'"
/>
<button mat-icon-button class="color-randomize-button" matSuffix (click)="this.randomizeColor()">
<mat-icon>refresh</mat-icon>
</button>
</mat-form-field>
</div>
<div mat-dialog-actions class="actions">
<button mat-raised-button color="warn" (click)="this.onLabelCancelClick()">Cancel</button>
<button
mat-raised-button
color="success"
[disabled]="loading || validationLabelName.invalid || !list.totalCount"
(click)="this.onConfirmClick(labelName.value, labelDescription.value)"
>
<ng-container *ngIf="data.editExisting"> Apply </ng-container>
<ng-container *ngIf="!data.editExisting"> Create </ng-container>
</button>
</div>
./create-edit-label-dialog.component.scss
.component-selector {
margin-bottom: 16px;
}
.new-label-input {
padding: 6px;
width: 100%;
}
.error-label-create {
background-color: rgb(204, 58, 58);
color: white;
margin-top: 5px;
}
.color-randomize-button {
margin-left: 4px;
}
.mat-success {
background-color: green;
color: #fff;
}
.actions {
float: right;
}