mirror of
https://github.com/wekan/wekan.git
synced 2026-02-21 07:24:07 +01:00
fix the hour notation
This commit is contained in:
parent
93ebae78b8
commit
0951c37536
1 changed files with 175 additions and 97 deletions
|
|
@ -27,16 +27,19 @@ BlazeComponent.extendComponent({
|
|||
this.autorun(() => {
|
||||
const currentBoardId = Session.get('currentBoard');
|
||||
if (!currentBoardId) return;
|
||||
|
||||
|
||||
const handle = subManager.subscribe('board', currentBoardId, false);
|
||||
|
||||
|
||||
// Use a separate autorun for subscription ready state to avoid reactive loops
|
||||
this.subscriptionReadyAutorun = Tracker.autorun(() => {
|
||||
if (handle.ready()) {
|
||||
if (!this._boardProcessed || this._lastProcessedBoardId !== currentBoardId) {
|
||||
if (
|
||||
!this._boardProcessed ||
|
||||
this._lastProcessedBoardId !== currentBoardId
|
||||
) {
|
||||
this._boardProcessed = true;
|
||||
this._lastProcessedBoardId = currentBoardId;
|
||||
|
||||
|
||||
// Ensure default swimlane exists (only once per board)
|
||||
this.ensureDefaultSwimlane(currentBoardId);
|
||||
// Check if board needs conversion
|
||||
|
|
@ -67,7 +70,7 @@ BlazeComponent.extendComponent({
|
|||
if (!board) return;
|
||||
|
||||
const swimlanes = board.swimlanes();
|
||||
|
||||
|
||||
if (swimlanes.length === 0) {
|
||||
// Check if any swimlane exists in the database to avoid race conditions
|
||||
const existingSwimlanes = ReactiveCache.getSwimlanes({ boardId });
|
||||
|
|
@ -77,7 +80,9 @@ BlazeComponent.extendComponent({
|
|||
boardId: boardId,
|
||||
});
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log(`Created default swimlane ${swimlaneId} for board ${boardId}`);
|
||||
console.log(
|
||||
`Created default swimlane ${swimlaneId} for board ${boardId}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
this._swimlaneCreated.add(boardId);
|
||||
|
|
@ -98,7 +103,6 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
|
||||
this.isBoardReady.set(true);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error during board conversion check:', error);
|
||||
this.isConverting.set(false);
|
||||
|
|
@ -117,7 +121,9 @@ BlazeComponent.extendComponent({
|
|||
const isMobile = Utils.getMobileMode();
|
||||
if (!isMobile) {
|
||||
const openCardIds = Session.get('openCards') || [];
|
||||
return openCardIds.map(id => ReactiveCache.getCard(id)).filter(card => card);
|
||||
return openCardIds
|
||||
.map((id) => ReactiveCache.getCard(id))
|
||||
.filter((card) => card);
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
|
@ -159,7 +165,7 @@ BlazeComponent.extendComponent({
|
|||
if (nullSortSwimlanes.length > 0) {
|
||||
const swimlanes = currentBoardData.swimlanes();
|
||||
let count = 0;
|
||||
swimlanes.forEach(s => {
|
||||
swimlanes.forEach((s) => {
|
||||
Swimlanes.update(s._id, {
|
||||
$set: {
|
||||
sort: count,
|
||||
|
|
@ -181,7 +187,7 @@ BlazeComponent.extendComponent({
|
|||
if (nullSortLists.length > 0) {
|
||||
const lists = currentBoardData.lists();
|
||||
let count = 0;
|
||||
lists.forEach(l => {
|
||||
lists.forEach((l) => {
|
||||
Lists.update(l._id, {
|
||||
$set: {
|
||||
sort: count,
|
||||
|
|
@ -208,7 +214,9 @@ BlazeComponent.extendComponent({
|
|||
function focusFirstInteractive(container) {
|
||||
if (!container) return;
|
||||
// Find first focusable element
|
||||
const focusable = container.querySelectorAll('button, [role="button"], a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
|
||||
const focusable = container.querySelectorAll(
|
||||
'button, [role="button"], a[href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
||||
);
|
||||
for (let i = 0; i < focusable.length; i++) {
|
||||
if (!focusable[i].disabled && focusable[i].offsetParent !== null) {
|
||||
focusable[i].focus();
|
||||
|
|
@ -218,16 +226,22 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
|
||||
// Observe for new popups/menus and set focus (but exclude swimlane content)
|
||||
const popupObserver = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
mutation.addedNodes.forEach(function(node) {
|
||||
if (node.nodeType === 1 &&
|
||||
(node.classList.contains('popup') || node.classList.contains('modal') || node.classList.contains('menu')) &&
|
||||
!node.closest('.js-swimlanes') &&
|
||||
!node.closest('.swimlane') &&
|
||||
!node.closest('.list') &&
|
||||
!node.closest('.minicard')) {
|
||||
setTimeout(function() { focusFirstInteractive(node); }, 10);
|
||||
const popupObserver = new MutationObserver(function (mutations) {
|
||||
mutations.forEach(function (mutation) {
|
||||
mutation.addedNodes.forEach(function (node) {
|
||||
if (
|
||||
node.nodeType === 1 &&
|
||||
(node.classList.contains('popup') ||
|
||||
node.classList.contains('modal') ||
|
||||
node.classList.contains('menu')) &&
|
||||
!node.closest('.js-swimlanes') &&
|
||||
!node.closest('.swimlane') &&
|
||||
!node.closest('.list') &&
|
||||
!node.closest('.minicard')
|
||||
) {
|
||||
setTimeout(function () {
|
||||
focusFirstInteractive(node);
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -235,11 +249,15 @@ BlazeComponent.extendComponent({
|
|||
popupObserver.observe(document.body, { childList: true, subtree: true });
|
||||
|
||||
// Remove tabindex from non-interactive elements (e.g., user abbreviations, labels)
|
||||
document.querySelectorAll('.user-abbreviation, .user-label, .card-header-label, .edit-label, .private-label').forEach(function(el) {
|
||||
if (el.hasAttribute('tabindex')) {
|
||||
el.removeAttribute('tabindex');
|
||||
}
|
||||
});
|
||||
document
|
||||
.querySelectorAll(
|
||||
'.user-abbreviation, .user-label, .card-header-label, .edit-label, .private-label',
|
||||
)
|
||||
.forEach(function (el) {
|
||||
if (el.hasAttribute('tabindex')) {
|
||||
el.removeAttribute('tabindex');
|
||||
}
|
||||
});
|
||||
/*
|
||||
// Add a toggle button for keyboard shortcuts accessibility
|
||||
if (!document.getElementById('wekan-shortcuts-toggle')) {
|
||||
|
|
@ -272,7 +290,7 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
*/
|
||||
// Ensure toggle-buttons, color choices, reactions, renaming, and calendar controls are focusable and have ARIA roles
|
||||
document.querySelectorAll('.js-toggle').forEach(function(el) {
|
||||
document.querySelectorAll('.js-toggle').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
// Short, descriptive label for favorite/star toggle
|
||||
|
|
@ -282,27 +300,27 @@ BlazeComponent.extendComponent({
|
|||
el.setAttribute('aria-label', 'Toggle');
|
||||
}
|
||||
});
|
||||
document.querySelectorAll('.js-color-choice').forEach(function(el) {
|
||||
document.querySelectorAll('.js-color-choice').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Choose color');
|
||||
});
|
||||
document.querySelectorAll('.js-reaction').forEach(function(el) {
|
||||
document.querySelectorAll('.js-reaction').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'React');
|
||||
});
|
||||
document.querySelectorAll('.js-rename-swimlane').forEach(function(el) {
|
||||
document.querySelectorAll('.js-rename-swimlane').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Rename swimlane');
|
||||
});
|
||||
document.querySelectorAll('.js-rename-list').forEach(function(el) {
|
||||
document.querySelectorAll('.js-rename-list').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Rename list');
|
||||
});
|
||||
document.querySelectorAll('.fc-button').forEach(function(el) {
|
||||
document.querySelectorAll('.fc-button').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
});
|
||||
|
|
@ -313,7 +331,10 @@ BlazeComponent.extendComponent({
|
|||
// This fixes WCAG 2.5.3: Label in Name
|
||||
const swimlanesSwitcher = this.$('.js-board-view-swimlanes');
|
||||
if (swimlanesSwitcher.length) {
|
||||
swimlanesSwitcher.attr('aria-label', swimlanesSwitcher.text().trim() || 'Swimlanes');
|
||||
swimlanesSwitcher.attr(
|
||||
'aria-label',
|
||||
swimlanesSwitcher.text().trim() || 'Swimlanes',
|
||||
);
|
||||
}
|
||||
|
||||
// Add a highly visible focus indicator and improve contrast for interactive elements
|
||||
|
|
@ -376,7 +397,7 @@ BlazeComponent.extendComponent({
|
|||
document.head.appendChild(style);
|
||||
}
|
||||
// Ensure plus/add elements are focusable and have ARIA roles
|
||||
document.querySelectorAll('.js-add-card').forEach(function(el) {
|
||||
document.querySelectorAll('.js-add-card').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Add new card');
|
||||
|
|
@ -506,7 +527,11 @@ BlazeComponent.extendComponent({
|
|||
|
||||
if ($swimlanesDom.data('uiSortable') || $swimlanesDom.data('sortable')) {
|
||||
if (Utils.isTouchScreenOrShowDesktopDragHandles()) {
|
||||
$swimlanesDom.sortable('option', 'handle', '.js-swimlane-header-handle');
|
||||
$swimlanesDom.sortable(
|
||||
'option',
|
||||
'handle',
|
||||
'.js-swimlane-header-handle',
|
||||
);
|
||||
} else {
|
||||
$swimlanesDom.sortable('option', 'handle', '.swimlane-header');
|
||||
}
|
||||
|
|
@ -532,65 +557,72 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
|
||||
notDisplayThisBoard() {
|
||||
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne('tableVisibilityMode-allowPrivateOnly');
|
||||
let allowPrivateVisibilityOnly = TableVisibilityModeSettings.findOne(
|
||||
'tableVisibilityMode-allowPrivateOnly',
|
||||
);
|
||||
let currentBoard = Utils.getCurrentBoard();
|
||||
return allowPrivateVisibilityOnly !== undefined && allowPrivateVisibilityOnly.booleanValue && currentBoard && currentBoard.permission == 'public';
|
||||
return (
|
||||
allowPrivateVisibilityOnly !== undefined &&
|
||||
allowPrivateVisibilityOnly.booleanValue &&
|
||||
currentBoard &&
|
||||
currentBoard.permission == 'public'
|
||||
);
|
||||
},
|
||||
|
||||
isViewSwimlanes() {
|
||||
const currentUser = ReactiveCache.getCurrentUser();
|
||||
let boardView;
|
||||
|
||||
|
||||
if (currentUser) {
|
||||
boardView = (currentUser.profile || {}).boardView;
|
||||
} else {
|
||||
boardView = window.localStorage.getItem('boardView');
|
||||
}
|
||||
|
||||
|
||||
// If no board view is set, default to swimlanes
|
||||
if (!boardView) {
|
||||
boardView = 'board-view-swimlanes';
|
||||
}
|
||||
|
||||
|
||||
return boardView === 'board-view-swimlanes';
|
||||
},
|
||||
|
||||
isViewLists() {
|
||||
const currentUser = ReactiveCache.getCurrentUser();
|
||||
let boardView;
|
||||
|
||||
|
||||
if (currentUser) {
|
||||
boardView = (currentUser.profile || {}).boardView;
|
||||
} else {
|
||||
boardView = window.localStorage.getItem('boardView');
|
||||
}
|
||||
|
||||
|
||||
return boardView === 'board-view-lists';
|
||||
},
|
||||
|
||||
isViewCalendar() {
|
||||
const currentUser = ReactiveCache.getCurrentUser();
|
||||
let boardView;
|
||||
|
||||
|
||||
if (currentUser) {
|
||||
boardView = (currentUser.profile || {}).boardView;
|
||||
} else {
|
||||
boardView = window.localStorage.getItem('boardView');
|
||||
}
|
||||
|
||||
|
||||
return boardView === 'board-view-cal';
|
||||
},
|
||||
|
||||
isViewGantt() {
|
||||
const currentUser = ReactiveCache.getCurrentUser();
|
||||
let boardView;
|
||||
|
||||
|
||||
if (currentUser) {
|
||||
boardView = (currentUser.profile || {}).boardView;
|
||||
} else {
|
||||
boardView = window.localStorage.getItem('boardView');
|
||||
}
|
||||
|
||||
|
||||
return boardView === 'board-view-gantt';
|
||||
},
|
||||
|
||||
|
|
@ -602,12 +634,16 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const swimlanes = currentBoard.swimlanes();
|
||||
const hasSwimlanes = swimlanes && swimlanes.length > 0;
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('hasSwimlanes: Board has', swimlanes ? swimlanes.length : 0, 'swimlanes');
|
||||
console.log(
|
||||
'hasSwimlanes: Board has',
|
||||
swimlanes ? swimlanes.length : 0,
|
||||
'swimlanes',
|
||||
);
|
||||
}
|
||||
return hasSwimlanes;
|
||||
} catch (error) {
|
||||
|
|
@ -616,7 +652,6 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
},
|
||||
|
||||
|
||||
isVerticalScrollbars() {
|
||||
const user = ReactiveCache.getCurrentUser();
|
||||
return user && user.isVerticalScrollbars();
|
||||
|
|
@ -638,28 +673,31 @@ BlazeComponent.extendComponent({
|
|||
const isBoardReady = this.isBoardReady.get();
|
||||
const isConverting = this.isConverting.get();
|
||||
const boardView = Utils.boardView();
|
||||
|
||||
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('=== BOARD DEBUG STATE ===');
|
||||
console.log('currentBoardId:', currentBoardId);
|
||||
console.log('currentBoard:', !!currentBoard, currentBoard ? currentBoard.title : 'none');
|
||||
console.log(
|
||||
'currentBoard:',
|
||||
!!currentBoard,
|
||||
currentBoard ? currentBoard.title : 'none',
|
||||
);
|
||||
console.log('isBoardReady:', isBoardReady);
|
||||
console.log('isConverting:', isConverting);
|
||||
console.log('boardView:', boardView);
|
||||
console.log('========================');
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
currentBoardId,
|
||||
hasCurrentBoard: !!currentBoard,
|
||||
currentBoardTitle: currentBoard ? currentBoard.title : 'none',
|
||||
isBoardReady,
|
||||
isConverting,
|
||||
boardView
|
||||
boardView,
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
openNewListForm() {
|
||||
if (this.isViewSwimlanes()) {
|
||||
// The form had been removed in 416b17062e57f215206e93a85b02ef9eb1ab4902
|
||||
|
|
@ -686,7 +724,11 @@ BlazeComponent.extendComponent({
|
|||
// Global drag and drop file upload handlers for better visual feedback
|
||||
'dragover .board-canvas'(event) {
|
||||
const dataTransfer = event.originalEvent.dataTransfer;
|
||||
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
|
||||
if (
|
||||
dataTransfer &&
|
||||
dataTransfer.types &&
|
||||
dataTransfer.types.includes('Files')
|
||||
) {
|
||||
event.preventDefault();
|
||||
// Add visual indicator that files can be dropped
|
||||
$('.board-canvas').addClass('file-drag-over');
|
||||
|
|
@ -694,7 +736,11 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
'dragleave .board-canvas'(event) {
|
||||
const dataTransfer = event.originalEvent.dataTransfer;
|
||||
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
|
||||
if (
|
||||
dataTransfer &&
|
||||
dataTransfer.types &&
|
||||
dataTransfer.types.includes('Files')
|
||||
) {
|
||||
// Only remove class if we're leaving the board canvas entirely
|
||||
if (!event.currentTarget.contains(event.relatedTarget)) {
|
||||
$('.board-canvas').removeClass('file-drag-over');
|
||||
|
|
@ -703,7 +749,11 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
'drop .board-canvas'(event) {
|
||||
const dataTransfer = event.originalEvent.dataTransfer;
|
||||
if (dataTransfer && dataTransfer.types && dataTransfer.types.includes('Files')) {
|
||||
if (
|
||||
dataTransfer &&
|
||||
dataTransfer.types &&
|
||||
dataTransfer.types.includes('Files')
|
||||
) {
|
||||
event.preventDefault();
|
||||
$('.board-canvas').removeClass('file-drag-over');
|
||||
}
|
||||
|
|
@ -738,12 +788,12 @@ BlazeComponent.extendComponent({
|
|||
|
||||
// Accessibility: Allow users to enable/disable keyboard shortcuts
|
||||
window.wekanShortcutsEnabled = true;
|
||||
window.toggleWekanShortcuts = function(enabled) {
|
||||
window.toggleWekanShortcuts = function (enabled) {
|
||||
window.wekanShortcutsEnabled = !!enabled;
|
||||
};
|
||||
|
||||
// Example: Wrap your character key shortcut handler like this
|
||||
document.addEventListener('keydown', function(e) {
|
||||
document.addEventListener('keydown', function (e) {
|
||||
// Example: "W" key shortcut (replace with your actual shortcut logic)
|
||||
if (!window.wekanShortcutsEnabled) return;
|
||||
if (e.key === 'w' || e.key === 'W') {
|
||||
|
|
@ -753,7 +803,7 @@ document.addEventListener('keydown', function(e) {
|
|||
});
|
||||
|
||||
// Keyboard accessibility for card actions (favorite, archive, duplicate, etc.)
|
||||
document.addEventListener('keydown', function(e) {
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (!window.wekanShortcutsEnabled) return;
|
||||
// Only proceed if focus is on a card action element
|
||||
const active = document.activeElement;
|
||||
|
|
@ -798,14 +848,20 @@ document.addEventListener('keydown', function(e) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Ensure move card buttons are focusable and have ARIA roles
|
||||
document.querySelectorAll('.js-move-card').forEach(function(el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Move card');
|
||||
});
|
||||
// Ensure move card buttons are focusable and have ARIA roles
|
||||
document.querySelectorAll('.js-move-card').forEach(function (el) {
|
||||
el.setAttribute('tabindex', '0');
|
||||
el.setAttribute('role', 'button');
|
||||
el.setAttribute('aria-label', 'Move card');
|
||||
});
|
||||
// Make toggle-buttons, color choices, reactions, and X-buttons keyboard accessible
|
||||
if (active && (active.classList.contains('js-toggle') || active.classList.contains('js-color-choice') || active.classList.contains('js-reaction') || active.classList.contains('close'))) {
|
||||
if (
|
||||
active &&
|
||||
(active.classList.contains('js-toggle') ||
|
||||
active.classList.contains('js-color-choice') ||
|
||||
active.classList.contains('js-reaction') ||
|
||||
active.classList.contains('close'))
|
||||
) {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
active.click();
|
||||
|
|
@ -813,13 +869,21 @@ document.addEventListener('keydown', function(e) {
|
|||
}
|
||||
// Prevent scripts from removing focus when received
|
||||
if (active) {
|
||||
active.addEventListener('focus', function(e) {
|
||||
// Do not remove focus
|
||||
// No-op: This prevents F55 failure
|
||||
}, { once: true });
|
||||
active.addEventListener(
|
||||
'focus',
|
||||
function (e) {
|
||||
// Do not remove focus
|
||||
// No-op: This prevents F55 failure
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
}
|
||||
// Make swimlane/list renaming keyboard accessible
|
||||
if (active && (active.classList.contains('js-rename-swimlane') || active.classList.contains('js-rename-list'))) {
|
||||
if (
|
||||
active &&
|
||||
(active.classList.contains('js-rename-swimlane') ||
|
||||
active.classList.contains('js-rename-list'))
|
||||
) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
active.click();
|
||||
|
|
@ -851,20 +915,23 @@ BlazeComponent.extendComponent({
|
|||
selectable: true,
|
||||
timezone: 'local',
|
||||
weekNumbers: true,
|
||||
// Use non-localized AM/PM time format to avoid confusing notations like 上/下/中
|
||||
timeFormat: 'h:mma',
|
||||
slotLabelFormat: 'h:mma',
|
||||
header: {
|
||||
left: 'title today prev,next',
|
||||
left: 'title today prev,next',
|
||||
center:
|
||||
'agendaDay,listDay,timelineDay agendaWeek,listWeek,timelineWeek month,listMonth',
|
||||
right: '',
|
||||
},
|
||||
buttonText: {
|
||||
prev: TAPi18n.__('calendar-previous-month-label'), // e.g. "Previous month"
|
||||
next: TAPi18n.__('calendar-next-month-label'), // e.g. "Next month"
|
||||
},
|
||||
ariaLabel: {
|
||||
prev: TAPi18n.__('calendar-previous-month-label'),
|
||||
next: TAPi18n.__('calendar-next-month-label'),
|
||||
},
|
||||
buttonText: {
|
||||
prev: TAPi18n.__('calendar-previous-month-label'), // e.g. "Previous month"
|
||||
next: TAPi18n.__('calendar-next-month-label'), // e.g. "Next month"
|
||||
},
|
||||
ariaLabel: {
|
||||
prev: TAPi18n.__('calendar-previous-month-label'),
|
||||
next: TAPi18n.__('calendar-next-month-label'),
|
||||
},
|
||||
// height: 'parent', nope, doesn't work as the parent might be small
|
||||
height: 'auto',
|
||||
/* TODO: lists as resources: https://fullcalendar.io/docs/vertical-resource-view */
|
||||
|
|
@ -976,40 +1043,52 @@ BlazeComponent.extendComponent({
|
|||
</div>
|
||||
</div>
|
||||
`;
|
||||
const createCardButton = modalElement.querySelector('#create-card-button');
|
||||
const createCardButton = modalElement.querySelector(
|
||||
'#create-card-button',
|
||||
);
|
||||
createCardButton.addEventListener('click', function () {
|
||||
const myTitle = modalElement.querySelector('#card-title-input').value;
|
||||
if (myTitle) {
|
||||
const firstList = currentBoard.draggableLists()[0];
|
||||
const firstSwimlane = currentBoard.swimlanes()[0];
|
||||
Meteor.call('createCardWithDueDate', currentBoard._id, firstList._id, myTitle, startDate.toDate(), firstSwimlane._id, function(error, result) {
|
||||
if (error) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log(error);
|
||||
Meteor.call(
|
||||
'createCardWithDueDate',
|
||||
currentBoard._id,
|
||||
firstList._id,
|
||||
myTitle,
|
||||
startDate.toDate(),
|
||||
firstSwimlane._id,
|
||||
function (error, result) {
|
||||
if (error) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log(error);
|
||||
}
|
||||
} else {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('Card Created', result);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log("Card Created", result);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
closeModal();
|
||||
}
|
||||
});
|
||||
document.body.appendChild(modalElement);
|
||||
const openModal = function() {
|
||||
const openModal = function () {
|
||||
modalElement.style.display = 'flex';
|
||||
// Set focus to the input field for better keyboard accessibility
|
||||
const input = modalElement.querySelector('#card-title-input');
|
||||
if (input) input.focus();
|
||||
};
|
||||
const closeModal = function() {
|
||||
const closeModal = function () {
|
||||
modalElement.style.display = 'none';
|
||||
};
|
||||
const closeButton = modalElement.querySelector('[data-dismiss="modal"]');
|
||||
const closeButton = modalElement.querySelector(
|
||||
'[data-dismiss="modal"]',
|
||||
);
|
||||
closeButton.addEventListener('click', closeModal);
|
||||
openModal();
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
isViewCalendar() {
|
||||
|
|
@ -1025,4 +1104,3 @@ BlazeComponent.extendComponent({
|
|||
* Gantt View Component
|
||||
* Displays cards as a Gantt chart with start/due dates
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue