diff --git a/dolphinscheduler-ui-next/src/components/form/fields.ts b/dolphinscheduler-ui-next/src/components/form/fields.ts index 1fe4388ce3..e1d5b859b9 100644 --- a/dolphinscheduler-ui-next/src/components/form/fields.ts +++ b/dolphinscheduler-ui-next/src/components/form/fields.ts @@ -17,6 +17,7 @@ import { h } from 'vue' import { NInput, NRadio, NRadioGroup, NSpace } from 'naive-ui' +import Editor from '@/components/monaco-editor' import type { IFieldParams } from './types' // TODO Support other widgets later @@ -52,3 +53,13 @@ export function renderRadio(params: IFieldParams) { ) ) } + +// Editor +export function renderEditor(params: IFieldParams) { + const { props, fields, field } = params + return h(Editor, { + ...props, + value: fields[field], + onUpdateValue: (value) => void (fields[field] = value) + }) +} diff --git a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts index e88037000d..48fdef396a 100644 --- a/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts +++ b/dolphinscheduler-ui-next/src/components/form/get-elements-by-json.ts @@ -22,9 +22,7 @@ import type { IJsonItem } from './types' export default function getElementByJson( json: IJsonItem[], - fields: { [field: string]: any }, - t: Function, - prefix: string + fields: { [field: string]: any } ) { const rules: FormRules = {} const initialValues: { [field: string]: any } = {} @@ -41,6 +39,13 @@ export default function getElementByJson( options }) } + if (type === 'editor') { + return Field.renderEditor({ + field, + fields, + props + }) + } return Field.renderInput({ field, fields, props }) } @@ -50,7 +55,7 @@ export default function getElementByJson( initialValues[item.field] = item.value if (item.validate) rules[item.field] = formatValidate(item.validate) elements.push({ - label: t(prefix + '.' + item.field), + label: item.name, path: item.field, widget: () => getElement(item) }) diff --git a/dolphinscheduler-ui-next/src/components/form/types.ts b/dolphinscheduler-ui-next/src/components/form/types.ts index 95babad420..70993cd90e 100644 --- a/dolphinscheduler-ui-next/src/components/form/types.ts +++ b/dolphinscheduler-ui-next/src/components/form/types.ts @@ -24,7 +24,7 @@ import type { SelectOption } from 'naive-ui' -type IType = 'input' | 'radio' +type IType = 'input' | 'radio' | 'editor' type IOption = SelectOption diff --git a/dolphinscheduler-ui-next/src/components/form/utils.ts b/dolphinscheduler-ui-next/src/components/form/utils.ts index 20c5df1a0f..fc41698afb 100644 --- a/dolphinscheduler-ui-next/src/components/form/utils.ts +++ b/dolphinscheduler-ui-next/src/components/form/utils.ts @@ -27,7 +27,7 @@ export function formatValidate( ): FormItemRule { if (!validate) return {} if (Array.isArray(validate)) { - validate.map((item: FormItemRule) => { + validate.forEach((item: FormItemRule) => { if (!item?.message) delete item.message return item }) diff --git a/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx b/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx index 1fbbfb5e63..a0f21c3072 100644 --- a/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx +++ b/dolphinscheduler-ui-next/src/components/monaco-editor/index.tsx @@ -24,18 +24,26 @@ import { ref, watch } from 'vue' +import { useFormItem } from 'naive-ui/es/_mixins' +import { call } from 'naive-ui/es/_utils' import * as monaco from 'monaco-editor' import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' +import type { MaybeArray, OnUpdateValue, OnUpdateValueImpl } from './types' const props = { - modelValue: { + value: { type: String as PropType, default: '' }, + defaultValue: { + type: String as PropType + }, + 'onUpdate:value': [Function, Array] as PropType>, + onUpdateValue: [Function, Array] as PropType>, language: { type: String as PropType, default: 'shell' @@ -72,13 +80,18 @@ window.MonacoEnvironment = { export default defineComponent({ name: 'MonacoEditor', props, - setup(props) { + emits: ['change', 'focus', 'blur'], + setup(props, ctx) { let editor = null as monaco.editor.IStandaloneCodeEditor | null - const content = ref() + + const editorRef = ref() + const getValue = () => editor?.getValue() + const formItem = useFormItem({}) + watch( - () => props.modelValue, + () => props.value, (val) => { if (val !== getValue()) { editor?.setValue(val) @@ -87,17 +100,34 @@ export default defineComponent({ ) onMounted(async () => { - content.value = props.modelValue - await nextTick() - const dom = document.getElementById('monaco-container') + const dom = editorRef.value if (dom) { editor = monaco.editor.create(dom, props.options, { - value: props.modelValue, + value: props.defaultValue ?? props.value, language: props.language, readOnly: props.readOnly, automaticLayout: true }) + editor.onDidChangeModelContent(() => { + const { onUpdateValue, 'onUpdate:value': _onUpdateValue } = props + const value = editor?.getValue() || '' + + if (onUpdateValue) call(onUpdateValue as OnUpdateValueImpl, value) + if (_onUpdateValue) call(_onUpdateValue as OnUpdateValueImpl, value) + ctx.emit('change', value) + + formItem.nTriggerFormChange() + formItem.nTriggerFormInput() + }) + editor.onDidBlurEditorWidget(() => { + ctx.emit('blur') + formItem.nTriggerFormBlur() + }) + editor.onDidFocusEditorWidget(() => { + ctx.emit('focus') + formItem.nTriggerFormFocus() + }) } }) @@ -105,14 +135,17 @@ export default defineComponent({ editor?.dispose() }) - return { getValue } + ctx.expose({ getValue }) + + return { editorRef } }, render() { return (
diff --git a/dolphinscheduler-ui-next/src/components/monaco-editor/types.ts b/dolphinscheduler-ui-next/src/components/monaco-editor/types.ts new file mode 100644 index 0000000000..830c07aebf --- /dev/null +++ b/dolphinscheduler-ui-next/src/components/monaco-editor/types.ts @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import type { MaybeArray } from 'naive-ui/es/_utils' + +type OnUpdateValue = (value: T) => void +type OnUpdateValueImpl = (value: string) => void + +export { MaybeArray, OnUpdateValue, OnUpdateValueImpl } diff --git a/dolphinscheduler-ui-next/src/views/datasource/list/use-columns.ts b/dolphinscheduler-ui-next/src/views/datasource/list/use-columns.ts index 7ff3afd157..5a73c7438a 100644 --- a/dolphinscheduler-ui-next/src/views/datasource/list/use-columns.ts +++ b/dolphinscheduler-ui-next/src/views/datasource/list/use-columns.ts @@ -91,7 +91,6 @@ export function useColumns(onCallback: Function) { NButton, { circle: true, - class: styles['mr-10'], type: 'info', onClick: () => void onCallback(rowData.id, 'edit') }, diff --git a/dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx b/dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx index 711e5f2614..ba55691fca 100644 --- a/dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx +++ b/dolphinscheduler-ui-next/src/views/resource/file/create/index.tsx @@ -35,7 +35,6 @@ export default defineComponent({ setup() { const router: Router = useRouter() - const codeEditorRef = ref() const { state } = useForm() const { handleCreateFile } = useCreate(state) @@ -46,7 +45,6 @@ export default defineComponent({ })) const handleFile = () => { - state.fileForm.content = codeEditorRef.value?.getValue() handleCreateFile() } @@ -57,7 +55,6 @@ export default defineComponent({ } return { - codeEditorRef, fileSuffixOptions, handleFile, handleReturn, @@ -105,7 +102,7 @@ export default defineComponent({ width: '90%' }} > - +
diff --git a/dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx b/dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx index c76076685b..c6caf2336b 100644 --- a/dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx +++ b/dolphinscheduler-ui-next/src/views/resource/file/edit/index.tsx @@ -33,7 +33,6 @@ export default defineComponent({ const router: Router = useRouter() const resourceViewRef = ref() - const codeEditorRef = ref() const routeNameRef = ref(router.currentRoute.value.name) const idRef = ref(Number(router.currentRoute.value.params.id)) @@ -41,7 +40,7 @@ export default defineComponent({ const { getResourceView, handleUpdateContent } = useEdit(state) const handleFileContent = () => { - state.fileForm.content = codeEditorRef.value?.getValue() + state.fileForm.content = resourceViewRef.value.content handleUpdateContent(idRef.value) } @@ -56,7 +55,6 @@ export default defineComponent({ return { idRef, routeNameRef, - codeEditorRef, resourceViewRef, handleReturn, handleFileContent, @@ -84,8 +82,7 @@ export default defineComponent({ }} >
diff --git a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx index a42648437e..80fefa6a77 100644 --- a/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx +++ b/dolphinscheduler-ui-next/src/views/security/alarm-instance-manage/detail.tsx @@ -83,13 +83,12 @@ const DetailModal = defineComponent({ watch( () => state.json, () => { + if (state.json?.length) return + state.json.forEach((item) => { + item.name = t('security.alarm_instance' + '.' + item.field) + }) const { rules: fieldsRules, elements: fieldsElements } = - getElementByJson( - state.json, - state.detailForm, - t, - 'security.alarm_instance' - ) + getElementByJson(state.json, state.detailForm) rules.value = fieldsRules elements.value = fieldsElements }