Skip to content

Commit 4cf7874

Browse files
authored
Feat: Add validation check and alert user before saving the file (#164)
* feat: added validation check for save * fix: update font weight for alert title
1 parent 2d6187b commit 4cf7874

File tree

5 files changed

+114
-2
lines changed

5 files changed

+114
-2
lines changed

public/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const schemaMap = [
2424
schema: {
2525
title: "FooBar editor",
2626
type: "object",
27+
required: ["foo"],
2728
properties: {
2829
id: {
2930
type: "string",
@@ -35,6 +36,7 @@ const schemaMap = [
3536
title: "Foo",
3637
type: "string",
3738
description: "Simple string input",
39+
minLength: 1,
3840
options: {
3941
inputAttributes: {
4042
placeholder: "Type something...",

src/assets/main.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,13 @@ html {
7878
.z-index {
7979
z-index: 1;
8080
}
81+
82+
.v-alert__content {
83+
font-size: 0.875rem;
84+
color: rgb(var(--v-theme-on-surface));
85+
}
86+
87+
.v-alert__content .v-alert-title {
88+
font-size: 1rem;
89+
font-weight: 700;
90+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<script setup>
2+
import { ref, watch } from "vue";
3+
4+
const props = defineProps({
5+
validationErrors: {
6+
type: Array,
7+
required: true,
8+
},
9+
closeValidationErrors: {
10+
type: Function,
11+
required: true,
12+
},
13+
saveFile: {
14+
type: Function,
15+
required: true,
16+
},
17+
});
18+
19+
const validateBind = ref(true);
20+
</script>
21+
22+
<template>
23+
<v-dialog
24+
v-model="validateBind"
25+
width="auto"
26+
@update:model-value="!$event && closeValidationErrors()"
27+
>
28+
<v-card class="rounded-lg">
29+
<template v-slot:text>
30+
<h2 class="text-center pl-3 pr-3">
31+
File contains incomplete or invalid fields.
32+
</h2>
33+
34+
<v-alert
35+
class="my-6"
36+
text="There are issues in this file. You can fix the fields or continue saving with errors."
37+
title="Validation Issues Detected"
38+
type="warning"
39+
variant="tonal"
40+
icon="mdi-alert"
41+
rounded="lg"
42+
></v-alert>
43+
<div class="d-flex ga-4">
44+
<div class="flex-grow-1">
45+
<v-btn
46+
variant="tonal"
47+
block
48+
color="primary"
49+
prepend-icon="mdi-arrow-left"
50+
@click="closeValidationErrors"
51+
>
52+
Back to Editing
53+
</v-btn>
54+
</div>
55+
<div class="flex-grow-1">
56+
<v-btn
57+
block
58+
color="primary"
59+
variant="flat"
60+
prepend-icon="mdi-alert"
61+
@click="saveFile"
62+
>
63+
Save Anyway
64+
</v-btn>
65+
</div>
66+
</div>
67+
</template>
68+
</v-card>
69+
</v-dialog>
70+
</template>
71+
72+
<style>
73+
.v-card {
74+
max-width: 480px !important;
75+
}
76+
.v-card-text {
77+
padding: 1.5rem !important;
78+
}
79+
</style>

src/components/file/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export { default as RenameFile } from "./Rename.vue";
77
export { default as PreviewBtn } from "./Preview.vue";
88
export { default as Github } from "./Github.vue";
99
export { default as UploadArea } from "./UplaodArea.vue";
10+
export { default as ValidationError } from "./ValidationError.vue";

src/views/FileEditView.vue

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ import {
2323
jsonSchemaFileChangeMethod,
2424
addPostMessageEventMethod,
2525
} from "../methods/file-edit-view";
26-
import { ActionTabFileEditor } from "@/components/file/index.js";
26+
import {
27+
ActionTabFileEditor,
28+
ValidationError,
29+
} from "@/components/file/index.js";
2730
import debounce from "lodash.debounce";
2831
import "@eox/jsonform";
2932
import "@eox/drawtools";
@@ -47,6 +50,7 @@ const schemaMetaDetails = ref(null);
4750
const customInterfaces = ref([]);
4851
const previewExpanded = ref(false);
4952
const showPreview = ref(window.innerWidth >= 960);
53+
const validationErrors = ref([]);
5054
5155
const snackbar = inject("set-snackbar");
5256
const navButtonConfig = inject("set-nav-button-config");
@@ -102,6 +106,7 @@ const updateFileDetails = async (cache = true) => {
102106
};
103107
104108
const saveFile = async () => {
109+
validationErrors.value = [];
105110
const loader = useLoader().show(
106111
{},
107112
{
@@ -166,11 +171,20 @@ const saveFile = async () => {
166171
loader.hide();
167172
};
168173
174+
const validateFileBeforeSave = () => {
175+
validationErrors.value = jsonFormInstance.value.editor.validate();
176+
if (validationErrors.value.length === 0) saveFile();
177+
};
178+
179+
const closeValidationErrors = () => {
180+
validationErrors.value = [];
181+
};
182+
169183
const updateNavButtonConfig = (text = "Saved", disabled = true) => {
170184
navButtonConfig.value = {
171185
text,
172186
disabled,
173-
click: () => saveFile(),
187+
click: () => validateFileBeforeSave(),
174188
icon: "mdi-cloud-upload-outline",
175189
};
176190
reset.value = disabled;
@@ -289,6 +303,12 @@ onUnmounted(() => {
289303
</v-col>
290304
</v-row>
291305
</div>
306+
<ValidationError
307+
v-if="validationErrors.length > 0"
308+
:validationErrors="validationErrors"
309+
:closeValidationErrors="closeValidationErrors"
310+
:saveFile="saveFile"
311+
/>
292312
</template>
293313

294314
<style>

0 commit comments

Comments
 (0)