class PeriodPopover extends Popover { setPeriodData(period) { //Reset the deleting flag. this.deleting = false; //If a new period is shown ... if (!this.period || (this.period && period.period_id != this.period.period_id)) { //Remove the current period listener if there is one. if (this.onPeriodUpdateBound) { TimeCards.dataManager.removeDataListener("period", this.onPeriodUpdateBound); } else { this.onPeriodUpdateBound = this.onPeriodUpdate.bind(this); } //Add a period listener to capture any server-side updates. //We only do this when the period already exists on the server (i.e. if it has an ID). if ("period_id" in period) { TimeCards.dataManager.addDataListener("period", { period_id: period.period_id }, this.onPeriodUpdateBound); } else { //We do not want to have the bound method yet if this is a new period. This is to preserve the above behaviour. this.onPeriodUpdateBound = null; } } this.period = period; this.cardTitleField.value = this.period.card_title; this.projectSelectController.setValue(this.period.id_project); this.notesField.value = this.period.notes; var endTime = this.period.end_time ?? new Date().getTime(); var startDate = new Date(this.period.start_time); var endDate = new Date(endTime); this.startTimeLabel.innerText = this.zeroPad(startDate.getHours().toString()) + ":" + this.zeroPad(startDate.getMinutes().toString()); this.endTimeLabel.innerText = this.zeroPad(endDate.getHours().toString()) + ":" + this.zeroPad(endDate.getMinutes().toString()); this.durationLabel.innerText = Time.formatDuration(endTime - this.period.start_time); //Enable or disable the input elements depending on whether the user has write access to that specific period or not. this.cardTitleField.classList.remove("available_w__period"); this.cardTitleField.classList.remove("available_w__period_all"); this.projectSelect.classList.remove("available_w__period"); this.projectSelect.classList.remove("available_w__period_all"); this.notesField.classList.remove("available_w__period"); this.notesField.classList.remove("available_w__period_all"); if (this.period.id_user == Authentication.currentUser.user_id) { this.cardTitleField.classList.add("available_w__period"); this.projectSelect.classList.add("available_w__period"); this.notesField.classList.add("available_w__period"); } else { this.cardTitleField.classList.add("available_w__period_all"); this.projectSelect.classList.add("available_w__period_all"); this.notesField.classList.add("available_w__period_all"); } Authentication.applyPermissionsToElement(this.notesField); } zeroPad(numberString) { while (numberString.length < 2) { numberString = "0" + numberString; } return numberString; } onDeleteButtonPressed(event) { this.deleting = true; this.dismiss(); this.periodView.onDeleteButtonPressed(); } viewWillDisappear() { if (!this.editForm.checkValidity()) { return; } this.save(); } onFormSubmitted(event) { event.preventDefault(); this.dismiss(); } save() { //Save the values if any of them were altered or if the period is new. //Only save when there is a project selected. //Do not save if the popover was dismissed because the user clicked the delete button. if (!this.deleting && this.projectSelect.value && (!this.period.period_id || (this.notesField.value == "" && this.period.notes != null) || (this.notesField.value != "" && this.notesField.value != this.period.notes) || this.projectSelect.value != this.period.id_project || this.cardTitleField.value != this.period.card_title)) { //Use null as the key if the period ID is undefined. This will create a new period. TimeCards.dataManager.store("period", this.period.period_id ?? null, { id_card: this.period.id_card, id_project: this.projectSelect.value, card_title: this.cardTitleField.value, id_user: this.period.id_user, start_time: this.period.start_time, end_time: this.period.end_time, notes: this.notesField.value, id_invoice: this.period.id_invoice }, this.onPeriodCreated.bind(this)); } else if (!this.projectSelect.value || (!this.period.period_id && this.deleting)) { //Report to the period view if no project was selected for the newly created period or if the delete button was pressed before the period was saved. //This is essentially a cancellation of the creation of the new period. this.periodView.dayView.endPeriodCreation(); } } onPeriodCreated(periodId, period) { this.periodView.dayView.endPeriodCreation(); } onPeriodUpdate(periodId, period) { //Do nothing if the updated period is not the displayed one. if (periodId != this.period.period_id) { return; } if (!period) { //Remove the listeners if the period is deleted. TimeCards.dataManager.removeDataListener("period", this.onCardUpdateBound); //Also dismiss the period popover. this.dismiss(); return; } //Update the period data if the period popover is still visible. if (this.visible) { this.setPeriodData(period); } } } UIKit.registerPopoverType(PeriodPopover);