('savedData') as SavedData;
const onClick = (type: 'add' | 'remove') => {
if (type === 'add') {
- savedData.joinTables.push(createEmptyJoinTable());
+ const currentIndex = savedData.joinTables.findIndex((t) => t.id === props.tableId);
+ if (currentIndex !== -1) {
+ savedData.joinTables.splice(currentIndex + 1, 0, createEmptyJoinTable());
+ } else {
+ savedData.joinTables.push(createEmptyJoinTable());
+ }
} else if (savedData.joinTables.length > 1) {
savedData.joinTables = savedData.joinTables.filter((t) => t.id !== props.tableId);
}
diff --git a/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue b/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue
index ee9a072..a577d1f 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue
@@ -16,15 +16,15 @@
-
+
-
+
-
+
@@ -43,7 +43,6 @@ import {
} from '@/js/helper';
import { types } from '@/js/kintone-rest-api-client';
import type { CachedData, CachedSelectedAppData, FieldsInfo, JoinTable, SavedData } from '@/types/model';
-import type { KucEvent } from '@/types/my-kintone';
import { computed, inject, provide, reactive, ref, watch } from 'vue';
const savedData = inject('savedData') as SavedData;
@@ -69,7 +68,6 @@ watch(
() => tableOptions.value,
() => {
if (!props.table.table) return;
- debugger
componentKey.value += 1;
},
{
@@ -87,13 +85,14 @@ watch(
const fields = await loadAppFieldsAndLayout(newVal);
tableOptions.value = getTableFieldsDropdownItems(fields, types.SUBTABLE);
selectedAppData.appFields = fields;
+ props.table.meta = fields.fields;
!!oldVal && resetTable(props.table);
loading.value = false;
},
{ immediate: true },
);
-const selectTable = (e: KucEvent) => {
+const selectTable = () => {
resetConditions(props.table);
};
diff --git a/vue-project/my-kintone-plugin/src/components/basic/PluginTableConditionRow.vue b/vue-project/my-kintone-plugin/src/components/basic/PluginTableConditionRow.vue
index ba53863..982f3a3 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/PluginTableConditionRow.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/PluginTableConditionRow.vue
@@ -4,10 +4,9 @@
diff --git a/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue b/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue
index 74fb64a..3c41243 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue
@@ -3,32 +3,66 @@
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 2148d7c..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 @@
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 d957b09..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
@@ -9,27 +9,34 @@
diff --git a/vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue
index fad7907..4128c61 100644
--- a/vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue
+++ b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue
@@ -15,24 +15,33 @@
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/helper.ts b/vue-project/my-kintone-plugin/src/js/helper.ts
index 2e47cea..b249e1d 100644
--- a/vue-project/my-kintone-plugin/src/js/helper.ts
+++ b/vue-project/my-kintone-plugin/src/js/helper.ts
@@ -1,17 +1,37 @@
-import type { FieldsInfo, 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 type { FieldsInfo, FieldsJoinMapping, JoinTable, WhereCondition } from '@/types/model';
+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: '',
label: '--------',
} as DropdownItem;
-export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '' }) as WhereCondition;
-export const getEmptyOnCondition = () => ({ leftField: '', rightField: '' });
-export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '' });
+export function generateId(): string {
+ const timestamp = new Date().getTime().toString(36);
+ const randomNum = Math.random().toString(36).substring(2, 11);
+ return `${timestamp}-${randomNum}`;
+}
-export function createEmptyJoinTable(id = Number(new Date())) {
+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 function createEmptyJoinTable(id = generateId()) {
return resetTable({ id, app: '' } as JoinTable);
}
@@ -49,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,
@@ -75,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) => {
@@ -99,19 +150,35 @@ 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);
+ return meta[fieldCode];
+}
+
+export function getMeta(fields: Properties, subTableCode?: string) {
+ if (!fields || !subTableCode) {
+ return fields;
+ }
+ let meta = 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..5acddf2
--- /dev/null
+++ b/vue-project/my-kintone-plugin/src/js/join.ts
@@ -0,0 +1,59 @@
+import type { CalcType } from '@/types/my-kintone';
+import { isType, type FieldType, type OneOf } from './kintone-rest-api-client';
+
+
+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] : [];
+}
diff --git a/vue-project/my-kintone-plugin/src/js/kintone-rest-api-client.ts b/vue-project/my-kintone-plugin/src/js/kintone-rest-api-client.ts
index 43f1ad9..fd58f7f 100644
--- a/vue-project/my-kintone-plugin/src/js/kintone-rest-api-client.ts
+++ b/vue-project/my-kintone-plugin/src/js/kintone-rest-api-client.ts
@@ -10,7 +10,7 @@ export type App = {
export type Properties = Awaited>['properties'];
export type Layout = Awaited>['layout'];
-type OneOf = Properties[string];
+export type OneOf = Properties[string];
export type FieldType = OneOf['type'];
const typeNames = [
@@ -54,7 +54,7 @@ export const types = typeNames.reduce(
type ExtractOneOf = Extract;
function createTypeGuard(type: T) {
- return (value: OneOf): value is ExtractOneOf => value.type === type;
+ return (value: OneOf): value is ExtractOneOf => value?.type === type;
}
export const isType = Object.fromEntries(
diff --git a/vue-project/my-kintone-plugin/src/types/model.d.ts b/vue-project/my-kintone-plugin/src/types/model.d.ts
index e35fdfa..62791ac 100644
--- a/vue-project/my-kintone-plugin/src/types/model.d.ts
+++ b/vue-project/my-kintone-plugin/src/types/model.d.ts
@@ -2,24 +2,27 @@ import type { ConditionValue } from '@/js/conditions';
import type { Layout, Properties } from '@/js/kintone-rest-api-client';
import type { DropdownItem } from 'kintone-ui-component';
-export interface FieldsJoinMapping {
- leftField: string;
- rightField: string;
+export interface FieldsJoinMapping {
+ id: string;
+ leftField: FieldType;
+ rightField: FieldType;
}
-export interface WhereCondition {
- field: string;
+export interface WhereCondition {
+ id: string;
+ field: FieldType;
condition: ConditionValue;
data: string;
}
-export interface JoinTable {
- id: number; // 用于唯一区分
+export interface JoinTable {
+ id: string;
app: string; // 取得元アプリ
table: string; // テーブル
- onConditions: FieldsJoinMapping[]; // 連結条件
- fieldsMapping: FieldsJoinMapping[]; // 取得フィールド
- whereConditions: WhereCondition[]; // 絞込条件
+ onConditions: FieldsJoinMapping[]; // 連結条件
+ fieldsMapping: FieldsJoinMapping[]; // 取得フィールド
+ whereConditions: WhereCondition[]; // 絞込条件
+ meta?: Properties;
}
// 存储的数据格式
diff --git a/vue-project/my-kintone-plugin/src/types/my-kintone.d.ts b/vue-project/my-kintone-plugin/src/types/my-kintone.d.ts
index 7e32aee..394f20c 100644
--- a/vue-project/my-kintone-plugin/src/types/my-kintone.d.ts
+++ b/vue-project/my-kintone-plugin/src/types/my-kintone.d.ts
@@ -1,5 +1,5 @@
-export interface KucEvent {
- detail: {
- value: string;
- };
+export interface KucEvent {
+ detail: T;
}
+
+export type CalcType = 'NUMBER' | 'NUMBER_DIGIT' | 'DATETIME' | 'DATE' | 'TIME' | 'HOUR_MINUTE' | 'DAY_HOUR_MINUTE';