merge to kintone exec
This commit is contained in:
Binary file not shown.
@@ -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;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
config: {
|
config: {
|
||||||
title: 'Settings for data fetch plugin',
|
title: 'Data Fetch Plugin Settings',
|
||||||
desc: 'This message is displayed on the app page after the app has been updated.',
|
desc: 'Set the aggregation button name, data source app, fetch fields, filter conditions, and linking conditions, then save.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
config: {
|
config: {
|
||||||
title: 'Settings for data fetch plugin',
|
title: 'データ取得プラグインの設定',
|
||||||
desc: 'This message is displayed on the app page after the app has been updated.',
|
desc: '集約ボタン名とデータ取得元アプリ、取得フィールド、絞込条件や連結条件を設定後、保存してください。',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { FieldLayout, FieldsJoinMapping, JoinTable, Record, RecordForParameter, SavedData, WhereCondition } from "@/types/model";
|
import type { FieldLayout, FieldsJoinMapping, JoinTable, Record, RecordForParameter, SavedData, WhereCondition } from "@/types/model";
|
||||||
import type { isType, OneOf } from "./kintone-rest-api-client";
|
import { type OneOf ,isType} from "./field-types";
|
||||||
declare var KintoneRestAPIClient: typeof import("@kintone/rest-api-client").KintoneRestAPIClient;
|
declare var KintoneRestAPIClient: typeof import("@kintone/rest-api-client").KintoneRestAPIClient;
|
||||||
export class KintoneIndexEventHandler {
|
export class KintoneIndexEventHandler {
|
||||||
private config: SavedData<FieldLayout>;
|
private config: SavedData<FieldLayout>;
|
||||||
|
|||||||
@@ -23,22 +23,16 @@ type ConditionItem = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const conditionList: ConditionItem[] = [
|
export const conditionList: ConditionItem[] = [
|
||||||
{ value: '=', label: '=(等しい)', type: 'input' },
|
{ value: 'eq', label: '=(等しい)', type: 'input' },
|
||||||
{ value: '!=', label: '≠ (等しくない)', type: 'input' },
|
{ value: 'ne', label: '≠ (等しくない)', type: 'input' },
|
||||||
{ value: '<=', label: (field) => isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)', type: 'input' },
|
{ value: 'le', label: (field) => isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)', type: 'input' },
|
||||||
{ value: '<', label: '< (より前)', type: 'input' },
|
{ value: 'lt', label: '< (より前)', type: 'input' },
|
||||||
{ value: '>', label: '> (より後)', type: 'input' },
|
{ value: 'gt', label: '> (より後)', type: 'input' },
|
||||||
{ value: '>=', label: (field) => isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)', type: 'input' },
|
{ value: 'ge', label: (field) => isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)', type: 'input' },
|
||||||
{ value: 'like', label: '次のキーワードを含む', type: 'input' },
|
{ value: 'contains', label: '次のいずれかを含む', type: 'input' },
|
||||||
{ value: 'not like', label:'次のキーワードを含まない', type: 'input' },
|
{ value: 'not_contain', label: '次のいずれも含まない', type: 'input' },
|
||||||
{ value: 'in', label: '次のいずれかを含む', type: 'input' },
|
|
||||||
{ value: 'not in', 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(
|
||||||
@@ -50,7 +44,6 @@ export const conditionMap: Record<ConditionValue, ConditionItem> = conditionList
|
|||||||
);
|
);
|
||||||
|
|
||||||
type FieldConditions = Partial<Record<FieldType, ConditionValue[]>>;
|
type FieldConditions = Partial<Record<FieldType, ConditionValue[]>>;
|
||||||
|
|
||||||
const textCondition: ConditionValue[] = ['=', '!=', 'in', 'like','not like'];
|
const textCondition: ConditionValue[] = ['=', '!=', 'in', 'like','not like'];
|
||||||
const numberCondition: ConditionValue[] = ['=', '!=', '<=', '>='];
|
const numberCondition: ConditionValue[] = ['=', '!=', '<=', '>='];
|
||||||
const timeCondition: ConditionValue[] = ['=', '!=', '<=', '>=', '<', '>'];
|
const timeCondition: ConditionValue[] = ['=', '!=', '<=', '>=', '<', '>'];
|
||||||
@@ -98,11 +91,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',
|
||||||
@@ -112,7 +109,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];
|
||||||
};
|
};
|
||||||
|
|||||||
55
vue-project/my-kintone-plugin/src/js/field-types.ts
Normal file
55
vue-project/my-kintone-plugin/src/js/field-types.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
declare var KintoneRestAPIClient: typeof import("@kintone/rest-api-client").KintoneRestAPIClient;
|
||||||
|
const client = new KintoneRestAPIClient();
|
||||||
|
export type Properties = Awaited<ReturnType<typeof client.app.getFormFields>>['properties'];
|
||||||
|
export type Layout = Awaited<ReturnType<typeof client.app.getFormLayout>>['layout'];
|
||||||
|
|
||||||
|
export type OneOf = Properties[string];
|
||||||
|
export type FieldType = OneOf['type'];
|
||||||
|
|
||||||
|
const typeNames = [
|
||||||
|
'RECORD_NUMBER',
|
||||||
|
'CREATOR',
|
||||||
|
'CREATED_TIME',
|
||||||
|
'MODIFIER',
|
||||||
|
'UPDATED_TIME',
|
||||||
|
'CATEGORY',
|
||||||
|
'STATUS',
|
||||||
|
'STATUS_ASSIGNEE',
|
||||||
|
'SINGLE_LINE_TEXT',
|
||||||
|
'NUMBER',
|
||||||
|
'CALC',
|
||||||
|
'MULTI_LINE_TEXT',
|
||||||
|
'RICH_TEXT',
|
||||||
|
'LINK',
|
||||||
|
'CHECK_BOX',
|
||||||
|
'RADIO_BUTTON',
|
||||||
|
'DROP_DOWN',
|
||||||
|
'MULTI_SELECT',
|
||||||
|
'FILE',
|
||||||
|
'DATE',
|
||||||
|
'TIME',
|
||||||
|
'DATETIME',
|
||||||
|
'USER_SELECT',
|
||||||
|
'ORGANIZATION_SELECT',
|
||||||
|
'GROUP_SELECT',
|
||||||
|
'GROUP',
|
||||||
|
'REFERENCE_TABLE',
|
||||||
|
'SUBTABLE',
|
||||||
|
] as const satisfies readonly FieldType[];
|
||||||
|
|
||||||
|
export const types = typeNames.reduce(
|
||||||
|
(acc, name) => {
|
||||||
|
acc[name] = name;
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{} as Record<(typeof typeNames)[number], (typeof typeNames)[number]>,
|
||||||
|
);
|
||||||
|
|
||||||
|
type ExtractOneOf<T extends FieldType> = Extract<OneOf, { type: T }>;
|
||||||
|
function createTypeGuard<T extends FieldType>(type: T) {
|
||||||
|
return (value: OneOf): value is ExtractOneOf<T> => value?.type === type;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isType = Object.fromEntries(
|
||||||
|
typeNames.map((typeName) => [typeName, createTypeGuard(typeName as FieldType)]),
|
||||||
|
) as { [K in (typeof typeNames)[number]]: (value: OneOf) => value is ExtractOneOf<K> };
|
||||||
@@ -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 + '].' + subField.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[]);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import type { ConditionValue } from '@/js/conditions';
|
|||||||
import type { Layout, Properties } from '@/js/kintone-rest-api-client';
|
import type { Layout, Properties } from '@/js/kintone-rest-api-client';
|
||||||
import type { DropdownItem } from 'kintone-ui-component';
|
import type { DropdownItem } from 'kintone-ui-component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface FieldsJoinMapping<FieldType = string> {
|
export interface FieldsJoinMapping<FieldType = string> {
|
||||||
id: string;
|
id: string;
|
||||||
leftField: FieldType;
|
leftField: FieldType;
|
||||||
@@ -59,4 +61,9 @@ export type RecordForParameter = {
|
|||||||
export type Field={
|
export type Field={
|
||||||
type:string;
|
type:string;
|
||||||
value:any;
|
value:any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FieldLayout={
|
||||||
|
type:string;
|
||||||
|
code:string;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user