diff --git a/migrations/036_default_value_keys.sql b/migrations/036_default_value_keys.sql new file mode 100644 index 000000000..c018e8286 --- /dev/null +++ b/migrations/036_default_value_keys.sql @@ -0,0 +1,5 @@ +ALTER TABLE metatype_keys ALTER COLUMN default_value TYPE jsonb USING default_value::jsonb; +ALTER TABLE metatype_relationship_keys ALTER COLUMN default_value TYPE jsonb USING default_value::jsonb; + +ALTER TABLE metatype_keys ALTER COLUMN options TYPE jsonb USING to_jsonb(options); +ALTER TABLE metatype_relationship_keys ALTER COLUMN options TYPE jsonb USING to_jsonb(options); diff --git a/src/data_storage/metatype_key_storage.ts b/src/data_storage/metatype_key_storage.ts index aa548b0c6..b1c0fb8c7 100644 --- a/src/data_storage/metatype_key_storage.ts +++ b/src/data_storage/metatype_key_storage.ts @@ -124,14 +124,29 @@ export default class MetatypeKeyStorage extends PostgresStorage{ let i = 1; Object.keys(updatedField).map(k => { - updateStatement.push(`${k} = $${i}`); - values.push(updatedField[k]); - i++ + if(k === `created_at` || k === `created_by` || k === 'modified_at' || k === 'modified_by') { + return + } + + // we must stringify the default value as it could be something other + // than a string, we store it as a string in the DB for ease of use + if(k === 'default_value' || k === 'options') { + updateStatement.push(`${k} = $${i}`); + values.push(JSON.stringify(updatedField[k])); + i++ + return + } + + updateStatement.push(`${k} = $${i}`); + values.push(updatedField[k]); + i++ }); updateStatement.push(`modified_by = $${i}`); values.push(userID); + updateStatement.push('modified_at = NOW()') + return new Promise(resolve => { PostgresAdapter.Instance.Pool.query({ text: `UPDATE metatype_keys SET ${updateStatement.join(",")} WHERE id = '${id}'`, @@ -246,8 +261,8 @@ INSERT INTO metatype_keys(metatype_id, id, name, description, property_name, required, data_type, options, default_value, validation, created_by, modified_by) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, values: [key.metatype_id, key.id, key.name, key.description, - key.property_name, key.required, key.data_type, key.options, - key.default_value, key.validation, key.created_by, key.modified_by] + key.property_name, key.required, key.data_type, JSON.stringify(key.options), + JSON.stringify(key.default_value), key.validation, key.created_by, key.modified_by] } } @@ -291,8 +306,8 @@ VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, validation = $8 WHERE id = $9`, values: [key.name, key.description, - key.property_name, key.required, key.data_type, key.options, - key.default_value,key.validation, key.id] + key.property_name, key.required, key.data_type, JSON.stringify(key.options), + JSON.stringify(key.default_value),key.validation, key.id] } } } diff --git a/src/data_storage/metatype_relationship_key_storage.ts b/src/data_storage/metatype_relationship_key_storage.ts index 1e98b8f84..2345edfbb 100644 --- a/src/data_storage/metatype_relationship_key_storage.ts +++ b/src/data_storage/metatype_relationship_key_storage.ts @@ -127,6 +127,19 @@ export default class MetatypeRelationshipKeyStorage extends PostgresStorage{ let i = 1; Object.keys(updatedField).map(k => { + if(k === `created_at` || k === `created_by` || k === 'modified_at' || k === 'modified_by') { + return + } + + // we must stringify the default value as it could be something other + // than a string, we store it as a string in the DB for ease of use + if(k === 'default_value' || k === 'options') { + updateStatement.push(`${k} = $${i}`); + values.push(JSON.stringify(updatedField[k])); + i++ + return + } + updateStatement.push(`${k} = $${i}`); values.push(updatedField[k]); i++ @@ -135,6 +148,8 @@ export default class MetatypeRelationshipKeyStorage extends PostgresStorage{ updateStatement.push(`modified_by = $${i}`); values.push(userID); + updateStatement.push('modified_at = NOW()') + return new Promise(resolve => { PostgresAdapter.Instance.Pool.query({ text: `UPDATE metatype_relationship_keys SET ${updateStatement.join(",")} WHERE id = '${id}'`, @@ -252,8 +267,8 @@ export default class MetatypeRelationshipKeyStorage extends PostgresStorage{ text:`INSERT INTO metatype_relationship_keys(metatype_relationship_id, id, name, description, property_name, required, data_type, options, default_value,validation, created_by, modified_by) VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, values: [key.metatype_relationship_id, key.id, key.name, key.description, - key.property_name, key.required, key.data_type, key.options, - key.default_value,key.validation, key.created_by, key.modified_by] + key.property_name, key.required, key.data_type, JSON.stringify(key.options), + JSON.stringify(key.default_value),key.validation, key.created_by, key.modified_by] } } @@ -297,8 +312,8 @@ VALUES($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, validation = $8 WHERE id = $9`, values: [key.name, key.description, - key.property_name, key.required, key.data_type, key.options, - key.default_value,key.validation, key.id] + key.property_name, key.required, key.data_type, JSON.stringify(key.options), + JSON.stringify(key.default_value),key.validation, key.id] } } } diff --git a/src/logger.ts b/src/logger.ts index 525a80ec0..9399d0b25 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -39,6 +39,7 @@ export class Winston implements Logger { private constructor() { this.logger = winston.createLogger({ level: Config.log_level, + silent: Config.log_level === 'silent', transports: [ new winston.transports.Console({ format: winston.format.combine( diff --git a/web_ui/src/api/client.ts b/web_ui/src/api/client.ts index 9ebf13f85..3f5a9298a 100644 --- a/web_ui/src/api/client.ts +++ b/web_ui/src/api/client.ts @@ -132,16 +132,16 @@ export class Client { } - createMetatype(containerID: string, metatype: any): Promise { - return this.post(`/containers/${containerID}/metatypes`, metatype) + createMetatype(containerID: string, name: string, description: string): Promise { + return this.post(`/containers/${containerID}/metatypes`, {name, description}) } retrieveMetatype(containerID: string, metatypeID: string): Promise { return this.get(`/containers/${containerID}/metatypes/${metatypeID}`) } - updateMetatype(containerID: string, metatypeID: string, metatype: any): Promise { - return this.put(`/containers/${containerID}/metatypes/${metatypeID}`, metatype) + updateMetatype(containerID: string, metatypeID: string, metatype: any): Promise { + return this.put(`/containers/${containerID}/metatypes/${metatypeID}`, metatype) } deleteMetatype(containerID: string, metatypeID: string): Promise { @@ -152,6 +152,18 @@ export class Client { return this.get(`/containers/${containerID}/metatypes/${metatypeID}/keys`) } + createMetatypeKey(containerID: string, metatypeID: string, key: MetatypeKeyT): Promise { + return this.post(`/containers/${containerID}/metatypes/${metatypeID}/keys`, key) + } + + deleteMetatypeKey(containerID: string, metatypeID: string, keyID: string): Promise { + return this.delete(`/containers/${containerID}/metatypes/${metatypeID}/keys/${keyID}`) + } + + updateMetatypeKey(containerID: string, metatypeID: string, keyID: string, key: MetatypeKeyT): Promise { + return this.put(`/containers/${containerID}/metatypes/${metatypeID}/keys/${keyID}`, key) + } + listMetatypeRelationships(containerID: string, {name, description, limit, offset, sortBy, sortDesc, count}: {name?: string; description?: string; limit?: number; offset?: number; sortBy?: string; sortDesc?: boolean; count?: boolean}): Promise { const query: {[key: string]: any} = {} @@ -170,28 +182,28 @@ export class Client { return this.get(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`) } - createMetatypeRelationship(containerID: string, metatypeRelationship: any): Promise { - return this.post(`/containers/${containerID}/metatype_relationships`, metatypeRelationship) + createMetatypeRelationship(containerID: string, name: string, description: string): Promise { + return this.post(`/containers/${containerID}/metatype_relationships`, {name, description}) } retrieveMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string): Promise { return this.get(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`) } - updateMetatypeRelationship(containerID: string, metatypeRelationshipID: string, metatypeRelationship: any): Promise { - return this.put(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`, metatypeRelationship) + updateMetatypeRelationship(containerID: string, metatypeRelationshipID: string, metatypeRelationship: any): Promise { + return this.put(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`, metatypeRelationship) } deleteMetatypeRelationship(containerID: string, metatypeRelationshipID: string): Promise { return this.delete(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`) } - createMetatypeRelationshipPair(containerID: string, metatypeRelationshipPair: any): Promise { - return this.post(`/containers/${containerID}/metatype_relationship_pairs`, metatypeRelationshipPair) + createMetatypeRelationshipPair(containerID: string, metatypeRelationshipPair: any): Promise { + return this.post(`/containers/${containerID}/metatype_relationship_pairs`, metatypeRelationshipPair) } - updateMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string, metatypeRelationshipPair: any): Promise { - return this.put(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`, metatypeRelationshipPair) + updateMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string, metatypeRelationshipPair: any): Promise { + return this.put(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`, metatypeRelationshipPair) } deleteMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string): Promise { @@ -202,6 +214,18 @@ export class Client { return this.get(`/containers/${containerID}/metatype_relationships/${relationshipID}/keys`) } + deleteMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, keyID: string): Promise { + return this.delete(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys/${keyID}`) + } + + createMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, key: MetatypeRelationshipKeyT): Promise { + return this.post(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys`, key) + } + + updateMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, keyID: string, key: MetatypeRelationshipKeyT): Promise { + return this.put(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys/${keyID}`, key) + } + createDataSource(containerID: string, dataSource: any): Promise { return this.post(`/containers/${containerID}/import/datasources`, dataSource) } diff --git a/web_ui/src/api/types.ts b/web_ui/src/api/types.ts index 470fff458..930c528c7 100644 --- a/web_ui/src/api/types.ts +++ b/web_ui/src/api/types.ts @@ -57,13 +57,11 @@ export type MetatypeKeyT= { description: string; data_type: "number" | "date" | "string" | "boolean" | "enumeration" | "file"; archived: boolean; - cardinality: number | undefined; validation: { regex: string; min: number; max: number; } | undefined; - unique: boolean; options: string[] | undefined; default_value: string | boolean | number | any[] | undefined; created_at: string; @@ -81,13 +79,11 @@ export type MetatypeRelationshipKeyT= { description: string; data_type: "number" | "date" | "string" | "boolean" | "enumeration" | "file"; archived: boolean; - cardinality: number | undefined; validation: { regex: string; min: number; max: number; - } | undefined; - unique: boolean; + }; options: string[] | undefined; default_value: string | boolean | number | any[] | undefined; created_at: string; diff --git a/web_ui/src/components/createMetatypeDialog.vue b/web_ui/src/components/createMetatypeDialog.vue new file mode 100644 index 000000000..a60363697 --- /dev/null +++ b/web_ui/src/components/createMetatypeDialog.vue @@ -0,0 +1,95 @@ + + + diff --git a/web_ui/src/components/createMetatypeKeyDialog.vue b/web_ui/src/components/createMetatypeKeyDialog.vue new file mode 100644 index 000000000..6c28ee2e0 --- /dev/null +++ b/web_ui/src/components/createMetatypeKeyDialog.vue @@ -0,0 +1,186 @@ + + + diff --git a/web_ui/src/components/createMetatypeRelationshipDialog.vue b/web_ui/src/components/createMetatypeRelationshipDialog.vue new file mode 100644 index 000000000..686c06807 --- /dev/null +++ b/web_ui/src/components/createMetatypeRelationshipDialog.vue @@ -0,0 +1,95 @@ + + + diff --git a/web_ui/src/components/createMetatypeRelationshipKeyDialog.vue b/web_ui/src/components/createMetatypeRelationshipKeyDialog.vue new file mode 100644 index 000000000..f31d2b47f --- /dev/null +++ b/web_ui/src/components/createMetatypeRelationshipKeyDialog.vue @@ -0,0 +1,182 @@ + + + diff --git a/web_ui/src/components/createRelationshipPairDialog.vue b/web_ui/src/components/createRelationshipPairDialog.vue new file mode 100644 index 000000000..3b3a246e9 --- /dev/null +++ b/web_ui/src/components/createRelationshipPairDialog.vue @@ -0,0 +1,190 @@ + + + diff --git a/web_ui/src/components/dataTypeMapping.vue b/web_ui/src/components/dataTypeMapping.vue index 416c07647..b9d726c58 100644 --- a/web_ui/src/components/dataTypeMapping.vue +++ b/web_ui/src/components/dataTypeMapping.vue @@ -77,13 +77,11 @@ diff --git a/web_ui/src/components/editMetatypeKeyDialog.vue b/web_ui/src/components/editMetatypeKeyDialog.vue new file mode 100644 index 000000000..a11ac903f --- /dev/null +++ b/web_ui/src/components/editMetatypeKeyDialog.vue @@ -0,0 +1,199 @@ + + + diff --git a/web_ui/src/components/editMetatypeRelationshipDialog.vue b/web_ui/src/components/editMetatypeRelationshipDialog.vue new file mode 100644 index 000000000..7fd718fe2 --- /dev/null +++ b/web_ui/src/components/editMetatypeRelationshipDialog.vue @@ -0,0 +1,183 @@ + + + diff --git a/web_ui/src/components/editMetatypeRelationshipKeyDialog.vue b/web_ui/src/components/editMetatypeRelationshipKeyDialog.vue new file mode 100644 index 000000000..944ac904d --- /dev/null +++ b/web_ui/src/components/editMetatypeRelationshipKeyDialog.vue @@ -0,0 +1,201 @@ + + + diff --git a/web_ui/src/components/editRelationshipPairDialog.vue b/web_ui/src/components/editRelationshipPairDialog.vue new file mode 100644 index 000000000..490e32346 --- /dev/null +++ b/web_ui/src/components/editRelationshipPairDialog.vue @@ -0,0 +1,176 @@ + + + diff --git a/web_ui/src/components/newContainerDialog.vue b/web_ui/src/components/newContainerDialog.vue index 1ac32958c..a6d3d3e3a 100644 --- a/web_ui/src/components/newContainerDialog.vue +++ b/web_ui/src/components/newContainerDialog.vue @@ -65,11 +65,8 @@ diff --git a/web_ui/src/views/MetatypeRelationships.vue b/web_ui/src/views/MetatypeRelationships.vue index 82b58bdf3..33ee2deff 100644 --- a/web_ui/src/views/MetatypeRelationships.vue +++ b/web_ui/src/views/MetatypeRelationships.vue @@ -7,6 +7,7 @@ :options.sync="options" :loading="loading" :items-per-page="100" + :item-key="id" :footer-props="{ 'items-per-page-options': [25, 50, 100] }" @@ -15,6 +16,12 @@ - - - - - Edit {{selectedRelationship.name}} - - - - - - - - - - - - - - - - - - - - {{$t("home.cancel")}} - {{$t("home.save")}} - - - diff --git a/web_ui/src/views/Metatypes.vue b/web_ui/src/views/Metatypes.vue index 7849cd567..4b1f8d448 100644 --- a/web_ui/src/views/Metatypes.vue +++ b/web_ui/src/views/Metatypes.vue @@ -10,12 +10,19 @@ :footer-props="{ 'items-per-page-options': [25, 50, 100] }" + :item-key="id" class="elevation-1" > - - - - - Edit {{selectedMetatype.name}} - - - - - - - - - - - - - - - - - - - - {{$t("home.cancel")}} - {{$t("home.save")}} - - -