Skip to content

Commit

Permalink
feat(frontend): 工具箱支持资源池协议变更_editable_table #8076
Browse files Browse the repository at this point in the history
# Reviewed, transaction id: 26393
  • Loading branch information
hLinx committed Dec 10, 2024
1 parent 5cf9958 commit 95b63ab
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 82 deletions.
111 changes: 60 additions & 51 deletions dbm-ui/frontend/src/components/editable-table/Column.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,27 +96,20 @@
const hasOwn = (obj: Record<string, any>, key: string) => Object.prototype.hasOwnProperty.call(obj, key);
const getRuleMessage = (rule: IRule) => {
if (typeof rule.message === 'function') {
return rule.message();
}
return rule.message;
};
export interface IContext {
instance: ComponentInternalInstance;
el: HTMLElement;
key: string;
props: Props;
slots: Slots;
validate: () => Promise<boolean>;
validate: (trigger?: string) => Promise<boolean>;
}
export const EditableTableColumnKey: InjectionKey<{
blur: () => void;
focus: () => void;
registerRules: (params: IRule[]) => void;
validate: () => Promise<boolean>;
validate: (trigger?: string) => Promise<boolean>;
clearValidate: () => void;
}> = Symbol('EditableTableColumnKey');
</script>
Expand Down Expand Up @@ -258,6 +251,25 @@
return [...filterPropRules, ...formatConfigRules];
};
const getTriggerRules = (rules: IFinalRule[], trigger?: string) =>
rules.reduce((result, rule) => {
if (!rule.trigger || !trigger) {
result.push(rule);
return result;
}
if (rule.trigger === trigger) {
result.push(rule);
}
return result;
}, [] as IFinalRule[]);
const getRuleMessage = (rule: IFinalRule) => {
if (typeof rule.message === 'function') {
return rule.message();
}
return rule.message;
};
let registerRules: IRule[] = [];
const rootRef = ref<HTMLElement>();
Expand All @@ -283,25 +295,33 @@
return result ? '无法操作' : '';
});
const validate = (): Promise<boolean> => {
const validate = (trigger?: string): Promise<boolean> => {
// 重新触发验证重置上次的验证状态
validateState.isError = false;
validateState.errorMessage = '';
if (!tableContext) {
return Promise.resolve(false);
}
// 单元格被合并跳过验证
if (!isRowspanRender.value) {
return Promise.resolve(true);
}
// 没有设置 field 不进行验证
if (!props.field) {
return Promise.resolve(true);
}
let rules: IRule[] = [];
// 继承 form 的验证规则
// 继承 table 的验证规则
if (tableContext && tableContext.props.rules && hasOwn(tableContext.props.rules, props.field)) {
rules = tableContext.props.rules[props.field];
}
// form-item 自己的 rules 规则优先级更高
// column 自己的 rules 规则优先级更高
if (props.rules) {
rules = props.rules as IRule[];
} else if (props.appendRules) {
// 配置了 props.rules 时 props.appendRules 不生效
// props.appendRules 与 form 的验证规则合并且优先级高
// props.appendRules 与 table 的验证规则合并且优先级高
rules = [...rules, ...props.appendRules];
}
Expand All @@ -311,15 +331,13 @@
}
// 合并规则属性配置
const finalRuleList = mergeRules(rules, getRulesFromProps(props));
const finalRuleList = getTriggerRules(mergeRules(rules, getRulesFromProps(props)), trigger);
// 重新触发验证重置上次的验证状态
if (rules.length > 0) {
validateState.isError = false;
validateState.errorMessage = '';
if (finalRuleList.length < 1) {
return Promise.resolve(true);
}
const value = get(tableContext.props.model, props.field);
const value = get(tableContext.props.model[rowContext!.getRowIndex()], props.field);
const doValidate = (() => {
let stepIndex = -1;
Expand All @@ -334,39 +352,30 @@
return Promise.resolve().then(() => {
const result = rule.validator(value);
// 异步验证(validator 返回一个 Promise)
if (typeof result !== 'boolean' && typeof result !== 'string' && typeof result.then === 'function') {
return result
.then((data) => {
// 异步验证结果为 false
if (data === false) {
return Promise.reject(getRuleMessage(rule));
}
if (typeof data === 'string') {
return Promise.reject(data);
}
})
.then(
() => doValidate(),
(errorMessage: string) => {
validateState.isError = true;
validateState.errorMessage = errorMessage;
tableContext.emits('validate', props.field || '', false, errorMessage);
return Promise.reject(validateState.errorMessage);
},
);
// 同步验证通过下一步
if (result === true) {
return doValidate();
}
// 同步验证失败
if (result === false) {
const errorMessage = getRuleMessage(rule);
validateState.isError = true;
// 验证结果返回的是 String 表示验证失败,返回结果作为错误信息
validateState.errorMessage = typeof result === 'string' ? result : errorMessage;
tableContext.emits('validate', props.field || '', false, errorMessage);
return Promise.reject(validateState.errorMessage);
}
// 下一步
return doValidate();
// Promise异步处理验证结果
return Promise.resolve(result)
.then((data) => {
// 异步验证结果为 false
if (data === false) {
return Promise.reject(getRuleMessage(rule));
}
if (typeof data === 'string') {
return Promise.reject(data);
}
})
.then(
() => doValidate(),
(errorMessage: string) => {
validateState.isError = true;
validateState.errorMessage = errorMessage;
tableContext.emits('validate', props.field || '', false, errorMessage);
return Promise.reject(validateState.errorMessage);
},
);
});
};
})();
Expand Down
4 changes: 4 additions & 0 deletions dbm-ui/frontend/src/components/editable-table/Row.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
registerColumn: (column: IColumnContext) => void;
unregisterColumn: (columnKey: string) => void;
getColumnIndex: () => number;
getRowIndex: () => number;
}> = Symbol.for('bk-editable-table-row');
</script>
<script setup lang="ts">
Expand Down Expand Up @@ -47,10 +48,13 @@
};
})();
const getRowIndex = () => tableContext?.getAllColumnList().findIndex((item) => item === columnList) as number;
provide(injectKey, {
registerColumn,
unregisterColumn,
getColumnIndex,
getRowIndex,
});
onMounted(() => {
Expand Down
11 changes: 7 additions & 4 deletions dbm-ui/frontend/src/components/editable-table/edit/Block.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
</div>
</template>
<script setup lang="ts">
import { onBeforeUpdate, ref, useTemplateRef, type VNode, watch } from 'vue';
import { nextTick, onUpdated, ref, useTemplateRef, type VNode, watch } from 'vue';
import useColumn from '../useColumn';
Expand All @@ -60,19 +60,22 @@
const isShowPlacehoder = ref(false);
watch(modelValue, () => {
columnContext?.validate();
columnContext?.validate('change');
});
const handleBlur = () => {
columnContext?.blur();
columnContext?.validate('blur');
};
const handleFocus = () => {
columnContext?.focus();
};
onBeforeUpdate(() => {
isShowPlacehoder.value = !contentRef.value?.innerText;
onUpdated(() => {
nextTick(() => {
isShowPlacehoder.value = !contentRef.value?.innerText;
});
});
</script>
<style lang="less">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,51 @@
<BkDatePicker
append-to-body
class="bk-editable-date-picker"
clearable
v-bind="{ ...attrs, ...props }"
@blur="handleBlur"
@focus="handleFocus" />
</template>
<script setup lang="ts">
<script lang="ts">
/* eslint-disable vue/no-unused-properties */
interface Props {
placeholder?: string;
format?: string;
multiple?: boolean;
disabledDate?: (date: Date | number) => boolean;
}
</script>
<script setup lang="ts" generic="T extends [string, string] | string | Date">
import { useAttrs, watch } from 'vue';
import useColumn from '../useColumn';
const props = defineProps<Props>();
const emits = defineEmits<{
(e: 'blur'): void;
(e: 'focus'): void;
(e: 'change', value: T): void;
}>();
const attrs = useAttrs();
const columnContext = useColumn();
const modelValue = defineModel<T>();
watch(modelValue, () => {
columnContext?.validate('change');
});
const handleBlur = () => {
columnContext?.blur();
columnContext?.validate('blur');
emits('blur');
};
const handleFocus = () => {
columnContext?.focus();
emits('focus');
};
</script>
<style lang="less">
Expand Down
30 changes: 28 additions & 2 deletions dbm-ui/frontend/src/components/editable-table/edit/Input.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,54 @@
<BkInput
v-model="modelValue"
class="bk-editable-input"
v-bind="{ ...attrs, ...props }"
clearable
@blur="handleBlur"
@focus="handleFocus" />
</template>
<script setup lang="ts">
import { watch } from 'vue';
import { useAttrs, watch } from 'vue';
import useColumn from '../useColumn';
/* eslint-disable vue/no-unused-properties */
interface Props {
placeholder?: string;
prefix?: string;
suffix?: string;
maxlength?: number;
minlength?: number;
}
interface Emits {
(e: 'blur'): void;
(e: 'focus'): void;
}
const props = defineProps<Props>();
const emits = defineEmits<Emits>();
const attrs = useAttrs();
const columnContext = useColumn();
const modelValue = defineModel<string>();
watch(modelValue, () => {
columnContext?.validate();
columnContext?.validate('change');
console.log('change');
});
const handleBlur = () => {
columnContext?.blur();
columnContext?.validate('blur');
emits('blur');
console.log('handleBlur');
};
const handleFocus = () => {
columnContext?.focus();
emits('focus');
};
</script>
<style lang="less">
Expand Down
Loading

0 comments on commit 95b63ab

Please sign in to comment.