Skip to content

Commit

Permalink
feat: support edit as JSON, fix koishijs/koishi#1270
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 21, 2024
1 parent b13d3d8 commit b8425dc
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 4 deletions.
5 changes: 5 additions & 0 deletions packages/form/src/icons/code.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<svg class="k-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512">
<path fill="currentColor" d="M414.9 31.11L270.9 495.1C266.1 507.8 253.5 514.8 240.9 510.9C228.2 506.1 221.1 493.5 225.1 480.9L369.1 16.89C373 4.226 386.5-2.852 399.1 1.077C411.8 5.006 418.9 18.45 414.9 31.11V31.11zM504.4 118.5L632.4 238.5C637.3 243 640 249.4 640 255.1C640 262.6 637.3 268.1 632.4 273.5L504.4 393.5C494.7 402.6 479.6 402.1 470.5 392.4C461.4 382.7 461.9 367.6 471.6 358.5L580.9 255.1L471.6 153.5C461.9 144.4 461.4 129.3 470.5 119.6C479.6 109.9 494.7 109.4 504.4 118.5V118.5zM168.4 153.5L59.09 255.1L168.4 358.5C178.1 367.6 178.6 382.7 169.5 392.4C160.4 402.1 145.3 402.6 135.6 393.5L7.585 273.5C2.746 268.1 0 262.6 0 255.1C0 249.4 2.746 243 7.585 238.5L135.6 118.5C145.3 109.4 160.4 109.9 169.5 119.6C178.6 129.3 178.1 144.4 168.4 153.5V153.5z"/>
</svg>
</template>
2 changes: 2 additions & 0 deletions packages/form/src/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import IconArrowDown from './arrow-down.vue'
import IconArrowUp from './arrow-up.vue'
import IconBranch from './branch.vue'
import IconClose from './close.vue'
import IconCode from './code.vue'
import IconCollapse from './collapse.vue'
import IconDelete from './delete.vue'
import IconEllipsis from './ellipsis.vue'
Expand All @@ -25,6 +26,7 @@ export {
IconArrowUp,
IconBranch,
IconClose,
IconCode,
IconCollapse,
IconDelete,
IconEllipsis,
Expand Down
6 changes: 6 additions & 0 deletions packages/form/src/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ initial: Undo
default: Restore to Default
collapse: Collapse
expand: Expand to Edit
edit:
json: Edit JSON
invalid: Invalid configuration.
save: Save Changes
copy: Copy to Clipboard
copied: Copied
badge:
deprecated: deprecated
experimental: experimental
Expand Down
6 changes: 6 additions & 0 deletions packages/form/src/locales/zh-CN.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ initial: 撤销更改
default: 恢复默认值
collapse: 折叠子项
expand: 展开以编辑
edit:
json: 编辑 JSON
invalid: 无效的配置。
save: 保存更改
copy: 复制到剪贴板
copied: 已复制
badge:
deprecated: 已废弃
experimental: 实验性
Expand Down
71 changes: 67 additions & 4 deletions packages/form/src/schema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
>
<template #title><slot name="title"></slot></template>
<template #menu>
<div
class="k-menu-item"
@click="showJson = true">
<span class="k-menu-icon"><icon-code></icon-code></span>
{{ t('edit.json') }}
</div>
<div
class="k-menu-item"
:class="{ disabled: disabled || deepEqual(initial, modelValue) }"
Expand Down Expand Up @@ -49,15 +55,43 @@
></schema-primitive>
</template>
</schema-component>
<el-dialog
v-model="showJson"
destroy-on-close
class="k-schema-edit-dialog"
:title="t('edit.json')"
@open="input?.focus()"
>
<el-input
ref="input"
type="textarea"
:class="{ invalid: jsonError }"
:autosize="{ minRows: 2, maxRows: 10 }"
v-model="jsonInput"
></el-input>
<template #footer>
<div></div>
<div>
<el-button @click="copyToClipboard">{{ t('edit.copy') }}</el-button>
<el-button
type="primary"
:disabled="!!jsonError"
@click="saveChanges"
>{{ t('edit.save') }}</el-button>
</div>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { computed, PropType } from 'vue'
import { computed, PropType, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { clone, deepEqual, isNullable } from 'cosmokit'
import extensions, { Schema, useI18nText } from './utils'
import { IconUndo, IconReset } from './icons'
import { ElMessage } from 'element-plus'
import extensions, { getFallback, Schema, useI18nText } from './utils'
import { IconCode, IconUndo, IconReset } from './icons'
import SchemaPrimitive from './primitive.vue'
import SchemaBase from './base.vue'
import zhCN from './locales/zh-CN.yml'
Expand All @@ -73,7 +107,36 @@ const props = defineProps({
prefix: { type: String, default: '' },
})
defineEmits(['update:modelValue'])
const emit = defineEmits(['update:modelValue'])
const input = ref()
const showJson = ref(false)
const jsonInput = ref('')
const jsonError = ref('')
watch(() => props.modelValue, (value) => {
jsonInput.value = JSON.stringify(value ?? getFallback(props.schema), null, 2)
}, { immediate: true })
watch(jsonInput, (value: string) => {
jsonError.value = ''
try {
const config = JSON.parse(value)
Schema(props.schema)(config)
} catch (e) {
jsonError.value = t('edit.invalid')
}
})
async function copyToClipboard() {
await navigator.clipboard.writeText(jsonInput.value)
ElMessage.success(t('edit.copied'))
}
function saveChanges() {
emit('update:modelValue', Schema(props.schema).simplify(JSON.parse(jsonInput.value)))
showJson.value = false
}
const tt = useI18nText()
Expand Down
15 changes: 15 additions & 0 deletions packages/form/src/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,18 @@
border-top: none;
}
}

.el-input.invalid .el-input__wrapper {
box-shadow: 0 0 0 1px var(--el-color-danger) inset;
}

.el-textarea.invalid .el-textarea__inner {
box-shadow: 0 0 0 1px var(--el-color-danger) inset;
}

.k-schema-edit-dialog {
.el-dialog__footer {
display: flex;
justify-content: space-between;
}
}

0 comments on commit b8425dc

Please sign in to comment.