import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, signal, SimpleChanges } from '@angular/core'; import { FormControl } from '@angular/forms'; export interface Task { name: string; code?: string; completed: boolean; subtasks?: Task[]; } @Component({ selector: 'kit-checkbox-group', templateUrl: './checkbox-group.component.html', styleUrl: './checkbox-group.component.css', changeDetection: ChangeDetectionStrategy.OnPush, }) export class CheckboxGroupComponent implements OnChanges{ @Input() options: any[] = []; @Input() defaultOptions: string[] = []; @Input() disabled: boolean = false; @Input() control: FormControl | any; @Input() direction: string | null = 'HORIZONTAL'; //HORIZONTAL, VERTICAL @Input() style: string = 'empty'; //empty, filled @Output() changeCheck = new EventEmitter(); readonly task = signal({ name: 'Parent task', completed: false, subtasks: [], }); constructor() {} ngOnChanges(changes: SimpleChanges) { if (changes['options']) { this.task.update(task => ({ ...task, subtasks: this.options.map(option => ({ name: option.name, code: option.code, completed: option.completed || this.defaultOptions.includes(option.code) })) })); this.control.markAsUntouched(); } } update(completed: boolean, index?: number) { this.task.update(task => { if (index === undefined) { task.completed = completed; task.subtasks?.forEach(t => (t.completed = completed)); } else { task.subtasks![index].completed = completed; task.completed = task.subtasks?.every(t => t.completed) ?? true; } const selecteds: any = this.task().subtasks?.filter(option => option.completed).map(({ name, code }) => ({ name, code })); if (selecteds.length === 0) { this.control.setValue(null) this.control.setErrors({ required: true }); } else { this.control.setErrors(null); this.control.setValue(selecteds) } this.changeCheck.emit(selecteds); return {...task}; }); } }