From 58ad3571cd7d3fa4e88c01bc29671022da04c6e5 Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 22 Jan 2025 23:37:31 +0800 Subject: [PATCH 1/2] Add condition part --- vue-project/my-kintone-plugin/components.d.ts | 5 ++- .../src/components/Config.vue | 4 +- .../src/components/basic/PluginTableArea.vue | 22 +++++++--- .../basic/PluginTableConditionRow.vue | 37 +++++++++-------- .../basic/PluginTableConnectRow.vue | 10 ++--- .../basic/{condition => }/TableCombobox.vue | 11 +++-- .../components/basic/condition/TableInput.vue | 22 ---------- .../basic/conditions/TableCondition.vue | 35 ++++++++++++++++ .../basic/conditions/TableConditionValue.vue | 38 ++++++++++++++++++ .../my-kintone-plugin/src/js/conditions.ts | 40 +++++++++++++------ .../my-kintone-plugin/src/js/helper.ts | 40 ++++++++++--------- .../src/js/kintone-rest-api-client.ts | 12 +++--- .../my-kintone-plugin/src/types/model.d.ts | 2 +- 13 files changed, 186 insertions(+), 92 deletions(-) rename vue-project/my-kintone-plugin/src/components/basic/{condition => }/TableCombobox.vue (57%) delete mode 100644 vue-project/my-kintone-plugin/src/components/basic/condition/TableInput.vue create mode 100644 vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue create mode 100644 vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue diff --git a/vue-project/my-kintone-plugin/components.d.ts b/vue-project/my-kintone-plugin/components.d.ts index 7455103..809b8ed 100644 --- a/vue-project/my-kintone-plugin/components.d.ts +++ b/vue-project/my-kintone-plugin/components.d.ts @@ -17,7 +17,8 @@ declare module 'vue' { PluginTableArea: typeof import('./src/components/basic/PluginTableArea.vue')['default'] PluginTableConditionRow: typeof import('./src/components/basic/PluginTableConditionRow.vue')['default'] PluginTableConnectRow: typeof import('./src/components/basic/PluginTableConnectRow.vue')['default'] - TableCombobox: typeof import('./src/components/basic/condition/TableCombobox.vue')['default'] - TableInput: typeof import('./src/components/basic/condition/TableInput.vue')['default'] + TableCombobox: typeof import('./src/components/basic/TableCombobox.vue')['default'] + TableCondition: typeof import('./src/components/basic/conditions/TableCondition.vue')['default'] + TableConditionValue: typeof import('./src/components/basic/conditions/TableConditionValue.vue')['default'] } } diff --git a/vue-project/my-kintone-plugin/src/components/Config.vue b/vue-project/my-kintone-plugin/src/components/Config.vue index 70c1be0..29d5d37 100644 --- a/vue-project/my-kintone-plugin/src/components/Config.vue +++ b/vue-project/my-kintone-plugin/src/components/Config.vue @@ -33,7 +33,7 @@ const data: SavedData = reactive({ const cachedData: CachedData = reactive({ apps: [EMPTY_OPTION], - currentAppFields: { fields: [], layout: [] } as FieldsInfo, + currentAppFields: { fields: {}, layout: [] } as FieldsInfo, }); provide('savedData', data); @@ -45,6 +45,7 @@ const spinner = shallowRef(null); onMounted(async () => { spinner.value?.close(); // 修复不自动挂载到节点的 bug const savedData = kintone.plugin.app.getConfig(props.pluginId); + // TODO data.buttonName = savedData?.buttonName || '集約'; data.joinTables = savedData?.joinTables ? JSON.parse(savedData.joinTables) : [createEmptyJoinTable()]; nextTick(async () => { @@ -62,7 +63,6 @@ watch(loading, (load) => { watch( () => data.joinTables.length, (newLength) => { - console.log(data.joinTables); if (newLength === 1) { data.joinTables[0].onConditions = [getEmptyOnCondition()]; } 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 302676b..fc2fbd2 100644 --- a/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue +++ b/vue-project/my-kintone-plugin/src/components/basic/PluginTableArea.vue @@ -5,7 +5,13 @@ - + @@ -27,11 +33,17 @@ 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 new file mode 100644 index 0000000..d957b09 --- /dev/null +++ b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableCondition.vue @@ -0,0 +1,35 @@ + + + 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 new file mode 100644 index 0000000..fad7907 --- /dev/null +++ b/vue-project/my-kintone-plugin/src/components/basic/conditions/TableConditionValue.vue @@ -0,0 +1,38 @@ + + + diff --git a/vue-project/my-kintone-plugin/src/js/conditions.ts b/vue-project/my-kintone-plugin/src/js/conditions.ts index a2e592a..847b2f8 100644 --- a/vue-project/my-kintone-plugin/src/js/conditions.ts +++ b/vue-project/my-kintone-plugin/src/js/conditions.ts @@ -1,14 +1,8 @@ -import TableCombobox from '@/components/basic/condition/TableCombobox.vue'; -import TableInput from '@/components/basic/condition/TableInput.vue'; +import type { FieldsInfo } from '@/types/model'; +import type { FieldType } from './kintone-rest-api-client'; -const component = { - '': undefined, - input: TableInput, - select: TableCombobox, -}; -export type ComponentType = keyof typeof component; - -export type ConditionValue = '' | 'eq' | 'ne'; +// Condition +export type ConditionValue = '' | 'eq' | 'ne' | 'test'; type ConditionItem = { value: ConditionValue; @@ -21,10 +15,9 @@ export const conditionList: ConditionItem[] = [ { value: '', label: '--------', type: '', func: (a: string, b: string) => true }, { value: 'eq', label: '=(等しい)', type: 'input', func: (a: string, b: string) => a === b }, { value: 'ne', label: '≠ (等しくない)', type: 'input', func: (a: string, b: string) => a !== b }, + { value: 'test', label: 'test combobox', type: 'select', func: (a: string, b: string) => a < b }, ]; -// type ConditionItem = (typeof conditionList)[number]; - export const conditionMap: Record = conditionList.reduce( (map, item) => { map[item.value] = item; @@ -33,6 +26,29 @@ export const conditionMap: Record = conditionList {} as Record, ); +// Field Type -> Condition +type FieldConditions = Partial>; + +const fieldConditions: FieldConditions = { + SINGLE_LINE_TEXT: ['eq', 'ne'], + NUMBER: ['ne', 'test'], +} as const; + +export const getAvailableCondition = (fieldCode: string, { fields }: FieldsInfo) => { + if (!fieldCode||!fields) return; + const conditions = fieldConditions[fields[fieldCode]?.type] || []; + return conditions.map((condition) => conditionMap[condition]); +}; + +// Condition -> Component + +const component = { + '': undefined, + input: 'kuc-text', + select: 'kuc-combobox', +}; +export type ComponentType = keyof typeof component; export const getComponent = (value: ConditionValue) => { + if (!value) return; return component[conditionMap[value].type]; }; diff --git a/vue-project/my-kintone-plugin/src/js/helper.ts b/vue-project/my-kintone-plugin/src/js/helper.ts index 6647644..2e47cea 100644 --- a/vue-project/my-kintone-plugin/src/js/helper.ts +++ b/vue-project/my-kintone-plugin/src/js/helper.ts @@ -1,14 +1,13 @@ import type { FieldsInfo, JoinTable, WhereCondition } from '@/types/model'; -import { client, isType, type OneOf, type App, type Layout } from './kintone-rest-api-client'; +import { client, isType, type FieldType, type App, type Layout } from './kintone-rest-api-client'; import type { DropdownItem } from 'kintone-ui-component'; - export const EMPTY_OPTION = { value: '', label: '--------', } as DropdownItem; -export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '' } as WhereCondition); +export const getEmptyWhereCondition = () => ({ field: '', condition: '', data: '' }) as WhereCondition; export const getEmptyOnCondition = () => ({ leftField: '', rightField: '' }); export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '' }); @@ -50,10 +49,10 @@ export const loadAppFieldsAndLayout = async (appId: string | number = kintone.ap } as FieldsInfo; }; +type Param = { subTableCode?: string; filterType?: FieldType; defaultLabel?: string }; export const getFieldsDropdownItems = ( { fields, layout }: FieldsInfo, - subTableCode?: string, - filterType?: OneOf['type'], + { subTableCode, filterType, defaultLabel }: Param = {}, ) => { // get used field codes let fieldOrder: string[]; @@ -61,26 +60,31 @@ export const getFieldsDropdownItems = ( if (subTableCode) { const subTableFields = layout.find((each) => each.type === 'SUBTABLE' && each.code === subTableCode) as any; fieldOrder = subTableFields?.fields.map((field: { code: string }) => field.code) || []; - fieldMap = fieldMap[subTableCode].fields; + const subTableFieldMap = fieldMap[subTableCode] as { fields: Record } | undefined; + fieldMap = subTableFieldMap?.fields || {}; } else { fieldOrder = extractNoSubTableFields(layout); } + // create labels - return fieldOrder.reduce( - (acc, fieldCode) => { - const field = fieldMap[fieldCode]; - if (!fieldCode || filterType && !isType[filterType](field)) return acc; - acc.push({ - value: fieldCode, - label: field.label + '(FC: ' + fieldCode + ')', - }); - return acc; + const labels = [ + { + value: EMPTY_OPTION.value, + label: defaultLabel || EMPTY_OPTION.label, }, - [EMPTY_OPTION], - ); + ]; + return fieldOrder.reduce((acc, fieldCode) => { + const field = fieldMap[fieldCode]; + if (!fieldCode || (filterType && !isType[filterType](field))) return acc; + acc.push({ + value: fieldCode, + label: field.label + '(FC: ' + fieldCode + ')', + }); + return acc; + }, labels); }; -export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?: OneOf['type']) => { +export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?: FieldType) => { return Object.keys(fields).reduce( (acc, fieldCode) => { const field = fields[fieldCode]; 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 cf59117..43f1ad9 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 @@ -9,7 +9,9 @@ export type App = { export type Properties = Awaited>['properties']; export type Layout = Awaited>['layout']; -export type OneOf = Properties[string]; + +type OneOf = Properties[string]; +export type FieldType = OneOf['type']; const typeNames = [ 'RECORD_NUMBER', @@ -40,7 +42,7 @@ const typeNames = [ 'GROUP', 'REFERENCE_TABLE', 'SUBTABLE', -] as const satisfies readonly OneOf['type'][]; +] as const satisfies readonly FieldType[]; export const types = typeNames.reduce( (acc, name) => { @@ -50,11 +52,11 @@ export const types = typeNames.reduce( {} as Record<(typeof typeNames)[number], (typeof typeNames)[number]>, ); -type ExtractOneOf = Extract; -function createTypeGuard(type: T) { +type ExtractOneOf = Extract; +function createTypeGuard(type: T) { return (value: OneOf): value is ExtractOneOf => value.type === type; } export const isType = Object.fromEntries( - typeNames.map((typeName) => [typeName, createTypeGuard(typeName as OneOf['type'])]), + typeNames.map((typeName) => [typeName, createTypeGuard(typeName as FieldType)]), ) as { [K in (typeof typeNames)[number]]: (value: OneOf) => value is ExtractOneOf }; 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 c5cd67c..e35fdfa 100644 --- a/vue-project/my-kintone-plugin/src/types/model.d.ts +++ b/vue-project/my-kintone-plugin/src/types/model.d.ts @@ -1,5 +1,5 @@ import type { ConditionValue } from '@/js/conditions'; -import type { Layout } from '@/js/kintone-rest-api-client'; +import type { Layout, Properties } from '@/js/kintone-rest-api-client'; import type { DropdownItem } from 'kintone-ui-component'; export interface FieldsJoinMapping { From e022cb5d89aa9dd849ca01b383a1b8e118a9d025 Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 22 Jan 2025 23:50:54 +0800 Subject: [PATCH 2/2] add comment --- vue-project/my-kintone-plugin/src/js/conditions.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/vue-project/my-kintone-plugin/src/js/conditions.ts b/vue-project/my-kintone-plugin/src/js/conditions.ts index 847b2f8..f80cd68 100644 --- a/vue-project/my-kintone-plugin/src/js/conditions.ts +++ b/vue-project/my-kintone-plugin/src/js/conditions.ts @@ -1,7 +1,9 @@ import type { FieldsInfo } from '@/types/model'; import type { FieldType } from './kintone-rest-api-client'; -// Condition +// conditionValue = '' | 'eq' | 'ne' +// conditionItem = { value: 'eq', label: '=(等しい)', type: 'input', func: (a: string, b: string) => a === b } +// = conditionMap[conditionValue] export type ConditionValue = '' | 'eq' | 'ne' | 'test'; type ConditionItem = { @@ -18,6 +20,8 @@ export const conditionList: ConditionItem[] = [ { value: 'test', label: 'test combobox', type: 'select', func: (a: string, b: string) => a < b }, ]; +// search from conditionList +// conditionItem = conditionMap[conditionValue] export const conditionMap: Record = conditionList.reduce( (map, item) => { map[item.value] = item; @@ -26,22 +30,21 @@ export const conditionMap: Record = conditionList {} as Record, ); -// Field Type -> Condition type FieldConditions = Partial>; +// FieldType -> ConditionValue[] const fieldConditions: FieldConditions = { SINGLE_LINE_TEXT: ['eq', 'ne'], NUMBER: ['ne', 'test'], } as const; +// fieldCode -> conditionList: ConditionItem[] export const getAvailableCondition = (fieldCode: string, { fields }: FieldsInfo) => { - if (!fieldCode||!fields) return; + if (!fieldCode || !fields) return; const conditions = fieldConditions[fields[fieldCode]?.type] || []; return conditions.map((condition) => conditionMap[condition]); }; -// Condition -> Component - const component = { '': undefined, input: 'kuc-text',