Migrate sidebar and settings components from BlazeComponent to Template

Convert sidebar, sidebarArchives, sidebarCustomFields, sidebarFilters,
sidebarSearches, and all settings panel components to use native Meteor
Template.onCreated/helpers/events pattern.
This commit is contained in:
Harry Adel 2026-03-08 11:01:21 +02:00
parent d3625db755
commit bae23f9ed8
12 changed files with 2937 additions and 3046 deletions

View file

@ -1,143 +1,178 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
import { AttachmentStorage } from '/models/attachments';
import { CardSearchPagedComponent } from '/client/lib/cardSearch';
import { CardSearchPaged } from '/client/lib/cardSearch';
import SessionData from '/models/usersessiondata';
import { QueryParams } from '/config/query-classes';
import { OPERATOR_LIMIT } from '/config/search-const';
const filesize = require('filesize');
BlazeComponent.extendComponent({
subscription: null,
showFilesReport: new ReactiveVar(false),
showBrokenCardsReport: new ReactiveVar(false),
showOrphanedFilesReport: new ReactiveVar(false),
showRulesReport: new ReactiveVar(false),
showCardsReport: new ReactiveVar(false),
showBoardsReport: new ReactiveVar(false),
sessionId: null,
// --- Shared helper functions (formerly AdminReport base class methods) ---
onCreated() {
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
this.sessionId = SessionData.getSessionId();
},
events() {
return [
{
'click a.js-report-broken': this.switchMenu,
'click a.js-report-files': this.switchMenu,
'click a.js-report-rules': this.switchMenu,
'click a.js-report-cards': this.switchMenu,
'click a.js-report-boards': this.switchMenu,
},
];
},
switchMenu(event) {
const target = $(event.target);
if (!target.hasClass('active')) {
this.loading.set(true);
this.showFilesReport.set(false);
this.showBrokenCardsReport.set(false);
this.showOrphanedFilesReport.set(false);
this.showRulesReport.set(false)
this.showBoardsReport.set(false);
this.showCardsReport.set(false);
if (this.subscription) {
this.subscription.stop();
}
$('.side-menu li.active').removeClass('active');
target.parent().addClass('active');
const targetID = target.data('id');
if ('report-broken' === targetID) {
this.showBrokenCardsReport.set(true);
this.subscription = Meteor.subscribe(
'brokenCards',
SessionData.getSessionId(),
() => {
this.loading.set(false);
},
);
} else if ('report-files' === targetID) {
this.showFilesReport.set(true);
this.subscription = Meteor.subscribe('attachmentsList', () => {
this.loading.set(false);
});
} else if ('report-rules' === targetID) {
this.subscription = Meteor.subscribe('rulesReport', () => {
this.showRulesReport.set(true);
this.loading.set(false);
});
} else if ('report-boards' === targetID) {
this.subscription = Meteor.subscribe('boardsReport', () => {
this.showBoardsReport.set(true);
this.loading.set(false);
});
} else if ('report-cards' === targetID) {
const qp = new QueryParams();
qp.addPredicate(OPERATOR_LIMIT, 300);
this.subscription = Meteor.subscribe(
'globalSearch',
this.sessionId,
qp.getParams(),
qp.text,
() => {
this.showCardsReport.set(true);
this.loading.set(false);
},
);
}
}
},
}).register('adminReports');
class AdminReport extends BlazeComponent {
collection;
results() {
// eslint-disable-next-line no-console
return this.collection.find();
}
yesOrNo(value) {
if (value) {
return TAPi18n.__('yes');
} else {
return TAPi18n.__('no');
}
}
resultsCount() {
return this.collection.find().count();
}
fileSize(size) {
let ret = "";
if (_.isNumber(size)) {
ret = filesize(size);
}
return ret;
}
abbreviate(text) {
if (text?.length > 30) {
return `${text.substr(0, 29)}...`;
}
return text;
function yesOrNo(value) {
if (value) {
return TAPi18n.__('yes');
} else {
return TAPi18n.__('no');
}
}
(class extends AdminReport {
collection = Attachments;
}.register('filesReport'));
function fileSizeHelper(size) {
let ret = "";
if (_.isNumber(size)) {
ret = filesize(size);
}
return ret;
}
(class extends AdminReport {
collection = Rules;
function abbreviate(text) {
if (text?.length > 30) {
return `${text.substr(0, 29)}...`;
}
return text;
}
function collectionResults(collection) {
return collection.find();
}
function collectionResultsCount(collection) {
return collection.find().count();
}
// --- adminReports template ---
Template.adminReports.onCreated(function () {
this.subscription = null;
this.showFilesReport = new ReactiveVar(false);
this.showBrokenCardsReport = new ReactiveVar(false);
this.showOrphanedFilesReport = new ReactiveVar(false);
this.showRulesReport = new ReactiveVar(false);
this.showCardsReport = new ReactiveVar(false);
this.showBoardsReport = new ReactiveVar(false);
this.sessionId = SessionData.getSessionId();
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
});
Template.adminReports.helpers({
showFilesReport() {
return Template.instance().showFilesReport;
},
showBrokenCardsReport() {
return Template.instance().showBrokenCardsReport;
},
showOrphanedFilesReport() {
return Template.instance().showOrphanedFilesReport;
},
showRulesReport() {
return Template.instance().showRulesReport;
},
showCardsReport() {
return Template.instance().showCardsReport;
},
showBoardsReport() {
return Template.instance().showBoardsReport;
},
loading() {
return Template.instance().loading;
},
});
Template.adminReports.events({
'click a.js-report-broken'(event) {
switchMenu(event, Template.instance());
},
'click a.js-report-files'(event) {
switchMenu(event, Template.instance());
},
'click a.js-report-rules'(event) {
switchMenu(event, Template.instance());
},
'click a.js-report-cards'(event) {
switchMenu(event, Template.instance());
},
'click a.js-report-boards'(event) {
switchMenu(event, Template.instance());
},
});
function switchMenu(event, tmpl) {
const target = $(event.target);
if (!target.hasClass('active')) {
tmpl.loading.set(true);
tmpl.showFilesReport.set(false);
tmpl.showBrokenCardsReport.set(false);
tmpl.showOrphanedFilesReport.set(false);
tmpl.showRulesReport.set(false);
tmpl.showBoardsReport.set(false);
tmpl.showCardsReport.set(false);
if (tmpl.subscription) {
tmpl.subscription.stop();
}
$('.side-menu li.active').removeClass('active');
target.parent().addClass('active');
const targetID = target.data('id');
if ('report-broken' === targetID) {
tmpl.showBrokenCardsReport.set(true);
tmpl.subscription = Meteor.subscribe(
'brokenCards',
SessionData.getSessionId(),
() => {
tmpl.loading.set(false);
},
);
} else if ('report-files' === targetID) {
tmpl.showFilesReport.set(true);
tmpl.subscription = Meteor.subscribe('attachmentsList', () => {
tmpl.loading.set(false);
});
} else if ('report-rules' === targetID) {
tmpl.subscription = Meteor.subscribe('rulesReport', () => {
tmpl.showRulesReport.set(true);
tmpl.loading.set(false);
});
} else if ('report-boards' === targetID) {
tmpl.subscription = Meteor.subscribe('boardsReport', () => {
tmpl.showBoardsReport.set(true);
tmpl.loading.set(false);
});
} else if ('report-cards' === targetID) {
const qp = new QueryParams();
qp.addPredicate(OPERATOR_LIMIT, 300);
tmpl.subscription = Meteor.subscribe(
'globalSearch',
tmpl.sessionId,
qp.getParams(),
qp.text,
() => {
tmpl.showCardsReport.set(true);
tmpl.loading.set(false);
},
);
}
}
}
// --- filesReport template ---
Template.filesReport.helpers({
results() {
return collectionResults(Attachments);
},
resultsCount() {
return collectionResultsCount(Attachments);
},
fileSize(size) {
return fileSizeHelper(size);
},
});
// --- rulesReport template ---
Template.rulesReport.helpers({
results() {
const rules = [];
@ -155,12 +190,27 @@ class AdminReport extends BlazeComponent {
// eslint-disable-next-line no-console
console.log('rows:', rules);
return rules;
}
}.register('rulesReport'));
},
resultsCount() {
return collectionResultsCount(Rules);
},
});
(class extends AdminReport {
collection = Boards;
// --- boardsReport template ---
Template.boardsReport.helpers({
results() {
return collectionResults(Boards);
},
resultsCount() {
return collectionResultsCount(Boards);
},
yesOrNo(value) {
return yesOrNo(value);
},
abbreviate(text) {
return abbreviate(text);
},
userNames(members) {
const ret = (members || [])
.map(_member => {
@ -169,7 +219,7 @@ class AdminReport extends BlazeComponent {
})
.join(", ");
return ret;
}
},
teams(memberTeams) {
const ret = (memberTeams || [])
.map(_memberTeam => {
@ -178,7 +228,7 @@ class AdminReport extends BlazeComponent {
})
.join(", ");
return ret;
}
},
orgs(orgs) {
const ret = (orgs || [])
.map(_orgs => {
@ -187,13 +237,21 @@ class AdminReport extends BlazeComponent {
})
.join(", ");
return ret;
}
}.register('boardsReport'));
},
});
// --- cardsReport template ---
(class extends AdminReport {
collection = Cards;
Template.cardsReport.helpers({
results() {
return collectionResults(Cards);
},
resultsCount() {
return collectionResultsCount(Cards);
},
abbreviate(text) {
return abbreviate(text);
},
userNames(userIds) {
const ret = (userIds || [])
.map(_userId => {
@ -201,13 +259,45 @@ class AdminReport extends BlazeComponent {
return _ret;
})
.join(", ");
return ret
}
}.register('cardsReport'));
return ret;
},
});
class BrokenCardsComponent extends CardSearchPagedComponent {
onCreated() {
super.onCreated();
}
}
BrokenCardsComponent.register('brokenCardsReport');
// --- brokenCardsReport template ---
Template.brokenCardsReport.onCreated(function () {
const search = new CardSearchPaged(this);
this.search = search;
});
Template.brokenCardsReport.helpers({
resultsCount() {
return Template.instance().search.resultsCount;
},
resultsHeading() {
return Template.instance().search.resultsHeading;
},
results() {
return Template.instance().search.results;
},
getSearchHref() {
return Template.instance().search.getSearchHref();
},
hasPreviousPage() {
return Template.instance().search.hasPreviousPage;
},
hasNextPage() {
return Template.instance().search.hasNextPage;
},
});
Template.brokenCardsReport.events({
'click .js-next-page'(evt, tpl) {
evt.preventDefault();
tpl.search.nextPage();
},
'click .js-previous-page'(evt, tpl) {
evt.preventDefault();
tpl.search.previousPage();
},
});