From 6aba3fc0653c37826af3d697fb74153407c7f61a Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 22 Jan 2025 13:57:33 +0800 Subject: [PATCH 1/2] Fix load apps --- vue-project/my-kintone-plugin/components.d.ts | 1 + .../src/components/Config.vue | 20 +++-- .../src/components/basic/PluginTableArea.vue | 50 ++++++----- .../basic/PluginTableConditionRow.vue | 17 ++-- .../basic/PluginTableConnectRow.vue | 70 +++++++++------ .../src/components/basic/TableCombobox.vue | 24 ++++++ .../my-kintone-plugin/src/js/helper.ts | 85 +++++++++++++------ .../src/js/kintone-rest-api-client.ts | 1 + .../my-kintone-plugin/src/types/model.d.ts | 21 ++++- vue-project/my-kintone-plugin/vite.config.ts | 1 + 10 files changed, 205 insertions(+), 85 deletions(-) create mode 100644 vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue diff --git a/vue-project/my-kintone-plugin/components.d.ts b/vue-project/my-kintone-plugin/components.d.ts index fb726aa..19c9f84 100644 --- a/vue-project/my-kintone-plugin/components.d.ts +++ b/vue-project/my-kintone-plugin/components.d.ts @@ -17,5 +17,6 @@ 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/TableCombobox.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 154ca55..3a5c1cb 100644 --- a/vue-project/my-kintone-plugin/src/components/Config.vue +++ b/vue-project/my-kintone-plugin/src/components/Config.vue @@ -18,9 +18,9 @@ diff --git a/vue-project/my-kintone-plugin/src/js/helper.ts b/vue-project/my-kintone-plugin/src/js/helper.ts index 22efbe1..4c3f092 100644 --- a/vue-project/my-kintone-plugin/src/js/helper.ts +++ b/vue-project/my-kintone-plugin/src/js/helper.ts @@ -1,6 +1,6 @@ -import type { JoinTable } from '@/types/model'; +import type { FieldsInfo, JoinTable } from '@/types/model'; import type { KucDropdownItem } from '@/types/my-kintone'; -import { client, isType, type App, type Properties, type OneOf } from './kintone-rest-api-client'; +import { client, isType, type OneOf, type App, type Layout } from './kintone-rest-api-client'; export const condition = { unset: '', @@ -18,50 +18,87 @@ export function createEmptyJoinTable(id = Number(new Date())) { } export function resetTable(table: JoinTable) { + table.table = ''; table.whereConditions = [{ field: '', condition: condition.unset, data: '' }]; table.onConditions = [{ leftField: '', rightField: '' }]; table.fieldsMapping = [{ leftField: '', rightField: '' }]; } +export const EMPTY_OPTION = { + value: "", + label: "--------", +} as KucDropdownItem; + const LIMIT = 100; // 每次请求的最大应用数量 -let allAppsCache: KucDropdownItem[] = []; -let allFieldsCache: Properties = {}; -export const fetchApps = async (offset = 0, _apps: KucDropdownItem[] = []): Promise => { - if (allAppsCache.length) return allAppsCache; +export const loadApps = async (offset = 0, _apps: KucDropdownItem[] = []): Promise => { const { apps } = await client.app.getApps({ limit: LIMIT, offset }); const allApps: KucDropdownItem[] = [ ..._apps, ...apps.map((app: App) => ({ value: app.appId, label: app.name + '(ID: ' + app.appId + ')' })), ]; if (apps.length === LIMIT) { - return fetchApps(offset + LIMIT, allApps); + return loadApps(offset + LIMIT, allApps); } - allAppsCache = allApps.sort((a, b) => Number(b.value) - Number(a.value)); + allApps.sort((a, b) => Number(b.value) - Number(a.value)); + allApps.unshift(EMPTY_OPTION); return allApps; }; -export const fetchFields = async (appId: string, filter: OneOf['type']) => { - let properties = allFieldsCache; - if (!allFieldsCache.length) { - properties = (await client.app.getFormFields({ app: appId })).properties; - allFieldsCache = properties; +export const loadAppFieldsAndLayout = async (appId: string | number = kintone.app.getId() as number) => { + return { + fields: (await client.app.getFormFields({ app: appId })).properties, + layout: (await client.app.getFormLayout({ app: appId })).layout, + } as FieldsInfo; +}; + +export const getFieldsDropdownItems = ( + { fields, layout }: FieldsInfo, + subTable?: string, + filterType?: OneOf['type'], +) => { + let fieldOrder: string[]; + if (subTable) { + const subTableFields = layout.find((each) => each.type === 'SUBTABLE' && each.code === subTable) as any; + fieldOrder = subTableFields?.fields.map((field: { code: string }) => field.code) || []; + } else { + fieldOrder = extractNoSubTableFields(layout); } - const labels = Object.keys(properties).reduce((acc, fieldCode) => { - const field = properties[fieldCode]; - if (filter && !isType[filter](field)) return acc; + return fieldOrder.reduce((acc, fieldCode) => { + const field = fields[fieldCode]; + if (filterType && !isType[filterType](field)) return acc; acc.push({ value: fieldCode, label: field.label + '(FC: ' + fieldCode + ')', }); return acc; - }, [] as KucDropdownItem[]); - return labels; + }, [EMPTY_OPTION]); }; -export const getField = (fieldCode: string) => { - const field = allFieldsCache[fieldCode]; - if (isType.SUBTABLE(field)) { - console.log(field.fields); - } - return field; +export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?: OneOf['type']) => { + return Object.keys(fields).reduce((acc, fieldCode) => { + const field = fields[fieldCode]; + if (filterType && !isType[filterType](field)) return acc; + acc.push({ + value: fieldCode, + label: field.label + '(FC: ' + fieldCode + ')', + }); + return acc; + }, [EMPTY_OPTION]); }; + +const extractNoSubTableFields = (layout: Layout) => { + 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)); + } else if (each.type === 'GROUP') { + acc.push(...extractNoSubTableFields(each.layout)); + } + return acc; + }, [] as string[]); +}; + +// if (isType.SUBTABLE(field)) { +// console.log(field.fields); +// } 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 8e11435..cf59117 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 @@ -8,6 +8,7 @@ export type App = { }; export type Properties = Awaited>['properties']; +export type Layout = Awaited>['layout']; export type OneOf = Properties[string]; const typeNames = [ 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 035dab3..7ac164a 100644 --- a/vue-project/my-kintone-plugin/src/types/model.d.ts +++ b/vue-project/my-kintone-plugin/src/types/model.d.ts @@ -1,4 +1,7 @@ +import { Layout } from './../js/kintone-rest-api-client'; +import type { Layout } from '@/js/kintone-rest-api-client'; import { condition } from './helper'; +import type { KucDropdownItem } from './my-kintone'; export interface FieldsJoinMapping { leftField: string; @@ -24,4 +27,20 @@ export interface JoinTable { export interface SavedData { buttonName: string; joinTables: JoinTable[]; -} \ No newline at end of file +} + +export interface FieldsInfo { + fields: Properties; + layout: Layout; +} + +export interface CachedData { + apps: KucDropdownItem[], + currentAppFields: FieldsInfo, +} + +export interface CachedSelectedAppData { + appFields: FieldsInfo, + loading: boolean, + table: JoinTable, +} diff --git a/vue-project/my-kintone-plugin/vite.config.ts b/vue-project/my-kintone-plugin/vite.config.ts index 7c734d5..68449d1 100644 --- a/vue-project/my-kintone-plugin/vite.config.ts +++ b/vue-project/my-kintone-plugin/vite.config.ts @@ -66,6 +66,7 @@ export default defineConfig({ }, }, build: { + sourcemap: 'inline', rollupOptions: { input: { config: path.resolve(__dirname, 'index.html'), From 270940abca5307b0e0e517ae5aa233c67f8a5897 Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 22 Jan 2025 17:23:20 +0800 Subject: [PATCH 2/2] update --- vue-project/my-kintone-plugin/components.d.ts | 3 +- vue-project/my-kintone-plugin/env.d.ts | 8 +- .../src/components/Config.vue | 8 +- .../src/components/basic/PluginTableArea.vue | 10 +- .../basic/PluginTableConditionRow.vue | 107 +++++++++--------- .../basic/PluginTableConnectRow.vue | 20 +--- .../basic/{ => condition}/TableCombobox.vue | 0 .../components/basic/condition/TableInput.vue | 22 ++++ .../my-kintone-plugin/src/js/conditions.ts | 38 +++++++ .../my-kintone-plugin/src/js/helper.ts | 97 +++++++++------- .../my-kintone-plugin/src/types/model.d.ts | 9 +- .../src/types/my-kintone.d.ts | 12 -- 12 files changed, 192 insertions(+), 142 deletions(-) rename vue-project/my-kintone-plugin/src/components/basic/{ => condition}/TableCombobox.vue (100%) create mode 100644 vue-project/my-kintone-plugin/src/components/basic/condition/TableInput.vue create mode 100644 vue-project/my-kintone-plugin/src/js/conditions.ts diff --git a/vue-project/my-kintone-plugin/components.d.ts b/vue-project/my-kintone-plugin/components.d.ts index 19c9f84..7455103 100644 --- a/vue-project/my-kintone-plugin/components.d.ts +++ b/vue-project/my-kintone-plugin/components.d.ts @@ -17,6 +17,7 @@ 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/TableCombobox.vue')['default'] + TableCombobox: typeof import('./src/components/basic/condition/TableCombobox.vue')['default'] + TableInput: typeof import('./src/components/basic/condition/TableInput.vue')['default'] } } diff --git a/vue-project/my-kintone-plugin/env.d.ts b/vue-project/my-kintone-plugin/env.d.ts index 1a06ebe..528bb9b 100644 --- a/vue-project/my-kintone-plugin/env.d.ts +++ b/vue-project/my-kintone-plugin/env.d.ts @@ -1,2 +1,8 @@ /// -/// \ No newline at end of file +/// + +declare module '*.vue' { + import { DefineComponent } from 'vue'; + const component: DefineComponent<{}, {}, any>; + export default component; +} diff --git a/vue-project/my-kintone-plugin/src/components/Config.vue b/vue-project/my-kintone-plugin/src/components/Config.vue index 3a5c1cb..70c1be0 100644 --- a/vue-project/my-kintone-plugin/src/components/Config.vue +++ b/vue-project/my-kintone-plugin/src/components/Config.vue @@ -18,9 +18,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 91fa0d3..309294a 100644 --- a/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue +++ b/vue-project/my-kintone-plugin/src/components/basic/PluginTableConnectRow.vue @@ -1,21 +1,18 @@ diff --git a/vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue b/vue-project/my-kintone-plugin/src/components/basic/condition/TableCombobox.vue similarity index 100% rename from vue-project/my-kintone-plugin/src/components/basic/TableCombobox.vue rename to vue-project/my-kintone-plugin/src/components/basic/condition/TableCombobox.vue diff --git a/vue-project/my-kintone-plugin/src/components/basic/condition/TableInput.vue b/vue-project/my-kintone-plugin/src/components/basic/condition/TableInput.vue new file mode 100644 index 0000000..3437caf --- /dev/null +++ b/vue-project/my-kintone-plugin/src/components/basic/condition/TableInput.vue @@ -0,0 +1,22 @@ + + + diff --git a/vue-project/my-kintone-plugin/src/js/conditions.ts b/vue-project/my-kintone-plugin/src/js/conditions.ts new file mode 100644 index 0000000..a2e592a --- /dev/null +++ b/vue-project/my-kintone-plugin/src/js/conditions.ts @@ -0,0 +1,38 @@ +import TableCombobox from '@/components/basic/condition/TableCombobox.vue'; +import TableInput from '@/components/basic/condition/TableInput.vue'; + +const component = { + '': undefined, + input: TableInput, + select: TableCombobox, +}; +export type ComponentType = keyof typeof component; + +export type ConditionValue = '' | 'eq' | 'ne'; + +type ConditionItem = { + value: ConditionValue; + label: string; + type: ComponentType; + func: (a: string, b: string) => boolean; +}; + +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 }, +]; + +// type ConditionItem = (typeof conditionList)[number]; + +export const conditionMap: Record = conditionList.reduce( + (map, item) => { + map[item.value] = item; + return map; + }, + {} as Record, +); + +export const getComponent = (value: ConditionValue) => { + 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 4c3f092..6647644 100644 --- a/vue-project/my-kintone-plugin/src/js/helper.ts +++ b/vue-project/my-kintone-plugin/src/js/helper.ts @@ -1,38 +1,37 @@ -import type { FieldsInfo, JoinTable } from '@/types/model'; -import type { KucDropdownItem } from '@/types/my-kintone'; +import type { FieldsInfo, JoinTable, WhereCondition } from '@/types/model'; import { client, isType, type OneOf, 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 getEmptyOnCondition = () => ({ leftField: '', rightField: '' }); +export const getEmptyFieldsMapping = () => ({ leftField: '', rightField: '' }); -export const condition = { - unset: '', - eq: '=', -}; export function createEmptyJoinTable(id = Number(new Date())) { - return { - id, - app: '', - table: '', - onConditions: [{ leftField: '', rightField: '' }], - fieldsMapping: [{ leftField: '', rightField: '' }], - whereConditions: [{ field: '', condition: condition.unset, data: '' }], - } as JoinTable; + return resetTable({ id, app: '' } as JoinTable); } export function resetTable(table: JoinTable) { table.table = ''; - table.whereConditions = [{ field: '', condition: condition.unset, data: '' }]; - table.onConditions = [{ leftField: '', rightField: '' }]; - table.fieldsMapping = [{ leftField: '', rightField: '' }]; + return resetConditions(table); } -export const EMPTY_OPTION = { - value: "", - label: "--------", -} as KucDropdownItem; +export function resetConditions(table: JoinTable) { + table.onConditions = [getEmptyOnCondition()]; + table.fieldsMapping = [getEmptyFieldsMapping()]; + table.whereConditions = [getEmptyWhereCondition()]; + return table; +} const LIMIT = 100; // 每次请求的最大应用数量 -export const loadApps = async (offset = 0, _apps: KucDropdownItem[] = []): Promise => { +export const loadApps = async (offset = 0, _apps: DropdownItem[] = []): Promise => { const { apps } = await client.app.getApps({ limit: LIMIT, offset }); - const allApps: KucDropdownItem[] = [ + const allApps: DropdownItem[] = [ ..._apps, ...apps.map((app: App) => ({ value: app.appId, label: app.name + '(ID: ' + app.appId + ')' })), ]; @@ -53,37 +52,47 @@ export const loadAppFieldsAndLayout = async (appId: string | number = kintone.ap export const getFieldsDropdownItems = ( { fields, layout }: FieldsInfo, - subTable?: string, + subTableCode?: string, filterType?: OneOf['type'], ) => { + // get used field codes let fieldOrder: string[]; - if (subTable) { - const subTableFields = layout.find((each) => each.type === 'SUBTABLE' && each.code === subTable) as any; + 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) || []; + fieldMap = fieldMap[subTableCode].fields; } else { fieldOrder = extractNoSubTableFields(layout); } - return fieldOrder.reduce((acc, fieldCode) => { - const field = fields[fieldCode]; - if (filterType && !isType[filterType](field)) return acc; - acc.push({ - value: fieldCode, - label: field.label + '(FC: ' + fieldCode + ')', - }); - return acc; - }, [EMPTY_OPTION]); + // 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; + }, + [EMPTY_OPTION], + ); }; export const getTableFieldsDropdownItems = ({ fields }: FieldsInfo, filterType?: OneOf['type']) => { - return Object.keys(fields).reduce((acc, fieldCode) => { - const field = fields[fieldCode]; - if (filterType && !isType[filterType](field)) return acc; - acc.push({ - value: fieldCode, - label: field.label + '(FC: ' + fieldCode + ')', - }); - return acc; - }, [EMPTY_OPTION]); + return Object.keys(fields).reduce( + (acc, fieldCode) => { + const field = fields[fieldCode]; + if (filterType && !isType[filterType](field)) return acc; + acc.push({ + value: fieldCode, + label: field.label + '(FC: ' + fieldCode + ')', + }); + return acc; + }, + [EMPTY_OPTION], + ); }; const extractNoSubTableFields = (layout: Layout) => { 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 7ac164a..c5cd67c 100644 --- a/vue-project/my-kintone-plugin/src/types/model.d.ts +++ b/vue-project/my-kintone-plugin/src/types/model.d.ts @@ -1,7 +1,6 @@ -import { Layout } from './../js/kintone-rest-api-client'; +import type { ConditionValue } from '@/js/conditions'; import type { Layout } from '@/js/kintone-rest-api-client'; -import { condition } from './helper'; -import type { KucDropdownItem } from './my-kintone'; +import type { DropdownItem } from 'kintone-ui-component'; export interface FieldsJoinMapping { leftField: string; @@ -10,7 +9,7 @@ export interface FieldsJoinMapping { export interface WhereCondition { field: string; - condition: (typeof condition)[keyof typeof condition]; + condition: ConditionValue; data: string; } @@ -35,7 +34,7 @@ export interface FieldsInfo { } export interface CachedData { - apps: KucDropdownItem[], + apps: DropdownItem[], currentAppFields: FieldsInfo, } 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 1c0d110..7e32aee 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,15 +1,3 @@ -// 组件相关 -export interface KucDropdownItem { - label: string; - value: string; - disabled?: boolean; -} - -export interface KucSpinnerEl { - open: function; - close: function; -} - export interface KucEvent { detail: { value: string;