Skip to content

Commit

Permalink
Merge remote-tracking branch 'front/feat/replace-schema-form' into _V…
Browse files Browse the repository at this point in the history
…2.4.X/dev_issue#2461_test
  • Loading branch information
Huayeaaa committed Oct 23, 2024
2 parents 2f4f829 + fb923c9 commit ad805cf
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 41 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
}
},
"dependencies": {
"@blueking/bkui-form": "^0.0.42-beta.14",
"@blueking/crypto-js-sdk": "0.0.4",
"@blueking/ip-selector": "0.2.0-beta",
"@blueking/login-modal": "^1.0.1",
Expand Down
108 changes: 108 additions & 0 deletions frontend/src/components/RussianDolls/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,114 @@ export function initSchema(schema: IItem): Doll[] {
// return formatSchema(schema, schema.property)
}

export const transformSchema = (schema: any, parentRequired: any[] = [], key: string = '') => {
if (!schema || typeof schema !== 'object') return schema;

// 处理对象类型的属性
if (schema.type === 'object' && schema.properties) {
const requiredProps = [];
for (const key in schema.properties) {
const prop = schema.properties[key];
if (typeof prop.required !== 'undefined') {
if (prop.required) {
requiredProps.push(key);
if (prop.type === 'array') {
prop['minItems'] = 1;
prop['ui:group'] = {
"props": {
"verifiable": true,
},
};
}
prop['ui:rules'] = ['required']; // 增加 ui:rules
}
// 删除所有的 required,无论是 true 还是 false
delete prop.required;
}
// 递归处理子属性
transformSchema(prop, requiredProps, key);
}
if (schema.required !== undefined) {
if (schema.required) {
parentRequired.push(key);
}
// 处理对象类型中的 required 属性
delete schema.required;
}

if (requiredProps.length > 0) {
schema.required = requiredProps;
}
}

// 处理数组类型的项
if (schema.type === 'array' && schema.items) {
const itemRequiredProps: any = [];
// 递归处理数组的每个项
transformSchema(schema.items, itemRequiredProps, key);
if (schema.required !== undefined) {
delete schema.required; // 删除数组项中的 required
}
// 处理描述信息
if (schema.description) {
schema['ui:group'] = {
"props": {
"description": schema.description,
},
};
}
if (schema.items.properties && Object.keys(schema.items.properties).length >= 2) {
// 如果是 key 和 value,添加 ui:component
if (schema.items.properties.key && schema.items.properties.value) {
schema['ui:component'] = { "name": "bfArray" };
}
schema.items['ui:group'] = {
"props": {
"type": "card",
},
"style": {
"background": "#F5F7FA",
},
};
}
if (schema.items.type === 'string' || schema.items.type === 'boolean' || schema.items.type === 'integer') {
parentRequired.push(key);
}
}

// 转换 ui_component 属性到 ui:component
if (schema.ui_component && schema.ui_component.type === 'select') {
const datasource = [];
for (const optionKey in schema.ui_component.properties) {
const option = schema.ui_component.properties[optionKey];
datasource.push({
label: option.title,
value: option.value
});
}
schema['ui:component'] = {
name: 'select',
props: {
datasource,
clearable: false
}
};
delete schema.ui_component; // 删除原始的 ui_component
}

// 处理字符串、布尔和整数类型的属性,删除 required
if (schema.type === 'string' || schema.type === 'boolean' || schema.type === 'integer') {
if (schema.required !== undefined) {
if (schema.required) {
schema['ui:rules'] = ['required'];
}
// 删除 required
delete schema.required;
}
}

return schema;
}
export const createItem = (property: string, params: IItem, id?: string): Doll => {
console.log('property: ', property, params.type, '; params: ', params);
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@ $bgColor: #f5f7fa;
}
}
.rule-create {
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
Expand All @@ -433,3 +434,8 @@ $bgColor: #f5f7fa;
}
}
</style>
<style>
article {
height: 100%;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,25 @@
<!-- :ref="`form${mainItem.name}`" -->
<!-- ref="nnnnnnnn" -->
<DollForm
<!-- <DollForm
v-if="!isPluginType && mainItem.variables?.properties"
:ref="`form${mainItem.name}`"
:data="mainItem.variables"
:label-width="200"
:value="mainItem.form"
@change="formChange" />
@change="formChange" /> -->
<!-- @focus="handleOperate(arguments, mainItem, 'focus')"
@blur="handleOperate(arguments, mainItem, 'blur')" -->
<BKUIFrom
v-if="!isPluginType && mainItem.variables?.properties"
ref="bkuiFormRef"
:label-width="300"
v-model="mainItem.form"
:schema="mainItem.variables"
form-type="vertical"
:key="mainItem.id"
>
</BKUIFrom>
<!-- <bk-form
v-if="mainItem.data.length"
:model="mainItem.form"
Expand Down Expand Up @@ -253,6 +262,11 @@ import ExceptionCard from '@/components/exception/exception-card.vue';
import { reguRequired } from '@/common/form-check';
import { pluginOperate } from '../../operateConfig';
import bus from '@/common/bus';
import createForm from '@blueking/bkui-form';
import '@blueking/bkui-form/dist/bkui-form.css';
import { transformSchema } from '@/components/RussianDolls/create'
const BKUIFrom = createForm()
interface IVariables {
title: string
Expand Down Expand Up @@ -284,6 +298,7 @@ interface IVariablesItem {
components: {
VariablePopover,
ExceptionCard,
BKUIFrom,
},
})
/**
Expand Down Expand Up @@ -320,6 +335,7 @@ export default class ParamsConfig extends Vue {
[key: string]: IVariablesItem[]
} = {};
private popoverInstance: any = null;
private bkuiFormRef: any = null;
@Ref('popoverRef') private readonly popoverRef!: any;
@Ref('configContent') private readonly configContent!: any;
Expand Down Expand Up @@ -393,7 +409,30 @@ export default class ParamsConfig extends Vue {
});
this.variableMap = res;
}
private getDefaultValue(type: string) {
let defaultValue;
switch(type){
case 'string':
defaultValue = '';
break;
case 'boolean':
defaultValue = false;
break;
case 'number':
defaultValue = 0;
break;
case 'object':
defaultValue = {};
break;
case 'array':
defaultValue = [];
break;
default:
defaultValue = '';
break;
}
return defaultValue;
}
// 初始化主配置和子配置,并按操作系统分类 && 回填表单
private async getVariablesConfig() {
let idList: number[] = [];
Expand All @@ -406,15 +445,15 @@ export default class ParamsConfig extends Vue {
idList = Array.from(new Set(idList));
if (idList.length) {
this.loading = true;
const list = await PluginStore.getConfigVariables({ config_tpl_ids: idList });
let list = await PluginStore.getConfigVariables({ config_tpl_ids: idList });
this.loading = false;
list.forEach((item: IVariablesRes) => {
const itemList = Object.entries(item.variables?.properties || {});
const form: Dictionary = {};
let variableList: IParamsData[] = [];
// 处理表单遍历所需的统一格式 && 回填参数
itemList.forEach(([key, value]) => {
form[key] = value.default || '';
form[key] = value.default || this.getDefaultValue(value.type);
variableList.push({
prop: key,
type: value.type === 'number' ? 'number' : 'string', // 强制转为字符串
Expand Down Expand Up @@ -460,6 +499,7 @@ export default class ParamsConfig extends Vue {
variables: item.variables || {},
});
}
sysItem.variables = transformSchema(item.variables);
}
});
});
Expand Down Expand Up @@ -573,50 +613,52 @@ export default class ParamsConfig extends Vue {
// 检查表单
public async handleValidateForm() {
const validateRes: boolean[] = [];
bus.$emit('validate', (result: boolean) => {
validateRes.push(result);
});
bus.$emit('validateKV', (result: boolean) => {
validateRes.push(result);
});
if(validateRes.some(res => !res)) return true;
const checkList: Promise<boolean>[] = [];
this.list.forEach((item: IParamsConfig) => {
const refs: any = this.$refs[`form${item.name}`];
if (refs?.length) {
refs.reduce((list: Promise<boolean>[], ref: any) => {
list.push(ref.validate());
return list;
}, checkList);
}
});
return new Promise((resolve) => {
Promise.all(checkList)
.then(() => {
resolve(false);
})
.catch(() => {
// const active = this.list.filter(item =>
// Object.values(item.form).some(value => !value)).map(item => item.name);
// this.activeName = Array.from(new Set((active as string[])
// .concat(this.activeName)));
resolve(true);
});
});
// const validateRes: boolean[] = [];
// bus.$emit('validate', (result: boolean) => {
// validateRes.push(result);
// });
// if(validateRes.some(res => !res)) return true;
// const checkList: Promise<boolean>[] = [];
// this.list.forEach((item: IParamsConfig) => {
// const refs: any = this.$refs[`form${item.name}`];
// if (refs?.length) {
// refs.reduce((list: Promise<boolean>[], ref: any) => {
// list.push(ref.validate());
// return list;
// }, checkList);
// }
// });
// return new Promise((resolve) => {
// Promise.all(checkList)
// .then(() => {
// resolve(false);
// })
// .catch(() => {
// // const active = this.list.filter(item =>
// // Object.values(item.form).some(value => !value)).map(item => item.name);
// // this.activeName = Array.from(new Set((active as string[])
// // .concat(this.activeName)));
// resolve(true);
// });
// });
const validRes: boolean[] = [];
(this.$refs.bkuiFormRef as Array<any>)?.forEach((item: any) => {
validRes.push(item.validateForm());
})
return validRes.some(valid => !valid);
}
// 更新策略的 params 和 configs 属性
public async beforeStepLeave() {
await this.handleValidateForm();
const formatValue = JSON.parse(JSON.stringify(PluginStore.strategyData.params));
this.list.forEach((item) => {
const formRef = (this.$refs[`form${item.name}`] as any)?.[0];
this.list.forEach((item, ind) => {
const formRef = (this.$refs.bkuiFormRef as Array<any>)?.[ind];
const params: Dictionary = {
cpu_arch: item.cpu_arch,
os: item.os,
context: formRef?.getFormData?.(), // 主配置、子配置的值都集合到context
context: formRef?.value, // 主配置、子配置的值都集合到context
};
// const itemList = Object.entries(item.form);
// itemList.forEach(([key, value]) => {
Expand Down

0 comments on commit ad805cf

Please sign in to comment.