Skip to content

Commit

Permalink
Ontology CRUD UI (#140)
Browse files Browse the repository at this point in the history
* basic structure in place

* completed relationship keys

* fixed validation, metatype relationship pairs UI CRUD

* corrected clearable chips, modified update keys function

* required edit changed, fixed default value boolean

* corrected translations and data tables updates

Co-authored-by: Darrington, John Wayne <[email protected]>
  • Loading branch information
DnOberon and DnOberon authored Feb 8, 2021
1 parent 14f0ae2 commit fe6cc9f
Show file tree
Hide file tree
Showing 26 changed files with 2,083 additions and 550 deletions.
5 changes: 5 additions & 0 deletions migrations/036_default_value_keys.sql
Original file line number Diff line number Diff line change
@@ -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);
29 changes: 22 additions & 7 deletions src/data_storage/metatype_key_storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}'`,
Expand Down Expand Up @@ -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]
}
}

Expand Down Expand Up @@ -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]
}
}
}
23 changes: 19 additions & 4 deletions src/data_storage/metatype_relationship_key_storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand All @@ -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}'`,
Expand Down Expand Up @@ -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]
}
}

Expand Down Expand Up @@ -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]
}
}
}
1 change: 1 addition & 0 deletions src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
48 changes: 36 additions & 12 deletions web_ui/src/api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,16 @@ export class Client {
}


createMetatype(containerID: string, metatype: any): Promise<MetatypeT> {
return this.post<MetatypeT>(`/containers/${containerID}/metatypes`, metatype)
createMetatype(containerID: string, name: string, description: string): Promise<MetatypeT[]> {
return this.post<MetatypeT[]>(`/containers/${containerID}/metatypes`, {name, description})
}

retrieveMetatype(containerID: string, metatypeID: string): Promise<MetatypeT> {
return this.get<MetatypeT>(`/containers/${containerID}/metatypes/${metatypeID}`)
}

updateMetatype(containerID: string, metatypeID: string, metatype: any): Promise<MetatypeT> {
return this.put<MetatypeT>(`/containers/${containerID}/metatypes/${metatypeID}`, metatype)
updateMetatype(containerID: string, metatypeID: string, metatype: any): Promise<boolean> {
return this.put<boolean>(`/containers/${containerID}/metatypes/${metatypeID}`, metatype)
}

deleteMetatype(containerID: string, metatypeID: string): Promise<boolean> {
Expand All @@ -152,6 +152,18 @@ export class Client {
return this.get<MetatypeKeyT[]>(`/containers/${containerID}/metatypes/${metatypeID}/keys`)
}

createMetatypeKey(containerID: string, metatypeID: string, key: MetatypeKeyT): Promise<MetatypeKeyT[]> {
return this.post<MetatypeKeyT[]>(`/containers/${containerID}/metatypes/${metatypeID}/keys`, key)
}

deleteMetatypeKey(containerID: string, metatypeID: string, keyID: string): Promise<boolean> {
return this.delete(`/containers/${containerID}/metatypes/${metatypeID}/keys/${keyID}`)
}

updateMetatypeKey(containerID: string, metatypeID: string, keyID: string, key: MetatypeKeyT): Promise<boolean> {
return this.put<boolean>(`/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<MetatypeRelationshipT[] | number> {
const query: {[key: string]: any} = {}

Expand All @@ -170,28 +182,28 @@ export class Client {
return this.get<MetatypeRelationshipT>(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`)
}

createMetatypeRelationship(containerID: string, metatypeRelationship: any): Promise<MetatypeRelationshipT> {
return this.post<MetatypeRelationshipT>(`/containers/${containerID}/metatype_relationships`, metatypeRelationship)
createMetatypeRelationship(containerID: string, name: string, description: string): Promise<MetatypeRelationshipT[]> {
return this.post<MetatypeRelationshipT[]>(`/containers/${containerID}/metatype_relationships`, {name, description})
}

retrieveMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string): Promise<MetatypeRelationshipPairT> {
return this.get<MetatypeRelationshipPairT>(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`)
}

updateMetatypeRelationship(containerID: string, metatypeRelationshipID: string, metatypeRelationship: any): Promise<MetatypeRelationshipT> {
return this.put<MetatypeRelationshipT>(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`, metatypeRelationship)
updateMetatypeRelationship(containerID: string, metatypeRelationshipID: string, metatypeRelationship: any): Promise<boolean> {
return this.put<boolean>(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`, metatypeRelationship)
}

deleteMetatypeRelationship(containerID: string, metatypeRelationshipID: string): Promise<boolean> {
return this.delete(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}`)
}

createMetatypeRelationshipPair(containerID: string, metatypeRelationshipPair: any): Promise<MetatypeRelationshipPairT> {
return this.post<MetatypeRelationshipPairT>(`/containers/${containerID}/metatype_relationship_pairs`, metatypeRelationshipPair)
createMetatypeRelationshipPair(containerID: string, metatypeRelationshipPair: any): Promise<MetatypeRelationshipPairT[]> {
return this.post<MetatypeRelationshipPairT[]>(`/containers/${containerID}/metatype_relationship_pairs`, metatypeRelationshipPair)
}

updateMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string, metatypeRelationshipPair: any): Promise<MetatypeRelationshipPairT> {
return this.put<MetatypeRelationshipPairT>(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`, metatypeRelationshipPair)
updateMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string, metatypeRelationshipPair: any): Promise<boolean> {
return this.put<boolean>(`/containers/${containerID}/metatype_relationship_pairs/${metatypeRelationshipPairID}`, metatypeRelationshipPair)
}

deleteMetatypeRelationshipPair(containerID: string, metatypeRelationshipPairID: string): Promise<boolean> {
Expand All @@ -202,6 +214,18 @@ export class Client {
return this.get<MetatypeRelationshipKeyT[]>(`/containers/${containerID}/metatype_relationships/${relationshipID}/keys`)
}

deleteMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, keyID: string): Promise<boolean> {
return this.delete(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys/${keyID}`)
}

createMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, key: MetatypeRelationshipKeyT): Promise<MetatypeRelationshipKeyT[]> {
return this.post<MetatypeRelationshipKeyT[]>(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys`, key)
}

updateMetatypeRelationshipKey(containerID: string, metatypeRelationshipID: string, keyID: string, key: MetatypeRelationshipKeyT): Promise<boolean> {
return this.put<boolean>(`/containers/${containerID}/metatype_relationships/${metatypeRelationshipID}/keys/${keyID}`, key)
}

createDataSource(containerID: string, dataSource: any): Promise<DataSourceT> {
return this.post<DataSourceT>(`/containers/${containerID}/import/datasources`, dataSource)
}
Expand Down
6 changes: 1 addition & 5 deletions web_ui/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
95 changes: 95 additions & 0 deletions web_ui/src/components/createMetatypeDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<template>
<v-dialog v-model="dialog" @click:outside="dialog = false; reset()" max-width="60%">
<template v-slot:activator="{ on }">
<v-icon
v-if="icon"
small
class="mr-2"
v-on="on"
>mdi-card-plus</v-icon>
<v-btn v-if="!icon" color="primary" dark class="mb-2" v-on="on">{{$t("createMetatype.createMetatype")}}</v-btn>
</template>

<v-card>
<v-card-text>
<v-container>
<error-banner :message="errorMessage"></error-banner>
<span class="headline">{{$t('createMetatype.newMetatype')}}</span>
<v-row>
<v-col :cols="12">

<v-form
ref="form"
v-model="valid"
>
<v-text-field
v-model="name"
:rules="[v => !!v || $t('createMetatype.nameRequired')]"
required
>
<template v-slot:label>{{$t('createMetatype.name')}} <small style="color:red" >*</small></template>
</v-text-field>
<v-textarea
v-model="description"
required
:rules="[v => !!v || $t('createMetatype.nameRequired')]"
>
<template v-slot:label>{{$t('createMetatype.description')}} <small style="color:red" >*</small></template>
</v-textarea>
</v-form>
<p><span style="color:red">*</span> = {{$t('createMetatype.requiredField')}}</p>
</v-col>
</v-row>
</v-container>
</v-card-text>

<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text @click="dialog = false; reset()" >{{$t("createMetatype.cancel")}}</v-btn>
<v-btn color="blue darken-1" :disabled="!valid" text @click="createMetatype()">{{$t("createMetatype.save")}}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>

<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator'
@Component
export default class CreateMetatypeDialog extends Vue {
@Prop({required: true})
containerID!: string;
@Prop({required: false})
readonly icon!: boolean
errorMessage = ""
dialog = false
name = ""
description = ""
valid = false
createMetatype() {
this.$client.createMetatype(this.containerID, this.name, this.description)
.then(result => {
if(!result) {
this.errorMessage = this.$t('createMetatype.errorCreatingAPI') as string
} else {
this.dialog = false
// emit only the first object in the result array, as we're only creating
// a single metatype
this.$emit('metatypeCreated', result[0])
this.reset()
}
})
.catch(e => this.errorMessage = this.$t('createMetatype.errorCreatingAPI') as string + e)
}
reset() {
this.name = ""
this.description = ""
}
}
</script>
Loading

0 comments on commit fe6cc9f

Please sign in to comment.