/* eslint-disable no-console */ import { IField, IOptionManager, IOptionManagerOptionsAction, IOptionManagerOptionsArray, IOptionManagerParams } from '@wowpic/xform-types'; import fetch from './fetch'; import { isNull, strEval } from './utils'; export default class OptionManager implements IOptionManager { public nameProperty: string; public valueProperty: string; public action: IOptionManagerOptionsAction; public path: string; public watch: string[]; public defaultIndex?: number; public initialOptions: IOptionManagerOptionsArray; private context: IField; constructor(context: IField, params: IOptionManagerParams) { this.context = context; this.initialize(params); } public async initialize(params: IOptionManagerParams) { const { options } = params; const field = this.context; if (typeof options === 'string') { this.action = options || ''; this.nameProperty = 'name'; this.valueProperty = 'value'; this.path = ''; this.watch = []; field.options = []; await Promise.resolve(); this.initialOptions = await this.getOptions(); } else if (Array.isArray(options)) { this.action = ''; this.nameProperty = 'name'; this.valueProperty = 'value'; this.path = ''; this.watch = []; field.options = options; this.initialOptions = options; this.triggerEvent(); } else if (typeof options === 'object') { this.action = options.action; this.nameProperty = options.nameProperty || 'name'; this.valueProperty = options.valueProperty || 'value'; this.path = options.path || ''; this.watch = options.watch || []; this.defaultIndex = options.defaultIndex; field.options = []; await Promise.resolve(); this.initialOptions = await this.getOptions(); } } private setDefaultItem() { const field = this.context; const defaultIndex = this.defaultIndex; const options = field.options; const value = field.value; if (Number.isInteger(defaultIndex) && options.length > defaultIndex && (isNull(field.value) || !options.find(item => item.value === value))) { const item = options[defaultIndex]; field.setValue(item.value); } } public async getOptions() { const { path, nameProperty, valueProperty, action } = this; const field = this.context; const form = field.context; if (typeof action === 'function') { const options = await action(field, form); field.options = options; this.setDefaultItem(); this.triggerEvent(); return options; } if (typeof action === 'string') { const formPurified = form.purify(); const url = strEval(action, formPurified); try { const data = await fetch(url); const list = path.split('.').reduce((result, index) => { return index ? result[index] : result; }, data); const options = list.map((item: { [key: string]: any }) => { return { ...item, name: item[nameProperty], value: item[valueProperty] }; }); field.options = options; this.setDefaultItem(); this.triggerEvent(); return options; } catch (e) { console.error(e); throw e; } } return []; } public reset() { const field = this.context; field.options = this.initialOptions; field.triggerEvent('OPTIONS_CHANGE'); } private triggerEvent() { const field = this.context; field.triggerEvent('OPTIONS_CHANGE'); } };