Files
mayfly-go/frontend/src/views/ops/db/component/table/ColumnFormItem.vue

262 lines
6.6 KiB
Vue
Raw Normal View History

<template>
2024-05-10 19:59:49 +08:00
<div class="string-input-container w100" v-if="dataType == DataType.String || dataType == DataType.Number">
<el-input
2024-12-08 13:04:23 +08:00
:ref="
(el: any) => {
nextTick(() => {
focus && el?.focus();
});
}
"
:disabled="disabled"
2023-12-22 17:04:06 +08:00
@blur="handleBlur"
:class="`w100 mb4 ${showEditorIcon ? 'string-input-container-show-icon' : ''}`"
size="small"
v-model="itemValue"
2024-12-08 13:04:23 +08:00
:placeholder="placeholder ?? $t('common.pleaseInput')"
/>
2023-12-22 17:04:06 +08:00
<SvgIcon v-if="showEditorIcon" @mousedown="openEditor" class="string-input-container-icon" name="FullScreen" :size="10" />
</div>
<el-date-picker
v-else-if="dataType == DataType.Date"
2024-12-08 13:04:23 +08:00
:ref="
(el: any) => {
nextTick(() => {
focus && el?.focus();
});
}
"
:disabled="disabled"
2024-12-08 13:04:23 +08:00
@change="handleBlur"
2023-12-22 17:04:06 +08:00
@blur="handleBlur"
class="edit-time-picker mb4"
popper-class="edit-time-picker-popper"
size="small"
v-model="itemValue"
:clearable="false"
2024-12-08 13:04:23 +08:00
type="date"
value-format="YYYY-MM-DD"
2024-12-08 13:04:23 +08:00
:placeholder="`date-${placeholder ?? $t('common.pleaseSelect')}`"
/>
<el-date-picker
v-else-if="dataType == DataType.DateTime"
2024-12-08 13:04:23 +08:00
:ref="
(el: any) => {
nextTick(() => {
focus && el?.focus();
});
}
"
:disabled="disabled"
2023-12-22 17:04:06 +08:00
@change="handleBlur"
@blur="handleBlur"
class="edit-time-picker mb4"
popper-class="edit-time-picker-popper"
size="small"
v-model="itemValue"
:clearable="false"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
2024-12-08 13:04:23 +08:00
:placeholder="`datetime-${placeholder ?? $t('common.pleaseSelect')}`"
/>
<el-time-picker
v-else-if="dataType == DataType.Time"
2024-12-08 13:04:23 +08:00
:ref="
(el: any) => {
nextTick(() => {
focus && el?.focus();
});
}
"
:disabled="disabled"
2023-12-22 17:04:06 +08:00
@change="handleBlur"
@blur="handleBlur"
class="edit-time-picker mb4"
popper-class="edit-time-picker-popper"
size="small"
v-model="itemValue"
:clearable="false"
value-format="HH:mm:ss"
2024-12-08 13:04:23 +08:00
:placeholder="`time-${placeholder ?? $t('common.pleaseSelect')}`"
/>
</template>
<script lang="ts" setup>
2024-12-08 13:04:23 +08:00
import { computed, nextTick, ref, Ref } from 'vue';
2024-05-10 19:59:49 +08:00
import { ElInput, ElMessage } from 'element-plus';
import { DataType } from '../../dialect/index';
import SvgIcon from '@/components/svgIcon/index.vue';
import MonacoEditorDialog from '@/components/monaco/MonacoEditorDialog';
2024-11-20 22:43:53 +08:00
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
export interface ColumnFormItemProps {
modelValue: string | number; // 绑定的值
dataType: DataType; // 数据类型
focus?: boolean; // 是否获取焦点
placeholder?: string;
columnName?: string;
disabled?: boolean;
}
const props = withDefaults(defineProps<ColumnFormItemProps>(), {
focus: false,
dataType: DataType.String,
disabled: false,
});
const emit = defineEmits(['update:modelValue', 'blur']);
2023-12-22 17:04:06 +08:00
const itemValue: Ref<any> = ref(props.modelValue);
const showEditorIcon = computed(() => {
return typeof itemValue.value === 'string' && itemValue.value.length > 50;
});
const editorOpening = ref(false);
const openEditor = () => {
editorOpening.value = true;
// 编辑器语言json、html、text
let editorLang = getEditorLangByValue(itemValue.value);
MonacoEditorDialog({
content: itemValue.value,
2024-11-20 22:43:53 +08:00
title: `${t('db.editField')} [${props.columnName}]`,
language: editorLang,
confirmFn: (newVal: any) => {
itemValue.value = newVal;
closeEditorDialog();
},
cancelFn: closeEditorDialog,
});
};
const closeEditorDialog = () => {
editorOpening.value = false;
2023-12-22 17:04:06 +08:00
handleBlur();
};
2023-12-22 17:04:06 +08:00
const handleBlur = () => {
if (editorOpening.value) {
return;
}
if (props.dataType == DataType.Number && itemValue.value && !/^-?\d*\.?\d+$/.test(itemValue.value)) {
2024-11-20 22:43:53 +08:00
ElMessage.error(t('db.valueTypeNoMatch'));
2024-05-10 19:59:49 +08:00
return;
}
2023-12-22 17:04:06 +08:00
emit('update:modelValue', itemValue.value);
emit('blur');
};
const getEditorLangByValue = (value: any) => {
// 判断是否是json
try {
if (typeof JSON.parse(value) === 'object') {
return 'json';
}
} catch (e) {
/* empty */
}
// 判断是否是html
try {
const doc = new DOMParser().parseFromString(value, 'text/html');
if (Array.from(doc.body.childNodes).some((node) => node.nodeType === 1)) {
return 'html';
}
} catch (e) {
/* empty */
}
return 'text';
};
</script>
<style lang="scss">
.string-input-container {
position: relative;
.el-input__wrapper {
padding: 1px 3px;
}
}
2023-12-22 17:04:06 +08:00
.string-input-container-show-icon {
.el-input__inner {
padding-right: 10px;
}
}
.string-input-container-icon {
position: absolute;
top: 5px; /* 调整图标的垂直位置 */
2023-12-22 17:04:06 +08:00
right: 3px; /* 调整图标的水平位置 */
color: var(--el-color-primary);
}
.string-input-container-icon:hover {
color: var(--el-color-success);
}
.edit-time-picker {
height: 26px;
width: 100% !important;
.el-input__prefix {
display: none;
}
.el-input__wrapper {
padding: 1px 3px;
}
}
.edit-time-picker-popper {
.el-date-picker {
width: 250px !important;
.el-date-picker__header {
margin: 0 5px;
}
.el-picker-panel__content {
width: unset;
margin: 0 5px;
}
.el-date-picker__header-label {
font-size: 13px;
}
.el-picker-panel__footer {
padding: 0 5px;
button {
font-size: 11px;
padding: 5px 6px;
height: 20px;
}
}
}
.el-date-table {
th {
font-size: 10px;
font-weight: 600;
padding: 0;
}
td {
padding: 0;
}
}
.el-time-panel {
width: 100px;
.el-time-spinner__list {
&::after,
&::before {
height: 10px;
}
.el-time-spinner__item {
height: 20px;
line-height: 20px;
}
}
}
}
</style>