2025-10-16 20:23:05 +03:00
|
|
|
import { ReactiveVar } from 'meteor/reactive-var';
|
|
|
|
|
import { Meteor } from 'meteor/meteor';
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Component to display original positions for all entities on a board
|
|
|
|
|
*/
|
2026-03-08 10:59:21 +02:00
|
|
|
|
|
|
|
|
Template.originalPositionsView.onCreated(function () {
|
|
|
|
|
this.showOriginalPositions = new ReactiveVar(false);
|
|
|
|
|
this.boardHistory = new ReactiveVar([]);
|
|
|
|
|
this.isLoading = new ReactiveVar(false);
|
|
|
|
|
this.filterType = new ReactiveVar('all'); // 'all', 'swimlane', 'list', 'card'
|
|
|
|
|
|
|
|
|
|
const tpl = this;
|
|
|
|
|
|
|
|
|
|
this.loadBoardHistory = function () {
|
2025-10-16 20:23:05 +03:00
|
|
|
const boardId = Session.get('currentBoard');
|
|
|
|
|
if (!boardId) return;
|
|
|
|
|
|
2026-03-08 10:59:21 +02:00
|
|
|
tpl.isLoading.set(true);
|
2026-02-08 00:48:39 +02:00
|
|
|
|
2025-10-16 20:23:05 +03:00
|
|
|
Meteor.call('positionHistory.getBoardHistory', boardId, (error, result) => {
|
2026-03-08 10:59:21 +02:00
|
|
|
tpl.isLoading.set(false);
|
2025-10-16 20:23:05 +03:00
|
|
|
if (error) {
|
|
|
|
|
console.error('Error loading board history:', error);
|
2026-03-08 10:59:21 +02:00
|
|
|
tpl.boardHistory.set([]);
|
2025-10-16 20:23:05 +03:00
|
|
|
} else {
|
2026-03-08 10:59:21 +02:00
|
|
|
tpl.boardHistory.set(result);
|
2025-10-16 20:23:05 +03:00
|
|
|
}
|
|
|
|
|
});
|
2026-03-08 10:59:21 +02:00
|
|
|
};
|
|
|
|
|
});
|
2025-10-16 20:23:05 +03:00
|
|
|
|
2026-03-08 10:59:21 +02:00
|
|
|
Template.originalPositionsView.onRendered(function () {
|
|
|
|
|
this.loadBoardHistory();
|
|
|
|
|
});
|
2025-10-16 20:23:05 +03:00
|
|
|
|
2026-03-08 10:59:21 +02:00
|
|
|
Template.originalPositionsView.helpers({
|
2025-10-16 20:23:05 +03:00
|
|
|
isShowingOriginalPositions() {
|
2026-03-08 10:59:21 +02:00
|
|
|
return Template.instance().showOriginalPositions.get();
|
|
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
isLoading() {
|
2026-03-08 10:59:21 +02:00
|
|
|
return Template.instance().isLoading.get();
|
|
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getBoardHistory() {
|
2026-03-08 10:59:21 +02:00
|
|
|
return Template.instance().boardHistory.get();
|
|
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getFilteredHistory() {
|
2026-03-08 10:59:21 +02:00
|
|
|
const tpl = Template.instance();
|
|
|
|
|
const history = tpl.boardHistory.get();
|
|
|
|
|
const filterType = tpl.filterType.get();
|
2026-02-08 00:48:39 +02:00
|
|
|
|
2025-10-16 20:23:05 +03:00
|
|
|
if (filterType === 'all') {
|
|
|
|
|
return history;
|
|
|
|
|
}
|
2026-02-08 00:48:39 +02:00
|
|
|
|
2025-10-16 20:23:05 +03:00
|
|
|
return history.filter(item => item.entityType === filterType);
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
2026-03-08 10:59:21 +02:00
|
|
|
isFilterType(type) {
|
|
|
|
|
return Template.instance().filterType.get() === type;
|
|
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getEntityDisplayName(entity) {
|
|
|
|
|
const position = entity.originalPosition || {};
|
|
|
|
|
return position.title || `Entity ${entity.entityId}`;
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getEntityOriginalPositionDescription(entity) {
|
|
|
|
|
const position = entity.originalPosition || {};
|
|
|
|
|
let description = `Position: ${position.sort || 0}`;
|
2026-02-08 00:48:39 +02:00
|
|
|
|
2025-10-16 20:23:05 +03:00
|
|
|
if (entity.entityType === 'list' && entity.originalSwimlaneId) {
|
|
|
|
|
description += ` in swimlane ${entity.originalSwimlaneId}`;
|
|
|
|
|
} else if (entity.entityType === 'card') {
|
|
|
|
|
if (entity.originalSwimlaneId) {
|
|
|
|
|
description += ` in swimlane ${entity.originalSwimlaneId}`;
|
|
|
|
|
}
|
|
|
|
|
if (entity.originalListId) {
|
|
|
|
|
description += ` in list ${entity.originalListId}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-02-08 00:48:39 +02:00
|
|
|
|
2025-10-16 20:23:05 +03:00
|
|
|
return description;
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getEntityTypeIcon(entityType) {
|
|
|
|
|
switch (entityType) {
|
|
|
|
|
case 'swimlane':
|
|
|
|
|
return 'fa-bars';
|
|
|
|
|
case 'list':
|
|
|
|
|
return 'fa-columns';
|
|
|
|
|
case 'card':
|
|
|
|
|
return 'fa-sticky-note';
|
|
|
|
|
default:
|
|
|
|
|
return 'fa-question';
|
|
|
|
|
}
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
getEntityTypeLabel(entityType) {
|
|
|
|
|
switch (entityType) {
|
|
|
|
|
case 'swimlane':
|
|
|
|
|
return 'Swimlane';
|
|
|
|
|
case 'list':
|
|
|
|
|
return 'List';
|
|
|
|
|
case 'card':
|
|
|
|
|
return 'Card';
|
|
|
|
|
default:
|
|
|
|
|
return 'Unknown';
|
|
|
|
|
}
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
2025-10-16 20:23:05 +03:00
|
|
|
|
|
|
|
|
formatDate(date) {
|
|
|
|
|
return new Date(date).toLocaleString();
|
2026-03-08 10:59:21 +02:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Template.originalPositionsView.events({
|
|
|
|
|
'click .js-toggle-original-positions'(evt, tpl) {
|
|
|
|
|
tpl.showOriginalPositions.set(!tpl.showOriginalPositions.get());
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'click .js-refresh-history'(evt, tpl) {
|
|
|
|
|
tpl.loadBoardHistory();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
'click .js-filter-type'(evt, tpl) {
|
|
|
|
|
const type = evt.currentTarget.dataset.filterType;
|
|
|
|
|
tpl.filterType.set(type);
|
|
|
|
|
},
|
|
|
|
|
});
|