mirror of
https://github.com/wekan/wekan.git
synced 2026-02-13 11:44:20 +01:00
Show original positions of swimlanes, lists and cards.
Thanks to xet7 ! Fixes #5939
This commit is contained in:
parent
915ab47a72
commit
2543df9425
13 changed files with 1719 additions and 0 deletions
263
client/components/boards/originalPositionsView.css
Normal file
263
client/components/boards/originalPositionsView.css
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/* Original Positions View Styles */
|
||||
.original-positions-view {
|
||||
margin: 10px 0;
|
||||
padding: 15px;
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.original-positions-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.original-positions-header .btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.original-positions-content {
|
||||
background-color: white;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 4px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.original-positions-loading {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.original-positions-loading i {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.original-positions-filters {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.original-positions-filters .btn-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.original-positions-filters .btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.original-positions-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.original-position-item {
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 10px;
|
||||
padding: 12px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.original-position-item:hover {
|
||||
background-color: #e9ecef;
|
||||
border-color: #ced4da;
|
||||
}
|
||||
|
||||
.original-position-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.original-position-item-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.original-position-item-header i {
|
||||
color: #6c757d;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.entity-type {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.entity-name {
|
||||
color: #212529;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.entity-id {
|
||||
color: #6c757d;
|
||||
font-size: 11px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.original-position-item-details {
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.original-position-description {
|
||||
color: #495057;
|
||||
margin-bottom: 6px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.original-title {
|
||||
color: #6c757d;
|
||||
font-size: 12px;
|
||||
margin-bottom: 6px;
|
||||
padding: 4px 6px;
|
||||
background-color: #e9ecef;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.original-title strong {
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.original-position-date {
|
||||
color: #6c757d;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.no-original-positions {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.no-original-positions i {
|
||||
font-size: 24px;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
color: #adb5bd;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.original-positions-view {
|
||||
margin: 5px 0;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.original-positions-header {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.original-positions-header .btn {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.original-positions-filters .btn-group {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.original-position-item-header {
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.entity-name {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.original-position-item-details {
|
||||
margin-left: 0;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark theme support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.original-positions-view {
|
||||
background-color: #2d3748;
|
||||
border-color: #4a5568;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-positions-content {
|
||||
background-color: #1a202c;
|
||||
border-color: #4a5568;
|
||||
}
|
||||
|
||||
.original-position-item {
|
||||
background-color: #2d3748;
|
||||
border-color: #4a5568;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-position-item:hover {
|
||||
background-color: #4a5568;
|
||||
border-color: #718096;
|
||||
}
|
||||
|
||||
.original-position-item-header {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-position-item-header i {
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
.entity-name {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.entity-id {
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
.original-position-description {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-title {
|
||||
background-color: #4a5568;
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
.original-title strong {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-position-date {
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
.no-original-positions {
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
.no-original-positions i {
|
||||
color: #718096;
|
||||
}
|
||||
}
|
||||
82
client/components/boards/originalPositionsView.html
Normal file
82
client/components/boards/originalPositionsView.html
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<template name="originalPositionsView">
|
||||
<div class="original-positions-view">
|
||||
<div class="original-positions-header">
|
||||
<button class="btn btn-sm btn-outline-secondary" onclick="{{toggleOriginalPositions}}">
|
||||
<i class="fa fa-history"></i>
|
||||
{{#if isShowingOriginalPositions}}Hide{{else}}Show{{/if}} Original Positions
|
||||
</button>
|
||||
|
||||
{{#if isShowingOriginalPositions}}
|
||||
<button class="btn btn-sm btn-outline-primary" onclick="{{refreshHistory}}">
|
||||
<i class="fa fa-refresh"></i> Refresh
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if isShowingOriginalPositions}}
|
||||
<div class="original-positions-content">
|
||||
{{#if isLoading}}
|
||||
<div class="original-positions-loading">
|
||||
<i class="fa fa-spinner fa-spin"></i> Loading original positions...
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="original-positions-filters">
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button"
|
||||
class="btn {{#if isFilterType 'all'}}btn-primary{{else}}btn-outline-secondary{{/if}}"
|
||||
onclick="{{setFilterType 'all'}}">
|
||||
All
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn {{#if isFilterType 'swimlane'}}btn-primary{{else}}btn-outline-secondary{{/if}}"
|
||||
onclick="{{setFilterType 'swimlane'}}">
|
||||
<i class="fa fa-bars"></i> Swimlanes
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn {{#if isFilterType 'list'}}btn-primary{{else}}btn-outline-secondary{{/if}}"
|
||||
onclick="{{setFilterType 'list'}}">
|
||||
<i class="fa fa-columns"></i> Lists
|
||||
</button>
|
||||
<button type="button"
|
||||
class="btn {{#if isFilterType 'card'}}btn-primary{{else}}btn-outline-secondary{{/if}}"
|
||||
onclick="{{setFilterType 'card'}}">
|
||||
<i class="fa fa-sticky-note"></i> Cards
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="original-positions-list">
|
||||
{{#each getFilteredHistory}}
|
||||
<div class="original-position-item">
|
||||
<div class="original-position-item-header">
|
||||
<i class="fa {{getEntityTypeIcon entityType}}"></i>
|
||||
<span class="entity-type">{{getEntityTypeLabel entityType}}</span>
|
||||
<span class="entity-name">{{getEntityDisplayName this}}</span>
|
||||
<span class="entity-id">({{entityId}})</span>
|
||||
</div>
|
||||
<div class="original-position-item-details">
|
||||
<div class="original-position-description">
|
||||
{{getEntityOriginalPositionDescription this}}
|
||||
</div>
|
||||
{{#if originalTitle}}
|
||||
<div class="original-title">
|
||||
<strong>Original title:</strong> {{originalTitle}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="original-position-date">
|
||||
<small class="text-muted">Created: {{formatDate createdAt}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="no-original-positions">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
No original position data available for this board.
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
148
client/components/boards/originalPositionsView.js
Normal file
148
client/components/boards/originalPositionsView.js
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import { BlazeComponent } from 'meteor/peerlibrary:blaze-components';
|
||||
import { ReactiveVar } from 'meteor/reactive-var';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import './originalPositionsView.html';
|
||||
|
||||
/**
|
||||
* Component to display original positions for all entities on a board
|
||||
*/
|
||||
class OriginalPositionsViewComponent extends BlazeComponent {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
this.showOriginalPositions = new ReactiveVar(false);
|
||||
this.boardHistory = new ReactiveVar([]);
|
||||
this.isLoading = new ReactiveVar(false);
|
||||
this.filterType = new ReactiveVar('all'); // 'all', 'swimlane', 'list', 'card'
|
||||
}
|
||||
|
||||
onRendered() {
|
||||
super.onRendered();
|
||||
this.loadBoardHistory();
|
||||
}
|
||||
|
||||
loadBoardHistory() {
|
||||
const boardId = Session.get('currentBoard');
|
||||
if (!boardId) return;
|
||||
|
||||
this.isLoading.set(true);
|
||||
|
||||
Meteor.call('positionHistory.getBoardHistory', boardId, (error, result) => {
|
||||
this.isLoading.set(false);
|
||||
if (error) {
|
||||
console.error('Error loading board history:', error);
|
||||
this.boardHistory.set([]);
|
||||
} else {
|
||||
this.boardHistory.set(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleOriginalPositions() {
|
||||
this.showOriginalPositions.set(!this.showOriginalPositions.get());
|
||||
}
|
||||
|
||||
isShowingOriginalPositions() {
|
||||
return this.showOriginalPositions.get();
|
||||
}
|
||||
|
||||
isLoading() {
|
||||
return this.isLoading.get();
|
||||
}
|
||||
|
||||
getBoardHistory() {
|
||||
return this.boardHistory.get();
|
||||
}
|
||||
|
||||
getFilteredHistory() {
|
||||
const history = this.getBoardHistory();
|
||||
const filterType = this.filterType.get();
|
||||
|
||||
if (filterType === 'all') {
|
||||
return history;
|
||||
}
|
||||
|
||||
return history.filter(item => item.entityType === filterType);
|
||||
}
|
||||
|
||||
getSwimlanesHistory() {
|
||||
return this.getBoardHistory().filter(item => item.entityType === 'swimlane');
|
||||
}
|
||||
|
||||
getListsHistory() {
|
||||
return this.getBoardHistory().filter(item => item.entityType === 'list');
|
||||
}
|
||||
|
||||
getCardsHistory() {
|
||||
return this.getBoardHistory().filter(item => item.entityType === 'card');
|
||||
}
|
||||
|
||||
setFilterType(type) {
|
||||
this.filterType.set(type);
|
||||
}
|
||||
|
||||
getFilterType() {
|
||||
return this.filterType.get();
|
||||
}
|
||||
|
||||
getEntityDisplayName(entity) {
|
||||
const position = entity.originalPosition || {};
|
||||
return position.title || `Entity ${entity.entityId}`;
|
||||
}
|
||||
|
||||
getEntityOriginalPositionDescription(entity) {
|
||||
const position = entity.originalPosition || {};
|
||||
let description = `Position: ${position.sort || 0}`;
|
||||
|
||||
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}`;
|
||||
}
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
getEntityTypeIcon(entityType) {
|
||||
switch (entityType) {
|
||||
case 'swimlane':
|
||||
return 'fa-bars';
|
||||
case 'list':
|
||||
return 'fa-columns';
|
||||
case 'card':
|
||||
return 'fa-sticky-note';
|
||||
default:
|
||||
return 'fa-question';
|
||||
}
|
||||
}
|
||||
|
||||
getEntityTypeLabel(entityType) {
|
||||
switch (entityType) {
|
||||
case 'swimlane':
|
||||
return 'Swimlane';
|
||||
case 'list':
|
||||
return 'List';
|
||||
case 'card':
|
||||
return 'Card';
|
||||
default:
|
||||
return 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
formatDate(date) {
|
||||
return new Date(date).toLocaleString();
|
||||
}
|
||||
|
||||
refreshHistory() {
|
||||
this.loadBoardHistory();
|
||||
}
|
||||
}
|
||||
|
||||
OriginalPositionsViewComponent.register('originalPositionsView');
|
||||
|
||||
export default OriginalPositionsViewComponent;
|
||||
123
client/components/common/originalPosition.css
Normal file
123
client/components/common/originalPosition.css
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/* Original Position Component Styles */
|
||||
.original-position-info {
|
||||
margin: 5px 0;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.original-position-loading {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.original-position-loading i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.original-position-details {
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 3px;
|
||||
padding: 6px 8px;
|
||||
}
|
||||
|
||||
.original-position-moved {
|
||||
color: #856404;
|
||||
background-color: #fff3cd;
|
||||
border: 1px solid #ffeaa7;
|
||||
border-radius: 3px;
|
||||
padding: 4px 6px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.original-position-moved i {
|
||||
color: #f39c12;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.original-position-unchanged {
|
||||
color: #155724;
|
||||
background-color: #d4edda;
|
||||
border: 1px solid #c3e6cb;
|
||||
border-radius: 3px;
|
||||
padding: 4px 6px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.original-position-unchanged i {
|
||||
color: #28a745;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.original-position-text {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.original-title {
|
||||
color: #6c757d;
|
||||
font-size: 11px;
|
||||
margin-top: 4px;
|
||||
padding-top: 4px;
|
||||
border-top: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.original-title strong {
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Integration with existing Wekan styles */
|
||||
.swimlane .original-position-info,
|
||||
.list .original-position-info,
|
||||
.card .original-position-info {
|
||||
margin: 2px 0;
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.original-position-info {
|
||||
font-size: 11px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.original-position-details {
|
||||
padding: 4px 6px;
|
||||
}
|
||||
|
||||
.original-position-moved,
|
||||
.original-position-unchanged {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark theme support */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.original-position-details {
|
||||
background-color: #2d3748;
|
||||
border-color: #4a5568;
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
.original-position-moved {
|
||||
background-color: #744210;
|
||||
border-color: #b7791f;
|
||||
color: #fbd38d;
|
||||
}
|
||||
|
||||
.original-position-unchanged {
|
||||
background-color: #22543d;
|
||||
border-color: #38a169;
|
||||
color: #9ae6b4;
|
||||
}
|
||||
|
||||
.original-title {
|
||||
color: #a0aec0;
|
||||
border-color: #4a5568;
|
||||
}
|
||||
|
||||
.original-title strong {
|
||||
color: #e2e8f0;
|
||||
}
|
||||
}
|
||||
29
client/components/common/originalPosition.html
Normal file
29
client/components/common/originalPosition.html
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<template name="originalPosition">
|
||||
<div class="original-position-info">
|
||||
{{#if isLoading}}
|
||||
<div class="original-position-loading">
|
||||
<i class="fa fa-spinner fa-spin"></i> Loading original position...
|
||||
</div>
|
||||
{{else if showOriginalPosition}}
|
||||
<div class="original-position-details">
|
||||
{{#if hasMovedFromOriginal}}
|
||||
<div class="original-position-moved">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<span class="original-position-text">{{getOriginalPositionDescription}}</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="original-position-unchanged">
|
||||
<i class="fa fa-check-circle"></i>
|
||||
<span class="original-position-text">In original position</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if getOriginalTitle}}
|
||||
<div class="original-title">
|
||||
<strong>Original title:</strong> {{getOriginalTitle}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
98
client/components/common/originalPosition.js
Normal file
98
client/components/common/originalPosition.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import { BlazeComponent } from 'meteor/peerlibrary:blaze-components';
|
||||
import { ReactiveVar } from 'meteor/reactive-var';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Template } from 'meteor/templating';
|
||||
import './originalPosition.html';
|
||||
|
||||
/**
|
||||
* Component to display original position information for swimlanes, lists, and cards
|
||||
*/
|
||||
class OriginalPositionComponent extends BlazeComponent {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
this.originalPosition = new ReactiveVar(null);
|
||||
this.isLoading = new ReactiveVar(false);
|
||||
this.hasMoved = new ReactiveVar(false);
|
||||
|
||||
this.autorun(() => {
|
||||
const data = this.data();
|
||||
if (data && data.entityId && data.entityType) {
|
||||
this.loadOriginalPosition(data.entityId, data.entityType);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadOriginalPosition(entityId, entityType) {
|
||||
this.isLoading.set(true);
|
||||
|
||||
const methodName = `positionHistory.get${entityType.charAt(0).toUpperCase() + entityType.slice(1)}OriginalPosition`;
|
||||
|
||||
Meteor.call(methodName, entityId, (error, result) => {
|
||||
this.isLoading.set(false);
|
||||
if (error) {
|
||||
console.error('Error loading original position:', error);
|
||||
this.originalPosition.set(null);
|
||||
} else {
|
||||
this.originalPosition.set(result);
|
||||
|
||||
// Check if the entity has moved
|
||||
const movedMethodName = `positionHistory.has${entityType.charAt(0).toUpperCase() + entityType.slice(1)}Moved`;
|
||||
Meteor.call(movedMethodName, entityId, (movedError, movedResult) => {
|
||||
if (!movedError) {
|
||||
this.hasMoved.set(movedResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getOriginalPosition() {
|
||||
return this.originalPosition.get();
|
||||
}
|
||||
|
||||
isLoading() {
|
||||
return this.isLoading.get();
|
||||
}
|
||||
|
||||
hasMovedFromOriginal() {
|
||||
return this.hasMoved.get();
|
||||
}
|
||||
|
||||
getOriginalPositionDescription() {
|
||||
const position = this.getOriginalPosition();
|
||||
if (!position) return 'No original position data';
|
||||
|
||||
if (position.originalPosition) {
|
||||
const entityType = this.data().entityType;
|
||||
let description = `Original position: ${position.originalPosition.sort || 0}`;
|
||||
|
||||
if (entityType === 'list' && position.originalSwimlaneId) {
|
||||
description += ` in swimlane ${position.originalSwimlaneId}`;
|
||||
} else if (entityType === 'card') {
|
||||
if (position.originalSwimlaneId) {
|
||||
description += ` in swimlane ${position.originalSwimlaneId}`;
|
||||
}
|
||||
if (position.originalListId) {
|
||||
description += ` in list ${position.originalListId}`;
|
||||
}
|
||||
}
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
return 'No original position data';
|
||||
}
|
||||
|
||||
getOriginalTitle() {
|
||||
const position = this.getOriginalPosition();
|
||||
return position ? position.originalTitle : '';
|
||||
}
|
||||
|
||||
showOriginalPosition() {
|
||||
return this.getOriginalPosition() !== null;
|
||||
}
|
||||
}
|
||||
|
||||
OriginalPositionComponent.register('originalPosition');
|
||||
|
||||
export default OriginalPositionComponent;
|
||||
Loading…
Add table
Add a link
Reference in a new issue