class WorkTimeClockView extends DragTargetView { constructor(element) { super(element); this.onCardUpdateBound = this.onCardUpdate.bind(this); TimeCards.dataManager.addStoreErrorListener("period", this.onPeriodStoreError.bind(this)); } build(element) { super.build(element); this.stopButton = document.createElement("BUTTON"); this.stopButton.className = "stop-button"; this.stopButton.innerText = "⏏︎"; this.stopButton.disabled = true; this.stopButton.title = "Eject card"; this.stopButton.addEventListener("click", this.onStopButtonPressed.bind(this)); element.appendChild(this.stopButton); this.cardView = new CardView(); this.cardView.element.style.display = "none"; element.appendChild(this.cardView.element); return element; } viewDidLoad() { //Wait for the user to log in. TimeCards.dataManager.addDataListener("user", { is_session_user: true }, this.onUserUpdate.bind(this)); } onDragOver(draggedObject, validType, x, y) { } onDragEnter(draggedObject, validType) { } onDragExit() { } onDragEnd() { } onDrop(droppedObject, sourceView) { if (this.activePeriod && this.activePeriod.id_card == droppedObject.card_id) { return; } this.removeCard(); this.insertCard(droppedObject); } acceptsType(draggableType) { //Refuse the card if the user has no write permission for periods. return (draggableType == "card") && Authentication.isResourceAvailable("period", "w"); } onUserUpdate(userId, user) { //Add or update the period listener when the logged in user changes. if (!this.onPeriodUpdateBound) { this.onPeriodUpdateBound = this.onPeriodUpdate.bind(this); } else { TimeCards.dataManager.removeDataListener("period", this.onPeriodUpdateBound); } TimeCards.dataManager.addDataListener("period", { end_time: null, id_user: user.user_id }, this.onPeriodUpdateBound); } onPeriodUpdate(periodId, period) { if (!period || period.end_time) { //Remove the card if the period was deleted. //Stop counting if the period has got an end time. this.onCardRemoved(); } else if (!this.activePeriod) { //Started counting. this.counting = true; this.activePeriod = period; //Display the card in the clock view. this.cardView.element.style.display = ""; this.stopButton.disabled = false; //Add the data listener for the recording card. TimeCards.dataManager.addDataListener("card", { card_id: this.activePeriod.id_card }, this.onCardUpdateBound); } else { if (this.activePeriod.id_card != period.id_card) { //Handle the changed card. this.cardView.setCardData(TimeCards.dataManager.getEntity("card", period.id_card)); } this.activePeriod = period; } } onPeriodStoreError(periodId, period, error) { if (this.activePeriod) { //Re-enable the stop button if the stopping failed. this.stopButton.disabled = false; } else { //Reset the flag if the counting could not be started. this.counting = false; } } insertCard(card) { if (this.counting) { alert("There is already an active card. Remove it first."); } this.counting = true; TimeCards.dataManager.store("period", { start_time: new Date().getTime(), end_time: null, id_card: card.card_id, id_project: card.id_project, card_title: card.title, notes: card.description, id_user: Authentication.currentUser.user_id }); } removeCard() { if (!this.activePeriod) { return; } if (!this.counting) { alert("The card has already been removed."); } TimeCards.dataManager.store("period", this.activePeriod.period_id, { end_time: new Date().getTime() }); } onCardRemoved() { if (!this.activePeriod) { return; } this.stopButton.disabled = true; this.counting = false; this.activePeriod = null; //Remove the card data listener. TimeCards.dataManager.removeDataListener("card", this.onCardUpdateBound); //Either remove the card from the clock entirely or just hover it above if the user paused the counting. this.cardView.element.style.display = "none"; } onStopButtonPressed(event) { this.removeCard(); this.stopButton.disabled = true; } /** * Called when the currently recording card has updated. */ onCardUpdate(cardId, card) { if (card) { this.cardView.setCardData(card); } } } UIKit.registerViewType(WorkTimeClockView, "work-time-clock");