@beinformed/ui 1.43.5 → 1.43.7
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.
- package/CHANGELOG.md +14 -0
- package/esm/hooks/useModels.js +10 -4
- package/esm/hooks/useModels.js.map +1 -1
- package/esm/models/content/ContentLinkModel.js +7 -8
- package/esm/models/content/ContentLinkModel.js.map +1 -1
- package/esm/react-theme/createTheme.js +9 -0
- package/esm/react-theme/createTheme.js.map +1 -1
- package/lib/hooks/useModels.js +10 -4
- package/lib/hooks/useModels.js.flow +13 -6
- package/lib/hooks/useModels.js.map +1 -1
- package/lib/models/content/ContentLinkModel.js +7 -8
- package/lib/models/content/ContentLinkModel.js.flow +8 -12
- package/lib/models/content/ContentLinkModel.js.map +1 -1
- package/lib/models/content/__tests__/ContentIndexModel.spec.js.flow +37 -0
- package/lib/models/content/__tests__/ContentLinkModel.spec.js.flow +81 -0
- package/lib/react-theme/__tests__/ThemeProvider.spec.js.flow +17 -2
- package/lib/react-theme/createTheme.js +9 -0
- package/lib/react-theme/createTheme.js.flow +10 -0
- package/lib/react-theme/createTheme.js.map +1 -1
- package/package.json +1 -1
- package/src/hooks/useModels.js +13 -6
- package/src/models/content/ContentLinkModel.js +8 -12
- package/src/models/content/__tests__/ContentIndexModel.spec.js +37 -0
- package/src/models/content/__tests__/ContentLinkModel.spec.js +81 -0
- package/src/models/content/__tests__/content-index-contributions.json +50 -0
- package/src/models/content/__tests__/content-index.json +163 -0
- package/src/react-theme/__tests__/ThemeProvider.spec.js +17 -2
- package/src/react-theme/createTheme.js +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [1.43.7](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.43.6...v1.43.7) (2024-03-18)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **settings:** merge custom settings into default settings ([29fcc31](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/commit/29fcc312b70559cdd8ec52044087839e4bff91ec))
|
|
11
|
+
|
|
12
|
+
## [1.43.6](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.43.5...v1.43.6) (2024-03-13)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **content-link:** fix encoded selfhref ([91188c0](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/commit/91188c0251577484e70da12f9eebd64501b3a736))
|
|
18
|
+
|
|
5
19
|
## [1.43.5](https://git.beinformed.com/public/nl.beinformed.bi.layout.lib.ui/compare/v1.43.3...v1.43.5) (2024-03-13)
|
|
6
20
|
|
|
7
21
|
|
package/esm/hooks/useModels.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
|
2
2
|
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
|
3
|
-
import _Object$values from "@babel/runtime-corejs3/core-js-stable/object/values";
|
|
4
3
|
import { createSelector } from "reselect";
|
|
5
4
|
import { useSelector, useDispatch } from "react-redux";
|
|
6
5
|
import { reloadModel } from "../redux/_modularui/ModularUIActions";
|
|
@@ -12,8 +11,15 @@ export const useModels = () => {
|
|
|
12
11
|
const dispatch = useDispatch();
|
|
13
12
|
const selectModularUI = state => state.modularui;
|
|
14
13
|
const selector = createSelector([selectModularUI], modularui => {
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const models = [];
|
|
15
|
+
const keys = _Object$keys(modularui);
|
|
16
|
+
for (const key of keys) {
|
|
17
|
+
const model = modularui[key];
|
|
18
|
+
if (model?.status === MODULARUI_STATUS.FINISHED) {
|
|
19
|
+
models.push(model.model);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return models;
|
|
17
23
|
});
|
|
18
24
|
const modularuiModels = useSelector(selector);
|
|
19
25
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModels.js","names":["createSelector","useSelector","useDispatch","reloadModel","MODULARUI_STATUS","useModels","dispatch","selectModularUI","state","modularui","selector","
|
|
1
|
+
{"version":3,"file":"useModels.js","names":["createSelector","useSelector","useDispatch","reloadModel","MODULARUI_STATUS","useModels","dispatch","selectModularUI","state","modularui","selector","models","keys","_Object$keys","key","model","status","FINISHED","push","modularuiModels","reload","options","reloadWithFilter","callbackFn","modelsToReload","_filterInstanceProperty","call","modelToReload"],"sources":["../../src/hooks/useModels.js"],"sourcesContent":["// @flow\nimport { createSelector } from \"reselect\";\nimport { useSelector, useDispatch } from \"react-redux\";\n\nimport { reloadModel } from \"../redux/_modularui/ModularUIActions\";\nimport { MODULARUI_STATUS } from \"../constants/Constants\";\n\nimport type { ModularUIModel } from \"../models/types\";\nimport type { ReduxState, ModelEntry } from \"../redux\";\n\ntype ReloadCallback = (model: ModularUIModel) => boolean;\n\ntype UseModels = () => {\n reload: (model: ModularUIModel, options?: any) => void,\n reloadWithFilter: (callbackFn: ReloadCallback, options?: any) => void,\n};\n\n/**\n * Hook that contains the reload property that can be used to reload a model\n */\nexport const useModels: UseModels = () => {\n const dispatch = useDispatch();\n\n const selectModularUI = (state: ReduxState) => state.modularui;\n const selector = createSelector([selectModularUI], (modularui) => {\n const models = [];\n const keys = Object.keys(modularui);\n for (const key of keys) {\n const model: ModelEntry = modularui[key];\n if (model?.status === MODULARUI_STATUS.FINISHED) {\n models.push(model.model);\n }\n }\n return models;\n });\n\n const modularuiModels = useSelector(selector);\n\n return {\n reload: (model: ModularUIModel, options?: Object) => {\n dispatch(reloadModel(model, options));\n },\n reloadWithFilter: (callbackFn: ReloadCallback, options?: Object) => {\n const modelsToReload = modularuiModels.filter(callbackFn);\n for (const modelToReload of modelsToReload) {\n dispatch(reloadModel(modelToReload, options));\n }\n },\n };\n};\n"],"mappings":";;AACA,SAASA,cAAc,QAAQ,UAAU;AACzC,SAASC,WAAW,EAAEC,WAAW,QAAQ,aAAa;AAEtD,SAASC,WAAW,QAAQ,sCAAsC;AAClE,SAASC,gBAAgB,QAAQ,wBAAwB;AAYzD;AACA;AACA;AACA,OAAO,MAAMC,SAAoB,GAAGA,CAAA,KAAM;EACxC,MAAMC,QAAQ,GAAGJ,WAAW,CAAC,CAAC;EAE9B,MAAMK,eAAe,GAAIC,KAAiB,IAAKA,KAAK,CAACC,SAAS;EAC9D,MAAMC,QAAQ,GAAGV,cAAc,CAAC,CAACO,eAAe,CAAC,EAAGE,SAAS,IAAK;IAChE,MAAME,MAAM,GAAG,EAAE;IACjB,MAAMC,IAAI,GAAGC,YAAA,CAAYJ,SAAS,CAAC;IACnC,KAAK,MAAMK,GAAG,IAAIF,IAAI,EAAE;MACtB,MAAMG,KAAiB,GAAGN,SAAS,CAACK,GAAG,CAAC;MACxC,IAAIC,KAAK,EAAEC,MAAM,KAAKZ,gBAAgB,CAACa,QAAQ,EAAE;QAC/CN,MAAM,CAACO,IAAI,CAACH,KAAK,CAACA,KAAK,CAAC;MAC1B;IACF;IACA,OAAOJ,MAAM;EACf,CAAC,CAAC;EAEF,MAAMQ,eAAe,GAAGlB,WAAW,CAACS,QAAQ,CAAC;EAE7C,OAAO;IACLU,MAAM,EAAEA,CAACL,KAAqB,EAAEM,OAAgB,KAAK;MACnDf,QAAQ,CAACH,WAAW,CAACY,KAAK,EAAEM,OAAO,CAAC,CAAC;IACvC,CAAC;IACDC,gBAAgB,EAAEA,CAACC,UAA0B,EAAEF,OAAgB,KAAK;MAClE,MAAMG,cAAc,GAAGC,uBAAA,CAAAN,eAAe,EAAAO,IAAA,CAAfP,eAAe,EAAQI,UAAU,CAAC;MACzD,KAAK,MAAMI,aAAa,IAAIH,cAAc,EAAE;QAC1ClB,QAAQ,CAACH,WAAW,CAACwB,aAAa,EAAEN,OAAO,CAAC,CAAC;MAC/C;IACF;EACF,CAAC;AACH,CAAC","ignoreList":[]}
|
|
@@ -91,17 +91,16 @@ export default class ContentLinkModel extends BaseModel {
|
|
|
91
91
|
*/
|
|
92
92
|
createEncodedHref() {
|
|
93
93
|
const startURI = "/content/";
|
|
94
|
-
const
|
|
94
|
+
const selfHref = new Href(this.data._links.self.href);
|
|
95
|
+
const href = selfHref.path;
|
|
95
96
|
const section = this.data.section;
|
|
96
|
-
const sourceId = section ?
|
|
97
|
-
let hash = "";
|
|
98
|
-
if (selfhref.hash) {
|
|
99
|
-
hash = `#${selfhref.hash}`;
|
|
100
|
-
}
|
|
97
|
+
const sourceId = section ? href.substring(startURI.length, href.lastIndexOf("/")) : href.substring(startURI.length);
|
|
101
98
|
if (section) {
|
|
102
|
-
|
|
99
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;
|
|
100
|
+
} else {
|
|
101
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;
|
|
103
102
|
}
|
|
104
|
-
return
|
|
103
|
+
return selfHref;
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentLinkModel.js","names":["BaseModel","Href","LinkModel","ContentTypeModel","TIMEVERSION_FILTER_NAME","LinkCollection","ContentLinkModel","constructor","data","entryDate","arguments","length","undefined","_defineProperty","_entryDate","getInitialChildModelLinks","contentTypeLink","isCacheable","setChildModels","models","href","contentTypeModel","_findInstanceProperty","call","model","selfhref","equalsWithParameters","type","contentType","_contentType","key","getData","label","sourceLabel","createEncodedHref","startURI","_links","self","section","sourceId","substring","lastIndexOf","
|
|
1
|
+
{"version":3,"file":"ContentLinkModel.js","names":["BaseModel","Href","LinkModel","ContentTypeModel","TIMEVERSION_FILTER_NAME","LinkCollection","ContentLinkModel","constructor","data","entryDate","arguments","length","undefined","_defineProperty","_entryDate","getInitialChildModelLinks","contentTypeLink","isCacheable","setChildModels","models","href","contentTypeModel","_findInstanceProperty","call","model","selfhref","equalsWithParameters","type","contentType","_contentType","key","getData","label","sourceLabel","createEncodedHref","startURI","selfHref","_links","self","path","section","sourceId","substring","lastIndexOf","encodeURIComponent","encodedHref","addParameter","links","Array","isArray","selflink","getLinkByKey","Error","subSectionID","hash","contentTypeHref","items","_items"],"sources":["../../../src/models/content/ContentLinkModel.js"],"sourcesContent":["// @flow\nimport BaseModel from \"../base/BaseModel\";\nimport Href from \"../href/Href\";\nimport LinkModel from \"../links/LinkModel\";\nimport ContentTypeModel from \"./ContentTypeModel\";\nimport { TIMEVERSION_FILTER_NAME } from \"../../constants/Constants\";\n\nimport LinkCollection from \"../links/LinkCollection\";\n\nimport type { ModularUIModel, IModelWithChildModels } from \"../types\";\n\n/**\n * Link to a concept\n */\nexport default class ContentLinkModel\n extends BaseModel\n implements IModelWithChildModels\n{\n _links: ?LinkCollection;\n _entryDate: ?ISO_DATE;\n _contentType: ContentTypeModel | null = null;\n _items: Array<ContentLinkModel>;\n\n /**\n */\n constructor(data: Object, entryDate: ?ISO_DATE = null) {\n super(data, {});\n\n this._entryDate = entryDate;\n }\n\n /**\n */\n // $FlowFixMe[method-unbinding]\n getInitialChildModelLinks(): Array<LinkModel> {\n if (this.contentTypeLink) {\n this.contentTypeLink.isCacheable = true;\n return [this.contentTypeLink];\n }\n\n return [];\n }\n\n /**\n */\n // $FlowFixMe[method-unbinding]\n setChildModels(models: Array<ModularUIModel>) {\n if (this.contentTypeLink) {\n const href = this.contentTypeLink.href;\n const contentTypeModel = models.find((model) =>\n model.selfhref.equalsWithParameters(href),\n );\n\n if (contentTypeModel?.type === \"ContentType\") {\n this.contentType = contentTypeModel;\n }\n }\n }\n\n /**\n * Retrieve content type\n */\n get contentType(): ?ContentTypeModel | null {\n return this._contentType;\n }\n\n /**\n * Set concept type\n */\n set contentType(contentType: ?ModularUIModel) {\n this._contentType =\n contentType instanceof ContentTypeModel ? contentType : null;\n }\n\n /**\n */\n set entryDate(entryDate: ISO_DATE) {\n this._entryDate = entryDate;\n }\n\n /**\n * Retrieve key\n */\n get key(): string {\n return this.getData(\"_id\", \"\");\n }\n\n /**\n * Retrieve label\n */\n get label(): string {\n return this.getData(\"label\", \"\");\n }\n\n /**\n * Retrieve the label of the source a link to a section belongs to\n */\n get sourceLabel(): string | null {\n return this.getData(\"sourceLabel\");\n }\n\n /**\n */\n createEncodedHref(): Href {\n const startURI = \"/content/\";\n const selfHref = new Href(this.data._links.self.href);\n const href = selfHref.path;\n\n const section = this.data.section;\n const sourceId = section\n ? href.substring(startURI.length, href.lastIndexOf(\"/\"))\n : href.substring(startURI.length);\n\n if (section) {\n selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;\n } else {\n selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;\n }\n\n return selfHref;\n }\n\n /**\n * Encode the content-identifier of the path to the content resource.\n * This makes it a single uri part, which can be used on routes to make nested routes\n */\n get encodedHref(): Href {\n const href = this.createEncodedHref();\n\n if (this._entryDate !== null) {\n return href.addParameter(TIMEVERSION_FILTER_NAME, this._entryDate);\n }\n\n return href;\n }\n\n /**\n * Getting the links of the resource\n */\n get links(): LinkCollection {\n if (!this._links) {\n this._links = new LinkCollection(\n Array.isArray(this.data._links)\n ? this.data._links[0]\n : this.data._links,\n );\n }\n\n return this._links;\n }\n\n /**\n * Get self link of model\n */\n get selflink(): LinkModel {\n const selflink = this.links.getLinkByKey(\"self\");\n\n if (selflink === null) {\n throw new Error(\n `Could not find self link for ${\n this.key === null ? \"unknown\" : this.key\n }`,\n );\n }\n\n return selflink;\n }\n\n /**\n * Self href of concept\n */\n get selfhref(): Href {\n if (this._entryDate !== null) {\n return this.selflink.href.addParameter(\n TIMEVERSION_FILTER_NAME,\n this._entryDate,\n );\n }\n\n return this.selflink.href;\n }\n\n /**\n */\n get subSectionID(): string {\n return this.selfhref.hash;\n }\n\n /**\n */\n get contentTypeLink(): LinkModel | null {\n return this.links.getLinkByKey(\"contenttype\");\n }\n\n /**\n * Concept type href of concept\n */\n get contentTypeHref(): Href | null {\n if (this.contentTypeLink) {\n return this.contentTypeLink.href;\n }\n\n return null;\n }\n\n /**\n * Children of link model in TOC\n */\n set items(items: Array<ContentLinkModel>) {\n this._items = items;\n }\n\n /**\n */\n get items(): Array<ContentLinkModel> {\n return this._items;\n }\n}\n"],"mappings":";;AACA,OAAOA,SAAS,MAAM,mBAAmB;AACzC,OAAOC,IAAI,MAAM,cAAc;AAC/B,OAAOC,SAAS,MAAM,oBAAoB;AAC1C,OAAOC,gBAAgB,MAAM,oBAAoB;AACjD,SAASC,uBAAuB,QAAQ,2BAA2B;AAEnE,OAAOC,cAAc,MAAM,yBAAyB;AAIpD;AACA;AACA;AACA,eAAe,MAAMC,gBAAgB,SAC3BN,SAAS,CAEnB;EAME;AACF;EACEO,WAAWA,CAACC,IAAY,EAA+B;IAAA,IAA7BC,SAAoB,GAAAC,SAAA,CAAAC,MAAA,QAAAD,SAAA,QAAAE,SAAA,GAAAF,SAAA,MAAG,IAAI;IACnD,KAAK,CAACF,IAAI,EAAE,CAAC,CAAC,CAAC;IAACK,eAAA;IAAAA,eAAA;IAAAA,eAAA,uBANsB,IAAI;IAAAA,eAAA;IAQ1C,IAAI,CAACC,UAAU,GAAGL,SAAS;EAC7B;;EAEA;AACF;EACE;EACAM,yBAAyBA,CAAA,EAAqB;IAC5C,IAAI,IAAI,CAACC,eAAe,EAAE;MACxB,IAAI,CAACA,eAAe,CAACC,WAAW,GAAG,IAAI;MACvC,OAAO,CAAC,IAAI,CAACD,eAAe,CAAC;IAC/B;IAEA,OAAO,EAAE;EACX;;EAEA;AACF;EACE;EACAE,cAAcA,CAACC,MAA6B,EAAE;IAC5C,IAAI,IAAI,CAACH,eAAe,EAAE;MACxB,MAAMI,IAAI,GAAG,IAAI,CAACJ,eAAe,CAACI,IAAI;MACtC,MAAMC,gBAAgB,GAAGC,qBAAA,CAAAH,MAAM,EAAAI,IAAA,CAANJ,MAAM,EAAOK,KAAK,IACzCA,KAAK,CAACC,QAAQ,CAACC,oBAAoB,CAACN,IAAI,CAC1C,CAAC;MAED,IAAIC,gBAAgB,EAAEM,IAAI,KAAK,aAAa,EAAE;QAC5C,IAAI,CAACC,WAAW,GAAGP,gBAAgB;MACrC;IACF;EACF;;EAEA;AACF;AACA;EACE,IAAIO,WAAWA,CAAA,EAA6B;IAC1C,OAAO,IAAI,CAACC,YAAY;EAC1B;;EAEA;AACF;AACA;EACE,IAAID,WAAWA,CAACA,WAA4B,EAAE;IAC5C,IAAI,CAACC,YAAY,GACfD,WAAW,YAAYzB,gBAAgB,GAAGyB,WAAW,GAAG,IAAI;EAChE;;EAEA;AACF;EACE,IAAInB,SAASA,CAACA,SAAmB,EAAE;IACjC,IAAI,CAACK,UAAU,GAAGL,SAAS;EAC7B;;EAEA;AACF;AACA;EACE,IAAIqB,GAAGA,CAAA,EAAW;IAChB,OAAO,IAAI,CAACC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;EAChC;;EAEA;AACF;AACA;EACE,IAAIC,KAAKA,CAAA,EAAW;IAClB,OAAO,IAAI,CAACD,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;EAClC;;EAEA;AACF;AACA;EACE,IAAIE,WAAWA,CAAA,EAAkB;IAC/B,OAAO,IAAI,CAACF,OAAO,CAAC,aAAa,CAAC;EACpC;;EAEA;AACF;EACEG,iBAAiBA,CAAA,EAAS;IACxB,MAAMC,QAAQ,GAAG,WAAW;IAC5B,MAAMC,QAAQ,GAAG,IAAInC,IAAI,CAAC,IAAI,CAACO,IAAI,CAAC6B,MAAM,CAACC,IAAI,CAAClB,IAAI,CAAC;IACrD,MAAMA,IAAI,GAAGgB,QAAQ,CAACG,IAAI;IAE1B,MAAMC,OAAO,GAAG,IAAI,CAAChC,IAAI,CAACgC,OAAO;IACjC,MAAMC,QAAQ,GAAGD,OAAO,GACpBpB,IAAI,CAACsB,SAAS,CAACP,QAAQ,CAACxB,MAAM,EAAES,IAAI,CAACuB,WAAW,CAAC,GAAG,CAAC,CAAC,GACtDvB,IAAI,CAACsB,SAAS,CAACP,QAAQ,CAACxB,MAAM,CAAC;IAEnC,IAAI6B,OAAO,EAAE;MACXJ,QAAQ,CAACG,IAAI,GAAI,GAAEJ,QAAS,GAAES,kBAAkB,CAACH,QAAQ,CAAE,IAAGG,kBAAkB,CAACJ,OAAO,CAAE,EAAC;IAC7F,CAAC,MAAM;MACLJ,QAAQ,CAACG,IAAI,GAAI,GAAEJ,QAAS,GAAES,kBAAkB,CAACH,QAAQ,CAAE,EAAC;IAC9D;IAEA,OAAOL,QAAQ;EACjB;;EAEA;AACF;AACA;AACA;EACE,IAAIS,WAAWA,CAAA,EAAS;IACtB,MAAMzB,IAAI,GAAG,IAAI,CAACc,iBAAiB,CAAC,CAAC;IAErC,IAAI,IAAI,CAACpB,UAAU,KAAK,IAAI,EAAE;MAC5B,OAAOM,IAAI,CAAC0B,YAAY,CAAC1C,uBAAuB,EAAE,IAAI,CAACU,UAAU,CAAC;IACpE;IAEA,OAAOM,IAAI;EACb;;EAEA;AACF;AACA;EACE,IAAI2B,KAAKA,CAAA,EAAmB;IAC1B,IAAI,CAAC,IAAI,CAACV,MAAM,EAAE;MAChB,IAAI,CAACA,MAAM,GAAG,IAAIhC,cAAc,CAC9B2C,KAAK,CAACC,OAAO,CAAC,IAAI,CAACzC,IAAI,CAAC6B,MAAM,CAAC,GAC3B,IAAI,CAAC7B,IAAI,CAAC6B,MAAM,CAAC,CAAC,CAAC,GACnB,IAAI,CAAC7B,IAAI,CAAC6B,MAChB,CAAC;IACH;IAEA,OAAO,IAAI,CAACA,MAAM;EACpB;;EAEA;AACF;AACA;EACE,IAAIa,QAAQA,CAAA,EAAc;IACxB,MAAMA,QAAQ,GAAG,IAAI,CAACH,KAAK,CAACI,YAAY,CAAC,MAAM,CAAC;IAEhD,IAAID,QAAQ,KAAK,IAAI,EAAE;MACrB,MAAM,IAAIE,KAAK,CACZ,gCACC,IAAI,CAACtB,GAAG,KAAK,IAAI,GAAG,SAAS,GAAG,IAAI,CAACA,GACtC,EACH,CAAC;IACH;IAEA,OAAOoB,QAAQ;EACjB;;EAEA;AACF;AACA;EACE,IAAIzB,QAAQA,CAAA,EAAS;IACnB,IAAI,IAAI,CAACX,UAAU,KAAK,IAAI,EAAE;MAC5B,OAAO,IAAI,CAACoC,QAAQ,CAAC9B,IAAI,CAAC0B,YAAY,CACpC1C,uBAAuB,EACvB,IAAI,CAACU,UACP,CAAC;IACH;IAEA,OAAO,IAAI,CAACoC,QAAQ,CAAC9B,IAAI;EAC3B;;EAEA;AACF;EACE,IAAIiC,YAAYA,CAAA,EAAW;IACzB,OAAO,IAAI,CAAC5B,QAAQ,CAAC6B,IAAI;EAC3B;;EAEA;AACF;EACE,IAAItC,eAAeA,CAAA,EAAqB;IACtC,OAAO,IAAI,CAAC+B,KAAK,CAACI,YAAY,CAAC,aAAa,CAAC;EAC/C;;EAEA;AACF;AACA;EACE,IAAII,eAAeA,CAAA,EAAgB;IACjC,IAAI,IAAI,CAACvC,eAAe,EAAE;MACxB,OAAO,IAAI,CAACA,eAAe,CAACI,IAAI;IAClC;IAEA,OAAO,IAAI;EACb;;EAEA;AACF;AACA;EACE,IAAIoC,KAAKA,CAACA,KAA8B,EAAE;IACxC,IAAI,CAACC,MAAM,GAAGD,KAAK;EACrB;;EAEA;AACF;EACE,IAAIA,KAAKA,CAAA,EAA4B;IACnC,OAAO,IAAI,CAACC,MAAM;EACpB;AACF","ignoreList":[]}
|
|
@@ -19,6 +19,7 @@ const replacePlaceholders = inputTheme => {
|
|
|
19
19
|
return inputTheme;
|
|
20
20
|
};
|
|
21
21
|
const generateTheme = function (storedTheme) {
|
|
22
|
+
const storedSettings = storedTheme?.settings ?? {};
|
|
22
23
|
let generatedTheme = {
|
|
23
24
|
settings: {}
|
|
24
25
|
};
|
|
@@ -29,12 +30,20 @@ const generateTheme = function (storedTheme) {
|
|
|
29
30
|
if (typeof element === "function") {
|
|
30
31
|
generatedTheme = element(replacePlaceholders(generatedTheme));
|
|
31
32
|
} else if (isPlainObject(element)) {
|
|
33
|
+
const generatedSettings = generatedTheme.settings;
|
|
32
34
|
// $FlowFixMe[cannot-spread-indexer]
|
|
33
35
|
generatedTheme = {
|
|
34
36
|
...generatedTheme,
|
|
35
37
|
...element,
|
|
36
38
|
...storedTheme
|
|
37
39
|
};
|
|
40
|
+
if ("settings" in element) {
|
|
41
|
+
generatedTheme.settings = {
|
|
42
|
+
...generatedSettings,
|
|
43
|
+
...element.settings,
|
|
44
|
+
...storedSettings
|
|
45
|
+
};
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
48
|
}
|
|
40
49
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTheme.js","names":["flattenDeep","isPlainObject","setSettings","replacePlaceholders","inputTheme","_context","possibleKeys","_mapInstanceProperty","_Object$keys","call","key","join","re","RegExp","_Object$entries","forEach","_ref","value","replace","match","capture","generateTheme","storedTheme","
|
|
1
|
+
{"version":3,"file":"createTheme.js","names":["flattenDeep","isPlainObject","setSettings","replacePlaceholders","inputTheme","_context","possibleKeys","_mapInstanceProperty","_Object$keys","call","key","join","re","RegExp","_Object$entries","forEach","_ref","value","replace","match","capture","generateTheme","storedTheme","storedSettings","settings","generatedTheme","_len","arguments","length","themeElements","Array","_key","element","generatedSettings","createTheme","_len2","themeConfigs","_key2","customTheme"],"sources":["../../src/react-theme/createTheme.js"],"sourcesContent":["// @flow\nimport flattenDeep from \"lodash/flattenDeep\";\n\nimport { isPlainObject } from \"../utils/helpers/objects\";\n\nimport { setSettings } from \"../constants/Settings\";\n\nimport type { Theme } from \"./types\";\n\nconst replacePlaceholders = (inputTheme: Theme) => {\n const possibleKeys = Object.keys(inputTheme)\n .map((key) => `\\\\b${key}\\\\b`)\n .join(\"|\");\n\n const re = new RegExp(`\\\\$(${possibleKeys})`, \"g\");\n Object.entries(inputTheme).forEach(([key, value]) => {\n if (key !== \"settings\" && typeof value === \"string\") {\n inputTheme[key] = value.replace(\n re,\n // $FlowIssue[incompatible-call]\n (match, capture) => inputTheme[capture],\n );\n }\n });\n\n return inputTheme;\n};\n\nconst generateTheme = (storedTheme: Theme, ...themeElements: Array<Theme>) => {\n const storedSettings = storedTheme?.settings ?? {};\n\n let generatedTheme = { settings: {} };\n for (const element of themeElements) {\n if (typeof element === \"function\") {\n generatedTheme = element(replacePlaceholders(generatedTheme));\n } else if (isPlainObject(element)) {\n const generatedSettings = generatedTheme.settings;\n // $FlowFixMe[cannot-spread-indexer]\n generatedTheme = { ...generatedTheme, ...element, ...storedTheme };\n if (\"settings\" in element) {\n generatedTheme.settings = {\n ...generatedSettings,\n ...element.settings,\n ...storedSettings,\n };\n }\n }\n }\n\n // final - replace any assignments inside the theme\n return replacePlaceholders(generatedTheme);\n};\n\n/**\n * Create a theme from multiple theme configuration objects.\n * Properties are overwriten by iterating the configuration objects from left to right.\n *\n * The first argument represents a stored theme part, this is optional. The stored theme part will overwrite every part in the collection of theme parts.\n * Thus a stored configuration is leading as it can be configured by a modeller through the repository.\n *\n * Placeholders can be used, they are replaced before calling a function theme part or at the end of the theme creation.\n *\n * Both objects and function can be used, where a function receives the previous objects as input arguments.\n * For example using the method createTheme(ThemeObject, ThemeObject2, ThemeFunction, ThemeFunction2), will be handled as:\n *\n * ThemeFunction2(ThemeFunction1({ ...ThemeObject, ...ThemeObject2 }))\n *\n * @example\n * Example where the primary color of the default theme is overwritten with a primary color of the custom theme,\n * but the button bg still uses the yiq function of the default theme:\n *\n * const DefaultTheme = {\n * PRIMARY_COLOR: \"#0000ff\",\n * SECONDARY_COLOR: \"#00ff00\",\n * BUTTON_COLOR: \"$PRIMARY_COLOR\"\n * }\n *\n * const createDefaultTheme = (input) => ({\n * ...input,\n * BUTTON_BG: getContrastYIQ(input.BUTTON_COLOR)\n * })\n *\n * const CustomTheme = {\n * PRIMARY_COLOR: \"#ff0000\"\n * }\n *\n * createTheme(null, DefaultTheme, CustomTheme, createDefaultTheme);\n *\n * // Result:\n * {\n * PRIMARY_COLOR: \"#ff0000\",\n * BUTTON_COLOR: \"#ff0000\",\n * BUTTON_BG: \"#fff\",\n * SECONDARY_COLOR: \"#00ff00\",\n * }\n */\nconst createTheme = (\n storedTheme: Theme,\n ...themeConfigs: Array<Theme | Array<Theme> | void>\n):\n | any\n | {}\n | {\n INPUT_FOCUS_BORDER_COLOR?: string,\n LINK_HOVER_COLOR?: string,\n PAGING_HOVER_COLOR?: string,\n settings?: { [settingName: string]: string },\n } => {\n const customTheme = generateTheme(storedTheme, ...flattenDeep(themeConfigs));\n\n if (customTheme) {\n setSettings(customTheme.settings);\n }\n\n return customTheme;\n};\n\nexport default createTheme;\n"],"mappings":"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","ignoreList":[]}
|
package/lib/hooks/useModels.js
CHANGED
|
@@ -5,9 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.useModels = void 0;
|
|
8
|
-
var
|
|
8
|
+
var _keys = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/keys"));
|
|
9
9
|
var _filter = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/filter"));
|
|
10
|
-
var _values = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/object/values"));
|
|
11
10
|
var _reselect = require("reselect");
|
|
12
11
|
var _reactRedux = require("react-redux");
|
|
13
12
|
var _ModularUIActions = require("../redux/_modularui/ModularUIActions");
|
|
@@ -19,8 +18,15 @@ const useModels = () => {
|
|
|
19
18
|
const dispatch = (0, _reactRedux.useDispatch)();
|
|
20
19
|
const selectModularUI = state => state.modularui;
|
|
21
20
|
const selector = (0, _reselect.createSelector)([selectModularUI], modularui => {
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const models = [];
|
|
22
|
+
const keys = (0, _keys.default)(modularui);
|
|
23
|
+
for (const key of keys) {
|
|
24
|
+
const model = modularui[key];
|
|
25
|
+
if (model?.status === _Constants.MODULARUI_STATUS.FINISHED) {
|
|
26
|
+
models.push(model.model);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return models;
|
|
24
30
|
});
|
|
25
31
|
const modularuiModels = (0, _reactRedux.useSelector)(selector);
|
|
26
32
|
return {
|
|
@@ -6,7 +6,7 @@ import { reloadModel } from "../redux/_modularui/ModularUIActions";
|
|
|
6
6
|
import { MODULARUI_STATUS } from "../constants/Constants";
|
|
7
7
|
|
|
8
8
|
import type { ModularUIModel } from "../models/types";
|
|
9
|
-
import type { ReduxState } from "../redux";
|
|
9
|
+
import type { ReduxState, ModelEntry } from "../redux";
|
|
10
10
|
|
|
11
11
|
type ReloadCallback = (model: ModularUIModel) => boolean;
|
|
12
12
|
|
|
@@ -22,11 +22,18 @@ export const useModels: UseModels = () => {
|
|
|
22
22
|
const dispatch = useDispatch();
|
|
23
23
|
|
|
24
24
|
const selectModularUI = (state: ReduxState) => state.modularui;
|
|
25
|
-
const selector = createSelector([selectModularUI], (modularui) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const selector = createSelector([selectModularUI], (modularui) => {
|
|
26
|
+
const models = [];
|
|
27
|
+
const keys = Object.keys(modularui);
|
|
28
|
+
for (const key of keys) {
|
|
29
|
+
const model: ModelEntry = modularui[key];
|
|
30
|
+
if (model?.status === MODULARUI_STATUS.FINISHED) {
|
|
31
|
+
models.push(model.model);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return models;
|
|
35
|
+
});
|
|
36
|
+
|
|
30
37
|
const modularuiModels = useSelector(selector);
|
|
31
38
|
|
|
32
39
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useModels.js","names":["_reselect","require","_reactRedux","_ModularUIActions","_Constants","useModels","dispatch","useDispatch","selectModularUI","state","modularui","selector","createSelector","
|
|
1
|
+
{"version":3,"file":"useModels.js","names":["_reselect","require","_reactRedux","_ModularUIActions","_Constants","useModels","dispatch","useDispatch","selectModularUI","state","modularui","selector","createSelector","models","keys","_keys","default","key","model","status","MODULARUI_STATUS","FINISHED","push","modularuiModels","useSelector","reload","options","reloadModel","reloadWithFilter","callbackFn","modelsToReload","_filter","call","modelToReload","exports"],"sources":["../../src/hooks/useModels.js"],"sourcesContent":["// @flow\nimport { createSelector } from \"reselect\";\nimport { useSelector, useDispatch } from \"react-redux\";\n\nimport { reloadModel } from \"../redux/_modularui/ModularUIActions\";\nimport { MODULARUI_STATUS } from \"../constants/Constants\";\n\nimport type { ModularUIModel } from \"../models/types\";\nimport type { ReduxState, ModelEntry } from \"../redux\";\n\ntype ReloadCallback = (model: ModularUIModel) => boolean;\n\ntype UseModels = () => {\n reload: (model: ModularUIModel, options?: any) => void,\n reloadWithFilter: (callbackFn: ReloadCallback, options?: any) => void,\n};\n\n/**\n * Hook that contains the reload property that can be used to reload a model\n */\nexport const useModels: UseModels = () => {\n const dispatch = useDispatch();\n\n const selectModularUI = (state: ReduxState) => state.modularui;\n const selector = createSelector([selectModularUI], (modularui) => {\n const models = [];\n const keys = Object.keys(modularui);\n for (const key of keys) {\n const model: ModelEntry = modularui[key];\n if (model?.status === MODULARUI_STATUS.FINISHED) {\n models.push(model.model);\n }\n }\n return models;\n });\n\n const modularuiModels = useSelector(selector);\n\n return {\n reload: (model: ModularUIModel, options?: Object) => {\n dispatch(reloadModel(model, options));\n },\n reloadWithFilter: (callbackFn: ReloadCallback, options?: Object) => {\n const modelsToReload = modularuiModels.filter(callbackFn);\n for (const modelToReload of modelsToReload) {\n dispatch(reloadModel(modelToReload, options));\n }\n },\n };\n};\n"],"mappings":";;;;;;;;;AACA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,WAAA,GAAAD,OAAA;AAEA,IAAAE,iBAAA,GAAAF,OAAA;AACA,IAAAG,UAAA,GAAAH,OAAA;AAYA;AACA;AACA;AACO,MAAMI,SAAoB,GAAGA,CAAA,KAAM;EACxC,MAAMC,QAAQ,GAAG,IAAAC,uBAAW,EAAC,CAAC;EAE9B,MAAMC,eAAe,GAAIC,KAAiB,IAAKA,KAAK,CAACC,SAAS;EAC9D,MAAMC,QAAQ,GAAG,IAAAC,wBAAc,EAAC,CAACJ,eAAe,CAAC,EAAGE,SAAS,IAAK;IAChE,MAAMG,MAAM,GAAG,EAAE;IACjB,MAAMC,IAAI,GAAG,IAAAC,KAAA,CAAAC,OAAA,EAAYN,SAAS,CAAC;IACnC,KAAK,MAAMO,GAAG,IAAIH,IAAI,EAAE;MACtB,MAAMI,KAAiB,GAAGR,SAAS,CAACO,GAAG,CAAC;MACxC,IAAIC,KAAK,EAAEC,MAAM,KAAKC,2BAAgB,CAACC,QAAQ,EAAE;QAC/CR,MAAM,CAACS,IAAI,CAACJ,KAAK,CAACA,KAAK,CAAC;MAC1B;IACF;IACA,OAAOL,MAAM;EACf,CAAC,CAAC;EAEF,MAAMU,eAAe,GAAG,IAAAC,uBAAW,EAACb,QAAQ,CAAC;EAE7C,OAAO;IACLc,MAAM,EAAEA,CAACP,KAAqB,EAAEQ,OAAgB,KAAK;MACnDpB,QAAQ,CAAC,IAAAqB,6BAAW,EAACT,KAAK,EAAEQ,OAAO,CAAC,CAAC;IACvC,CAAC;IACDE,gBAAgB,EAAEA,CAACC,UAA0B,EAAEH,OAAgB,KAAK;MAClE,MAAMI,cAAc,GAAG,IAAAC,OAAA,CAAAf,OAAA,EAAAO,eAAe,EAAAS,IAAA,CAAfT,eAAe,EAAQM,UAAU,CAAC;MACzD,KAAK,MAAMI,aAAa,IAAIH,cAAc,EAAE;QAC1CxB,QAAQ,CAAC,IAAAqB,6BAAW,EAACM,aAAa,EAAEP,OAAO,CAAC,CAAC;MAC/C;IACF;EACF,CAAC;AACH,CAAC;AAACQ,OAAA,CAAA7B,SAAA,GAAAA,SAAA","ignoreList":[]}
|
|
@@ -98,17 +98,16 @@ class ContentLinkModel extends _BaseModel.default {
|
|
|
98
98
|
*/
|
|
99
99
|
createEncodedHref() {
|
|
100
100
|
const startURI = "/content/";
|
|
101
|
-
const
|
|
101
|
+
const selfHref = new _Href.default(this.data._links.self.href);
|
|
102
|
+
const href = selfHref.path;
|
|
102
103
|
const section = this.data.section;
|
|
103
|
-
const sourceId = section ?
|
|
104
|
-
let hash = "";
|
|
105
|
-
if (selfhref.hash) {
|
|
106
|
-
hash = `#${selfhref.hash}`;
|
|
107
|
-
}
|
|
104
|
+
const sourceId = section ? href.substring(startURI.length, href.lastIndexOf("/")) : href.substring(startURI.length);
|
|
108
105
|
if (section) {
|
|
109
|
-
|
|
106
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;
|
|
107
|
+
} else {
|
|
108
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;
|
|
110
109
|
}
|
|
111
|
-
return
|
|
110
|
+
return selfHref;
|
|
112
111
|
}
|
|
113
112
|
|
|
114
113
|
/**
|
|
@@ -103,25 +103,21 @@ export default class ContentLinkModel
|
|
|
103
103
|
*/
|
|
104
104
|
createEncodedHref(): Href {
|
|
105
105
|
const startURI = "/content/";
|
|
106
|
-
const
|
|
106
|
+
const selfHref = new Href(this.data._links.self.href);
|
|
107
|
+
const href = selfHref.path;
|
|
107
108
|
|
|
108
109
|
const section = this.data.section;
|
|
109
110
|
const sourceId = section
|
|
110
|
-
?
|
|
111
|
-
:
|
|
112
|
-
|
|
113
|
-
let hash = "";
|
|
114
|
-
if (selfhref.hash) {
|
|
115
|
-
hash = `#${selfhref.hash}`;
|
|
116
|
-
}
|
|
111
|
+
? href.substring(startURI.length, href.lastIndexOf("/"))
|
|
112
|
+
: href.substring(startURI.length);
|
|
117
113
|
|
|
118
114
|
if (section) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
)
|
|
115
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;
|
|
116
|
+
} else {
|
|
117
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
return
|
|
120
|
+
return selfHref;
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentLinkModel.js","names":["_BaseModel","_interopRequireDefault","require","_Href","_LinkModel","_ContentTypeModel","_Constants","_LinkCollection","ContentLinkModel","BaseModel","constructor","data","entryDate","arguments","length","undefined","_defineProperty2","default","_entryDate","getInitialChildModelLinks","contentTypeLink","isCacheable","setChildModels","models","href","contentTypeModel","_find","call","model","selfhref","equalsWithParameters","type","contentType","_contentType","ContentTypeModel","key","getData","label","sourceLabel","createEncodedHref","startURI","_links","self","section","sourceId","substring","lastIndexOf","
|
|
1
|
+
{"version":3,"file":"ContentLinkModel.js","names":["_BaseModel","_interopRequireDefault","require","_Href","_LinkModel","_ContentTypeModel","_Constants","_LinkCollection","ContentLinkModel","BaseModel","constructor","data","entryDate","arguments","length","undefined","_defineProperty2","default","_entryDate","getInitialChildModelLinks","contentTypeLink","isCacheable","setChildModels","models","href","contentTypeModel","_find","call","model","selfhref","equalsWithParameters","type","contentType","_contentType","ContentTypeModel","key","getData","label","sourceLabel","createEncodedHref","startURI","selfHref","Href","_links","self","path","section","sourceId","substring","lastIndexOf","encodeURIComponent","encodedHref","addParameter","TIMEVERSION_FILTER_NAME","links","LinkCollection","Array","isArray","selflink","getLinkByKey","Error","subSectionID","hash","contentTypeHref","items","_items","exports"],"sources":["../../../src/models/content/ContentLinkModel.js"],"sourcesContent":["// @flow\nimport BaseModel from \"../base/BaseModel\";\nimport Href from \"../href/Href\";\nimport LinkModel from \"../links/LinkModel\";\nimport ContentTypeModel from \"./ContentTypeModel\";\nimport { TIMEVERSION_FILTER_NAME } from \"../../constants/Constants\";\n\nimport LinkCollection from \"../links/LinkCollection\";\n\nimport type { ModularUIModel, IModelWithChildModels } from \"../types\";\n\n/**\n * Link to a concept\n */\nexport default class ContentLinkModel\n extends BaseModel\n implements IModelWithChildModels\n{\n _links: ?LinkCollection;\n _entryDate: ?ISO_DATE;\n _contentType: ContentTypeModel | null = null;\n _items: Array<ContentLinkModel>;\n\n /**\n */\n constructor(data: Object, entryDate: ?ISO_DATE = null) {\n super(data, {});\n\n this._entryDate = entryDate;\n }\n\n /**\n */\n // $FlowFixMe[method-unbinding]\n getInitialChildModelLinks(): Array<LinkModel> {\n if (this.contentTypeLink) {\n this.contentTypeLink.isCacheable = true;\n return [this.contentTypeLink];\n }\n\n return [];\n }\n\n /**\n */\n // $FlowFixMe[method-unbinding]\n setChildModels(models: Array<ModularUIModel>) {\n if (this.contentTypeLink) {\n const href = this.contentTypeLink.href;\n const contentTypeModel = models.find((model) =>\n model.selfhref.equalsWithParameters(href),\n );\n\n if (contentTypeModel?.type === \"ContentType\") {\n this.contentType = contentTypeModel;\n }\n }\n }\n\n /**\n * Retrieve content type\n */\n get contentType(): ?ContentTypeModel | null {\n return this._contentType;\n }\n\n /**\n * Set concept type\n */\n set contentType(contentType: ?ModularUIModel) {\n this._contentType =\n contentType instanceof ContentTypeModel ? contentType : null;\n }\n\n /**\n */\n set entryDate(entryDate: ISO_DATE) {\n this._entryDate = entryDate;\n }\n\n /**\n * Retrieve key\n */\n get key(): string {\n return this.getData(\"_id\", \"\");\n }\n\n /**\n * Retrieve label\n */\n get label(): string {\n return this.getData(\"label\", \"\");\n }\n\n /**\n * Retrieve the label of the source a link to a section belongs to\n */\n get sourceLabel(): string | null {\n return this.getData(\"sourceLabel\");\n }\n\n /**\n */\n createEncodedHref(): Href {\n const startURI = \"/content/\";\n const selfHref = new Href(this.data._links.self.href);\n const href = selfHref.path;\n\n const section = this.data.section;\n const sourceId = section\n ? href.substring(startURI.length, href.lastIndexOf(\"/\"))\n : href.substring(startURI.length);\n\n if (section) {\n selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;\n } else {\n selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;\n }\n\n return selfHref;\n }\n\n /**\n * Encode the content-identifier of the path to the content resource.\n * This makes it a single uri part, which can be used on routes to make nested routes\n */\n get encodedHref(): Href {\n const href = this.createEncodedHref();\n\n if (this._entryDate !== null) {\n return href.addParameter(TIMEVERSION_FILTER_NAME, this._entryDate);\n }\n\n return href;\n }\n\n /**\n * Getting the links of the resource\n */\n get links(): LinkCollection {\n if (!this._links) {\n this._links = new LinkCollection(\n Array.isArray(this.data._links)\n ? this.data._links[0]\n : this.data._links,\n );\n }\n\n return this._links;\n }\n\n /**\n * Get self link of model\n */\n get selflink(): LinkModel {\n const selflink = this.links.getLinkByKey(\"self\");\n\n if (selflink === null) {\n throw new Error(\n `Could not find self link for ${\n this.key === null ? \"unknown\" : this.key\n }`,\n );\n }\n\n return selflink;\n }\n\n /**\n * Self href of concept\n */\n get selfhref(): Href {\n if (this._entryDate !== null) {\n return this.selflink.href.addParameter(\n TIMEVERSION_FILTER_NAME,\n this._entryDate,\n );\n }\n\n return this.selflink.href;\n }\n\n /**\n */\n get subSectionID(): string {\n return this.selfhref.hash;\n }\n\n /**\n */\n get contentTypeLink(): LinkModel | null {\n return this.links.getLinkByKey(\"contenttype\");\n }\n\n /**\n * Concept type href of concept\n */\n get contentTypeHref(): Href | null {\n if (this.contentTypeLink) {\n return this.contentTypeLink.href;\n }\n\n return null;\n }\n\n /**\n * Children of link model in TOC\n */\n set items(items: Array<ContentLinkModel>) {\n this._items = items;\n }\n\n /**\n */\n get items(): Array<ContentLinkModel> {\n return this._items;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import ContentIndexModel from "../ContentIndexModel";
|
|
2
|
+
|
|
3
|
+
import data from "./content-index.json";
|
|
4
|
+
import contributions from "./content-index-contributions.json";
|
|
5
|
+
import ModularUIResponse from "../../../modularui/ModularUIResponse";
|
|
6
|
+
import ContentLinkModel from "../ContentLinkModel";
|
|
7
|
+
|
|
8
|
+
describe("content index model", () => {
|
|
9
|
+
it("should be able to create an empty ContentIndexModel object", () => {
|
|
10
|
+
const model = new ContentIndexModel();
|
|
11
|
+
|
|
12
|
+
expect(model).toBeInstanceOf(ContentIndexModel);
|
|
13
|
+
expect(model.type).toBe("ContentIndex");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("can handle a search result", () => {
|
|
17
|
+
const response = ModularUIResponse.create({
|
|
18
|
+
key: "contentindexmodel",
|
|
19
|
+
data,
|
|
20
|
+
contributions,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(ContentIndexModel.isApplicableModel(response)).toBe(true);
|
|
24
|
+
|
|
25
|
+
const contentIndexModel = new ContentIndexModel(response);
|
|
26
|
+
expect(contentIndexModel.label).toBe("content");
|
|
27
|
+
|
|
28
|
+
expect(contentIndexModel.items).toHaveLength(1);
|
|
29
|
+
|
|
30
|
+
const firstLink = contentIndexModel.items.first;
|
|
31
|
+
expect(firstLink).toBeInstanceOf(ContentLinkModel);
|
|
32
|
+
|
|
33
|
+
expect(firstLink.encodedHref.toString()).toBe(
|
|
34
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import ContentLinkModel from "../ContentLinkModel";
|
|
2
|
+
|
|
3
|
+
describe("content link model", () => {
|
|
4
|
+
it("should be able to create an empty ContentLinkModel object", () => {
|
|
5
|
+
const contentLinkModel = new ContentLinkModel();
|
|
6
|
+
|
|
7
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("can handle href to source", () => {
|
|
11
|
+
const contentLinkModel = new ContentLinkModel({
|
|
12
|
+
_id: "/Content/Sources/Formal/Another formal content.formalsource",
|
|
13
|
+
label: "Another formal content",
|
|
14
|
+
_links: {
|
|
15
|
+
self: {
|
|
16
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
17
|
+
name: "self",
|
|
18
|
+
},
|
|
19
|
+
contenttype: {
|
|
20
|
+
href: "/contenttypes/Content/Source%20types/Content%20type%20definitions.bixml/Policy",
|
|
21
|
+
name: "contenttype",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
27
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
28
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
29
|
+
);
|
|
30
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
31
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("can handle href to source section", () => {
|
|
36
|
+
const contentLinkModel = new ContentLinkModel({
|
|
37
|
+
_links: {
|
|
38
|
+
self: {
|
|
39
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource/section-id.%3A-",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
_id: "section-id.:-",
|
|
43
|
+
label: "Another formal content Section",
|
|
44
|
+
section: "section-id.:-",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
48
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
49
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource/section-id.%3A-",
|
|
50
|
+
);
|
|
51
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
52
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource/section-id.%3A-",
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("can handle href to source with hash", () => {
|
|
57
|
+
const contentLinkModel = new ContentLinkModel({
|
|
58
|
+
_id: "/Content/Sources/Formal/Another formal content.formalsource#hashid",
|
|
59
|
+
label: "Another formal content",
|
|
60
|
+
_links: {
|
|
61
|
+
self: {
|
|
62
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource#hashid",
|
|
63
|
+
name: "self",
|
|
64
|
+
},
|
|
65
|
+
contenttype: {
|
|
66
|
+
href: "/contenttypes/Content/Source%20types/Content%20type%20definitions.bixml/Policy",
|
|
67
|
+
name: "contenttype",
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
73
|
+
|
|
74
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
75
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
76
|
+
);
|
|
77
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
78
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -5,6 +5,10 @@ import { getContrastYIQ } from "../utils/contrast";
|
|
|
5
5
|
describe("themeProvider", () => {
|
|
6
6
|
it("tests configuration as found in ThemeProvider.js, with stored theme", () => {
|
|
7
7
|
const DefaultTheme = {
|
|
8
|
+
settings: {
|
|
9
|
+
SettingA: "ValueA",
|
|
10
|
+
SettingOVerride: "DefaultValue",
|
|
11
|
+
},
|
|
8
12
|
PRIMARY_ACCENT_COLOR: "#0d3256",
|
|
9
13
|
APPLICATION_LABEL_COLOR: "$PRIMARY_ACCENT_COLOR",
|
|
10
14
|
PRIMARY_COLOR: "#0000ff",
|
|
@@ -18,6 +22,10 @@ describe("themeProvider", () => {
|
|
|
18
22
|
});
|
|
19
23
|
|
|
20
24
|
const CustomThemeFromRepo = {
|
|
25
|
+
settings: {
|
|
26
|
+
SettingB: "ValueB",
|
|
27
|
+
SettingOVerride: "CustomValue",
|
|
28
|
+
},
|
|
21
29
|
BRAND_COLOR: "green",
|
|
22
30
|
APPLICATION_LABEL_COLOR: "$BRAND_COLOR",
|
|
23
31
|
PRIMARY_COLOR: "red",
|
|
@@ -29,7 +37,11 @@ describe("themeProvider", () => {
|
|
|
29
37
|
]);
|
|
30
38
|
|
|
31
39
|
expect(theme).toStrictEqual({
|
|
32
|
-
settings: {
|
|
40
|
+
settings: {
|
|
41
|
+
SettingA: "ValueA",
|
|
42
|
+
SettingB: "ValueB",
|
|
43
|
+
SettingOVerride: "CustomValue",
|
|
44
|
+
},
|
|
33
45
|
APPLICATION_LABEL_COLOR: "green",
|
|
34
46
|
BRAND_COLOR: "green",
|
|
35
47
|
BUTTON_BG: "#fff",
|
|
@@ -42,6 +54,9 @@ describe("themeProvider", () => {
|
|
|
42
54
|
|
|
43
55
|
it("tests configuration as found in ThemeProvider.js, without stored theme", () => {
|
|
44
56
|
const DefaultTheme = {
|
|
57
|
+
settings: {
|
|
58
|
+
SettingA: "ValueA",
|
|
59
|
+
},
|
|
45
60
|
PRIMARY_ACCENT_COLOR: "#0d3256",
|
|
46
61
|
APPLICATION_LABEL_COLOR: "$PRIMARY_ACCENT_COLOR",
|
|
47
62
|
PRIMARY_COLOR: "#0000ff",
|
|
@@ -57,7 +72,7 @@ describe("themeProvider", () => {
|
|
|
57
72
|
const theme = createTheme(void 0, [DefaultTheme, createDefaultTheme]);
|
|
58
73
|
|
|
59
74
|
expect(theme).toStrictEqual({
|
|
60
|
-
settings: {},
|
|
75
|
+
settings: { SettingA: "ValueA" },
|
|
61
76
|
APPLICATION_LABEL_COLOR: "#0d3256",
|
|
62
77
|
BUTTON_BG: "#fff",
|
|
63
78
|
BUTTON_COLOR: "#0000ff",
|
|
@@ -26,6 +26,7 @@ const replacePlaceholders = inputTheme => {
|
|
|
26
26
|
return inputTheme;
|
|
27
27
|
};
|
|
28
28
|
const generateTheme = function (storedTheme) {
|
|
29
|
+
const storedSettings = storedTheme?.settings ?? {};
|
|
29
30
|
let generatedTheme = {
|
|
30
31
|
settings: {}
|
|
31
32
|
};
|
|
@@ -36,12 +37,20 @@ const generateTheme = function (storedTheme) {
|
|
|
36
37
|
if (typeof element === "function") {
|
|
37
38
|
generatedTheme = element(replacePlaceholders(generatedTheme));
|
|
38
39
|
} else if ((0, _objects.isPlainObject)(element)) {
|
|
40
|
+
const generatedSettings = generatedTheme.settings;
|
|
39
41
|
// $FlowFixMe[cannot-spread-indexer]
|
|
40
42
|
generatedTheme = {
|
|
41
43
|
...generatedTheme,
|
|
42
44
|
...element,
|
|
43
45
|
...storedTheme
|
|
44
46
|
};
|
|
47
|
+
if ("settings" in element) {
|
|
48
|
+
generatedTheme.settings = {
|
|
49
|
+
...generatedSettings,
|
|
50
|
+
...element.settings,
|
|
51
|
+
...storedSettings
|
|
52
|
+
};
|
|
53
|
+
}
|
|
45
54
|
}
|
|
46
55
|
}
|
|
47
56
|
|
|
@@ -27,13 +27,23 @@ const replacePlaceholders = (inputTheme: Theme) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const generateTheme = (storedTheme: Theme, ...themeElements: Array<Theme>) => {
|
|
30
|
+
const storedSettings = storedTheme?.settings ?? {};
|
|
31
|
+
|
|
30
32
|
let generatedTheme = { settings: {} };
|
|
31
33
|
for (const element of themeElements) {
|
|
32
34
|
if (typeof element === "function") {
|
|
33
35
|
generatedTheme = element(replacePlaceholders(generatedTheme));
|
|
34
36
|
} else if (isPlainObject(element)) {
|
|
37
|
+
const generatedSettings = generatedTheme.settings;
|
|
35
38
|
// $FlowFixMe[cannot-spread-indexer]
|
|
36
39
|
generatedTheme = { ...generatedTheme, ...element, ...storedTheme };
|
|
40
|
+
if ("settings" in element) {
|
|
41
|
+
generatedTheme.settings = {
|
|
42
|
+
...generatedSettings,
|
|
43
|
+
...element.settings,
|
|
44
|
+
...storedSettings,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createTheme.js","names":["_flattenDeep","_interopRequireDefault","require","_objects","_Settings","replacePlaceholders","inputTheme","_context","possibleKeys","_map","default","_keys","call","key","join","re","RegExp","_entries","forEach","_ref","value","replace","match","capture","generateTheme","storedTheme","
|
|
1
|
+
{"version":3,"file":"createTheme.js","names":["_flattenDeep","_interopRequireDefault","require","_objects","_Settings","replacePlaceholders","inputTheme","_context","possibleKeys","_map","default","_keys","call","key","join","re","RegExp","_entries","forEach","_ref","value","replace","match","capture","generateTheme","storedTheme","storedSettings","settings","generatedTheme","_len","arguments","length","themeElements","Array","_key","element","isPlainObject","generatedSettings","createTheme","_len2","themeConfigs","_key2","customTheme","flattenDeep","setSettings","_default","exports"],"sources":["../../src/react-theme/createTheme.js"],"sourcesContent":["// @flow\nimport flattenDeep from \"lodash/flattenDeep\";\n\nimport { isPlainObject } from \"../utils/helpers/objects\";\n\nimport { setSettings } from \"../constants/Settings\";\n\nimport type { Theme } from \"./types\";\n\nconst replacePlaceholders = (inputTheme: Theme) => {\n const possibleKeys = Object.keys(inputTheme)\n .map((key) => `\\\\b${key}\\\\b`)\n .join(\"|\");\n\n const re = new RegExp(`\\\\$(${possibleKeys})`, \"g\");\n Object.entries(inputTheme).forEach(([key, value]) => {\n if (key !== \"settings\" && typeof value === \"string\") {\n inputTheme[key] = value.replace(\n re,\n // $FlowIssue[incompatible-call]\n (match, capture) => inputTheme[capture],\n );\n }\n });\n\n return inputTheme;\n};\n\nconst generateTheme = (storedTheme: Theme, ...themeElements: Array<Theme>) => {\n const storedSettings = storedTheme?.settings ?? {};\n\n let generatedTheme = { settings: {} };\n for (const element of themeElements) {\n if (typeof element === \"function\") {\n generatedTheme = element(replacePlaceholders(generatedTheme));\n } else if (isPlainObject(element)) {\n const generatedSettings = generatedTheme.settings;\n // $FlowFixMe[cannot-spread-indexer]\n generatedTheme = { ...generatedTheme, ...element, ...storedTheme };\n if (\"settings\" in element) {\n generatedTheme.settings = {\n ...generatedSettings,\n ...element.settings,\n ...storedSettings,\n };\n }\n }\n }\n\n // final - replace any assignments inside the theme\n return replacePlaceholders(generatedTheme);\n};\n\n/**\n * Create a theme from multiple theme configuration objects.\n * Properties are overwriten by iterating the configuration objects from left to right.\n *\n * The first argument represents a stored theme part, this is optional. The stored theme part will overwrite every part in the collection of theme parts.\n * Thus a stored configuration is leading as it can be configured by a modeller through the repository.\n *\n * Placeholders can be used, they are replaced before calling a function theme part or at the end of the theme creation.\n *\n * Both objects and function can be used, where a function receives the previous objects as input arguments.\n * For example using the method createTheme(ThemeObject, ThemeObject2, ThemeFunction, ThemeFunction2), will be handled as:\n *\n * ThemeFunction2(ThemeFunction1({ ...ThemeObject, ...ThemeObject2 }))\n *\n * @example\n * Example where the primary color of the default theme is overwritten with a primary color of the custom theme,\n * but the button bg still uses the yiq function of the default theme:\n *\n * const DefaultTheme = {\n * PRIMARY_COLOR: \"#0000ff\",\n * SECONDARY_COLOR: \"#00ff00\",\n * BUTTON_COLOR: \"$PRIMARY_COLOR\"\n * }\n *\n * const createDefaultTheme = (input) => ({\n * ...input,\n * BUTTON_BG: getContrastYIQ(input.BUTTON_COLOR)\n * })\n *\n * const CustomTheme = {\n * PRIMARY_COLOR: \"#ff0000\"\n * }\n *\n * createTheme(null, DefaultTheme, CustomTheme, createDefaultTheme);\n *\n * // Result:\n * {\n * PRIMARY_COLOR: \"#ff0000\",\n * BUTTON_COLOR: \"#ff0000\",\n * BUTTON_BG: \"#fff\",\n * SECONDARY_COLOR: \"#00ff00\",\n * }\n */\nconst createTheme = (\n storedTheme: Theme,\n ...themeConfigs: Array<Theme | Array<Theme> | void>\n):\n | any\n | {}\n | {\n INPUT_FOCUS_BORDER_COLOR?: string,\n LINK_HOVER_COLOR?: string,\n PAGING_HOVER_COLOR?: string,\n settings?: { [settingName: string]: string },\n } => {\n const customTheme = generateTheme(storedTheme, ...flattenDeep(themeConfigs));\n\n if (customTheme) {\n setSettings(customTheme.settings);\n }\n\n return customTheme;\n};\n\nexport default createTheme;\n"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
package/src/hooks/useModels.js
CHANGED
|
@@ -6,7 +6,7 @@ import { reloadModel } from "../redux/_modularui/ModularUIActions";
|
|
|
6
6
|
import { MODULARUI_STATUS } from "../constants/Constants";
|
|
7
7
|
|
|
8
8
|
import type { ModularUIModel } from "../models/types";
|
|
9
|
-
import type { ReduxState } from "../redux";
|
|
9
|
+
import type { ReduxState, ModelEntry } from "../redux";
|
|
10
10
|
|
|
11
11
|
type ReloadCallback = (model: ModularUIModel) => boolean;
|
|
12
12
|
|
|
@@ -22,11 +22,18 @@ export const useModels: UseModels = () => {
|
|
|
22
22
|
const dispatch = useDispatch();
|
|
23
23
|
|
|
24
24
|
const selectModularUI = (state: ReduxState) => state.modularui;
|
|
25
|
-
const selector = createSelector([selectModularUI], (modularui) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const selector = createSelector([selectModularUI], (modularui) => {
|
|
26
|
+
const models = [];
|
|
27
|
+
const keys = Object.keys(modularui);
|
|
28
|
+
for (const key of keys) {
|
|
29
|
+
const model: ModelEntry = modularui[key];
|
|
30
|
+
if (model?.status === MODULARUI_STATUS.FINISHED) {
|
|
31
|
+
models.push(model.model);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return models;
|
|
35
|
+
});
|
|
36
|
+
|
|
30
37
|
const modularuiModels = useSelector(selector);
|
|
31
38
|
|
|
32
39
|
return {
|
|
@@ -103,25 +103,21 @@ export default class ContentLinkModel
|
|
|
103
103
|
*/
|
|
104
104
|
createEncodedHref(): Href {
|
|
105
105
|
const startURI = "/content/";
|
|
106
|
-
const
|
|
106
|
+
const selfHref = new Href(this.data._links.self.href);
|
|
107
|
+
const href = selfHref.path;
|
|
107
108
|
|
|
108
109
|
const section = this.data.section;
|
|
109
110
|
const sourceId = section
|
|
110
|
-
?
|
|
111
|
-
:
|
|
112
|
-
|
|
113
|
-
let hash = "";
|
|
114
|
-
if (selfhref.hash) {
|
|
115
|
-
hash = `#${selfhref.hash}`;
|
|
116
|
-
}
|
|
111
|
+
? href.substring(startURI.length, href.lastIndexOf("/"))
|
|
112
|
+
: href.substring(startURI.length);
|
|
117
113
|
|
|
118
114
|
if (section) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
)
|
|
115
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}/${encodeURIComponent(section)}`;
|
|
116
|
+
} else {
|
|
117
|
+
selfHref.path = `${startURI}${encodeURIComponent(sourceId)}`;
|
|
122
118
|
}
|
|
123
119
|
|
|
124
|
-
return
|
|
120
|
+
return selfHref;
|
|
125
121
|
}
|
|
126
122
|
|
|
127
123
|
/**
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import ContentIndexModel from "../ContentIndexModel";
|
|
2
|
+
|
|
3
|
+
import data from "./content-index.json";
|
|
4
|
+
import contributions from "./content-index-contributions.json";
|
|
5
|
+
import ModularUIResponse from "../../../modularui/ModularUIResponse";
|
|
6
|
+
import ContentLinkModel from "../ContentLinkModel";
|
|
7
|
+
|
|
8
|
+
describe("content index model", () => {
|
|
9
|
+
it("should be able to create an empty ContentIndexModel object", () => {
|
|
10
|
+
const model = new ContentIndexModel();
|
|
11
|
+
|
|
12
|
+
expect(model).toBeInstanceOf(ContentIndexModel);
|
|
13
|
+
expect(model.type).toBe("ContentIndex");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("can handle a search result", () => {
|
|
17
|
+
const response = ModularUIResponse.create({
|
|
18
|
+
key: "contentindexmodel",
|
|
19
|
+
data,
|
|
20
|
+
contributions,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
expect(ContentIndexModel.isApplicableModel(response)).toBe(true);
|
|
24
|
+
|
|
25
|
+
const contentIndexModel = new ContentIndexModel(response);
|
|
26
|
+
expect(contentIndexModel.label).toBe("content");
|
|
27
|
+
|
|
28
|
+
expect(contentIndexModel.items).toHaveLength(1);
|
|
29
|
+
|
|
30
|
+
const firstLink = contentIndexModel.items.first;
|
|
31
|
+
expect(firstLink).toBeInstanceOf(ContentLinkModel);
|
|
32
|
+
|
|
33
|
+
expect(firstLink.encodedHref.toString()).toBe(
|
|
34
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import ContentLinkModel from "../ContentLinkModel";
|
|
2
|
+
|
|
3
|
+
describe("content link model", () => {
|
|
4
|
+
it("should be able to create an empty ContentLinkModel object", () => {
|
|
5
|
+
const contentLinkModel = new ContentLinkModel();
|
|
6
|
+
|
|
7
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("can handle href to source", () => {
|
|
11
|
+
const contentLinkModel = new ContentLinkModel({
|
|
12
|
+
_id: "/Content/Sources/Formal/Another formal content.formalsource",
|
|
13
|
+
label: "Another formal content",
|
|
14
|
+
_links: {
|
|
15
|
+
self: {
|
|
16
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
17
|
+
name: "self",
|
|
18
|
+
},
|
|
19
|
+
contenttype: {
|
|
20
|
+
href: "/contenttypes/Content/Source%20types/Content%20type%20definitions.bixml/Policy",
|
|
21
|
+
name: "contenttype",
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
27
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
28
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
29
|
+
);
|
|
30
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
31
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("can handle href to source section", () => {
|
|
36
|
+
const contentLinkModel = new ContentLinkModel({
|
|
37
|
+
_links: {
|
|
38
|
+
self: {
|
|
39
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource/section-id.%3A-",
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
_id: "section-id.:-",
|
|
43
|
+
label: "Another formal content Section",
|
|
44
|
+
section: "section-id.:-",
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
48
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
49
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource/section-id.%3A-",
|
|
50
|
+
);
|
|
51
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
52
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource/section-id.%3A-",
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("can handle href to source with hash", () => {
|
|
57
|
+
const contentLinkModel = new ContentLinkModel({
|
|
58
|
+
_id: "/Content/Sources/Formal/Another formal content.formalsource#hashid",
|
|
59
|
+
label: "Another formal content",
|
|
60
|
+
_links: {
|
|
61
|
+
self: {
|
|
62
|
+
href: "/content/Content/Sources/Formal/Another%20formal%20content.formalsource#hashid",
|
|
63
|
+
name: "self",
|
|
64
|
+
},
|
|
65
|
+
contenttype: {
|
|
66
|
+
href: "/contenttypes/Content/Source%20types/Content%20type%20definitions.bixml/Policy",
|
|
67
|
+
name: "contenttype",
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
expect(contentLinkModel).toBeInstanceOf(ContentLinkModel);
|
|
73
|
+
|
|
74
|
+
expect(contentLinkModel.selfhref.toString()).toBe(
|
|
75
|
+
"/content/Content/Sources/Formal/Another%20formal%20content.formalsource",
|
|
76
|
+
);
|
|
77
|
+
expect(contentLinkModel.encodedHref.toString()).toBe(
|
|
78
|
+
"/content/Content%2FSources%2FFormal%2FAnother%2520formal%2520content.formalsource",
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"content": {
|
|
3
|
+
"label": "content",
|
|
4
|
+
"resourcetype": "ContentSearch",
|
|
5
|
+
"filter": [
|
|
6
|
+
{
|
|
7
|
+
"index": {
|
|
8
|
+
"type": "choicefilter",
|
|
9
|
+
"label": "Index",
|
|
10
|
+
"layouthint": ["combobox"],
|
|
11
|
+
"multiplechoice": false,
|
|
12
|
+
"optionMode": "dynamic"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"label": {
|
|
17
|
+
"type": "stringfilter",
|
|
18
|
+
"label": "Label",
|
|
19
|
+
"multiplechoice": false
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": {
|
|
24
|
+
"type": "choicefilter",
|
|
25
|
+
"label": "Type",
|
|
26
|
+
"layouthint": ["checkbox"],
|
|
27
|
+
"multiplechoice": true,
|
|
28
|
+
"optionMode": "dynamic"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"results": {
|
|
33
|
+
"content": {
|
|
34
|
+
"metadata": {
|
|
35
|
+
"_id": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"attributes": [
|
|
40
|
+
{
|
|
41
|
+
"label": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"label": "content label"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
{
|
|
2
|
+
"content": {
|
|
3
|
+
"_links": {
|
|
4
|
+
"self": {
|
|
5
|
+
"href": "/content"
|
|
6
|
+
},
|
|
7
|
+
"api_doc": {
|
|
8
|
+
"href": "/api-docs/v3/content"
|
|
9
|
+
},
|
|
10
|
+
"contributions": {
|
|
11
|
+
"href": "/contributions/content"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dynamicschema": {
|
|
15
|
+
"index": [
|
|
16
|
+
{
|
|
17
|
+
"code": "A",
|
|
18
|
+
"label": "A"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"code": "B",
|
|
22
|
+
"label": "B"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"code": "C",
|
|
26
|
+
"label": "C"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"code": "L",
|
|
30
|
+
"label": "L"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"code": "N",
|
|
34
|
+
"label": "N"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"code": "R",
|
|
38
|
+
"label": "R"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"code": "S",
|
|
42
|
+
"label": "S"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"code": "T",
|
|
46
|
+
"label": "T"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"code": "U",
|
|
50
|
+
"label": "U"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"code": "X",
|
|
54
|
+
"label": "X"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"type": [
|
|
58
|
+
{
|
|
59
|
+
"code": "/Content/Source types/Source type definitions.bixml/Law",
|
|
60
|
+
"label": "Law"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"code": "/Content/Source types/Content type definitions.bixml/Memo",
|
|
64
|
+
"label": "Memo"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"code": "/Content/Source types/Content type definitions.bixml/Policy",
|
|
68
|
+
"label": "Policy"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"code": "/Content/Source types/Content type definitions.bixml/Regulation",
|
|
72
|
+
"label": "Regulation"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"code": "untyped",
|
|
76
|
+
"label": "Untyped"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"filter": {
|
|
81
|
+
"index": {
|
|
82
|
+
"param": "index",
|
|
83
|
+
"name": "index",
|
|
84
|
+
"options": [
|
|
85
|
+
{
|
|
86
|
+
"key": "A",
|
|
87
|
+
"selected": true
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"key": "B"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"key": "C"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"key": "L"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"key": "N"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"key": "R"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"key": "S"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"key": "T"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"key": "U"
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"key": "X"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
"label": {
|
|
119
|
+
"param": "label",
|
|
120
|
+
"name": "label"
|
|
121
|
+
},
|
|
122
|
+
"type": {
|
|
123
|
+
"param": "type",
|
|
124
|
+
"name": "type",
|
|
125
|
+
"options": [
|
|
126
|
+
{
|
|
127
|
+
"key": "/Content/Source types/Source type definitions.bixml/Law"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"key": "/Content/Source types/Content type definitions.bixml/Memo"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"key": "/Content/Source types/Content type definitions.bixml/Policy"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"key": "/Content/Source types/Content type definitions.bixml/Regulation"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"key": "untyped"
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"_embedded": {
|
|
145
|
+
"results": [
|
|
146
|
+
{
|
|
147
|
+
"content": {
|
|
148
|
+
"_id": "/Content/Sources/Formal/Another formal content.formalsource",
|
|
149
|
+
"label": "Another formal content",
|
|
150
|
+
"_links": {
|
|
151
|
+
"self": {
|
|
152
|
+
"href": "/content/Content/Sources/Formal/Another%20formal%20content.formalsource"
|
|
153
|
+
},
|
|
154
|
+
"contenttype": {
|
|
155
|
+
"href": "/contenttypes/Content/Source%20types/Content%20type%20definitions.bixml/Policy"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
@@ -5,6 +5,10 @@ import { getContrastYIQ } from "../utils/contrast";
|
|
|
5
5
|
describe("themeProvider", () => {
|
|
6
6
|
it("tests configuration as found in ThemeProvider.js, with stored theme", () => {
|
|
7
7
|
const DefaultTheme = {
|
|
8
|
+
settings: {
|
|
9
|
+
SettingA: "ValueA",
|
|
10
|
+
SettingOVerride: "DefaultValue",
|
|
11
|
+
},
|
|
8
12
|
PRIMARY_ACCENT_COLOR: "#0d3256",
|
|
9
13
|
APPLICATION_LABEL_COLOR: "$PRIMARY_ACCENT_COLOR",
|
|
10
14
|
PRIMARY_COLOR: "#0000ff",
|
|
@@ -18,6 +22,10 @@ describe("themeProvider", () => {
|
|
|
18
22
|
});
|
|
19
23
|
|
|
20
24
|
const CustomThemeFromRepo = {
|
|
25
|
+
settings: {
|
|
26
|
+
SettingB: "ValueB",
|
|
27
|
+
SettingOVerride: "CustomValue",
|
|
28
|
+
},
|
|
21
29
|
BRAND_COLOR: "green",
|
|
22
30
|
APPLICATION_LABEL_COLOR: "$BRAND_COLOR",
|
|
23
31
|
PRIMARY_COLOR: "red",
|
|
@@ -29,7 +37,11 @@ describe("themeProvider", () => {
|
|
|
29
37
|
]);
|
|
30
38
|
|
|
31
39
|
expect(theme).toStrictEqual({
|
|
32
|
-
settings: {
|
|
40
|
+
settings: {
|
|
41
|
+
SettingA: "ValueA",
|
|
42
|
+
SettingB: "ValueB",
|
|
43
|
+
SettingOVerride: "CustomValue",
|
|
44
|
+
},
|
|
33
45
|
APPLICATION_LABEL_COLOR: "green",
|
|
34
46
|
BRAND_COLOR: "green",
|
|
35
47
|
BUTTON_BG: "#fff",
|
|
@@ -42,6 +54,9 @@ describe("themeProvider", () => {
|
|
|
42
54
|
|
|
43
55
|
it("tests configuration as found in ThemeProvider.js, without stored theme", () => {
|
|
44
56
|
const DefaultTheme = {
|
|
57
|
+
settings: {
|
|
58
|
+
SettingA: "ValueA",
|
|
59
|
+
},
|
|
45
60
|
PRIMARY_ACCENT_COLOR: "#0d3256",
|
|
46
61
|
APPLICATION_LABEL_COLOR: "$PRIMARY_ACCENT_COLOR",
|
|
47
62
|
PRIMARY_COLOR: "#0000ff",
|
|
@@ -57,7 +72,7 @@ describe("themeProvider", () => {
|
|
|
57
72
|
const theme = createTheme(void 0, [DefaultTheme, createDefaultTheme]);
|
|
58
73
|
|
|
59
74
|
expect(theme).toStrictEqual({
|
|
60
|
-
settings: {},
|
|
75
|
+
settings: { SettingA: "ValueA" },
|
|
61
76
|
APPLICATION_LABEL_COLOR: "#0d3256",
|
|
62
77
|
BUTTON_BG: "#fff",
|
|
63
78
|
BUTTON_COLOR: "#0000ff",
|
|
@@ -27,13 +27,23 @@ const replacePlaceholders = (inputTheme: Theme) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const generateTheme = (storedTheme: Theme, ...themeElements: Array<Theme>) => {
|
|
30
|
+
const storedSettings = storedTheme?.settings ?? {};
|
|
31
|
+
|
|
30
32
|
let generatedTheme = { settings: {} };
|
|
31
33
|
for (const element of themeElements) {
|
|
32
34
|
if (typeof element === "function") {
|
|
33
35
|
generatedTheme = element(replacePlaceholders(generatedTheme));
|
|
34
36
|
} else if (isPlainObject(element)) {
|
|
37
|
+
const generatedSettings = generatedTheme.settings;
|
|
35
38
|
// $FlowFixMe[cannot-spread-indexer]
|
|
36
39
|
generatedTheme = { ...generatedTheme, ...element, ...storedTheme };
|
|
40
|
+
if ("settings" in element) {
|
|
41
|
+
generatedTheme.settings = {
|
|
42
|
+
...generatedSettings,
|
|
43
|
+
...element.settings,
|
|
44
|
+
...storedSettings,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
37
47
|
}
|
|
38
48
|
}
|
|
39
49
|
|