« get me outta code hell

hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/data/things/homepage-layout.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/things/homepage-layout.js')
-rw-r--r--src/data/things/homepage-layout.js114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/data/things/homepage-layout.js b/src/data/things/homepage-layout.js
new file mode 100644
index 0000000..5948ff4
--- /dev/null
+++ b/src/data/things/homepage-layout.js
@@ -0,0 +1,114 @@
+import Thing from './thing.js';
+
+import find from '../../util/find.js';
+
+export class HomepageLayout extends Thing {
+  static [Thing.getPropertyDescriptors] = ({
+    HomepageLayoutRow,
+
+    validators: {
+      validateArrayItems,
+      validateInstanceOf,
+    },
+  }) => ({
+    // Update & expose
+
+    sidebarContent: Thing.common.simpleString(),
+
+    rows: {
+      flags: {update: true, expose: true},
+
+      update: {
+        validate: validateArrayItems(validateInstanceOf(HomepageLayoutRow)),
+      },
+    },
+  })
+}
+
+export class HomepageLayoutRow extends Thing {
+  static [Thing.getPropertyDescriptors] = ({
+    Album,
+    Group,
+  }) => ({
+    // Update & expose
+
+    name: Thing.common.name('Unnamed Homepage Row'),
+
+    type: {
+      flags: {update: true, expose: true},
+
+      update: {
+        validate() {
+          throw new Error(`'type' property validator must be overridden`);
+        },
+      },
+    },
+
+    color: Thing.common.color(),
+
+    // Update only
+
+    // These aren't necessarily used by every HomepageLayoutRow subclass, but
+    // for convenience of providing this data, every row accepts all wiki data
+    // arrays depended upon by any subclass's behavior.
+    albumData: Thing.common.wikiData(Album),
+    groupData: Thing.common.wikiData(Group),
+  });
+}
+
+export class HomepageLayoutAlbumsRow extends HomepageLayoutRow {
+  static [Thing.getPropertyDescriptors] = (opts, {
+    Album,
+    Group,
+
+    validators: {
+      isCountingNumber,
+      isString,
+      validateArrayItems,
+    },
+  } = opts) => ({
+    ...HomepageLayoutRow[Thing.getPropertyDescriptors](opts),
+
+    // Update & expose
+
+    type: {
+      flags: {update: true, expose: true},
+      update: {
+        validate(value) {
+          if (value !== 'albums') {
+            throw new TypeError(`Expected 'albums'`);
+          }
+
+          return true;
+        },
+      },
+    },
+
+    sourceGroupByRef: Thing.common.singleReference(Group),
+    sourceAlbumsByRef: Thing.common.referenceList(Album),
+
+    countAlbumsFromGroup: {
+      flags: {update: true, expose: true},
+      update: {validate: isCountingNumber},
+    },
+
+    actionLinks: {
+      flags: {update: true, expose: true},
+      update: {validate: validateArrayItems(isString)},
+    },
+
+    // Expose only
+
+    sourceGroup: Thing.common.dynamicThingFromSingleReference(
+      'sourceGroupByRef',
+      'groupData',
+      find.group
+    ),
+
+    sourceAlbums: Thing.common.dynamicThingsFromReferenceList(
+      'sourceAlbumsByRef',
+      'albumData',
+      find.album
+    ),
+  });
+}