feat: embedded monaco editor for complex types

This commit is contained in:
Lykin 2023-11-29 00:24:42 +08:00
parent 8662027a68
commit 6b1fcb3779
2 changed files with 29 additions and 10 deletions

View File

@ -11,6 +11,7 @@ import FullScreen from '@/components/icons/FullScreen.vue'
import WindowClose from '@/components/icons/WindowClose.vue' import WindowClose from '@/components/icons/WindowClose.vue'
import Pin from '@/components/icons/Pin.vue' import Pin from '@/components/icons/Pin.vue'
import OffScreen from '@/components/icons/OffScreen.vue' import OffScreen from '@/components/icons/OffScreen.vue'
import ContentEditor from '@/components/content_value/ContentEditor.vue'
const props = defineProps({ const props = defineProps({
field: { field: {
@ -79,6 +80,19 @@ const displayValue = computed(() => {
} }
return viewAs.value return viewAs.value
}) })
const editingContent = ref('')
const enableSave = computed(() => {
return editingContent.value !== viewAs.value
})
const viewLanguage = computed(() => {
switch (viewAs.format) {
case formatTypes.JSON:
return 'json'
default:
return 'plaintext'
}
})
const btnStyle = computed(() => ({ const btnStyle = computed(() => ({
padding: '3px', padding: '3px',
@ -112,7 +126,7 @@ const onFormatChanged = async (decode = '', format = '') => {
format, format,
}) })
viewAs.field = props.field + '' viewAs.field = props.field + ''
viewAs.value = value editingContent.value = viewAs.value = value
viewAs.decode = decode || retDecode viewAs.decode = decode || retDecode
viewAs.format = format || retFormat viewAs.format = format || retFormat
} finally { } finally {
@ -125,6 +139,10 @@ const onUpdateValue = (value) => {
viewAs.value = value viewAs.value = value
} }
const onInput = (content) => {
editingContent.value = content
}
const onToggleFullscreen = () => { const onToggleFullscreen = () => {
emit('update:fullscreen', !!!props.fullscreen) emit('update:fullscreen', !!!props.fullscreen)
} }
@ -135,7 +153,7 @@ const onClose = () => {
} }
const onSave = () => { const onSave = () => {
emit('save', viewAs.field, viewAs.value, viewAs.decode, viewAs.format) emit('save', viewAs.field, editingContent.value, viewAs.decode, viewAs.format)
if (!isPin.value) { if (!isPin.value) {
nextTick().then(onClose) nextTick().then(onClose)
} }
@ -160,14 +178,14 @@ const onSave = () => {
<!-- value --> <!-- value -->
<div class="editor-content-item flex-box-v flex-item-expand"> <div class="editor-content-item flex-box-v flex-item-expand">
<div class="editor-content-item-label">{{ props.valueLabel }}</div> <div class="editor-content-item-label">{{ props.valueLabel }}</div>
<n-input <content-editor
:placeholder="props.value" :border="true"
:resizable="false" :content="displayValue"
:value="displayValue" :language="viewLanguage"
autofocus
class="flex-item-expand" class="flex-item-expand"
type="textarea" style="height: 100%"
@update:value="onUpdateValue" /> @input="onInput"
@reset="onInput" />
<format-selector <format-selector
:decode="viewAs.decode" :decode="viewAs.decode"
:format="viewAs.format" :format="viewAs.format"
@ -202,7 +220,7 @@ const onSave = () => {
</template> </template>
<template #action> <template #action>
<n-space :wrap="false" :wrap-item="false" justify="end"> <n-space :wrap="false" :wrap-item="false" justify="end">
<n-button ghost @click="onSave"> <n-button :disabled="!enableSave" :secondary="enableSave" type="primary" @click="onSave">
<template #icon> <template #icon>
<n-icon :component="Save" /> <n-icon :component="Save" />
</template> </template>

View File

@ -162,6 +162,7 @@ const saveEdit = async (field, value, decode, format) => {
index: [currentEditRow.no - 1], index: [currentEditRow.no - 1],
}) })
if (success) { if (success) {
currentEditRow.value = value
$message.success(i18n.t('dialogue.save_value_succ')) $message.success(i18n.t('dialogue.save_value_succ'))
} else { } else {
$message.error(msg) $message.error(msg)