diff --git a/plugin/kintone-addins/src/actions/data-mapping.ts b/plugin/kintone-addins/src/actions/data-mapping.ts new file mode 100644 index 0000000..c082d5b --- /dev/null +++ b/plugin/kintone-addins/src/actions/data-mapping.ts @@ -0,0 +1,182 @@ +import { + IAction, + IActionResult, + IActionNode, + IActionProperty, + IContext, +} from "../types/ActionTypes"; +import { actionAddins } from "."; + +export type IApp = { + id: string; + name: string; +}; +export type IField = { + name: string; + code: string; + type: string; +}; + +export type IAppFields = { + app?: IApp; + fields: IField[]; +}; + +type ValueType = { + id: string; + from: { + objectType: "variable" | "field"; + name: { name: string }; + code: string; + }; + to: IAppFields & { + isDialogVisible: boolean; + }; +}; + +type Props = { app: IApp; field: ValueType[] }; + +export class DataMappingAction implements IAction { + name: string; + actionProps: IActionProperty[]; + dataMappingProps: Props; + constructor() { + this.name = "DataMapping"; + this.actionProps = []; + this.dataMappingProps = {} as Props; + this.register(); + } + + async process( + prop: IActionNode, + event: any, + context: IContext + ): Promise { + this.initActionProps(prop); + this.initTypedActionProps(); + let result = { + canNext: true, + result: "", + } as IActionResult; + try { + for (const item of this.dataMappingProps.field) { + if (item.from.objectType === "variable") { + if ( + item.from.name.name && + item.to.app && + item.to.fields && + item.to.fields.length > 0 + ) { + const value = getValueByPath( + context.variables, + item.from.name.name + ); + if (value) { + await kintone.api( + kintone.api.url("/k/v1/record.json", true), + "POST", + { + app: item.to.app.id, + record: { + [item.to.fields[0].code]: { + value: value, + }, + }, + } + ); + } + } + } else if (item.from.objectType === "field") { + if ( + item.from.code && + item.to.app && + item.to.fields && + item.to.fields.length > 0 + ) { + const value = await selectData( + item.to.app.id, + item.to.fields[0].code + ); + if (value && value.type === context.record[item.from.code].type) { + await kintone.api( + kintone.api.url("/k/v1/records.json", true), + "POST", + { + app: item.to.app.id, + records: value.value.map((v) => ({ + [item.to.fields[0].code]: { + value: v, + }, + })), + } + ); + } + } + } + } + } catch (error) { + console.error("DataMappingAction error", error); + result.canNext = false; + } + console.log("dataMappingProps", this.dataMappingProps); + + return result; + } + + private initActionProps(nodes: IActionNode) { + this.actionProps = nodes.actionProps; + } + private initTypedActionProps() { + for (const action of this.actionProps) { + if (action.component === "DataMapping") { + this.dataMappingProps.field = action.props.modelValue as ValueType[]; + } else if (action.component === "AppSelect") { + this.dataMappingProps.app = action.props.modelValue.app as IApp; + } + } + } + + register(): void { + actionAddins[this.name] = this; + } +} + +new DataMappingAction(); + +const getValueByPath = (obj: any, path: string) => { + return path.split(".").reduce((o, k) => (o || {})[k], obj); +}; + +type Resp = { records: RespRecordType[] }; + +type RespRecordType = { + [key: string]: { + type: string; + value: any; + }; +}; + +type Result = { + type: string; + value: any[]; +}; + +const selectData = async (appid: string, field: string): Promise => { + return kintone + .api(kintone.api.url("/k/v1/records", true), "GET", { + app: appid ?? kintone.app.getId(), + fields: [field], + }) + .then((resp: Resp) => { + const result: Result = { type: "", value: [] }; + resp.records.forEach((element) => { + for (const [key, value] of Object.entries(element)) { + if (result.type === "") { + result.type = value.type; + } + result.value.push(value.value); + } + }); + return result; + }); +}; diff --git a/plugin/kintone-addins/src/types/action-process.ts b/plugin/kintone-addins/src/types/action-process.ts index 2bf094c..6d2c972 100644 --- a/plugin/kintone-addins/src/types/action-process.ts +++ b/plugin/kintone-addins/src/types/action-process.ts @@ -7,6 +7,7 @@ import '../actions/error-show'; import '../actions/button-add'; import '../actions/condition-action'; import '../actions/data-processing'; +import '../actions/data-mapping'; import { ActionFlow,IActionFlow, IActionResult,IContext } from "./ActionTypes"; export class ActionProcess{