feat: improve collection hooks/fields/actions/views... (#30)
* feat: add onFinish callback * fix: update json attribute unsaved after query * refactor: collection hooks * feat: add migrate options
This commit is contained in:
		
							parent
							
								
									1980464f63
								
							
						
					
					
						commit
						3e3cb416b6
					
				@ -166,7 +166,7 @@ const data = {
 | 
			
		||||
  const tables = database.getTables([]);
 | 
			
		||||
 | 
			
		||||
  for (let table of tables) {
 | 
			
		||||
    await Collection.import(table.getOptions(), { hooks: false });
 | 
			
		||||
    await Collection.import(table.getOptions(), { migrate: false });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const Page = database.getModel('pages');
 | 
			
		||||
 | 
			
		||||
@ -5,15 +5,15 @@ import ViewFactory from '@/components/views';
 | 
			
		||||
export function Create(props) {
 | 
			
		||||
  console.log(props);
 | 
			
		||||
  const { title, viewName, collection_name } = props.schema;
 | 
			
		||||
  const { activeTab = {}, item = {} } = props;
 | 
			
		||||
  const { activeTab = {}, item = {}, associatedName, associatedKey } = props;
 | 
			
		||||
  const { association  } = activeTab;
 | 
			
		||||
 | 
			
		||||
  const params = {};
 | 
			
		||||
 | 
			
		||||
  if (association) {
 | 
			
		||||
    params['resourceName'] = association;
 | 
			
		||||
    params['associatedName'] = activeTab.collection_name;
 | 
			
		||||
    params['associatedKey'] = item.itemId;
 | 
			
		||||
    params['associatedName'] = associatedName;
 | 
			
		||||
    params['associatedKey'] = associatedKey;
 | 
			
		||||
  } else {
 | 
			
		||||
    params['resourceName'] = collection_name;
 | 
			
		||||
    params['resourceKey'] = item.itemId;
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ export function Update(props) {
 | 
			
		||||
        {...props}
 | 
			
		||||
        reference={drawerRef}
 | 
			
		||||
        viewName={viewName}
 | 
			
		||||
        mode={'update'}
 | 
			
		||||
        {...params}
 | 
			
		||||
      />
 | 
			
		||||
      <Button type={'primary'} onClick={() => {
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@ export function Details(props: any) {
 | 
			
		||||
    associatedKey,
 | 
			
		||||
    resourceKey,
 | 
			
		||||
  } = props;
 | 
			
		||||
  const { data = {}, loading } = useRequest(() => {
 | 
			
		||||
  const { data = {}, loading, refresh } = useRequest(() => {
 | 
			
		||||
    const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
 | 
			
		||||
    return api.resource(name).get({
 | 
			
		||||
      resourceKey,
 | 
			
		||||
@ -26,7 +26,9 @@ export function Details(props: any) {
 | 
			
		||||
  const { actions = [], fields = [] } = props.schema;
 | 
			
		||||
  return (
 | 
			
		||||
    <Card bordered={false}>
 | 
			
		||||
      <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
      <Actions {...props} onFinish={() => {
 | 
			
		||||
        refresh();
 | 
			
		||||
      }} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
      {loading ? <Spin/> : (
 | 
			
		||||
        <Descriptions bordered column={1}>
 | 
			
		||||
          {fields.map((field: any) => {
 | 
			
		||||
 | 
			
		||||
@ -27,10 +27,14 @@ export const DrawerForm = forwardRef((props: any, ref) => {
 | 
			
		||||
    resourceName,
 | 
			
		||||
    associatedName,
 | 
			
		||||
    associatedKey,
 | 
			
		||||
    onFinish,
 | 
			
		||||
  } = props;
 | 
			
		||||
  console.log(associatedKey);
 | 
			
		||||
  const [resourceKey, setResourceKey] = useState(props.resourceKey);
 | 
			
		||||
  const [visible, setVisible] = useState(false);
 | 
			
		||||
  const { data, run, loading } = useRequest((resourceKey) => {
 | 
			
		||||
  const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
 | 
			
		||||
  const { data, run, loading } = useRequest((resourceKey) => {
 | 
			
		||||
    setResourceKey(resourceKey);
 | 
			
		||||
    return api.resource(name).get({
 | 
			
		||||
      resourceKey,
 | 
			
		||||
      associatedKey,
 | 
			
		||||
@ -44,7 +48,7 @@ export const DrawerForm = forwardRef((props: any, ref) => {
 | 
			
		||||
  }));
 | 
			
		||||
  const actions = createAsyncFormActions();
 | 
			
		||||
  const { title, fields: properties ={} } = props.schema||{};
 | 
			
		||||
  console.log({properties});
 | 
			
		||||
  console.log({onFinish});
 | 
			
		||||
  return (
 | 
			
		||||
    <Drawer
 | 
			
		||||
      {...props}
 | 
			
		||||
@ -57,8 +61,22 @@ export const DrawerForm = forwardRef((props: any, ref) => {
 | 
			
		||||
      title={title}
 | 
			
		||||
      footer={[
 | 
			
		||||
        <Button type={'primary'} onClick={async () => {
 | 
			
		||||
          const values = await actions.submit();
 | 
			
		||||
          const { values = {} } = await actions.submit();
 | 
			
		||||
          console.log(values);
 | 
			
		||||
          if (resourceKey) {
 | 
			
		||||
            await api.resource(name).update({
 | 
			
		||||
              resourceKey,
 | 
			
		||||
              associatedKey,
 | 
			
		||||
              ...values,
 | 
			
		||||
            });
 | 
			
		||||
          } else {
 | 
			
		||||
            await api.resource(name).create({
 | 
			
		||||
              associatedKey,
 | 
			
		||||
              ...values,
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
          setVisible(false);
 | 
			
		||||
          onFinish && onFinish(values);
 | 
			
		||||
        }}>提交</Button>
 | 
			
		||||
      ]}
 | 
			
		||||
    >
 | 
			
		||||
 | 
			
		||||
@ -64,9 +64,17 @@ export function SimpleTable(props: SimpleTableProps) {
 | 
			
		||||
  console.log('rowViewName', {rowViewName})
 | 
			
		||||
  return (
 | 
			
		||||
    <Card bordered={false}>
 | 
			
		||||
      <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
      <Actions
 | 
			
		||||
        {...props}
 | 
			
		||||
        style={{ marginBottom: 14 }}
 | 
			
		||||
        actions={actions}
 | 
			
		||||
        onFinish={() => {
 | 
			
		||||
          refresh();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <ViewFactory
 | 
			
		||||
        {...props}
 | 
			
		||||
        mode={'update'}
 | 
			
		||||
        viewName={rowViewName}
 | 
			
		||||
        reference={drawerRef}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
@ -80,7 +80,14 @@ export function Table(props: TableProps) {
 | 
			
		||||
  }
 | 
			
		||||
  return (
 | 
			
		||||
    <Card bordered={false}>
 | 
			
		||||
      <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
      <Actions
 | 
			
		||||
        {...props}
 | 
			
		||||
        style={{ marginBottom: 14 }}
 | 
			
		||||
        actions={actions}
 | 
			
		||||
        onFinish={() => {
 | 
			
		||||
          refresh();
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <AntdTable 
 | 
			
		||||
        rowKey={rowKey}
 | 
			
		||||
        columns={fields2columns(fields)}
 | 
			
		||||
 | 
			
		||||
@ -45,12 +45,14 @@ export default function ViewFactory(props: ViewProps) {
 | 
			
		||||
    associatedKey,
 | 
			
		||||
    resourceName,
 | 
			
		||||
    viewName,
 | 
			
		||||
    mode,
 | 
			
		||||
    reference,
 | 
			
		||||
  } = props;
 | 
			
		||||
  const { data = {}, loading } = useRequest(() => {
 | 
			
		||||
    const params = {
 | 
			
		||||
      resourceKey: viewName,
 | 
			
		||||
      associatedName: associatedName,
 | 
			
		||||
      mode,
 | 
			
		||||
    };
 | 
			
		||||
    return api.resource(resourceName).getView(params);
 | 
			
		||||
  }, {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import Database, { ModelCtor } from '@nocobase/database';
 | 
			
		||||
import { getDatabase } from '.';
 | 
			
		||||
import BaseModel from '../models/base';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
describe('base model', () => {
 | 
			
		||||
  let database: Database;
 | 
			
		||||
@ -21,6 +22,11 @@ describe('base model', () => {
 | 
			
		||||
          name: 'title',
 | 
			
		||||
          type: 'virtual',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: 'xyz',
 | 
			
		||||
          type: 'virtual',
 | 
			
		||||
          defaultValue: 'xyz1',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: 'content',
 | 
			
		||||
          type: 'virtual',
 | 
			
		||||
@ -92,6 +98,7 @@ describe('base model', () => {
 | 
			
		||||
        bb: 'bb',
 | 
			
		||||
      },
 | 
			
		||||
      bcd: 'bbb',
 | 
			
		||||
      xyz: "xyz1",
 | 
			
		||||
      arr: [{a: 'a'}, {b: 'b'}],
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
@ -189,4 +196,64 @@ describe('base model', () => {
 | 
			
		||||
    });
 | 
			
		||||
    expect(test2.get('content')).toBeUndefined();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('update', async () => {
 | 
			
		||||
    const t = await TestModel.create({
 | 
			
		||||
      name: 'name1',
 | 
			
		||||
      // xyz: 'xyz',
 | 
			
		||||
    });
 | 
			
		||||
    await t.update({
 | 
			
		||||
      abc: 'abc',
 | 
			
		||||
    });
 | 
			
		||||
    const t2 = await TestModel.findOne({
 | 
			
		||||
      where: {
 | 
			
		||||
        name: 'name1',
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    expect(t2.get()).toMatchObject({
 | 
			
		||||
      xyz: 'xyz1',
 | 
			
		||||
      abc: 'abc',
 | 
			
		||||
      key2: 'val2',
 | 
			
		||||
      id: 2,
 | 
			
		||||
      name: 'name1',
 | 
			
		||||
    });
 | 
			
		||||
    await t2.update({
 | 
			
		||||
      abc: 'abcdef',
 | 
			
		||||
    });
 | 
			
		||||
    const t3 = await TestModel.findOne({
 | 
			
		||||
      where: {
 | 
			
		||||
        name: 'name1',
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    // 查询之后更新再重新查询
 | 
			
		||||
    expect(t3.get()).toMatchObject({
 | 
			
		||||
      xyz: 'xyz1',
 | 
			
		||||
      abc: 'abcdef',
 | 
			
		||||
      key2: 'val2',
 | 
			
		||||
      id: 2,
 | 
			
		||||
      name: 'name1',
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('update', async () => {
 | 
			
		||||
    const t = await TestModel.create({
 | 
			
		||||
      name: 'name1',
 | 
			
		||||
      xyz: 'xyz',
 | 
			
		||||
    });
 | 
			
		||||
    await t.update({
 | 
			
		||||
      abc: 'abc',
 | 
			
		||||
    });
 | 
			
		||||
    const t2 = await TestModel.findOne({
 | 
			
		||||
      where: {
 | 
			
		||||
        name: 'name1',
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    expect(t2.get()).toMatchObject({
 | 
			
		||||
      xyz: 'xyz',
 | 
			
		||||
      abc: 'abc',
 | 
			
		||||
      key2: 'val2',
 | 
			
		||||
      id: 2,
 | 
			
		||||
      name: 'name1',
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,7 @@ describe('collection hooks', () => {
 | 
			
		||||
    const tables = app.database.getTables([]);
 | 
			
		||||
    for (const table of tables) {
 | 
			
		||||
      const Collection = app.database.getModel('collections');
 | 
			
		||||
      await Collection.import(table.getOptions(), { hooks: false });
 | 
			
		||||
      await Collection.import(table.getOptions(), { migrate: false });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -139,7 +139,7 @@ export default {
 | 
			
		||||
      name: 'component.tooltip',
 | 
			
		||||
      title: '提示信息',
 | 
			
		||||
      component: {
 | 
			
		||||
        type: 'string',
 | 
			
		||||
        type: 'textarea',
 | 
			
		||||
        showInDetail: true,
 | 
			
		||||
        showInForm: true,
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,8 @@
 | 
			
		||||
import CollectionModel from '../models/collection';
 | 
			
		||||
 | 
			
		||||
export default async function (model: CollectionModel) {
 | 
			
		||||
export default async function (model: CollectionModel, options: any = {}) {
 | 
			
		||||
  const { migrate = true } = options;
 | 
			
		||||
  if (migrate) {
 | 
			
		||||
    await model.migrate();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
import CollectionModel from '../models/collection';
 | 
			
		||||
 | 
			
		||||
export default async function (model: CollectionModel) {
 | 
			
		||||
  if (!model.get('name')) {
 | 
			
		||||
    model.setDataValue('name', this.generateName());
 | 
			
		||||
  }
 | 
			
		||||
  model.generateNameIfNull();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,8 @@
 | 
			
		||||
import FieldModel from '../models/field';
 | 
			
		||||
 | 
			
		||||
export default async function (model: FieldModel) {
 | 
			
		||||
  // console.log('afterCreate', model.toJSON());
 | 
			
		||||
export default async function (model: FieldModel, options: any = {}) {
 | 
			
		||||
  const { migrate = true } = options;
 | 
			
		||||
  if (migrate) {
 | 
			
		||||
    await model.migrate();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,28 +1,10 @@
 | 
			
		||||
import FieldModel from '../models/field';
 | 
			
		||||
import * as types from '../interfaces/types';
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
export default async function (model: FieldModel) {
 | 
			
		||||
  const values = model.get();
 | 
			
		||||
  if (!values.name) {
 | 
			
		||||
    values.name = this.generateName();
 | 
			
		||||
  model.generateNameIfNull();
 | 
			
		||||
  if (model.get('interface')) {
 | 
			
		||||
    model.setInterface(model.get('interface'));
 | 
			
		||||
  }
 | 
			
		||||
  if (values.interface) {
 | 
			
		||||
    const { options } = types[values.interface];
 | 
			
		||||
    Object.keys(options).forEach(key => {
 | 
			
		||||
      switch (typeof values[key]) {
 | 
			
		||||
        case 'undefined':
 | 
			
		||||
          values[key] = options[key];
 | 
			
		||||
          break;
 | 
			
		||||
          
 | 
			
		||||
        case 'object':
 | 
			
		||||
          values[key] = {
 | 
			
		||||
            ...options[key],
 | 
			
		||||
            ...values[key]
 | 
			
		||||
          };
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  model.set(values, { raw: true });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -453,6 +453,7 @@ export const json = {
 | 
			
		||||
  options: {
 | 
			
		||||
    interface: 'json',
 | 
			
		||||
    type: 'json',
 | 
			
		||||
    dottie: true,
 | 
			
		||||
    component: {
 | 
			
		||||
      type: 'hidden',
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,9 @@
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import { getDataTypeKey, Model } from '@nocobase/database';
 | 
			
		||||
import { Utils } from 'sequelize';
 | 
			
		||||
 | 
			
		||||
export class BaseModel extends Model {
 | 
			
		||||
 | 
			
		||||
  get additionalAttribute() {
 | 
			
		||||
    const tableOptions = this.database.getTable(this.constructor.name).getOptions();
 | 
			
		||||
    return _.get(tableOptions, 'additionalAttribute') || 'options';
 | 
			
		||||
@ -57,7 +59,7 @@ export class BaseModel extends Model {
 | 
			
		||||
    return _.get(options, key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set(key?: any, value?: any, options?: any) {
 | 
			
		||||
  set(key?: any, value?: any, options: any = {}) {
 | 
			
		||||
    if (typeof key === 'string') {
 | 
			
		||||
      // 不处理关系数据
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
@ -66,10 +68,13 @@ export class BaseModel extends Model {
 | 
			
		||||
      }
 | 
			
		||||
      // 如果是 object 数据,merge 处理
 | 
			
		||||
      if (_.isPlainObject(value)) {
 | 
			
		||||
        value = _.merge(this.get(key)||{}, value);
 | 
			
		||||
        // @ts-ignore
 | 
			
		||||
        value = Utils.merge(this.get(key)||{}, value);
 | 
			
		||||
      }
 | 
			
		||||
      const [column, ...path] = key.split('.');
 | 
			
		||||
      if (!options.raw) {
 | 
			
		||||
        this.changed(column, true);
 | 
			
		||||
      }
 | 
			
		||||
      if (this.hasSetAttribute(column)) {
 | 
			
		||||
        if (!path.length) {
 | 
			
		||||
          return super.set(key, value, options);
 | 
			
		||||
@ -81,7 +86,9 @@ export class BaseModel extends Model {
 | 
			
		||||
      // 如果未设置 attribute,存到 additionalAttribute 里
 | 
			
		||||
      const opts = this.get(this.additionalAttribute, options) || {};
 | 
			
		||||
      _.set(opts, key, value);
 | 
			
		||||
      if (!options.raw) {
 | 
			
		||||
        this.changed(this.additionalAttribute, true);
 | 
			
		||||
      }
 | 
			
		||||
      return super.set(this.additionalAttribute, opts, options);
 | 
			
		||||
    }
 | 
			
		||||
    return super.set(key, value, options);
 | 
			
		||||
@ -94,7 +101,8 @@ export class BaseModel extends Model {
 | 
			
		||||
      return this;
 | 
			
		||||
    }
 | 
			
		||||
    if (_.isPlainObject(value)) {
 | 
			
		||||
      value = _.merge(this.get(key)||{}, value);
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      value = Utils.merge(this.get(key)||{}, value);
 | 
			
		||||
    }
 | 
			
		||||
    const [column, ...path] = key.split('.');
 | 
			
		||||
    this.changed(column, true);
 | 
			
		||||
 | 
			
		||||
@ -1,18 +1,7 @@
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import BaseModel from './base';
 | 
			
		||||
import { TableOptions } from '@nocobase/database';
 | 
			
		||||
import { SaveOptions, Utils } from 'sequelize';
 | 
			
		||||
 | 
			
		||||
export class CollectionModel extends BaseModel {
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 通过 name 获取 collection
 | 
			
		||||
   *
 | 
			
		||||
   * @param name 
 | 
			
		||||
   */
 | 
			
		||||
  static async findByName(name: string) {
 | 
			
		||||
    return this.findOne({ where: { name } });
 | 
			
		||||
  }
 | 
			
		||||
import { SaveOptions } from 'sequelize';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 生成随机数据库表名
 | 
			
		||||
@ -26,10 +15,31 @@ export class CollectionModel extends BaseModel {
 | 
			
		||||
 * 
 | 
			
		||||
 * @param title 显示的名称
 | 
			
		||||
 */
 | 
			
		||||
  static generateName(title?: string): string {
 | 
			
		||||
export function generateCollectionName(title?: string): string {
 | 
			
		||||
  return `t_${Date.now().toString(36)}_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class CollectionModel extends BaseModel {
 | 
			
		||||
 | 
			
		||||
  generateName() {
 | 
			
		||||
    this.set('name', generateCollectionName());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  generateNameIfNull() {
 | 
			
		||||
    if (!this.get('name')) {
 | 
			
		||||
      this.generateName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 通过 name 获取 collection
 | 
			
		||||
   *
 | 
			
		||||
   * @param name 
 | 
			
		||||
   */
 | 
			
		||||
  static async findByName(name: string) {
 | 
			
		||||
    return this.findOne({ where: { name } });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * 迁移
 | 
			
		||||
   */
 | 
			
		||||
@ -80,12 +90,8 @@ export class CollectionModel extends BaseModel {
 | 
			
		||||
        ...item,
 | 
			
		||||
        sort,
 | 
			
		||||
      }));
 | 
			
		||||
      for (const item of items[key]) {
 | 
			
		||||
        await collection[`create${_.upperFirst(Utils.singularize(key))}`](item);
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
    // updateAssociations 有 BUG
 | 
			
		||||
    // await collection.updateAssociations(items, options);
 | 
			
		||||
    await collection.updateAssociations(items, options);
 | 
			
		||||
    return collection;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,30 @@
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
import BaseModel from './base';
 | 
			
		||||
import { FieldOptions } from '@nocobase/database';
 | 
			
		||||
import * as types from '../interfaces/types';
 | 
			
		||||
import { Utils } from 'sequelize';
 | 
			
		||||
 | 
			
		||||
export function generateFieldName(title?: string): string {
 | 
			
		||||
  return `f_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class FieldModel extends BaseModel {
 | 
			
		||||
  static generateName(title?: string): string {
 | 
			
		||||
    return `f_${Math.random().toString(36).replace('0.', '').slice(-4).padStart(4, '0')}`;
 | 
			
		||||
 | 
			
		||||
  generateName() {
 | 
			
		||||
    this.set('name', generateFieldName());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  generateNameIfNull() {
 | 
			
		||||
    if (!this.get('name')) {
 | 
			
		||||
      this.generateName();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setInterface(value) {
 | 
			
		||||
    const { options } = types[value];
 | 
			
		||||
    // @ts-ignore
 | 
			
		||||
    const values = Utils.merge(options, this.get());
 | 
			
		||||
    this.set(values);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async getOptions(): Promise<FieldOptions> {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user