mirror of
https://github.com/wekan/wekan.git
synced 2026-03-13 17:06:13 +01:00
Migrate rules, activities, and remaining components to Template
Convert all remaining BlazeComponent-based components to native Meteor Template pattern: activities, comments, all rules actions/triggers, swimlanes, users, gantt, import, and main utility components.
This commit is contained in:
parent
bae23f9ed8
commit
477e1c89e5
29 changed files with 2859 additions and 2894 deletions
|
|
@ -1,178 +1,37 @@
|
|||
import { ReactiveCache } from '/imports/reactiveCache';
|
||||
import { BlazeComponent } from 'meteor/peerlibrary:blaze-components';
|
||||
import { TAPi18n } from '/imports/i18n';
|
||||
|
||||
// const subManager = new SubsManager();
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
Template.dueCardsHeaderBar.helpers({
|
||||
dueCardsView() {
|
||||
// eslint-disable-next-line no-console
|
||||
// console.log('sort:', Utils.dueCardsView());
|
||||
return Utils && Utils.dueCardsView ? Utils.dueCardsView() : 'me';
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-due-cards-view-change': Popup.open('dueCardsViewChange'),
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('dueCardsHeaderBar');
|
||||
|
||||
Template.dueCards.helpers({
|
||||
userId() {
|
||||
return Meteor.userId();
|
||||
},
|
||||
dueCardsList() {
|
||||
const component = BlazeComponent.getComponentForElement(this.firstNode);
|
||||
if (component && component.dueCardsList) {
|
||||
return component.dueCardsList();
|
||||
}
|
||||
return [];
|
||||
},
|
||||
hasResults() {
|
||||
const component = BlazeComponent.getComponentForElement(this.firstNode);
|
||||
if (component && component.hasResults) {
|
||||
return component.hasResults.get();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
searching() {
|
||||
const component = BlazeComponent.getComponentForElement(this.firstNode);
|
||||
if (component && component.isLoading) {
|
||||
return component.isLoading.get();
|
||||
}
|
||||
return true; // Show loading by default
|
||||
},
|
||||
hasQueryErrors() {
|
||||
return false; // No longer using search, so always false
|
||||
},
|
||||
errorMessages() {
|
||||
return []; // No longer using search, so always empty
|
||||
},
|
||||
cardsCount() {
|
||||
const component = BlazeComponent.getComponentForElement(this.firstNode);
|
||||
if (component && component.cardsCount) {
|
||||
return component.cardsCount();
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
resultsText() {
|
||||
const component = BlazeComponent.getComponentForElement(this.firstNode);
|
||||
if (component && component.resultsText) {
|
||||
return component.resultsText();
|
||||
}
|
||||
return '';
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-due-cards-view-me'() {
|
||||
if (Utils && Utils.setDueCardsView) {
|
||||
Utils.setDueCardsView('me');
|
||||
}
|
||||
Popup.back();
|
||||
},
|
||||
Template.dueCardsHeaderBar.events({
|
||||
'click .js-due-cards-view-change': Popup.open('dueCardsViewChange'),
|
||||
});
|
||||
|
||||
'click .js-due-cards-view-all'() {
|
||||
if (Utils && Utils.setDueCardsView) {
|
||||
Utils.setDueCardsView('all');
|
||||
}
|
||||
Popup.back();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('dueCardsViewChangePopup');
|
||||
Template.dueCards.onCreated(function () {
|
||||
this._cachedCards = null;
|
||||
this._cachedTimestamp = null;
|
||||
this.subscriptionHandle = null;
|
||||
this.isLoading = new ReactiveVar(true);
|
||||
this.hasResults = new ReactiveVar(false);
|
||||
this.searching = new ReactiveVar(false);
|
||||
|
||||
class DueCardsComponent extends BlazeComponent {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
const tpl = this;
|
||||
|
||||
this._cachedCards = null;
|
||||
this._cachedTimestamp = null;
|
||||
this.subscriptionHandle = null;
|
||||
this.isLoading = new ReactiveVar(true);
|
||||
this.hasResults = new ReactiveVar(false);
|
||||
this.searching = new ReactiveVar(false);
|
||||
|
||||
// Subscribe to the optimized due cards publication
|
||||
this.autorun(() => {
|
||||
const allUsers = this.dueCardsView() === 'all';
|
||||
if (this.subscriptionHandle) {
|
||||
this.subscriptionHandle.stop();
|
||||
}
|
||||
this.subscriptionHandle = Meteor.subscribe('dueCards', allUsers);
|
||||
|
||||
// Update loading state based on subscription
|
||||
this.autorun(() => {
|
||||
if (this.subscriptionHandle && this.subscriptionHandle.ready()) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: subscription ready, loading data...');
|
||||
}
|
||||
this.isLoading.set(false);
|
||||
const cards = this.dueCardsList();
|
||||
this.hasResults.set(cards && cards.length > 0);
|
||||
} else {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: subscription not ready, showing loading...');
|
||||
}
|
||||
this.isLoading.set(true);
|
||||
this.hasResults.set(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onDestroyed() {
|
||||
super.onDestroyed();
|
||||
if (this.subscriptionHandle) {
|
||||
this.subscriptionHandle.stop();
|
||||
}
|
||||
}
|
||||
|
||||
dueCardsView() {
|
||||
// eslint-disable-next-line no-console
|
||||
//console.log('sort:', Utils.dueCardsView());
|
||||
function dueCardsView() {
|
||||
return Utils && Utils.dueCardsView ? Utils.dueCardsView() : 'me';
|
||||
}
|
||||
|
||||
sortByBoard() {
|
||||
return this.dueCardsView() === 'board';
|
||||
}
|
||||
|
||||
hasResults() {
|
||||
return this.hasResults.get();
|
||||
}
|
||||
|
||||
cardsCount() {
|
||||
const cards = this.dueCardsList();
|
||||
return cards ? cards.length : 0;
|
||||
}
|
||||
|
||||
resultsText() {
|
||||
const count = this.cardsCount();
|
||||
if (count === 1) {
|
||||
return TAPi18n.__('one-card-found');
|
||||
} else {
|
||||
// Get the translated text and manually replace %s with the count
|
||||
const baseText = TAPi18n.__('n-cards-found');
|
||||
const result = baseText.replace('%s', count);
|
||||
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: base text:', baseText, 'count:', count, 'result:', result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
dueCardsList() {
|
||||
function dueCardsList() {
|
||||
// Check if subscription is ready
|
||||
if (!this.subscriptionHandle || !this.subscriptionHandle.ready()) {
|
||||
if (!tpl.subscriptionHandle || !tpl.subscriptionHandle.ready()) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards client: subscription not ready');
|
||||
}
|
||||
|
|
@ -180,11 +39,11 @@ class DueCardsComponent extends BlazeComponent {
|
|||
}
|
||||
|
||||
// Use cached results if available to avoid expensive re-sorting
|
||||
if (this._cachedCards && this._cachedTimestamp && (Date.now() - this._cachedTimestamp < 5000)) {
|
||||
if (tpl._cachedCards && tpl._cachedTimestamp && (Date.now() - tpl._cachedTimestamp < 5000)) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards client: using cached results,', this._cachedCards.length, 'cards');
|
||||
console.log('dueCards client: using cached results,', tpl._cachedCards.length, 'cards');
|
||||
}
|
||||
return this._cachedCards;
|
||||
return tpl._cachedCards;
|
||||
}
|
||||
|
||||
// Get cards directly from the subscription (already sorted by the publication)
|
||||
|
|
@ -208,7 +67,7 @@ class DueCardsComponent extends BlazeComponent {
|
|||
}
|
||||
|
||||
// Filter cards based on user view preference
|
||||
const allUsers = this.dueCardsView() === 'all';
|
||||
const allUsers = dueCardsView() === 'all';
|
||||
const currentUser = ReactiveCache.getCurrentUser();
|
||||
let filteredCards = cards;
|
||||
|
||||
|
|
@ -255,15 +114,106 @@ class DueCardsComponent extends BlazeComponent {
|
|||
}
|
||||
|
||||
// Cache the results for 5 seconds to avoid re-filtering on every render
|
||||
this._cachedCards = filteredCards;
|
||||
this._cachedTimestamp = Date.now();
|
||||
tpl._cachedCards = filteredCards;
|
||||
tpl._cachedTimestamp = Date.now();
|
||||
|
||||
// Update reactive variables
|
||||
this.hasResults.set(filteredCards && filteredCards.length > 0);
|
||||
this.isLoading.set(false);
|
||||
tpl.hasResults.set(filteredCards && filteredCards.length > 0);
|
||||
tpl.isLoading.set(false);
|
||||
|
||||
return filteredCards;
|
||||
}
|
||||
}
|
||||
|
||||
DueCardsComponent.register('dueCards');
|
||||
// Store dueCardsList on the instance so helpers can call it
|
||||
this.dueCardsList = dueCardsList;
|
||||
this.dueCardsView = dueCardsView;
|
||||
|
||||
// Subscribe to the optimized due cards publication
|
||||
this.autorun(() => {
|
||||
const allUsers = dueCardsView() === 'all';
|
||||
if (tpl.subscriptionHandle) {
|
||||
tpl.subscriptionHandle.stop();
|
||||
}
|
||||
tpl.subscriptionHandle = Meteor.subscribe('dueCards', allUsers);
|
||||
|
||||
// Update loading state based on subscription
|
||||
tpl.autorun(() => {
|
||||
if (tpl.subscriptionHandle && tpl.subscriptionHandle.ready()) {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: subscription ready, loading data...');
|
||||
}
|
||||
tpl.isLoading.set(false);
|
||||
const cards = dueCardsList();
|
||||
tpl.hasResults.set(cards && cards.length > 0);
|
||||
} else {
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: subscription not ready, showing loading...');
|
||||
}
|
||||
tpl.isLoading.set(true);
|
||||
tpl.hasResults.set(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Template.dueCards.onDestroyed(function () {
|
||||
if (this.subscriptionHandle) {
|
||||
this.subscriptionHandle.stop();
|
||||
}
|
||||
});
|
||||
|
||||
Template.dueCards.helpers({
|
||||
userId() {
|
||||
return Meteor.userId();
|
||||
},
|
||||
// Return ReactiveVar so jade can use .get pattern
|
||||
searching() {
|
||||
return Template.instance().isLoading;
|
||||
},
|
||||
hasResults() {
|
||||
return Template.instance().hasResults;
|
||||
},
|
||||
hasQueryErrors() {
|
||||
return new ReactiveVar(false);
|
||||
},
|
||||
errorMessages() {
|
||||
return [];
|
||||
},
|
||||
dueCardsList() {
|
||||
const tpl = Template.instance();
|
||||
return tpl.dueCardsList ? tpl.dueCardsList() : [];
|
||||
},
|
||||
resultsText() {
|
||||
const tpl = Template.instance();
|
||||
const cards = tpl.dueCardsList ? tpl.dueCardsList() : [];
|
||||
const count = cards ? cards.length : 0;
|
||||
if (count === 1) {
|
||||
return TAPi18n.__('one-card-found');
|
||||
} else {
|
||||
// Get the translated text and manually replace %s with the count
|
||||
const baseText = TAPi18n.__('n-cards-found');
|
||||
const result = baseText.replace('%s', count);
|
||||
|
||||
if (process.env.DEBUG === 'true') {
|
||||
console.log('dueCards: base text:', baseText, 'count:', count, 'result:', result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Template.dueCardsViewChangePopup.events({
|
||||
'click .js-due-cards-view-me'() {
|
||||
if (Utils && Utils.setDueCardsView) {
|
||||
Utils.setDueCardsView('me');
|
||||
}
|
||||
Popup.back();
|
||||
},
|
||||
|
||||
'click .js-due-cards-view-all'() {
|
||||
if (Utils && Utils.setDueCardsView) {
|
||||
Utils.setDueCardsView('all');
|
||||
}
|
||||
Popup.back();
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue