merge to kintone exec
This commit is contained in:
Binary file not shown.
@@ -6,16 +6,28 @@
|
||||
:disabled="selectedAppData.loading == undefined ? false : selectedAppData.loading"
|
||||
/>
|
||||
<kuc-combobox
|
||||
v-if="type == 'kuc-combobox'"
|
||||
v-else-if="type == 'kuc-combobox'"
|
||||
:value="modelValue"
|
||||
@change="updateValue"
|
||||
: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>
|
||||
|
||||
<script setup lang="ts">
|
||||
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 { KucEvent } from '@/types/my-kintone';
|
||||
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 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 = {
|
||||
obj?: WhereCondition;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
config: {
|
||||
title: 'Settings for data fetch plugin',
|
||||
desc: 'This message is displayed on the app page after the app has been updated.',
|
||||
title: 'Data Fetch Plugin Settings',
|
||||
desc: 'Set the aggregation button name, data source app, fetch fields, filter conditions, and linking conditions, then save.',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default {
|
||||
config: {
|
||||
title: 'Settings for data fetch plugin',
|
||||
desc: 'This message is displayed on the app page after the app has been updated.',
|
||||
title: 'データ取得プラグインの設定',
|
||||
desc: '集約ボタン名とデータ取得元アプリ、取得フィールド、絞込条件や連結条件を設定後、保存してください。',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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;
|
||||
export class KintoneIndexEventHandler {
|
||||
private config: SavedData<FieldLayout>;
|
||||
|
||||
@@ -23,22 +23,16 @@ type ConditionItem = {
|
||||
};
|
||||
|
||||
export const conditionList: ConditionItem[] = [
|
||||
{ value: '=', label: '=(等しい)', type: 'input' },
|
||||
{ value: '!=', label: '≠ (等しくない)', type: 'input' },
|
||||
{ value: '<=', label: (field) => isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)', type: 'input' },
|
||||
{ value: '<', label: '< (より前)', type: 'input' },
|
||||
{ value: '>', label: '> (より後)', type: 'input' },
|
||||
{ value: '>=', label: (field) => isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)', type: 'input' },
|
||||
{ value: 'like', label: '次のキーワードを含む', type: 'input' },
|
||||
{ value: 'not like', label:'次のキーワードを含まない', type: 'input' },
|
||||
{ value: 'in', label: '次のいずれかを含む', type: 'input' },
|
||||
{ value: 'not in', label: '次のいずれも含まない', type: 'input' },
|
||||
{ value: 'eq', label: '=(等しい)', type: 'input' },
|
||||
{ value: 'ne', label: '≠ (等しくない)', type: 'input' },
|
||||
{ value: 'le', label: (field) => isDateTimeType(field) ? '≦ (以前)' : '≦ (以下)', type: 'input' },
|
||||
{ value: 'lt', label: '< (より前)', type: 'input' },
|
||||
{ value: 'gt', label: '> (より後)', type: 'input' },
|
||||
{ value: 'ge', label: (field) => isDateTimeType(field) ? '≧ (以降)' : '≧ (以上)', type: 'input' },
|
||||
{ value: 'contains', 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
|
||||
// conditionItem = conditionMap[conditionValue]
|
||||
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[]>>;
|
||||
|
||||
const textCondition: ConditionValue[] = ['=', '!=', 'in', 'like','not like'];
|
||||
const numberCondition: ConditionValue[] = ['=', '!=', '<=', '>='];
|
||||
const timeCondition: ConditionValue[] = ['=', '!=', '<=', '>=', '<', '>'];
|
||||
@@ -98,11 +91,15 @@ export const getAvailableCondition = (fieldCode: string, fieldsInfo: FieldsInfo,
|
||||
const component = {
|
||||
input: 'kuc-text',
|
||||
select: 'kuc-combobox',
|
||||
time: 'time',
|
||||
time: 'kuc-time',
|
||||
date: 'date',
|
||||
datetime: 'datetime',
|
||||
};
|
||||
|
||||
export const isDateTimeType = (field: OneOf) => {
|
||||
return field.type in dateTimeComponent;
|
||||
}
|
||||
|
||||
const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
|
||||
TIME: 'time',
|
||||
DATE: 'date',
|
||||
@@ -112,7 +109,8 @@ const dateTimeComponent: Partial<Record<FieldType, ComponentType>> = {
|
||||
}
|
||||
|
||||
export type ComponentType = keyof typeof component;
|
||||
export const getComponent = (value: ConditionValue) => {
|
||||
export const getComponent = (value: ConditionValue, fieldObj: OneOf) => {
|
||||
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) => {
|
||||
const fields = (await client.app.getFormFields({ app: appId })).properties;
|
||||
return {
|
||||
fields: (await client.app.getFormFields({ app: appId })).properties,
|
||||
fields: flatFields(fields),
|
||||
layout: (await client.app.getFormLayout({ app: appId })).layout,
|
||||
} 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 Param = {
|
||||
subTableCode: string | undefined;
|
||||
@@ -77,10 +92,19 @@ type Param = {
|
||||
dependFilterField?: OneOf;
|
||||
defaultLabel?: string;
|
||||
defaultDisableCallback?: (field: OneOf) => boolean;
|
||||
needSubTableField?: boolean;
|
||||
};
|
||||
export const getFieldsDropdownItems = (
|
||||
{ fields, layout }: FieldsInfo,
|
||||
{ subTableCode, filterType, baseFilter, dependFilterField, defaultLabel, defaultDisableCallback }: Param,
|
||||
{
|
||||
subTableCode,
|
||||
filterType,
|
||||
baseFilter,
|
||||
dependFilterField,
|
||||
defaultLabel,
|
||||
defaultDisableCallback,
|
||||
needSubTableField = true,
|
||||
}: Param,
|
||||
) => {
|
||||
// get used field codes
|
||||
let fieldOrder: string[];
|
||||
@@ -96,7 +120,7 @@ export const getFieldsDropdownItems = (
|
||||
const subTableFieldMap = fieldMap[subTableCode] as { fields: Record<string, any> } | undefined;
|
||||
fieldMap = subTableFieldMap?.fields || {};
|
||||
} else {
|
||||
fieldOrder = extractNoSubTableFields(layout, baseFilter);
|
||||
fieldOrder = extractNoSubTableFields(layout, baseFilter, !!needSubTableField);
|
||||
}
|
||||
|
||||
// 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) => {
|
||||
if (each.type === 'SUBTABLE') {
|
||||
return acc;
|
||||
} else if (each.type === 'ROW') {
|
||||
if (each.type === 'GROUP') {
|
||||
acc.push(...extractNoSubTableFields(each.layout, baseFilter, needSubTableField));
|
||||
} else if (each.type === 'ROW' || (needSubTableField && each.type === 'SUBTABLE')) {
|
||||
acc.push(
|
||||
...each.fields.map((field: any) => {
|
||||
...each.fields.map((field) => {
|
||||
if (!('code' in field)) return '';
|
||||
if (!baseFilter) return field.code;
|
||||
return baseFilter.find((t) => t === field.type) ? field?.code || '' : '';
|
||||
}),
|
||||
);
|
||||
} else if (each.type === 'GROUP') {
|
||||
acc.push(...extractNoSubTableFields(each.layout, baseFilter));
|
||||
}
|
||||
return acc;
|
||||
}, [] as string[]);
|
||||
|
||||
@@ -2,6 +2,8 @@ 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<FieldType = string> {
|
||||
id: string;
|
||||
leftField: FieldType;
|
||||
@@ -59,4 +61,9 @@ export type RecordForParameter = {
|
||||
export type Field={
|
||||
type:string;
|
||||
value:any;
|
||||
}
|
||||
|
||||
export type FieldLayout={
|
||||
type:string;
|
||||
code:string;
|
||||
}
|
||||
Reference in New Issue
Block a user