blob: 77f060ad915641895f9ae6eda570754af36a8db3 [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 { watch, getCurrentInstance } from '@vue/runtime-core';
import { reactive, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import TagEditor from './tagEditor.vue';
import FieldsEditor from './fieldsEditor.vue';
import type { FormInstance } from 'element-plus';
import { ElMessage } from 'element-plus';
import { createResources, editResources, getStreamOrMeasure } from '@/api/index';
import FormHeader from '../common/FormHeader.vue';
const $loadingCreate = getCurrentInstance().appContext.config.globalProperties.$loadingCreate;
const $loadingClose = getCurrentInstance().appContext.config.globalProperties.$loadingClose;
const $bus = getCurrentInstance().appContext.config.globalProperties.mittBus;
const router = useRouter();
const route = useRoute();
const ruleFormRef = ref<FormInstance>();
const tagEditorRef = ref();
const fieldEditorRef = ref();
const rules = {
group: [
{
required: true,
message: 'Please enter the group',
trigger: 'blur',
},
],
name: [
{
required: true,
message: 'Please select the name',
trigger: 'blur',
},
],
};
const data = reactive({
type: route.params.type,
operator: route.params.operator,
form: {
group: route.params.group,
name: route.params.group,
modRevision: route.params.modRevision,
interval: 1,
intervalUnit: 'm',
indexMode: false,
},
});
const options = [
{
label: 'seconds',
value: 's',
},
{
label: 'minutes',
value: 'm',
},
{
label: 'hours',
value: 'h',
},
{
label: 'days',
value: 'd',
},
];
watch(
() => route,
() => {
data.form.group = route.params.group;
data.form.name = route.params.name;
data.form.modRevision = route.params.modRevision;
data.type = route.params.type + '';
data.operator = route.params.operator;
initData();
},
{
immediate: true,
deep: true,
},
);
const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid) => {
if (valid) {
const arr = tagEditorRef.value.getTagFamilies();
const tagFamilies = [];
const entity = [];
const shardingKey = [];
arr.forEach((item) => {
const index = tagFamilies.findIndex((tagItem) => {
return tagItem.name === item.tagFamily;
});
if (item.entity === true) {
entity.push(item.tag);
}
if (item.shardingKey === true) {
shardingKey.push(item.tag);
}
if (index >= 0) {
let obj = {
name: item.tag,
type: item.type,
};
return tagFamilies[index].tags.push(obj);
}
let obj = {
name: item.tagFamily,
tags: [
{
name: item.tag,
type: item.type,
},
],
};
tagFamilies.push(obj);
});
if (entity.length === 0) {
ElMessage({
message: 'At least one Entity is required',
type: 'error',
duration: 5000,
});
return;
}
const form = {
metadata: {
group: data.form.group,
name: data.form.name,
modRevision: data.form.modRevision,
},
tagFamilies: tagFamilies,
entity: {
tagNames: entity,
},
shardingKey: {
tagNames: shardingKey,
},
};
if (data.type === 'measure') {
const fields = fieldEditorRef.value.getFields();
form['fields'] = fields;
form['interval'] = data.form.interval + data.form.intervalUnit;
}
$loadingCreate();
let params = {};
params[data.type + ''] = form;
if (data.operator === 'edit' && data.form.group && data.form.name) {
return editResources(data.type, data.form.group, data.form.name, params)
.then((res) => {
if (res.status === 200) {
ElMessage({
message: 'Edit successed',
type: 'success',
duration: 5000,
});
$bus.emit('refreshAside');
$bus.emit('deleteResource', data.form.name);
openResourses();
}
})
.finally(() => {
$loadingClose();
});
}
createResources(data.type, params)
.then((res) => {
if (res.status === 200) {
ElMessage({
message: 'Create successed',
type: 'success',
duration: 5000,
});
$bus.emit('refreshAside');
$bus.emit('deleteGroup', data.form.group);
openResourses();
}
})
.finally(() => {
$loadingClose();
});
}
});
};
function openResourses() {
const route = {
name: data.type + '',
params: {
group: data.form.group,
name: data.form.name,
operator: 'read',
type: data.type + '',
},
};
router.push(route);
const add = {
label: data.form.name,
type: 'Read',
route,
};
$bus.emit('AddTabs', add);
}
function initData() {
if (data.operator === 'edit' && data.form.group && data.form.name) {
$loadingCreate();
getStreamOrMeasure(data.type, data.form.group, data.form.name)
.then((res) => {
if (res.status === 200) {
data.form.indexMode = res.data[String(data.type)]?.indexMode || false;
const tagFamilies = res.data[String(data.type)]?.tagFamilies || [];
const entity = res.data[String(data.type)]?.entity?.tagNames || [];
const shardingKey = res.data[String(data.type)]?.shardingKey?.tagNames || [];
const arr = [];
tagFamilies.forEach((item) => {
item.tags.forEach((tag) => {
const entityIndex = entity.findIndex((entityItem) => {
return entityItem === tag.name;
});
const shardingKeyIndex = shardingKey.findIndex((shardingKeyItem) => {
return shardingKeyItem === tag.name;
});
const obj = {
tagFamily: item.name,
tag: tag.name,
type: tag.type,
entity: entityIndex >= 0 ? true : false,
shardingKey: shardingKeyIndex >= 0 ? true : false,
};
arr.push(obj);
});
});
tagEditorRef.value.setTagFamilies(arr);
if (data.type === 'measure') {
const fields = res.data[data.type + ''].fields;
const intervalArr = res.data[data.type + ''].interval.split('');
let interval = 0;
let intervalUnit = '';
intervalArr.forEach((char) => {
let code = char.charCodeAt();
if (code >= 48 && code < 58) {
interval = interval * 10 + (char - 0);
} else {
intervalUnit = intervalUnit + char;
}
});
data.form.interval = interval;
data.form.intervalUnit = intervalUnit;
fieldEditorRef.value.setFields(fields);
}
data.form.modRevision = res.data[data.type + ''].metadata.modRevision;
}
})
.finally(() => {
$loadingClose();
});
}
}
</script>
<template>
<div>
<el-card shadow="always">
<template #header>
<el-row>
<el-col :span="20">
<FormHeader :fields="{ ...data, catalog: data.type }" />
</el-col>
<el-col :span="4">
<div class="flex align-item-center justify-end" style="height: 30px">
<el-button size="small" type="primary" @click="submit(ruleFormRef)" color="#6E38F7">Submit</el-button>
</div>
</el-col>
</el-row>
</template>
<el-form ref="ruleFormRef" :model="data.form" label-position="left" :rules="rules" :inline="true">
<el-form-item label="group" prop="group">
<el-input clearable disabled v-model="data.form.group"></el-input>
</el-form-item>
<el-form-item label="name" prop="name">
<el-input style="width: 300px" clearable v-model="data.form.name"></el-input>
</el-form-item>
<el-form-item v-if="data.type === 'measure'" label="interval" prop="interval">
<el-input-number v-model="data.form.interval" :min="1" />
<el-select v-model="data.form.intervalUnit" style="width: 100px; margin-left: 5px">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="Index Mode" prop="indexMode">
<span>{{ data.form.indexMode ? `Yes` : `No` }}</span>
</el-form-item>
</el-form>
<TagEditor ref="tagEditorRef"></TagEditor>
<el-divider v-if="data.type === 'measure'" border-style="dashed" />
<FieldsEditor ref="fieldEditorRef" v-if="data.type === 'measure'"></FieldsEditor>
</el-card>
</div>
</template>
<style lang="scss" scoped>
:deep(.el-card) {
margin: 15px;
}
</style>