import { Component, ViewChild, Input, Output, EventEmitter } from '@angular/core'; import { OnInit, OnDestroy } from '@angular/core'; import { AlertController, ToastController, Events } from 'ionic-angular'; import { DateIdUtil } from '@canvuus-internal/mvp0-task-core'; import { MediaAttachment } from '@canvuus-internal/mvp0-task-base'; import { TaskItem, TaskStatus, TaskBit } from '@canvuus-internal/mvp0-task-data'; import { VoicePlayer, VoiceRecorder, VoiceRecordingPlayer, BasePlayer, BaseRecorder, BaseRecordingPlayer } from '@canvuus-internal/mvp0-task-view'; import { CommonEvents } from '@canvuus-internal/mvp0-task-view'; import { CommonColorBadgeComponent } from '@canvuus-internal/mvp0-task-view'; import { TaskActions } from '../../common/core/task-actions'; import { TaskEvents } from '../../common/events/task-events'; @Component({ selector: 'mvp0-task-editor', // templateUrl: 'mvp0-task-editor.html', template: ` {{data.priority}}
Importance & Urgency -5 5 -5 5 Task Dates Target Date Due Date Task Bits {{bit.label}} Voice Memos {{vm.label}}
` }) export class Mvp0TaskEditorComponent implements OnInit, OnDestroy { // @ViewChild("taskColorTag") taskColorTag: CommonColorTagComponent; // @ViewChild("taskColorTag") taskColorTag: CommonColorAvatarComponent; @ViewChild("taskColorTag") taskColorTag: CommonColorBadgeComponent; // If true, the color tag will use grayscale for resolved items. @Input("color-changeable") isColorChangeEnabled: boolean; // If true, voice memo-related menus will show. @Input("voicememo-enabled") isVoiceMemosEnabled: boolean; // text: string; data: TaskItem; // testing private voiceRecordingPlayer: VoiceRecordingPlayer; // testing // fillstyle0: string; constructor(private alertCtrl: AlertController, private toastCtrl: ToastController, private events: Events) { // console.log('Hello Mvp0TaskEditor Component'); // False by default. this.isColorChangeEnabled = false; this.isVoiceMemosEnabled = false; // temporary this.data = new TaskItem(); // this.taskColorTag.colorTag = this.data.colorTag; // .... // testing this.voiceRecordingPlayer = new BaseRecordingPlayer("Test VoiceMemo Player"); } ngOnInit() { // console.log('::: ngOnInit()'); // testing this.voiceRecordingPlayer.reset(); } ngOnDestroy() { // console.log('::: ngOnDestroy()'); // testing this.voiceRecordingPlayer.dispose(); } get isGray(): boolean { return this.isColorChangeEnabled && ((this.data) ? this.data.isResolved : false); } get showVoiceMemoMenus(): boolean { return this.isVoiceMemosEnabled && ((this.data) && this.data.isActive); } // temporary get isVoiceMemoRecording(): boolean { return false; } get isVoiceMemoPlaying(): boolean { return false; } // temporary // tbd refreshData(_data: (TaskItem | null) = null): void { console.log('Mvp0TaskEditorComponent: >>> refreshData() _data = ' + _data); if (_data) { this.data = _data.clone(); // ?? } else { // This shouldn't happen. this.data = new TaskItem(); } if (this.taskColorTag) { this.taskColorTag.colorTag = this.data.colorTag; } // console.log('>>> refreshData() this.data = ' + this.data); } saveData(): void { // console.log(">>> saveData()"); // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE); // why is this.data missing here ??? this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data); // need to check this... } onDataChange(event) { // console.log('onDataChange(): event = ' + event); if (this.data) { this.data.isDirty = true; } } // Does this slow down the slider UI????? get priorityBadgeColor(): string { let priority = this.data.priority; if (priority >= 3) { return 'danger'; } else if (priority >= 0) { return 'primary'; } else { return 'secondary'; } } get targetDate(): string { return (this.data.targetDate) ? DateIdUtil.getLocaleDateString(this.data.targetDate) : ''; // ??? } get isoTargetDate(): string { return (this.data && this.data.targetDate) ? DateIdUtil.getISODateString(this.data.targetDate) : ''; // ??? } set isoTargetDate(str: string) { if (this.data) { this.data.setTargetDate(DateIdUtil.fromISODateString(str)); } } onTargetDateChange(event) { console.log('Mvp0TaskEditorComponent: onTargetDateChange(): event = ' + event); // Do not save it. // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data); if (this.data) { this.data.isDirty = true; } } get dueDate(): string { return DateIdUtil.getLocaleDateString(this.data.dueDate); } get isoDueDate(): string { return (this.data) ? DateIdUtil.getISODateString(this.data.dueDate) : ""; // ??? } set isoDueDate(str: string) { if (this.data) { this.data.setDueDate(DateIdUtil.fromISODateString(str)); } } onDueDateChange(event) { console.log('Mvp0TaskEditorComponent: onDueDateChange(): event = ' + event); // Do not save it. // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data); if (this.data) { this.data.isDirty = true; } } markAsActive() { // console.log("markAsActive()"); if (this.data.isActive) { // Do not change the status. e.g., if it's "doing", changing it to "ready"" does not make sense. console.log('Mvp0TaskEditorComponent: Current status will not be changed: status = ' + this.data.status); } else { this.data.setStatus(TaskStatus.ready); // In the current UI design, // We need to do both save and dismiss or do neither. // if (this.data.isSynched) { // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data, TaskActions.ACTION_MARKED_AS_READY); // } else { // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data, TaskActions.ACTION_NEW_TASK_CREATED); // } // Instead, just signal the status change... this.events.publish(TaskEvents.MVP0_UI_TASK_STATUS_CHANGED, this.data.status); } // Then dismiss this page. Just let data events handle this ??? // this.events.publish(CommonEvents.MVP0_NAV_DISMISS_SELF, true); } markAsDone() { // console.log("markAsDone()"); // tbd: // save the task first // (here or in the parent page???) // this.readInputData(); this.data.setStatus(TaskStatus.done); // this.events.publish((this.data.isSynched) ? CommonEvents.MVP0_DATA_TASKITEM_UPDATE : CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data); if (this.data.isSynched) { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data, TaskActions.ACTION_MARKED_AS_DONE); } else { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data, TaskActions.ACTION_CREATED_AS_DONE); // ??? } // console.log("########### this.data = " + this.data); // Then dismiss this page. Just let data events handle this ??? this.events.publish(CommonEvents.MVP0_NAV_DISMISS_SELF, true); } deferTillTomorrow() { // console.log("deferTillTomorrow"); // tbd: // Not "tommorow", but the next day. // this.data.setTargetDate(DateIdUtil.getTomorrowId()); let nextDayId: string; if (this.data.targetDate) { nextDayId = DateIdUtil.getNextDayId(this.data.targetDate); } else { nextDayId = DateIdUtil.getTomorrowId(); } this.data.setTargetDate(nextDayId); if (this.data.isResolved) { // duplicate this item.. let copiedItem = this.data.copy(); this.data = copiedItem; this.data.setStatus(TaskStatus.ready); // New task. // TBD: Rename the task title ???? this.data.setTitle(this.data.title + " (Copied)"); // ... } else { this.data.setStatus(TaskStatus.ready); // this task can be currently "doing", reset it back to ready. } // ... // this.events.publish((this.data.isSynched) ? CommonEvents.MVP0_DATA_TASKITEM_UPDATE : CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data); if (this.data.isSynched) { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data, TaskActions.ACTION_DEFERRED_TILL_TOMORROW); } else { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data, TaskActions.ACTION_CREATED_FOR_TOMORROW); } // Then dismiss this page. Just let data events handle this ??? this.events.publish(CommonEvents.MVP0_NAV_DISMISS_SELF, true); } moveToBacklog() { // console.log("moveToBacklog"); // tbd: this.data.removeTargetDate(); if (this.data.isResolved) { // duplicate this item.. let copiedItem = this.data.copy(); this.data = copiedItem; this.data.setStatus(TaskStatus.ready); // ??? // TBD: Rename the task title ???? this.data.setTitle(this.data.title + " (Copied)"); // ... } else { // this.data.setStatus(TaskStatus.postponed); // "postponed" is used for tasks with no target date. this.data.setStatus(TaskStatus.ready); // Just reset... } // ... // this.events.publish((this.data.isSynched) ? CommonEvents.MVP0_DATA_TASKITEM_UPDATE : CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data); if (this.data.isSynched) { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data, TaskActions.ACTION_MOVED_TO_BACKLOG); } else { this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_CREATE, this.data, TaskActions.ACTION_CREATED_IN_BACKLOG); } // Then dismiss this page. Just let data events handle this ??? this.events.publish(CommonEvents.MVP0_NAV_DISMISS_SELF, true); } deleteThisItem() { // console.log("deleteThisItem"); // Show confirm dialog.... let alert = this.alertCtrl.create({ title: 'Delete Item', message: 'Do you want to delete this task item?', buttons: [ { text: 'Cancel', role: 'cancel', handler: () => { // console.log('Cancel clicked'); } }, { text: 'Delete', handler: () => { // console.log('Delete clicked'); // tbd: // save/delete the task // (here or in the parent page???) // this.readInputData(); this.data.removeTargetDate(); this.data.status = TaskStatus.deleted; // this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_UPDATE, this.data); this.events.publish(CommonEvents.MVP0_DATA_TASKITEM_DELETE, this.data); // Then dismiss this page. Just let data events handle this ??? this.events.publish(CommonEvents.MVP0_NAV_DISMISS_SELF, true); } } ] }); alert.present(); } createTaskBit(event: MouseEvent): void { // console.log('createTaskBit()'); this.presentPromptForNewTaskBit(); } // Not being used -> To be deleted. // toggleTaskBitDone(event: MouseEvent, id: (string | null) = null): void { // // console.log('toggleTaskBitDone(): ' + id); // // let srcId = event.srcElement.id; // // console.log('::: srcId = ' + srcId); // let taskBit: TaskBit; // try { // let bitId = parseInt(id); // if (bitId > 0) { // taskBit = this.data.getBit(bitId); // } // } catch (ex) { // // ignore // } // if (taskBit) { // // tbd: // taskBit.isDone = !taskBit.isDone; // } // } editTaskBit(event: MouseEvent, id: (string | null) = null): void { // console.log('editTaskBit(): ' + id); // let srcId = event.srcElement.id; // console.log('::: srcId = ' + srcId); let taskBit: (TaskBit | null) = null; if(id) { try { let bitId = parseInt(id); if (bitId > 0) { taskBit = this.data.getBit(bitId); console.log('Mvp0TaskEditorComponent: ::: taskBit = ' + taskBit); } } catch (ex) { // ignore } if (taskBit != null) { this.presentPromptForEditTaskBit(taskBit); } else { // ???? // what to do???? // Create a new bit??? taskBit = new TaskBit(""); // .... } } } // // Delete or just hide? // deleteTaskBit(event: MouseEvent, id: string = null): void { // console.log('deleteTaskBit(): ' + id); // } presentPromptForNewTaskBit(): void { // console.log('presentPromptForTaskBit()'); let alert = this.alertCtrl.create({ title: 'Task Bit', inputs: [ { name: 'taskbitLabel', placeholder: 'Title' }, { name: 'taskbitSynopsis', placeholder: 'Description' } ], buttons: [ { text: 'Cancel', role: 'cancel', handler: data => { // console.log('Cancel clicked'); } }, { text: 'Create', handler: data => { if (data.taskbitLabel) { // TBD: Allow an empty label bit? // save the bit. let newBit = new TaskBit(data.taskbitLabel, data.taskbitSynopsis); this.data.addBit(newBit); // return true; } else { // tbd: // just cancel? console.log('Mvp0TaskEditorComponent: Task bit label not specified.'); // return false; } return true; } } ] }); alert.present(); } presentPromptForEditTaskBit(taskBit: TaskBit): void { // console.log('presentPromptForEditTaskBit()'); let alert = this.alertCtrl.create({ title: 'Task Bit', inputs: [ { name: 'taskbitLabel', placeholder: 'Title', value: (taskBit.label) ? taskBit.label : '' }, { name: 'taskbitSynopsis', placeholder: 'Description', value: (taskBit.synopsis) ? taskBit.synopsis : '' } ], buttons: [ // { // text: 'Delete', // handler: data => { // console.log('Delete clicked'); // } // }, { text: 'Remove', handler: data => { // console.log('Remove clicked'); this.data.removeBit(taskBit.bitId); // ... } }, // { // text: 'Hide', // handler: data => { // console.log('Hide clicked'); // } // }, { text: 'Cancel', role: 'cancel', handler: data => { // console.log('Cancel clicked'); } }, { text: 'Save', handler: data => { if (data.taskbitLabel) { // tbd... // save the bit. taskBit.label = data.taskbitLabel; taskBit.synopsis = data.taskbitSynopsis; this.data.updateBit(taskBit.bitId, taskBit); // Is this necessary ???? // return true; } else { // tbd: // just cancel? console.log('Mvp0TaskEditorComponent: Task bit label is empty.'); // return false; } return true; } } ] }); alert.present(); } // tbd: recordVoiceMemo() { // if(this.voiceRecordingPlayer.canRecord()) { // } this.events.publish(TaskEvents.MVP0_UI_TASKITEM_VOICEMEMO_RECORD); } playVoiceMemos() { // if(this.voiceRecordingPlayer.canPlay()) { // } this.events.publish(TaskEvents.MVP0_UI_TASKITEM_VOICEMEMO_PLAY_ALL); } playVoiceMemo(id: string) { // if(this.voiceRecordingPlayer.canPlay()) { // } this.events.publish(TaskEvents.MVP0_UI_TASKITEM_VOICEMEMO_PLAY, id); } }