2016-10-25 03:49:45 +00:00
|
|
|
/* jslint node: true */
|
|
|
|
'use strict';
|
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// ENiGMA½
|
2022-06-05 20:04:25 +00:00
|
|
|
const MenuModule = require('./menu_module.js').MenuModule;
|
|
|
|
const ViewController = require('./view_controller.js').ViewController;
|
|
|
|
const getSortedAvailableFileAreas =
|
|
|
|
require('./file_base_area.js').getSortedAvailableFileAreas;
|
|
|
|
const FileBaseFilters = require('./file_base_filter.js');
|
|
|
|
const stringFormat = require('./string_format.js');
|
|
|
|
const UserProps = require('./user_property.js');
|
2016-10-25 03:49:45 +00:00
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// deps
|
2022-06-05 20:04:25 +00:00
|
|
|
const async = require('async');
|
2016-10-25 03:49:45 +00:00
|
|
|
|
|
|
|
exports.moduleInfo = {
|
2022-06-05 20:04:25 +00:00
|
|
|
name: 'File Area Filter Editor',
|
|
|
|
desc: 'Module for adding, deleting, and modifying file base filters',
|
|
|
|
author: 'NuSkooler',
|
2016-10-25 03:49:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const MciViewIds = {
|
2022-06-05 20:04:25 +00:00
|
|
|
editor: {
|
|
|
|
searchTerms: 1,
|
|
|
|
tags: 2,
|
|
|
|
area: 3,
|
|
|
|
sort: 4,
|
|
|
|
order: 5,
|
|
|
|
filterName: 6,
|
|
|
|
navMenu: 7,
|
2018-06-23 03:26:46 +00:00
|
|
|
|
|
|
|
// :TODO: use the customs new standard thing - filter obj can have active/selected, etc.
|
2022-06-05 20:04:25 +00:00
|
|
|
selectedFilterInfo: 10, // { ...filter object ... }
|
|
|
|
activeFilterInfo: 11, // { ...filter object ... }
|
|
|
|
error: 12, // validation errors
|
|
|
|
},
|
2016-10-25 03:49:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
exports.getModule = class FileAreaFilterEdit extends MenuModule {
|
2018-06-22 05:15:04 +00:00
|
|
|
constructor(options) {
|
|
|
|
super(options);
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
this.filtersArray = new FileBaseFilters(this.client).toArray(); // ordered, such that we can index into them
|
|
|
|
this.currentFilterIndex = 0; // into |filtersArray|
|
2018-06-22 05:15:04 +00:00
|
|
|
|
|
|
|
//
|
2018-06-23 03:26:46 +00:00
|
|
|
// Lexical sort + keep currently active filter (if any) as the first item in |filtersArray|
|
2018-06-22 05:15:04 +00:00
|
|
|
//
|
|
|
|
const activeFilter = FileBaseFilters.getActiveFilter(this.client);
|
2022-06-05 20:04:25 +00:00
|
|
|
this.filtersArray.sort((filterA, filterB) => {
|
|
|
|
if (activeFilter) {
|
|
|
|
if (filterA.uuid === activeFilter.uuid) {
|
2018-06-22 05:15:04 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2022-06-05 20:04:25 +00:00
|
|
|
if (filterB.uuid === activeFilter.uuid) {
|
2018-06-22 05:15:04 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
return filterA.name.localeCompare(filterB.name, {
|
|
|
|
sensitivity: false,
|
|
|
|
numeric: true,
|
|
|
|
});
|
2018-06-22 05:15:04 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
this.menuMethods = {
|
2022-06-05 20:04:25 +00:00
|
|
|
saveFilter: (formData, extraArgs, cb) => {
|
2018-06-22 05:15:04 +00:00
|
|
|
return this.saveCurrentFilter(formData, cb);
|
|
|
|
},
|
2022-06-05 20:04:25 +00:00
|
|
|
prevFilter: (formData, extraArgs, cb) => {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.currentFilterIndex -= 1;
|
2022-06-05 20:04:25 +00:00
|
|
|
if (this.currentFilterIndex < 0) {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.currentFilterIndex = this.filtersArray.length - 1;
|
|
|
|
}
|
|
|
|
this.loadDataForFilter(this.currentFilterIndex);
|
|
|
|
return cb(null);
|
|
|
|
},
|
2022-06-05 20:04:25 +00:00
|
|
|
nextFilter: (formData, extraArgs, cb) => {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.currentFilterIndex += 1;
|
2022-06-05 20:04:25 +00:00
|
|
|
if (this.currentFilterIndex >= this.filtersArray.length) {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.currentFilterIndex = 0;
|
|
|
|
}
|
|
|
|
this.loadDataForFilter(this.currentFilterIndex);
|
|
|
|
return cb(null);
|
|
|
|
},
|
2022-06-05 20:04:25 +00:00
|
|
|
makeFilterActive: (formData, extraArgs, cb) => {
|
2018-06-22 05:15:04 +00:00
|
|
|
const filters = new FileBaseFilters(this.client);
|
|
|
|
filters.setActive(this.filtersArray[this.currentFilterIndex].uuid);
|
|
|
|
|
|
|
|
this.updateActiveLabel();
|
|
|
|
|
|
|
|
return cb(null);
|
|
|
|
},
|
2022-06-05 20:04:25 +00:00
|
|
|
newFilter: (formData, extraArgs, cb) => {
|
2018-06-23 03:26:46 +00:00
|
|
|
this.currentFilterIndex = this.filtersArray.length; // next avail slot
|
2018-06-22 05:15:04 +00:00
|
|
|
this.clearForm(MciViewIds.editor.searchTerms);
|
|
|
|
return cb(null);
|
|
|
|
},
|
2022-06-05 20:04:25 +00:00
|
|
|
deleteFilter: (formData, extraArgs, cb) => {
|
|
|
|
const selectedFilter = this.filtersArray[this.currentFilterIndex];
|
|
|
|
const filterUuid = selectedFilter.uuid;
|
2018-06-22 05:15:04 +00:00
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// cannot delete built-in/system filters
|
2022-06-05 20:04:25 +00:00
|
|
|
if (true === selectedFilter.system) {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.showError('Cannot delete built in filters!');
|
|
|
|
return cb(null);
|
|
|
|
}
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
this.filtersArray.splice(this.currentFilterIndex, 1); // remove selected entry
|
2018-06-22 05:15:04 +00:00
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// remove from stored properties
|
2018-06-22 05:15:04 +00:00
|
|
|
const filters = new FileBaseFilters(this.client);
|
|
|
|
filters.remove(filterUuid);
|
2022-06-05 20:04:25 +00:00
|
|
|
filters.persist(() => {
|
2018-06-22 05:15:04 +00:00
|
|
|
//
|
2018-06-23 03:26:46 +00:00
|
|
|
// If the item was also the active filter, we need to make a new one active
|
2018-06-22 05:15:04 +00:00
|
|
|
//
|
2022-06-05 20:04:25 +00:00
|
|
|
if (
|
|
|
|
filterUuid ===
|
|
|
|
this.client.user.properties[UserProps.FileBaseFilterActiveUuid]
|
|
|
|
) {
|
2018-06-22 05:15:04 +00:00
|
|
|
const newActive = this.filtersArray[this.currentFilterIndex];
|
2022-06-05 20:04:25 +00:00
|
|
|
if (newActive) {
|
2018-06-22 05:15:04 +00:00
|
|
|
filters.setActive(newActive.uuid);
|
|
|
|
} else {
|
2018-06-23 03:26:46 +00:00
|
|
|
// nothing to set active to
|
2022-06-05 20:04:25 +00:00
|
|
|
this.client.user.removeProperty(
|
|
|
|
'file_base_filter_active_uuid'
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// update UI
|
2018-06-22 05:15:04 +00:00
|
|
|
this.updateActiveLabel();
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
if (this.filtersArray.length > 0) {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.loadDataForFilter(this.currentFilterIndex);
|
|
|
|
} else {
|
|
|
|
this.clearForm();
|
|
|
|
}
|
|
|
|
return cb(null);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
viewValidationListener: (err, cb) => {
|
|
|
|
const errorView = this.viewControllers.editor.getView(
|
|
|
|
MciViewIds.editor.error
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
let newFocusId;
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
if (errorView) {
|
|
|
|
if (err) {
|
2018-06-22 05:15:04 +00:00
|
|
|
errorView.setText(err.message);
|
2022-06-05 20:04:25 +00:00
|
|
|
err.view.clearText(); // clear out the invalid data
|
2018-06-22 05:15:04 +00:00
|
|
|
} else {
|
|
|
|
errorView.clearText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cb(newFocusId);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
showError(errMsg) {
|
|
|
|
const errorView = this.viewControllers.editor.getView(MciViewIds.editor.error);
|
2022-06-05 20:04:25 +00:00
|
|
|
if (errorView) {
|
|
|
|
if (errMsg) {
|
2018-06-22 05:15:04 +00:00
|
|
|
errorView.setText(errMsg);
|
|
|
|
} else {
|
|
|
|
errorView.clearText();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mciReady(mciData, cb) {
|
|
|
|
super.mciReady(mciData, err => {
|
2022-06-05 20:04:25 +00:00
|
|
|
if (err) {
|
2018-06-22 05:15:04 +00:00
|
|
|
return cb(err);
|
|
|
|
}
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
const self = this;
|
|
|
|
const vc = self.addViewController(
|
|
|
|
'editor',
|
|
|
|
new ViewController({ client: this.client })
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
|
|
|
|
async.series(
|
|
|
|
[
|
|
|
|
function loadFromConfig(callback) {
|
2022-06-05 20:04:25 +00:00
|
|
|
return vc.loadFromMenuConfig(
|
|
|
|
{ callingMenu: self, mciMap: mciData.menu },
|
|
|
|
callback
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
},
|
|
|
|
function populateAreas(callback) {
|
2022-06-05 20:04:25 +00:00
|
|
|
self.availAreas = [{ name: '-ALL-' }].concat(
|
|
|
|
getSortedAvailableFileAreas(self.client) || []
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
|
|
|
|
const areasView = vc.getView(MciViewIds.editor.area);
|
2022-06-05 20:04:25 +00:00
|
|
|
if (areasView) {
|
|
|
|
areasView.setItems(self.availAreas.map(a => a.name));
|
2018-06-22 05:15:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.updateActiveLabel();
|
|
|
|
self.loadDataForFilter(self.currentFilterIndex);
|
|
|
|
self.viewControllers.editor.resetInitialFocus();
|
|
|
|
return callback(null);
|
2022-06-05 20:04:25 +00:00
|
|
|
},
|
2018-06-22 05:15:04 +00:00
|
|
|
],
|
|
|
|
err => {
|
|
|
|
return cb(err);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
getCurrentFilter() {
|
|
|
|
return this.filtersArray[this.currentFilterIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
setText(mciId, text) {
|
|
|
|
const view = this.viewControllers.editor.getView(mciId);
|
2022-06-05 20:04:25 +00:00
|
|
|
if (view) {
|
2018-06-22 05:15:04 +00:00
|
|
|
view.setText(text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateActiveLabel() {
|
|
|
|
const activeFilter = FileBaseFilters.getActiveFilter(this.client);
|
2022-06-05 20:04:25 +00:00
|
|
|
if (activeFilter) {
|
2018-06-22 05:15:04 +00:00
|
|
|
const activeFormat = this.menuConfig.config.activeFormat || '{name}';
|
2022-06-05 20:04:25 +00:00
|
|
|
this.setText(
|
|
|
|
MciViewIds.editor.activeFilterInfo,
|
|
|
|
stringFormat(activeFormat, activeFilter)
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setFocusItemIndex(mciId, index) {
|
|
|
|
const view = this.viewControllers.editor.getView(mciId);
|
2022-06-05 20:04:25 +00:00
|
|
|
if (view) {
|
2018-06-22 05:15:04 +00:00
|
|
|
view.setFocusItemIndex(index);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
clearForm(newFocusId) {
|
2022-06-05 20:04:25 +00:00
|
|
|
[
|
|
|
|
MciViewIds.editor.searchTerms,
|
|
|
|
MciViewIds.editor.tags,
|
|
|
|
MciViewIds.editor.filterName,
|
|
|
|
].forEach(mciId => {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.setText(mciId, '');
|
|
|
|
});
|
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
[MciViewIds.editor.area, MciViewIds.editor.order, MciViewIds.editor.sort].forEach(
|
|
|
|
mciId => {
|
|
|
|
this.setFocusItemIndex(mciId, 0);
|
|
|
|
}
|
|
|
|
);
|
2018-06-22 05:15:04 +00:00
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
if (newFocusId) {
|
2018-06-22 05:15:04 +00:00
|
|
|
this.viewControllers.editor.switchFocus(newFocusId);
|
|
|
|
} else {
|
|
|
|
this.viewControllers.editor.resetInitialFocus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getSelectedAreaTag(index) {
|
2022-06-05 20:04:25 +00:00
|
|
|
if (0 === index) {
|
|
|
|
return ''; // -ALL-
|
2018-06-22 05:15:04 +00:00
|
|
|
}
|
|
|
|
const area = this.availAreas[index];
|
2022-06-05 20:04:25 +00:00
|
|
|
if (!area) {
|
2018-06-22 05:15:04 +00:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
return area.areaTag;
|
|
|
|
}
|
|
|
|
|
|
|
|
getOrderBy(index) {
|
|
|
|
return FileBaseFilters.OrderByValues[index] || FileBaseFilters.OrderByValues[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
setAreaIndexFromCurrentFilter() {
|
|
|
|
let index;
|
|
|
|
const filter = this.getCurrentFilter();
|
2022-06-05 20:04:25 +00:00
|
|
|
if (filter) {
|
2018-06-23 03:26:46 +00:00
|
|
|
// special treatment: areaTag saved as blank ("") if -ALL-
|
2022-06-05 20:04:25 +00:00
|
|
|
index =
|
|
|
|
(filter.areaTag &&
|
|
|
|
this.availAreas.findIndex(area => filter.areaTag === area.areaTag)) ||
|
|
|
|
0;
|
2018-06-22 05:15:04 +00:00
|
|
|
} else {
|
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
this.setFocusItemIndex(MciViewIds.editor.area, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
setOrderByFromCurrentFilter() {
|
|
|
|
let index;
|
|
|
|
const filter = this.getCurrentFilter();
|
2022-06-05 20:04:25 +00:00
|
|
|
if (filter) {
|
|
|
|
index =
|
|
|
|
FileBaseFilters.OrderByValues.findIndex(ob => filter.order === ob) || 0;
|
2018-06-22 05:15:04 +00:00
|
|
|
} else {
|
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
this.setFocusItemIndex(MciViewIds.editor.order, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
setSortByFromCurrentFilter() {
|
|
|
|
let index;
|
|
|
|
const filter = this.getCurrentFilter();
|
2022-06-05 20:04:25 +00:00
|
|
|
if (filter) {
|
|
|
|
index = FileBaseFilters.SortByValues.findIndex(sb => filter.sort === sb) || 0;
|
2018-06-22 05:15:04 +00:00
|
|
|
} else {
|
|
|
|
index = 0;
|
|
|
|
}
|
|
|
|
this.setFocusItemIndex(MciViewIds.editor.sort, index);
|
|
|
|
}
|
|
|
|
|
|
|
|
getSortBy(index) {
|
|
|
|
return FileBaseFilters.SortByValues[index] || FileBaseFilters.SortByValues[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
setFilterValuesFromFormData(filter, formData) {
|
2022-06-05 20:04:25 +00:00
|
|
|
filter.name = formData.value.name;
|
|
|
|
filter.areaTag = this.getSelectedAreaTag(formData.value.areaIndex);
|
|
|
|
filter.terms = formData.value.searchTerms;
|
|
|
|
filter.tags = formData.value.tags;
|
|
|
|
filter.order = this.getOrderBy(formData.value.orderByIndex);
|
|
|
|
filter.sort = this.getSortBy(formData.value.sortByIndex);
|
2018-06-22 05:15:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
saveCurrentFilter(formData, cb) {
|
2022-06-05 20:04:25 +00:00
|
|
|
const filters = new FileBaseFilters(this.client);
|
|
|
|
const selectedFilter = this.filtersArray[this.currentFilterIndex];
|
2018-06-22 05:15:04 +00:00
|
|
|
|
2022-06-05 20:04:25 +00:00
|
|
|
if (selectedFilter) {
|
2018-06-23 03:26:46 +00:00
|
|
|
// *update* currently selected filter
|
2018-06-22 05:15:04 +00:00
|
|
|
this.setFilterValuesFromFormData(selectedFilter, formData);
|
|
|
|
filters.replace(selectedFilter.uuid, selectedFilter);
|
|
|
|
} else {
|
2018-06-23 03:26:46 +00:00
|
|
|
// add a new entry; note that UUID will be generated
|
2018-06-22 05:15:04 +00:00
|
|
|
const newFilter = {};
|
|
|
|
this.setFilterValuesFromFormData(newFilter, formData);
|
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// set current to what we just saved
|
2018-06-22 05:15:04 +00:00
|
|
|
newFilter.uuid = filters.add(newFilter);
|
|
|
|
|
2018-06-23 03:26:46 +00:00
|
|
|
// add to our array (at current index position)
|
2018-06-22 05:15:04 +00:00
|
|
|
this.filtersArray[this.currentFilterIndex] = newFilter;
|
|
|
|
}
|
|
|
|
|
|
|
|
return filters.persist(cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
loadDataForFilter(filterIndex) {
|
|
|
|
const filter = this.filtersArray[filterIndex];
|
2022-06-05 20:04:25 +00:00
|
|
|
if (filter) {
|
2018-06-23 03:26:46 +00:00
|
|
|
this.setText(MciViewIds.editor.searchTerms, filter.terms);
|
2022-06-05 20:04:25 +00:00
|
|
|
this.setText(MciViewIds.editor.tags, filter.tags);
|
|
|
|
this.setText(MciViewIds.editor.filterName, filter.name);
|
2018-06-22 05:15:04 +00:00
|
|
|
|
|
|
|
this.setAreaIndexFromCurrentFilter();
|
|
|
|
this.setSortByFromCurrentFilter();
|
|
|
|
this.setOrderByFromCurrentFilter();
|
|
|
|
}
|
|
|
|
}
|
2016-10-25 03:49:45 +00:00
|
|
|
};
|