fix(editor): 区分直接关闭和保存后关闭

#440
This commit is contained in:
parisma 2022-10-31 15:17:41 +08:00
parent 0f0ec183a8
commit 0eab817a11
4 changed files with 82 additions and 67 deletions

View File

@ -319,6 +319,7 @@ export default defineComponent({
provide('services', services); provide('services', services);
provide('codeOptions', props.codeOptions);
provide( provide(
'stageOptions', 'stageOptions',
reactive({ reactive({

View File

@ -5,12 +5,8 @@
class="m-editor-container" class="m-editor-container"
:init-values="`${codeContent}`" :init-values="`${codeContent}`"
@save="saveCodeDraft" @save="saveCodeDraft"
:options="{ :language="language"
tabSize: 2, :options="codeOptions"
fontSize: 16,
formatOnPaste: true,
readOnly: !editable,
}"
></magic-code-editor> ></magic-code-editor>
<div class="m-editor-content-bottom" v-if="editable"> <div class="m-editor-content-bottom" v-if="editable">
<TMagicButton type="primary" class="button" @click="saveCode">保存</TMagicButton> <TMagicButton type="primary" class="button" @click="saveCode">保存</TMagicButton>
@ -22,7 +18,7 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { inject, ref, watchEffect } from 'vue'; import { computed, inject, ref, watchEffect } from 'vue';
import type * as monaco from 'monaco-editor'; import type * as monaco from 'monaco-editor';
import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design'; import { TMagicButton, tMagicMessage, tMagicMessageBox } from '@tmagic/design';
@ -31,9 +27,6 @@ import { datetimeFormatter } from '@tmagic/utils';
import MagicCodeEditor from '../layouts/CodeEditor.vue'; import MagicCodeEditor from '../layouts/CodeEditor.vue';
import type { Services } from '../type'; import type { Services } from '../type';
// 稿
const draftTipTimeOut = 100;
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
/** 代码id */ /** 代码id */
@ -44,22 +37,30 @@ const props = withDefaults(
editable?: boolean; editable?: boolean;
/** 是否自动保存草稿 */ /** 是否自动保存草稿 */
autoSaveDraft?: boolean; autoSaveDraft?: boolean;
/** 编辑器参数 */
codeOptions?: Object;
/** 编辑器语言 */
language?: string;
}>(), }>(),
{ {
editable: true, editable: true,
autoSaveDraft: true, autoSaveDraft: true,
}, },
); );
const emit = defineEmits(['save', 'close']); const emit = defineEmits(['save', 'close', 'saveAndClose']);
const services = inject<Services>('services'); const services = inject<Services>('services');
const codeContent = ref<string>(''); const codeContent = ref<string>('');
const editorContent = ref<string>('');
const codeEditor = ref<InstanceType<typeof MagicCodeEditor>>(); const codeEditor = ref<InstanceType<typeof MagicCodeEditor>>();
// //
const originCodeContent = ref<string | null>(null); const originCodeContent = ref<string | null>(null);
// 稿
const shouldShowDraftTip = ref(true); const codeOptions = computed(() => ({
...props.codeOptions,
readOnly: !props.editable,
}));
watchEffect(() => { watchEffect(() => {
codeContent.value = props.content; codeContent.value = props.content;
@ -83,63 +84,45 @@ const saveCodeDraft = async (codeValue: string) => {
return; return;
} }
services?.codeBlockService.setCodeDraft(props.id, codeValue); services?.codeBlockService.setCodeDraft(props.id, codeValue);
tMagicMessage.success(`代码草稿保存成功 ${datetimeFormatter(new Date())}`);
setTimeout(() => {
if (shouldShowDraftTip.value) {
tMagicMessage.success(`代码草稿保存成功 ${datetimeFormatter(new Date())}`);
}
}, draftTipTimeOut);
}; };
// //
const saveCode = async (): Promise<boolean> => { const saveCode = (): void => {
if (!codeEditor.value || !props.editable) return true; if (!codeEditor.value || !props.editable) return;
//
try { editorContent.value = (codeEditor.value.getEditor() as monaco.editor.IStandaloneCodeEditor)?.getValue();
// emit('save', editorContent.value);
const editorContent = (codeEditor.value.getEditor() as monaco.editor.IStandaloneCodeEditor)?.getValue();
/* eslint no-eval: "off" */
eval(editorContent);
//
shouldShowDraftTip.value = false;
// 稿
services?.codeBlockService.removeCodeDraft(props.id);
emit('save', editorContent);
shouldShowDraftTip.value = true;
return true;
} catch (e: any) {
tMagicMessage.error(e.stack);
return false;
}
}; };
const beforeClose = async () => { //
const codeDraft = services?.codeBlockService.getCodeDraft(props.id); const saveAndClose = (): void => {
if (!codeDraft || !props.autoSaveDraft) { if (!codeEditor.value || !props.editable) return;
return await saveCode(); //
} editorContent.value = (codeEditor.value.getEditor() as monaco.editor.IStandaloneCodeEditor)?.getValue();
let saveRes = true; emit('saveAndClose', editorContent.value);
await tMagicMessageBox
.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
//
saveRes = await saveCode();
})
.catch(() => {
// 稿
services?.codeBlockService.removeCodeDraft(props.id);
});
return saveRes;
}; };
// //
const close = async () => { const close = async () => {
const shouldClose = await beforeClose(); const codeDraft = services?.codeBlockService.getCodeDraft(props.id);
if (shouldClose) { if (codeDraft) {
tMagicMessageBox
.confirm('您有代码修改未保存,是否保存后再关闭?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
//
saveAndClose();
})
.catch(() => {
// 稿
services?.codeBlockService.removeCodeDraft(props.id);
emit('close');
});
} else {
emit('close'); emit('close');
} }
}; };

View File

@ -11,7 +11,10 @@
:content="codeContent" :content="codeContent"
:editable="editable" :editable="editable"
:autoSaveDraft="autoSaveDraft" :autoSaveDraft="autoSaveDraft"
:codeOptions="codeOptions"
language="javascript"
@save="saveCode" @save="saveCode"
@saveAndClose="saveAndClose"
@close="close" @close="close"
></CodeDraftEditor> ></CodeDraftEditor>
</TMagicCard> </TMagicCard>
@ -32,6 +35,7 @@ const props = withDefaults(
content: string; content: string;
editable?: boolean; editable?: boolean;
autoSaveDraft?: boolean; autoSaveDraft?: boolean;
codeOptions?: object;
}>(), }>(),
{ {
editable: true, editable: true,
@ -43,22 +47,47 @@ const services = inject<Services>('services');
const codeName = ref<string>(''); const codeName = ref<string>('');
const codeContent = ref<string>(''); const codeContent = ref<string>('');
const evalRes = ref(true);
watchEffect(() => { watchEffect(() => {
codeName.value = props.name; codeName.value = props.name;
codeContent.value = props.content; codeContent.value = props.content;
}); });
//
const beforeSave = (codeValue: string): boolean => {
try {
// eslint-disable-next-line no-eval
eval(codeValue);
return true;
} catch (e: any) {
tMagicMessage.error(e.stack);
return false;
}
};
// //
const saveCode = async (codeValue: string): Promise<void> => { const saveCode = async (codeValue: string): Promise<void> => {
if (!props.editable) return; if (!props.editable) return;
evalRes.value = beforeSave(codeValue);
if (evalRes.value) {
// dsl
await services?.codeBlockService.setCodeDslById(props.id, {
name: codeName.value,
content: codeValue,
});
tMagicMessage.success('代码保存成功');
// 稿
services?.codeBlockService.removeCodeDraft(props.id);
}
};
// dsl //
await services?.codeBlockService.setCodeDslById(props.id, { const saveAndClose = async (codeValue: string) => {
name: codeName.value, await saveCode(codeValue);
content: codeValue, if (evalRes.value) {
}); close();
tMagicMessage.success('代码保存成功'); }
}; };
// //

View File

@ -48,6 +48,7 @@
:content="codeConfig.content" :content="codeConfig.content"
:editable="!!editable" :editable="!!editable"
:autoSaveDraft="mode === CodeEditorMode.EDITOR" :autoSaveDraft="mode === CodeEditorMode.EDITOR"
:codeOptions="codeOptions"
></FunctionEditor> ></FunctionEditor>
</div> </div>
</template> </template>
@ -68,6 +69,7 @@ import { CodeEditorMode } from '../../../type';
import { serializeConfig } from '../../../utils/editor'; import { serializeConfig } from '../../../utils/editor';
const services = inject<Services>('services'); const services = inject<Services>('services');
const codeOptions = inject('codeOptions', {});
const left = ref(200); const left = ref(200);
const currentTitle = ref(''); const currentTitle = ref('');