From d26d6fbc094bdcbd5b394edce35da0424ba8e064 Mon Sep 17 00:00:00 2001 From: Mike Bryant Date: Fri, 26 Jul 2024 17:02:11 +0100 Subject: [PATCH] Rework various forms and integrate type metadata into forms This is done by extending the existing form config system, now called field hints, which is integrated into various action builders for editing and saving forms. --- Gruntfile.js | 9 + conf/schema/pg.sql | 104 - .../20240807_add_entity_meta_tables.sql | 35 + .../admin/app/assets/css/admin/_admin.scss | 61 +- modules/admin/app/assets/css/dmeditor.scss | 27 + modules/admin/app/assets/js/admin.js | 6 +- .../datasets/components/_manager-convert.vue | 1 - .../app/assets/js/dmeditor/__mocks__/api.ts | 26 +- modules/admin/app/assets/js/dmeditor/api.ts | 23 +- .../admin/app/assets/js/dmeditor/app.spec.ts | 10 +- modules/admin/app/assets/js/dmeditor/app.vue | 3 + .../js/dmeditor/components/_list-et.vue | 131 +- .../dmeditor/components/_modal-et-editor.vue | 48 +- .../dmeditor/components/_modal-fm-editor.vue | 135 +- .../app/assets/js/lib/vue-i18n.global.js | 6690 +++++++++++++++++ .../app/controllers/admin/Indexing.scala | 7 +- .../admin/app/controllers/admin/Ingest.scala | 12 +- .../admin/app/controllers/admin/Tasks.scala | 4 +- .../authorities/HistoricalAgents.scala | 20 +- .../app/controllers/countries/Countries.scala | 37 +- .../controllers/cypher/CypherQueries.scala | 3 - .../datamodel/EntityTypeMetadataApi.scala | 2 +- .../controllers/datasets/ConvertConfigs.scala | 2 - .../controllers/datasets/HarvestConfigs.scala | 6 +- .../controllers/datasets/ImportDatasets.scala | 5 +- .../app/controllers/datasets/ImportLogs.scala | 3 - .../datasets/LongRunningJobs.scala | 3 - .../admin/app/controllers/groups/Groups.scala | 6 +- .../institutions/Repositories.scala | 35 +- .../app/controllers/keywords/Concepts.scala | 16 +- .../controllers/sets/AuthoritativeSets.scala | 33 +- .../admin/app/controllers/tools/Tools.scala | 7 +- .../controllers/units/DocumentaryUnits.scala | 54 +- .../controllers/virtual/VirtualUnits.scala | 68 +- .../vocabularies/Vocabularies.scala | 20 +- modules/admin/app/views/admin/Helpers.scala | 5 + .../admin/authoritativeSet/create.scala.html | 11 +- .../admin/authoritativeSet/edit.scala.html | 6 +- .../admin/authoritativeSet/form.scala.html | 12 +- .../admin/common/validationErrors.scala.html | 34 + .../app/views/admin/concept/create.scala.html | 8 +- .../app/views/admin/concept/edit.scala.html | 8 +- .../app/views/admin/concept/form.scala.html | 24 +- .../views/admin/concept/inlineName.scala.html | 11 - .../admin/concept/inlineNameSet.scala.html | 16 - .../app/views/admin/country/create.scala.html | 14 +- .../app/views/admin/country/edit.scala.html | 12 +- .../app/views/admin/country/form.scala.html | 16 +- .../app/views/admin/country/show.scala.html | 8 +- .../views/admin/datamodel/editor.scala.html | 26 +- .../admin/documentaryUnit/create.scala.html | 10 +- .../createDescription.scala.html | 8 +- .../deleteDescription.scala.html | 2 +- .../documentaryUnit/description.scala.html | 3 +- .../admin/documentaryUnit/edit.scala.html | 10 +- .../editDescription.scala.html | 8 +- .../admin/documentaryUnit/form.scala.html | 4 +- ...v.scala.html => formNavigation.scala.html} | 0 .../admin/documentaryUnit/show.scala.html | 106 +- .../admin/historicalAgent/create.scala.html | 8 +- .../historicalAgent/description.scala.html | 3 +- .../admin/historicalAgent/edit.scala.html | 8 +- .../admin/historicalAgent/form.scala.html | 4 +- ...v.scala.html => formNavigation.scala.html} | 0 .../admin/historicalAgent/show.scala.html | 13 +- .../adminSinglePageAppLayout.scala.html | 1 + .../app/views/admin/link/edit.scala.html | 2 +- .../admin/repository/addressForm.scala.html | 2 +- .../views/admin/repository/create.scala.html | 8 +- .../admin/repository/description.scala.html | 3 +- .../repository/descriptionForm.scala.html | 20 +- .../views/admin/repository/edit.scala.html | 8 +- .../views/admin/repository/form.scala.html | 4 +- ...v.scala.html => formNavigation.scala.html} | 0 .../admin/repository/inlineGeoname.scala.html | 22 +- .../views/admin/repository/show.scala.html | 12 +- .../views/admin/virtualUnit/create.scala.html | 6 +- .../virtualUnit/createDescription.scala.html | 8 +- .../virtualUnit/deleteDescription.scala.html | 2 +- .../views/admin/virtualUnit/edit.scala.html | 7 +- .../virtualUnit/editDescription.scala.html | 8 +- .../views/admin/virtualUnit/form.scala.html | 4 +- .../views/admin/vocabulary/create.scala.html | 10 +- .../views/admin/vocabulary/edit.scala.html | 10 +- .../views/admin/vocabulary/form.scala.html | 12 +- .../app/views/formHelpers/dateJs.scala.html | 5 - .../formHelpers/enumChoiceInput.scala.html | 22 +- .../formHelpers/fieldTemplate.scala.html | 6 +- .../fieldTemplateWithHints.scala.html | 28 + .../app/views/formHelpers/formJs.scala.html | 24 + .../formHelpers/formNavigation.scala.html | 35 +- .../formHelpers/inlineDateSet.scala.html | 18 +- .../formHelpers/inlineNameSet.scala.html | 18 +- .../formHelpers/inlineTextSet.scala.html | 21 +- modules/admin/conf/datamodel.routes | 2 +- modules/admin/conf/messages | 6 +- .../controllers/api/datasets/Datasets.scala | 5 +- .../api/app/controllers/api/v1/ApiV1.scala | 6 +- .../controllers/base/ControllerHelpers.scala | 6 + .../controllers/base/CoreActionBuilders.scala | 3 + .../controllers/base/RecaptchaHelpers.scala | 3 - .../scala/controllers/generic/Create.scala | 35 +- .../scala/controllers/generic/Creator.scala | 63 +- .../main/scala/controllers/generic/Read.scala | 7 +- .../scala/controllers/generic/Search.scala | 3 - .../scala/controllers/generic/Update.scala | 40 +- .../main/scala}/forms/FormFieldHints.scala | 31 +- .../main/scala/forms/mappings/package.scala | 38 + .../core/src/main/scala/forms/package.scala | 25 - .../main/scala/models/AuthoritativeSet.scala | 3 +- .../scala/models/ConceptDescription.scala | 2 +- .../core/src/main/scala/models/Country.scala | 27 +- .../main/scala/models/DocumentaryUnit.scala | 3 + .../models/DocumentaryUnitDescription.scala | 2 +- .../core/src/main/scala/models/Entity.scala | 3 +- .../scala}/models/EntityTypeMetadata.scala | 0 .../main/scala}/models/FieldMetadata.scala | 4 +- .../main/scala/models/FieldMetadataSet.scala | 68 + .../core/src/main/scala/models/Group.scala | 3 +- .../models/HistoricalAgentDescription.scala | 3 +- .../core/src/main/scala/models/IsadG.scala | 12 + .../core/src/main/scala/models/Isdiah.scala | 7 +- .../scala/models/RepositoryDescription.scala | 2 +- .../src/main/scala/models/Vocabulary.scala | 3 +- .../datamodel/EntityTypeMetadataService.scala | 5 + .../SqlEntityTypeMetadataService.scala | 19 +- .../portal/app/assets/css/portal/_layout.scss | 3 +- .../portal/app/assets/css/portal/_style.scss | 29 +- .../app/controllers/AppComponents.scala | 41 +- .../app/controllers/base/SearchVC.scala | 5 +- .../app/controllers/portal/Feedback.scala | 12 +- .../controllers/portal/account/Accounts.scala | 5 +- .../portal/base/PortalController.scala | 12 +- .../portal/users/UserProfiles.scala | 6 +- .../portal/app/models/FieldMetadataSet.scala | 30 - .../portal/app/views/common/footer.scala.html | 1 + modules/portal/app/views/dataModel.scala.html | 141 +- .../views/formHelpers/lineInput.scala.html | 4 +- modules/portal/conf/messages | 9 +- .../test/models/FieldMetadataSetSpec.scala | 20 +- package-lock.json | 104 + package.json | 1 + .../SqlEntityTypeMetadataServiceSpec.scala | 7 +- 143 files changed, 8190 insertions(+), 1055 deletions(-) delete mode 100644 conf/schema/pg.sql create mode 100644 etc/db_migrations/20240807_add_entity_meta_tables.sql create mode 100644 modules/admin/app/assets/js/lib/vue-i18n.global.js create mode 100644 modules/admin/app/views/admin/common/validationErrors.scala.html delete mode 100644 modules/admin/app/views/admin/concept/inlineName.scala.html delete mode 100644 modules/admin/app/views/admin/concept/inlineNameSet.scala.html rename modules/admin/app/views/admin/documentaryUnit/{formNav.scala.html => formNavigation.scala.html} (100%) rename modules/admin/app/views/admin/historicalAgent/{formNav.scala.html => formNavigation.scala.html} (100%) rename modules/admin/app/views/admin/repository/{formNav.scala.html => formNavigation.scala.html} (100%) delete mode 100644 modules/admin/app/views/formHelpers/dateJs.scala.html create mode 100644 modules/admin/app/views/formHelpers/fieldTemplateWithHints.scala.html create mode 100644 modules/admin/app/views/formHelpers/formJs.scala.html rename modules/{portal/app => core/src/main/scala}/forms/FormFieldHints.scala (75%) create mode 100644 modules/core/src/main/scala/forms/mappings/package.scala rename modules/{portal/app => core/src/main/scala}/models/EntityTypeMetadata.scala (100%) rename modules/{portal/app => core/src/main/scala}/models/FieldMetadata.scala (98%) create mode 100644 modules/core/src/main/scala/models/FieldMetadataSet.scala rename modules/{portal/app => core/src/main/scala}/services/datamodel/EntityTypeMetadataService.scala (95%) rename modules/{portal/app => core/src/main/scala}/services/datamodel/SqlEntityTypeMetadataService.scala (84%) delete mode 100644 modules/portal/app/models/FieldMetadataSet.scala diff --git a/Gruntfile.js b/Gruntfile.js index 96ace8aafa..87c89e0e52 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -205,6 +205,15 @@ module.exports = function (grunt) { ], dest: paths.adminJsLib }, + { + expand: true, + cwd: 'node_modules/vue-i18n/dist', + src: [ + // not using runtime 'cos we need the messages compiler + 'vue-i18n.global.js' + ], + dest: paths.adminJsLib + }, ], }, }, diff --git a/conf/schema/pg.sql b/conf/schema/pg.sql deleted file mode 100644 index 59eca9824c..0000000000 --- a/conf/schema/pg.sql +++ /dev/null @@ -1,104 +0,0 @@ -CREATE TABLE users ( - id VARCHAR(50) NOT NULL PRIMARY KEY, - email VARCHAR(255) NOT NULL, - verified BOOLEAN NOT NULL DEFAULT FALSE, - staff BOOLEAN NOT NULL DEFAULT FALSE, - active BOOLEAN NOT NULL DEFAULT TRUE, - allow_messaging BOOLEAN NOT NULL DEFAULT TRUE, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - last_login TIMESTAMP NULL, - password VARCHAR(255) NULL, - is_legacy BOOLEAN NOT NULL DEFAULT FALSE -); - -CREATE UNIQUE INDEX users_email ON users (email); - -CREATE TABLE openid_association ( - id VARCHAR(50) NOT NULL, - openid_url VARCHAR(255) NOT NULL, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY(id, openid_url) -); - -ALTER TABLE openid_association ADD CONSTRAINT openid_association_id FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE; - -CREATE TABLE oauth2_association ( - id VARCHAR(50) NOT NULL, - provider_id VARCHAR(255) NOT NULL, - provider VARCHAR(255) NOT NULL, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY(id, provider_id, provider) -); - -ALTER TABLE oauth2_association ADD CONSTRAINT oauth2_association_id FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE; - -CREATE TABLE token ( - id VARCHAR(50) NOT NULL, - token VARCHAR(255) NOT NULL PRIMARY KEY, - expires TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - is_sign_up BOOLEAN NOT NULL DEFAULT FALSE -); - -ALTER TABLE token ADD CONSTRAINT token_profile_id FOREIGN KEY (id) REFERENCES users (id) ON DELETE CASCADE; - -CREATE TABLE moved_pages( - original_path_sha1 CHAR(40) PRIMARY KEY, - original_path TEXT NOT NULL, - new_path TEXT NOT NULL, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -); - -CREATE TABLE research_guide ( - id SERIAL PRIMARY KEY, - name TEXT NOT NULL, - path VARCHAR(255) DEFAULT NULL, - picture VARCHAR(255) DEFAULT NULL, - virtual_unit VARCHAR(255) DEFAULT NULL, - description TEXT, - css TEXT, - active BOOLEAN NOT NULL DEFAULT TRUE, - default_page INTEGER NULL -); - -ALTER TABLE research_guide ADD CONSTRAINT research_guide_path_unique UNIQUE(path); - -CREATE TABLE research_guide_page ( - id SERIAL PRIMARY KEY, - research_guide_id INTEGER NOT NULL, - name TEXT NOT NULL, - layout VARCHAR(45) DEFAULT NULL, - content TEXT, - path VARCHAR(45) DEFAULT NULL, - position VARCHAR(45) DEFAULT NULL, - description TEXT, - params VARCHAR(255) DEFAULT NULL -); - -ALTER TABLE research_guide_page ADD CONSTRAINT research_guide_page_id FOREIGN KEY (research_guide_id) REFERENCES research_guide (id) ON DELETE CASCADE; -ALTER TABLE research_guide_page ADD CONSTRAINT research_guide_path_guide_id UNIQUE (research_guide_id, path); - -CREATE TABLE feedback ( - id CHAR(10) NOT NULL PRIMARY KEY, - user_id VARCHAR(50) DEFAULT NULL, - name VARCHAR (255) DEFAULT NULL, - email VARCHAR (255) DEFAULT NULL, - text TEXT, - type VARCHAR (10) DEFAULT NULL, - copy BOOLEAN DEFAULT FALSE, - context TEXT, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated TIMESTAMP NULL, - mode VARCHAR(10) NOT NULL -); - -CREATE TABLE cypher_queries ( - id CHAR(10) NOT NULL PRIMARY KEY , - user_id VARCHAR(50) DEFAULT NULL, - name VARCHAR(255) NOT NULL, - query TEXT NOT NULL, - description TEXT, - public BOOLEAN DEFAULT FALSE, - created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated TIMESTAMP NULL -); - diff --git a/etc/db_migrations/20240807_add_entity_meta_tables.sql b/etc/db_migrations/20240807_add_entity_meta_tables.sql new file mode 100644 index 0000000000..a16f249480 --- /dev/null +++ b/etc/db_migrations/20240807_add_entity_meta_tables.sql @@ -0,0 +1,35 @@ +BEGIN TRANSACTION; + +CREATE TABLE entity_type_meta( + entity_type VARCHAR(50) NOT NULL PRIMARY KEY, + name VARCHAR(100) NOT NULL, + description TEXT, + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated TIMESTAMP +); + +CREATE INDEX entity_type_meta_entity_type ON entity_type_meta(entity_type); + +CREATE TABLE field_meta( + entity_type VARCHAR(50) NOT NULL, + id VARCHAR(50) NOT NULL, + name VARCHAR(100) NOT NULL, + description TEXT, + usage VARCHAR(50), + category VARCHAR(50), + default_val TEXT, + see_also TEXT[], + created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated TIMESTAMP, + PRIMARY KEY (entity_type, id), + CONSTRAINT field_meta_entity_type + FOREIGN KEY (entity_type) + REFERENCES entity_type_meta (entity_type) + ON DELETE CASCADE + ON UPDATE CASCADE +); + +CREATE INDEX field_meta_entity_type ON field_meta(entity_type); +CREATE INDEX field_meta_id ON field_meta(id); + +COMMIT; diff --git a/modules/admin/app/assets/css/admin/_admin.scss b/modules/admin/app/assets/css/admin/_admin.scss index d1a96563e5..05f1991331 100644 --- a/modules/admin/app/assets/css/admin/_admin.scss +++ b/modules/admin/app/assets/css/admin/_admin.scss @@ -80,11 +80,11 @@ body > .admin-content > .flash { background-color: $gray-100; } } +} - .markdown-helper { - font-style: italic; - cursor: help; - } +.markdown-helper { + font-style: italic; + cursor: pointer; } .inline-remove > a:hover { @@ -92,6 +92,24 @@ body > .admin-content > .flash { cursor: pointer; } +.form-legend { + font-size: $font-size-base; + + dl { + display: flex; + flex-wrap: wrap; + + dt { + @include make-col(3); + font-weight: bold; + } + + dd { + @include make-col(9); + } + } +} + .address-form, .concept-description-form { background-color: $gray-100; @@ -127,8 +145,11 @@ body > .admin-content > .flash { padding-top: $margin-md; } -.add-address { +.add-address, +.add-concept +{ float: right; + margin-bottom: $margin-md; } .admin-help-notice { @@ -315,12 +336,18 @@ pre.code-format { margin-bottom: $margin-md; } -.add-description { - margin-bottom: $margin-md; - @include clearfix(); - a { - float: right; +.control-elements { + .add-inline-element:not(.btn) { + display: block; + background-color: $gray-100; + border-bottom: 1px solid darken($gray-100, 5%); + padding: 0 $margin-xs; + color: $gray-700; + } + .add-inline-element:hover:not(.btn) { + background-color: darken($gray-100, 5%); } + } .inline-element-block-controls { @@ -436,6 +463,20 @@ pre.code-format { } } +// Metadata validation +.metadata-validation { + summary { + font-size: $font-size-lg; + @extend .alert, .alert-warning; + } + .validation-errors { + @extend .alert, .alert-danger; + } + .validation-warnings { + @extend .alert, .alert-warning; + } +} + // Vue Single-page applications %expanding-row { display: flex; diff --git a/modules/admin/app/assets/css/dmeditor.scss b/modules/admin/app/assets/css/dmeditor.scss index 179e9a1ada..addeafbddb 100644 --- a/modules/admin/app/assets/css/dmeditor.scss +++ b/modules/admin/app/assets/css/dmeditor.scss @@ -12,3 +12,30 @@ $active-table-row: #e7f1ff; overflow: auto; flex-basis: 0; } + +.section { + background-color: $gray-100; + font-weight: bold; +} + +.fm-list td.fm-actions { + width: 5rem; +} + +.fm-see-also a + a { + display: inline-block; +} + +.fm-usage { + white-space: nowrap; + +} + +.fm-list td:last-child a { + margin-left: $margin-xs; +} + +#delete-metadata { + margin-right: auto; +} + diff --git a/modules/admin/app/assets/js/admin.js b/modules/admin/app/assets/js/admin.js index 350c6c4d38..c8cb3b104f 100644 --- a/modules/admin/app/assets/js/admin.js +++ b/modules/admin/app/assets/js/admin.js @@ -188,7 +188,7 @@ jQuery(function ($) { event.preventDefault(); var container = $(event.target).closest(".inline-formset"); - var set = container.children(".inline-element-list"); + var set = container.children(".control-elements").children(".inline-element-list").first(); var prefix = container.data("prefix"); if (!prefix) { throw "No prefix found for formset"; @@ -212,6 +212,10 @@ jQuery(function ($) { // And a help popover addPopover($elem.find("textarea,input")); + + // Focus the first input + $elem.find("input,textarea").first().focus(); + }).on("click", ".remove-inline-element", function (event) { event.preventDefault(); $(this) diff --git a/modules/admin/app/assets/js/datasets/components/_manager-convert.vue b/modules/admin/app/assets/js/datasets/components/_manager-convert.vue index 3f180bf347..062ead04e0 100644 --- a/modules/admin/app/assets/js/datasets/components/_manager-convert.vue +++ b/modules/admin/app/assets/js/datasets/components/_manager-convert.vue @@ -20,7 +20,6 @@ import _takeWhile from 'lodash/takeWhile'; import _find from 'lodash/find'; import {DataTransformation} from "../types"; - let initialConvertState = function (config) { return { ingesting: {}, diff --git a/modules/admin/app/assets/js/dmeditor/__mocks__/api.ts b/modules/admin/app/assets/js/dmeditor/__mocks__/api.ts index 83edd95ea5..df03adcec5 100644 --- a/modules/admin/app/assets/js/dmeditor/__mocks__/api.ts +++ b/modules/admin/app/assets/js/dmeditor/__mocks__/api.ts @@ -1,4 +1,5 @@ import { + EntityType, EntityTypeMetadata, EntityTypeMetadataInfo, FieldMetadata, @@ -17,9 +18,9 @@ export default class EntityTypeMetadataApi { this.etData = { Country: { entityType: "Country", - name: "Country", - description: "Country description", - created: "2021-06-01" + name: "Country", + description: "Country description", + created: "2021-06-01" } }; @@ -31,6 +32,7 @@ export default class EntityTypeMetadataApi { name: "History", description: "Test", usage: "mandatory", + defaultVal: null, seeAlso: ["seeAlso"], created: "2021-06-01" } @@ -39,34 +41,34 @@ export default class EntityTypeMetadataApi { } - list(): Promise> { + list(): Promise> { return Promise.resolve(this.etData); } - get(entityType: string): Promise { + get(entityType: EntityType): Promise { return Promise.resolve(this.etData[entityType] || null); } - save(entityType: string, data: EntityTypeMetadataInfo): Promise { + save(entityType: EntityType, data: EntityTypeMetadataInfo): Promise { return Promise.resolve({ entityType, ...data } as EntityTypeMetadata); } - delete(entityType: string): Promise { + delete(entityType: EntityType): Promise { return Promise.resolve(true); } - listFields(entityType?: string): Promise> { + listFields(entityType?: EntityType): Promise> { return Promise.resolve(this.fData); } - getField(entityType: string, id: string): Promise { + getField(entityType: EntityType, id: string): Promise { return Promise.resolve(this.fData[entityType].find(f => f.id === id) || null); } - saveField(entityType: string, id: string, data: FieldMetadataInfo): Promise { + saveField(entityType: EntityType, id: string, data: FieldMetadataInfo): Promise { return Promise.resolve({ entityType, id, @@ -74,7 +76,7 @@ export default class EntityTypeMetadataApi { } as FieldMetadata); } - deleteField(entityType: string, id: string): Promise { + deleteField(entityType: EntityType, id: string): Promise { // remove the item from fData: this.fData[entityType] = this.fData[entityType].filter(f => f.id !== id); return Promise.resolve(true); @@ -83,7 +85,7 @@ export default class EntityTypeMetadataApi { templates(): Promise { return Promise.resolve({ Country: { - "" : ["history"] + "_" : ["history"] } } as FieldMetadataTemplates); } diff --git a/modules/admin/app/assets/js/dmeditor/api.ts b/modules/admin/app/assets/js/dmeditor/api.ts index e7a92aba19..9c2bfc3179 100644 --- a/modules/admin/app/assets/js/dmeditor/api.ts +++ b/modules/admin/app/assets/js/dmeditor/api.ts @@ -1,5 +1,6 @@ import axios from "axios"; import { + EntityType, EntityTypeMetadata, EntityTypeMetadataInfo, FieldMetadata, FieldMetadataInfo, FieldMetadataTemplates, @@ -30,36 +31,36 @@ export default class EntityTypeMetadataApi { withCredentials: true, }).then(r => r.data); } - list(): Promise> { - return EntityTypeMetadataApi.call>(this.service.list(), {}); + list(): Promise> { + return EntityTypeMetadataApi.call>(this.service.list(), {}); } - get(entityType: string): Promise> { - return EntityTypeMetadataApi.call>(this.service.list(), {}, {entityType}); + get(entityType: EntityType): Promise> { + return EntityTypeMetadataApi.call>(this.service.list(), {}, {entityType}); } - save(entityType: string, data: EntityTypeMetadataInfo): Promise { + save(entityType: EntityType, data: EntityTypeMetadataInfo): Promise { return EntityTypeMetadataApi.call(this.service.save(entityType), data); } - delete(entityType: string): Promise { + delete(entityType: EntityType): Promise { return EntityTypeMetadataApi.call(this.service.delete(entityType)); } - listFields(entityType?: string): Promise> { + listFields(entityType?: EntityType): Promise> { let params = entityType ? {entityType} : {}; - return EntityTypeMetadataApi.call>(this.service.listFields(), {}, params) + return EntityTypeMetadataApi.call>(this.service.listFields(), {}, params) } - getField(entityType: string, id: string): Promise { + getField(entityType: EntityType, id: string): Promise { return EntityTypeMetadataApi.call(this.service.getField(entityType, id)); } - saveField(entityType: string, id: string, data: FieldMetadataInfo): Promise { + saveField(entityType: EntityType, id: string, data: FieldMetadataInfo): Promise { return EntityTypeMetadataApi.call(this.service.saveField(entityType, id), data); } - deleteField(entityType: string, id: string): Promise { + deleteField(entityType: EntityType, id: string): Promise { return EntityTypeMetadataApi.call(this.service.deleteField(entityType, id)); } diff --git a/modules/admin/app/assets/js/dmeditor/app.spec.ts b/modules/admin/app/assets/js/dmeditor/app.spec.ts index 279bfb3ada..563deec623 100644 --- a/modules/admin/app/assets/js/dmeditor/app.spec.ts +++ b/modules/admin/app/assets/js/dmeditor/app.spec.ts @@ -1,10 +1,14 @@ -import {mount, flushPromises} from '@vue/test-utils'; +import {mount, flushPromises,config} from '@vue/test-utils'; import App from './app.vue'; import ListEt from './components/_list-et.vue'; import EntityTypeMetadataApi from "./api"; jest.mock('./api'); +config.global.mocks = { + '$t': (msg) => msg, // return i18n key +} + const defaultInit = { props: { service: {}, @@ -55,7 +59,9 @@ test('deleting a field', async () => { expect(wrapper.find(".fm-list").exists()).toBe(true); expect(wrapper.find("#fm-Country-history").exists()).toBe(true); - await wrapper.find("#fm-Country-history .fm-delete").trigger("click"); + await wrapper.find("#fm-Country-history .fm-edit").trigger("click"); + expect(wrapper.find("#delete-metadata").exists()).toBe(true); + await wrapper.find("#delete-metadata").trigger("click"); expect(wrapper.find(".confirm-delete-field-metadata").exists()).toBe(true); await wrapper.find(".confirm-delete-field-metadata button.accept").trigger("click"); await flushPromises(); diff --git a/modules/admin/app/assets/js/dmeditor/app.vue b/modules/admin/app/assets/js/dmeditor/app.vue index d1947272cd..9f90a1bd61 100644 --- a/modules/admin/app/assets/js/dmeditor/app.vue +++ b/modules/admin/app/assets/js/dmeditor/app.vue @@ -1,6 +1,9 @@ - - diff --git a/modules/admin/app/assets/js/dmeditor/components/_modal-fm-editor.vue b/modules/admin/app/assets/js/dmeditor/components/_modal-fm-editor.vue index 447b9cf9b1..25a5bdbd5f 100644 --- a/modules/admin/app/assets/js/dmeditor/components/_modal-fm-editor.vue +++ b/modules/admin/app/assets/js/dmeditor/components/_modal-fm-editor.vue @@ -1,29 +1,34 @@