feat: improve plugins (#14)
* feat: delete defined resources * feat: api client * feat: view fields & tab field options & page info... * fix: view type
This commit is contained in:
		
							parent
							
								
									92160d0fe5
								
							
						
					
					
						commit
						9daae13c68
					
				
							
								
								
									
										56
									
								
								packages/app/src/api-client.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								packages/app/src/api-client.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
import { request } from 'umi';
 | 
			
		||||
 | 
			
		||||
interface ResourceProxyConstructor {
 | 
			
		||||
  new <T, H extends object>(target: T, handler: ProxyHandler<H>): H
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ResourceProxy = Proxy as ResourceProxyConstructor;
 | 
			
		||||
 | 
			
		||||
interface Params {
 | 
			
		||||
  resourceKey?: string | number;
 | 
			
		||||
  // resourceName?: string;
 | 
			
		||||
  // associatedName?: string;
 | 
			
		||||
  associatedKey?: string | number;
 | 
			
		||||
  fields?: any;
 | 
			
		||||
  filter?: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Handler {
 | 
			
		||||
  [name: string]: (params?: Params) => Promise<any>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class APIClient {
 | 
			
		||||
  resource(name: string) {
 | 
			
		||||
    return new ResourceProxy<object, Handler>({}, {
 | 
			
		||||
      get(target, method, receiver) {
 | 
			
		||||
        return (params: Params = {}) => {
 | 
			
		||||
          console.log(params);
 | 
			
		||||
          const { associatedKey, resourceKey, ...restParams } = params;
 | 
			
		||||
          let url = `/${name}`;
 | 
			
		||||
          let options: any = {};
 | 
			
		||||
          if (['list', 'get'].indexOf(method as string) !== -1) {
 | 
			
		||||
            options.method = 'get';
 | 
			
		||||
            options.params = restParams;
 | 
			
		||||
          } else {
 | 
			
		||||
            options.method = 'post';
 | 
			
		||||
            options.data = restParams;
 | 
			
		||||
          }
 | 
			
		||||
          if (associatedKey) {
 | 
			
		||||
            url = `/${name.split('.').join(`/${associatedKey}/`)}`;
 | 
			
		||||
          }
 | 
			
		||||
          url += `:${method as string}`;
 | 
			
		||||
          // console.log(name, name.split('.'), associatedKey, name.split('.').join(`/${associatedKey}/`));
 | 
			
		||||
          if (resourceKey) {
 | 
			
		||||
            url += `/${resourceKey}`;
 | 
			
		||||
          }
 | 
			
		||||
          console.log({url, params});
 | 
			
		||||
          return request(url, options);
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const api = new APIClient();
 | 
			
		||||
 | 
			
		||||
export default api;
 | 
			
		||||
@ -2,7 +2,8 @@ import Api from '../../../server/src';
 | 
			
		||||
import dotenv from 'dotenv';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import Database, { Model } from '@nocobase/database';
 | 
			
		||||
import { get } from 'lodash';
 | 
			
		||||
import actions from '../../../actions/src';
 | 
			
		||||
import associated from '../../../actions/src/middlewares/associated';
 | 
			
		||||
 | 
			
		||||
const sync = {
 | 
			
		||||
  force: true,
 | 
			
		||||
@ -34,6 +35,9 @@ const api = Api.create({
 | 
			
		||||
  },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
api.resourcer.use(associated);
 | 
			
		||||
api.resourcer.registerHandlers(actions.associate);
 | 
			
		||||
 | 
			
		||||
const data = {
 | 
			
		||||
  title: '后台应用',
 | 
			
		||||
  path: '/',
 | 
			
		||||
 | 
			
		||||
@ -2,12 +2,19 @@ import React from 'react';
 | 
			
		||||
import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd';
 | 
			
		||||
import { CollectionTabPane } from './CollectionTabPane';
 | 
			
		||||
import { getPathName, redirectTo } from './utils';
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
import { useRequest } from 'umi';
 | 
			
		||||
 | 
			
		||||
export function CollectionSingle(props) {
 | 
			
		||||
  console.log(props);
 | 
			
		||||
  const { item = {} } = props;
 | 
			
		||||
  const { tabs = [] } = props.collection;
 | 
			
		||||
  const activeTab = tabs.find(tab => tab.name == item.tabName)||{};
 | 
			
		||||
  console.log(activeTab);
 | 
			
		||||
  const { data = {} } = useRequest(() => activeTab && api.resource(activeTab.collection_name).getPageInfo({
 | 
			
		||||
    resourceKey: item.itemId,
 | 
			
		||||
  }));
 | 
			
		||||
  console.log(data);
 | 
			
		||||
  if (!activeTab) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
@ -21,7 +28,7 @@ export function CollectionSingle(props) {
 | 
			
		||||
            removeLastItem: true,
 | 
			
		||||
          });
 | 
			
		||||
        }}
 | 
			
		||||
        title={'企业信息库'}
 | 
			
		||||
        title={data.pageTitle}
 | 
			
		||||
        // subTitle="This is a subtitle"
 | 
			
		||||
        extra={[
 | 
			
		||||
          // <Button key="3">Operation</Button>,
 | 
			
		||||
@ -47,7 +54,7 @@ export function CollectionSingle(props) {
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
      <div className={'collection-content'}>
 | 
			
		||||
        <CollectionTabPane {...props} activeTab={activeTab}/>
 | 
			
		||||
        <CollectionTabPane {...props} pageInfo={data} activeTab={activeTab}/>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
@ -4,23 +4,27 @@ import { PageHeader, Tabs, Button, Statistic, Descriptions } from 'antd';
 | 
			
		||||
import { useRequest, request, Spin } from '@nocobase/client';
 | 
			
		||||
 | 
			
		||||
export function CollectionTabPane(props) {
 | 
			
		||||
  const { activeTab = {}, item = {} } = props;
 | 
			
		||||
  const { viewCollectionName, viewName, association, collection_name } = activeTab;
 | 
			
		||||
  const { pageInfo = {}, activeTab = {}, item = {} } = props;
 | 
			
		||||
  const { viewCollectionName, viewName, association, collection_name, field = {} } = activeTab;
 | 
			
		||||
  const { sourceKey = 'id' } = field;
 | 
			
		||||
 | 
			
		||||
  const params = {};
 | 
			
		||||
 | 
			
		||||
  if (association) {
 | 
			
		||||
    params['resourceName'] = association;
 | 
			
		||||
    params['associatedName'] = collection_name;
 | 
			
		||||
    params['associatedKey'] = item.itemId;
 | 
			
		||||
    params['associatedKey'] = pageInfo[sourceKey] || item.itemId;
 | 
			
		||||
  } else {
 | 
			
		||||
    params['resourceName'] = collection_name;
 | 
			
		||||
    params['resourceKey'] = item.itemId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  console.log(activeTab);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <div>
 | 
			
		||||
      <ViewFactory {...props} 
 | 
			
		||||
      <ViewFactory
 | 
			
		||||
        {...props} 
 | 
			
		||||
        viewCollectionName={viewCollectionName} 
 | 
			
		||||
        viewName={viewName}
 | 
			
		||||
        {...params}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import CollectionIndex from './CollectionIndex';
 | 
			
		||||
import CollectionSingle from './CollectionSingle';
 | 
			
		||||
import './style.less';
 | 
			
		||||
import { useRequest, request, Spin } from '@nocobase/client';
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
 | 
			
		||||
export function CollectionLoader(props: any) {
 | 
			
		||||
  let { path, pagepath, collection } = props.match.params;
 | 
			
		||||
@ -24,7 +25,7 @@ export function CollectionLoader(props: any) {
 | 
			
		||||
  }));
 | 
			
		||||
  props.match.params['items'] = items;
 | 
			
		||||
  console.log(props.match, path);
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => request(`/${collection}:getCollection`));
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => api.resource(collection).getCollection());
 | 
			
		||||
 | 
			
		||||
  if (loading) {
 | 
			
		||||
    return <Spin/>;
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,11 @@ import React, { useState } from 'react';
 | 
			
		||||
import { TemplateLoader } from './TemplateLoader';
 | 
			
		||||
import { useRequest, request } from '@nocobase/client';
 | 
			
		||||
import templates from '@/templates';
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
 | 
			
		||||
export function PageLoader(props: any) {
 | 
			
		||||
  const { path } = props.match.params;
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => request('/pages:getRoutes'));
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => api.resource('pages').getRoutes());
 | 
			
		||||
  const [first, setFirst] = useState(true);
 | 
			
		||||
  (window as any).routesReload = async () => {
 | 
			
		||||
    setFirst(false);
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,10 @@
 | 
			
		||||
import React, { useRef } from 'react';
 | 
			
		||||
import React, { useEffect, useRef } from 'react';
 | 
			
		||||
import { Table as AntdTable, Card } from 'antd';
 | 
			
		||||
import { redirectTo } from '@/components/pages/CollectionLoader/utils';
 | 
			
		||||
import { Actions } from '@/components/actions';
 | 
			
		||||
import ViewFactory from '@/components/views';
 | 
			
		||||
import { request, useRequest } from 'umi';
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
 | 
			
		||||
const dataSource = [];
 | 
			
		||||
for (let i = 0; i < 46; i++) {
 | 
			
		||||
@ -32,20 +34,42 @@ const columns = [
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export function SimpleTable(props: any) {
 | 
			
		||||
export interface SimpleTableProps {
 | 
			
		||||
  schema?: any;
 | 
			
		||||
  activeTab?: any;
 | 
			
		||||
  resourceName: string;
 | 
			
		||||
  associatedName?: string;
 | 
			
		||||
  associatedKey?: string;
 | 
			
		||||
  [key: string]: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function SimpleTable(props: SimpleTableProps) {
 | 
			
		||||
  console.log(props);
 | 
			
		||||
  const { activeTab, schema } = props;
 | 
			
		||||
  const { viewCollectionName, rowViewName, actions = [] } = schema;
 | 
			
		||||
  const {
 | 
			
		||||
    activeTab = {},
 | 
			
		||||
    pageInfo = {},
 | 
			
		||||
    schema,
 | 
			
		||||
    resourceName,
 | 
			
		||||
    associatedName,
 | 
			
		||||
    associatedKey,
 | 
			
		||||
  } = props;
 | 
			
		||||
  const { fields, viewCollectionName, rowViewName, actions = [] } = schema;
 | 
			
		||||
  const { sourceKey = 'id' } = activeTab.field||{};
 | 
			
		||||
  const drawerRef = useRef<any>();
 | 
			
		||||
  const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
 | 
			
		||||
  const { data } = useRequest(() => api.resource(name).list({
 | 
			
		||||
    associatedKey,
 | 
			
		||||
  }));
 | 
			
		||||
  console.log(activeTab);
 | 
			
		||||
  return (
 | 
			
		||||
    <Card bordered={false}>
 | 
			
		||||
      <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
      <ViewFactory reference={drawerRef} viewCollectionName={viewCollectionName} viewName={rowViewName}/>
 | 
			
		||||
      <AntdTable dataSource={dataSource} onRow={(data) => ({
 | 
			
		||||
      <AntdTable dataSource={data} onRow={(data) => ({
 | 
			
		||||
        onClick: () => {
 | 
			
		||||
          drawerRef.current.setVisible(true);
 | 
			
		||||
        },
 | 
			
		||||
      })} columns={columns} />
 | 
			
		||||
      })} columns={fields} />
 | 
			
		||||
    </Card>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import { Table } from './Table';
 | 
			
		||||
import { Details } from './Details';
 | 
			
		||||
import { useRequest, request, Spin } from '@nocobase/client';
 | 
			
		||||
import { SimpleTable } from './SimpleTable';
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
 | 
			
		||||
const TEMPLATES = new Map<string, any>();
 | 
			
		||||
 | 
			
		||||
@ -24,10 +25,14 @@ registerView('SimpleTable', SimpleTable);
 | 
			
		||||
registerView('Details', Details);
 | 
			
		||||
 | 
			
		||||
export default function ViewFactory(props) {
 | 
			
		||||
  const { viewCollectionName, viewName, reference } = props;
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => request(`/${viewCollectionName}:getView/${viewName}`), {
 | 
			
		||||
  const { activeTab, viewCollectionName, viewName, reference } = props;
 | 
			
		||||
  console.log({viewCollectionName, viewName});
 | 
			
		||||
  const { data = {}, error, loading, run } = useRequest(() => api.resource(viewCollectionName).getView({
 | 
			
		||||
    resourceKey: viewName,
 | 
			
		||||
  }), {
 | 
			
		||||
    refreshDeps: [viewCollectionName, viewName],
 | 
			
		||||
  });
 | 
			
		||||
  console.log(activeTab);
 | 
			
		||||
  if (loading) {
 | 
			
		||||
    return <Spin/>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -3,16 +3,7 @@ import { Table as AntdTable, Card } from 'antd';
 | 
			
		||||
import { redirectTo } from '@/components/pages/CollectionLoader/utils';
 | 
			
		||||
import { Actions } from '@/components/actions';
 | 
			
		||||
import { request, useRequest } from 'umi';
 | 
			
		||||
 | 
			
		||||
const dataSource = [];
 | 
			
		||||
for (let i = 0; i < 46; i++) {
 | 
			
		||||
  dataSource.push({
 | 
			
		||||
    id: i,
 | 
			
		||||
    name: `Edward King ${i}`,
 | 
			
		||||
    age: 32,
 | 
			
		||||
    address: `London, Park Lane no. ${i}`,
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
import api from '@/api-client';
 | 
			
		||||
 | 
			
		||||
const columns = [
 | 
			
		||||
  {
 | 
			
		||||
@ -32,12 +23,31 @@ const columns = [
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export function Table(props: any) {
 | 
			
		||||
  console.log(props);
 | 
			
		||||
  const { activeTab, schema } = props;
 | 
			
		||||
  const { defaultTabId, defaultTabName, actions = [] } = schema;
 | 
			
		||||
  const { data } = useRequest(() => request('/collections'));
 | 
			
		||||
export interface TableProps {
 | 
			
		||||
  schema?: any;
 | 
			
		||||
  activeTab?: any;
 | 
			
		||||
  resourceName: string;
 | 
			
		||||
  associatedName?: string;
 | 
			
		||||
  associatedKey?: string;
 | 
			
		||||
  [key: string]: any;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function Table(props: TableProps) {
 | 
			
		||||
  const {
 | 
			
		||||
    activeTab = {},
 | 
			
		||||
    schema,
 | 
			
		||||
    resourceName,
 | 
			
		||||
    associatedName,
 | 
			
		||||
    associatedKey,
 | 
			
		||||
  } = props;
 | 
			
		||||
  const { defaultTabId, fields, defaultTabName, rowKey = 'id', actions = [] } = schema;
 | 
			
		||||
  const name = associatedName ? `${associatedName}.${resourceName}` : resourceName;
 | 
			
		||||
  const { data } = useRequest(() => api.resource(name).list({
 | 
			
		||||
    associatedKey,
 | 
			
		||||
  }));
 | 
			
		||||
  const { sourceKey = 'id' } = activeTab.field||{};
 | 
			
		||||
  console.log(data);
 | 
			
		||||
  console.log(activeTab);
 | 
			
		||||
  return (
 | 
			
		||||
    <Card bordered={false}>
 | 
			
		||||
      <Actions {...props} style={{ marginBottom: 14 }} actions={actions}/>
 | 
			
		||||
@ -46,12 +56,12 @@ export function Table(props: any) {
 | 
			
		||||
          redirectTo({
 | 
			
		||||
            ...props.match.params,
 | 
			
		||||
            [activeTab ? 'newItem' : 'lastItem']: {
 | 
			
		||||
              itemId: data.id,
 | 
			
		||||
              itemId: data[rowKey]||data.id,
 | 
			
		||||
              tabName: defaultTabName,
 | 
			
		||||
            },
 | 
			
		||||
          });
 | 
			
		||||
        },
 | 
			
		||||
      })} columns={columns} />
 | 
			
		||||
      })} columns={fields} />
 | 
			
		||||
    </Card>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ export default {
 | 
			
		||||
      actionNames: ['update'],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'simple',
 | 
			
		||||
      type: 'table',
 | 
			
		||||
      name: 'simple',
 | 
			
		||||
      title: '简易模式',
 | 
			
		||||
      template: 'SimpleTable',
 | 
			
		||||
 | 
			
		||||
@ -104,7 +104,7 @@ export default {
 | 
			
		||||
      actionNames: ['update'],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'simple',
 | 
			
		||||
      type: 'table',
 | 
			
		||||
      name: 'simple',
 | 
			
		||||
      title: '简易模式',
 | 
			
		||||
      template: 'SimpleTable',
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ export default {
 | 
			
		||||
      actionNames: ['update'],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'simple',
 | 
			
		||||
      type: 'table',
 | 
			
		||||
      name: 'simple',
 | 
			
		||||
      title: '简易模式',
 | 
			
		||||
      template: 'SimpleTable',
 | 
			
		||||
 | 
			
		||||
@ -75,7 +75,7 @@ export default {
 | 
			
		||||
      actionNames: ['update'],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'simple',
 | 
			
		||||
      type: 'table',
 | 
			
		||||
      name: 'simple',
 | 
			
		||||
      title: '简易模式',
 | 
			
		||||
      template: 'SimpleTable',
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ export default {
 | 
			
		||||
      actionNames: ['update'],
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      type: 'simple',
 | 
			
		||||
      type: 'table',
 | 
			
		||||
      name: 'simple',
 | 
			
		||||
      title: '简易模式',
 | 
			
		||||
      template: 'SimpleTable',
 | 
			
		||||
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'actions',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -1,25 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'collections',
 | 
			
		||||
  actions: {
 | 
			
		||||
    list: {
 | 
			
		||||
      fields: {
 | 
			
		||||
        appends: ['fields'],
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    get: {
 | 
			
		||||
      fields: {
 | 
			
		||||
        appends: ['fields'],
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // get: {
 | 
			
		||||
    //   handler: async (ctx, next) => {
 | 
			
		||||
    //     ctx.body = {
 | 
			
		||||
    //       get: {}
 | 
			
		||||
    //     }
 | 
			
		||||
    //     await next();
 | 
			
		||||
    //   }
 | 
			
		||||
    // },
 | 
			
		||||
  },
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'fields',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'tabs',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'views',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -9,8 +9,4 @@ export default async function (this: any, options = {}) {
 | 
			
		||||
  database.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'collections'),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  resourcer.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'resources'),
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,8 +9,4 @@ export default async function (options = {}) {
 | 
			
		||||
  database.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'collections'),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  resourcer.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'resources'),
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import { get } from 'lodash';
 | 
			
		||||
 | 
			
		||||
export default async (ctx, next) => {
 | 
			
		||||
  const { resourceName, resourceKey } = ctx.action.params;
 | 
			
		||||
  const [Collection, Tab, View] = ctx.db.getModels(['collections', 'tabs', 'views']) as ModelCtor<Model>[];
 | 
			
		||||
  const [Collection, Field, Tab, View] = ctx.db.getModels(['collections', 'fields', 'tabs', 'views']) as ModelCtor<Model>[];
 | 
			
		||||
  const collection = await Collection.findOne(Collection.parseApiJson({
 | 
			
		||||
    filter: {
 | 
			
		||||
      name: resourceName,
 | 
			
		||||
@ -20,14 +20,33 @@ export default async (ctx, next) => {
 | 
			
		||||
  });
 | 
			
		||||
  collection.setDataValue('defaultViewId', get(views, [0, 'id']));
 | 
			
		||||
  collection.setDataValue('defaultViewName', get(views, [0, 'name']));
 | 
			
		||||
  const tabs = await collection.getTabs();
 | 
			
		||||
  ctx.body = {
 | 
			
		||||
    ...collection.toJSON(),
 | 
			
		||||
    tabs: tabs.map(tab => ({
 | 
			
		||||
  const tabs = await collection.getTabs() as Model[];
 | 
			
		||||
  const tabItems = [];
 | 
			
		||||
  for (const tab of tabs) {
 | 
			
		||||
    const itemTab = {
 | 
			
		||||
      ...tab.toJSON(),
 | 
			
		||||
      ...tab.options,
 | 
			
		||||
      viewCollectionName: tab.type == 'association' ? tab.options.association : tab.collection_name,
 | 
			
		||||
    })),
 | 
			
		||||
    };
 | 
			
		||||
    if (itemTab.type == 'association') {
 | 
			
		||||
      const field = await Field.findOne({
 | 
			
		||||
        where: {
 | 
			
		||||
          collection_name: itemTab.collection_name,
 | 
			
		||||
          name: itemTab.association,
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      itemTab.field = field ? {
 | 
			
		||||
        ...field.toJSON(),
 | 
			
		||||
        ...field.options,
 | 
			
		||||
      } : {};
 | 
			
		||||
      itemTab.viewCollectionName = itemTab.association;
 | 
			
		||||
    } else {
 | 
			
		||||
      itemTab.viewCollectionName = itemTab.collection_name;
 | 
			
		||||
    }
 | 
			
		||||
    tabItems.push(itemTab);
 | 
			
		||||
  }
 | 
			
		||||
  ctx.body = {
 | 
			
		||||
    ...collection.toJSON(),
 | 
			
		||||
    tabs: tabItems,
 | 
			
		||||
  };
 | 
			
		||||
  await next();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										14
									
								
								packages/plugin-pages/src/actions/getPageInfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								packages/plugin-pages/src/actions/getPageInfo.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
import { Model, ModelCtor } from '@nocobase/database';
 | 
			
		||||
import { get } from 'lodash';
 | 
			
		||||
 | 
			
		||||
export default async (ctx, next) => {
 | 
			
		||||
  const { resourceName, resourceKey } = ctx.action.params;
 | 
			
		||||
  const M = ctx.db.getModel(resourceName) as ModelCtor<Model>;
 | 
			
		||||
  const model = await M.findByPk(resourceKey);
 | 
			
		||||
  ctx.body = {
 | 
			
		||||
    pageTitle: model.title,
 | 
			
		||||
    ...model.toJSON(),
 | 
			
		||||
  };
 | 
			
		||||
  await next();
 | 
			
		||||
};
 | 
			
		||||
@ -2,6 +2,41 @@ import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
import { Model, ModelCtor } from '@nocobase/database';
 | 
			
		||||
import { get } from 'lodash';
 | 
			
		||||
 | 
			
		||||
const transforms = {
 | 
			
		||||
  table: async (fields: Model[]) => {
 | 
			
		||||
    const arr = [];
 | 
			
		||||
    for (const field of fields) {
 | 
			
		||||
      arr.push({
 | 
			
		||||
        ...field.toJSON(),
 | 
			
		||||
        ...field.options,
 | 
			
		||||
        dataIndex: field.name,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    return arr;
 | 
			
		||||
  },
 | 
			
		||||
  form: async (fields: Model[]) => {
 | 
			
		||||
    const arr = [];
 | 
			
		||||
    for (const field of fields) {
 | 
			
		||||
      arr.push({
 | 
			
		||||
        ...field.toJSON(),
 | 
			
		||||
        ...field.options,
 | 
			
		||||
        dataIndex: field.name,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    return arr;
 | 
			
		||||
  },
 | 
			
		||||
  details: async (fields: Model[]) => {
 | 
			
		||||
    const arr = [];
 | 
			
		||||
    for (const field of fields) {
 | 
			
		||||
      arr.push({
 | 
			
		||||
        ...field.toJSON(),
 | 
			
		||||
        ...field.options,
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    return arr;
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default async (ctx, next) => {
 | 
			
		||||
  const { resourceName, resourceKey } = ctx.action.params;
 | 
			
		||||
  const [View, Field, Action] = ctx.db.getModels(['views', 'fields', 'actions']) as ModelCtor<Model>[];
 | 
			
		||||
@ -10,9 +45,9 @@ export default async (ctx, next) => {
 | 
			
		||||
      collection_name: resourceName,
 | 
			
		||||
      name: resourceKey,
 | 
			
		||||
    },
 | 
			
		||||
    fields: {
 | 
			
		||||
      appends: ['actions', 'fields'],
 | 
			
		||||
    },
 | 
			
		||||
    // fields: {
 | 
			
		||||
    //   appends: ['actions', 'fields'],
 | 
			
		||||
    // },
 | 
			
		||||
  }));
 | 
			
		||||
  const collection = await view.getCollection();
 | 
			
		||||
  const fields = await collection.getFields();
 | 
			
		||||
@ -27,14 +62,14 @@ export default async (ctx, next) => {
 | 
			
		||||
    });
 | 
			
		||||
    view.setDataValue('defaultTabName', get(defaultTabs, [0, 'name']));
 | 
			
		||||
  }
 | 
			
		||||
  if (view.options.updateViewId) {
 | 
			
		||||
  if (view.options.updateViewName) {
 | 
			
		||||
    view.setDataValue('rowViewName', view.options.updateViewName);
 | 
			
		||||
  }
 | 
			
		||||
  view.setDataValue('viewCollectionName', view.collection_name);
 | 
			
		||||
  ctx.body = {
 | 
			
		||||
    ...view.toJSON(),
 | 
			
		||||
    ...(view.options||{}),
 | 
			
		||||
    fields,
 | 
			
		||||
    fields: await (transforms[view.type]||transforms.table)(fields),
 | 
			
		||||
    actions: actions.filter(action => actionNames.includes(action.name)).map(action => ({
 | 
			
		||||
      ...action.toJSON(),
 | 
			
		||||
      ...action.options,
 | 
			
		||||
 | 
			
		||||
@ -1,9 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
import getRoutes from '../actions/getRoutes';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'pages',
 | 
			
		||||
  actions: {
 | 
			
		||||
    getRoutes,
 | 
			
		||||
  },
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -3,6 +3,8 @@ import Database from '@nocobase/database';
 | 
			
		||||
import Resourcer from '@nocobase/resourcer';
 | 
			
		||||
import getCollection from './actions/getCollection';
 | 
			
		||||
import getView from './actions/getView';
 | 
			
		||||
import getRoutes from './actions/getRoutes';
 | 
			
		||||
import getPageInfo from './actions/getPageInfo';
 | 
			
		||||
 | 
			
		||||
export default async function (options = {}) {
 | 
			
		||||
  const database: Database = this.database;
 | 
			
		||||
@ -14,8 +16,6 @@ export default async function (options = {}) {
 | 
			
		||||
 | 
			
		||||
  resourcer.registerHandler('getCollection', getCollection);
 | 
			
		||||
  resourcer.registerHandler('getView', getView);
 | 
			
		||||
 | 
			
		||||
  resourcer.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'resources'),
 | 
			
		||||
  });
 | 
			
		||||
  resourcer.registerHandler('getPageInfo', getPageInfo);
 | 
			
		||||
  resourcer.registerHandler('pages:getRoutes', getRoutes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'roles',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -9,8 +9,4 @@ export default async function (options = {}) {
 | 
			
		||||
  database.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'collections'),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  resourcer.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'resources'),
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +0,0 @@
 | 
			
		||||
import { ResourceOptions } from '@nocobase/resourcer';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  name: 'users',
 | 
			
		||||
} as ResourceOptions;
 | 
			
		||||
@ -9,8 +9,4 @@ export default async function (options = {}) {
 | 
			
		||||
  database.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'collections'),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  resourcer.import({
 | 
			
		||||
    directory: path.resolve(__dirname, 'resources'),
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user