Skip to content

Commit

Permalink
Extract checklist item as a component
Browse files Browse the repository at this point in the history
  • Loading branch information
rdamazio committed Apr 21, 2024
1 parent 15639d8 commit d721507
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 138 deletions.
63 changes: 63 additions & 0 deletions src/app/checklists/items-list/item/item.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
@if (item) {
<mat-icon
cdkDragHandle
class="mat-icon-rtl-mirror item-icon drag-icon"
fontIcon="drag_handle" />
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
(click)="promptInput.edit(); expectationInput.edit()"
[attr.aria-label]="'Edit ' + item.prompt">
<mat-icon fontIcon="edit" />
</button>
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
[attr.aria-label]="'Indent ' + item.prompt + ' left'"
[disabled]="item.indent == 0"
(click)="onIndent(item, -1)">
<mat-icon fontIcon="format_indent_decrease" />
</button>
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
[attr.aria-label]="'Indent ' + item.prompt + ' right'"
[disabled]="item.indent == 4"
(click)="onIndent(item, 1)">
<mat-icon fontIcon="format_indent_increase" />
</button>
<span
class="item"
[class.item-prompt]="item.type == ChecklistItem_Type.ITEM_PROMPT"
[class.item-title]="item.type == ChecklistItem_Type.ITEM_TITLE"
[class.item-warning]="item.type == ChecklistItem_Type.ITEM_WARNING"
[class.item-caution]="item.type == ChecklistItem_Type.ITEM_CAUTION"
[class.item-note]="item.type == ChecklistItem_Type.ITEM_NOTE"
[class.item-space]="item.type == ChecklistItem_Type.ITEM_SPACE"
[style.padding-left]="item.indent*25 + 'px'">
<!-- TODO: Find a better solution than to save/cancel independent fields together -->
<editable-label
#promptInput
class="prompt-input"
label="Prompt text"
[value]="item.prompt"
(valueChanged)="item.prompt = promptInput.value; onItemUpdated(item); expectationInput.cancel();"
(cancelled)="expectationInput.cancel()" />
</span>
<span [hidden]="item.type !== ChecklistItem_Type.ITEM_PROMPT">
<!-- TODO: Make the dots fill the center space and nothing more -->
<span class="prompt-spacer" *ngIf="!expectationInput.editing">........................</span>
<span class="prompt-expectation">
<editable-label
#expectationInput
class="expectation-input"
label="Expectation text"
[value]="item.expectation"
(valueChanged)="item.expectation = expectationInput.value; onItemUpdated(item); promptInput.cancel();"
(cancelled)="promptInput.cancel()" />
</span>
</span>
}
62 changes: 62 additions & 0 deletions src/app/checklists/items-list/item/item.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.item {
vertical-align: middle;
}

.item-title {
color: white;
}

.item-caution {
color: red;
}

.item-caution:before {
padding: 10px;
content: "CAUTION:"
}

.item-warning {
color: yellow;
}

.item-warning:before {
padding: 10px;
content: "WARNING:"
}

.item-note {
color: gray;
}

.item-note:before {
padding: 10px;
content: "NOTE:"
}

.prompt-spacer {
text-wrap: nowrap;
overflow: hidden;
letter-spacing: 10px;
}

.prompt-expectation {
float: right;
color: cyan;
}

// TODO: Make this work without ng-deep
::ng-deep .prompt-input mat-form-field {
width: 400px;
}
::ng-deep .prompt-expectation mat-form-field {
width: 300px;
}

.item-icon {
vertical-align: middle;
}

.drag-icon {
cursor: move;
}

23 changes: 23 additions & 0 deletions src/app/checklists/items-list/item/item.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ChecklistItemComponent } from './item.component';

describe('ChecklistItemComponent', () => {
let component: ChecklistItemComponent;
let fixture: ComponentFixture<ChecklistItemComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ChecklistItemComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ChecklistItemComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
37 changes: 37 additions & 0 deletions src/app/checklists/items-list/item/item.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { CdkDragHandle } from '@angular/cdk/drag-drop';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatIconButtonSizesModule } from 'mat-icon-button-sizes';
import { EditableLabelComponent } from '../editable-label/editable-label.component';
import { NgIf } from '@angular/common';
import { ChecklistItem, ChecklistItem_Type } from '../../../../../gen/ts/checklist';

@Component({
selector: 'checklist-item',
standalone: true,
imports: [
CdkDragHandle,
EditableLabelComponent,
MatButtonModule,
MatIconButtonSizesModule,
MatIconModule,
NgIf,
],
templateUrl: './item.component.html',
styleUrl: './item.component.scss'
})
export class ChecklistItemComponent {
@Input() item!: ChecklistItem;
@Output() itemChanged = new EventEmitter<ChecklistItem>();
readonly ChecklistItem_Type = ChecklistItem_Type;

onIndent(item: ChecklistItem, delta: number) {
item.indent += delta;
this.onItemUpdated(item);
}

onItemUpdated(item: ChecklistItem) {
this.itemChanged.emit(this.item);
}
}
64 changes: 3 additions & 61 deletions src/app/checklists/items-list/items-list.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,67 +10,9 @@
class="list-item"
cdkDrag
cdkDragLockAxis="y">
<mat-icon
cdkDragHandle
class="mat-icon-rtl-mirror item-icon drag-icon"
fontIcon="drag_handle" />
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
(click)="promptInput.edit(); expectationInput.edit()"
[attr.aria-label]="'Edit ' + item.prompt">
<mat-icon fontIcon="edit" />
</button>
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
[attr.aria-label]="'Indent ' + item.prompt + ' left'"
[disabled]="item.indent == 0"
(click)="onIndent(item, -1)">
<mat-icon fontIcon="format_indent_decrease" />
</button>
<button
mat-icon-button
mat-medium-icon-button
class="item-icon"
[attr.aria-label]="'Indent ' + item.prompt + ' right'"
[disabled]="item.indent == 4"
(click)="onIndent(item, 1)">
<mat-icon fontIcon="format_indent_increase" />
</button>
<span
class="item"
[class.item-prompt]="item.type == ChecklistItem_Type.ITEM_PROMPT"
[class.item-title]="item.type == ChecklistItem_Type.ITEM_TITLE"
[class.item-warning]="item.type == ChecklistItem_Type.ITEM_WARNING"
[class.item-caution]="item.type == ChecklistItem_Type.ITEM_CAUTION"
[class.item-note]="item.type == ChecklistItem_Type.ITEM_NOTE"
[class.item-space]="item.type == ChecklistItem_Type.ITEM_SPACE"
[style.padding-left]="item.indent*25 + 'px'">
<!-- TODO: Find a better solution than to save/cancel independent fields together -->
<editable-label
#promptInput
class="prompt-input"
label="Prompt text"
[value]="item.prompt"
(valueChanged)="item.prompt = promptInput.value; onItemUpdated(); expectationInput.cancel();"
(cancelled)="expectationInput.cancel()" />
</span>
<span [hidden]="item.type !== ChecklistItem_Type.ITEM_PROMPT">
<!-- TODO: Make the dots fill the center space and nothing more -->
<span class="prompt-spacer" *ngIf="!expectationInput.editing">........................</span>
<span class="prompt-expectation">
<editable-label
#expectationInput
class="expectation-input"
label="Expectation text"
[value]="item.expectation"
(valueChange)="item.expectation = expectationInput.value; onItemUpdated(); promptInput.cancel();"
(cancelled)="promptInput.cancel()" />
</span>
</span>
<checklist-item
[item]="item"
(itemChanged)="onItemUpdated()" />
<div *cdkDragPlaceholder></div>
</div>
}
Expand Down
62 changes: 0 additions & 62 deletions src/app/checklists/items-list/items-list.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,68 +24,6 @@
font-size: 16px;
}

.item {
vertical-align: middle;
}

.item-title {
color: white;
}

.item-caution {
color: red;
}

.item-caution:before {
padding: 10px;
content: "CAUTION:"
}

.item-warning {
color: yellow;
}

.item-warning:before {
padding: 10px;
content: "WARNING:"
}

.item-note {
color: gray;
}

.item-note:before {
padding: 10px;
content: "NOTE:"
}

.prompt-spacer {
text-wrap: nowrap;
overflow: hidden;
letter-spacing: 10px;
}

.prompt-expectation {
float: right;
color: cyan;
}

// TODO: Make this work without ng-deep
::ng-deep .prompt-input mat-form-field {
width: 400px;
}
::ng-deep .prompt-expectation mat-form-field {
width: 300px;
}

.item-icon {
vertical-align: middle;
}

.drag-icon {
cursor: move;
}

.list-item:last-child {
border: none;
}
Expand Down
19 changes: 4 additions & 15 deletions src/app/checklists/items-list/items-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ import { CdkDrag, CdkDragDrop, CdkDragHandle, CdkDragPlaceholder, CdkDropList, m
import { NgIf } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatFormFieldModule, MatLabel } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { MatIconButtonSizesModule } from 'mat-icon-button-sizes';
import { Checklist, ChecklistItem, ChecklistItem_Type } from '../../../../gen/ts/checklist';
import { EditableLabelComponent } from './editable-label/editable-label.component';
import { Checklist, ChecklistItem } from '../../../../gen/ts/checklist';
import { ChecklistItemComponent } from './item/item.component';

@Component({
selector: 'checklist-items',
Expand All @@ -16,13 +14,9 @@ import { EditableLabelComponent } from './editable-label/editable-label.componen
standalone: true,
imports: [
CdkDrag,
CdkDragHandle,
CdkDragPlaceholder,
CdkDropList,
EditableLabelComponent,
MatButtonModule,
MatIconButtonSizesModule,
MatIconModule,
ChecklistItemComponent,
NgIf,
]
})
Expand All @@ -31,21 +25,16 @@ export class ChecklistItemsComponent {

editing: boolean = false;
_checklist?: Checklist;
readonly ChecklistItem_Type = ChecklistItem_Type;

@Input()
get checklist(): Checklist | undefined { return this._checklist; }
set checklist(checklist: Checklist | undefined) {
this._checklist = checklist;
}

onIndent(item: ChecklistItem, delta: number) {
item.indent += delta;
this.checklistChanged.emit(this._checklist);
}

onDrop(event: CdkDragDrop<ChecklistItem[]>): void {
moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);
this.onItemUpdated();
}

onItemUpdated() {
Expand Down

0 comments on commit d721507

Please sign in to comment.