mirror of
https://github.com/wekan/wekan.git
synced 2026-03-13 17:06:13 +01:00
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:
parent
d3625db755
commit
bae23f9ed8
12 changed files with 2937 additions and 3046 deletions
|
|
@ -1,143 +1,178 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
import { TAPi18n } from '/imports/i18n';
|
import { TAPi18n } from '/imports/i18n';
|
||||||
import { AttachmentStorage } from '/models/attachments';
|
import { AttachmentStorage } from '/models/attachments';
|
||||||
import { CardSearchPagedComponent } from '/client/lib/cardSearch';
|
import { CardSearchPaged } from '/client/lib/cardSearch';
|
||||||
import SessionData from '/models/usersessiondata';
|
import SessionData from '/models/usersessiondata';
|
||||||
import { QueryParams } from '/config/query-classes';
|
import { QueryParams } from '/config/query-classes';
|
||||||
import { OPERATOR_LIMIT } from '/config/search-const';
|
import { OPERATOR_LIMIT } from '/config/search-const';
|
||||||
const filesize = require('filesize');
|
const filesize = require('filesize');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
// --- Shared helper functions (formerly AdminReport base class methods) ---
|
||||||
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,
|
|
||||||
|
|
||||||
onCreated() {
|
function yesOrNo(value) {
|
||||||
this.error = new ReactiveVar('');
|
if (value) {
|
||||||
this.loading = new ReactiveVar(false);
|
return TAPi18n.__('yes');
|
||||||
this.sessionId = SessionData.getSessionId();
|
} else {
|
||||||
},
|
return TAPi18n.__('no');
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(class extends AdminReport {
|
function fileSizeHelper(size) {
|
||||||
collection = Attachments;
|
let ret = "";
|
||||||
}.register('filesReport'));
|
if (_.isNumber(size)) {
|
||||||
|
ret = filesize(size);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
(class extends AdminReport {
|
function abbreviate(text) {
|
||||||
collection = Rules;
|
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() {
|
results() {
|
||||||
const rules = [];
|
const rules = [];
|
||||||
|
|
||||||
|
|
@ -155,12 +190,27 @@ class AdminReport extends BlazeComponent {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('rows:', rules);
|
console.log('rows:', rules);
|
||||||
return rules;
|
return rules;
|
||||||
}
|
},
|
||||||
}.register('rulesReport'));
|
resultsCount() {
|
||||||
|
return collectionResultsCount(Rules);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
(class extends AdminReport {
|
// --- boardsReport template ---
|
||||||
collection = Boards;
|
|
||||||
|
|
||||||
|
Template.boardsReport.helpers({
|
||||||
|
results() {
|
||||||
|
return collectionResults(Boards);
|
||||||
|
},
|
||||||
|
resultsCount() {
|
||||||
|
return collectionResultsCount(Boards);
|
||||||
|
},
|
||||||
|
yesOrNo(value) {
|
||||||
|
return yesOrNo(value);
|
||||||
|
},
|
||||||
|
abbreviate(text) {
|
||||||
|
return abbreviate(text);
|
||||||
|
},
|
||||||
userNames(members) {
|
userNames(members) {
|
||||||
const ret = (members || [])
|
const ret = (members || [])
|
||||||
.map(_member => {
|
.map(_member => {
|
||||||
|
|
@ -169,7 +219,7 @@ class AdminReport extends BlazeComponent {
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
teams(memberTeams) {
|
teams(memberTeams) {
|
||||||
const ret = (memberTeams || [])
|
const ret = (memberTeams || [])
|
||||||
.map(_memberTeam => {
|
.map(_memberTeam => {
|
||||||
|
|
@ -178,7 +228,7 @@ class AdminReport extends BlazeComponent {
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
orgs(orgs) {
|
orgs(orgs) {
|
||||||
const ret = (orgs || [])
|
const ret = (orgs || [])
|
||||||
.map(_orgs => {
|
.map(_orgs => {
|
||||||
|
|
@ -187,13 +237,21 @@ class AdminReport extends BlazeComponent {
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
},
|
||||||
}.register('boardsReport'));
|
});
|
||||||
|
|
||||||
|
// --- cardsReport template ---
|
||||||
|
|
||||||
(class extends AdminReport {
|
Template.cardsReport.helpers({
|
||||||
collection = Cards;
|
results() {
|
||||||
|
return collectionResults(Cards);
|
||||||
|
},
|
||||||
|
resultsCount() {
|
||||||
|
return collectionResultsCount(Cards);
|
||||||
|
},
|
||||||
|
abbreviate(text) {
|
||||||
|
return abbreviate(text);
|
||||||
|
},
|
||||||
userNames(userIds) {
|
userNames(userIds) {
|
||||||
const ret = (userIds || [])
|
const ret = (userIds || [])
|
||||||
.map(_userId => {
|
.map(_userId => {
|
||||||
|
|
@ -201,13 +259,45 @@ class AdminReport extends BlazeComponent {
|
||||||
return _ret;
|
return _ret;
|
||||||
})
|
})
|
||||||
.join(", ");
|
.join(", ");
|
||||||
return ret
|
return ret;
|
||||||
}
|
},
|
||||||
}.register('cardsReport'));
|
});
|
||||||
|
|
||||||
class BrokenCardsComponent extends CardSearchPagedComponent {
|
// --- brokenCardsReport template ---
|
||||||
onCreated() {
|
|
||||||
super.onCreated();
|
Template.brokenCardsReport.onCreated(function () {
|
||||||
}
|
const search = new CardSearchPaged(this);
|
||||||
}
|
this.search = search;
|
||||||
BrokenCardsComponent.register('brokenCardsReport');
|
});
|
||||||
|
|
||||||
|
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();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,31 @@ import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
import Attachments, { fileStoreStrategyFactory } from '/models/attachments';
|
import Attachments, { fileStoreStrategyFactory } from '/models/attachments';
|
||||||
const filesize = require('filesize');
|
const filesize = require('filesize');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.attachments.onCreated(function () {
|
||||||
subscription: null,
|
this.subscription = null;
|
||||||
showMoveAttachments: new ReactiveVar(false),
|
this.showMoveAttachments = new ReactiveVar(false);
|
||||||
sessionId: null,
|
this.sessionId = null;
|
||||||
|
this.error = new ReactiveVar('');
|
||||||
|
this.loading = new ReactiveVar(false);
|
||||||
|
});
|
||||||
|
|
||||||
onCreated() {
|
Template.attachments.helpers({
|
||||||
this.error = new ReactiveVar('');
|
loading() {
|
||||||
this.loading = new ReactiveVar(false);
|
return Template.instance().loading;
|
||||||
},
|
},
|
||||||
|
showMoveAttachments() {
|
||||||
events() {
|
return Template.instance().showMoveAttachments;
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.js-move-attachments': this.switchMenu,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
switchMenu(event) {
|
Template.attachments.events({
|
||||||
|
'click a.js-move-attachments'(event, tpl) {
|
||||||
const target = $(event.target);
|
const target = $(event.target);
|
||||||
if (!target.hasClass('active')) {
|
if (!target.hasClass('active')) {
|
||||||
this.loading.set(true);
|
tpl.loading.set(true);
|
||||||
this.showMoveAttachments.set(false);
|
tpl.showMoveAttachments.set(false);
|
||||||
if (this.subscription) {
|
if (tpl.subscription) {
|
||||||
this.subscription.stop();
|
tpl.subscription.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.side-menu li.active').removeClass('active');
|
$('.side-menu li.active').removeClass('active');
|
||||||
|
|
@ -34,25 +34,30 @@ BlazeComponent.extendComponent({
|
||||||
const targetID = target.data('id');
|
const targetID = target.data('id');
|
||||||
|
|
||||||
if ('move-attachments' === targetID) {
|
if ('move-attachments' === targetID) {
|
||||||
this.showMoveAttachments.set(true);
|
tpl.showMoveAttachments.set(true);
|
||||||
this.subscription = Meteor.subscribe('attachmentsList', () => {
|
tpl.subscription = Meteor.subscribe('attachmentsList', () => {
|
||||||
this.loading.set(false);
|
tpl.loading.set(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}).register('attachments');
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.moveAttachments.onCreated(function () {
|
||||||
|
this.attachments = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.moveAttachments.helpers({
|
||||||
getBoardsWithAttachments() {
|
getBoardsWithAttachments() {
|
||||||
this.attachments = ReactiveCache.getAttachments();
|
const tpl = Template.instance();
|
||||||
this.attachmentsByBoardId = _.chain(this.attachments)
|
tpl.attachments = ReactiveCache.getAttachments();
|
||||||
|
const attachmentsByBoardId = _.chain(tpl.attachments)
|
||||||
.groupBy(fileObj => fileObj.meta.boardId)
|
.groupBy(fileObj => fileObj.meta.boardId)
|
||||||
.value();
|
.value();
|
||||||
|
|
||||||
const ret = Object.keys(this.attachmentsByBoardId)
|
const ret = Object.keys(attachmentsByBoardId)
|
||||||
.map(boardId => {
|
.map(boardId => {
|
||||||
const boardAttachments = this.attachmentsByBoardId[boardId];
|
const boardAttachments = attachmentsByBoardId[boardId];
|
||||||
|
|
||||||
_.each(boardAttachments, _attachment => {
|
_.each(boardAttachments, _attachment => {
|
||||||
_attachment.flatVersion = Object.keys(_attachment.versions)
|
_attachment.flatVersion = Object.keys(_attachment.versions)
|
||||||
|
|
@ -72,71 +77,65 @@ BlazeComponent.extendComponent({
|
||||||
const ret = ReactiveCache.getBoard(boardId);
|
const ret = ReactiveCache.getBoard(boardId);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
events() {
|
});
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click button.js-move-all-attachments-to-fs'(event) {
|
|
||||||
this.attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'click button.js-move-all-attachments-to-gridfs'(event) {
|
|
||||||
this.attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'click button.js-move-all-attachments-to-s3'(event) {
|
|
||||||
this.attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "s3");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}).register('moveAttachments');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.moveAttachments.events({
|
||||||
events() {
|
'click button.js-move-all-attachments-to-fs'(event, tpl) {
|
||||||
return [
|
tpl.attachments.forEach(_attachment => {
|
||||||
{
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
||||||
'click button.js-move-all-attachments-of-board-to-fs'(event) {
|
});
|
||||||
this.data().attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'click button.js-move-all-attachments-of-board-to-gridfs'(event) {
|
|
||||||
this.data().attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'click button.js-move-all-attachments-of-board-to-s3'(event) {
|
|
||||||
this.data().attachments.forEach(_attachment => {
|
|
||||||
Meteor.call('moveAttachmentToStorage', _attachment._id, "s3");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
}).register('moveBoardAttachments');
|
'click button.js-move-all-attachments-to-gridfs'(event, tpl) {
|
||||||
|
tpl.attachments.forEach(_attachment => {
|
||||||
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click button.js-move-all-attachments-to-s3'(event, tpl) {
|
||||||
|
tpl.attachments.forEach(_attachment => {
|
||||||
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "s3");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.moveBoardAttachments.events({
|
||||||
|
'click button.js-move-all-attachments-of-board-to-fs'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
data.attachments.forEach(_attachment => {
|
||||||
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click button.js-move-all-attachments-of-board-to-gridfs'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
data.attachments.forEach(_attachment => {
|
||||||
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click button.js-move-all-attachments-of-board-to-s3'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
data.attachments.forEach(_attachment => {
|
||||||
|
Meteor.call('moveAttachmentToStorage', _attachment._id, "s3");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.moveAttachment.helpers({
|
||||||
fileSize(size) {
|
fileSize(size) {
|
||||||
const ret = filesize(size);
|
const ret = filesize(size);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
events() {
|
});
|
||||||
return [
|
|
||||||
{
|
Template.moveAttachment.events({
|
||||||
'click button.js-move-storage-fs'(event) {
|
'click button.js-move-storage-fs'() {
|
||||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "fs");
|
const data = Template.currentData();
|
||||||
},
|
Meteor.call('moveAttachmentToStorage', data._id, "fs");
|
||||||
'click button.js-move-storage-gridfs'(event) {
|
|
||||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "gridfs");
|
|
||||||
},
|
|
||||||
'click button.js-move-storage-s3'(event) {
|
|
||||||
Meteor.call('moveAttachmentToStorage', this.data()._id, "s3");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
}).register('moveAttachment');
|
'click button.js-move-storage-gridfs'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
Meteor.call('moveAttachmentToStorage', data._id, "gridfs");
|
||||||
|
},
|
||||||
|
'click button.js-move-storage-s3'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
Meteor.call('moveAttachmentToStorage', data._id, "s3");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
import { TAPi18n } from '/imports/i18n';
|
import { TAPi18n } from '/imports/i18n';
|
||||||
const filesize = require('filesize');
|
const filesize = require('filesize');
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.statistics.onCreated(function () {
|
||||||
onCreated() {
|
this.info = new ReactiveVar({});
|
||||||
this.info = new ReactiveVar({});
|
Meteor.call('getStatistics', (error, ret) => {
|
||||||
Meteor.call('getStatistics', (error, ret) => {
|
if (!error && ret) {
|
||||||
if (!error && ret) {
|
this.info.set(ret);
|
||||||
this.info.set(ret);
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
|
Template.statistics.helpers({
|
||||||
statistics() {
|
statistics() {
|
||||||
return this.info.get();
|
return Template.instance().info.get();
|
||||||
},
|
},
|
||||||
|
|
||||||
humanReadableTime(time) {
|
humanReadableTime(time) {
|
||||||
|
|
@ -47,4 +47,4 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
}).register('statistics');
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,12 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
import LockoutSettings from '/models/lockoutSettings';
|
import LockoutSettings from '/models/lockoutSettings';
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.lockedUsersGeneral.onCreated(function () {
|
||||||
onCreated() {
|
this.lockedUsers = new ReactiveVar([]);
|
||||||
this.lockedUsers = new ReactiveVar([]);
|
this.isLoadingLockedUsers = new ReactiveVar(false);
|
||||||
this.isLoadingLockedUsers = new ReactiveVar(false);
|
|
||||||
|
|
||||||
// Don't load immediately to prevent unnecessary spinner
|
// Store refreshLockedUsers on the instance so it can be called from event handlers
|
||||||
// The data will be loaded when the tab is selected in peopleBody.js switchMenu
|
this.refreshLockedUsers = () => {
|
||||||
},
|
|
||||||
|
|
||||||
refreshLockedUsers() {
|
|
||||||
// Set loading state initially, but we'll hide it if no users are found
|
// Set loading state initially, but we'll hide it if no users are found
|
||||||
this.isLoadingLockedUsers.set(true);
|
this.isLoadingLockedUsers.set(true);
|
||||||
|
|
||||||
|
|
@ -44,9 +40,54 @@ BlazeComponent.extendComponent({
|
||||||
this.lockedUsers.set(users);
|
this.lockedUsers.set(users);
|
||||||
this.isLoadingLockedUsers.set(false);
|
this.isLoadingLockedUsers.set(false);
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Don't load immediately to prevent unnecessary spinner
|
||||||
|
// The data will be loaded when the tab is selected in peopleBody.js switchMenu
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.lockedUsersGeneral.helpers({
|
||||||
|
knownFailuresBeforeLockout() {
|
||||||
|
return LockoutSettings.findOne('known-failuresBeforeLockout')?.value || 3;
|
||||||
},
|
},
|
||||||
|
|
||||||
unlockUser(event) {
|
knownLockoutPeriod() {
|
||||||
|
return LockoutSettings.findOne('known-lockoutPeriod')?.value || 60;
|
||||||
|
},
|
||||||
|
|
||||||
|
knownFailureWindow() {
|
||||||
|
return LockoutSettings.findOne('known-failureWindow')?.value || 15;
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownFailuresBeforeLockout() {
|
||||||
|
return LockoutSettings.findOne('unknown-failuresBeforeLockout')?.value || 3;
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownLockoutPeriod() {
|
||||||
|
return LockoutSettings.findOne('unknown-lockoutPeriod')?.value || 60;
|
||||||
|
},
|
||||||
|
|
||||||
|
unknownFailureWindow() {
|
||||||
|
return LockoutSettings.findOne('unknown-failureWindow')?.value || 15;
|
||||||
|
},
|
||||||
|
|
||||||
|
lockedUsers() {
|
||||||
|
return Template.instance().lockedUsers.get();
|
||||||
|
},
|
||||||
|
|
||||||
|
isLoadingLockedUsers() {
|
||||||
|
return Template.instance().isLoadingLockedUsers.get();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.lockedUsersGeneral.events({
|
||||||
|
'click button.js-refresh-locked-users'(event, tpl) {
|
||||||
|
tpl.refreshLockedUsers();
|
||||||
|
},
|
||||||
|
'click button#refreshLockedUsers'(event, tpl) {
|
||||||
|
tpl.refreshLockedUsers();
|
||||||
|
},
|
||||||
|
'click button.js-unlock-user'(event, tpl) {
|
||||||
const userId = $(event.currentTarget).data('user-id');
|
const userId = $(event.currentTarget).data('user-id');
|
||||||
if (!userId) return;
|
if (!userId) return;
|
||||||
|
|
||||||
|
|
@ -61,13 +102,12 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
|
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
|
||||||
this.refreshLockedUsers();
|
tpl.refreshLockedUsers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'click button.js-unlock-all-users'(event, tpl) {
|
||||||
unlockAllUsers() {
|
|
||||||
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
|
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
|
||||||
Meteor.call('unlockAllUsers', (err, result) => {
|
Meteor.call('unlockAllUsers', (err, result) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
@ -79,13 +119,12 @@ BlazeComponent.extendComponent({
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
|
alert(TAPi18n.__('accounts-lockout-user-unlocked'));
|
||||||
this.refreshLockedUsers();
|
tpl.refreshLockedUsers();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'click button.js-lockout-save'() {
|
||||||
saveLockoutSettings() {
|
|
||||||
// Get values from form
|
// Get values from form
|
||||||
const knownFailuresBeforeLockout = parseInt($('#known-failures-before-lockout').val(), 10) || 3;
|
const knownFailuresBeforeLockout = parseInt($('#known-failures-before-lockout').val(), 10) || 3;
|
||||||
const knownLockoutPeriod = parseInt($('#known-lockout-period').val(), 10) || 60;
|
const knownLockoutPeriod = parseInt($('#known-lockout-period').val(), 10) || 60;
|
||||||
|
|
@ -128,48 +167,4 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
});
|
||||||
knownFailuresBeforeLockout() {
|
|
||||||
return LockoutSettings.findOne('known-failuresBeforeLockout')?.value || 3;
|
|
||||||
},
|
|
||||||
|
|
||||||
knownLockoutPeriod() {
|
|
||||||
return LockoutSettings.findOne('known-lockoutPeriod')?.value || 60;
|
|
||||||
},
|
|
||||||
|
|
||||||
knownFailureWindow() {
|
|
||||||
return LockoutSettings.findOne('known-failureWindow')?.value || 15;
|
|
||||||
},
|
|
||||||
|
|
||||||
unknownFailuresBeforeLockout() {
|
|
||||||
return LockoutSettings.findOne('unknown-failuresBeforeLockout')?.value || 3;
|
|
||||||
},
|
|
||||||
|
|
||||||
unknownLockoutPeriod() {
|
|
||||||
return LockoutSettings.findOne('unknown-lockoutPeriod')?.value || 60;
|
|
||||||
},
|
|
||||||
|
|
||||||
unknownFailureWindow() {
|
|
||||||
return LockoutSettings.findOne('unknown-failureWindow')?.value || 15;
|
|
||||||
},
|
|
||||||
|
|
||||||
lockedUsers() {
|
|
||||||
return this.lockedUsers.get();
|
|
||||||
},
|
|
||||||
|
|
||||||
isLoadingLockedUsers() {
|
|
||||||
return this.isLoadingLockedUsers.get();
|
|
||||||
},
|
|
||||||
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click button.js-refresh-locked-users': this.refreshLockedUsers,
|
|
||||||
'click button#refreshLockedUsers': this.refreshLockedUsers,
|
|
||||||
'click button.js-unlock-user': this.unlockUser,
|
|
||||||
'click button.js-unlock-all-users': this.unlockAllUsers,
|
|
||||||
'click button.js-lockout-save': this.saveLockoutSettings,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('lockedUsersGeneral');
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
|
import { InfiniteScrolling } from '/client/lib/infiniteScrolling';
|
||||||
import LockoutSettings from '/models/lockoutSettings';
|
import LockoutSettings from '/models/lockoutSettings';
|
||||||
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
|
import { FlowRouter } from 'meteor/ostrio:flow-router-extra';
|
||||||
|
|
||||||
|
|
@ -8,139 +9,73 @@ const usersPerPage = 25;
|
||||||
let userOrgsTeamsAction = ""; //poosible actions 'addOrg', 'addTeam', 'removeOrg' or 'removeTeam' when adding or modifying a user
|
let userOrgsTeamsAction = ""; //poosible actions 'addOrg', 'addTeam', 'removeOrg' or 'removeTeam' when adding or modifying a user
|
||||||
let selectedUserChkBoxUserIds = [];
|
let selectedUserChkBoxUserIds = [];
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.people.onCreated(function () {
|
||||||
mixins() {
|
this.infiniteScrolling = new InfiniteScrolling();
|
||||||
return [Mixins.InfiniteScrolling];
|
|
||||||
},
|
|
||||||
onCreated() {
|
|
||||||
this.error = new ReactiveVar('');
|
|
||||||
this.loading = new ReactiveVar(false);
|
|
||||||
this.orgSetting = new ReactiveVar(true);
|
|
||||||
this.teamSetting = new ReactiveVar(false);
|
|
||||||
this.peopleSetting = new ReactiveVar(false);
|
|
||||||
this.lockedUsersSetting = new ReactiveVar(false);
|
|
||||||
this.findOrgsOptions = new ReactiveVar({});
|
|
||||||
this.findTeamsOptions = new ReactiveVar({});
|
|
||||||
this.findUsersOptions = new ReactiveVar({});
|
|
||||||
this.numberOrgs = new ReactiveVar(0);
|
|
||||||
this.numberTeams = new ReactiveVar(0);
|
|
||||||
this.numberPeople = new ReactiveVar(0);
|
|
||||||
this.userFilterType = new ReactiveVar('all');
|
|
||||||
|
|
||||||
this.page = new ReactiveVar(1);
|
this.error = new ReactiveVar('');
|
||||||
this.loadNextPageLocked = false;
|
this.loading = new ReactiveVar(false);
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
this.orgSetting = new ReactiveVar(true);
|
||||||
this.autorun(() => {
|
this.teamSetting = new ReactiveVar(false);
|
||||||
const limitOrgs = this.page.get() * orgsPerPage;
|
this.peopleSetting = new ReactiveVar(false);
|
||||||
const limitTeams = this.page.get() * teamsPerPage;
|
this.lockedUsersSetting = new ReactiveVar(false);
|
||||||
const limitUsers = this.page.get() * usersPerPage;
|
this.findOrgsOptions = new ReactiveVar({});
|
||||||
|
this.findTeamsOptions = new ReactiveVar({});
|
||||||
|
this.findUsersOptions = new ReactiveVar({});
|
||||||
|
this.numberOrgs = new ReactiveVar(0);
|
||||||
|
this.numberTeams = new ReactiveVar(0);
|
||||||
|
this.numberPeople = new ReactiveVar(0);
|
||||||
|
this.userFilterType = new ReactiveVar('all');
|
||||||
|
|
||||||
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {
|
this.page = new ReactiveVar(1);
|
||||||
this.loadNextPageLocked = false;
|
this.loadNextPageLocked = false;
|
||||||
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
|
this.infiniteScrolling.resetNextPeak();
|
||||||
this.calculateNextPeak();
|
|
||||||
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
|
this.calculateNextPeak = () => {
|
||||||
if (nextPeakBefore === nextPeakAfter) {
|
const element = this.find('.main-body');
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
if (element) {
|
||||||
}
|
const altitude = element.scrollHeight;
|
||||||
|
this.infiniteScrolling.setNextPeak(altitude);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.loadNextPage = () => {
|
||||||
|
if (this.loadNextPageLocked === false) {
|
||||||
|
this.page.set(this.page.get() + 1);
|
||||||
|
this.loadNextPageLocked = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.filterOrg = () => {
|
||||||
|
const value = $('#searchOrgInput').first().val();
|
||||||
|
if (value !== '') {
|
||||||
|
const regex = new RegExp(value, 'i');
|
||||||
|
this.findOrgsOptions.set({
|
||||||
|
$or: [
|
||||||
|
{ orgDisplayName: regex },
|
||||||
|
{ orgShortName: regex },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.findOrgsOptions.set({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.subscribe('team', this.findTeamsOptions.get(), limitTeams, () => {
|
this.filterTeam = () => {
|
||||||
this.loadNextPageLocked = false;
|
const value = $('#searchTeamInput').first().val();
|
||||||
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
|
if (value !== '') {
|
||||||
this.calculateNextPeak();
|
const regex = new RegExp(value, 'i');
|
||||||
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
|
this.findTeamsOptions.set({
|
||||||
if (nextPeakBefore === nextPeakAfter) {
|
$or: [
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
{ teamDisplayName: regex },
|
||||||
}
|
{ teamShortName: regex },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
this.findTeamsOptions.set({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
this.subscribe('people', this.findUsersOptions.get(), limitUsers, () => {
|
this.filterPeople = () => {
|
||||||
this.loadNextPageLocked = false;
|
|
||||||
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
|
|
||||||
this.calculateNextPeak();
|
|
||||||
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
|
|
||||||
if (nextPeakBefore === nextPeakAfter) {
|
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click #searchOrgButton'() {
|
|
||||||
this.filterOrg();
|
|
||||||
},
|
|
||||||
'keydown #searchOrgInput'(event) {
|
|
||||||
if (event.keyCode === 13 && !event.shiftKey) {
|
|
||||||
this.filterOrg();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click #searchTeamButton'() {
|
|
||||||
this.filterTeam();
|
|
||||||
},
|
|
||||||
'keydown #searchTeamInput'(event) {
|
|
||||||
if (event.keyCode === 13 && !event.shiftKey) {
|
|
||||||
this.filterTeam();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click #searchButton'() {
|
|
||||||
this.filterPeople();
|
|
||||||
},
|
|
||||||
'click #addOrRemoveTeam'(){
|
|
||||||
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'block';
|
|
||||||
},
|
|
||||||
'keydown #searchInput'(event) {
|
|
||||||
if (event.keyCode === 13 && !event.shiftKey) {
|
|
||||||
this.filterPeople();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'change #userFilterSelect'(event) {
|
|
||||||
const filterType = $(event.target).val();
|
|
||||||
this.userFilterType.set(filterType);
|
|
||||||
this.filterPeople();
|
|
||||||
},
|
|
||||||
'click #unlockAllUsers'(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
|
|
||||||
Meteor.call('unlockAllUsers', (error) => {
|
|
||||||
if (error) {
|
|
||||||
console.error('Error unlocking all users:', error);
|
|
||||||
} else {
|
|
||||||
// Show a brief success message
|
|
||||||
const message = document.createElement('div');
|
|
||||||
message.className = 'unlock-all-success';
|
|
||||||
message.textContent = TAPi18n.__('accounts-lockout-all-users-unlocked');
|
|
||||||
document.body.appendChild(message);
|
|
||||||
|
|
||||||
// Remove the message after a short delay
|
|
||||||
setTimeout(() => {
|
|
||||||
if (message.parentNode) {
|
|
||||||
message.parentNode.removeChild(message);
|
|
||||||
}
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click #newOrgButton'() {
|
|
||||||
Popup.open('newOrg');
|
|
||||||
},
|
|
||||||
'click #newTeamButton'() {
|
|
||||||
Popup.open('newTeam');
|
|
||||||
},
|
|
||||||
'click #newUserButton'() {
|
|
||||||
Popup.open('newUser');
|
|
||||||
},
|
|
||||||
'click a.js-org-menu': this.switchMenu,
|
|
||||||
'click a.js-team-menu': this.switchMenu,
|
|
||||||
'click a.js-people-menu': this.switchMenu,
|
|
||||||
'click a.js-locked-users-menu': this.switchMenu,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
filterPeople() {
|
|
||||||
const value = $('#searchInput').first().val();
|
const value = $('#searchInput').first().val();
|
||||||
const filterType = this.userFilterType.get();
|
const filterType = this.userFilterType.get();
|
||||||
const currentTime = Number(new Date());
|
const currentTime = Number(new Date());
|
||||||
|
|
@ -184,72 +119,9 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
|
|
||||||
this.findUsersOptions.set(query);
|
this.findUsersOptions.set(query);
|
||||||
},
|
};
|
||||||
loadNextPage() {
|
|
||||||
if (this.loadNextPageLocked === false) {
|
this.switchMenu = (event) => {
|
||||||
this.page.set(this.page.get() + 1);
|
|
||||||
this.loadNextPageLocked = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
calculateNextPeak() {
|
|
||||||
const element = this.find('.main-body');
|
|
||||||
if (element) {
|
|
||||||
const altitude = element.scrollHeight;
|
|
||||||
this.callFirstWith(this, 'setNextPeak', altitude);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
reachNextPeak() {
|
|
||||||
this.loadNextPage();
|
|
||||||
},
|
|
||||||
setError(error) {
|
|
||||||
this.error.set(error);
|
|
||||||
},
|
|
||||||
setLoading(w) {
|
|
||||||
this.loading.set(w);
|
|
||||||
},
|
|
||||||
orgList() {
|
|
||||||
const limitOrgs = this.page.get() * orgsPerPage;
|
|
||||||
const orgs = ReactiveCache.getOrgs(this.findOrgsOptions.get(), {
|
|
||||||
sort: { orgDisplayName: 1 },
|
|
||||||
limit: limitOrgs,
|
|
||||||
fields: { _id: true },
|
|
||||||
});
|
|
||||||
// Count only the items currently loaded to browser, not total from database
|
|
||||||
this.numberOrgs.set(orgs.length);
|
|
||||||
return orgs;
|
|
||||||
},
|
|
||||||
teamList() {
|
|
||||||
const limitTeams = this.page.get() * teamsPerPage;
|
|
||||||
const teams = ReactiveCache.getTeams(this.findTeamsOptions.get(), {
|
|
||||||
sort: { teamDisplayName: 1 },
|
|
||||||
limit: limitTeams,
|
|
||||||
fields: { _id: true },
|
|
||||||
});
|
|
||||||
// Count only the items currently loaded to browser, not total from database
|
|
||||||
this.numberTeams.set(teams.length);
|
|
||||||
return teams;
|
|
||||||
},
|
|
||||||
peopleList() {
|
|
||||||
const limitUsers = this.page.get() * usersPerPage;
|
|
||||||
const users = ReactiveCache.getUsers(this.findUsersOptions.get(), {
|
|
||||||
sort: { username: 1 },
|
|
||||||
limit: limitUsers,
|
|
||||||
fields: { _id: true },
|
|
||||||
});
|
|
||||||
// Count only the items currently loaded to browser, not total from database
|
|
||||||
this.numberPeople.set(users.length);
|
|
||||||
return users;
|
|
||||||
},
|
|
||||||
orgNumber() {
|
|
||||||
return this.numberOrgs.get();
|
|
||||||
},
|
|
||||||
teamNumber() {
|
|
||||||
return this.numberTeams.get();
|
|
||||||
},
|
|
||||||
peopleNumber() {
|
|
||||||
return this.numberPeople.get();
|
|
||||||
},
|
|
||||||
switchMenu(event) {
|
|
||||||
const target = $(event.target);
|
const target = $(event.target);
|
||||||
if (!target.hasClass('active')) {
|
if (!target.hasClass('active')) {
|
||||||
$('.side-menu li.active').removeClass('active');
|
$('.side-menu li.active').removeClass('active');
|
||||||
|
|
@ -269,8 +141,191 @@ BlazeComponent.extendComponent({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.autorun(() => {
|
||||||
|
const limitOrgs = this.page.get() * orgsPerPage;
|
||||||
|
const limitTeams = this.page.get() * teamsPerPage;
|
||||||
|
const limitUsers = this.page.get() * usersPerPage;
|
||||||
|
|
||||||
|
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {
|
||||||
|
this.loadNextPageLocked = false;
|
||||||
|
const nextPeakBefore = this.infiniteScrolling.getNextPeak();
|
||||||
|
this.calculateNextPeak();
|
||||||
|
const nextPeakAfter = this.infiniteScrolling.getNextPeak();
|
||||||
|
if (nextPeakBefore === nextPeakAfter) {
|
||||||
|
this.infiniteScrolling.resetNextPeak();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.subscribe('team', this.findTeamsOptions.get(), limitTeams, () => {
|
||||||
|
this.loadNextPageLocked = false;
|
||||||
|
const nextPeakBefore = this.infiniteScrolling.getNextPeak();
|
||||||
|
this.calculateNextPeak();
|
||||||
|
const nextPeakAfter = this.infiniteScrolling.getNextPeak();
|
||||||
|
if (nextPeakBefore === nextPeakAfter) {
|
||||||
|
this.infiniteScrolling.resetNextPeak();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.subscribe('people', this.findUsersOptions.get(), limitUsers, () => {
|
||||||
|
this.loadNextPageLocked = false;
|
||||||
|
const nextPeakBefore = this.infiniteScrolling.getNextPeak();
|
||||||
|
this.calculateNextPeak();
|
||||||
|
const nextPeakAfter = this.infiniteScrolling.getNextPeak();
|
||||||
|
if (nextPeakBefore === nextPeakAfter) {
|
||||||
|
this.infiniteScrolling.resetNextPeak();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.people.helpers({
|
||||||
|
loading() {
|
||||||
|
return Template.instance().loading;
|
||||||
},
|
},
|
||||||
}).register('people');
|
orgSetting() {
|
||||||
|
return Template.instance().orgSetting;
|
||||||
|
},
|
||||||
|
teamSetting() {
|
||||||
|
return Template.instance().teamSetting;
|
||||||
|
},
|
||||||
|
peopleSetting() {
|
||||||
|
return Template.instance().peopleSetting;
|
||||||
|
},
|
||||||
|
lockedUsersSetting() {
|
||||||
|
return Template.instance().lockedUsersSetting;
|
||||||
|
},
|
||||||
|
orgList() {
|
||||||
|
const tpl = Template.instance();
|
||||||
|
const limitOrgs = tpl.page.get() * orgsPerPage;
|
||||||
|
const orgs = ReactiveCache.getOrgs(tpl.findOrgsOptions.get(), {
|
||||||
|
sort: { orgDisplayName: 1 },
|
||||||
|
limit: limitOrgs,
|
||||||
|
fields: { _id: true },
|
||||||
|
});
|
||||||
|
// Count only the items currently loaded to browser, not total from database
|
||||||
|
tpl.numberOrgs.set(orgs.length);
|
||||||
|
return orgs;
|
||||||
|
},
|
||||||
|
teamList() {
|
||||||
|
const tpl = Template.instance();
|
||||||
|
const limitTeams = tpl.page.get() * teamsPerPage;
|
||||||
|
const teams = ReactiveCache.getTeams(tpl.findTeamsOptions.get(), {
|
||||||
|
sort: { teamDisplayName: 1 },
|
||||||
|
limit: limitTeams,
|
||||||
|
fields: { _id: true },
|
||||||
|
});
|
||||||
|
// Count only the items currently loaded to browser, not total from database
|
||||||
|
tpl.numberTeams.set(teams.length);
|
||||||
|
return teams;
|
||||||
|
},
|
||||||
|
peopleList() {
|
||||||
|
const tpl = Template.instance();
|
||||||
|
const limitUsers = tpl.page.get() * usersPerPage;
|
||||||
|
const users = ReactiveCache.getUsers(tpl.findUsersOptions.get(), {
|
||||||
|
sort: { username: 1 },
|
||||||
|
limit: limitUsers,
|
||||||
|
fields: { _id: true },
|
||||||
|
});
|
||||||
|
// Count only the items currently loaded to browser, not total from database
|
||||||
|
tpl.numberPeople.set(users.length);
|
||||||
|
return users;
|
||||||
|
},
|
||||||
|
orgNumber() {
|
||||||
|
return Template.instance().numberOrgs.get();
|
||||||
|
},
|
||||||
|
teamNumber() {
|
||||||
|
return Template.instance().numberTeams.get();
|
||||||
|
},
|
||||||
|
peopleNumber() {
|
||||||
|
return Template.instance().numberPeople.get();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.people.events({
|
||||||
|
'scroll .main-body'(event, tpl) {
|
||||||
|
tpl.infiniteScrolling.checkScrollPosition(event.currentTarget, () => {
|
||||||
|
tpl.loadNextPage();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
'click #searchOrgButton'(event, tpl) {
|
||||||
|
tpl.filterOrg();
|
||||||
|
},
|
||||||
|
'keydown #searchOrgInput'(event, tpl) {
|
||||||
|
if (event.keyCode === 13 && !event.shiftKey) {
|
||||||
|
tpl.filterOrg();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click #searchTeamButton'(event, tpl) {
|
||||||
|
tpl.filterTeam();
|
||||||
|
},
|
||||||
|
'keydown #searchTeamInput'(event, tpl) {
|
||||||
|
if (event.keyCode === 13 && !event.shiftKey) {
|
||||||
|
tpl.filterTeam();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click #searchButton'(event, tpl) {
|
||||||
|
tpl.filterPeople();
|
||||||
|
},
|
||||||
|
'click #addOrRemoveTeam'(){
|
||||||
|
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'block';
|
||||||
|
},
|
||||||
|
'keydown #searchInput'(event, tpl) {
|
||||||
|
if (event.keyCode === 13 && !event.shiftKey) {
|
||||||
|
tpl.filterPeople();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'change #userFilterSelect'(event, tpl) {
|
||||||
|
const filterType = $(event.target).val();
|
||||||
|
tpl.userFilterType.set(filterType);
|
||||||
|
tpl.filterPeople();
|
||||||
|
},
|
||||||
|
'click #unlockAllUsers'(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
if (confirm(TAPi18n.__('accounts-lockout-confirm-unlock-all'))) {
|
||||||
|
Meteor.call('unlockAllUsers', (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('Error unlocking all users:', error);
|
||||||
|
} else {
|
||||||
|
// Show a brief success message
|
||||||
|
const message = document.createElement('div');
|
||||||
|
message.className = 'unlock-all-success';
|
||||||
|
message.textContent = TAPi18n.__('accounts-lockout-all-users-unlocked');
|
||||||
|
document.body.appendChild(message);
|
||||||
|
|
||||||
|
// Remove the message after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
if (message.parentNode) {
|
||||||
|
message.parentNode.removeChild(message);
|
||||||
|
}
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click #newOrgButton'() {
|
||||||
|
Popup.open('newOrg');
|
||||||
|
},
|
||||||
|
'click #newTeamButton'() {
|
||||||
|
Popup.open('newTeam');
|
||||||
|
},
|
||||||
|
'click #newUserButton'() {
|
||||||
|
Popup.open('newUser');
|
||||||
|
},
|
||||||
|
'click a.js-org-menu'(event, tpl) {
|
||||||
|
tpl.switchMenu(event);
|
||||||
|
},
|
||||||
|
'click a.js-team-menu'(event, tpl) {
|
||||||
|
tpl.switchMenu(event);
|
||||||
|
},
|
||||||
|
'click a.js-people-menu'(event, tpl) {
|
||||||
|
tpl.switchMenu(event);
|
||||||
|
},
|
||||||
|
'click a.js-locked-users-menu'(event, tpl) {
|
||||||
|
tpl.switchMenu(event);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Template.orgRow.helpers({
|
Template.orgRow.helpers({
|
||||||
orgData() {
|
orgData() {
|
||||||
|
|
@ -465,259 +520,201 @@ Template.newUserPopup.helpers({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.orgRow.events({
|
||||||
onCreated() {},
|
'click a.edit-org': Popup.open('editOrg'),
|
||||||
org() {
|
'click a.more-settings-org': Popup.open('settingsOrg'),
|
||||||
return ReactiveCache.getOrg(this.orgId);
|
});
|
||||||
|
|
||||||
|
Template.teamRow.events({
|
||||||
|
'click a.edit-team': Popup.open('editTeam'),
|
||||||
|
'click a.more-settings-team': Popup.open('settingsTeam'),
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.peopleRow.events({
|
||||||
|
'click a.edit-user': Popup.open('editUser'),
|
||||||
|
'click a.more-settings-user': Popup.open('settingsUser'),
|
||||||
|
'click .selectUserChkBox': function(ev){
|
||||||
|
if(ev.currentTarget){
|
||||||
|
if(ev.currentTarget.checked){
|
||||||
|
if(!selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
|
||||||
|
selectedUserChkBoxUserIds.push(ev.currentTarget.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
|
||||||
|
let index = selectedUserChkBoxUserIds.indexOf(ev.currentTarget.id);
|
||||||
|
if(index > -1)
|
||||||
|
selectedUserChkBoxUserIds.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(selectedUserChkBoxUserIds.length > 0)
|
||||||
|
document.getElementById("divAddOrRemoveTeam").style.display = 'block';
|
||||||
|
else
|
||||||
|
document.getElementById("divAddOrRemoveTeam").style.display = 'none';
|
||||||
},
|
},
|
||||||
events() {
|
'click .js-toggle-active-status': function(ev) {
|
||||||
return [
|
ev.preventDefault();
|
||||||
{
|
const userId = this.userId;
|
||||||
'click a.edit-org': Popup.open('editOrg'),
|
const user = ReactiveCache.getUser(userId);
|
||||||
'click a.more-settings-org': Popup.open('settingsOrg'),
|
|
||||||
},
|
if (!user) return;
|
||||||
];
|
|
||||||
|
// Toggle loginDisabled status
|
||||||
|
const isActive = !(user.loginDisabled === true);
|
||||||
|
|
||||||
|
// Update the user's active status
|
||||||
|
Users.update(userId, {
|
||||||
|
$set: {
|
||||||
|
loginDisabled: isActive
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}).register('orgRow');
|
'click .js-toggle-lock-status': function(ev){
|
||||||
|
ev.preventDefault();
|
||||||
|
const userId = this.userId;
|
||||||
|
const user = ReactiveCache.getUser(userId);
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
if (!user) return;
|
||||||
onCreated() {},
|
|
||||||
team() {
|
// Check if user is currently locked
|
||||||
return ReactiveCache.getTeam(this.teamId);
|
const isLocked = user.services &&
|
||||||
|
user.services['accounts-lockout'] &&
|
||||||
|
user.services['accounts-lockout'].unlockTime &&
|
||||||
|
user.services['accounts-lockout'].unlockTime > Number(new Date());
|
||||||
|
|
||||||
|
if (isLocked) {
|
||||||
|
// Unlock the user
|
||||||
|
Meteor.call('unlockUser', userId, (error) => {
|
||||||
|
if (error) {
|
||||||
|
console.error('Error unlocking user:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Lock the user - this is optional, you may want to only allow unlocking
|
||||||
|
// If you want to implement locking too, you would need a server method for it
|
||||||
|
// For now, we'll leave this as a no-op
|
||||||
|
}
|
||||||
},
|
},
|
||||||
events() {
|
});
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.edit-team': Popup.open('editTeam'),
|
|
||||||
'click a.more-settings-team': Popup.open('settingsTeam'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('teamRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.modifyTeamsUsers.helpers({
|
||||||
onCreated() {},
|
|
||||||
user() {
|
|
||||||
return ReactiveCache.getUser(this.userId);
|
|
||||||
},
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.edit-user': Popup.open('editUser'),
|
|
||||||
'click a.more-settings-user': Popup.open('settingsUser'),
|
|
||||||
'click .selectUserChkBox': function(ev){
|
|
||||||
if(ev.currentTarget){
|
|
||||||
if(ev.currentTarget.checked){
|
|
||||||
if(!selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
|
|
||||||
selectedUserChkBoxUserIds.push(ev.currentTarget.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(selectedUserChkBoxUserIds.includes(ev.currentTarget.id)){
|
|
||||||
let index = selectedUserChkBoxUserIds.indexOf(ev.currentTarget.id);
|
|
||||||
if(index > -1)
|
|
||||||
selectedUserChkBoxUserIds.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(selectedUserChkBoxUserIds.length > 0)
|
|
||||||
document.getElementById("divAddOrRemoveTeam").style.display = 'block';
|
|
||||||
else
|
|
||||||
document.getElementById("divAddOrRemoveTeam").style.display = 'none';
|
|
||||||
},
|
|
||||||
'click .js-toggle-active-status': function(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
const userId = this.userId;
|
|
||||||
const user = ReactiveCache.getUser(userId);
|
|
||||||
|
|
||||||
if (!user) return;
|
|
||||||
|
|
||||||
// Toggle loginDisabled status
|
|
||||||
const isActive = !(user.loginDisabled === true);
|
|
||||||
|
|
||||||
// Update the user's active status
|
|
||||||
Users.update(userId, {
|
|
||||||
$set: {
|
|
||||||
loginDisabled: isActive
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
'click .js-toggle-lock-status': function(ev){
|
|
||||||
ev.preventDefault();
|
|
||||||
const userId = this.userId;
|
|
||||||
const user = ReactiveCache.getUser(userId);
|
|
||||||
|
|
||||||
if (!user) return;
|
|
||||||
|
|
||||||
// Check if user is currently locked
|
|
||||||
const isLocked = user.services &&
|
|
||||||
user.services['accounts-lockout'] &&
|
|
||||||
user.services['accounts-lockout'].unlockTime &&
|
|
||||||
user.services['accounts-lockout'].unlockTime > Number(new Date());
|
|
||||||
|
|
||||||
if (isLocked) {
|
|
||||||
// Unlock the user
|
|
||||||
Meteor.call('unlockUser', userId, (error) => {
|
|
||||||
if (error) {
|
|
||||||
console.error('Error unlocking user:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Lock the user - this is optional, you may want to only allow unlocking
|
|
||||||
// If you want to implement locking too, you would need a server method for it
|
|
||||||
// For now, we'll leave this as a no-op
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('peopleRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
|
||||||
onCreated() {},
|
|
||||||
teamsDatas() {
|
teamsDatas() {
|
||||||
const ret = ReactiveCache.getTeams({}, {sort: { teamDisplayName: 1 }});
|
const ret = ReactiveCache.getTeams({}, {sort: { teamDisplayName: 1 }});
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
events() {
|
});
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click #cancelBtn': function(){
|
|
||||||
let selectedElt = document.getElementById("jsteamsUser");
|
|
||||||
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
|
|
||||||
},
|
|
||||||
'click #addTeamBtn': function(){
|
|
||||||
let selectedElt;
|
|
||||||
let selectedEltValue;
|
|
||||||
let selectedEltValueId;
|
|
||||||
let userTms = [];
|
|
||||||
let currentUser;
|
|
||||||
let currUserTeamIndex;
|
|
||||||
|
|
||||||
selectedElt = document.getElementById("jsteamsUser");
|
Template.modifyTeamsUsers.events({
|
||||||
selectedEltValue = selectedElt.options[selectedElt.selectedIndex].text;
|
'click #cancelBtn': function(){
|
||||||
selectedEltValueId = selectedElt.options[selectedElt.selectedIndex].value;
|
let selectedElt = document.getElementById("jsteamsUser");
|
||||||
|
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
|
||||||
|
},
|
||||||
|
'click #addTeamBtn': function(){
|
||||||
|
let selectedElt;
|
||||||
|
let selectedEltValue;
|
||||||
|
let selectedEltValueId;
|
||||||
|
let userTms = [];
|
||||||
|
let currentUser;
|
||||||
|
let currUserTeamIndex;
|
||||||
|
|
||||||
if(document.getElementById('addAction').checked){
|
selectedElt = document.getElementById("jsteamsUser");
|
||||||
for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
|
selectedEltValue = selectedElt.options[selectedElt.selectedIndex].text;
|
||||||
currentUser = ReactiveCache.getUser(selectedUserChkBoxUserIds[i]);
|
selectedEltValueId = selectedElt.options[selectedElt.selectedIndex].value;
|
||||||
userTms = currentUser.teams;
|
|
||||||
if(userTms == undefined || userTms.length == 0){
|
|
||||||
userTms = [];
|
|
||||||
userTms.push({
|
|
||||||
"teamId": selectedEltValueId,
|
|
||||||
"teamDisplayName": selectedEltValue,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else if(userTms.length > 0)
|
|
||||||
{
|
|
||||||
currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
|
|
||||||
if(currUserTeamIndex == -1){
|
|
||||||
userTms.push({
|
|
||||||
"teamId": selectedEltValueId,
|
|
||||||
"teamDisplayName": selectedEltValue,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Users.update(selectedUserChkBoxUserIds[i], {
|
if(document.getElementById('addAction').checked){
|
||||||
$set:{
|
for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
|
||||||
teams: userTms
|
currentUser = ReactiveCache.getUser(selectedUserChkBoxUserIds[i]);
|
||||||
}
|
userTms = currentUser.teams;
|
||||||
});
|
if(userTms == undefined || userTms.length == 0){
|
||||||
}
|
userTms = [];
|
||||||
|
userTms.push({
|
||||||
|
"teamId": selectedEltValueId,
|
||||||
|
"teamDisplayName": selectedEltValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if(userTms.length > 0)
|
||||||
|
{
|
||||||
|
currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
|
||||||
|
if(currUserTeamIndex == -1){
|
||||||
|
userTms.push({
|
||||||
|
"teamId": selectedEltValueId,
|
||||||
|
"teamDisplayName": selectedEltValue,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
|
|
||||||
currentUser = ReactiveCache.getUser(selectedUserChkBoxUserIds[i]);
|
|
||||||
userTms = currentUser.teams;
|
|
||||||
if(userTms !== undefined || userTms.length > 0)
|
|
||||||
{
|
|
||||||
currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
|
|
||||||
if(currUserTeamIndex != -1){
|
|
||||||
userTms.splice(currUserTeamIndex, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Users.update(selectedUserChkBoxUserIds[i], {
|
Users.update(selectedUserChkBoxUserIds[i], {
|
||||||
$set:{
|
$set:{
|
||||||
teams: userTms
|
teams: userTms
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
|
}
|
||||||
},
|
}
|
||||||
},
|
else{
|
||||||
];
|
for(let i = 0; i < selectedUserChkBoxUserIds.length; i++){
|
||||||
},
|
currentUser = ReactiveCache.getUser(selectedUserChkBoxUserIds[i]);
|
||||||
}).register('modifyTeamsUsers');
|
userTms = currentUser.teams;
|
||||||
|
if(userTms !== undefined || userTms.length > 0)
|
||||||
BlazeComponent.extendComponent({
|
{
|
||||||
events() {
|
currUserTeamIndex = userTms.findIndex(function(t){ return t.teamId == selectedEltValueId});
|
||||||
return [
|
if(currUserTeamIndex != -1){
|
||||||
{
|
userTms.splice(currUserTeamIndex, 1);
|
||||||
'click a.new-org': Popup.open('newOrg'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('newOrgRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.new-team': Popup.open('newTeam'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('newTeamRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.new-user': Popup.open('newUser'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('newUserRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click .allUserChkBox': function(ev){
|
|
||||||
selectedUserChkBoxUserIds = [];
|
|
||||||
const checkboxes = document.getElementsByClassName("selectUserChkBox");
|
|
||||||
if(ev.currentTarget){
|
|
||||||
if(ev.currentTarget.checked){
|
|
||||||
for (let i=0; i<checkboxes.length; i++) {
|
|
||||||
if (!checkboxes[i].disabled) {
|
|
||||||
selectedUserChkBoxUserIds.push(checkboxes[i].id);
|
|
||||||
checkboxes[i].checked = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for (let i=0; i<checkboxes.length; i++) {
|
|
||||||
if (!checkboxes[i].disabled) {
|
|
||||||
checkboxes[i].checked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(selectedUserChkBoxUserIds.length > 0)
|
Users.update(selectedUserChkBoxUserIds[i], {
|
||||||
document.getElementById("divAddOrRemoveTeam").style.display = 'block';
|
$set:{
|
||||||
else
|
teams: userTms
|
||||||
document.getElementById("divAddOrRemoveTeam").style.display = 'none';
|
}
|
||||||
},
|
});
|
||||||
},
|
}
|
||||||
];
|
}
|
||||||
|
|
||||||
|
document.getElementById("divAddOrRemoveTeamContainer").style.display = 'none';
|
||||||
},
|
},
|
||||||
}).register('selectAllUser');
|
});
|
||||||
|
|
||||||
|
Template.newOrgRow.events({
|
||||||
|
'click a.new-org': Popup.open('newOrg'),
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.newTeamRow.events({
|
||||||
|
'click a.new-team': Popup.open('newTeam'),
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.newUserRow.events({
|
||||||
|
'click a.new-user': Popup.open('newUser'),
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.selectAllUser.events({
|
||||||
|
'click .allUserChkBox': function(ev){
|
||||||
|
selectedUserChkBoxUserIds = [];
|
||||||
|
const checkboxes = document.getElementsByClassName("selectUserChkBox");
|
||||||
|
if(ev.currentTarget){
|
||||||
|
if(ev.currentTarget.checked){
|
||||||
|
for (let i=0; i<checkboxes.length; i++) {
|
||||||
|
if (!checkboxes[i].disabled) {
|
||||||
|
selectedUserChkBoxUserIds.push(checkboxes[i].id);
|
||||||
|
checkboxes[i].checked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
for (let i=0; i<checkboxes.length; i++) {
|
||||||
|
if (!checkboxes[i].disabled) {
|
||||||
|
checkboxes[i].checked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(selectedUserChkBoxUserIds.length > 0)
|
||||||
|
document.getElementById("divAddOrRemoveTeam").style.display = 'block';
|
||||||
|
else
|
||||||
|
document.getElementById("divAddOrRemoveTeam").style.display = 'none';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Template.editOrgPopup.events({
|
Template.editOrgPopup.events({
|
||||||
submit(event, templateInstance) {
|
submit(event, templateInstance) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,111 +1,118 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
|
import { InfiniteScrolling } from '/client/lib/infiniteScrolling';
|
||||||
|
|
||||||
const translationsPerPage = 25;
|
const translationsPerPage = 25;
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.translation.onCreated(function () {
|
||||||
mixins() {
|
this.error = new ReactiveVar('');
|
||||||
return [Mixins.InfiniteScrolling];
|
this.loading = new ReactiveVar(false);
|
||||||
},
|
this.translationSetting = new ReactiveVar(true);
|
||||||
onCreated() {
|
this.findTranslationsOptions = new ReactiveVar({});
|
||||||
this.error = new ReactiveVar('');
|
this.numberTranslations = new ReactiveVar(0);
|
||||||
this.loading = new ReactiveVar(false);
|
|
||||||
this.translationSetting = new ReactiveVar(true);
|
|
||||||
this.findTranslationsOptions = new ReactiveVar({});
|
|
||||||
this.numberTranslations = new ReactiveVar(0);
|
|
||||||
|
|
||||||
this.page = new ReactiveVar(1);
|
this.page = new ReactiveVar(1);
|
||||||
this.loadNextPageLocked = false;
|
this.loadNextPageLocked = false;
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
this.infiniteScrolling = new InfiniteScrolling();
|
||||||
this.autorun(() => {
|
|
||||||
const limitTranslations = this.page.get() * translationsPerPage;
|
|
||||||
|
|
||||||
this.subscribe('translation', this.findTranslationsOptions.get(), 0, () => {
|
this.loadNextPage = () => {
|
||||||
this.loadNextPageLocked = false;
|
|
||||||
const nextPeakBefore = this.callFirstWith(null, 'getNextPeak');
|
|
||||||
this.calculateNextPeak();
|
|
||||||
const nextPeakAfter = this.callFirstWith(null, 'getNextPeak');
|
|
||||||
if (nextPeakBefore === nextPeakAfter) {
|
|
||||||
this.callFirstWith(null, 'resetNextPeak');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click #searchTranslationButton'() {
|
|
||||||
this.filterTranslation();
|
|
||||||
},
|
|
||||||
'keydown #searchTranslationInput'(event) {
|
|
||||||
if (event.keyCode === 13 && !event.shiftKey) {
|
|
||||||
this.filterTranslation();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click #newTranslationButton'() {
|
|
||||||
Popup.open('newTranslation');
|
|
||||||
},
|
|
||||||
'click a.js-translation-menu': this.switchMenu,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
filterTranslation() {
|
|
||||||
const value = $('#searchTranslationInput').first().val();
|
|
||||||
if (value === '') {
|
|
||||||
this.findTranslationsOptions.set({});
|
|
||||||
} else {
|
|
||||||
const regex = new RegExp(value, 'i');
|
|
||||||
this.findTranslationsOptions.set({
|
|
||||||
$or: [
|
|
||||||
{ language: regex },
|
|
||||||
{ text: regex },
|
|
||||||
{ translationText: regex },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loadNextPage() {
|
|
||||||
if (this.loadNextPageLocked === false) {
|
if (this.loadNextPageLocked === false) {
|
||||||
this.page.set(this.page.get() + 1);
|
this.page.set(this.page.get() + 1);
|
||||||
this.loadNextPageLocked = true;
|
this.loadNextPageLocked = true;
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
calculateNextPeak() {
|
|
||||||
|
this.calculateNextPeak = () => {
|
||||||
const element = this.find('.main-body');
|
const element = this.find('.main-body');
|
||||||
if (element) {
|
if (element) {
|
||||||
const altitude = element.scrollHeight;
|
this.infiniteScrolling.setNextPeak(element.scrollHeight);
|
||||||
this.callFirstWith(this, 'setNextPeak', altitude);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.autorun(() => {
|
||||||
|
const limitTranslations = this.page.get() * translationsPerPage;
|
||||||
|
|
||||||
|
this.subscribe('translation', this.findTranslationsOptions.get(), 0, () => {
|
||||||
|
this.loadNextPageLocked = false;
|
||||||
|
const nextPeakBefore = this.infiniteScrolling.getNextPeak();
|
||||||
|
this.calculateNextPeak();
|
||||||
|
const nextPeakAfter = this.infiniteScrolling.getNextPeak();
|
||||||
|
if (nextPeakBefore === nextPeakAfter) {
|
||||||
|
this.infiniteScrolling.resetNextPeak();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.translation.helpers({
|
||||||
|
loading() {
|
||||||
|
return Template.instance().loading;
|
||||||
},
|
},
|
||||||
reachNextPeak() {
|
translationSetting() {
|
||||||
this.loadNextPage();
|
return Template.instance().translationSetting;
|
||||||
},
|
|
||||||
setError(error) {
|
|
||||||
this.error.set(error);
|
|
||||||
},
|
|
||||||
setLoading(w) {
|
|
||||||
this.loading.set(w);
|
|
||||||
},
|
},
|
||||||
translationList() {
|
translationList() {
|
||||||
const translations = ReactiveCache.getTranslations(this.findTranslationsOptions.get(), {
|
const tpl = Template.instance();
|
||||||
|
const translations = ReactiveCache.getTranslations(tpl.findTranslationsOptions.get(), {
|
||||||
sort: { modifiedAt: 1 },
|
sort: { modifiedAt: 1 },
|
||||||
fields: { _id: true },
|
fields: { _id: true },
|
||||||
});
|
});
|
||||||
this.numberTranslations.set(translations.length);
|
tpl.numberTranslations.set(translations.length);
|
||||||
return translations;
|
return translations;
|
||||||
},
|
},
|
||||||
translationNumber() {
|
translationNumber() {
|
||||||
return this.numberTranslations.get();
|
return Template.instance().numberTranslations.get();
|
||||||
},
|
},
|
||||||
switchMenu(event) {
|
setError(error) {
|
||||||
|
Template.instance().error.set(error);
|
||||||
|
},
|
||||||
|
setLoading(w) {
|
||||||
|
Template.instance().loading.set(w);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.translation.events({
|
||||||
|
'click #searchTranslationButton'(event, tpl) {
|
||||||
|
_filterTranslation(tpl);
|
||||||
|
},
|
||||||
|
'keydown #searchTranslationInput'(event, tpl) {
|
||||||
|
if (event.keyCode === 13 && !event.shiftKey) {
|
||||||
|
_filterTranslation(tpl);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click #newTranslationButton'() {
|
||||||
|
Popup.open('newTranslation');
|
||||||
|
},
|
||||||
|
'click a.js-translation-menu'(event, tpl) {
|
||||||
const target = $(event.target);
|
const target = $(event.target);
|
||||||
if (!target.hasClass('active')) {
|
if (!target.hasClass('active')) {
|
||||||
$('.side-menu li.active').removeClass('active');
|
$('.side-menu li.active').removeClass('active');
|
||||||
target.parent().addClass('active');
|
target.parent().addClass('active');
|
||||||
const targetID = target.data('id');
|
const targetID = target.data('id');
|
||||||
this.translationSetting.set('translation-setting' === targetID);
|
tpl.translationSetting.set('translation-setting' === targetID);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}).register('translation');
|
'scroll .main-body'(event, tpl) {
|
||||||
|
tpl.infiniteScrolling.checkScrollPosition(event.currentTarget, () => {
|
||||||
|
tpl.loadNextPage();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function _filterTranslation(tpl) {
|
||||||
|
const value = $('#searchTranslationInput').first().val();
|
||||||
|
if (value === '') {
|
||||||
|
tpl.findTranslationsOptions.set({});
|
||||||
|
} else {
|
||||||
|
const regex = new RegExp(value, 'i');
|
||||||
|
tpl.findTranslationsOptions.set({
|
||||||
|
$or: [
|
||||||
|
{ language: regex },
|
||||||
|
{ text: regex },
|
||||||
|
{ translationText: regex },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Template.translationRow.helpers({
|
Template.translationRow.helpers({
|
||||||
translationData() {
|
translationData() {
|
||||||
|
|
@ -135,30 +142,20 @@ Template.newTranslationPopup.helpers({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.translationRow.helpers({
|
||||||
onCreated() {},
|
|
||||||
translation() {
|
translation() {
|
||||||
return ReactiveCache.getTranslation(this.translationId);
|
return ReactiveCache.getTranslation(this.translationId);
|
||||||
},
|
},
|
||||||
events() {
|
});
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click a.edit-translation': Popup.open('editTranslation'),
|
|
||||||
'click a.more-settings-translation': Popup.open('settingsTranslation'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('translationRow');
|
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.translationRow.events({
|
||||||
events() {
|
'click a.edit-translation': Popup.open('editTranslation'),
|
||||||
return [
|
'click a.more-settings-translation': Popup.open('settingsTranslation'),
|
||||||
{
|
});
|
||||||
'click a.new-translation': Popup.open('newTranslation'),
|
|
||||||
},
|
Template.newTranslationRow.events({
|
||||||
];
|
'click a.new-translation': Popup.open('newTranslation'),
|
||||||
},
|
});
|
||||||
}).register('newTranslationRow');
|
|
||||||
|
|
||||||
Template.editTranslationPopup.events({
|
Template.editTranslationPopup.events({
|
||||||
submit(event, templateInstance) {
|
submit(event, templateInstance) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,28 +1,84 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
import { TAPi18n } from '/imports/i18n';
|
import { TAPi18n } from '/imports/i18n';
|
||||||
|
import Lists from '/models/lists';
|
||||||
|
import Swimlanes from '/models/swimlanes';
|
||||||
|
|
||||||
//archivedRequested = false;
|
//archivedRequested = false;
|
||||||
const subManager = new SubsManager();
|
const subManager = new SubsManager();
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
function getArchivedCards() {
|
||||||
onCreated() {
|
const ret = ReactiveCache.getCards(
|
||||||
this.isArchiveReady = new ReactiveVar(false);
|
{
|
||||||
|
archived: true,
|
||||||
|
boardId: Session.get('currentBoard'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// The pattern we use to manually handle data loading is described here:
|
function getArchivedLists() {
|
||||||
// https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
|
return ReactiveCache.getLists(
|
||||||
// XXX The boardId should be readed from some sort the component "props",
|
{
|
||||||
// unfortunatly, Blaze doesn't have this notion.
|
archived: true,
|
||||||
this.autorun(() => {
|
boardId: Session.get('currentBoard'),
|
||||||
const currentBoardId = Session.get('currentBoard');
|
},
|
||||||
if (!currentBoardId) return;
|
{
|
||||||
const handle = subManager.subscribe('board', currentBoardId, true);
|
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||||
//archivedRequested = true;
|
},
|
||||||
Tracker.nonreactive(() => {
|
);
|
||||||
Tracker.autorun(() => {
|
}
|
||||||
this.isArchiveReady.set(handle.ready());
|
|
||||||
});
|
function getArchivedSwimlanes() {
|
||||||
|
return ReactiveCache.getSwimlanes(
|
||||||
|
{
|
||||||
|
archived: true,
|
||||||
|
boardId: Session.get('currentBoard'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
sort: { archivedAt: -1, modifiedAt: -1 },
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Template.archivesSidebar.onCreated(function () {
|
||||||
|
this.isArchiveReady = new ReactiveVar(false);
|
||||||
|
|
||||||
|
// The pattern we use to manually handle data loading is described here:
|
||||||
|
// https://kadira.io/academy/meteor-routing-guide/content/subscriptions-and-data-management/using-subs-manager
|
||||||
|
// XXX The boardId should be readed from some sort the component "props",
|
||||||
|
// unfortunatly, Blaze doesn't have this notion.
|
||||||
|
this.autorun(() => {
|
||||||
|
const currentBoardId = Session.get('currentBoard');
|
||||||
|
if (!currentBoardId) return;
|
||||||
|
const handle = subManager.subscribe('board', currentBoardId, true);
|
||||||
|
//archivedRequested = true;
|
||||||
|
Tracker.nonreactive(() => {
|
||||||
|
Tracker.autorun(() => {
|
||||||
|
this.isArchiveReady.set(handle.ready());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.archivesSidebar.onRendered(function () {
|
||||||
|
// XXX We should support dragging a card from the sidebar to the board
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.archivesSidebar.helpers({
|
||||||
|
isArchiveReady() {
|
||||||
|
return Template.instance().isArchiveReady;
|
||||||
|
},
|
||||||
|
isBoardAdmin() {
|
||||||
|
return ReactiveCache.getCurrentUser().isBoardAdmin();
|
||||||
|
},
|
||||||
|
isWorker() {
|
||||||
|
const currentBoard = Utils.getCurrentBoard();
|
||||||
|
return (
|
||||||
|
!currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
tabs() {
|
tabs() {
|
||||||
|
|
@ -34,139 +90,98 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
archivedCards() {
|
archivedCards() {
|
||||||
const ret = ReactiveCache.getCards(
|
return getArchivedCards();
|
||||||
{
|
|
||||||
archived: true,
|
|
||||||
boardId: Session.get('currentBoard'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return ret;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
archivedLists() {
|
archivedLists() {
|
||||||
return ReactiveCache.getLists(
|
return getArchivedLists();
|
||||||
{
|
|
||||||
archived: true,
|
|
||||||
boardId: Session.get('currentBoard'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
archivedSwimlanes() {
|
archivedSwimlanes() {
|
||||||
return ReactiveCache.getSwimlanes(
|
return getArchivedSwimlanes();
|
||||||
{
|
|
||||||
archived: true,
|
|
||||||
boardId: Session.get('currentBoard'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
sort: { archivedAt: -1, modifiedAt: -1 },
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cardIsInArchivedList() {
|
cardIsInArchivedList() {
|
||||||
return this.currentData().list().archived;
|
return Template.currentData().list().archived;
|
||||||
},
|
|
||||||
|
|
||||||
onRendered() {
|
|
||||||
// XXX We should support dragging a card from the sidebar to the board
|
|
||||||
},
|
|
||||||
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
async 'click .js-restore-card'() {
|
|
||||||
const card = this.currentData();
|
|
||||||
if (card.canBeRestored()) {
|
|
||||||
await card.restore();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async 'click .js-restore-all-cards'() {
|
|
||||||
for (const card of this.archivedCards()) {
|
|
||||||
if (card.canBeRestored()) {
|
|
||||||
await card.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'click .js-delete-card': Popup.afterConfirm('cardDelete', async function() {
|
|
||||||
const cardId = this._id;
|
|
||||||
await Cards.removeAsync(cardId);
|
|
||||||
Popup.back();
|
|
||||||
}),
|
|
||||||
'click .js-delete-all-cards': Popup.afterConfirm('cardDelete', async () => {
|
|
||||||
for (const card of this.archivedCards()) {
|
|
||||||
await Cards.removeAsync(card._id);
|
|
||||||
}
|
|
||||||
Popup.back();
|
|
||||||
}),
|
|
||||||
|
|
||||||
async 'click .js-restore-list'() {
|
|
||||||
const list = this.currentData();
|
|
||||||
await list.restore();
|
|
||||||
},
|
|
||||||
async 'click .js-restore-all-lists'() {
|
|
||||||
for (const list of this.archivedLists()) {
|
|
||||||
await list.restore();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'click .js-delete-list': Popup.afterConfirm('listDelete', async function() {
|
|
||||||
await this.remove();
|
|
||||||
Popup.back();
|
|
||||||
}),
|
|
||||||
'click .js-delete-all-lists': Popup.afterConfirm('listDelete', async () => {
|
|
||||||
for (const list of this.archivedLists()) {
|
|
||||||
await list.remove();
|
|
||||||
}
|
|
||||||
Popup.back();
|
|
||||||
}),
|
|
||||||
|
|
||||||
async 'click .js-restore-swimlane'() {
|
|
||||||
const swimlane = this.currentData();
|
|
||||||
await swimlane.restore();
|
|
||||||
},
|
|
||||||
async 'click .js-restore-all-swimlanes'() {
|
|
||||||
for (const swimlane of this.archivedSwimlanes()) {
|
|
||||||
await swimlane.restore();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
'click .js-delete-swimlane': Popup.afterConfirm(
|
|
||||||
'swimlaneDelete',
|
|
||||||
async function() {
|
|
||||||
await this.remove();
|
|
||||||
Popup.back();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
'click .js-delete-all-swimlanes': Popup.afterConfirm(
|
|
||||||
'swimlaneDelete',
|
|
||||||
async () => {
|
|
||||||
for (const swimlane of this.archivedSwimlanes()) {
|
|
||||||
await swimlane.remove();
|
|
||||||
}
|
|
||||||
Popup.back();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('archivesSidebar');
|
|
||||||
|
|
||||||
Template.archivesSidebar.helpers({
|
|
||||||
isBoardAdmin() {
|
|
||||||
return ReactiveCache.getCurrentUser().isBoardAdmin();
|
|
||||||
},
|
|
||||||
isWorker() {
|
|
||||||
const currentBoard = Utils.getCurrentBoard();
|
|
||||||
return (
|
|
||||||
!currentBoard.hasAdmin(this.userId) && currentBoard.hasWorker(this.userId)
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Template.archivesSidebar.events({
|
||||||
|
async 'click .js-restore-card'() {
|
||||||
|
const card = Template.currentData();
|
||||||
|
if (card.canBeRestored()) {
|
||||||
|
await card.restore();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async 'click .js-restore-all-cards'() {
|
||||||
|
for (const card of getArchivedCards()) {
|
||||||
|
if (card.canBeRestored()) {
|
||||||
|
await card.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'click .js-delete-card': Popup.afterConfirm('cardDelete', async function() {
|
||||||
|
const cardId = this._id;
|
||||||
|
await Cards.removeAsync(cardId);
|
||||||
|
Popup.back();
|
||||||
|
}),
|
||||||
|
'click .js-delete-all-cards': Popup.afterConfirm('cardDelete', async () => {
|
||||||
|
for (const card of getArchivedCards()) {
|
||||||
|
await Cards.removeAsync(card._id);
|
||||||
|
}
|
||||||
|
Popup.back();
|
||||||
|
}),
|
||||||
|
|
||||||
|
async 'click .js-restore-list'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
const list = Lists.findOne(data._id) || data;
|
||||||
|
await list.restore();
|
||||||
|
},
|
||||||
|
async 'click .js-restore-all-lists'() {
|
||||||
|
for (const list of getArchivedLists()) {
|
||||||
|
await list.restore();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'click .js-delete-list': Popup.afterConfirm('listDelete', async function() {
|
||||||
|
const list = Lists.findOne(this._id);
|
||||||
|
if (list) await list.remove();
|
||||||
|
Popup.back();
|
||||||
|
}),
|
||||||
|
'click .js-delete-all-lists': Popup.afterConfirm('listDelete', async () => {
|
||||||
|
for (const list of getArchivedLists()) {
|
||||||
|
await list.remove();
|
||||||
|
}
|
||||||
|
Popup.back();
|
||||||
|
}),
|
||||||
|
|
||||||
|
async 'click .js-restore-swimlane'() {
|
||||||
|
const data = Template.currentData();
|
||||||
|
const swimlane = Swimlanes.findOne(data._id) || data;
|
||||||
|
await swimlane.restore();
|
||||||
|
},
|
||||||
|
async 'click .js-restore-all-swimlanes'() {
|
||||||
|
for (const swimlane of getArchivedSwimlanes()) {
|
||||||
|
await swimlane.restore();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
'click .js-delete-swimlane': Popup.afterConfirm(
|
||||||
|
'swimlaneDelete',
|
||||||
|
async function() {
|
||||||
|
const swimlane = Swimlanes.findOne(this._id);
|
||||||
|
if (swimlane) await swimlane.remove();
|
||||||
|
Popup.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
'click .js-delete-all-swimlanes': Popup.afterConfirm(
|
||||||
|
'swimlaneDelete',
|
||||||
|
async () => {
|
||||||
|
for (const swimlane of getArchivedSwimlanes()) {
|
||||||
|
await swimlane.remove();
|
||||||
|
}
|
||||||
|
Popup.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,111 +1,119 @@
|
||||||
import { ReactiveCache } from '/imports/reactiveCache';
|
import { ReactiveCache } from '/imports/reactiveCache';
|
||||||
import { TAPi18n } from '/imports/i18n';
|
import { TAPi18n } from '/imports/i18n';
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.customFieldsSidebar.helpers({
|
||||||
customFields() {
|
customFields() {
|
||||||
const ret = ReactiveCache.getCustomFields({
|
const ret = ReactiveCache.getCustomFields({
|
||||||
boardIds: { $in: [Session.get('currentBoard')] },
|
boardIds: { $in: [Session.get('currentBoard')] },
|
||||||
});
|
});
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
events() {
|
Template.customFieldsSidebar.events({
|
||||||
return [
|
'click .js-open-create-custom-field': Popup.open('createCustomField'),
|
||||||
{
|
'click .js-edit-custom-field': Popup.open('editCustomField'),
|
||||||
'click .js-open-create-custom-field': Popup.open('createCustomField'),
|
});
|
||||||
'click .js-edit-custom-field': Popup.open('editCustomField'),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('customFieldsSidebar');
|
|
||||||
|
|
||||||
const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
const CUSTOM_FIELD_TYPES = [
|
||||||
_types: [
|
'text',
|
||||||
'text',
|
'number',
|
||||||
'number',
|
'date',
|
||||||
'date',
|
'dropdown',
|
||||||
'dropdown',
|
'currency',
|
||||||
'currency',
|
'checkbox',
|
||||||
'checkbox',
|
'stringtemplate',
|
||||||
'stringtemplate',
|
];
|
||||||
],
|
|
||||||
|
|
||||||
_currencyList: [
|
const CURRENCY_LIST = [
|
||||||
{
|
{ name: 'US Dollar', code: 'USD' },
|
||||||
name: 'US Dollar',
|
{ name: 'Euro', code: 'EUR' },
|
||||||
code: 'USD',
|
{ name: 'Yen', code: 'JPY' },
|
||||||
},
|
{ name: 'Pound Sterling', code: 'GBP' },
|
||||||
{
|
{ name: 'Australian Dollar', code: 'AUD' },
|
||||||
name: 'Euro',
|
{ name: 'Canadian Dollar', code: 'CAD' },
|
||||||
code: 'EUR',
|
{ name: 'Swiss Franc', code: 'CHF' },
|
||||||
},
|
{ name: 'Yuan Renminbi', code: 'CNY' },
|
||||||
{
|
{ name: 'Hong Kong Dollar', code: 'HKD' },
|
||||||
name: 'Yen',
|
{ name: 'New Zealand Dollar', code: 'NZD' },
|
||||||
code: 'JPY',
|
];
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Pound Sterling',
|
|
||||||
code: 'GBP',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Australian Dollar',
|
|
||||||
code: 'AUD',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Canadian Dollar',
|
|
||||||
code: 'CAD',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Swiss Franc',
|
|
||||||
code: 'CHF',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Yuan Renminbi',
|
|
||||||
code: 'CNY',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Hong Kong Dollar',
|
|
||||||
code: 'HKD',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'New Zealand Dollar',
|
|
||||||
code: 'NZD',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
onCreated() {
|
function getDropdownItems(tpl) {
|
||||||
this.type = new ReactiveVar(
|
const items = tpl.dropdownItems.get();
|
||||||
this.data().type ? this.data().type : this._types[0],
|
Array.from(tpl.findAll('.js-field-settings-dropdown input')).forEach(
|
||||||
);
|
(el, index) => {
|
||||||
|
if (!items[index])
|
||||||
|
items[index] = {
|
||||||
|
_id: Random.id(6),
|
||||||
|
};
|
||||||
|
items[index].name = el.value.trim();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
this.currencyCode = new ReactiveVar(
|
function getSettings(tpl) {
|
||||||
this.data().settings && this.data().settings.currencyCode
|
const settings = {};
|
||||||
? this.data().settings.currencyCode
|
switch (tpl.type.get()) {
|
||||||
: this._currencyList[0].code,
|
case 'currency': {
|
||||||
);
|
const currencyCode = tpl.currencyCode.get();
|
||||||
|
settings.currencyCode = currencyCode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'dropdown': {
|
||||||
|
const dropdownItems = getDropdownItems(tpl).filter(
|
||||||
|
item => !!item.name.trim(),
|
||||||
|
);
|
||||||
|
settings.dropdownItems = dropdownItems;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'stringtemplate': {
|
||||||
|
const stringtemplateFormat = tpl.stringtemplateFormat.get();
|
||||||
|
settings.stringtemplateFormat = stringtemplateFormat;
|
||||||
|
|
||||||
this.dropdownItems = new ReactiveVar(
|
const stringtemplateSeparator = tpl.stringtemplateSeparator.get();
|
||||||
this.data().settings && this.data().settings.dropdownItems
|
settings.stringtemplateSeparator = stringtemplateSeparator;
|
||||||
? this.data().settings.dropdownItems
|
break;
|
||||||
: [],
|
}
|
||||||
);
|
}
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
this.stringtemplateFormat = new ReactiveVar(
|
Template.createCustomFieldPopup.onCreated(function () {
|
||||||
this.data().settings && this.data().settings.stringtemplateFormat
|
const data = Template.currentData();
|
||||||
? this.data().settings.stringtemplateFormat
|
this.type = new ReactiveVar(
|
||||||
: '',
|
data.type ? data.type : CUSTOM_FIELD_TYPES[0],
|
||||||
);
|
);
|
||||||
|
|
||||||
this.stringtemplateSeparator = new ReactiveVar(
|
this.currencyCode = new ReactiveVar(
|
||||||
this.data().settings && this.data().settings.stringtemplateSeparator
|
data.settings && data.settings.currencyCode
|
||||||
? this.data().settings.stringtemplateSeparator
|
? data.settings.currencyCode
|
||||||
: '',
|
: CURRENCY_LIST[0].code,
|
||||||
);
|
);
|
||||||
},
|
|
||||||
|
|
||||||
|
this.dropdownItems = new ReactiveVar(
|
||||||
|
data.settings && data.settings.dropdownItems
|
||||||
|
? data.settings.dropdownItems
|
||||||
|
: [],
|
||||||
|
);
|
||||||
|
|
||||||
|
this.stringtemplateFormat = new ReactiveVar(
|
||||||
|
data.settings && data.settings.stringtemplateFormat
|
||||||
|
? data.settings.stringtemplateFormat
|
||||||
|
: '',
|
||||||
|
);
|
||||||
|
|
||||||
|
this.stringtemplateSeparator = new ReactiveVar(
|
||||||
|
data.settings && data.settings.stringtemplateSeparator
|
||||||
|
? data.settings.stringtemplateSeparator
|
||||||
|
: '',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.createCustomFieldPopup.helpers({
|
||||||
types() {
|
types() {
|
||||||
const currentType = this.data().type;
|
const currentType = Template.currentData().type;
|
||||||
return this._types.map(type => {
|
return CUSTOM_FIELD_TYPES.map(type => {
|
||||||
return {
|
return {
|
||||||
value: type,
|
value: type,
|
||||||
name: TAPi18n.__(`custom-field-${type}`),
|
name: TAPi18n.__(`custom-field-${type}`),
|
||||||
|
|
@ -115,13 +123,13 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
isTypeNotSelected(type) {
|
isTypeNotSelected(type) {
|
||||||
return this.type.get() !== type;
|
return Template.instance().type.get() !== type;
|
||||||
},
|
},
|
||||||
|
|
||||||
getCurrencyCodes() {
|
getCurrencyCodes() {
|
||||||
const currentCode = this.currencyCode.get();
|
const currentCode = Template.instance().currencyCode.get();
|
||||||
|
|
||||||
return this._currencyList.map(({ name, code }) => {
|
return CURRENCY_LIST.map(({ name, code }) => {
|
||||||
return {
|
return {
|
||||||
name: `${code} - ${name}`,
|
name: `${code} - ${name}`,
|
||||||
value: code,
|
value: code,
|
||||||
|
|
@ -131,176 +139,128 @@ const CreateCustomFieldPopup = BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
getDropdownItems() {
|
getDropdownItems() {
|
||||||
const items = this.dropdownItems.get();
|
return getDropdownItems(Template.instance());
|
||||||
Array.from(this.findAll('.js-field-settings-dropdown input')).forEach(
|
|
||||||
(el, index) => {
|
|
||||||
//console.log('each item!', index, el.value);
|
|
||||||
if (!items[index])
|
|
||||||
items[index] = {
|
|
||||||
_id: Random.id(6),
|
|
||||||
};
|
|
||||||
items[index].name = el.value.trim();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
return items;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getStringtemplateFormat() {
|
getStringtemplateFormat() {
|
||||||
return this.stringtemplateFormat.get();
|
return Template.instance().stringtemplateFormat.get();
|
||||||
},
|
},
|
||||||
|
|
||||||
getStringtemplateSeparator() {
|
getStringtemplateSeparator() {
|
||||||
return this.stringtemplateSeparator.get();
|
return Template.instance().stringtemplateSeparator.get();
|
||||||
},
|
|
||||||
|
|
||||||
getSettings() {
|
|
||||||
const settings = {};
|
|
||||||
switch (this.type.get()) {
|
|
||||||
case 'currency': {
|
|
||||||
const currencyCode = this.currencyCode.get();
|
|
||||||
settings.currencyCode = currencyCode;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'dropdown': {
|
|
||||||
const dropdownItems = this.getDropdownItems().filter(
|
|
||||||
item => !!item.name.trim(),
|
|
||||||
);
|
|
||||||
settings.dropdownItems = dropdownItems;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'stringtemplate': {
|
|
||||||
const stringtemplateFormat = this.stringtemplateFormat.get();
|
|
||||||
settings.stringtemplateFormat = stringtemplateFormat;
|
|
||||||
|
|
||||||
const stringtemplateSeparator = this.stringtemplateSeparator.get();
|
|
||||||
settings.stringtemplateSeparator = stringtemplateSeparator;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return settings;
|
|
||||||
},
|
|
||||||
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'change .js-field-type'(evt) {
|
|
||||||
const value = evt.target.value;
|
|
||||||
this.type.set(value);
|
|
||||||
},
|
|
||||||
'change .js-field-currency'(evt) {
|
|
||||||
const value = evt.target.value;
|
|
||||||
this.currencyCode.set(value);
|
|
||||||
},
|
|
||||||
'keydown .js-dropdown-item.last'(evt) {
|
|
||||||
if (evt.target.value.trim() && evt.keyCode === 13) {
|
|
||||||
const items = this.getDropdownItems();
|
|
||||||
this.dropdownItems.set(items);
|
|
||||||
evt.target.value = '';
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'input .js-field-stringtemplate-format'(evt) {
|
|
||||||
const value = evt.target.value;
|
|
||||||
this.stringtemplateFormat.set(value);
|
|
||||||
},
|
|
||||||
'input .js-field-stringtemplate-separator'(evt) {
|
|
||||||
const value = evt.target.value;
|
|
||||||
this.stringtemplateSeparator.set(value);
|
|
||||||
},
|
|
||||||
'click .js-field-show-on-card'(evt) {
|
|
||||||
let $target = $(evt.target);
|
|
||||||
if (!$target.hasClass('js-field-show-on-card')) {
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
|
||||||
'click .js-field-automatically-on-card'(evt) {
|
|
||||||
let $target = $(evt.target);
|
|
||||||
if (!$target.hasClass('js-field-automatically-on-card')) {
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
|
||||||
'click .js-field-always-on-card'(evt) {
|
|
||||||
let $target = $(evt.target);
|
|
||||||
if (!$target.hasClass('js-field-always-on-card')) {
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
|
||||||
'click .js-field-showLabel-on-card'(evt) {
|
|
||||||
let $target = $(evt.target);
|
|
||||||
if (!$target.hasClass('js-field-showLabel-on-card')) {
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
|
||||||
'click .js-field-show-sum-at-top-of-list'(evt) {
|
|
||||||
let $target = $(evt.target);
|
|
||||||
if (!$target.hasClass('js-field-show-sum-at-top-of-list')) {
|
|
||||||
$target = $target.parent();
|
|
||||||
}
|
|
||||||
$target.find('.materialCheckBox').toggleClass('is-checked');
|
|
||||||
$target.toggleClass('is-checked');
|
|
||||||
},
|
|
||||||
'click .primary'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
name: this.find('.js-field-name').value.trim(),
|
|
||||||
type: this.type.get(),
|
|
||||||
settings: this.getSettings(),
|
|
||||||
showOnCard: this.find('.js-field-show-on-card.is-checked') !== null,
|
|
||||||
showLabelOnMiniCard:
|
|
||||||
this.find('.js-field-showLabel-on-card.is-checked') !== null,
|
|
||||||
automaticallyOnCard:
|
|
||||||
this.find('.js-field-automatically-on-card.is-checked') !== null,
|
|
||||||
alwaysOnCard:
|
|
||||||
this.find('.js-field-always-on-card.is-checked') !== null,
|
|
||||||
showSumAtTopOfList:
|
|
||||||
this.find('.js-field-show-sum-at-top-of-list.is-checked') !== null,
|
|
||||||
};
|
|
||||||
|
|
||||||
// insert or update
|
|
||||||
if (!this.data()._id) {
|
|
||||||
data.boardIds = [Session.get('currentBoard')];
|
|
||||||
CustomFields.insert(data);
|
|
||||||
} else {
|
|
||||||
CustomFields.update(this.data()._id, { $set: data });
|
|
||||||
}
|
|
||||||
|
|
||||||
Popup.back();
|
|
||||||
},
|
|
||||||
'click .js-delete-custom-field': Popup.afterConfirm(
|
|
||||||
'deleteCustomField',
|
|
||||||
function() {
|
|
||||||
const customField = ReactiveCache.getCustomField(this._id);
|
|
||||||
if (customField.boardIds.length > 1) {
|
|
||||||
CustomFields.update(customField._id, {
|
|
||||||
$pull: {
|
|
||||||
boardIds: Session.get('currentBoard'),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
CustomFields.remove(customField._id);
|
|
||||||
}
|
|
||||||
Popup.back();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
CreateCustomFieldPopup.register('createCustomFieldPopup');
|
|
||||||
|
|
||||||
(class extends CreateCustomFieldPopup {
|
Template.createCustomFieldPopup.events({
|
||||||
template() {
|
'change .js-field-type'(evt, tpl) {
|
||||||
return 'createCustomFieldPopup';
|
const value = evt.target.value;
|
||||||
}
|
tpl.type.set(value);
|
||||||
}.register('editCustomFieldPopup'));
|
},
|
||||||
|
'change .js-field-currency'(evt, tpl) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
tpl.currencyCode.set(value);
|
||||||
|
},
|
||||||
|
'keydown .js-dropdown-item.last'(evt, tpl) {
|
||||||
|
if (evt.target.value.trim() && evt.keyCode === 13) {
|
||||||
|
const items = getDropdownItems(tpl);
|
||||||
|
tpl.dropdownItems.set(items);
|
||||||
|
evt.target.value = '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'input .js-field-stringtemplate-format'(evt, tpl) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
tpl.stringtemplateFormat.set(value);
|
||||||
|
},
|
||||||
|
'input .js-field-stringtemplate-separator'(evt, tpl) {
|
||||||
|
const value = evt.target.value;
|
||||||
|
tpl.stringtemplateSeparator.set(value);
|
||||||
|
},
|
||||||
|
'click .js-field-show-on-card'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if (!$target.hasClass('js-field-show-on-card')) {
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .js-field-automatically-on-card'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if (!$target.hasClass('js-field-automatically-on-card')) {
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .js-field-always-on-card'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if (!$target.hasClass('js-field-always-on-card')) {
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .js-field-showLabel-on-card'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if (!$target.hasClass('js-field-showLabel-on-card')) {
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .js-field-show-sum-at-top-of-list'(evt) {
|
||||||
|
let $target = $(evt.target);
|
||||||
|
if (!$target.hasClass('js-field-show-sum-at-top-of-list')) {
|
||||||
|
$target = $target.parent();
|
||||||
|
}
|
||||||
|
$target.find('.materialCheckBox').toggleClass('is-checked');
|
||||||
|
$target.toggleClass('is-checked');
|
||||||
|
},
|
||||||
|
'click .primary'(evt, tpl) {
|
||||||
|
evt.preventDefault();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
name: tpl.find('.js-field-name').value.trim(),
|
||||||
|
type: tpl.type.get(),
|
||||||
|
settings: getSettings(tpl),
|
||||||
|
showOnCard: tpl.find('.js-field-show-on-card.is-checked') !== null,
|
||||||
|
showLabelOnMiniCard:
|
||||||
|
tpl.find('.js-field-showLabel-on-card.is-checked') !== null,
|
||||||
|
automaticallyOnCard:
|
||||||
|
tpl.find('.js-field-automatically-on-card.is-checked') !== null,
|
||||||
|
alwaysOnCard:
|
||||||
|
tpl.find('.js-field-always-on-card.is-checked') !== null,
|
||||||
|
showSumAtTopOfList:
|
||||||
|
tpl.find('.js-field-show-sum-at-top-of-list.is-checked') !== null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentData = Template.currentData();
|
||||||
|
// insert or update
|
||||||
|
if (!currentData._id) {
|
||||||
|
data.boardIds = [Session.get('currentBoard')];
|
||||||
|
CustomFields.insert(data);
|
||||||
|
} else {
|
||||||
|
CustomFields.update(currentData._id, { $set: data });
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup.back();
|
||||||
|
},
|
||||||
|
'click .js-delete-custom-field': Popup.afterConfirm(
|
||||||
|
'deleteCustomField',
|
||||||
|
function() {
|
||||||
|
const customField = ReactiveCache.getCustomField(this._id);
|
||||||
|
if (customField.boardIds.length > 1) {
|
||||||
|
CustomFields.update(customField._id, {
|
||||||
|
$pull: {
|
||||||
|
boardIds: Session.get('currentBoard'),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
CustomFields.remove(customField._id);
|
||||||
|
}
|
||||||
|
Popup.back();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
/*Template.deleteCustomFieldPopup.events({
|
/*Template.deleteCustomFieldPopup.events({
|
||||||
'submit'(evt) {
|
'submit'(evt) {
|
||||||
|
|
|
||||||
|
|
@ -3,108 +3,102 @@ import { TAPi18n } from '/imports/i18n';
|
||||||
|
|
||||||
const subManager = new SubsManager();
|
const subManager = new SubsManager();
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
Template.filterSidebar.events({
|
||||||
events() {
|
'submit .js-list-filter'(evt, tpl) {
|
||||||
return [
|
evt.preventDefault();
|
||||||
{
|
Filter.lists.set(tpl.find('.js-list-filter input').value.trim());
|
||||||
'submit .js-list-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.lists.set(this.find('.js-list-filter input').value.trim());
|
|
||||||
},
|
|
||||||
'change .js-field-card-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.title.set(this.find('.js-field-card-filter').value.trim());
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-label-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.labelIds.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-member-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.members.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-assignee-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.assignees.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-no-due-date-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.noDate();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-overdue-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.past();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-due-today-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.today();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-due-tomorrow-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.tomorrow();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-due-this-week-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.thisWeek();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-due-next-week-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.dueAt.nextWeek();
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-archive-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.archive.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
const currentBoardId = Session.get('currentBoard');
|
|
||||||
if (!currentBoardId) return;
|
|
||||||
subManager.subscribe(
|
|
||||||
'board',
|
|
||||||
currentBoardId,
|
|
||||||
Filter.archive.isSelected(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
'click .js-toggle-hideEmpty-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.hideEmpty.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-toggle-custom-fields-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.customFields.toggle(this.currentData()._id);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'change .js-field-advanced-filter'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.advanced.set(
|
|
||||||
this.find('.js-field-advanced-filter').value.trim(),
|
|
||||||
);
|
|
||||||
Filter.resetExceptions();
|
|
||||||
},
|
|
||||||
'click .js-clear-all'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
Filter.reset();
|
|
||||||
},
|
|
||||||
'click .js-filter-to-selection'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
const selectedCards = ReactiveCache.getCards(Filter.mongoSelector()).map(c => {
|
|
||||||
return c._id;
|
|
||||||
});
|
|
||||||
MultiSelection.add(selectedCards);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
},
|
||||||
}).register('filterSidebar');
|
'change .js-field-card-filter'(evt, tpl) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.title.set(tpl.find('.js-field-card-filter').value.trim());
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-label-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.labelIds.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-member-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.members.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-assignee-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.assignees.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-no-due-date-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.noDate();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-overdue-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.past();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-due-today-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.today();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-due-tomorrow-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.tomorrow();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-due-this-week-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.thisWeek();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-due-next-week-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.dueAt.nextWeek();
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-archive-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.archive.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
const currentBoardId = Session.get('currentBoard');
|
||||||
|
if (!currentBoardId) return;
|
||||||
|
subManager.subscribe(
|
||||||
|
'board',
|
||||||
|
currentBoardId,
|
||||||
|
Filter.archive.isSelected(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
'click .js-toggle-hideEmpty-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.hideEmpty.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-toggle-custom-fields-filter'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.customFields.toggle(Template.currentData()._id);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'change .js-field-advanced-filter'(evt, tpl) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.advanced.set(
|
||||||
|
tpl.find('.js-field-advanced-filter').value.trim(),
|
||||||
|
);
|
||||||
|
Filter.resetExceptions();
|
||||||
|
},
|
||||||
|
'click .js-clear-all'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
Filter.reset();
|
||||||
|
},
|
||||||
|
'click .js-filter-to-selection'(evt) {
|
||||||
|
evt.preventDefault();
|
||||||
|
const selectedCards = ReactiveCache.getCards(Filter.mongoSelector()).map(c => {
|
||||||
|
return c._id;
|
||||||
|
});
|
||||||
|
MultiSelection.add(selectedCards);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
async function mutateSelectedCards(mutationNameOrCallback, ...args) {
|
async function mutateSelectedCards(mutationNameOrCallback, ...args) {
|
||||||
const cards = ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']});
|
const cards = ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']});
|
||||||
|
|
@ -181,67 +175,12 @@ function buildInsertionSortIndexes(cardsCount, targetCard, position, listId, swi
|
||||||
return indexes;
|
return indexes;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlazeComponent.extendComponent({
|
function mapSelection(kind, _id) {
|
||||||
mapSelection(kind, _id) {
|
return ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']}).map(card => {
|
||||||
return ReactiveCache.getCards(MultiSelection.getMongoSelector(), {sort: ['sort']}).map(card => {
|
const methodName = kind === 'label' ? 'hasLabel' : 'isAssigned';
|
||||||
const methodName = kind === 'label' ? 'hasLabel' : 'isAssigned';
|
return card[methodName](_id);
|
||||||
return card[methodName](_id);
|
});
|
||||||
});
|
}
|
||||||
},
|
|
||||||
|
|
||||||
allSelectedElementHave(kind, _id) {
|
|
||||||
if (MultiSelection.isEmpty()) return false;
|
|
||||||
else return _.every(this.mapSelection(kind, _id));
|
|
||||||
},
|
|
||||||
|
|
||||||
someSelectedElementHave(kind, _id) {
|
|
||||||
if (MultiSelection.isEmpty()) return false;
|
|
||||||
else return _.some(this.mapSelection(kind, _id));
|
|
||||||
},
|
|
||||||
|
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click .js-toggle-label-multiselection'(evt) {
|
|
||||||
const labelId = this.currentData()._id;
|
|
||||||
const mappedSelection = this.mapSelection('label', labelId);
|
|
||||||
|
|
||||||
if (_.every(mappedSelection)) {
|
|
||||||
mutateSelectedCards('removeLabel', labelId);
|
|
||||||
} else if (_.every(mappedSelection, bool => !bool)) {
|
|
||||||
mutateSelectedCards('addLabel', labelId);
|
|
||||||
} else {
|
|
||||||
const popup = Popup.open('disambiguateMultiLabel');
|
|
||||||
// XXX We need to have a better integration between the popup and the
|
|
||||||
// UI components systems.
|
|
||||||
popup.call(this.currentData(), evt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click .js-toggle-member-multiselection'(evt) {
|
|
||||||
const memberId = this.currentData()._id;
|
|
||||||
const mappedSelection = this.mapSelection('member', memberId);
|
|
||||||
if (_.every(mappedSelection)) {
|
|
||||||
mutateSelectedCards('unassignMember', memberId);
|
|
||||||
} else if (_.every(mappedSelection, bool => !bool)) {
|
|
||||||
mutateSelectedCards('assignMember', memberId);
|
|
||||||
} else {
|
|
||||||
const popup = Popup.open('disambiguateMultiMember');
|
|
||||||
// XXX We need to have a better integration between the popup and the
|
|
||||||
// UI components systems.
|
|
||||||
popup.call(this.currentData(), evt);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'click .js-move-selection': Popup.open('moveSelection'),
|
|
||||||
'click .js-copy-selection': Popup.open('copySelection'),
|
|
||||||
'click .js-selection-color': Popup.open('setSelectionColor'),
|
|
||||||
'click .js-archive-selection'() {
|
|
||||||
mutateSelectedCards('archive');
|
|
||||||
EscapeActions.executeUpTo('multiselection');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('multiselectionSidebar');
|
|
||||||
|
|
||||||
Template.multiselectionSidebar.helpers({
|
Template.multiselectionSidebar.helpers({
|
||||||
isBoardAdmin() {
|
isBoardAdmin() {
|
||||||
|
|
@ -250,6 +189,53 @@ Template.multiselectionSidebar.helpers({
|
||||||
isCommentOnly() {
|
isCommentOnly() {
|
||||||
return ReactiveCache.getCurrentUser().isCommentOnly();
|
return ReactiveCache.getCurrentUser().isCommentOnly();
|
||||||
},
|
},
|
||||||
|
allSelectedElementHave(kind, _id) {
|
||||||
|
if (MultiSelection.isEmpty()) return false;
|
||||||
|
else return _.every(mapSelection(kind, _id));
|
||||||
|
},
|
||||||
|
someSelectedElementHave(kind, _id) {
|
||||||
|
if (MultiSelection.isEmpty()) return false;
|
||||||
|
else return _.some(mapSelection(kind, _id));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.multiselectionSidebar.events({
|
||||||
|
'click .js-toggle-label-multiselection'(evt) {
|
||||||
|
const labelId = Template.currentData()._id;
|
||||||
|
const mappedSelection = mapSelection('label', labelId);
|
||||||
|
|
||||||
|
if (_.every(mappedSelection)) {
|
||||||
|
mutateSelectedCards('removeLabel', labelId);
|
||||||
|
} else if (_.every(mappedSelection, bool => !bool)) {
|
||||||
|
mutateSelectedCards('addLabel', labelId);
|
||||||
|
} else {
|
||||||
|
const popup = Popup.open('disambiguateMultiLabel');
|
||||||
|
// XXX We need to have a better integration between the popup and the
|
||||||
|
// UI components systems.
|
||||||
|
popup.call(Template.currentData(), evt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click .js-toggle-member-multiselection'(evt) {
|
||||||
|
const memberId = Template.currentData()._id;
|
||||||
|
const mappedSelection = mapSelection('member', memberId);
|
||||||
|
if (_.every(mappedSelection)) {
|
||||||
|
mutateSelectedCards('unassignMember', memberId);
|
||||||
|
} else if (_.every(mappedSelection, bool => !bool)) {
|
||||||
|
mutateSelectedCards('assignMember', memberId);
|
||||||
|
} else {
|
||||||
|
const popup = Popup.open('disambiguateMultiMember');
|
||||||
|
// XXX We need to have a better integration between the popup and the
|
||||||
|
// UI components systems.
|
||||||
|
popup.call(Template.currentData(), evt);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'click .js-move-selection': Popup.open('moveSelection'),
|
||||||
|
'click .js-copy-selection': Popup.open('copySelection'),
|
||||||
|
'click .js-selection-color': Popup.open('setSelectionColor'),
|
||||||
|
'click .js-archive-selection'() {
|
||||||
|
mutateSelectedCards('archive');
|
||||||
|
EscapeActions.executeUpTo('multiselection');
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.disambiguateMultiLabelPopup.events({
|
Template.disambiguateMultiLabelPopup.events({
|
||||||
|
|
|
||||||
|
|
@ -1,41 +1,31 @@
|
||||||
BlazeComponent.extendComponent({
|
Template.searchSidebar.onCreated(function () {
|
||||||
onCreated() {
|
this.term = new ReactiveVar('');
|
||||||
this.term = new ReactiveVar('');
|
});
|
||||||
},
|
|
||||||
|
|
||||||
|
Template.searchSidebar.helpers({
|
||||||
cards() {
|
cards() {
|
||||||
const currentBoard = Utils.getCurrentBoard();
|
const currentBoard = Utils.getCurrentBoard();
|
||||||
return currentBoard.searchCards(this.term.get());
|
return currentBoard.searchCards(Template.instance().term.get());
|
||||||
},
|
},
|
||||||
|
|
||||||
lists() {
|
lists() {
|
||||||
const currentBoard = Utils.getCurrentBoard();
|
const currentBoard = Utils.getCurrentBoard();
|
||||||
return currentBoard.searchLists(this.term.get());
|
return currentBoard.searchLists(Template.instance().term.get());
|
||||||
},
|
},
|
||||||
|
});
|
||||||
|
|
||||||
clickOnMiniCard(evt) {
|
Template.searchSidebar.events({
|
||||||
|
'click .js-minicard'(evt) {
|
||||||
if (Utils.isMiniScreen()) {
|
if (Utils.isMiniScreen()) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
Session.set('popupCardId', this.currentData()._id);
|
Session.set('popupCardId', Template.currentData()._id);
|
||||||
this.cardDetailsPopup(evt);
|
if (!Popup.isOpen()) {
|
||||||
|
Popup.open("cardDetails")(evt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
'submit .js-search-term-form'(evt, tpl) {
|
||||||
cardDetailsPopup(event) {
|
evt.preventDefault();
|
||||||
if (!Popup.isOpen()) {
|
tpl.term.set(evt.target.searchTerm.value);
|
||||||
Popup.open("cardDetails")(event);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
});
|
||||||
events() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
'click .js-minicard': this.clickOnMiniCard,
|
|
||||||
'submit .js-search-term-form'(evt) {
|
|
||||||
evt.preventDefault();
|
|
||||||
this.term.set(evt.target.searchTerm.value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
}).register('searchSidebar');
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue