@beinformed/ui 1.43.6 → 1.44.0

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 (46) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/esm/models/attributes/AttributeModel.js +0 -7
  3. package/esm/models/attributes/AttributeModel.js.map +1 -1
  4. package/esm/models/attributes/ChoiceAttributeModel.js +22 -24
  5. package/esm/models/attributes/ChoiceAttributeModel.js.map +1 -1
  6. package/esm/models/attributes/ChoiceAttributeOptionCollection.js +2 -1
  7. package/esm/models/attributes/ChoiceAttributeOptionCollection.js.map +1 -1
  8. package/esm/models/attributes/ChoiceAttributeOptionModel.js +8 -0
  9. package/esm/models/attributes/ChoiceAttributeOptionModel.js.map +1 -1
  10. package/esm/models/detail/DetailModel.js +2 -6
  11. package/esm/models/detail/DetailModel.js.map +1 -1
  12. package/esm/models/user/UserModel.js.map +1 -1
  13. package/esm/react-theme/createTheme.js +9 -0
  14. package/esm/react-theme/createTheme.js.map +1 -1
  15. package/lib/models/attributes/AttributeModel.js +0 -7
  16. package/lib/models/attributes/AttributeModel.js.flow +0 -7
  17. package/lib/models/attributes/AttributeModel.js.map +1 -1
  18. package/lib/models/attributes/ChoiceAttributeModel.js +22 -24
  19. package/lib/models/attributes/ChoiceAttributeModel.js.flow +6 -10
  20. package/lib/models/attributes/ChoiceAttributeModel.js.map +1 -1
  21. package/lib/models/attributes/ChoiceAttributeOptionCollection.js +2 -1
  22. package/lib/models/attributes/ChoiceAttributeOptionCollection.js.flow +1 -0
  23. package/lib/models/attributes/ChoiceAttributeOptionCollection.js.map +1 -1
  24. package/lib/models/attributes/ChoiceAttributeOptionModel.js +8 -0
  25. package/lib/models/attributes/ChoiceAttributeOptionModel.js.flow +9 -0
  26. package/lib/models/attributes/ChoiceAttributeOptionModel.js.map +1 -1
  27. package/lib/models/attributes/__tests__/ChoiceAttributeModel.spec.js.flow +27 -0
  28. package/lib/models/detail/DetailModel.js +2 -6
  29. package/lib/models/detail/DetailModel.js.flow +8 -16
  30. package/lib/models/detail/DetailModel.js.map +1 -1
  31. package/lib/models/user/UserModel.js.flow +1 -1
  32. package/lib/models/user/UserModel.js.map +1 -1
  33. package/lib/react-theme/__tests__/ThemeProvider.spec.js.flow +17 -2
  34. package/lib/react-theme/createTheme.js +9 -0
  35. package/lib/react-theme/createTheme.js.flow +10 -0
  36. package/lib/react-theme/createTheme.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/models/attributes/AttributeModel.js +0 -7
  39. package/src/models/attributes/ChoiceAttributeModel.js +6 -10
  40. package/src/models/attributes/ChoiceAttributeOptionCollection.js +1 -0
  41. package/src/models/attributes/ChoiceAttributeOptionModel.js +9 -0
  42. package/src/models/attributes/__tests__/ChoiceAttributeModel.spec.js +27 -0
  43. package/src/models/detail/DetailModel.js +8 -16
  44. package/src/models/user/UserModel.js +1 -1
  45. package/src/react-theme/__tests__/ThemeProvider.spec.js +17 -2
  46. package/src/react-theme/createTheme.js +10 -0
@@ -196,30 +196,22 @@ export default class DetailModel extends ResourceModel {
196
196
  * Getting the attribute that has as layout hint 'avatar-for-title'
197
197
  */
198
198
  get avatarForTitleAttribute(): ?AttributeType {
199
- const avatarAttributes = this._attributeCollection.all.filter((attribute) =>
200
- attribute.layouthint.hasExact(AVATAR),
199
+ return this._attributeCollection.find(
200
+ (attribute) =>
201
+ attribute.layouthint.hasExact(AVATAR_IN_TITLE) &&
202
+ attribute.layouthint.hasExact(AVATAR),
201
203
  );
202
-
203
- const avatarForTitleAttribute = avatarAttributes.find((attribute) =>
204
- attribute.layouthint.hasExact(AVATAR_IN_TITLE),
205
- );
206
-
207
- return avatarForTitleAttribute || null;
208
204
  }
209
205
 
210
206
  /**
211
207
  * Getting the attribute that has as layout hint 'title'
212
208
  */
213
209
  get titleAttribute(): ?AttributeType {
214
- const nonAvatarAttributes = this._attributeCollection.all.filter(
215
- (attribute) => !attribute.layouthint.hasExact(AVATAR),
210
+ return this._attributeCollection.find(
211
+ (attribute) =>
212
+ attribute.layouthint.has(TITLE) &&
213
+ !attribute.layouthint.hasExact(AVATAR),
216
214
  );
217
-
218
- const titleAttribute = nonAvatarAttributes.find((attribute) =>
219
- attribute.layouthint.has(TITLE),
220
- );
221
-
222
- return titleAttribute || null;
223
215
  }
224
216
 
225
217
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"DetailModel.js","names":["_objects","require","_ActionCollection","_interopRequireDefault","_AttributeCollection","_ResourceModel","_LayoutHints","DetailModel","ResourceModel","constructor","modularuiResponse","_defineProperty2","default","createAttributeCollection","createMetadataCollection","createActionCollection","type","modelName","isApplicableModel","data","_context","resourceType","contributions","resourcetype","_endsWith","call","_includes","getInitialChildModelLinks","_attributeCollection","setChildModels","models","id","getData","key","label","getContribution","_context2","attributeContributions","attributes","_filter","contribution","_keys","has","attributeCollection","AttributeCollection","collection","_context3","all","attribute","hasTitle","layouthint","hasExact","TITLE","hasAvatar","AVATAR","hasAvatarForTitle","AVATAR_IN_TITLE","isHidden","getAttributeByKey","_context4","metadataContributions","metadata","_map","metadataKey","metadataCollection","_metadataCollection","_actionCollection","ActionCollection","actions","actionCollection","isCase","avatarForTitleAttribute","_context5","avatarAttributes","_find","titleAttribute","_context6","nonAvatarAttributes","update","model","clonedModel","clone","equals","toString","exports"],"sources":["../../../src/models/detail/DetailModel.js"],"sourcesContent":["// @flow\nimport { has } from \"../../utils/helpers/objects\";\n\nimport ActionCollection from \"../actions/ActionCollection\";\nimport AttributeCollection from \"../attributes/AttributeCollection\";\nimport ResourceModel from \"../base/ResourceModel\";\n\nimport { AVATAR, AVATAR_IN_TITLE, TITLE } from \"../../constants/LayoutHints\";\n\nimport type { ModularUIResponse } from \"../../modularui\";\nimport type { ModularUIModel, AttributeType } from \"../types\";\nimport type LinkModel from \"../links/LinkModel\";\n\n/**\n * Base class for details<br/>\n * For instance the details of case 1<br/>\n * For instance the details of record 12<br/>\n */\nexport default class DetailModel extends ResourceModel {\n _attributeCollection: AttributeCollection;\n _metadataCollection: AttributeCollection;\n _actionCollection: ActionCollection;\n\n /**\n */\n constructor(modularuiResponse: ModularUIResponse) {\n super(modularuiResponse);\n\n this.createAttributeCollection();\n this.createMetadataCollection();\n this.createActionCollection();\n }\n\n /**\n */\n get type(): string {\n return \"Detail\";\n }\n\n /**\n */\n static get modelName(): string {\n return \"DetailModel\";\n }\n\n /**\n */\n static isApplicableModel(data: ModularUIResponse): boolean {\n const resourceType = data.contributions?.resourcetype;\n return (\n resourceType &&\n (resourceType.endsWith(\"DetailPanel\") ||\n [\"Detail\", \"CasePropertiesPanel\", \"CasePropertiesPanelDetail\"].includes(\n resourceType,\n ))\n );\n }\n\n /**\n */\n getInitialChildModelLinks(): Array<LinkModel> {\n return this._attributeCollection.getInitialChildModelLinks();\n }\n\n /**\n */\n setChildModels(models: Array<ModularUIModel>) {\n this._attributeCollection.setChildModels(models);\n }\n\n /**\n * Getting the unique identifier of the details\n */\n get id(): string {\n return this.getData(\"_id\", this.key);\n }\n\n /**\n */\n get label(): string {\n return this.getContribution(\"label\", \"\");\n }\n\n /**\n * Attribute collection\n */\n createAttributeCollection() {\n const attributeContributions = this.contributions.attributes\n ? this.contributions.attributes.filter((contribution) => {\n const [key] = Object.keys(contribution);\n return has(this.data, key);\n })\n : [];\n\n this.attributeCollection = new AttributeCollection(\n this.data,\n attributeContributions,\n true,\n );\n }\n\n /**\n */\n get attributeCollection(): AttributeCollection {\n return this._attributeCollection;\n }\n\n /**\n */\n set attributeCollection(collection: AttributeCollection) {\n this._attributeCollection = collection;\n }\n\n /**\n * Retrieve list of visible attributes\n */\n get attributes(): Array<AttributeType> {\n return this.attributeCollection.all.filter((attribute) => {\n const hasTitle = attribute.layouthint.hasExact(TITLE);\n const hasAvatar = attribute.layouthint.hasExact(AVATAR);\n const hasAvatarForTitle = attribute.layouthint.hasExact(AVATAR_IN_TITLE);\n return (\n !attribute.isHidden &&\n (!hasTitle || (hasTitle && hasAvatar)) &&\n (!hasAvatarForTitle || (hasAvatarForTitle && !hasAvatar))\n );\n });\n }\n\n /**\n * Retrieve an attribute by it's key\n */\n getAttributeByKey(key: string): AttributeType | null {\n return this._attributeCollection.getAttributeByKey(key);\n }\n\n /**\n * Metadata collection\n */\n createMetadataCollection() {\n const metadataContributions = this.contributions.metadata\n ? Object.keys(this.contributions.metadata).map((metadataKey) => ({\n [metadataKey]: this.contributions.metadata[metadataKey],\n }))\n : [];\n\n this.metadataCollection = new AttributeCollection(\n this.data,\n metadataContributions,\n true,\n );\n }\n\n /**\n */\n get metadataCollection(): AttributeCollection {\n return this._metadataCollection;\n }\n\n /**\n */\n set metadataCollection(collection: AttributeCollection) {\n this._metadataCollection = collection;\n }\n\n /**\n * Action collection\n */\n createActionCollection() {\n this._actionCollection = new ActionCollection(\n this.data.actions,\n this.contributions.actions,\n );\n }\n\n /**\n */\n get actionCollection(): ActionCollection {\n return this._actionCollection;\n }\n\n /**\n */\n set actionCollection(actionCollection: ActionCollection) {\n this._actionCollection = actionCollection;\n }\n\n /**\n * Determines if this is a case\n */\n get isCase(): boolean {\n return this.contributions.resourcetype === \"CaseView\";\n }\n\n /**\n * Getting the attribute that has as layout hint 'avatar-for-title'\n */\n get avatarForTitleAttribute(): ?AttributeType {\n const avatarAttributes = this._attributeCollection.all.filter((attribute) =>\n attribute.layouthint.hasExact(AVATAR),\n );\n\n const avatarForTitleAttribute = avatarAttributes.find((attribute) =>\n attribute.layouthint.hasExact(AVATAR_IN_TITLE),\n );\n\n return avatarForTitleAttribute || null;\n }\n\n /**\n * Getting the attribute that has as layout hint 'title'\n */\n get titleAttribute(): ?AttributeType {\n const nonAvatarAttributes = this._attributeCollection.all.filter(\n (attribute) => !attribute.layouthint.hasExact(AVATAR),\n );\n\n const titleAttribute = nonAvatarAttributes.find((attribute) =>\n attribute.layouthint.has(TITLE),\n );\n\n return titleAttribute || null;\n }\n\n /**\n * Update current detail with a new detail model and return a cloned version of the model\n */\n update(model: ModularUIModel): DetailModel {\n if (model instanceof DetailModel) {\n const clonedModel = this.clone();\n\n clonedModel.attributeCollection = model._attributeCollection;\n clonedModel.metadataCollection = model._metadataCollection;\n clonedModel.actionCollection = model._actionCollection;\n\n return clonedModel;\n }\n\n return this;\n }\n\n /**\n */\n equals(model: DetailModel): boolean {\n return this.id.toString() === model.id.toString();\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"DetailModel.js","names":["_objects","require","_ActionCollection","_interopRequireDefault","_AttributeCollection","_ResourceModel","_LayoutHints","DetailModel","ResourceModel","constructor","modularuiResponse","_defineProperty2","default","createAttributeCollection","createMetadataCollection","createActionCollection","type","modelName","isApplicableModel","data","_context","resourceType","contributions","resourcetype","_endsWith","call","_includes","getInitialChildModelLinks","_attributeCollection","setChildModels","models","id","getData","key","label","getContribution","_context2","attributeContributions","attributes","_filter","contribution","_keys","has","attributeCollection","AttributeCollection","collection","_context3","all","attribute","hasTitle","layouthint","hasExact","TITLE","hasAvatar","AVATAR","hasAvatarForTitle","AVATAR_IN_TITLE","isHidden","getAttributeByKey","_context4","metadataContributions","metadata","_map","metadataKey","metadataCollection","_metadataCollection","_actionCollection","ActionCollection","actions","actionCollection","isCase","avatarForTitleAttribute","_context5","_find","titleAttribute","_context6","update","model","clonedModel","clone","equals","toString","exports"],"sources":["../../../src/models/detail/DetailModel.js"],"sourcesContent":["// @flow\nimport { has } from \"../../utils/helpers/objects\";\n\nimport ActionCollection from \"../actions/ActionCollection\";\nimport AttributeCollection from \"../attributes/AttributeCollection\";\nimport ResourceModel from \"../base/ResourceModel\";\n\nimport { AVATAR, AVATAR_IN_TITLE, TITLE } from \"../../constants/LayoutHints\";\n\nimport type { ModularUIResponse } from \"../../modularui\";\nimport type { ModularUIModel, AttributeType } from \"../types\";\nimport type LinkModel from \"../links/LinkModel\";\n\n/**\n * Base class for details<br/>\n * For instance the details of case 1<br/>\n * For instance the details of record 12<br/>\n */\nexport default class DetailModel extends ResourceModel {\n _attributeCollection: AttributeCollection;\n _metadataCollection: AttributeCollection;\n _actionCollection: ActionCollection;\n\n /**\n */\n constructor(modularuiResponse: ModularUIResponse) {\n super(modularuiResponse);\n\n this.createAttributeCollection();\n this.createMetadataCollection();\n this.createActionCollection();\n }\n\n /**\n */\n get type(): string {\n return \"Detail\";\n }\n\n /**\n */\n static get modelName(): string {\n return \"DetailModel\";\n }\n\n /**\n */\n static isApplicableModel(data: ModularUIResponse): boolean {\n const resourceType = data.contributions?.resourcetype;\n return (\n resourceType &&\n (resourceType.endsWith(\"DetailPanel\") ||\n [\"Detail\", \"CasePropertiesPanel\", \"CasePropertiesPanelDetail\"].includes(\n resourceType,\n ))\n );\n }\n\n /**\n */\n getInitialChildModelLinks(): Array<LinkModel> {\n return this._attributeCollection.getInitialChildModelLinks();\n }\n\n /**\n */\n setChildModels(models: Array<ModularUIModel>) {\n this._attributeCollection.setChildModels(models);\n }\n\n /**\n * Getting the unique identifier of the details\n */\n get id(): string {\n return this.getData(\"_id\", this.key);\n }\n\n /**\n */\n get label(): string {\n return this.getContribution(\"label\", \"\");\n }\n\n /**\n * Attribute collection\n */\n createAttributeCollection() {\n const attributeContributions = this.contributions.attributes\n ? this.contributions.attributes.filter((contribution) => {\n const [key] = Object.keys(contribution);\n return has(this.data, key);\n })\n : [];\n\n this.attributeCollection = new AttributeCollection(\n this.data,\n attributeContributions,\n true,\n );\n }\n\n /**\n */\n get attributeCollection(): AttributeCollection {\n return this._attributeCollection;\n }\n\n /**\n */\n set attributeCollection(collection: AttributeCollection) {\n this._attributeCollection = collection;\n }\n\n /**\n * Retrieve list of visible attributes\n */\n get attributes(): Array<AttributeType> {\n return this.attributeCollection.all.filter((attribute) => {\n const hasTitle = attribute.layouthint.hasExact(TITLE);\n const hasAvatar = attribute.layouthint.hasExact(AVATAR);\n const hasAvatarForTitle = attribute.layouthint.hasExact(AVATAR_IN_TITLE);\n return (\n !attribute.isHidden &&\n (!hasTitle || (hasTitle && hasAvatar)) &&\n (!hasAvatarForTitle || (hasAvatarForTitle && !hasAvatar))\n );\n });\n }\n\n /**\n * Retrieve an attribute by it's key\n */\n getAttributeByKey(key: string): AttributeType | null {\n return this._attributeCollection.getAttributeByKey(key);\n }\n\n /**\n * Metadata collection\n */\n createMetadataCollection() {\n const metadataContributions = this.contributions.metadata\n ? Object.keys(this.contributions.metadata).map((metadataKey) => ({\n [metadataKey]: this.contributions.metadata[metadataKey],\n }))\n : [];\n\n this.metadataCollection = new AttributeCollection(\n this.data,\n metadataContributions,\n true,\n );\n }\n\n /**\n */\n get metadataCollection(): AttributeCollection {\n return this._metadataCollection;\n }\n\n /**\n */\n set metadataCollection(collection: AttributeCollection) {\n this._metadataCollection = collection;\n }\n\n /**\n * Action collection\n */\n createActionCollection() {\n this._actionCollection = new ActionCollection(\n this.data.actions,\n this.contributions.actions,\n );\n }\n\n /**\n */\n get actionCollection(): ActionCollection {\n return this._actionCollection;\n }\n\n /**\n */\n set actionCollection(actionCollection: ActionCollection) {\n this._actionCollection = actionCollection;\n }\n\n /**\n * Determines if this is a case\n */\n get isCase(): boolean {\n return this.contributions.resourcetype === \"CaseView\";\n }\n\n /**\n * Getting the attribute that has as layout hint 'avatar-for-title'\n */\n get avatarForTitleAttribute(): ?AttributeType {\n return this._attributeCollection.find(\n (attribute) =>\n attribute.layouthint.hasExact(AVATAR_IN_TITLE) &&\n attribute.layouthint.hasExact(AVATAR),\n );\n }\n\n /**\n * Getting the attribute that has as layout hint 'title'\n */\n get titleAttribute(): ?AttributeType {\n return this._attributeCollection.find(\n (attribute) =>\n attribute.layouthint.has(TITLE) &&\n !attribute.layouthint.hasExact(AVATAR),\n );\n }\n\n /**\n * Update current detail with a new detail model and return a cloned version of the model\n */\n update(model: ModularUIModel): DetailModel {\n if (model instanceof DetailModel) {\n const clonedModel = this.clone();\n\n clonedModel.attributeCollection = model._attributeCollection;\n clonedModel.metadataCollection = model._metadataCollection;\n clonedModel.actionCollection = model._actionCollection;\n\n return clonedModel;\n }\n\n return this;\n }\n\n /**\n */\n equals(model: DetailModel): boolean {\n return this.id.toString() === model.id.toString();\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -31,7 +31,7 @@ export default class UserModel extends ResourceModel {
31
31
  /**
32
32
  * Retrieve username of user
33
33
  */
34
- get avatar(): string {
34
+ get avatar(): string | null {
35
35
  return this.data.Avatar;
36
36
  }
37
37
 
@@ -1 +1 @@
1
- {"version":3,"file":"UserModel.js","names":["_ResourceModel","_interopRequireDefault","require","UserModel","ResourceModel","type","modelName","isApplicableModel","data","contributions","resourcetype","avatar","Avatar","username","Username","fullname","Fullname","label","exports","default"],"sources":["../../../src/models/user/UserModel.js"],"sourcesContent":["// @flow\nimport ResourceModel from \"../base/ResourceModel\";\n\nimport type { ModularUIResponse } from \"../../modularui\";\n\n/**\n * User model\n */\nexport default class UserModel extends ResourceModel {\n /**\n */\n get type(): string {\n return \"User\";\n }\n\n /**\n */\n static get modelName(): string {\n return \"UserModel\";\n }\n\n /**\n */\n static isApplicableModel(data: ModularUIResponse): boolean {\n return (\n data.contributions.resourcetype &&\n data.contributions.resourcetype === \"userdata\"\n );\n }\n\n /**\n * Retrieve username of user\n */\n get avatar(): string {\n return this.data.Avatar;\n }\n\n /**\n * Retrieve username of user\n */\n get username(): string {\n return this.data.Username || \"Guest\";\n }\n\n /**\n * retrieve the fullname of the user\n */\n get fullname(): string {\n return this.data.Fullname || \"Guest\";\n }\n\n /**\n */\n get label(): string {\n return this.contributions.label;\n }\n}\n"],"mappings":";;;;;;;AACA,IAAAA,cAAA,GAAAC,sBAAA,CAAAC,OAAA;AAIA;AACA;AACA;AACe,MAAMC,SAAS,SAASC,sBAAa,CAAC;EACnD;AACF;EACE,IAAIC,IAAIA,CAAA,EAAW;IACjB,OAAO,MAAM;EACf;;EAEA;AACF;EACE,WAAWC,SAASA,CAAA,EAAW;IAC7B,OAAO,WAAW;EACpB;;EAEA;AACF;EACE,OAAOC,iBAAiBA,CAACC,IAAuB,EAAW;IACzD,OACEA,IAAI,CAACC,aAAa,CAACC,YAAY,IAC/BF,IAAI,CAACC,aAAa,CAACC,YAAY,KAAK,UAAU;EAElD;;EAEA;AACF;AACA;EACE,IAAIC,MAAMA,CAAA,EAAW;IACnB,OAAO,IAAI,CAACH,IAAI,CAACI,MAAM;EACzB;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACL,IAAI,CAACM,QAAQ,IAAI,OAAO;EACtC;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACP,IAAI,CAACQ,QAAQ,IAAI,OAAO;EACtC;;EAEA;AACF;EACE,IAAIC,KAAKA,CAAA,EAAW;IAClB,OAAO,IAAI,CAACR,aAAa,CAACQ,KAAK;EACjC;AACF;AAACC,OAAA,CAAAC,OAAA,GAAAhB,SAAA","ignoreList":[]}
1
+ {"version":3,"file":"UserModel.js","names":["_ResourceModel","_interopRequireDefault","require","UserModel","ResourceModel","type","modelName","isApplicableModel","data","contributions","resourcetype","avatar","Avatar","username","Username","fullname","Fullname","label","exports","default"],"sources":["../../../src/models/user/UserModel.js"],"sourcesContent":["// @flow\nimport ResourceModel from \"../base/ResourceModel\";\n\nimport type { ModularUIResponse } from \"../../modularui\";\n\n/**\n * User model\n */\nexport default class UserModel extends ResourceModel {\n /**\n */\n get type(): string {\n return \"User\";\n }\n\n /**\n */\n static get modelName(): string {\n return \"UserModel\";\n }\n\n /**\n */\n static isApplicableModel(data: ModularUIResponse): boolean {\n return (\n data.contributions.resourcetype &&\n data.contributions.resourcetype === \"userdata\"\n );\n }\n\n /**\n * Retrieve username of user\n */\n get avatar(): string | null {\n return this.data.Avatar;\n }\n\n /**\n * Retrieve username of user\n */\n get username(): string {\n return this.data.Username || \"Guest\";\n }\n\n /**\n * retrieve the fullname of the user\n */\n get fullname(): string {\n return this.data.Fullname || \"Guest\";\n }\n\n /**\n */\n get label(): string {\n return this.contributions.label;\n }\n}\n"],"mappings":";;;;;;;AACA,IAAAA,cAAA,GAAAC,sBAAA,CAAAC,OAAA;AAIA;AACA;AACA;AACe,MAAMC,SAAS,SAASC,sBAAa,CAAC;EACnD;AACF;EACE,IAAIC,IAAIA,CAAA,EAAW;IACjB,OAAO,MAAM;EACf;;EAEA;AACF;EACE,WAAWC,SAASA,CAAA,EAAW;IAC7B,OAAO,WAAW;EACpB;;EAEA;AACF;EACE,OAAOC,iBAAiBA,CAACC,IAAuB,EAAW;IACzD,OACEA,IAAI,CAACC,aAAa,CAACC,YAAY,IAC/BF,IAAI,CAACC,aAAa,CAACC,YAAY,KAAK,UAAU;EAElD;;EAEA;AACF;AACA;EACE,IAAIC,MAAMA,CAAA,EAAkB;IAC1B,OAAO,IAAI,CAACH,IAAI,CAACI,MAAM;EACzB;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACL,IAAI,CAACM,QAAQ,IAAI,OAAO;EACtC;;EAEA;AACF;AACA;EACE,IAAIC,QAAQA,CAAA,EAAW;IACrB,OAAO,IAAI,CAACP,IAAI,CAACQ,QAAQ,IAAI,OAAO;EACtC;;EAEA;AACF;EACE,IAAIC,KAAKA,CAAA,EAAW;IAClB,OAAO,IAAI,CAACR,aAAa,CAACQ,KAAK;EACjC;AACF;AAACC,OAAA,CAAAC,OAAA,GAAAhB,SAAA","ignoreList":[]}
@@ -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","generatedTheme","settings","_len","arguments","length","themeElements","Array","_key","element","isPlainObject","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 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 // $FlowFixMe[cannot-spread-indexer]\n generatedTheme = { ...generatedTheme, ...element, ...storedTheme };\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":[]}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beinformed/ui",
3
- "version": "1.43.6",
3
+ "version": "1.44.0",
4
4
  "description": "Toolbox for be informed javascript layouts",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "bugs": "http://support.beinformed.com",
@@ -554,13 +554,6 @@ export default class AttributeModel
554
554
  this._isResult = isResult;
555
555
  }
556
556
 
557
- /**
558
- *
559
- */
560
- get isAvatar(): boolean {
561
- return this.contributions?.optionType === "user" ?? false;
562
- }
563
-
564
557
  /**
565
558
  * Getting the display and input format of a attribute
566
559
  */
@@ -71,6 +71,12 @@ export default class ChoiceAttributeModel extends AttributeModel {
71
71
  return "choice";
72
72
  }
73
73
 
74
+ /**
75
+ */
76
+ get optionType(): string {
77
+ return this.contributions?.optionType ?? "generic";
78
+ }
79
+
74
80
  /**
75
81
  */
76
82
  getInitialChildModelLinks(): Array<LinkModel> {
@@ -122,16 +128,6 @@ export default class ChoiceAttributeModel extends AttributeModel {
122
128
  return this.contributions.lookupList?.label ?? "";
123
129
  }
124
130
 
125
- /**
126
- *
127
- */
128
- get avatarLink(): LinkModel | null {
129
- return (
130
- this.options.collection.find((option) => option.code === this.value)
131
- ?.avatarLink || null
132
- );
133
- }
134
-
135
131
  /**
136
132
  * Retrieve reference date of attribute which can be used as entryDate for content
137
133
  */
@@ -114,6 +114,7 @@ class ChoiceAttributeOptionCollection extends ResourceCollection<ChoiceAttribute
114
114
  {
115
115
  ...optionContributions,
116
116
  count: this.getOptionCount(optionCode, data.options),
117
+ optionType: contributions.optionType ?? "generic",
117
118
  },
118
119
  referenceDate,
119
120
  );
@@ -32,6 +32,7 @@ class ChoiceAttributeOptionModel
32
32
  _links: LinkCollection;
33
33
  _attributeCollection: AttributeCollection;
34
34
  _content: AttributeContent;
35
+ _isUser: boolean = false;
35
36
 
36
37
  /**
37
38
  */
@@ -56,6 +57,8 @@ class ChoiceAttributeOptionModel
56
57
  this._links = new LinkCollection(this.contributions._links);
57
58
 
58
59
  this._content = new AttributeContent(option.content);
60
+
61
+ this._isUser = option.optionType === "user";
59
62
  }
60
63
 
61
64
  /**
@@ -381,6 +384,12 @@ class ChoiceAttributeOptionModel
381
384
  get content(): AttributeContent {
382
385
  return this._content;
383
386
  }
387
+
388
+ /**
389
+ */
390
+ get isUser(): boolean {
391
+ return this._isUser;
392
+ }
384
393
  }
385
394
 
386
395
  export default ChoiceAttributeOptionModel;
@@ -677,4 +677,31 @@ describe("choiceAttributeModel", () => {
677
677
  "answer-option-key": "book-label",
678
678
  });
679
679
  });
680
+
681
+ it("sets isUser on options where attribute has optionType user", () => {
682
+ const data = {
683
+ key: "Users",
684
+ value: [],
685
+ };
686
+
687
+ const contributions = {
688
+ label: "Users",
689
+ type: "choice",
690
+ optionType: "user",
691
+ options: [
692
+ {
693
+ code: "user1",
694
+ label: "User 1",
695
+ },
696
+ {
697
+ code: "user2",
698
+ label: "User 2",
699
+ },
700
+ ],
701
+ };
702
+
703
+ const attribute = new ChoiceAttributeModel(data, contributions);
704
+
705
+ expect(attribute.options.first.isUser).toBe(true);
706
+ });
680
707
  });
@@ -196,30 +196,22 @@ export default class DetailModel extends ResourceModel {
196
196
  * Getting the attribute that has as layout hint 'avatar-for-title'
197
197
  */
198
198
  get avatarForTitleAttribute(): ?AttributeType {
199
- const avatarAttributes = this._attributeCollection.all.filter((attribute) =>
200
- attribute.layouthint.hasExact(AVATAR),
199
+ return this._attributeCollection.find(
200
+ (attribute) =>
201
+ attribute.layouthint.hasExact(AVATAR_IN_TITLE) &&
202
+ attribute.layouthint.hasExact(AVATAR),
201
203
  );
202
-
203
- const avatarForTitleAttribute = avatarAttributes.find((attribute) =>
204
- attribute.layouthint.hasExact(AVATAR_IN_TITLE),
205
- );
206
-
207
- return avatarForTitleAttribute || null;
208
204
  }
209
205
 
210
206
  /**
211
207
  * Getting the attribute that has as layout hint 'title'
212
208
  */
213
209
  get titleAttribute(): ?AttributeType {
214
- const nonAvatarAttributes = this._attributeCollection.all.filter(
215
- (attribute) => !attribute.layouthint.hasExact(AVATAR),
210
+ return this._attributeCollection.find(
211
+ (attribute) =>
212
+ attribute.layouthint.has(TITLE) &&
213
+ !attribute.layouthint.hasExact(AVATAR),
216
214
  );
217
-
218
- const titleAttribute = nonAvatarAttributes.find((attribute) =>
219
- attribute.layouthint.has(TITLE),
220
- );
221
-
222
- return titleAttribute || null;
223
215
  }
224
216
 
225
217
  /**
@@ -31,7 +31,7 @@ export default class UserModel extends ResourceModel {
31
31
  /**
32
32
  * Retrieve username of user
33
33
  */
34
- get avatar(): string {
34
+ get avatar(): string | null {
35
35
  return this.data.Avatar;
36
36
  }
37
37
 
@@ -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