36 changed files with 281 additions and 887 deletions
@ -1,8 +1,4 @@ |
|||||
{ |
{ |
||||
"menu.testcase": "Test Case", |
"menu.testcase": "Test Case", |
||||
"menu.testcase.component": "Component", |
"menu.testcase.formElements": "Form Elements" |
||||
"menu.testcase.dialog": "Dialog", |
|
||||
"menu.testcase.select": "Select", |
|
||||
"menu.testcase.treeGrid": "Tree Grid", |
|
||||
"menu.testcase.table": "Table" |
|
||||
} |
} |
||||
|
@ -1,8 +1,4 @@ |
|||||
{ |
{ |
||||
"menu.testcase": "測試用例", |
"menu.testcase": "測試用例", |
||||
"menu.testcase.component": "組件", |
"menu.testcase.formElements": "表單控件" |
||||
"menu.testcase.dialog": "Dialog", |
|
||||
"menu.testcase.select": "Select", |
|
||||
"menu.testcase.treeGrid": "Tree Grid", |
|
||||
"menu.testcase.table": "Table" |
|
||||
} |
} |
||||
|
@ -1,8 +1,4 @@ |
|||||
{ |
{ |
||||
"menu.testcase": "测试用例", |
"menu.testcase": "测试用例", |
||||
"menu.testcase.component": "组件", |
"menu.testcase.formElements": "表单控件" |
||||
"menu.testcase.dialog": "Dialog", |
|
||||
"menu.testcase.select": "Select", |
|
||||
"menu.testcase.treeGrid": "Tree Grid", |
|
||||
"menu.testcase.table": "Table" |
|
||||
} |
} |
||||
|
@ -0,0 +1,170 @@ |
|||||
|
<template> |
||||
|
<q-field v-bind="attrs" :stack-label="stackLabelRef" @focus="focus" @blur="blur"> |
||||
|
<template #control> |
||||
|
<div ref="codemirrorRef" style="width: 100%"></div> |
||||
|
</template> |
||||
|
</q-field> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, useAttrs, onMounted, onUnmounted, onUpdated } from 'vue'; |
||||
|
import { Tools } from '@/platform'; |
||||
|
import { EditorView } from '@codemirror/view'; |
||||
|
import { EditorState, Compartment } from '@codemirror/state'; |
||||
|
import * as view from '@codemirror/view'; |
||||
|
import * as language from '@codemirror/language'; |
||||
|
import * as commands from '@codemirror/commands'; |
||||
|
import * as search from '@codemirror/search'; |
||||
|
import * as autocomplete from '@codemirror/autocomplete'; |
||||
|
|
||||
|
import { LanguageSupport } from '@codemirror/language'; |
||||
|
import { html } from '@codemirror/lang-html'; |
||||
|
import { java } from '@codemirror/lang-java'; |
||||
|
import { javascript } from '@codemirror/lang-javascript'; |
||||
|
import { json } from '@codemirror/lang-json'; |
||||
|
import { sql } from '@codemirror/lang-sql'; |
||||
|
import { xml } from '@codemirror/lang-xml'; |
||||
|
|
||||
|
const attrs = useAttrs(); |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
modelValue: { type: String, default: '' }, |
||||
|
lang: { type: String, default: 'json' }, |
||||
|
width: { type: [Number, String], default: '100%' }, |
||||
|
height: { type: [Number, String], default: undefined }, |
||||
|
rows: { type: Number, default: 4 }, |
||||
|
tabSize: { type: Number, default: 4 }, |
||||
|
}); |
||||
|
|
||||
|
const emits = defineEmits(['update:modelValue']); |
||||
|
|
||||
|
const basicSetup = [ |
||||
|
EditorState.allowMultipleSelections.of(true), |
||||
|
|
||||
|
//view.lineNumbers(), |
||||
|
//view.highlightActiveLine(), |
||||
|
view.highlightActiveLineGutter(), |
||||
|
view.highlightSpecialChars(), |
||||
|
view.drawSelection(), |
||||
|
view.dropCursor(), |
||||
|
view.rectangularSelection(), |
||||
|
view.crosshairCursor(), |
||||
|
|
||||
|
commands.history(), |
||||
|
|
||||
|
//language.foldGutter(), |
||||
|
language.indentOnInput(), |
||||
|
language.syntaxHighlighting(language.defaultHighlightStyle, { fallback: true }), |
||||
|
language.bracketMatching(), |
||||
|
|
||||
|
autocomplete.closeBrackets(), |
||||
|
autocomplete.autocompletion(), |
||||
|
|
||||
|
search.highlightSelectionMatches(), |
||||
|
|
||||
|
view.keymap.of([ |
||||
|
...commands.defaultKeymap, |
||||
|
...commands.historyKeymap, |
||||
|
...language.foldKeymap, |
||||
|
...autocomplete.completionKeymap, |
||||
|
...autocomplete.closeBracketsKeymap, |
||||
|
...search.searchKeymap, |
||||
|
//commands.indentWithTab, |
||||
|
]), |
||||
|
]; |
||||
|
|
||||
|
const getLanguage = (lang: string): LanguageSupport => { |
||||
|
lang = lang || 'json'; |
||||
|
switch (lang.toLowerCase()) { |
||||
|
case 'html': |
||||
|
return html(); |
||||
|
case 'java': |
||||
|
return java(); |
||||
|
case 'javascript': |
||||
|
return javascript(); |
||||
|
case 'json': |
||||
|
return json(); |
||||
|
case 'sql': |
||||
|
return sql(); |
||||
|
case 'xml': |
||||
|
return xml(); |
||||
|
default: |
||||
|
return json(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const codemirrorRef = ref(); |
||||
|
// q-field 的 stack-label 属性是对 field 的 label 进行设置效果 |
||||
|
// 如果 field 有值时, 无论是否获得焦点 label 都缩小显示 |
||||
|
// 如果 field 无值时, 如果 field 获得焦点 label 就缩小显示, 否则 label 放大显示 |
||||
|
const stackLabelRef = ref(!Tools.isUndefinedOrNull(props.modelValue)); |
||||
|
|
||||
|
let editorView; |
||||
|
let isFocus = false; |
||||
|
|
||||
|
onMounted(() => { |
||||
|
if (codemirrorRef.value) { |
||||
|
let language = new Compartment(); |
||||
|
let tabSize = new Compartment(); |
||||
|
editorView = new EditorView({ |
||||
|
extensions: [ |
||||
|
basicSetup, |
||||
|
language.of(getLanguage(props.lang)), |
||||
|
tabSize.of(EditorState.tabSize.of(props.tabSize)), |
||||
|
EditorView.theme({ |
||||
|
'&': { |
||||
|
outline: 'none !important', |
||||
|
width: Tools.px(props.width), |
||||
|
height: props.height ? Tools.px(props.height) : props.rows * 22 + 'px', |
||||
|
}, |
||||
|
}), |
||||
|
// 以下代码可以添加内容变化后的操作, 为避免重复操作, 更新操作放到 blur 方法中了 |
||||
|
EditorView.updateListener.of(function (e) { |
||||
|
emits('update:modelValue', e.state.doc.toString()); |
||||
|
}), |
||||
|
], |
||||
|
parent: codemirrorRef.value, |
||||
|
doc: props.modelValue, |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
onUnmounted(() => { |
||||
|
editorView.destroy(); |
||||
|
}); |
||||
|
|
||||
|
onUpdated(() => { |
||||
|
if (!isFocus) { |
||||
|
// 当未获得焦点时,更新变更, 当获得焦点时不能更新 |
||||
|
editorView.dispatch({ changes: { from: 0, to: editorView.state.doc.length, insert: props.modelValue } }); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
const focus = () => { |
||||
|
isFocus = true; |
||||
|
stackLabelRef.value = true; |
||||
|
}; |
||||
|
|
||||
|
const blur = () => { |
||||
|
isFocus = false; |
||||
|
const content = editorView.state.doc.toString(); |
||||
|
//emits('update:modelValue', content); |
||||
|
if (content) { |
||||
|
stackLabelRef.value = true; |
||||
|
} else { |
||||
|
stackLabelRef.value = false; |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
const getValue = () => { |
||||
|
return editorView.state.doc.toString(); |
||||
|
}; |
||||
|
|
||||
|
const setValue = (value: string) => { |
||||
|
editorView.dispatch({ changes: { from: 0, to: editorView.state.doc.length, insert: value } }); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
getValue, |
||||
|
setValue, |
||||
|
}); |
||||
|
</script> |
@ -1,72 +0,0 @@ |
|||||
import { |
|
||||
EditorView, |
|
||||
lineNumbers, |
|
||||
highlightActiveLineGutter, |
|
||||
highlightSpecialChars, |
|
||||
drawSelection, |
|
||||
dropCursor, |
|
||||
rectangularSelection, |
|
||||
crosshairCursor, |
|
||||
highlightActiveLine, |
|
||||
keymap, |
|
||||
} from '@codemirror/view'; |
|
||||
import { EditorState } from '@codemirror/state'; |
|
||||
import { foldGutter, indentOnInput, syntaxHighlighting, defaultHighlightStyle, bracketMatching, foldKeymap } from '@codemirror/language'; |
|
||||
import { history, defaultKeymap, historyKeymap } from '@codemirror/commands'; |
|
||||
import { highlightSelectionMatches, searchKeymap } from '@codemirror/search'; |
|
||||
import { closeBrackets, autocompletion, closeBracketsKeymap, completionKeymap } from '@codemirror/autocomplete'; |
|
||||
import { lintKeymap } from '@codemirror/lint'; |
|
||||
|
|
||||
import { html } from '@codemirror/lang-html'; |
|
||||
import { java } from '@codemirror/lang-java'; |
|
||||
import { javascript } from '@codemirror/lang-javascript'; |
|
||||
import { json } from '@codemirror/lang-json'; |
|
||||
import { sql } from '@codemirror/lang-sql'; |
|
||||
import { xml } from '@codemirror/lang-xml'; |
|
||||
|
|
||||
export const basicSetup = [ |
|
||||
//lineNumbers(),
|
|
||||
highlightActiveLineGutter(), |
|
||||
highlightSpecialChars(), |
|
||||
history(), |
|
||||
//foldGutter(),
|
|
||||
drawSelection(), |
|
||||
dropCursor(), |
|
||||
EditorState.allowMultipleSelections.of(true), |
|
||||
indentOnInput(), |
|
||||
syntaxHighlighting(defaultHighlightStyle, { fallback: true }), |
|
||||
bracketMatching(), |
|
||||
closeBrackets(), |
|
||||
autocompletion(), |
|
||||
rectangularSelection(), |
|
||||
crosshairCursor(), |
|
||||
//highlightActiveLine(),
|
|
||||
highlightSelectionMatches(), |
|
||||
keymap.of([...closeBracketsKeymap, ...defaultKeymap, ...searchKeymap, ...historyKeymap, ...foldKeymap, ...completionKeymap, ...lintKeymap]), |
|
||||
]; |
|
||||
|
|
||||
export const basicTheme = () => { |
|
||||
return EditorView.theme({ |
|
||||
'.cm-editor': { |
|
||||
outline: 'none !important', |
|
||||
}, |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
export const getLanguage = (lang: string) => { |
|
||||
if (lang === 'html') { |
|
||||
return html(); |
|
||||
} else if (lang === 'java') { |
|
||||
return java(); |
|
||||
} else if (lang === 'javascript') { |
|
||||
return javascript(); |
|
||||
} else if (lang === 'json') { |
|
||||
return json(); |
|
||||
} else if (lang === 'sql') { |
|
||||
return sql(); |
|
||||
} else if (lang === 'xml') { |
|
||||
return xml(); |
|
||||
} else { |
|
||||
return json(); |
|
||||
} |
|
||||
}; |
|
@ -1,38 +0,0 @@ |
|||||
<template> |
|
||||
<q-field :v-bind="attrs"> |
|
||||
<template #control> |
|
||||
<div ref="codemirrorRef" class="border border-red-500" style="padding-top: 1px"></div> |
|
||||
</template> |
|
||||
</q-field> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref, useAttrs, onMounted, onUnmounted } from 'vue'; |
|
||||
import { EditorView } from '@codemirror/view'; |
|
||||
import { basicSetup, basicTheme, getLanguage } from './Util'; |
|
||||
|
|
||||
const attrs = useAttrs(); |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
lang: { type: String, default: 'json' }, |
|
||||
}); |
|
||||
|
|
||||
const codemirrorRef = ref(); |
|
||||
let view; |
|
||||
|
|
||||
onMounted(() => { |
|
||||
view = new EditorView({ |
|
||||
extensions: [basicSetup, getLanguage(props.lang), basicTheme()], |
|
||||
parent: codemirrorRef.value, |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
onUnmounted(() => { |
|
||||
view.destroy(); |
|
||||
}); |
|
||||
const value = ref('<xml><a name="name"></a></xml>'); |
|
||||
</script> |
|
||||
<style> |
|
||||
.cm-editor { |
|
||||
outline: none !important; |
|
||||
} |
|
||||
</style> |
|
@ -1,31 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<CodeMirror basic :lang="language" class="overflow-y-auto" v-bind="attrs"></CodeMirror> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { useAttrs, ref, onMounted } from 'vue'; |
|
||||
import CodeMirror from 'vue-codemirror6'; |
|
||||
import { java } from '@codemirror/lang-java'; |
|
||||
import { json } from '@codemirror/lang-json'; |
|
||||
import { sql } from '@codemirror/lang-sql'; |
|
||||
import { xml } from '@codemirror/lang-xml'; |
|
||||
|
|
||||
const attrs = useAttrs(); |
|
||||
const props = defineProps({ |
|
||||
lang: { type: String, default: 'json' }, |
|
||||
}); |
|
||||
|
|
||||
let language = json(); |
|
||||
if (props.lang === 'java') { |
|
||||
language = java(); |
|
||||
} else if (props.lang === 'json') { |
|
||||
language = json(); |
|
||||
} else if (props.lang === 'sql') { |
|
||||
language = sql(); |
|
||||
} else if (props.lang === 'xml') { |
|
||||
language = xml(); |
|
||||
} |
|
||||
|
|
||||
console.log(props.lang); |
|
||||
</script> |
|
@ -1,7 +0,0 @@ |
|||||
<template> |
|
||||
<q-select outlined emit-value map-options v-bind="attrs" /> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { useAttrs } from 'vue'; |
|
||||
const attrs = useAttrs(); |
|
||||
</script> |
|
@ -1,50 +0,0 @@ |
|||||
<template> |
|
||||
<!-- <w-codemirror |
|
||||
v-model="value" |
|
||||
lang="xml" |
|
||||
placeholder="Code goes here..." |
|
||||
:autofocus="false" |
|
||||
:tab-size="2" |
|
||||
:style="{ height: '200px', padding: '20px' }" |
|
||||
></w-codemirror> --> |
|
||||
<q-input outlined label="OK"></q-input> |
|
||||
<label class="q-field row no-wrap items-start q-field--outlined q-input q-field--labeled" for="f_eef31e6a-a3a8-4a87-b35c-481f40af889e"> |
|
||||
<div class="q-field__inner relative-position col self-stretch"> |
|
||||
<div class="q-field__control relative-position row no-wrap" tabindex="-1"> |
|
||||
<div class="q-field__control-container col relative-position row no-wrap q-anchor--skip"></div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</label> |
|
||||
|
|
||||
<div class="rounded-md" style="border: 1px solid #e5e7eb"> |
|
||||
<div class="px-3 text-gray-600 text-xs">OK</div> |
|
||||
<div ref="codemirrorRef" class="py-1"></div> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref, onMounted, onUnmounted } from 'vue'; |
|
||||
import { EditorView, basicSetup } from 'codemirror'; |
|
||||
import { javascript } from '@codemirror/lang-javascript'; |
|
||||
|
|
||||
const codemirrorRef = ref(); |
|
||||
let view; |
|
||||
|
|
||||
onMounted(() => { |
|
||||
view = new EditorView({ |
|
||||
extensions: [basicSetup, javascript()], |
|
||||
parent: codemirrorRef.value, |
|
||||
}); |
|
||||
//view.destroy(); |
|
||||
}); |
|
||||
|
|
||||
onUnmounted(() => { |
|
||||
console.log('>>>>>>'); |
|
||||
view.destroy(); |
|
||||
}); |
|
||||
const value = ref('<xml><a name="name"></a></xml>'); |
|
||||
</script> |
|
||||
<style> |
|
||||
.cm-editor2 { |
|
||||
outline: none !important; |
|
||||
} |
|
||||
</style> |
|
@ -1,29 +0,0 @@ |
|||||
<template> |
|
||||
<q-splitter v-model="splitWidthRef" style="height: 250px"> |
|
||||
<template #before> |
|
||||
<q-tabs v-model="selectedTab" vertical no-caps> |
|
||||
<q-tab name="cron" label="w-cron" /> |
|
||||
<q-tab name="codemirror" label="w-code-mirror" /> |
|
||||
</q-tabs> |
|
||||
</template> |
|
||||
|
|
||||
<template #after> |
|
||||
<q-tab-panels v-model="selectedTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up"> |
|
||||
<q-tab-panel name="cron"> |
|
||||
<w-cron v-model="valueRef" label="cron" outlined dense style="width: 200px"></w-cron> |
|
||||
</q-tab-panel> |
|
||||
<q-tab-panel name="codemirror"> |
|
||||
<w-code-mirror v-model="valueRef" label="codemirror" lang="sql" outlined dense></w-code-mirror> |
|
||||
<q-input v-model="valueRef" label="codemirror" outlined dense></q-input> |
|
||||
</q-tab-panel> |
|
||||
</q-tab-panels> |
|
||||
</template> |
|
||||
</q-splitter> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
|
|
||||
const selectedTab = ref('codemirror'); |
|
||||
const splitWidthRef = ref(20); |
|
||||
const valueRef = ref('* * * * * *'); |
|
||||
</script> |
|
@ -1,37 +0,0 @@ |
|||||
<template> |
|
||||
<w-dialog |
|
||||
ref="dialogRef" |
|
||||
:persistent="true" |
|
||||
:maximized="true" |
|
||||
title="xxx" |
|
||||
width="50%" |
|
||||
height="50%" |
|
||||
:can-maximize="true" |
|
||||
:actions="[ |
|
||||
{ |
|
||||
icon: PlatformIconEnum.保存, |
|
||||
label: '保存', |
|
||||
loading: false, |
|
||||
click: async () => {}, |
|
||||
}, |
|
||||
]" |
|
||||
@maximize="dialogMaximize" |
|
||||
></w-dialog> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref, reactive, onMounted } from 'vue'; |
|
||||
import { PlatformIconEnum, DialogManager } from '@/platform'; |
|
||||
|
|
||||
const dialogRef = ref(); |
|
||||
|
|
||||
const dialogMaximize = (maximizedToggle: boolean) => { |
|
||||
console.log(maximizedToggle); |
|
||||
}; |
|
||||
|
|
||||
onMounted(() => { |
|
||||
//dialogRef.value.show(); |
|
||||
DialogManager.confirm('kdjflksjdf', () => { |
|
||||
console.log('ok'); |
|
||||
}); |
|
||||
}); |
|
||||
</script> |
|
@ -1,30 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<w-form :fields="fields" :cols-num-auto="false" :cols-num="3"></w-form> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
const fields = [ |
|
||||
{ |
|
||||
label: '姓名', |
|
||||
name: 'name', |
|
||||
type: 'text', |
|
||||
required: true, |
|
||||
colspan: 2, |
|
||||
button: { |
|
||||
round: false, |
|
||||
icon: 'home', |
|
||||
label: '选择', |
|
||||
click: () => { |
|
||||
console.info('11111'); |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
label: '年龄', |
|
||||
name: 'age', |
|
||||
type: 'number', |
|
||||
required: true, |
|
||||
}, |
|
||||
]; |
|
||||
</script> |
|
@ -0,0 +1,44 @@ |
|||||
|
<template> |
||||
|
<q-splitter v-model="splitWidthRef"> |
||||
|
<template #before> |
||||
|
<q-tabs v-model="selectedTab" vertical no-caps> |
||||
|
<q-tab name="formElements" label="Form Elements" /> |
||||
|
<q-tab name="codemirror" label="w-code-mirror" /> |
||||
|
</q-tabs> |
||||
|
</template> |
||||
|
|
||||
|
<template #after> |
||||
|
<q-tab-panels v-model="selectedTab" animated swipeable vertical transition-prev="jump-up" transition-next="jump-up"> |
||||
|
<q-tab-panel name="formElements"> |
||||
|
<w-form |
||||
|
:cols-num="1" |
||||
|
:fields="[ |
||||
|
{ name: 'color', label: 'please select color', type: 'color-input', outlined: true, dense: true }, |
||||
|
{ name: 'colorPalette', label: 'please select color palette', type: 'color-input-palette', outlined: true, dense: true }, |
||||
|
{ name: 'codemirror', label: 'please input SQL', type: 'code-mirror', outlined: true, lang: 'sql', dense: true, rows: 5 }, |
||||
|
{ name: 'cron', label: 'please input cron expression', type: 'cron', outlined: true, dense: true }, |
||||
|
{ name: 'position', label: 'please select position', type: 'position', outlined: true, dense: true }, |
||||
|
]" |
||||
|
> |
||||
|
</w-form> |
||||
|
</q-tab-panel> |
||||
|
<q-tab-panel name="codemirror"> |
||||
|
<q-input v-model="valueRef" label="please input number 1:" outlined dense clearable></q-input> |
||||
|
<w-code-mirror v-model="valueRef" label="please input SQL:" lang="sql" outlined dense></w-code-mirror> |
||||
|
<q-input v-model="valueRef" label="please input number 2:" outlined dense clearable></q-input> |
||||
|
</q-tab-panel> |
||||
|
</q-tab-panels> |
||||
|
</template> |
||||
|
</q-splitter> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
|
||||
|
const selectedTab = ref('formElements'); |
||||
|
const splitWidthRef = ref(20); |
||||
|
const valueRef = ref('xxxx'); |
||||
|
|
||||
|
const focus = () => { |
||||
|
console.log('sfsdf'); |
||||
|
}; |
||||
|
</script> |
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>2222</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,22 +0,0 @@ |
|||||
<template> |
|
||||
<w-select v-model="model" :options="options" label="Status" @update:model-value="valueChanged" /> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { useI18n } from 'vue-i18n'; |
|
||||
import { EnumTools } from '@/platform'; |
|
||||
import { QBtn } from 'quasar'; |
|
||||
|
|
||||
const { t } = useI18n(); |
|
||||
const model = ref('value'); |
|
||||
const options = ref(); |
|
||||
|
|
||||
EnumTools.fetch('io.sc.platform.flowable.enums.ProcessStatus', t).then((data) => { |
|
||||
console.log(data.map); |
|
||||
options.value = data.map; |
|
||||
}); |
|
||||
|
|
||||
const valueChanged = (value) => { |
|
||||
console.log(value); |
|
||||
}; |
|
||||
</script> |
|
@ -1,64 +0,0 @@ |
|||||
<template> |
|
||||
<w-grid |
|
||||
:tree="true" |
|
||||
:title="$t('system.corporation.grid.title')" |
|
||||
:data-url="Environment.apiContextPath('/api/system/corporation')" |
|
||||
selection="multiple" |
|
||||
:checkbox-selection="false" |
|
||||
:pageable="false" |
|
||||
:full-screen-button="false" |
|
||||
:tree-icon=" |
|
||||
(row) => { |
|
||||
return { name: 'folder', color: 'amber' }; |
|
||||
} |
|
||||
" |
|
||||
:toolbar-configure="{ noIcon: false }" |
|
||||
:toolbar-actions="['refresh', 'separator', ['addTop', 'addChild'], 'edit', 'remove', 'separator', 'view']" |
|
||||
:columns="[ |
|
||||
{ width: '100%', name: 'name', label: $t('name') }, |
|
||||
{ width: 150, name: 'code', label: $t('code') }, |
|
||||
{ width: 90, name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
|
||||
{ width: 100, name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
|
||||
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() }, |
|
||||
]" |
|
||||
:editor="{ |
|
||||
dialog: { |
|
||||
width: '600px', |
|
||||
height: '300px', |
|
||||
}, |
|
||||
form: { |
|
||||
colsNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'code', label: $t('code'), type: 'text', required: true }, |
|
||||
{ name: 'name', label: $t('name'), type: 'text', required: true }, |
|
||||
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 }, |
|
||||
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'id', label: $t('id') }, |
|
||||
{ name: 'code', label: $t('code') }, |
|
||||
{ name: 'name', label: $t('name') }, |
|
||||
{ name: 'description', label: $t('description') }, |
|
||||
{ name: 'enable', label: $t('enable'), format: (value) => value }, |
|
||||
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: (value) => value }, |
|
||||
{ name: 'creator', label: $t('creator') }, |
|
||||
{ name: 'createDate', label: $t('createDate') }, |
|
||||
{ name: 'lastModifier', label: $t('lastModifier') }, |
|
||||
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: (value) => value }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
></w-grid> |
|
||||
</template> |
|
||||
|
|
||||
<script setup lang="ts"> |
|
||||
import { Environment,Formater,Options } from '@/platform'; |
|
||||
|
|
||||
|
|
||||
</script> |
|
@ -1,118 +0,0 @@ |
|||||
<template> |
|
||||
<div class="flex flex-nowrap py-2"> |
|
||||
<div ref="titleContainerRef" class="flex items-end text-subtitle2 text-no-wrap">{{ title }}</div> |
|
||||
<q-space /> |
|
||||
<div ref="actionContainerRef" class="flex flex-nowrap"> |
|
||||
<!-- baseActions --> |
|
||||
<template v-for="(action, index) in baseActions" :key="'baseAction_' + index"> |
|
||||
<q-separator |
|
||||
v-if="action.separator" |
|
||||
vertical |
|
||||
class="class-action-item" |
|
||||
:style="{ |
|
||||
'margin-left': '5px', |
|
||||
'margin-right': '5px', |
|
||||
}" |
|
||||
/> |
|
||||
<q-btn |
|
||||
v-else |
|
||||
v-bind="action" |
|
||||
:id="action.name" |
|
||||
:disable="action.enableIf ? !action.enableIf() : false" |
|
||||
no-wrap |
|
||||
class="class-action-item" |
|
||||
:style="{ |
|
||||
'margin-left': '5px', |
|
||||
'margin-right': '5px', |
|
||||
}" |
|
||||
@click="action.click" |
|
||||
/> |
|
||||
</template> |
|
||||
|
|
||||
<!-- moreActions --> |
|
||||
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" :label="$t('more')" class="class-action-item" style="margin-left: 5px"> |
|
||||
<q-list> |
|
||||
<template v-for="(action, index) in moreActions" :key="'moreAction_' + index"> |
|
||||
<q-separator v-if="action.separator" /> |
|
||||
<q-item v-else v-close-popup clickable @click="action.click"> |
|
||||
<q-item-section avatar style="min-width: 28px; padding-right: 0px"> |
|
||||
<q-icon :name="action.icon" size="20px" /> |
|
||||
</q-item-section> |
|
||||
<q-item-section> |
|
||||
<q-item-label :v-bind="action">{{ action.label }}</q-item-label> |
|
||||
</q-item-section> |
|
||||
</q-item> |
|
||||
</template> |
|
||||
</q-list> |
|
||||
</q-btn-dropdown> |
|
||||
</div> |
|
||||
<q-resize-observer @resize="onResize" /> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref } from 'vue'; |
|
||||
import { Tools } from '@/platform/utils'; |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
title: { type: String, default: '' }, |
|
||||
actions: { |
|
||||
type: Array, |
|
||||
default: () => { |
|
||||
return []; |
|
||||
}, |
|
||||
}, |
|
||||
}); |
|
||||
|
|
||||
const titleContainerRef = ref(); |
|
||||
const actionContainerRef = ref(); |
|
||||
|
|
||||
const actions = props.actions; |
|
||||
const baseActions = ref(actions); |
|
||||
const moreActions = ref([]); |
|
||||
const isActionWidthInitializedRef = ref(false); |
|
||||
const moreActionWidth = 100; |
|
||||
|
|
||||
const onResize = (size) => { |
|
||||
if (Tools.isUndefinedOrNull(titleContainerRef.value) || Tools.isUndefinedOrNull(actionContainerRef.value)) { |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (!isActionWidthInitializedRef.value) { |
|
||||
const nodes = actionContainerRef.value.getElementsByClassName('class-action-item'); |
|
||||
for (let i = 0; i < actions.length; i++) { |
|
||||
actions[i].width = nodes[i].clientWidth + 10; |
|
||||
} |
|
||||
isActionWidthInitializedRef.value = true; |
|
||||
} |
|
||||
|
|
||||
const _baseActions = []; |
|
||||
const _moreActions = []; |
|
||||
const length = actions.length; |
|
||||
let availableWidth = size.width - titleContainerRef.value.clientWidth; |
|
||||
let width = 0; |
|
||||
let index = 0; |
|
||||
|
|
||||
for (; index < length; index++) { |
|
||||
console.log(index, width + actions[index].width, availableWidth); |
|
||||
if (width + actions[index].width > availableWidth) { |
|
||||
availableWidth -= moreActionWidth; |
|
||||
while (width > availableWidth) { |
|
||||
index--; |
|
||||
width -= actions[index].width; |
|
||||
_baseActions.pop(); |
|
||||
} |
|
||||
break; |
|
||||
} else { |
|
||||
_baseActions.push(actions[index]); |
|
||||
width += actions[index].width; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
for (; index < length; index++) { |
|
||||
_moreActions.push(actions[index]); |
|
||||
} |
|
||||
|
|
||||
baseActions.value = _baseActions; |
|
||||
moreActions.value = _moreActions; |
|
||||
}; |
|
||||
</script> |
|
@ -1,236 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<div v-if="executeProgress.show" class="row pt-2"> |
|
||||
<div class="col-2 pl-4">{{ $t('io.sc.engine.mv.result.task.progress') }}</div> |
|
||||
<div class="col-3"> |
|
||||
<q-linear-progress size="20px" :value="executeProgress.percentage" color="primary" rounded> </q-linear-progress> |
|
||||
</div> |
|
||||
<div class="col-7 pl-4">{{ executeProgress.message }}</div> |
|
||||
<div class="col-1"></div> |
|
||||
</div> |
|
||||
<w-grid |
|
||||
ref="gridRef" |
|
||||
:title="$t('menu.engine.mv.result')" |
|
||||
:config-button="true" |
|
||||
selection="multiple" |
|
||||
:checkbox-selection="false" |
|
||||
:data-url="Environment.apiContextPath('/api/mv/viewer/result')" |
|
||||
:pageable="true" |
|
||||
:pagination="{ |
|
||||
sortBy: 'validateDate', |
|
||||
descending: true, |
|
||||
}" |
|
||||
:toolbar-configure="{ noIcon: false }" |
|
||||
:toolbar-actions="[ |
|
||||
'refresh', |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'execute', |
|
||||
label: $t('io.sc.engine.mv.result.grid.toolbar.execute'), |
|
||||
icon: 'bi-play-circle', |
|
||||
click: () => { |
|
||||
executorDialogRef.open(); |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
{ |
|
||||
name: 'detail', |
|
||||
label: $t('detail'), |
|
||||
icon: 'bi-display', |
|
||||
enableIf: (selecteds) => { |
|
||||
return selecteds && selecteds.length > 0; |
|
||||
}, |
|
||||
click: (selecteds) => { |
|
||||
if (selecteds && selecteds.length > 0) { |
|
||||
const selected = selecteds[0]; |
|
||||
resultDetailDialogRef.open(selected); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
extend: 'remove', |
|
||||
click: (selecteds) => { |
|
||||
if (selecteds && selecteds.length > 0) { |
|
||||
const selected = selecteds[0]; |
|
||||
axios |
|
||||
.request({ |
|
||||
url: Environment.apiContextPath('/api/mv/viewer/result'), |
|
||||
method: 'delete', |
|
||||
data: [{ validateDate: selected.validateDate, modelId: selected.modelId }], |
|
||||
}) |
|
||||
.then(() => { |
|
||||
gridRef.refresh(); |
|
||||
}); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
'separator', |
|
||||
'view', |
|
||||
'separator', |
|
||||
'export', |
|
||||
]" |
|
||||
:columns="[ |
|
||||
{ width: 150, name: 'validateDate', label: $t('io.sc.engine.mv.result.grid.entity.validateDate') }, |
|
||||
{ width: 150, name: 'modelId', label: $t('io.sc.engine.mv.result.grid.entity.modelId') }, |
|
||||
{ width: 200, name: 'modelName', label: $t('io.sc.engine.mv.result.grid.entity.modelName') }, |
|
||||
{ width: 100, name: 'executeMode', label: $t('io.sc.engine.mv.result.grid.entity.executeMode') }, |
|
||||
{ width: 100, name: 'totalSampleCount', label: $t('io.sc.engine.mv.result.grid.entity.totalSampleCount'), align: 'right' }, |
|
||||
{ width: 100, name: 'defaultSampleCount', label: $t('io.sc.engine.mv.result.grid.entity.defaultSampleCount'), align: 'right' }, |
|
||||
{ |
|
||||
width: 900, |
|
||||
name: 'discrimination', |
|
||||
label: $t('io.sc.engine.mv.result.grid.entity.discrimination'), |
|
||||
columns: [ |
|
||||
{ |
|
||||
name: 'total', |
|
||||
label: $t('io.sc.engine.mv.result.grid.entity.total'), |
|
||||
columns: [ |
|
||||
{ width: 100, name: 'auc', label: $t('io.sc.engine.mv.result.grid.entity.auc') }, |
|
||||
{ width: 100, name: 'ar', label: $t('io.sc.engine.mv.result.grid.entity.ar') }, |
|
||||
{ width: 100, name: 'ks', label: $t('io.sc.engine.mv.result.grid.entity.ks') }, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
name: 'quantitative', |
|
||||
label: $t('quantitative'), |
|
||||
columns: [ |
|
||||
{ width: 100, name: 'aucQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.auc') }, |
|
||||
{ width: 100, name: 'arQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.ar') }, |
|
||||
{ width: 100, name: 'ksQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.ks') }, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
name: 'qualitative', |
|
||||
label: $t('qualitative'), |
|
||||
columns: [ |
|
||||
{ width: 100, name: 'aucQualitative', label: $t('io.sc.engine.mv.result.grid.entity.auc') }, |
|
||||
{ width: 100, name: 'arQualitative', label: $t('io.sc.engine.mv.result.grid.entity.ar') }, |
|
||||
{ width: 100, name: 'ksQualitative', label: $t('io.sc.engine.mv.result.grid.entity.ks') }, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
width: 200, |
|
||||
name: 'stability', |
|
||||
label: $t('io.sc.engine.mv.result.grid.entity.stability'), |
|
||||
columns: [ |
|
||||
{ width: 100, name: 'svd', label: $t('io.sc.engine.mv.result.grid.entity.svd') }, |
|
||||
{ width: 100, name: 'psi', label: $t('io.sc.engine.mv.result.grid.entity.psi') }, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
width: 200, |
|
||||
name: 'scaleValidate', |
|
||||
label: $t('io.sc.engine.mv.result.grid.entity.scaleValidate'), |
|
||||
columns: [ |
|
||||
{ width: 100, name: 'chiSquare', label: $t('io.sc.engine.mv.result.grid.entity.chiSquare'), align: 'center', format: passOrNotFormater }, |
|
||||
{ width: 100, name: 'binomial', label: $t('io.sc.engine.mv.result.grid.entity.binomial'), align: 'center', format: passOrNotFormater }, |
|
||||
], |
|
||||
}, |
|
||||
]" |
|
||||
:viewer="{ |
|
||||
panel: { |
|
||||
columnNum: 1, |
|
||||
fields: [ |
|
||||
{ name: 'validateDate', label: $t('io.sc.engine.mv.result.grid.entity.validateDate') }, |
|
||||
{ |
|
||||
name: 'runtimeParameters', |
|
||||
label: $t('io.sc.engine.mv.result.grid.entity.runtimeParameters'), |
|
||||
format: (value) => { |
|
||||
let result = ''; |
|
||||
for (const item of value) { |
|
||||
result += |
|
||||
$t('io.sc.engine.mv.result.grid.entity.runtimeParameters.' + item.name) + |
|
||||
':' + |
|
||||
(Tools.isUndefinedOrNull(item.value) ? '' : item.value) + |
|
||||
'<br/>'; |
|
||||
} |
|
||||
return result; |
|
||||
}, |
|
||||
}, |
|
||||
{ name: 'modelId', label: $t('io.sc.engine.mv.result.grid.entity.modelId') }, |
|
||||
{ name: 'modelName', label: $t('io.sc.engine.mv.result.grid.entity.modelName') }, |
|
||||
{ name: 'executeMode', label: $t('io.sc.engine.mv.result.grid.entity.executeMode') }, |
|
||||
{ name: 'totalSampleCount', label: $t('io.sc.engine.mv.result.grid.entity.totalSampleCount') }, |
|
||||
{ name: 'defaultSampleCount', label: $t('io.sc.engine.mv.result.grid.entity.defaultSampleCount') }, |
|
||||
{ name: 'auc', label: $t('io.sc.engine.mv.result.grid.entity.total.auc') }, |
|
||||
{ name: 'ar', label: $t('io.sc.engine.mv.result.grid.entity.total.ar') }, |
|
||||
{ name: 'ks', label: $t('io.sc.engine.mv.result.grid.entity.total.ks') }, |
|
||||
{ name: 'aucQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.quantitative.auc') }, |
|
||||
{ name: 'arQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.quantitative.ar') }, |
|
||||
{ name: 'ksQuantitative', label: $t('io.sc.engine.mv.result.grid.entity.quantitative.ks') }, |
|
||||
{ name: 'aucQualitative', label: $t('io.sc.engine.mv.result.grid.entity.qualitative.auc') }, |
|
||||
{ name: 'arQualitative', label: $t('io.sc.engine.mv.result.grid.entity.qualitative.ar') }, |
|
||||
{ name: 'ksQualitative', label: $t('io.sc.engine.mv.result.grid.entity.qualitative.ks') }, |
|
||||
{ name: 'svd', label: $t('io.sc.engine.mv.result.grid.entity.svd') }, |
|
||||
{ name: 'psi', label: $t('io.sc.engine.mv.result.grid.entity.psi') }, |
|
||||
{ name: 'chiSquare', label: $t('io.sc.engine.mv.result.grid.entity.chiSquare'), format: Formater.none() }, |
|
||||
{ name: 'binomial', label: $t('io.sc.engine.mv.result.grid.entity.binomial'), format: Formater.none() }, |
|
||||
], |
|
||||
}, |
|
||||
}" |
|
||||
></w-grid> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { ref, reactive } from 'vue'; |
|
||||
import { axios, Environment, Tools, Formater, NotifyManager } from '@/platform'; |
|
||||
|
|
||||
const gridRef = ref(); |
|
||||
const resultDetailDialogRef = ref(); |
|
||||
const executorDialogRef = ref(); |
|
||||
const executeProgress = reactive({ |
|
||||
show: false, |
|
||||
percentage: 0, |
|
||||
message: '', |
|
||||
}); |
|
||||
let executeProgressInterval; |
|
||||
|
|
||||
const passOrNotFormater = (value) => { |
|
||||
if (Tools.isUndefinedOrNull(value)) { |
|
||||
return ''; |
|
||||
} |
|
||||
if (value === 'PASS') { |
|
||||
return { |
|
||||
componentType: 'QIcon', |
|
||||
attrs: { name: 'bi-check-circle', size: '20px', color: 'green' }, |
|
||||
}; |
|
||||
} else { |
|
||||
return { |
|
||||
componentType: 'QIcon', |
|
||||
attrs: { name: 'bi-x-circle', size: '20px', color: 'red' }, |
|
||||
}; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
const afterStartExecute = () => { |
|
||||
executeProgress.show = true; |
|
||||
executeProgress.percentage = 0; |
|
||||
executeProgressInterval = setInterval(() => { |
|
||||
axios |
|
||||
.get(Environment.apiContextPath('/api/mv/traceExecuteProgress')) |
|
||||
.then((response) => { |
|
||||
const progressInfo = response.data; |
|
||||
executeProgress.percentage = progressInfo.currentWeight / progressInfo.totalWeight; |
|
||||
executeProgress.message = progressInfo.messageKey; |
|
||||
if (executeProgress.percentage >= 1) { |
|
||||
clearInterval(executeProgressInterval); |
|
||||
executeProgress.show = false; |
|
||||
gridRef.value.refresh(); |
|
||||
} |
|
||||
}) |
|
||||
.catch(() => { |
|
||||
clearInterval(executeProgressInterval); |
|
||||
executeProgress.show = false; |
|
||||
gridRef.value.refresh(); |
|
||||
}); |
|
||||
}, 1000); |
|
||||
}; |
|
||||
|
|
||||
axios.get(Environment.apiContextPath('/api/mv/isExistsRunningExecutor')).then((response) => { |
|
||||
if (response.data) { |
|
||||
afterStartExecute(); |
|
||||
} |
|
||||
}); |
|
||||
</script> |
|
Loading…
Reference in new issue