@museumwnf/viewer-core 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE.md +44 -44
  2. package/README.md +658 -635
  3. package/package.json +50 -50
  4. package/src/AppRoot.vue +58 -58
  5. package/src/catalogue/dates.js +209 -209
  6. package/src/catalogue/facets.js +61 -61
  7. package/src/catalogue/keywordIndex.js +289 -289
  8. package/src/catalogue/listQuery.js +100 -100
  9. package/src/catalogue/pagination.js +57 -57
  10. package/src/catalogue/searchLanguage.js +32 -32
  11. package/src/catalogue/timeline.js +220 -220
  12. package/src/composables/useCatalogueData.js +141 -141
  13. package/src/composables/useDataPackage.js +98 -98
  14. package/src/composables/useEntities.js +100 -100
  15. package/src/composables/useRecordLanguage.js +71 -71
  16. package/src/conventions.js +252 -148
  17. package/src/createViewer.js +29 -29
  18. package/src/i18n/I18nText.vue +17 -17
  19. package/src/i18n/I18nTextInline.vue +17 -17
  20. package/src/i18n/index.js +88 -88
  21. package/src/i18n/language.js +127 -127
  22. package/src/i18n/markdown.js +265 -265
  23. package/src/index.js +51 -50
  24. package/src/injectionKeys.js +1 -1
  25. package/src/languages.js +49 -49
  26. package/src/legacy/index.js +58 -58
  27. package/src/record/collectionTree.js +307 -307
  28. package/src/record/derivations.js +154 -154
  29. package/src/record/partners.js +87 -87
  30. package/src/record/recordSheet.js +231 -231
  31. package/src/rights.js +53 -53
  32. package/src/router/index.js +138 -138
  33. package/src/siteConfig.js +37 -37
  34. package/src/styles/base.css +49 -49
  35. package/src/testing/checkOfferedLanguages.js +67 -67
  36. package/src/testing/index.js +3 -3
  37. package/src/testing/smoke.js +103 -103
  38. package/src/testing/viteConfig.js +72 -90
  39. package/src/views/DetailView.vue +53 -53
  40. package/src/views/HomeView.vue +20 -20
  41. package/src/views/ListView.vue +61 -61
  42. package/src/views/NotFoundView.vue +8 -8
  43. package/src/vite.js +8 -8
@@ -1,61 +1,61 @@
1
- import { computed, toValue } from 'vue'
2
-
3
- // The options a filter offers are the values the records in front of it
4
- // actually carry, labelled, sorted, and nothing else: a country no item is
5
- // from is not offered. Every results page derives that from its records —
6
- // the standalone sites copied the derivation into the entrance and the
7
- // results view of each site, the DXA sites wrote it over tags — and the one
8
- // real difference between them is which records they pass: all of them
9
- // (standalone), or the ones that survive the current filters (DXA, where
10
- // picking a country shrinks the type list). Both are legacy behaviours, and
11
- // both stay the caller's choice: this reads whatever records it is handed.
12
-
13
- const compareLabels = (a, b) => a.label.localeCompare(b.label)
14
-
15
- function valuesOf(record, spec) {
16
- if (typeof spec.values === 'function') return [spec.values(record)].flat()
17
- const raw = record?.[spec.field]
18
- return Array.isArray(raw) ? raw : [raw]
19
- }
20
-
21
- function capitalize(text) {
22
- const label = String(text ?? '')
23
- return label.charAt(0).toUpperCase() + label.slice(1)
24
- }
25
-
26
- /**
27
- * `{ [facet]: [{ value, label }] }` from `records`, one entry per facet of
28
- * `spec`. A facet is `{ field }` (the record property holding the value or
29
- * the values) or `{ values(record) }`, plus `label(value)` — the site's own
30
- * label helper, so a country reads as its name — and optionally
31
- * `include(value)` to keep some values only (a tag of one category),
32
- * `sort` (`'label'`, the default; a comparator over `{ value, label }`; or
33
- * `'none'` for the order met), and `capitalize` for the legacy upper-cased
34
- * first letter of a tag label.
35
- */
36
- export function facetOptions(records, spec) {
37
- const out = {}
38
- for (const [facet, definition] of Object.entries(spec ?? {})) {
39
- const seen = new Map()
40
- for (const record of records ?? []) {
41
- for (const value of valuesOf(record, definition)) {
42
- if (value == null || value === '' || seen.has(value)) continue
43
- if (definition.include && !definition.include(value, record)) continue
44
- let label = definition.label ? definition.label(value, record) : String(value)
45
- if (definition.capitalize) label = capitalize(label)
46
- seen.set(value, { value, label: String(label ?? value) })
47
- }
48
- }
49
- const options = [...seen.values()]
50
- const sort = definition.sort ?? 'label'
51
- if (sort === 'label') options.sort(compareLabels)
52
- else if (typeof sort === 'function') options.sort(sort)
53
- out[facet] = options
54
- }
55
- return out
56
- }
57
-
58
- /** `facetOptions` over a reactive record source. */
59
- export function useFacets(records, spec) {
60
- return computed(() => facetOptions(toValue(records), toValue(spec)))
61
- }
1
+ import { computed, toValue } from 'vue'
2
+
3
+ // The options a filter offers are the values the records in front of it
4
+ // actually carry, labelled, sorted, and nothing else: a country no item is
5
+ // from is not offered. Every results page derives that from its records —
6
+ // the standalone sites copied the derivation into the entrance and the
7
+ // results view of each site, the DXA sites wrote it over tags — and the one
8
+ // real difference between them is which records they pass: all of them
9
+ // (standalone), or the ones that survive the current filters (DXA, where
10
+ // picking a country shrinks the type list). Both are legacy behaviours, and
11
+ // both stay the caller's choice: this reads whatever records it is handed.
12
+
13
+ const compareLabels = (a, b) => a.label.localeCompare(b.label)
14
+
15
+ function valuesOf(record, spec) {
16
+ if (typeof spec.values === 'function') return [spec.values(record)].flat()
17
+ const raw = record?.[spec.field]
18
+ return Array.isArray(raw) ? raw : [raw]
19
+ }
20
+
21
+ function capitalize(text) {
22
+ const label = String(text ?? '')
23
+ return label.charAt(0).toUpperCase() + label.slice(1)
24
+ }
25
+
26
+ /**
27
+ * `{ [facet]: [{ value, label }] }` from `records`, one entry per facet of
28
+ * `spec`. A facet is `{ field }` (the record property holding the value or
29
+ * the values) or `{ values(record) }`, plus `label(value)` — the site's own
30
+ * label helper, so a country reads as its name — and optionally
31
+ * `include(value)` to keep some values only (a tag of one category),
32
+ * `sort` (`'label'`, the default; a comparator over `{ value, label }`; or
33
+ * `'none'` for the order met), and `capitalize` for the legacy upper-cased
34
+ * first letter of a tag label.
35
+ */
36
+ export function facetOptions(records, spec) {
37
+ const out = {}
38
+ for (const [facet, definition] of Object.entries(spec ?? {})) {
39
+ const seen = new Map()
40
+ for (const record of records ?? []) {
41
+ for (const value of valuesOf(record, definition)) {
42
+ if (value == null || value === '' || seen.has(value)) continue
43
+ if (definition.include && !definition.include(value, record)) continue
44
+ let label = definition.label ? definition.label(value, record) : String(value)
45
+ if (definition.capitalize) label = capitalize(label)
46
+ seen.set(value, { value, label: String(label ?? value) })
47
+ }
48
+ }
49
+ const options = [...seen.values()]
50
+ const sort = definition.sort ?? 'label'
51
+ if (sort === 'label') options.sort(compareLabels)
52
+ else if (typeof sort === 'function') options.sort(sort)
53
+ out[facet] = options
54
+ }
55
+ return out
56
+ }
57
+
58
+ /** `facetOptions` over a reactive record source. */
59
+ export function useFacets(records, spec) {
60
+ return computed(() => facetOptions(toValue(records), toValue(spec)))
61
+ }