diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e4a775e..7ba709a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -12,7 +12,8 @@ "@vue-flow/core": "^1.45.0", "cytoscape": "^3.32.1", "pinia": "^3.0.3", - "vue": "^3.5.17" + "vue": "^3.5.17", + "vue-toastification": "^2.0.0-rc.5" }, "devDependencies": { "@tsconfig/node22": "^22.0.2", @@ -5249,6 +5250,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/vue-toastification": { + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz", + "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.2" + } + }, "node_modules/vue-tsc": { "version": "2.2.12", "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.12.tgz", diff --git a/frontend/package.json b/frontend/package.json index 0eafca3..97f7b8e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,7 +17,8 @@ "@vue-flow/core": "^1.45.0", "cytoscape": "^3.32.1", "pinia": "^3.0.3", - "vue": "^3.5.17" + "vue": "^3.5.17", + "vue-toastification": "^2.0.0-rc.5" }, "devDependencies": { "@tsconfig/node22": "^22.0.2", diff --git a/frontend/src/App.vue b/frontend/src/App.vue index cfad2b1..9a92e55 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -37,7 +37,9 @@ import DatabaseStep from "./components/steps/DatabaseStep.vue" import SchemaStep from "./components/steps/SchemaStep.vue" import GlobalModal from "@/components/modal/GlobalModal.vue" -const steps: Array = [SchemaStep, ProjectNameStep, DatabaseStep, SchemaStep] +import type { Component } from "vue" + +const steps: Component[] = [ProjectNameStep, DatabaseStep, SchemaStep] diff --git a/frontend/src/components/modal/AddEnumValueModal.vue b/frontend/src/components/modal/AddEnumValueModal.vue index b113fa0..f340cfe 100644 --- a/frontend/src/components/modal/AddEnumValueModal.vue +++ b/frontend/src/components/modal/AddEnumValueModal.vue @@ -3,12 +3,12 @@
- +
- +
@@ -22,6 +22,8 @@ import { ref } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" +import { isValidEnumValueName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ enumName: string @@ -34,6 +36,10 @@ const name = ref("") const value = ref("auto()") const saveEnumValue = () => { + if (!isValidEnumValueName(name.value)) { + showDangerToast(warningMessages.enumValueName) + return + } projectStore.addEnumValue(props.enumName, { name: name.value, value: value.value, diff --git a/frontend/src/components/modal/AddFieldModal.vue b/frontend/src/components/modal/AddFieldModal.vue index 2188857..ce6aec5 100644 --- a/frontend/src/components/modal/AddFieldModal.vue +++ b/frontend/src/components/modal/AddFieldModal.vue @@ -3,7 +3,7 @@
- +
@@ -44,10 +44,11 @@
@@ -77,6 +78,8 @@ import { ref, watch } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" import type { EnumT, FieldType } from "@/types/types" +import { isValidFieldName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ id: string @@ -143,6 +146,10 @@ watch(type, (newVal) => { const saveField = () => { if (!fieldName.value || !type.value) return + if (!isValidFieldName(fieldName.value)) { + showDangerToast(warningMessages.fieldName) + return + } projectStore.addField(props.id, { name: fieldName.value, type: type.value as FieldType, diff --git a/frontend/src/components/modal/AddRelationModal.vue b/frontend/src/components/modal/AddRelationModal.vue index 355a891..0263e73 100644 --- a/frontend/src/components/modal/AddRelationModal.vue +++ b/frontend/src/components/modal/AddRelationModal.vue @@ -3,7 +3,7 @@
- +
@@ -27,7 +27,7 @@
- +
@@ -47,6 +47,9 @@ import { ref, computed } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" +import type { OnDeleteType } from "@/types/types" +import { isValidFieldName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ id: string @@ -67,11 +70,15 @@ const filteredNodes = computed(() => projectStore.nodes.filter((node) => node.id const saveSelect = () => { if (!selectedNodeId.value || !fieldName.value) return + if (!isValidFieldName(fieldName.value)) { + showDangerToast(warningMessages.fieldName) + return + } projectStore.addRelation(props.id, selectedNodeId.value, { fieldName: fieldName.value, targetModel: selectedNodeId.value, backPopulates: backPopulates.value, - onDelete: onDelete.value, + onDelete: onDelete.value as OnDeleteType, isNullable: nullable.value, isUnique: unique.value, isIndex: indexed.value, diff --git a/frontend/src/components/modal/EditEnumValueModal.vue b/frontend/src/components/modal/EditEnumValueModal.vue index 95ceafa..ebf42f3 100644 --- a/frontend/src/components/modal/EditEnumValueModal.vue +++ b/frontend/src/components/modal/EditEnumValueModal.vue @@ -3,12 +3,12 @@
- +
- +
@@ -23,6 +23,8 @@ import { ref } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" import type { EnumValue } from "@/types/types" +import { isValidEnumValueName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ enumName: string @@ -36,6 +38,10 @@ const name = ref(props.enumValue.name) const value = ref(props.enumValue.value) const saveEnumValue = () => { + if (!isValidEnumValueName(name.value)) { + showDangerToast(warningMessages.enumValueName) + return + } projectStore.updateEnumValue(props.enumName, props.enumValue.name, { name: name.value, value: value.value, @@ -101,3 +107,5 @@ const saveEnumValue = () => { box-shadow: none; } + +function showDangerToast(modelName: any) { throw new Error("Function not implemented."); } diff --git a/frontend/src/components/modal/EditFieldModal.vue b/frontend/src/components/modal/EditFieldModal.vue index 4e53897..ed4fab2 100644 --- a/frontend/src/components/modal/EditFieldModal.vue +++ b/frontend/src/components/modal/EditFieldModal.vue @@ -3,7 +3,7 @@
- +
@@ -44,10 +44,11 @@
@@ -78,6 +79,8 @@ import { ref, onMounted, watch } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" import type { EnumT, RelationalField } from "@/types/types" +import { isValidFieldName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ id: string @@ -153,6 +156,10 @@ watch(type, (newVal) => { }) const saveField = () => { + if (!isValidFieldName(fieldName.value)) { + showDangerToast(warningMessages.fieldName) + return + } projectStore.updateField(props.id, props.field.name, { name: fieldName.value, type: type.value, diff --git a/frontend/src/components/modal/EditRelationModal.vue b/frontend/src/components/modal/EditRelationModal.vue index 1798958..7a3adfa 100644 --- a/frontend/src/components/modal/EditRelationModal.vue +++ b/frontend/src/components/modal/EditRelationModal.vue @@ -3,7 +3,7 @@
- +
@@ -49,6 +49,9 @@ import { ref, computed, onMounted } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" import type { RelationalRelationField } from "@/types.types" +import { isValidFieldName, warningMessages } from "@/utils/validation" +import type { OnDeleteType } from "@/types/types" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ id: string @@ -82,11 +85,15 @@ const filteredNodes = computed(() => projectStore.nodes.filter((node) => node.id const saveChanges = () => { if (!selectedNodeId.value || !fieldName.value) return + if (!isValidFieldName(fieldName.value)) { + showDangerToast(warningMessages.fieldName) + return + } projectStore.updateRelation(props.id, props.relation.targetModel, props.relation.fieldName, { fieldName: fieldName.value, targetModel: selectedNodeId.value, backPopulates: backPopulates.value, - onDelete: onDelete.value, + onDelete: onDelete.value as OnDeleteType, isNullable: nullable.value, isUnique: unique.value, isIndex: indexed.value, diff --git a/frontend/src/components/modal/RenameNodeModal.vue b/frontend/src/components/modal/RenameNodeModal.vue index d635747..2c68551 100644 --- a/frontend/src/components/modal/RenameNodeModal.vue +++ b/frontend/src/components/modal/RenameNodeModal.vue @@ -3,7 +3,7 @@
- +
@@ -17,6 +17,8 @@ import { ref } from "vue" import { useProjectStore } from "@/stores/useProjectStore" import { useModalStore } from "@/stores/useModalStore" +import { isValidModelName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const props = defineProps<{ id: string @@ -25,15 +27,20 @@ const props = defineProps<{ const projectStore = useProjectStore() const modalStore = useModalStore() -const newNodeId = ref(props.id) +const nodeId = ref(props.id) const rename = () => { - if (!newNodeId.value.trim() || newNodeId.value === props.id) { + const newNodeId = nodeId.value.trim() + if (!isValidModelName(newNodeId)) { + showDangerToast(warningMessages.modelName) + return + } + if (!newNodeId || nodeId.value === props.id) { modalStore.close() return } - projectStore.renameNode(props.id, newNodeId.value.trim()) + projectStore.renameNode(props.id, newNodeId) modalStore.close() } diff --git a/frontend/src/components/schema_editor/EnumEditor.vue b/frontend/src/components/schema_editor/EnumEditor.vue index 118740a..f1f6180 100644 --- a/frontend/src/components/schema_editor/EnumEditor.vue +++ b/frontend/src/components/schema_editor/EnumEditor.vue @@ -11,7 +11,7 @@ placeholder="Enter new enum name" v-model="newEnumName" @keyup.enter="createEnum" - maxlength="50" + maxlength="100" />
@@ -154,6 +155,8 @@ import { useModalStore } from "@/stores/useModalStore" import AddEnumValueModal from "@/components/modal/AddEnumValueModal.vue" import EditEnumValueModal from "@/components/modal/EditEnumValueModal.vue" import type { EnumT, EnumValue } from "@/types/types" +import { isValidEnumName, warningMessages } from "@/utils/validation" +import { showDangerToast } from "@/utils/toast" const projectStore = useProjectStore() const modalStore = useModalStore() @@ -188,6 +191,10 @@ const selectEnum = (e: EnumT) => { const createEnum = () => { const name = newEnumName.value.trim() if (name === "") return + if (!isValidEnumName(name)) { + showDangerToast(warningMessages.enumName) + return + } const newEnum = projectStore.addEnum(name) newEnumName.value = "" selectEnum(newEnum) @@ -210,20 +217,19 @@ const handleEditToggle = (enumItem: EnumT) => { } else { editingEnumName.value = enumItem.name editedEnumName.value = enumItem.name - nextTick(() => { - if (enumNameInput.value) { - enumNameInput.value.focus() - } - }) } } const saveEnumName = (enumItem: EnumT) => { const newName = editedEnumName.value.trim() if (newName && newName !== enumItem.name) { - projectStore.updateEnumName(enumItem.name, newName) - if (selectedEnum.value?.name === enumItem.name) { - selectedEnum.value.name = newName + if (!isValidEnumName(newName)) { + showDangerToast(warningMessages.enumName) + } else { + projectStore.updateEnumName(enumItem.name, newName) + if (selectedEnum.value?.name === enumItem.name) { + selectedEnum.value.name = newName + } } } editingEnumName.value = null diff --git a/frontend/src/components/schema_editor/SchemaEditor.vue b/frontend/src/components/schema_editor/SchemaEditor.vue index f85dd96..f0d22b9 100644 --- a/frontend/src/components/schema_editor/SchemaEditor.vue +++ b/frontend/src/components/schema_editor/SchemaEditor.vue @@ -2,7 +2,6 @@
-
#