add subtable

This commit is contained in:
2025-01-26 16:11:02 +08:00
parent 0abea3628a
commit 53da9bebb3
3 changed files with 60 additions and 21 deletions

View File

@@ -6,16 +6,28 @@
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading" :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/> />
<kuc-combobox <kuc-combobox
v-if="type == 'kuc-combobox'" v-else-if="type == 'kuc-combobox'"
:value="modelValue" :value="modelValue"
@change="updateValue" @change="updateValue"
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading" :disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/> />
<kuc-time-picker
v-else-if="type == 'kuc-time'"
:value="modelValue"
@change="updateValue"
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/>
<!-- <table-condition-value-date-time
v-else-if="type == 'time'|type == 'date"
:value="modelValue"
@change="updateValue"
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
/> -->
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getComponent } from '@/js/conditions'; import { getComponent } from '@/js/conditions';
import { search } from '@/js/helper'; import { getFieldObj, search } from '@/js/helper';
import type { CachedSelectedAppData, WhereCondition } from '@/types/model'; import type { CachedSelectedAppData, WhereCondition } from '@/types/model';
import type { KucEvent } from '@/types/my-kintone'; import type { KucEvent } from '@/types/my-kintone';
import type { ComboboxChangeEventDetail, TextInputEventDetail } from 'kintone-ui-component'; import type { ComboboxChangeEventDetail, TextInputEventDetail } from 'kintone-ui-component';
@@ -30,7 +42,10 @@ const props = defineProps<{
const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined); const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
const type = computed(() => getComponent(whereCondition.value?.condition || '')); const type = computed(() => {
const field = getFieldObj(whereCondition.value?.field || '', props.selectedAppData.appFields, '');
return getComponent(whereCondition.value?.condition || '', field);
});
type EmitData = { type EmitData = {
obj?: WhereCondition; obj?: WhereCondition;

View File

@@ -24,10 +24,6 @@ export const conditionList: ConditionItem[] = [
{ value: 'not_contain', label: '次のいずれも含まない', type: 'input' }, { value: 'not_contain', label: '次のいずれも含まない', type: 'input' },
]; ];
export const isDateTimeType = (field: OneOf) => {
return isType.DATETIME(field) || isType.TIME(field) || isType.DATE(field) || isType.CREATED_TIME(field) || isType.UPDATED_TIME(field);
}
// search from conditionList // search from conditionList
// conditionItem = conditionMap[conditionValue] // conditionItem = conditionMap[conditionValue]
export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList.reduce( export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList.reduce(
@@ -42,7 +38,7 @@ type FieldConditions = Partial<Record<FieldType, ConditionValue[]>>;
const textCondition: ConditionValue[] = ['eq', 'ne', 'contains', 'not_contain']; const textCondition: ConditionValue[] = ['eq', 'ne', 'contains', 'not_contain'];
const numberCondition: ConditionValue[] = ['eq', 'ne', 'le', 'ge']; const numberCondition: ConditionValue[] = ['eq', 'ne', 'le', 'ge'];
const timeCondition: ConditionValue[] = [...numberCondition, 'lt', 'gt']; const timeCondition: ConditionValue[] = ['eq', 'ne', 'le', 'lt', 'ge', 'gt'];
const containsCondition: ConditionValue[] = ['contains', 'not_contain']; const containsCondition: ConditionValue[] = ['contains', 'not_contain'];
// FieldType -> ConditionValue[] // FieldType -> ConditionValue[]
@@ -87,11 +83,15 @@ export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo,
const component = { const component = {
input: 'kuc-text', input: 'kuc-text',
select: 'kuc-combobox', select: 'kuc-combobox',
time: 'time', time: 'kuc-time',
date: 'date', date: 'date',
datetime: 'datetime', datetime: 'datetime',
}; };
export const isDateTimeType = (field: OneOf) => {
return field.type in dateTimeComponent;
}
const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = { const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
TIME: 'time', TIME: 'time',
DATE: 'date', DATE: 'date',
@@ -101,7 +101,8 @@ const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
} }
export type ComponentType = keyof typeof component; export type ComponentType = keyof typeof component;
export const getComponent = (value: ConditionValue) => { export const getComponent = (value: ConditionValue, fieldObj: OneOf) => {
if (!value) return; if (!value) return;
return component[conditionMap[value].type]; const condition = conditionMap[value].type;
return component[typeof condition === 'function' ? condition(fieldObj) : condition];
}; };

View File

@@ -63,12 +63,27 @@ export const loadApps = async (offset = 0, _apps: DropdownItem[] = []): Promise<
}; };
export const loadAppFieldsAndLayout = async (appId: string | number = kintone.app.getId() as number) => { export const loadAppFieldsAndLayout = async (appId: string | number = kintone.app.getId() as number) => {
const fields = (await client.app.getFormFields({ app: appId })).properties;
return { return {
fields: (await client.app.getFormFields({ app: appId })).properties, fields: flatFields(fields),
layout: (await client.app.getFormLayout({ app: appId })).layout, layout: (await client.app.getFormLayout({ app: appId })).layout,
} as FieldsInfo; } as FieldsInfo;
}; };
function flatFields(fields: Properties) {
const subtableFields = {} as Properties;
Object.values(fields).forEach((field) => {
if (isType.SUBTABLE(field)) {
Object.values(field.fields).forEach((subField) => {
const copy = JSON.parse(JSON.stringify(subField)) as typeof subField;
copy.label = '[' + field.code + '].' + field.label;
subtableFields[subField.code] = copy;
})
}
});
return { ...fields, ...subtableFields };
}
type FilterType = Array<FieldType | SpecialType>; type FilterType = Array<FieldType | SpecialType>;
type Param = { type Param = {
subTableCode: string | undefined; subTableCode: string | undefined;
@@ -77,10 +92,19 @@ type Param = {
dependFilterField?: OneOf; dependFilterField?: OneOf;
defaultLabel?: string; defaultLabel?: string;
defaultDisableCallback?: (field: OneOf) => boolean; defaultDisableCallback?: (field: OneOf) => boolean;
needSubTableField?: boolean;
}; };
export const getFieldsDropdownItems = ( export const getFieldsDropdownItems = (
{ fields, layout }: FieldsInfo, { fields, layout }: FieldsInfo,
{ subTableCode, filterType, baseFilter, dependFilterField, defaultLabel, defaultDisableCallback }: Param, {
subTableCode,
filterType,
baseFilter,
dependFilterField,
defaultLabel,
defaultDisableCallback,
needSubTableField = true,
}: Param,
) => { ) => {
// get used field codes // get used field codes
let fieldOrder: string[]; let fieldOrder: string[];
@@ -96,7 +120,7 @@ export const getFieldsDropdownItems = (
const subTableFieldMap = fieldMap[subTableCode] as { fields: Record<string, any> } | undefined; const subTableFieldMap = fieldMap[subTableCode] as { fields: Record<string, any> } | undefined;
fieldMap = subTableFieldMap?.fields || {}; fieldMap = subTableFieldMap?.fields || {};
} else { } else {
fieldOrder = extractNoSubTableFields(layout, baseFilter); fieldOrder = extractNoSubTableFields(layout, baseFilter, !!needSubTableField);
} }
// create labels // create labels
@@ -145,19 +169,18 @@ export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?:
); );
}; };
const extractNoSubTableFields = (layout: Layout, baseFilter: FieldType[] | undefined) => { const extractNoSubTableFields = (layout: Layout, baseFilter: FieldType[] | undefined, needSubTableField: boolean) => {
return layout.reduce((acc, each) => { return layout.reduce((acc, each) => {
if (each.type === 'SUBTABLE') { if (each.type === 'GROUP') {
return acc; acc.push(...extractNoSubTableFields(each.layout, baseFilter, needSubTableField));
} else if (each.type === 'ROW') { } else if (each.type === 'ROW' || (needSubTableField && each.type === 'SUBTABLE')) {
acc.push( acc.push(
...each.fields.map((field: any) => { ...each.fields.map((field) => {
if (!('code' in field)) return '';
if (!baseFilter) return field.code; if (!baseFilter) return field.code;
return baseFilter.find((t) => t === field.type) ? field?.code || '' : ''; return baseFilter.find((t) => t === field.type) ? field?.code || '' : '';
}), }),
); );
} else if (each.type === 'GROUP') {
acc.push(...extractNoSubTableFields(each.layout, baseFilter));
} }
return acc; return acc;
}, [] as string[]); }, [] as string[]);