From 2737155a7f4aa095da9fd9acd4625d844ae213e9 Mon Sep 17 00:00:00 2001
From: ssongliu <songlius11@163.com>
Date: Fri, 23 Dec 2022 15:38:13 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E5=86=B3=20codemirror=20?=
 =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../codemirror-dialog/codemirror.vue          |  2 +-
 .../src/components/container-log/index.vue    | 15 +++++++++-
 .../views/container/compose/create/index.vue  |  2 +-
 .../views/container/compose/detail/index.vue  | 12 ++++----
 .../views/container/compose/edit/index.vue    |  3 +-
 .../src/views/container/compose/index.vue     |  4 +--
 .../views/container/container/log/index.vue   | 15 +++++++++-
 .../src/views/container/image/build/index.vue | 29 +++++++++++++++++--
 .../src/views/container/image/pull/index.vue  | 14 ++++++++-
 .../src/views/container/image/push/index.vue  | 14 ++++++++-
 .../container/template/operator/index.vue     |  2 +-
 .../database/mysql/setting/slow-log/index.vue | 14 ++++++++-
 frontend/src/views/log/system/index.vue       | 14 ++++++++-
 .../setting/backup-account/operate/index.vue  |  1 +
 frontend/src/views/setting/index.vue          |  2 +-
 15 files changed, 122 insertions(+), 21 deletions(-)

diff --git a/frontend/src/components/codemirror-dialog/codemirror.vue b/frontend/src/components/codemirror-dialog/codemirror.vue
index 3ecb55b60..ac9614d8b 100644
--- a/frontend/src/components/codemirror-dialog/codemirror.vue
+++ b/frontend/src/components/codemirror-dialog/codemirror.vue
@@ -11,7 +11,7 @@
             placeholder="None data"
             :indent-with-tab="true"
             :tabSize="4"
-            style="max-height: 500px"
+            style="max-height: 500px; min-height: 200px; width: 100%"
             :lineWrapping="true"
             :matchBrackets="true"
             theme="cobalt"
diff --git a/frontend/src/components/container-log/index.vue b/frontend/src/components/container-log/index.vue
index 581512a5d..2d0fb001b 100644
--- a/frontend/src/components/container-log/index.vue
+++ b/frontend/src/components/container-log/index.vue
@@ -23,6 +23,7 @@
             theme="cobalt"
             :styleActiveLine="true"
             :extensions="extensions"
+            @ready="handleReady"
             v-model="logInfo"
             :readOnly="true"
         />
@@ -33,7 +34,7 @@
 import { logContainer } from '@/api/modules/container';
 import i18n from '@/lang';
 import { dateFromatForName } from '@/utils/util';
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Codemirror } from 'vue-codemirror';
 import { javascript } from '@codemirror/lang-javascript';
 import { oneDark } from '@codemirror/theme-one-dark';
@@ -41,6 +42,11 @@ import { oneDark } from '@codemirror/theme-one-dark';
 const extensions = [javascript(), oneDark];
 
 const logInfo = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
+
 const logSearch = reactive({
     isWatch: false,
     container: '',
@@ -78,6 +84,13 @@ const onCloseLog = async () => {
 const searchLogs = async () => {
     const res = await logContainer(logSearch);
     logInfo.value = res.data;
+    nextTick(() => {
+        const state = view.value.state;
+        view.value.dispatch({
+            selection: { anchor: state.doc.length, head: state.doc.length },
+            scrollIntoView: true,
+        });
+    });
 };
 
 const onDownload = async () => {
diff --git a/frontend/src/views/container/compose/create/index.vue b/frontend/src/views/container/compose/create/index.vue
index ffaf7e910..f5b7aa6d2 100644
--- a/frontend/src/views/container/compose/create/index.vue
+++ b/frontend/src/views/container/compose/create/index.vue
@@ -39,7 +39,7 @@
                         placeholder="None data"
                         :indent-with-tab="true"
                         :tabSize="4"
-                        style="max-height: 500px; width: 100%"
+                        style="max-height: 500px; width: 100%; min-height: 200px"
                         :lineWrapping="true"
                         :matchBrackets="true"
                         theme="cobalt"
diff --git a/frontend/src/views/container/compose/detail/index.vue b/frontend/src/views/container/compose/detail/index.vue
index 7b421d78c..fdc2041ae 100644
--- a/frontend/src/views/container/compose/detail/index.vue
+++ b/frontend/src/views/container/compose/detail/index.vue
@@ -2,11 +2,13 @@
     <div v-loading="loading">
         <LayoutContent :header="composeName" back-name="Compose" :reload="true">
             <div v-if="createdBy === '1Panel'">
-                <el-button icon="VideoPlay" @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
-                <el-button icon="VideoPause" @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
-                <el-button icon="Delete" @click="onComposeOperate('down')" plain type="danger">
-                    {{ $t('container.remove') }}
-                </el-button>
+                <el-button-group>
+                    <el-button @click="onComposeOperate('start')">{{ $t('container.start') }}</el-button>
+                    <el-button @click="onComposeOperate('stop')">{{ $t('container.stop') }}</el-button>
+                    <el-button @click="onComposeOperate('down')">
+                        {{ $t('container.remove') }}
+                    </el-button>
+                </el-button-group>
             </div>
             <div v-else>
                 <el-alert :closable="false" show-icon :title="$t('container.composeDetailHelper')" type="info" />
diff --git a/frontend/src/views/container/compose/edit/index.vue b/frontend/src/views/container/compose/edit/index.vue
index 216da6da1..e8a6a3379 100644
--- a/frontend/src/views/container/compose/edit/index.vue
+++ b/frontend/src/views/container/compose/edit/index.vue
@@ -7,12 +7,11 @@
         </template>
         <div v-loading="loading">
             <codemirror
-                ref="mymirror"
                 :autofocus="true"
                 placeholder="None data"
                 :indent-with-tab="true"
                 :tabSize="4"
-                style="max-height: 500px"
+                style="max-height: 500px; width: 100%; min-height: 200px"
                 :lineWrapping="true"
                 :matchBrackets="true"
                 theme="cobalt"
diff --git a/frontend/src/views/container/compose/index.vue b/frontend/src/views/container/compose/index.vue
index ae9140d42..73f7fba67 100644
--- a/frontend/src/views/container/compose/index.vue
+++ b/frontend/src/views/container/compose/index.vue
@@ -170,7 +170,7 @@ const buttons = [
             onEdit(row);
         },
         disabled: (row: any) => {
-            return row.createdBy !== 'Local';
+            return row.createdBy !== '1Panel';
         },
     },
     {
@@ -179,7 +179,7 @@ const buttons = [
             onDelete(row);
         },
         disabled: (row: any) => {
-            return row.createdBy === 'Apps';
+            return row.createdBy !== '1Panel';
         },
     },
 ];
diff --git a/frontend/src/views/container/container/log/index.vue b/frontend/src/views/container/container/log/index.vue
index 759afc840..2cc449459 100644
--- a/frontend/src/views/container/container/log/index.vue
+++ b/frontend/src/views/container/container/log/index.vue
@@ -35,6 +35,7 @@
             :styleActiveLine="true"
             :extensions="extensions"
             v-model="logInfo"
+            @ready="handleReady"
             :readOnly="true"
         />
         <template #footer>
@@ -49,7 +50,7 @@
 import { logContainer } from '@/api/modules/container';
 import i18n from '@/lang';
 import { dateFromatForName } from '@/utils/util';
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Codemirror } from 'vue-codemirror';
 import { javascript } from '@codemirror/lang-javascript';
 import { oneDark } from '@codemirror/theme-one-dark';
@@ -59,6 +60,11 @@ const extensions = [javascript(), oneDark];
 const logVisiable = ref(false);
 
 const logInfo = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
+
 const logSearch = reactive({
     isWatch: false,
     container: '',
@@ -94,6 +100,13 @@ const onCloseLog = async () => {
 const searchLogs = async () => {
     const res = await logContainer(logSearch);
     logInfo.value = res.data;
+    nextTick(() => {
+        const state = view.value.state;
+        view.value.dispatch({
+            selection: { anchor: state.doc.length, head: state.doc.length },
+            scrollIntoView: true,
+        });
+    });
 };
 
 const onDownload = async () => {
diff --git a/frontend/src/views/container/image/build/index.vue b/frontend/src/views/container/image/build/index.vue
index 595e0b124..6cc2f9a72 100644
--- a/frontend/src/views/container/image/build/index.vue
+++ b/frontend/src/views/container/image/build/index.vue
@@ -22,7 +22,20 @@
                 </el-radio-group>
             </el-form-item>
             <el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
-                <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 10 }" v-model="form.dockerfile" />
+                <codemirror
+                    :autofocus="true"
+                    placeholder="None data"
+                    :indent-with-tab="true"
+                    :tabSize="4"
+                    style="max-height: 500px; width: 100%; min-height: 200px"
+                    :lineWrapping="true"
+                    :matchBrackets="true"
+                    theme="cobalt"
+                    :styleActiveLine="true"
+                    :extensions="extensions"
+                    v-model="form.dockerfile"
+                    :readOnly="true"
+                />
             </el-form-item>
             <el-form-item v-else :rules="Rules.requiredSelect" prop="dockerfile">
                 <el-input clearable v-model="form.dockerfile">
@@ -53,6 +66,7 @@
             theme="cobalt"
             :styleActiveLine="true"
             :extensions="extensions"
+            @ready="handleReady"
             v-model="logInfo"
             :readOnly="true"
         />
@@ -75,7 +89,7 @@ import FileList from '@/components/file-list/index.vue';
 import { Codemirror } from 'vue-codemirror';
 import { javascript } from '@codemirror/lang-javascript';
 import { oneDark } from '@codemirror/theme-one-dark';
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Rules } from '@/global/form-rules';
 import i18n from '@/lang';
 import { ElForm, ElMessage } from 'element-plus';
@@ -84,6 +98,10 @@ import { LoadFile } from '@/api/modules/files';
 
 const logVisiable = ref<boolean>(false);
 const logInfo = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
 const extensions = [javascript(), oneDark];
 let timer: NodeJS.Timer | null = null;
 
@@ -143,6 +161,13 @@ const loadLogs = async (path: string) => {
         if (logVisiable.value) {
             const res = await LoadFile({ path: path });
             logInfo.value = res.data;
+            nextTick(() => {
+                const state = view.value.state;
+                view.value.dispatch({
+                    selection: { anchor: state.doc.length, head: state.doc.length },
+                    scrollIntoView: true,
+                });
+            });
         }
     }, 1000 * 3);
 };
diff --git a/frontend/src/views/container/image/pull/index.vue b/frontend/src/views/container/image/pull/index.vue
index a88a176da..d17fe8339 100644
--- a/frontend/src/views/container/image/pull/index.vue
+++ b/frontend/src/views/container/image/pull/index.vue
@@ -44,6 +44,7 @@
             theme="cobalt"
             :styleActiveLine="true"
             :extensions="extensions"
+            @ready="handleReady"
             v-model="logInfo"
             :readOnly="true"
         />
@@ -61,7 +62,7 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Rules } from '@/global/form-rules';
 import i18n from '@/lang';
 import { ElForm, ElMessage } from 'element-plus';
@@ -83,6 +84,10 @@ const buttonDisabled = ref(false);
 
 const logVisiable = ref(false);
 const logInfo = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
 const extensions = [javascript(), oneDark];
 let timer: NodeJS.Timer | null = null;
 
@@ -125,6 +130,13 @@ const loadLogs = async (path: string) => {
         if (logVisiable.value) {
             const res = await LoadFile({ path: path });
             logInfo.value = res.data;
+            nextTick(() => {
+                const state = view.value.state;
+                view.value.dispatch({
+                    selection: { anchor: state.doc.length, head: state.doc.length },
+                    scrollIntoView: true,
+                });
+            });
         }
     }, 1000 * 3);
 };
diff --git a/frontend/src/views/container/image/push/index.vue b/frontend/src/views/container/image/push/index.vue
index cc9bca263..e8c660f6b 100644
--- a/frontend/src/views/container/image/push/index.vue
+++ b/frontend/src/views/container/image/push/index.vue
@@ -41,6 +41,7 @@
             theme="cobalt"
             :styleActiveLine="true"
             :extensions="extensions"
+            @ready="handleReady"
             v-model="logInfo"
             :readOnly="true"
         />
@@ -58,7 +59,7 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Rules } from '@/global/form-rules';
 import i18n from '@/lang';
 import { ElForm, ElMessage } from 'element-plus';
@@ -81,6 +82,10 @@ const buttonDisabled = ref(false);
 
 const logVisiable = ref(false);
 const logInfo = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
 const extensions = [javascript(), oneDark];
 let timer: NodeJS.Timer | null = null;
 
@@ -124,6 +129,13 @@ const loadLogs = async (path: string) => {
         if (logVisiable.value) {
             const res = await LoadFile({ path: path });
             logInfo.value = res.data;
+            nextTick(() => {
+                const state = view.value.state;
+                view.value.dispatch({
+                    selection: { anchor: state.doc.length, head: state.doc.length },
+                    scrollIntoView: true,
+                });
+            });
         }
     }, 1000 * 3);
 };
diff --git a/frontend/src/views/container/template/operator/index.vue b/frontend/src/views/container/template/operator/index.vue
index 0bcd4f0c3..1e358481b 100644
--- a/frontend/src/views/container/template/operator/index.vue
+++ b/frontend/src/views/container/template/operator/index.vue
@@ -18,7 +18,7 @@
                     placeholder="None data"
                     :indent-with-tab="true"
                     :tabSize="4"
-                    style="max-height: 500px; width: 100%"
+                    style="max-height: 500px; width: 100%; min-height: 200px"
                     :lineWrapping="true"
                     :matchBrackets="true"
                     theme="cobalt"
diff --git a/frontend/src/views/database/mysql/setting/slow-log/index.vue b/frontend/src/views/database/mysql/setting/slow-log/index.vue
index 139c6bd4b..30594a2f2 100644
--- a/frontend/src/views/database/mysql/setting/slow-log/index.vue
+++ b/frontend/src/views/database/mysql/setting/slow-log/index.vue
@@ -37,6 +37,7 @@
                 theme="cobalt"
                 :styleActiveLine="true"
                 :extensions="extensions"
+                @ready="handleReady"
                 v-model="slowLogs"
                 :readOnly="true"
             />
@@ -50,7 +51,7 @@
 import { Codemirror } from 'vue-codemirror';
 import { javascript } from '@codemirror/lang-javascript';
 import { oneDark } from '@codemirror/theme-one-dark';
-import { reactive, ref } from 'vue';
+import { nextTick, reactive, ref, shallowRef } from 'vue';
 import { Database } from '@/api/interface/database';
 import { LoadFile } from '@/api/modules/files';
 import ConfirmDialog from '@/components/confirm-dialog/index.vue';
@@ -62,6 +63,10 @@ import i18n from '@/lang';
 const loading = ref();
 const extensions = [javascript(), oneDark];
 const slowLogs = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
 
 const confirmDialogRef = ref();
 
@@ -142,6 +147,13 @@ const onDownload = async () => {
 const loadMysqlSlowlogs = async (path: string) => {
     const res = await LoadFile({ path: path });
     slowLogs.value = res.data;
+    nextTick(() => {
+        const state = view.value.state;
+        view.value.dispatch({
+            selection: { anchor: state.doc.length, head: state.doc.length },
+            scrollIntoView: true,
+        });
+    });
 };
 
 const onCloseLog = async () => {
diff --git a/frontend/src/views/log/system/index.vue b/frontend/src/views/log/system/index.vue
index f1250aec9..8e30eda89 100644
--- a/frontend/src/views/log/system/index.vue
+++ b/frontend/src/views/log/system/index.vue
@@ -13,6 +13,7 @@
                 theme="cobalt"
                 :styleActiveLine="true"
                 :extensions="extensions"
+                @ready="handleReady"
                 v-model="logs"
                 :readOnly="true"
             />
@@ -24,16 +25,27 @@
 import { Codemirror } from 'vue-codemirror';
 import { javascript } from '@codemirror/lang-javascript';
 import { oneDark } from '@codemirror/theme-one-dark';
-import { onMounted, ref } from 'vue';
+import { nextTick, onMounted, ref, shallowRef } from 'vue';
 import Submenu from '@/views/log/index.vue';
 import { LoadFile } from '@/api/modules/files';
 
 const extensions = [javascript(), oneDark];
 const logs = ref();
+const view = shallowRef();
+const handleReady = (payload) => {
+    view.value = payload.view;
+};
 
 const loadSystemlogs = async () => {
     const res = await LoadFile({ path: '/opt/1Panel/log/1Panel.log' });
     logs.value = res.data;
+    nextTick(() => {
+        const state = view.value.state;
+        view.value.dispatch({
+            selection: { anchor: state.doc.length, head: state.doc.length },
+            scrollIntoView: true,
+        });
+    });
 };
 
 onMounted(() => {
diff --git a/frontend/src/views/setting/backup-account/operate/index.vue b/frontend/src/views/setting/backup-account/operate/index.vue
index 72e322355..434841fb6 100644
--- a/frontend/src/views/setting/backup-account/operate/index.vue
+++ b/frontend/src/views/setting/backup-account/operate/index.vue
@@ -194,6 +194,7 @@ const onSubmit = async (formEl: FormInstance | undefined) => {
     formEl.validate(async (valid) => {
         if (!valid) return;
         if (!dialogData.value.rowData) return;
+        dialogData.value.rowData.vars = JSON.stringify(dialogData.value.rowData!.varsJson);
         if (dialogData.value.title === 'create') {
             await addBackup(dialogData.value.rowData);
         }
diff --git a/frontend/src/views/setting/index.vue b/frontend/src/views/setting/index.vue
index 252d73cdc..6210b329f 100644
--- a/frontend/src/views/setting/index.vue
+++ b/frontend/src/views/setting/index.vue
@@ -2,7 +2,7 @@
     <div>
         <el-card class="topCard">
             <el-radio-group v-model="active">
-                <el-radio-button class="topButton" size="large" @click="routerTo('/setting/panel')" label="panel">
+                <el-radio-button class="topButton" size="large" @click="routerTo('/setting')" label="panel">
                     {{ $t('setting.panel') }}
                 </el-radio-button>
                 <el-radio-button class="topButton" size="large" @click="routerTo('/setting/safe')" label="safe">