Manually merged fixes from seve12.

Thanks to seve12 !

Related https://github.com/wekan/wekan/pull/5967
This commit is contained in:
Lauri Ojansivu 2025-12-22 23:18:01 +02:00
parent fc3bb962f7
commit ecfb0f0fdf
14 changed files with 457 additions and 20 deletions

View file

@ -305,7 +305,7 @@ BlazeComponent.extendComponent({
{
'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () {
Popup.back(2);
const checklist = this.checklist;
const checklist = this.data().checklist;
if (checklist && checklist._id) {
Checklists.remove(checklist._id);
}

View file

@ -85,16 +85,19 @@ template(name="linkCardPopup")
label {{_ 'swimlanes'}}:
select.js-select-swimlanes
option(value="") {{_ 'custom-field-dropdown-none'}}
each swimlanes
option(value="{{_id}}") {{isTitleDefault title}}
label {{_ 'lists'}}:
select.js-select-lists
option(value="") {{_ 'custom-field-dropdown-none'}}
each lists
option(value="{{_id}}") {{isTitleDefault title}}
label {{_ 'cards'}}:
select.js-select-cards
option(value="") {{_ 'custom-field-dropdown-none'}}
each cards
option(value="{{getRealId}}") {{getTitle}}

View file

@ -542,8 +542,6 @@ BlazeComponent.extendComponent({
{
sort: { sort: 1 },
});
if (swimlanes.length)
this.selectedSwimlaneId.set(swimlanes[0]._id);
return swimlanes;
},
@ -558,7 +556,6 @@ BlazeComponent.extendComponent({
{
sort: { sort: 1 },
});
if (lists.length) this.selectedListId.set(lists[0]._id);
return lists;
},
@ -567,19 +564,17 @@ BlazeComponent.extendComponent({
return [];
}
const ownCardsIds = this.board.cards().map(card => card.getRealId());
const ret = ReactiveCache.getCards(
{
boardId: this.selectedBoardId.get(),
swimlaneId: this.selectedSwimlaneId.get(),
listId: this.selectedListId.get(),
const selector = {
archived: false,
linkedId: { $nin: ownCardsIds },
_id: { $nin: ownCardsIds },
type: { $nin: ['template-card'] },
},
{
sort: { sort: 1 },
});
};
if (this.selectedBoardId.get()) selector.boardId = this.selectedBoardId.get();
if (this.selectedSwimlaneId.get()) selector.swimlaneId = this.selectedSwimlaneId.get();
if (this.selectedListId.get()) selector.listId = this.selectedListId.get();
const ret = ReactiveCache.getCards(selector, { sort: { sort: 1 } });
return ret;
},
@ -600,8 +595,12 @@ BlazeComponent.extendComponent({
return [
{
'change .js-select-boards'(evt) {
subManager.subscribe('board', $(evt.currentTarget).val(), false);
this.selectedBoardId.set($(evt.currentTarget).val());
const val = $(evt.currentTarget).val();
subManager.subscribe('board', val, false);
// Clear selections to allow linking only board or re-choose swimlane/list
this.selectedSwimlaneId.set('');
this.selectedListId.set('');
this.selectedBoardId.set(val);
},
'change .js-select-swimlanes'(evt) {
this.selectedSwimlaneId.set($(evt.currentTarget).val());

View file

@ -232,6 +232,24 @@ class DueCardsComponent extends BlazeComponent {
});
}
// Normalize dueAt to timestamps for stable client-side ordering
const future = new Date('2100-12-31').getTime();
const toTime = v => {
if (v === null || v === undefined || v === '') return future;
if (v instanceof Date) return v.getTime();
const t = new Date(v);
if (!isNaN(t.getTime())) return t.getTime();
return future;
};
filteredCards.sort((a, b) => {
const x = toTime(a.dueAt);
const y = toTime(b.dueAt);
if (x > y) return 1;
if (x < y) return -1;
return 0;
});
if (process.env.DEBUG === 'true') {
console.log('dueCards client: filtered to', filteredCards.length, 'cards');
}

View file

@ -24,6 +24,7 @@ template(name="boardActions")
| {{_'r-the-board'}}
div.trigger-dropdown
select(id="board-id")
option(value="" disabled selected if=not boards.length) {{loadingBoardsLabel}}
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}
@ -85,6 +86,7 @@ template(name="boardActions")
| {{_'r-the-board'}}
div.trigger-dropdown
select(id="board-id-link")
option(value="" disabled selected if=not boards.length) {{loadingBoardsLabel}}
each boards
if $eq _id currentBoard._id
option(value="{{_id}}" selected) {{_ 'current'}}

View file

@ -1,7 +1,11 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
BlazeComponent.extendComponent({
onCreated() {},
onCreated() {
// Ensure boards are available for action dropdowns
this.subscribe('boards');
},
boards() {
const ret = ReactiveCache.getBoards(
@ -19,6 +23,16 @@ BlazeComponent.extendComponent({
return ret;
},
loadingBoardsLabel() {
try {
const txt = TAPi18n.__('loading-boards');
if (txt && !txt.startsWith("key '")) return txt;
} catch (e) {
// ignore translation lookup errors
}
return 'Loading boards...';
},
events() {
return [
{

View file

@ -5,6 +5,7 @@ BlazeComponent.extendComponent({
this.subscribe('allRules');
this.subscribe('allTriggers');
this.subscribe('allActions');
this.subscribe('boards');
},
trigger() {

View file

@ -1,7 +1,9 @@
template(name="rulesActions")
h2
| ✨
| {{_ 'r-rule' }} "#{data.ruleName.get}" - {{_ 'r-add-action'}}
| {{_ 'r-rule' }} "
= ruleName.get()
| " - {{_ 'r-add-action'}}
.triggers-content
.triggers-body
.triggers-side-menu

View file

@ -1,7 +1,9 @@
template(name="rulesTriggers")
h2
| ✨
| {{_ 'r-rule' }} "#{data.ruleName.get}" - {{_ 'r-add-trigger'}}
| {{_ 'r-rule' }} "
= ruleName.get()
| " - {{_ 'r-add-trigger'}}
.triggers-content
.triggers-body
.triggers-side-menu