« get me outta code hell

generateListingIndexList.js « dependencies « content « src - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/content/dependencies/generateListingIndexList.js
blob: ed153652b3e3ed2a28f162c57f8691c3710290ad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import {empty, stitchArrays} from '#sugar';

export default {
  contentDependencies: ['linkListing'],
  extraDependencies: ['html', 'language', 'wikiData'],

  sprawl({listingTargetSpec, wikiInfo}) {
    return {listingTargetSpec, wikiInfo};
  },

  query(sprawl) {
    const query = {};

    const targetListings =
      sprawl.listingTargetSpec
        .map(({listings}) =>
          listings
            .filter(listing =>
              !listing.featureFlag ||
              sprawl.wikiInfo[listing.featureFlag]));

    query.targets =
      sprawl.listingTargetSpec
        .filter((target, index) => !empty(targetListings[index]));

    query.targetListings =
      targetListings
        .filter(listings => !empty(listings))

    return query;
  },

  relations(relation, query) {
    return {
      listingLinks:
        query.targetListings
          .map(listings =>
            listings.map(listing => relation('linkListing', listing))),
    };
  },

  data(query, sprawl, currentListing) {
    const data = {};

    data.targetStringsKeys =
      query.targets
        .map(({stringsKey}) => stringsKey);

    data.listingStringsKeys =
      query.targetListings
        .map(listings =>
          listings.map(({stringsKey}) => stringsKey));

    if (currentListing) {
      data.currentTargetIndex =
        query.targets
          .indexOf(currentListing.target);

      data.currentListingIndex =
        query.targetListings
          .find(listings => listings.includes(currentListing))
          .indexOf(currentListing);
    }

    return data;
  },

  slots: {
    mode: {validate: v => v.is('content', 'sidebar')},
  },

  generate(data, relations, slots, {html, language}) {
    const listingLinkLists =
      stitchArrays({
        listingLinks: relations.listingLinks,
        listingStringsKeys: data.listingStringsKeys,
      }).map(({listingLinks, listingStringsKeys}, targetIndex) =>
          html.tag('ul',
            stitchArrays({
              listingLink: listingLinks,
              listingStringsKey: listingStringsKeys,
            }).map(({listingLink, listingStringsKey}, listingIndex) =>
                html.tag('li',
                  targetIndex === data.currentTargetIndex &&
                  listingIndex === data.currentListingIndex &&
                    {class: 'current'},

                  listingLink.slots({
                    content:
                      language.$('listingPage', listingStringsKey, 'title.short'),
                  })))));

    const targetTitles =
      data.targetStringsKeys
        .map(stringsKey => language.$('listingPage.target', stringsKey));

    switch (slots.mode) {
      case 'sidebar':
        return html.tags(
          stitchArrays({
            targetTitle: targetTitles,
            listingLinkList: listingLinkLists,
          }).map(({targetTitle, listingLinkList}, targetIndex) =>
              html.tag('details',
                targetIndex === data.currentTargetIndex &&
                  {class: 'current', open: true},

                [
                  html.tag('summary',
                    html.tag('span', {class: 'group-name'},
                      targetTitle)),

                  listingLinkList,
                ])));

      case 'content':
        return (
          html.tag('dl',
            stitchArrays({
              targetTitle: targetTitles,
              listingLinkList: listingLinkLists,
            }).map(({targetTitle, listingLinkList}) => [
                html.tag('dt', {class: 'content-heading'},
                  targetTitle),

                html.tag('dd',
                  listingLinkList),
              ])));
    }
  },
};