diff options
-rw-r--r-- | src/data/things/index.js | 2 | ||||
-rw-r--r-- | src/data/things/sorting-rule.js | 139 | ||||
-rwxr-xr-x | src/upd8.js | 1 |
3 files changed, 142 insertions, 0 deletions
diff --git a/src/data/things/index.js b/src/data/things/index.js index 9f033c23..309d0803 100644 --- a/src/data/things/index.js +++ b/src/data/things/index.js @@ -17,6 +17,7 @@ import * as groupClasses from './group.js'; import * as homepageLayoutClasses from './homepage-layout.js'; import * as languageClasses from './language.js'; import * as newsEntryClasses from './news-entry.js'; +import * as sortingRuleClasses from './sorting-rule.js'; import * as staticPageClasses from './static-page.js'; import * as trackClasses from './track.js'; import * as wikiInfoClasses from './wiki-info.js'; @@ -31,6 +32,7 @@ const allClassLists = { 'homepage-layout.js': homepageLayoutClasses, 'language.js': languageClasses, 'news-entry.js': newsEntryClasses, + 'sorting-rule.js': sortingRuleClasses, 'static-page.js': staticPageClasses, 'track.js': trackClasses, 'wiki-info.js': wikiInfoClasses, diff --git a/src/data/things/sorting-rule.js b/src/data/things/sorting-rule.js new file mode 100644 index 00000000..88f37719 --- /dev/null +++ b/src/data/things/sorting-rule.js @@ -0,0 +1,139 @@ +export const SORTING_RULE_DATA_FILE = 'sorting-rules.yaml'; + +import {input} from '#composite'; +import Thing from '#thing'; +import {isStringNonEmpty, strictArrayOf} from '#validators'; +import {documentModes} from '#yaml'; + +import { + compareCaseLessSensitive, + sortByDate, + sortByDirectory, + sortByName, +} from '#sort'; + +import {flag} from '#composite/wiki-properties'; + +export class SortingRule extends Thing { + static [Thing.friendlyName] = `Sorting Rule`; + + static [Thing.getPropertyDescriptors] = () => ({ + // Update & expose + + active: flag(true), + }); + + static [Thing.yamlDocumentSpec] = { + fields: { + 'Active': {property: 'active'}, + }, + }; + + static [Thing.getYamlLoadingSpec] = ({ + documentModes: {allInOne}, + thingConstructors: {DocumentSortingRule}, + }) => ({ + title: `Process sorting rules file`, + file: SORTING_RULE_DATA_FILE, + + documentMode: allInOne, + documentThing: document => + (document['Sort Documents'] + ? DocumentSortingRule + : null), + + save: (results) => ({sortingRules: results}), + }); +} + +export class DocumentSortingRule extends SortingRule { + static [Thing.getPropertyDescriptors] = () => ({ + // Update & expose + + // TODO: glob :plead: + filename: { + flags: {update: true, expose: true}, + update: { + validate: isStringNonEmpty, + }, + }, + + properties: { + flags: {update: true, expose: true}, + update: { + validate: strictArrayOf(isStringNonEmpty), + }, + }, + }); + + static [Thing.yamlDocumentSpec] = Thing.extendDocumentSpec(SortingRule, { + fields: { + 'Sort Documents': {property: 'filename'}, + 'By Properties': {property: 'properties'}, + }, + }); + + apply(layout) { + const fresh = {...layout}; + + let sortable = null; + switch (fresh.documentMode) { + case documentModes.headerAndEntries: + sortable = fresh.entryThings = + fresh.entryThings.slice(); + break; + + case documentModes.allInOne: + sortable = fresh.things = + fresh.things.slice(); + break; + + default: + throw new Error(`Invalid document type for sorting`); + } + + if (this.properties) { + for (const property of this.properties.slice().reverse()) { + const get = thing => thing[property]; + const lc = property.toLowerCase(); + + if (lc.endsWith('date')) { + sortByDate(sortable, {getDate: get}); + continue; + } + + if (lc.endsWith('directory')) { + sortByDirectory(sortable, {getDirectory: get}); + continue; + } + + if (lc.endsWith('name')) { + sortByName(sortable, {getName: get}); + continue; + } + + const values = sortable.map(get); + + if (values.every(v => typeof v === 'string')) { + sortable.sort((a, b) => + compareCaseLessSensitive(get(a), get(b))); + continue; + } + + if (values.every(v => typeof v === 'number')) { + sortable.sort((a, b) => get(a) - get(b)); + continue; + } + + sortable.sort((a, b) => + (get(a).toString() < get(b).toString() + ? -1 + : get(a).toString() > get(b).toString() + ? +1 + : 0)); + } + } + + return fresh; + } +} diff --git a/src/upd8.js b/src/upd8.js index 93f09122..a3840424 100755 --- a/src/upd8.js +++ b/src/upd8.js @@ -1510,6 +1510,7 @@ async function main() { logThings('newsData', 'news entries'); } logThings('staticPageData', 'static pages'); + logThings('sortingRules', 'sorting rules'); if (wikiData.homepageLayout) { logInfo` - ${1} homepage layout (${ wikiData.homepageLayout.sections.length |