diff --git a/vue-project/my-kintone-plugin/src/components/Config.vue b/vue-project/my-kintone-plugin/src/components/Config.vue
index bd5fea0..228b351 100644
--- a/vue-project/my-kintone-plugin/src/components/Config.vue
+++ b/vue-project/my-kintone-plugin/src/components/Config.vue
@@ -18,8 +18,8 @@
diff --git a/vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue b/vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue
index 13dfbc0..b4bd8f4 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue
@@ -1,7 +1,7 @@
;
- modelValue: string;
+ modelValue: Ref;
dataList: any[];
id: string;
selectedAppData: CachedSelectedAppData;
@@ -28,7 +28,7 @@ const componentKey = ref(0);
watch(
() => props.items.value,
() => {
- if (!props.modelValue) return;
+ if (!props.modelValue.value) return;
componentKey.value += 1;
},
{
diff --git a/vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue
index b56b582..9f4043f 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue
@@ -25,7 +25,7 @@ const props = defineProps<{
const whereCondition = computed(() => search(props.whereConditions, props.id) as WhereCondition | undefined);
-const items = computed(() => getAvailableCondition(whereCondition.value?.field || '', props.selectedAppData.appFields));
+const items = computed(() => getAvailableCondition(whereCondition.value?.field || '', props.selectedAppData.appFields, props.selectedAppData.table.table));
type EmitData = {
obj?: WhereCondition;
diff --git a/vue-project/my-kintone-plugin/src/js/conditions.ts b/vue-project/my-kintone-plugin/src/js/conditions.ts
index f80cd68..0ffd963 100644
--- a/vue-project/my-kintone-plugin/src/js/conditions.ts
+++ b/vue-project/my-kintone-plugin/src/js/conditions.ts
@@ -1,5 +1,6 @@
import type { FieldsInfo } from '@/types/model';
import type { FieldType } from './kintone-rest-api-client';
+import { getFieldObj } from './helper';
// conditionValue = '' | 'eq' | 'ne'
// conditionItem = { value: 'eq', label: '=(等しい)', type: 'input', func: (a: string, b: string) => a === b }
@@ -39,9 +40,11 @@ const fieldConditions: FieldConditions = {
} as const;
// fieldCode -> conditionList: ConditionItem[]
-export const getAvailableCondition = (fieldCode: string, { fields }: FieldsInfo) => {
- if (!fieldCode || !fields) return;
- const conditions = fieldConditions[fields[fieldCode]?.type] || [];
+export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo, subTableCode: string | '') => {
+ if (!fieldCode || !fieldsInfo.fields) return;
+ const fieldObj = getFieldObj(fieldCode, fieldsInfo, subTableCode);
+ if (!fieldObj) return;
+ const conditions = fieldConditions[fieldObj.type] || [];
return conditions.map((condition) => conditionMap[condition]);
};
diff --git a/vue-project/my-kintone-plugin/src/js/fields.ts b/vue-project/my-kintone-plugin/src/js/fields.ts
deleted file mode 100644
index 9f9185d..0000000
--- a/vue-project/my-kintone-plugin/src/js/fields.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import type { FieldType } from "./kintone-rest-api-client";
-
-const availableJoinType: FieldType[] = [
- 'SINGLE_LINE_TEXT',
- 'NUMBER',
- 'CALC',
- 'DATE',
- 'TIME',
- 'DATETIME',
- 'LINK'
-] as const
\ No newline at end of file
diff --git a/vue-project/my-kintone-plugin/src/js/helper.ts b/vue-project/my-kintone-plugin/src/js/helper.ts
index c58241b..63558e1 100644
--- a/vue-project/my-kintone-plugin/src/js/helper.ts
+++ b/vue-project/my-kintone-plugin/src/js/helper.ts
@@ -1,6 +1,15 @@
import type { FieldsInfo, FieldsJoinMapping, JoinTable, WhereCondition } from '@/types/model';
-import { client, isType, type FieldType, type App, type Layout } from './kintone-rest-api-client';
-import type { DropdownItem } from 'kintone-ui-component';
+import {
+ client,
+ isType,
+ type FieldType,
+ type App,
+ type Layout,
+ type OneOf,
+ type Properties,
+} from './kintone-rest-api-client';
+import type { ComboboxItem, DropdownItem } from 'kintone-ui-component';
+import { isForceDisable, type LeftCalcJoinType, type RightCalcJoinType } from './join';
export const EMPTY_OPTION = {
value: '',
@@ -13,13 +22,14 @@ export function generateId(): string {
return `${timestamp}-${randomNum}`;
}
-export function search(list: Array, id: string) {
- return list.find(item => item.id === id);
+export function search(list: Array, id: string) {
+ return list.find((item) => item.id === id);
}
-export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '', id: generateId()} as WhereCondition);
-export const getEmptyOnCondition = () => ({ leftField: '', rightField: '', id: generateId() } as FieldsJoinMapping);
-export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '', id: generateId() } as FieldsJoinMapping);
+export const getEmptyWhereCondition = () =>
+ ({ field: '', condition: '', data: '', id: generateId() }) as WhereCondition;
+export const getEmptyOnCondition = () => ({ leftField: '', rightField: '', id: generateId() }) as FieldsJoinMapping;
+export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '', id: generateId() }) as FieldsJoinMapping;
export function createEmptyJoinTable(id = generateId()) {
return resetTable({ id, app: '' } as JoinTable);
@@ -59,25 +69,37 @@ export const loadAppFieldsAndLayout = async (appId: string | number = kintone.ap
} as FieldsInfo;
};
-type Param = { subTableCode?: string; filterType?: FieldType; defaultLabel?: string };
+type FilterType = Array;
+type Param = {
+ subTableCode: string | undefined;
+ filterType?: FilterType;
+ baseFilter: FieldType[] | undefined;
+ defaultLabel?: string;
+ defaultDisableCallback?: (field: OneOf) => boolean;
+};
export const getFieldsDropdownItems = (
{ fields, layout }: FieldsInfo,
- { subTableCode, filterType, defaultLabel }: Param = {},
+ { subTableCode, filterType, baseFilter, defaultLabel, defaultDisableCallback }: Param,
) => {
// get used field codes
let fieldOrder: string[];
let fieldMap = fields;
if (subTableCode) {
const subTableFields = layout.find((each) => each.type === 'SUBTABLE' && each.code === subTableCode) as any;
- fieldOrder = subTableFields?.fields.map((field: { code: string }) => field.code) || [];
+ fieldOrder =
+ subTableFields?.fields.map((field: OneOf) => {
+ if (!baseFilter) return field.code;
+ return baseFilter.find((t) => t === field.type) ? field.code : '';
+ }) || [];
+
const subTableFieldMap = fieldMap[subTableCode] as { fields: Record } | undefined;
fieldMap = subTableFieldMap?.fields || {};
} else {
- fieldOrder = extractNoSubTableFields(layout);
+ fieldOrder = extractNoSubTableFields(layout, baseFilter);
}
// create labels
- const labels = [
+ const labels: ComboboxItem[] = [
{
value: EMPTY_OPTION.value,
label: defaultLabel || EMPTY_OPTION.label,
@@ -85,15 +107,34 @@ export const getFieldsDropdownItems = (
];
return fieldOrder.reduce((acc, fieldCode) => {
const field = fieldMap[fieldCode];
- if (!fieldCode || (filterType && !isType[filterType](field))) return acc;
+ if (!fieldCode) return acc;
acc.push({
value: fieldCode,
label: field.label + '(FC: ' + fieldCode + ')',
+ disabled: (defaultDisableCallback && defaultDisableCallback(field)) || (filterType && !checkFilterType(field, filterType)),
});
return acc;
}, labels);
};
+const checkFilterType = (field: OneOf, filterType: FilterType) => {
+ if (!filterType.length) return true; // [] means no filter
+ return !!filterType.find((type) => {
+ if (isRightCalcJoinType(type)) {
+ return isType.CALC(field) && type.format.find((e) => e === field.format);
+ }
+ return isType[type](field);
+ });
+};
+
+export function isLeftCalcJoinType(obj: FilterType | LeftCalcJoinType): obj is LeftCalcJoinType {
+ return !Array.isArray(obj);
+}
+
+function isRightCalcJoinType(obj: FieldType | RightCalcJoinType): obj is RightCalcJoinType {
+ return typeof obj === 'object' && obj.type === 'CALC';
+}
+
export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?: FieldType) => {
return Object.keys(fields).reduce(
(acc, fieldCode) => {
@@ -109,19 +150,37 @@ export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?:
);
};
-const extractNoSubTableFields = (layout: Layout) => {
+const extractNoSubTableFields = (layout: Layout, baseFilter: FieldType[] | undefined) => {
return layout.reduce((acc, each) => {
if (each.type === 'SUBTABLE') {
return acc;
} else if (each.type === 'ROW') {
- acc.push(...each.fields.map((field: any) => field.code));
+ acc.push(...each.fields.map((field: any) => {
+ if (!baseFilter) return field.code;
+ return baseFilter.find((t) => t === field.type) ? field?.code || '' : ''
+ }));
} else if (each.type === 'GROUP') {
- acc.push(...extractNoSubTableFields(each.layout));
+ acc.push(...extractNoSubTableFields(each.layout, baseFilter));
}
return acc;
}, [] as string[]);
};
-// if (isType.SUBTABLE(field)) {
-// console.log(field.fields);
-// }
+export function getFieldObj(fieldCode: string, { fields }: FieldsInfo, subTableCode?: string) {
+ const meta = getMeta(fields, subTableCode);
+ if (!meta) return '';
+ return meta[fieldCode];
+}
+
+export function getMeta(fields: Properties, subTableCode?: string) {
+ if (!fields || !subTableCode) {
+ return fields;
+ }
+ let meta = fields;
+ if (!meta) return fields;
+ const table = meta[subTableCode];
+ if (isType.SUBTABLE(table)) {
+ meta = table.fields;
+ }
+ return meta;
+}
diff --git a/vue-project/my-kintone-plugin/src/js/join.ts b/vue-project/my-kintone-plugin/src/js/join.ts
new file mode 100644
index 0000000..ffa3cb8
--- /dev/null
+++ b/vue-project/my-kintone-plugin/src/js/join.ts
@@ -0,0 +1,58 @@
+import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
+
+type CalcType = 'NUMBER' | 'NUMBER_DIGIT' | 'DATETIME' | 'DATE' | 'TIME' | 'HOUR_MINUTE' | 'DAY_HOUR_MINUTE';
+export type LeftCalcJoinType = Record;
+
+export function isForceDisable(field: OneOf) {
+ if (isType.CALC(field)) {
+ return field.format === 'DAY_HOUR_MINUTE' || field.format === 'HOUR_MINUTE';
+ }
+ return false;
+}
+
+const calcJoinType = {
+ NUMBER: ['SINGLE_LINE_TEXT', 'NUMBER'],
+ NUMBER_DIGIT: ['SINGLE_LINE_TEXT', 'NUMBER'],
+ DATE: ['DATE'],
+ TIME: ['TIME'],
+ DATETIME: ['DATETIME'],
+ HOUR_MINUTE: [],
+ DAY_HOUR_MINUTE: [],
+} as LeftCalcJoinType;
+
+const availableLeftJoinType = {
+ SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT'],
+ NUMBER: ['NUMBER'],
+ CALC: calcJoinType,
+ DATE: ['DATE'],
+ TIME: ['TIME'],
+ DATETIME: ['DATETIME'],
+ LINK: ['LINK'],
+} as Record;
+
+// undefined means all
+export function getRightAvailableJoinType(left?: OneOf | '') {
+ if (left === undefined) {
+ return Object.keys(availableRightJoinType) as FieldType[];
+ }
+ return left ? availableLeftJoinType[left.type] : [];
+}
+
+export type RightCalcJoinType = { type: 'CALC'; format: CalcType[] };
+
+const availableRightJoinType = {
+ SINGLE_LINE_TEXT: ['SINGLE_LINE_TEXT', { type: 'CALC', format: ['NUMBER', 'NUMBER_DIGIT'] }],
+ NUMBER: ['NUMBER', { type: 'CALC', format: ['NUMBER', 'NUMBER_DIGIT'] }],
+ DATE: ['DATE', { type: 'CALC', format: ['DATE'] }],
+ TIME: ['TIME', { type: 'CALC', format: ['TIME'] }],
+ DATETIME: ['DATETIME', { type: 'CALC', format: ['DATETIME'] }],
+ LINK: ['LINK'],
+} as Record>;
+
+// undefined means all
+export function getLeftAvailableJoinType(right?: OneOf | '') {
+ if (right === undefined) {
+ return Object.keys(availableLeftJoinType) as FieldType[];
+ }
+ return right ? availableRightJoinType[right.type] : [];
+}