blob: af941aced037655da563aff20a3506940fc3bc04 [file] [log] [blame]
<!--
~ Licensed to 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. Apache Software Foundation (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.
-->
<script lang="ts" setup>
import { reactive } from '@vue/reactivity';
import type { FormInstance } from 'element-plus';
import { ref } from 'vue';
const ruleFormRef = ref<FormInstance>();
const data = reactive({
tableData: [],
dialogVisible: false,
form: {
name: '',
fieldType: '',
encodingMethod: '',
compressionMethod: '',
},
fieldOperator: 'Add',
fieldEditIndex: -1,
});
const typeOptions = [
{
value: 'FIELD_TYPE_STRING',
label: 'STRING',
},
{
value: 'FIELD_TYPE_INT',
label: 'INT',
},
{
value: 'FIELD_TYPE_DATA_BINARY',
label: 'DATA_BINARY',
},
{
value: 'FIELD_TYPE_FLOAT',
label: 'FLOAT',
},
];
const encodingMethodOptions = [
{
value: 'ENCODING_METHOD_GORILLA',
label: 'GORILLA',
},
];
const compressionMethodOptions = [
{
value: 'COMPRESSION_METHOD_ZSTD',
label: 'ZSTD',
},
];
const validateName = (rule: any, value: any, callback: any) => {
if (value === '') {
callback(new Error('Please input the field name.'));
} else {
const index = data.tableData.findIndex((item) => {
return item.name === value;
});
if (index >= 0) {
if (data.fieldOperator === 'Edit' && data.fieldEditIndex === index) {
return callback();
}
return callback(new Error('The name is exists'));
}
callback();
}
};
const rules = {
name: [
{
required: true,
validator: validateName,
trigger: 'blur',
},
],
fieldType: [
{
required: true,
message: 'Please select the field type',
trigger: 'blur',
},
],
encodingMethod: [
{
required: true,
message: 'Please select the encoding method',
trigger: 'blur',
},
],
compressionMethod: [
{
required: true,
message: 'Please select the compression method',
trigger: 'blur',
},
],
};
const confirmForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (valid) {
if (data.fieldOperator === 'Add') {
data.tableData.push(data.form);
initForm();
} else {
data.tableData[data.fieldEditIndex] = data.form;
initForm();
}
data.dialogVisible = false;
}
});
};
function initForm() {
data.form = {
name: '',
fieldType: '',
encodingMethod: '',
compressionMethod: '',
};
}
function openAddField() {
data.fieldOperator = 'Add';
data.dialogVisible = true;
}
function openEditField(index) {
data.form = JSON.parse(JSON.stringify(data.tableData[index]));
data.fieldEditIndex = index;
data.fieldOperator = 'Edit';
data.dialogVisible = true;
}
function deleteTableData(index) {
data.tableData.splice(index, 1);
}
function getFields() {
return data.tableData;
}
function setFields(value) {
data.tableData = value;
}
defineExpose({
getFields,
setFields,
});
</script>
<template>
<el-button size="small" type="primary" color="#6E38F7" style="margin-top: 20px" @click="openAddField"
>Add Field</el-button
>
<el-table :data="data.tableData" style="width: 100%; margin-top: 20px" border>
<el-table-column label="Name" prop="name"></el-table-column>
<el-table-column label="Field Type" prop="fieldType"></el-table-column>
<el-table-column label="Encoding Method" prop="encodingMethod"></el-table-column>
<el-table-column label="Compression Method" prop="compressionMethod"></el-table-column>
<el-table-column label="Operator">
<template #default="scope">
<el-button
link
type="primary"
@click.prevent="openEditField(scope.$index)"
style="color: var(--color-main); font-weight: bold"
>Edit</el-button
>
<el-popconfirm @confirm="deleteTableData(scope.$index)" title="Are you sure to delete this?">
<template #reference>
<el-button link type="danger" style="color: red; font-weight: bold">Delete</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-dialog
v-model="data.dialogVisible"
:close-on-click-modal="false"
align-center
:title="data.fieldOperator === 'Add' ? 'Create Field' : 'Edit Field'"
width="30%"
>
<el-form ref="ruleFormRef" :rules="rules" :model="data.form" label-width="180" label-position="left">
<el-form-item label="Name" prop="name">
<el-input
v-model="data.form.name"
placeholder="Input the field name"
:disabled="data.fieldOperator === 'Edit'"
></el-input>
</el-form-item>
<el-form-item label="Field Type" prop="fieldType">
<el-select
v-model="data.form.fieldType"
default-first-option
:reserve-keyword="false"
placeholder="Choose field type"
style="width: 100%"
>
<el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="Encoding Method" prop="encodingMethod">
<el-select style="width: 100%" v-model="data.form.encodingMethod" placeholder="Choose encoding method">
<el-option v-for="item in encodingMethodOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="Compression Method" prop="compressionMethod">
<el-select style="width: 100%" v-model="data.form.compressionMethod" placeholder="Choose compression method">
<el-option
v-for="item in compressionMethodOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-form>
<span class="dialog-footer">
<div style="width: 100%" class="flex center">
<el-button
size="small"
@click="
data.dialogVisible = false;
initForm();
"
>Cancel</el-button
>
<el-button size="small" type="primary" color="#6E38F7" @click="confirmForm(ruleFormRef)"> Confirm </el-button>
</div>
</span>
</el-dialog>
</template>
<style lang="scss" scoped></style>