-
+
{{ proxy.$store.state.version }}
@@ -45,8 +50,42 @@
\ No newline at end of file
diff --git a/web/src/pages/Logs.vue b/web/src/pages/Logs.vue
index f76486f6..fbdfb72a 100644
--- a/web/src/pages/Logs.vue
+++ b/web/src/pages/Logs.vue
@@ -18,6 +18,10 @@
import PageTitle from '@/components/PageTitle.vue'
import { ref, getCurrentInstance, onMounted, onUnmounted } from 'vue'
+import {inject} from "vue";
+
+const snackbar = inject('snackbar');
+
const { proxy } = getCurrentInstance()
const logContent = ref('')
@@ -38,9 +42,15 @@ const refreshLog = () => {
start_offset: logPointer.start_offset
}
}).then(response => {
+ if (response.data.code != 0) {
+ snackbar.error(response.data.message)
+ return
+ }
logContent.value += response.data.data.logs
logPointer.start_page_number = response.data.data.end_page_number
logPointer.start_offset = response.data.data.end_offset
+ }).catch(error => {
+ snackbar.error(error.message)
})
}
diff --git a/web/src/pages/Settings.vue b/web/src/pages/Settings.vue
index 216ea7f6..adc40b57 100644
--- a/web/src/pages/Settings.vue
+++ b/web/src/pages/Settings.vue
@@ -15,15 +15,15 @@
-
+
-
+
-
+
mdi-view-dashboard-edit-outline
-
+
mdi-code-json
@@ -31,19 +31,24 @@
- 重置
- 应用
+ 重置
+ 应用
+
-
+
+
+
-
+
+
+
*JSON 格式不正确: {{ errorMessage }}
@@ -56,52 +61,183 @@
import PageTitle from '@/components/PageTitle.vue'
import { ref, getCurrentInstance, onMounted } from 'vue'
+import {inject} from "vue";
+
+const snackbar = inject('snackbar');
+
+import Vjsf from '@koumoul/vjsf';
+
const { proxy } = getCurrentInstance()
const managerList = ref([])
const configType = ref('json') // ui or json
const currentManager = ref(null)
-const currentManagerData = ref('')
+const currentManagerData = ref({})
+const currentManagerDataEditorString = ref('')
+const currentManagerSchema = ref(null)
const modified = ref(false)
+const VJSFOptions = {
+ "context": {},
+ "width": 1208,
+ "readOnly": false,
+ "summary": false,
+ "density": "comfortable",
+ "indent": true,
+ "titleDepth": 4,
+ "validateOn": "input",
+ "initialValidation": "withData",
+ "updateOn": "input",
+ "debounceInputMs": 300,
+ "defaultOn": "empty",
+ "removeAdditional": "error",
+ "autofocus": false,
+ "readOnlyPropertiesMode": "show",
+ "pluginsOptions": {},
+ "locale": "en",
+ "messages": {
+ "errorOneOf": "请选择一个",
+ "errorRequired": "必填信息",
+ "addItem": "添加",
+ "delete": "删除",
+ "edit": "编辑",
+ "close": "关闭",
+ "duplicate": "复制",
+ "sort": "排序",
+ "up": "向上移动",
+ "down": "向下移动",
+ "showHelp": "显示帮助信息",
+ "mdeLink1": "[链接标题",
+ "mdeLink2": "](链接地址)",
+ "mdeImg1": "",
+ "mdeTable1": "",
+ "mdeTable2": "\n\n| 列 1 | 列 2 | 列 3 |\n| -------- | -------- | -------- |\n| 文本 | 文本 | 文本 |\n\n",
+ "bold": "加粗",
+ "italic": "斜体",
+ "heading": "标题",
+ "quote": "引用",
+ "unorderedList": "无序列表",
+ "orderedList": "有序列表",
+ "createLink": "创建链接",
+ "insertImage": "插入图片",
+ "createTable": "创建表格",
+ "preview": "预览",
+ "mdeGuide": "文档",
+ "undo": "撤销",
+ "redo": "重做"
+ }
+}
+
const refresh = () => {
proxy.$axios.get('/settings').then(response => {
+
+ if (response.data.code != 0) {
+ snackbar.error(response.data.msg)
+ return
+ }
+
managerList.value = response.data.data.managers
- if (proxy.$store.state.settingsPageTab != '') {
- fetchCurrentManagerData(proxy.$store.state.settingsPageTab)
+ if (proxy.$store.state.settingsPageTab == '') {
+ proxy.$store.state.settingsPageTab = managerList.value[0].name
}
+ fetchCurrentManagerData(proxy.$store.state.settingsPageTab).then(() => {
+ firstJumpEditorAfterChangeTab()
+ })
+ }).catch(error => {
+ snackbar.error(error)
})
}
const onTabChange = (tab) => {
- fetchCurrentManagerData(tab)
+ isJsonValid.value = true
+ errorMessage.value = ''
+ fetchCurrentManagerData(tab).then(() => {
+ firstJumpEditorAfterChangeTab()
+ })
+}
+
+const firstJumpEditorAfterChangeTab = () => {
+ if (currentManagerSchema.value != null) {
+ configType.value = 'ui'
+ } else {
+ configType.value = 'json'
+ }
}
const fetchCurrentManagerData = (tab) => {
- proxy.$axios.get(`/settings/${tab}`).then(response => {
+ return proxy.$axios.get(`/settings/${tab}`).catch(error => {
+ snackbar.error(error)
+ }).then(response => {
+ if (response.data.code != 0) {
+ snackbar.error(response.data.msg)
+ return
+ }
currentManager.value = response.data.data.manager
- currentManagerData.value = JSON.stringify(currentManager.value.data, null, 2)
+ currentManagerData.value = currentManager.value.data
+ currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
+ currentManagerSchema.value = currentManager.value.schema
})
}
+const isJsonValid = ref(true)
+const errorMessage = ref('')
+
+const checkJsonValid = () => {
+ try {
+ JSON.parse(currentManagerDataEditorString.value)
+ isJsonValid.value = true
+ errorMessage.value = ''
+ } catch (error) {
+ isJsonValid.value = false
+ errorMessage.value = error.message
+ }
+}
+
const onInput = () => {
modified.value = true
+ checkJsonValid()
}
const saveAndApply = () => {
+ if (!isJsonValid.value) {
+ snackbar.error('JSON 格式不正确: ' + errorMessage.value)
+ return
+ }
+ if (configType.value == 'json') {
+ currentManagerData.value = JSON.parse(currentManagerDataEditorString.value)
+ }
proxy.$axios.put(`/settings/${currentManager.value.name}/data`, {
- data: JSON.parse(currentManagerData.value)
+ data: currentManagerData.value
}).then(response => {
+ if (response.data.code != 0) {
+ snackbar.error(response.data.msg)
+ return
+ }
fetchCurrentManagerData(currentManager.value.name)
modified.value = false
+ snackbar.success('应用成功')
+ }).catch(error => {
+ snackbar.error(error)
})
}
const reset = () => {
- currentManagerData.value = JSON.stringify(currentManager.value.data, null, 2)
- modified.value = false
+ if (configType.value == 'json') {
+ currentManagerData.value = currentManager.value.data
+ currentManagerDataEditorString.value = JSON.stringify(currentManager.value.data, null, 2)
+ isJsonValid.value = true
+ errorMessage.value = ''
+ modified.value = false
+ snackbar.success('重置成功')
+ } else {
+ fetchCurrentManagerData(currentManager.value.name).then(() => {
+ snackbar.success('重置成功')
+ modified.value = false
+ })
+ }
}
onMounted(async () => {
@@ -133,12 +269,12 @@ onMounted(async () => {
}
.config-tab-window {
- overflow: auto;
+ overflow: hidden;
}
.config-tab-toolbar {
margin: 0.5rem;
- height: 4rem;
+ height: 3.2rem;
display: flex;
flex-direction: row;
justify-content: space-between;
@@ -159,16 +295,38 @@ onMounted(async () => {
box-shadow: 0 0 0 2px #dddddd;
}
-.config-type-toggle-btn {}
-
-.config-tab-content {
+#config-tab-content {
margin: 0.2rem;
height: calc(100% - 1rem);
+ overflow: hidden;
+}
+
+#config-tab-content-ui {
+ margin: 0.5rem;
+ height: calc(100vh - 15rem);
+ margin-top: 1rem;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+#config-tab-content-ui-form {
+ height: 100%;
+ width: calc(100% - 1.5rem);
+ margin-left: 0.5rem;
+ overflow-y: auto;
+}
+
+#config-tab-content-ui-form-vjsf {
+ height: 100%;
+ width: calc(100% - 1rem);
}
#config-tab-content-json {
margin: 0.5rem;
- height: calc(100vh - 18rem);
+ height: calc(100vh - 16rem);
margin-top: 1rem;
}
@@ -186,4 +344,13 @@ onMounted(async () => {
line-height: 1.6rem;
text-wrap: nowrap;
}
+
+#config-tab-json-not-valid {
+ margin: 0rem;
+ margin-left: 0.6rem;
+ height: 1.5rem;
+ margin-top: 0.2rem;
+ font-size: 0.8rem;
+ color: red;
+}
\ No newline at end of file
diff --git a/web/vite.config.mjs b/web/vite.config.mjs
index 9870a71e..31052bbe 100644
--- a/web/vite.config.mjs
+++ b/web/vite.config.mjs
@@ -5,6 +5,8 @@ import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
import ViteFonts from 'unplugin-fonts/vite'
import VueRouter from 'unplugin-vue-router/vite'
+import { commonjsDeps } from '@koumoul/vjsf/utils/build.js'
+
// Utilities
import { defineConfig } from 'vite'
import { fileURLToPath, URL } from 'node:url'
@@ -51,4 +53,12 @@ export default defineConfig({
server: {
port: 3002,
},
+ optimizeDeps: {
+ include: commonjsDeps,
+ },
+ build: {
+ commonjsOptions: {
+ transformMixedEsModules: true,
+ },
+ }
})