feat: 统一 CodeMirror 组件 (#5716)

pull/5993/head
zhengkunwang 5 months ago committed by zhengkunwang223
parent ed2f5c42d0
commit d91ce3da65

@ -22,6 +22,7 @@
"dependencies": {
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-json": "^6.0.1",
"@codemirror/lang-php": "^6.0.1",
"@codemirror/language": "^6.10.2",
"@codemirror/legacy-modes": "^6.4.0",

@ -1,47 +1,16 @@
<template>
<el-drawer
v-model="codeVisible"
:destroy-on-close="true"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="50%"
>
<template #header>
<DrawerHeader :header="header" :back="handleClose" />
</template>
<codemirror
ref="mymirror"
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 160px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
:disabled="true"
/>
<DrawerPro v-model="codeVisible" :header="header" size="large" @close="handleClose">
<CodemirrorPro v-model="detailInfo" :height="800" :disabled="true" mode="json"></CodemirrorPro>
<template #footer>
<span class="dialog-footer">
<el-button @click="codeVisible = false">{{ $t('commons.button.cancel') }}</el-button>
</span>
</template>
</el-drawer>
</DrawerPro>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import DrawerHeader from '@/components/drawer-header/index.vue';
const mymirror = ref();
const extensions = [javascript(), oneDark];
const header = ref();
const detailInfo = ref();
const codeVisible = ref(false);

@ -0,0 +1,136 @@
<template>
<div :style="customStyle">
<div ref="editorRef" class="editor-container"></div>
</div>
</template>
<script lang="ts" setup>
import { CSSProperties } from 'vue';
import { basicSetup, EditorView } from 'codemirror';
import { EditorState } from '@codemirror/state';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { yaml } from '@codemirror/legacy-modes/mode/yaml';
import { dockerFile } from '@codemirror/legacy-modes/mode/dockerfile';
import { placeholder } from '@codemirror/view';
import { json } from '@codemirror/lang-json';
defineOptions({ name: 'CodemirrorPro' });
const props = defineProps({
disabled: {
type: Boolean,
default: false,
},
modelValue: {
type: String,
default: '',
},
mode: {
type: String,
default: 'javascript',
},
placeholder: {
type: String,
default: '',
},
heightDiff: {
type: Number,
default: 200,
},
minHeight: {
type: Number,
default: 400,
},
});
const emit = defineEmits(['update:modelValue']);
const editorRef = ref();
const editorView = ref();
const content = computed(() => {
return props.modelValue;
});
const customStyle = computed<CSSProperties>(() => ({
width: '100%',
}));
const initCodeMirror = () => {
const defaultTheme = EditorView.theme({
'&.cm-editor': {
minHeight: props.minHeight + 'px',
height: 'calc(100vh - ' + props.heightDiff + 'px)',
},
});
const extensions = [
defaultTheme,
oneDark,
basicSetup,
EditorView.updateListener.of((v: any) => {
if (v.docChanged) {
emit('update:modelValue', v.state.doc.toString());
}
}),
placeholder(props.placeholder),
EditorView.editable.of(!props.disabled),
];
switch (props.mode) {
case 'dockerfile':
extensions.push(StreamLanguage.define(dockerFile));
break;
case 'javascript':
extensions.push(javascript());
break;
case 'nginx':
extensions.push(StreamLanguage.define(nginx));
break;
case 'yaml':
extensions.push(StreamLanguage.define(yaml));
break;
case 'json':
extensions.push(json());
break;
}
let startState = EditorState.create({
doc: content.value,
extensions: extensions,
});
editorView.value = new EditorView({
state: startState,
parent: editorRef.value,
});
};
watch(
() => content.value,
(newValue) => {
if (editorView.value) {
if (newValue === editorView.value.state.doc.toString()) {
return;
}
editorView.value.dispatch({
changes: {
from: 0,
to: editorView.value.state.doc.length,
insert: newValue,
},
scrollIntoView: false,
});
} else {
initCodeMirror();
}
},
{ immediate: true },
);
onMounted(() => {
initCodeMirror();
});
onUnmounted(() => {
editorView.value?.destroy();
});
</script>

@ -38,48 +38,37 @@
</el-button>
</div>
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 200px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:disabled="true"
/>
<div class="mt-2.5">
<highlightjs
v-if="showLog"
ref="editorRef"
class="editor-main"
language="JavaScript"
:autodetect="false"
:code="logInfo"
></highlightjs>
</div>
</el-drawer>
</template>
<script lang="ts" setup>
import i18n from '@/lang';
import { dateFormatForName } from '@/utils/util';
import { computed, onBeforeUnmount, reactive, ref, shallowRef, watch } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';
import { MsgError } from '@/utils/message';
import { GlobalStore } from '@/store';
import screenfull from 'screenfull';
import { DownloadFile } from '@/api/modules/container';
const extensions = [javascript(), oneDark];
const logInfo = ref();
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
const terminalSocket = ref<WebSocket>();
const open = ref(false);
const resource = ref('');
const globalStore = GlobalStore();
const logVisible = ref(false);
const showLog = ref(false);
const editorRef = ref();
const scrollerElement = ref<HTMLElement | null>(null);
const mobile = computed(() => {
return globalStore.isMobile();
@ -146,10 +135,8 @@ const searchLogs = async () => {
);
terminalSocket.value.onmessage = (event) => {
logInfo.value += event.data;
const state = view.value.state;
view.value.dispatch({
selection: { anchor: state.doc.length, head: state.doc.length },
scrollIntoView: true,
nextTick(() => {
scrollerElement.value.scrollTop = scrollerElement.value.scrollHeight;
});
};
};
@ -208,6 +195,17 @@ onBeforeUnmount(() => {
handleClose();
});
onMounted(async () => {
await nextTick(() => {
showLog.value = true;
});
if (editorRef.value) {
scrollerElement.value = editorRef.value.$el as HTMLElement;
let hljsDom = scrollerElement.value.querySelector('.hljs') as HTMLElement;
hljsDom.style['min-height'] = '500px';
}
});
defineExpose({
acceptParams,
});
@ -217,4 +215,11 @@ defineExpose({
.selectWidth {
width: 200px;
}
.editor-main {
height: calc(100vh - 100px);
width: 100%;
min-height: 600px;
overflow: auto;
}
</style>

@ -26,21 +26,16 @@
</el-button>
</div>
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'margin-top': '10px' }"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="logInfo"
:disabled="true"
/>
<div :style="{ height: `calc(100vh - ${loadHeight()})`, 'margin-top': '10px', 'min-height': '400px' }">
<highlightjs
v-if="showLog"
ref="editorRef"
class="editor-main"
language="JavaScript"
:autodetect="false"
:code="logInfo"
></highlightjs>
</div>
</div>
</template>
@ -48,22 +43,16 @@
import { cleanContainerLog } from '@/api/modules/container';
import i18n from '@/lang';
import { dateFormatForName, downloadWithContent } from '@/utils/util';
import { onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { onBeforeUnmount, reactive, ref } from 'vue';
import { MsgError, MsgSuccess } from '@/utils/message';
import { GlobalStore } from '@/store';
const globalStore = GlobalStore();
const extensions = [javascript(), oneDark];
const logInfo = ref();
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
const terminalSocket = ref<WebSocket>();
const editorRef = ref();
const scrollerElement = ref<HTMLElement | null>(null);
const showLog = ref(false);
const loadHeight = () => {
return globalStore.openMenuTabs ? '405px' : '375px';
@ -113,10 +102,8 @@ const searchLogs = async () => {
);
terminalSocket.value.onmessage = (event) => {
logInfo.value += event.data;
const state = view.value.state;
view.value.dispatch({
selection: { anchor: state.doc.length, head: state.doc.length },
scrollIntoView: true,
nextTick(() => {
scrollerElement.value.scrollTop = scrollerElement.value.scrollHeight;
});
};
};
@ -165,6 +152,17 @@ onBeforeUnmount(() => {
terminalSocket.value?.send('close conn');
});
onMounted(async () => {
await nextTick(() => {
showLog.value = true;
});
if (editorRef.value) {
scrollerElement.value = editorRef.value.$el as HTMLElement;
let hljsDom = scrollerElement.value.querySelector('.hljs') as HTMLElement;
hljsDom.style['min-height'] = '500px';
}
});
defineExpose({
acceptParams,
});
@ -177,4 +175,10 @@ defineExpose({
.selectWidth {
width: 150px;
}
.editor-main {
height: calc(100vh - 480px);
width: 100%;
min-height: 600px;
overflow: auto;
}
</style>

@ -84,28 +84,16 @@
{{ $t('container.limitHelper', [limits.memory]) }}{{ req.memoryUnit }}B
</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="req.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<el-form-item pro="pullImage">
<el-checkbox v-model="req.pullImage" :label="$t('container.forcePull')" size="large" />
<span class="input-help">{{ $t('container.forcePullHelper') }}</span>
</el-form-item>
<el-form-item prop="editCompose">
<el-checkbox v-model="req.editCompose" :label="$t('app.editCompose')" size="large" />
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<div v-if="req.editCompose">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="height: 400px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="req.dockerCompose"
/>
<CodemirrorPro v-model="req.dockerCompose" mode="yaml"></CodemirrorPro>
</div>
</div>
</el-form>
@ -128,15 +116,12 @@ import { FormInstance, FormRules } from 'element-plus';
import { onMounted, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import Params from '../params/index.vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import i18n from '@/lang';
import { MsgError } from '@/utils/message';
import { Container } from '@/api/interface/container';
import { loadResourceLimit } from '@/api/modules/container';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const extensions = [javascript(), oneDark];
const router = useRouter();
interface InstallRrops {

@ -76,19 +76,7 @@
<span class="input-help">{{ $t('app.editComposeHelper') }}</span>
</el-form-item>
<div v-if="paramModel.editCompose">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="height: 400px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="paramModel.dockerCompose"
/>
<CodemirrorPro v-model="paramModel.dockerCompose" mode="yaml"></CodemirrorPro>
</div>
</div>
</el-form>
@ -111,13 +99,8 @@ import { FormInstance } from 'element-plus';
import { Rules, checkNumberRange } from '@/global/form-rules';
import { MsgSuccess } from '@/utils/message';
import i18n from '@/lang';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { getLanguage } from '@/utils/util';
const extensions = [javascript(), oneDark];
interface ParamProps {
id: Number;
app: any;

@ -64,20 +64,7 @@
<div v-if="useNewCompose">
<el-text type="danger">{{ $t('app.useCustomHelper') }}</el-text>
</div>
<codemirror
v-if="useNewCompose"
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 500px); margin-top: 10px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="newCompose"
/>
<CodemirrorPro v-if="useNewCompose" v-model="newCompose" mode="yaml"></CodemirrorPro>
</div>
<template #footer>
<span class="dialog-footer">
@ -100,10 +87,7 @@ import { MsgSuccess } from '@/utils/message';
import { Rules } from '@/global/form-rules';
import Diff from './diff/index.vue';
import bus from '../../bus';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
const extensions = [javascript(), oneDark];
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const composeDiffRef = ref();
const updateRef = ref<FormInstance>();

@ -36,28 +36,20 @@
</span>
</el-form-item>
<el-form-item>
<div v-if="form.from === 'edit' || form.from === 'template'" style="width: 100%">
<div v-if="form.from === 'edit' || form.from === 'template'" class="w-full">
<el-radio-group v-model="mode" size="small">
<el-radio-button label="edit">{{ $t('commons.button.edit') }}</el-radio-button>
<el-radio-button label="log">{{ $t('commons.button.log') }}</el-radio-button>
</el-radio-group>
<codemirror
@change="onEdit('')"
<CodemirrorPro
v-if="mode === 'edit'"
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 376px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="form.file"
/>
placeholder="#Define or paste the content of your docker-compose file here"
mode="yaml"
:heightDiff="400"
></CodemirrorPro>
</div>
<div style="width: 100%">
<div class="w-full">
<LogFile
ref="logRef"
v-model:is-reading="isReading"
@ -85,16 +77,13 @@
<script lang="ts" setup>
import { nextTick, onBeforeUnmount, reactive, ref } from 'vue';
import FileList from '@/components/file-list/index.vue';
import { Codemirror } from 'vue-codemirror';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm, ElMessageBox } from 'element-plus';
import { loadBaseDir } from '@/api/modules/setting';
import { MsgError } from '@/utils/message';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
const extensions = [javascript(), oneDark];
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import { listComposeTemplate, testCompose, upCompose } from '@/api/modules/container';
const showLog = ref(false);
const loading = ref();

@ -7,19 +7,11 @@
size="large"
>
<div v-loading="loading">
<codemirror
:autofocus="true"
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 175px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
<CodemirrorPro
v-model="content"
/>
mode="yaml"
placeholder="#Define or paste the content of your docker-compose file here"
></CodemirrorPro>
</div>
<template #footer>
<span class="dialog-footer">
@ -34,9 +26,6 @@
</DrawerPro>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { ref } from 'vue';
import { composeUpdate } from '@/api/modules/container';
import i18n from '@/lang';
@ -44,7 +33,6 @@ import { MsgSuccess } from '@/utils/message';
const loading = ref(false);
const composeVisible = ref(false);
const extensions = [javascript(), oneDark];
const path = ref();
const content = ref();
const name = ref();

@ -44,21 +44,13 @@
</el-button>
</div>
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 20px; height: calc(100vh - 230px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="logInfo"
@ready="handleReady"
:disabled="true"
/>
<highlightjs
class="mt-10 editor-main"
ref="editorRef"
language="JavaScript"
:autodetect="false"
:code="logInfo"
></highlightjs>
</template>
<template #footer>
<span class="dialog-footer">
@ -73,28 +65,22 @@
import { cleanContainerLog, DownloadFile } from '@/api/modules/container';
import i18n from '@/lang';
import { dateFormatForName } from '@/utils/util';
import { computed, onBeforeUnmount, reactive, ref, shallowRef, watch } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { computed, onBeforeUnmount, reactive, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import { MsgError, MsgSuccess } from '@/utils/message';
import screenfull from 'screenfull';
import { GlobalStore } from '@/store';
const extensions = [javascript(), oneDark];
const logVisible = ref(false);
const mobile = computed(() => {
return globalStore.isMobile();
});
const logInfo = ref<string>('');
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
const globalStore = GlobalStore();
const terminalSocket = ref<WebSocket>();
const editorRef = ref();
const scrollerElement = ref<HTMLElement | null>(null);
const logSearch = reactive({
isWatch: true,
@ -156,10 +142,9 @@ const searchLogs = async () => {
);
terminalSocket.value.onmessage = (event) => {
logInfo.value += event.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, '');
const state = view.value.state;
view.value.dispatch({
selection: { anchor: state.doc.length, head: state.doc.length },
scrollIntoView: true,
nextTick(() => {
initLog();
scrollerElement.value.scrollTop = scrollerElement.value.scrollHeight;
});
};
};
@ -230,6 +215,13 @@ const acceptParams = (props: DialogProps): void => {
onBeforeUnmount(() => {
handleClose();
});
const initLog = () => {
if (editorRef.value && scrollerElement.value == undefined) {
scrollerElement.value = editorRef.value.$el as HTMLElement;
let hljsDom = scrollerElement.value.querySelector('.hljs') as HTMLElement;
hljsDom.style['min-height'] = '500px';
}
};
defineExpose({
acceptParams,
@ -252,4 +244,11 @@ defineExpose({
width: 30%;
float: left;
}
.editor-main {
height: calc(100vh - 250px);
width: 100%;
min-height: 600px;
overflow: auto;
}
</style>

@ -11,7 +11,12 @@
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.from === 'edit'" :rules="Rules.requiredInput">
<codemirror
<CodemirrorPro
v-model="form.dockerfile"
mode="dockerfile"
placeholder="#Define or paste the content of your Dockerfile here"
></CodemirrorPro>
<!-- <codemirror
@change="onEdit()"
:autofocus="true"
placeholder="#Define or paste the content of your Dockerfile here"
@ -25,7 +30,7 @@
:extensions="extensions"
v-model="form.dockerfile"
:readOnly="true"
/>
/> -->
</el-form-item>
<el-form-item v-else :rules="Rules.requiredSelect" prop="dockerfile">
<el-input @change="onEdit()" clearable v-model="form.dockerfile">
@ -67,9 +72,6 @@
<script lang="ts" setup>
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 { nextTick, reactive, ref } from 'vue';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
@ -77,7 +79,6 @@ import { ElForm, ElMessage } from 'element-plus';
import { imageBuild } from '@/api/modules/container';
const logVisible = ref<boolean>(false);
const extensions = [javascript(), oneDark];
const drawerVisible = ref(false);
const logRef = ref();
const isStartReading = ref(false);

@ -158,20 +158,14 @@
</el-row>
<div v-if="confShowType === 'all'">
<codemirror
:autofocus="true"
placeholder="# The Docker configuration file does not exist or is empty (/etc/docker/daemon.json)"
:indent-with-tab="true"
:tabSize="4"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'margin-top': '10px' }"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
<CodemirrorPro
class="mt-5"
:heightDiff="loadHeight()"
v-model="dockerConf"
/>
<el-button :disabled="loading" type="primary" @click="onSaveFile" class="p-ml-5">
mode="json"
placeholder="# The Docker configuration file does not exist or is empty (/etc/docker/daemon.json)"
></CodemirrorPro>
<el-button :disabled="loading" type="primary" @click="onSaveFile" class="mt-2.5">
{{ $t('commons.button.save') }}
</el-button>
</div>
@ -237,9 +231,7 @@
<script lang="ts" setup>
import { ElMessageBox, FormInstance } from 'element-plus';
import { onMounted, reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import Mirror from '@/views/container/setting/mirror/index.vue';
import Registry from '@/views/container/setting/registry/index.vue';
import LogOption from '@/views/container/setting/log/index.vue';
@ -265,7 +257,6 @@ const submitInput = ref();
const loading = ref(false);
const showDaemonJsonAlert = ref(false);
const extensions = [javascript(), oneDark];
const confShowType = ref('base');
const logOptionRef = ref();
@ -322,7 +313,7 @@ const onSaveFile = async () => {
};
const loadHeight = () => {
return globalStore.openMenuTabs ? '450px' : '430px';
return globalStore.openMenuTabs ? 450 : 430;
};
const onChangeMirrors = () => {

@ -1,19 +1,12 @@
<template>
<DrawerPro v-model="detailVisible" :header="$t('commons.button.view')" size="large">
<codemirror
:autofocus="true"
<CodemirrorPro
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 160px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="detailInfo"
mode="yaml"
:heightDiff="160"
:disabled="true"
/>
></CodemirrorPro>
<template #footer>
<span class="dialog-footer">
<el-button @click="detailVisible = false">{{ $t('commons.button.cancel') }}</el-button>
@ -23,11 +16,7 @@
</template>
<script lang="ts" setup>
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
const extensions = [javascript(), oneDark];
const detailVisible = ref(false);
const detailInfo = ref();

@ -21,19 +21,12 @@
<el-input v-model="dialogData.rowData!.description"></el-input>
</el-form-item>
<el-form-item>
<codemirror
:autofocus="true"
<CodemirrorPro
placeholder="#Define or paste the content of your docker-compose file here"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 351px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="dialogData.rowData!.content"
/>
mode="yaml"
:heightDiff="400"
></CodemirrorPro>
</el-form-item>
</el-form>
<template #footer>
@ -51,15 +44,13 @@
<script lang="ts" setup>
import { reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { ElForm } from 'element-plus';
import { Container } from '@/api/interface/container';
import { createComposeTemplate, updateComposeTemplate } from '@/api/modules/container';
import { MsgSuccess } from '@/utils/message';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const loading = ref(false);
@ -68,7 +59,6 @@ interface DialogProps {
rowData?: Container.TemplateInfo;
getTableList?: () => Promise<any>;
}
const extensions = [javascript(), oneDark];
const title = ref<string>('');
const drawerVisible = ref(false);
const dialogData = ref<DialogProps>({

@ -169,22 +169,14 @@
</el-row>
<el-row v-if="currentRecord?.records">
<span>{{ $t('commons.table.records') }}</span>
<codemirror
ref="mymirror"
:autofocus="true"
:placeholder="$t('cronjob.noLogs')"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 488px); width: 100%; margin-top: 5px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="currentRecordDetail"
:disabled="true"
/>
<div class="editor-main">
<highlightjs
ref="mymirror"
language="JavaScript"
:autodetect="false"
:code="currentRecordDetail"
></highlightjs>
</div>
</el-row>
</el-form>
</el-col>
@ -230,15 +222,12 @@
</template>
<script lang="ts" setup>
import { nextTick, onBeforeUnmount, reactive, ref, shallowRef } from 'vue';
import { nextTick, onBeforeUnmount, reactive, ref } from 'vue';
import { Cronjob } from '@/api/interface/cronjob';
import { searchRecords, handleOnce, updateStatus, cleanRecords, getRecordLog } from '@/api/modules/cronjob';
import { dateFormat } from '@/utils/util';
import i18n from '@/lang';
import { ElMessageBox } from 'element-plus';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { MsgSuccess } from '@/utils/message';
import { listDbItems } from '@/api/modules/database';
import { ListAppInstalled } from '@/api/modules/app';
@ -251,11 +240,7 @@ const hasRecords = ref();
let timer: NodeJS.Timer | null = null;
const mymirror = ref();
const extensions = [javascript(), oneDark];
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
const scrollerElement = ref<HTMLElement | null>(null);
interface DialogProps {
rowData: Cronjob.CronjobInfo;
@ -410,11 +395,8 @@ const loadRecord = async (row: Cronjob.Record) => {
}
currentRecordDetail.value = log;
nextTick(() => {
const state = view.value.state;
view.value.dispatch({
selection: { anchor: state.doc.length, head: state.doc.length },
scrollIntoView: true,
});
initLog();
scrollerElement.value.scrollTop = scrollerElement.value.scrollHeight;
});
}
};
@ -451,6 +433,14 @@ const cleanRecord = async () => {
});
};
const initLog = () => {
if (mymirror.value && scrollerElement.value == undefined) {
scrollerElement.value = mymirror.value.$el as HTMLElement;
let hljsDom = scrollerElement.value.querySelector('.hljs') as HTMLElement;
hljsDom.style['min-height'] = '500px';
}
};
onBeforeUnmount(() => {
clearInterval(Number(timer));
timer = null;
@ -502,4 +492,10 @@ defineExpose({
min-width: 1200px;
}
}
.editor-main {
height: calc(100vh - 488px);
width: 100%;
margin-top: 5px;
overflow-x: auto;
}
</style>

@ -24,20 +24,8 @@
<template #main>
<div v-if="activeName === 'conf'">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="8"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'margin-top': '10px' }"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="postgresqlConf"
/>
<el-button type="primary" style="margin-top: 10px" @click="onSaveConf">
<CodemirrorPro v-model="postgresqlConf"></CodemirrorPro>
<el-button type="primary" class="mt-5" @click="onSaveConf">
{{ $t('commons.button.save') }}
</el-button>
</div>
@ -91,21 +79,16 @@ import { FormInstance } from 'element-plus';
import ContainerLog from '@/components/container-log/index.vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { onMounted, reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { loadDBFile, loadDBBaseInfo, updateDBFile } from '@/api/modules/database';
import { ChangePort, CheckAppInstalled } from '@/api/modules/app';
import { Rules } from '@/global/form-rules';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import router from '@/routers';
import { GlobalStore } from '@/store';
const globalStore = GlobalStore();
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const loading = ref(false);
const extensions = [javascript(), oneDark];
const activeName = ref('conf');
const baseInfo = reactive({
@ -132,10 +115,6 @@ const props = withDefaults(defineProps<DBProps>(), {
database: '',
});
const loadHeight = () => {
return globalStore.openMenuTabs ? '405px' : '375px';
};
const dialogContainerLogRef = ref();
const jumpToConf = async () => {
activeName.value = 'conf';

@ -35,31 +35,18 @@
</template>
<template #main>
<div v-if="activeName === 'conf'">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
:style="{ height: `calc(100vh - ${loadHeight()})`, 'margin-top': '10px' }"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
@ready="handleReady"
v-model="redisConf"
/>
<el-button style="margin-top: 10px" @click="getDefaultConfig()">
<CodemirrorPro v-model="redisConf" :placeholder="$t('commons.msg.noneData')"></CodemirrorPro>
<el-button class="mt-5" @click="getDefaultConfig()">
{{ $t('app.defaultConfig') }}
</el-button>
<el-button type="primary" @click="onSaveFile" style="margin-top: 10px">
<el-button type="primary" @click="onSaveFile" class="mt-5">
{{ $t('commons.button.save') }}
</el-button>
<el-row>
<el-col :span="8">
<el-alert
v-if="useOld"
style="margin-top: 10px"
class="mt-5"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
@ -70,7 +57,7 @@
<Status v-show="activeName === 'status'" ref="statusRef" />
<div v-if="activeName === 'tuning'">
<el-form :model="form" ref="formRef" :rules="rules" label-position="top">
<el-row style="margin-top: 20px">
<el-row class="mt-10">
<el-col :span="1"><br /></el-col>
<el-col :span="10">
<el-form-item :label="$t('database.timeout')" prop="timeout">
@ -128,10 +115,7 @@
<script lang="ts" setup>
import { FormInstance } from 'element-plus';
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';
import { reactive, ref } from 'vue';
import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import Status from '@/views/database/redis/setting/status/index.vue';
import Persistence from '@/views/database/redis/setting/persistence/index.vue';
@ -140,22 +124,9 @@ import i18n from '@/lang';
import { checkNumberRange, Rules } from '@/global/form-rules';
import { ChangePort, GetAppDefaultConfig } from '@/api/modules/app';
import { MsgSuccess } from '@/utils/message';
import { GlobalStore } from '@/store';
const globalStore = GlobalStore();
const extensions = [javascript(), oneDark];
const loading = ref(false);
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
const loadHeight = () => {
return globalStore.openMenuTabs ? '410px' : '380px';
};
const form = reactive({
name: '',
port: 6379,
@ -352,13 +323,6 @@ const loadConfFile = async () => {
.then((res) => {
loading.value = false;
redisConf.value = res.data;
nextTick(() => {
const state = view.value.state;
view.value.dispatch({
selection: { anchor: state.doc.length, head: state.doc.length },
scrollIntoView: true,
});
});
})
.catch(() => {
loading.value = false;

@ -51,19 +51,12 @@
</el-table>
</el-tab-pane>
<el-tab-pane :label="$t('process.env')" name="env">
<codemirror
:autofocus="true"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 200px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
<CodemirrorPro
:placeholder="$t('commons.msg.noneData')"
v-model="envStr"
:heightDiff="300"
:disabled="true"
/>
></CodemirrorPro>
</el-tab-pane>
<el-tab-pane :label="$t('process.net')" name="net">
<el-table :data="data.connects" border style="width: 100%">
@ -89,9 +82,6 @@
<script lang="ts" setup>
import { ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
interface InfoProps {
info: object;
@ -103,8 +93,6 @@ const resourceName = ref('');
const activeName = ref('basic');
const envStr = ref('');
const extensions = [javascript(), oneDark];
const handleClose = () => {
open.value = false;
};

@ -19,19 +19,11 @@
</el-form-item>
</el-form>
<div v-else>
<codemirror
:autofocus="true"
<CodemirrorPro
placeholder="# The DNS configuration file does not exist or is empty (/etc/resolv.conf)"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 260px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="dnsConf"
/>
:heightDiff="260"
></CodemirrorPro>
</div>
<template #footer>
<span class="dialog-footer">
@ -51,13 +43,9 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang';
import { MsgError, MsgSuccess } from '@/utils/message';
import { loadDeviceConf, checkDNS, updateDevice, updateDeviceByConf } from '@/api/modules/toolbox';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
const emit = defineEmits<{ (e: 'search'): void }>();
const extensions = [javascript(), oneDark];
const confShowType = ref('form');
const dnsConf = ref();

@ -29,19 +29,13 @@
</el-button>
</div>
<div v-else>
<codemirror
:autofocus="true"
<CodemirrorPro
class="mt-5"
placeholder="# The hosts configuration file does not exist or is empty (/etc/hosts)"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 200px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="hostsConf"
/>
:heightDiff="300"
:disabled="true"
></CodemirrorPro>
</div>
<template #footer>
<span class="dialog-footer">
@ -58,14 +52,10 @@ import { reactive, ref } from 'vue';
import i18n from '@/lang';
import { MsgError, MsgSuccess } from '@/utils/message';
import { loadDeviceConf, updateDeviceByConf, updateDeviceHost } from '@/api/modules/toolbox';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { Toolbox } from '@/api/interface/toolbox';
const emit = defineEmits<{ (e: 'search'): void }>();
const extensions = [javascript(), oneDark];
const confShowType = ref('base');
const hostsConf = ref();

@ -123,20 +123,13 @@
</el-row>
<div v-if="confShowType === 'all'">
<codemirror
:autofocus="true"
<CodemirrorPro
class="mt-5"
placeholder="# The Fail2ban configuration file does not exist or is empty (/etc/ssh/sshd_config)"
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: calc(100vh - 460px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="fail2banConf"
/>
<el-button :disabled="loading" type="primary" @click="onSaveFile" style="margin-top: 5px">
:heightDiff="460"
></CodemirrorPro>
<el-button :disabled="loading" type="primary" @click="onSaveFile" class="mt-2.5">
{{ $t('commons.button.save') }}
</el-button>
</div>
@ -175,9 +168,6 @@
<script lang="ts" setup>
import { onMounted, reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import MaxRetry from '@/views/toolbox/fail2ban/max-retry/index.vue';
import BanTime from '@/views/toolbox/fail2ban/ban-time/index.vue';
import FindTime from '@/views/toolbox/fail2ban/find-time/index.vue';
@ -193,7 +183,6 @@ import { transTimeUnit } from '@/utils/util';
const loading = ref(false);
const formRef = ref();
const extensions = [javascript(), oneDark];
const confShowType = ref('base');
const portRef = ref();

@ -1,20 +1,7 @@
<template>
<div v-loading="loading">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 375px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
:mode="'text/x-ini'"
v-model="content"
/>
<div style="margin-top: 10px">
<CodemirrorPro class="mt-5" v-model="content" :heightDiff="375"></CodemirrorPro>
<div class="mt-5">
<el-button type="primary" @click="submit()" :disabled="loading">
{{ $t('commons.button.save') }}
</el-button>
@ -23,16 +10,10 @@
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { StreamLanguage } from '@codemirror/language';
import { properties } from '@codemirror/legacy-modes/mode/properties';
import { oneDark } from '@codemirror/theme-one-dark';
import i18n from '@/lang';
import { MsgSuccess } from '@/utils/message';
import { OperateSupervisorConfig } from '@/api/modules/host-tool';
const extensions = [StreamLanguage.define(properties), oneDark];
let data = ref();
let content = ref('');
let loading = ref(false);

@ -15,20 +15,7 @@
</div>
<br />
<div v-loading="loading">
<codemirror
style="height: calc(100vh - 430px); min-height: 300px"
:autofocus="true"
:placeholder="$t('website.noLog')"
:indent-with-tab="true"
:tabSize="4"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="content"
@ready="handleReady"
/>
<CodemirrorPro class="mt-5" v-model="content" :heightDiff="400"></CodemirrorPro>
</div>
</template>
@ -44,16 +31,12 @@
<OpDialog ref="opRef" @search="getContent" />
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import { oneDark } from '@codemirror/theme-one-dark';
import { onUnmounted, reactive, ref, shallowRef } from 'vue';
import { onUnmounted, reactive, ref } from 'vue';
import { OperateSupervisorProcessFile } from '@/api/modules/host-tool';
import i18n from '@/lang';
import { TabsPaneContext } from 'element-plus';
import { MsgSuccess } from '@/utils/message';
const extensions = [javascript(), oneDark];
const loading = ref(false);
const content = ref('');
const tailLog = ref(false);
@ -67,10 +50,6 @@ const req = reactive({
const title = ref('');
const opRef = ref();
const view = shallowRef();
const handleReady = (payload) => {
view.value = payload.view;
};
let timer: NodeJS.Timer | null = null;
const em = defineEmits(['search']);

@ -1,31 +1,6 @@
<template>
<el-drawer
v-model="open"
:close-on-click-modal="false"
:close-on-press-escape="false"
:size="size"
:before-close="handleClose"
>
<template #header>
<DrawerHeader :header="$t('website.proxyFile')" :back="handleClose" />
</template>
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: 600px; width: 100%"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="req.content"
/>
</el-col>
</el-row>
<DrawerPro v-model="open" :header="$t('website.proxyFile')" :back="handleClose" :size="mobile ? 'full' : 'normal'">
<CodemirrorPro v-model="req.content" mode="nginx"></CodemirrorPro>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -34,28 +9,23 @@
</el-button>
</span>
</template>
</el-drawer>
</DrawerPro>
</template>
<script lang="ts" setup>
import DrawerHeader from '@/components/drawer-header/index.vue';
import i18n from '@/lang';
import { FormInstance } from 'element-plus';
import { computed, reactive, ref } from 'vue';
import { MsgSuccess } from '@/utils/message';
import { Codemirror } from 'vue-codemirror';
import { UpdateProxyConfigFile } from '@/api/modules/website';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { oneDark } from '@codemirror/theme-one-dark';
import { GlobalStore } from '@/store';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const globalStore = GlobalStore();
const mobile = computed(() => {
return globalStore.isMobile();
});
const extensions = [StreamLanguage.define(nginx), oneDark];
const proxyForm = ref<FormInstance>();
const open = ref(false);
const loading = ref(false);

@ -1,33 +1,6 @@
<template>
<el-drawer
v-model="open"
:close-on-click-modal="false"
:close-on-press-escape="false"
size="40%"
:before-close="handleClose"
>
<template #header>
<DrawerHeader :header="$t('website.proxyFile')" :back="handleClose" />
</template>
<el-row v-loading="loading">
<el-col :span="22" :offset="1">
<div class="redirect-editor">
<codemirror
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
:lineWrapping="true"
:matchBrackets="true"
style="height: 600px"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="req.content"
/>
</div>
</el-col>
</el-row>
<DrawerPro v-model="open" :header="$t('website.proxyFile')" :back="handleClose" size="normal">
<CodemirrorPro v-model="req.content" mode="nginx"></CodemirrorPro>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleClose" :disabled="loading">{{ $t('commons.button.cancel') }}</el-button>
@ -36,22 +9,17 @@
</el-button>
</span>
</template>
</el-drawer>
</DrawerPro>
</template>
<script lang="ts" setup>
import DrawerHeader from '@/components/drawer-header/index.vue';
import i18n from '@/lang';
import { FormInstance } from 'element-plus';
import { reactive, ref } from 'vue';
import { MsgSuccess } from '@/utils/message';
import { Codemirror } from 'vue-codemirror';
import { UpdateRedirectConfigFile } from '@/api/modules/website';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { oneDark } from '@codemirror/theme-one-dark';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const extensions = [StreamLanguage.define(nginx), oneDark];
const proxyForm = ref<FormInstance>();
const open = ref(false);
const loading = ref(false);
@ -90,10 +58,3 @@ defineExpose({
acceptParams,
});
</script>
<style scoped>
.redirect-editor {
margin-top: 10px;
width: 100%;
}
</style>

@ -12,21 +12,7 @@
</el-select>
</el-form-item>
<el-text type="warning">{{ $t('website.rewriteHelper2') }}</el-text>
<Codemirror
ref="codeRef"
v-loading="loading"
:autofocus="true"
placeholder=""
:indent-with-tab="true"
:tabSize="4"
style="margin-top: 10px; height: 300px"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="content"
/>
<CodemirrorPro v-model="content" mode="nginx"></CodemirrorPro>
<div class="mt-2">
<el-form-item>
<el-alert :title="$t('website.rewriteHelper')" type="info" :closable="false" />
@ -40,18 +26,14 @@
<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { oneDark } from '@codemirror/theme-one-dark';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { GetWebsite, GetRewriteConfig, UpdateRewriteConfig } from '@/api/modules/website';
import { Rewrites } from '@/global/mimetype';
import { MsgSuccess } from '@/utils/message';
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
import i18n from '@/lang';
const loading = ref(false);
const content = ref(' ');
const extensions = [StreamLanguage.define(nginx), oneDark];
const codeRef = ref();
const props = defineProps({

@ -1,34 +1,18 @@
<template>
<div v-loading="loading">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="content"
/>
<CodemirrorPro v-model="content" mode="nginx" />
<el-button type="primary" @click="submit()" class="mt-2.5">
{{ $t('nginx.saveAndReload') }}
</el-button>
</div>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { oneDark } from '@codemirror/theme-one-dark';
import { GetWebsiteConfig, UpdateNginxFile } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import { File } from '@/api/interface/file';
import i18n from '@/lang';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { MsgSuccess } from '@/utils/message';
const extensions = [StreamLanguage.define(nginx), oneDark];
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const props = defineProps({
id: {

@ -1,18 +1,6 @@
<template>
<div v-loading="loading">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="height: calc(100vh - 352px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
v-model="content"
/>
<CodemirrorPro v-model="content"></CodemirrorPro>
<el-button type="primary" @click="openUpdate()" class="mt-2.5">
{{ $t('nginx.saveAndReload') }}
</el-button>
@ -20,17 +8,12 @@
</div>
</template>
<script lang="ts" setup>
import { Codemirror } from 'vue-codemirror';
import { oneDark } from '@codemirror/theme-one-dark';
import { GetWebsiteConfig, UpdatePHPFile } from '@/api/modules/website';
import { computed, onMounted, ref } from 'vue';
import { File } from '@/api/interface/file';
import i18n from '@/lang';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { MsgSuccess } from '@/utils/message';
const extensions = [StreamLanguage.define(nginx), oneDark];
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
const props = defineProps({
id: {

@ -1,6 +1,6 @@
<template>
<LayoutContent :title="$t('nginx.nginxConfig')" :reload="true">
<template #buttons>
<template #leftToolBar>
<el-button type="primary" :plain="activeName !== '1'" @click="changeTab('1')">
{{ $t('nginx.status') }}
</el-button>

@ -1,20 +1,7 @@
<template>
<div v-loading="loading">
<codemirror
:autofocus="true"
:placeholder="$t('commons.msg.noneData')"
:indent-with-tab="true"
:tabSize="4"
style="width: 100%; height: calc(100vh - 375px)"
:lineWrapping="true"
:matchBrackets="true"
theme="cobalt"
:styleActiveLine="true"
:extensions="extensions"
:mode="'text/x-nginx-conf'"
v-model="content"
/>
<div style="margin-top: 10px">
<CodemirrorPro v-model="content" mode="nginx"></CodemirrorPro>
<div class="mt-2.5">
<el-button @click="getDefaultConfig()" :disabled="loading">
{{ $t('app.defaultConfig') }}
</el-button>
@ -26,7 +13,7 @@
<el-col :span="4">
<el-alert
v-if="useOld"
style="margin-top: 10px"
class="mt-2.5"
:title="$t('app.defaultConfigHelper')"
type="info"
:closable="false"
@ -38,15 +25,10 @@
<script lang="ts" setup>
import { GetNginx, UpdateNginxConfigFile } from '@/api/modules/nginx';
import { onMounted, ref } from 'vue';
import { Codemirror } from 'vue-codemirror';
import { StreamLanguage } from '@codemirror/language';
import { nginx } from '@codemirror/legacy-modes/mode/nginx';
import { oneDark } from '@codemirror/theme-one-dark';
import i18n from '@/lang';
import { GetAppDefaultConfig } from '@/api/modules/app';
import { MsgSuccess } from '@/utils/message';
const extensions = [StreamLanguage.define(nginx), oneDark];
import CodemirrorPro from '@/components/codemirror-pro/index.vue';
let content = ref('');
let loading = ref(false);

Loading…
Cancel
Save