/* eslint-disable @typescript-eslint/no-explicit-any */ import { ActionAttribute, ActionStatus, ActionType } from '../actions/types' import { create } from '../api' import { RootState } from '../store' import { VarDataType } from '../types' import { createAttributeGlobalId, parseAttributeGlobalId } from './attribute' const _lowerCase = (str = '') => String(str).toLowerCase() const oldActionTypeConverter = (type: string): ActionType => { switch (type) { case 'action': return ActionType.ACTION // return ActionType.COMPUTE case 'source': return ActionType.SOURCE case 'filter': return ActionType.FILTER default: return ActionType.ACTION } } const oldDatatypeConverter = (datatype: string): VarDataType => { switch (datatype) { case 'number': return VarDataType.number case 'boolean': return VarDataType.boolean case 'url': return VarDataType.url case 'email': return VarDataType.email case 'file': return VarDataType.file case 'image': return VarDataType.image case 'audio': return VarDataType.audio case 'video': return VarDataType.video case 'text': return VarDataType.text case 'any': return VarDataType.any default: return VarDataType.string } } const oldAttributeConverter = (x: ActionAttribute) => ({ ...x, id: createAttributeGlobalId({ relId: '', name: _lowerCase(x.name), datatype: oldDatatypeConverter(x.datatype), }), datatype: oldDatatypeConverter(x.datatype), }) export const convertSorceAction = ( step: { variables: any rAttributes: any id: any nextId: any position: any action: any name: any options: { [x: string]: any; elements: any } }, services: any[] ) => { const service = services.filter(x => step.action === x.id)[0] const actName = `${step.action}` const action = { id: `${step.action}`, name: actName, type: oldActionTypeConverter(service?.type), metadata: { status: ActionStatus.PUBLISHED, icon: service?.icon, name: service?.name, label: service?.label, description: service?.description, cost: service?.cost, time: service?.time, }, lAttributes: [], pAttributes: ['label', 'layout', 'description'].map(name => ({ id: createAttributeGlobalId({ relId: '', name: name, datatype: VarDataType.string, }), globalId: undefined, name: name, datatype: VarDataType.string, required: true, value: String( step.options && step.options[name as keyof typeof step.options] ), label: `Form ${name}`, description: '', })), rAttributes: (step.options.elements || []).map( (x: { name: string datatype: VarDataType required: any label: any }) => ({ id: createAttributeGlobalId({ relId: '', name: _lowerCase(x.name), datatype: oldDatatypeConverter(x.datatype), }), // globalId: '', name: parseAttributeGlobalId( createAttributeGlobalId({ relId: '', name: _lowerCase(x.name), datatype: oldDatatypeConverter(x.datatype), }) ).name, datatype: oldDatatypeConverter(x.datatype), required: x.required, value: '', label: x.label, description: '', }) ), } const relation = { id: `rel-${step.id}`, actName: step.action, label: step.name, rel: step.nextId ? [`rel-${step.nextId}`] : [], x: step.position[0], y: step.position[1], } const pipeline = { id: `rel-${step.id}`, consume: {}, params: Object.fromEntries( ['label', 'layout', 'description'].map(name => [ createAttributeGlobalId({ relId: '', name: _lowerCase(name), datatype: VarDataType.string, }), String(step.options && step.options[name as keyof typeof step.options]), ]) ), produce: Object.fromEntries( (step.options.elements || []).map((el: { name: any; datatype: any }) => [ createAttributeGlobalId({ relId: `rel-${step.id}`, name: _lowerCase(el.name), datatype: oldDatatypeConverter(el.datatype), }), createAttributeGlobalId({ relId: '', name: _lowerCase(el.name), datatype: oldDatatypeConverter(el.datatype), }), ]) ), } const __legacy_variablesMap = (step.variables || []).reduce( ( acc: object, el: { datatype: string name: string } ) => ({ ...acc, [createAttributeGlobalId({ relId: `rel-${step.id}`, name: _lowerCase(el.name), datatype: oldDatatypeConverter(el.datatype), })]: el.name, }), {} ) return { action, relation, pipeline, __legacy_variablesMap } } export const convertComputeAction = ( step: { lAttributes: string[] rAttributes: string[] action: any name: any options: { [x: string]: any; elements: any } variables: any id: any nextId: any position: any[] }, __legacy_variablesMap: { [key: string]: any }, services: any[], labels: { [key: string]: any } ) => { const service = services.filter(x => step.action === x.id)[0] const actName = `${step.action}` const action = { id: `${step.action}`, name: actName, type: oldActionTypeConverter(service?.type), metadata: { status: ActionStatus.PUBLISHED, icon: service?.icon, name: service?.name || 'Unknown action', label: service?.label || 'unknown', description: service?.description || 'unknown', cost: service?.cost || 0, time: service?.time || 0, }, // WARNING: This right attributes is only that uses in compute action // not those which are originally in action (service has more right attributes) // find action by `step.action` and replace with current action lAttributes: ((service?.lAttributes || []) as ActionAttribute[]).map( oldAttributeConverter ), pAttributes: ((service?.pAttributes || []) as ActionAttribute[]).map( oldAttributeConverter ), // WARNING: This right attributes is only that uses in compute action // not those which are originally in action (service has more right attributes) rAttributes: ((service?.rAttributes || []) as ActionAttribute[]).map( oldAttributeConverter ), } const relation = { id: `rel-${step.id}`, actName: step.action, label: step.name, rel: step.nextId ? [`rel-${step.nextId}`] : [], x: step.position[0], y: step.position[1], } const pipeline = { id: `rel-${step.id}`, consume: Object.fromEntries( (step.lAttributes || []) .map((x: string) => { const [l, r] = x.split('=') return r ? [l, r] : [l, l] }) // ['A', 'searchQuery_'] .map(([leftAttr, rightAttr]) => { const l = action.lAttributes.filter( (act: { name: string }) => act.name === leftAttr )[0] const r = Object.entries(__legacy_variablesMap).filter( ([, value]) => value === rightAttr )[0] || {} return [l ? l.id : leftAttr, r ? r[0] : 'unknown'] }) ), params: Object.fromEntries( action.pAttributes.map(({ name, value, datatype }) => [ createAttributeGlobalId({ relId: '', name: _lowerCase(name), datatype: oldDatatypeConverter(datatype), }), step.options[name] || value, ]) ), produce: Object.fromEntries( (step.rAttributes || []) // [searchResults=text,path=path,page=page"] //[result=$json.DomainInfo.domainAvailability] .map((x: string) => { const [l, r] = x.split('=') return r ? [l, r] : [l, l] }) // ['generatedText2', 'text'] ["global", "local"] .map(([leftAttr, rightAttr]) => { const attr = action.rAttributes.filter(x => x.name === rightAttr)[0] || {} const l = createAttributeGlobalId({ relId: `rel-${step.id}`, name: _lowerCase(rightAttr), datatype: oldDatatypeConverter(attr.datatype), }) const r = createAttributeGlobalId({ relId: '', name: _lowerCase(rightAttr), datatype: oldDatatypeConverter(attr.datatype), }) __legacy_variablesMap[l] = leftAttr const variable = (step.variables || []).filter( (v: { name: string }) => v.name === leftAttr )[0] if (variable && variable.label) { labels[l] = variable.label } return [l || leftAttr, r] }) ), } const __legacy_variablesMap2 = (step.variables || []).reduce( ( acc: object, variable: { label: string; datatype: string; name: string } ) => ({ ...acc, [createAttributeGlobalId({ relId: `rel-${step.id}`, name: _lowerCase(variable.name), datatype: oldDatatypeConverter(variable.datatype), })]: `${variable.name}`, }), __legacy_variablesMap ) return { action, relation, pipeline, labels, __legacy_variablesMap: __legacy_variablesMap2, } } export const convertFilterAction = ( step: { lAttributes: string[] rAttributes: string[] action: any name: any options: { [x: string]: any; elements: any } variables: any id: any nextId: any position: any[] }, __legacy_variablesMap: { [key: string]: any }, services: any[] ) => { const service = services.filter(x => step.action === x.id)[0] // const options = { // filters: [ // ['*', 'cn', 'searchQuery_', 'path', 'v'], // ['*', 'cn', 'osIndex_', 'page', 'v'], // ], // __filters: [ // ['*', 'cn', 'rel-908__searchquery:text', 'rel-909__path:text', 'v'], // ['*', 'cn', 'rel-908__osindex:text', 'rel-909__page:number', 'v'], // ], // } const actName = `${step.action}` const action = { id: `${step.action}`, name: actName, type: oldActionTypeConverter(service?.type), metadata: { status: ActionStatus.PUBLISHED, icon: service?.icon, name: service?.name, label: service?.label, description: service?.description, cost: service?.cost, time: service?.time, }, // WARNING: This right attributes is only that uses in compute action // not those which are originally in action (service has more right attributes) // find action by `step.action` and replace with current action lAttributes: [], pAttributes: ['A', 'B', 'C', 'D', 'E'].map((name, i) => ({ name, datatype: VarDataType.text, required: !i, value: '', label: `Filter ${name}`, description: '', id: createAttributeGlobalId({ relId: '', name: name.toLowerCase(), datatype: VarDataType.text, }), })), // WARNING: This right attributes is only that uses in compute action // not those which are originally in action (service has more right attributes) rAttributes: [], } const relation = { id: `rel-${step.id}`, actName: step.action, label: step.name, rel: step.nextId ? [`rel-${step.nextId}`] : [], x: step.position[0], y: step.position[1], } const params = Object.fromEntries( (step.options.filters || []).map((filter: string[], i: number) => { const l = Object.entries(__legacy_variablesMap).filter( ([, value]) => value === filter[2] )[0] const r = Object.entries(__legacy_variablesMap).filter( ([, value]) => value === filter[3] )[0] filter[2] = l ? l[0] : filter[2] filter[3] = r ? r[0] : filter[3] return [action.pAttributes[i].id, filter.join(';')] }) ) const pipeline = { id: `rel-${step.id}`, consume: {}, params: params, produce: {}, } // { // "__legacy_variablesMap": { // "rel-908__searchquery:text": "searchQuery_", // "rel-908__osindex:text": "osIndex_", // "rel-909__path:text": "path", // "rel-909__page:number": "page", // "rel-909__searchresults:text": "searchResults" // } // } return { action, relation, pipeline, __legacy_variablesMap } } export const convertOutput = ( output: { id: any layout: any label: any elements: any position: any }, __legacy_variablesMap: { [key: string]: any } ) => { let elements: { [key: string]: any } = {} try { const parsed = output.elements as { name: string label: string component: string datatype: string }[] elements = Object.fromEntries( (parsed || []).map((x: { name: any; component: any }) => { const l = Object.entries(__legacy_variablesMap).filter( ([, value]) => value === x.name )[0] return [l[0] || x.name, x.component] }) ) } catch (ex) { elements = {} } return { id: `view-${output.id}`, layout: output.layout, label: output.label, // elements: { // 'rel-908__searchquery:text': 'CardDescription', // 'rel-908__osindex:text': 'CardDescription', // }, elements: elements, position: output.position, } } export const convertOldWorkflowToFlowApplicationData = (payload: { workflow: any steps: any[] outputs: any[] services: any[] }): RootState & { __legacy: any } => { const { workflow, steps, outputs, services } = payload const labels = {} let __legacy_variablesMap = { '$rows__count:number': '_COUNT_', '$rows__index:number': '_INDEX_', } const data: RootState = steps.reduce( (acc: any, step: any) => { let results: any switch (step.type) { case 'action': { results = convertComputeAction( step, __legacy_variablesMap, services, labels ) break } case 'filter': { results = convertFilterAction(step, __legacy_variablesMap, services) break } case 'source': default: { results = convertSorceAction(step, services) break } } __legacy_variablesMap = { ...__legacy_variablesMap, ...results.__legacy_variablesMap, } return { actions: [...acc.actions, results.action], relations: [...acc.relations, results.relation], pipeline: [...acc.pipeline, results.pipeline], labels: { ...acc.labels, ...results.labels }, views: [], } }, { metadata: {}, actions: [], relations: [], pipeline: [], labels: {}, } ) data.metadata = { id: workflow.id, name: workflow.name, description: workflow.description, icon: workflow.iconUrl, tags: workflow.tags, favourite: workflow.favourite, } data.views = outputs.map(x => convertOutput(x, __legacy_variablesMap)) const api = create({ ...data, __legacy: { variables: __legacy_variablesMap }, }) const snapshot = { ...api.getState(), ...api.selectNormalizedState() } return snapshot }