Merge pull request 'merge_from_upstream' (#358) from merge_from_upstream into @hera/dev
Reviewed-on: daoyoucloud/tachycode#358
This commit is contained in:
		
						commit
						4bd5a1beda
					
				
							
								
								
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 | 
			
		||||
 | 
			
		||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
 | 
			
		||||
 | 
			
		||||
## [v0.20.0-alpha.9](https://github.com/nocobase/nocobase/compare/v0.20.0-alpha.8...v0.20.0-alpha.9) - 2024-03-12
 | 
			
		||||
 | 
			
		||||
### Merged
 | 
			
		||||
 | 
			
		||||
- refactor: add child in inheritance of tree collection [`#3676`](https://github.com/nocobase/nocobase/pull/3676)
 | 
			
		||||
- fix: data source add field refresh(T-3253) [`#3645`](https://github.com/nocobase/nocobase/pull/3645)
 | 
			
		||||
- chore: escape underscore char in include query [`#3681`](https://github.com/nocobase/nocobase/pull/3681)
 | 
			
		||||
- fix: upgrade app after restore [`#3680`](https://github.com/nocobase/nocobase/pull/3680)
 | 
			
		||||
- fix: view collection association field foreignkey should be select [`#3671`](https://github.com/nocobase/nocobase/pull/3671)
 | 
			
		||||
- fix: acl should return true when resource allowed [`#3675`](https://github.com/nocobase/nocobase/pull/3675)
 | 
			
		||||
- fix: init scope value when all data is null value [`#3674`](https://github.com/nocobase/nocobase/pull/3674)
 | 
			
		||||
- fix: inheritance cache bug [`#3669`](https://github.com/nocobase/nocobase/pull/3669)
 | 
			
		||||
 | 
			
		||||
### Commits
 | 
			
		||||
 | 
			
		||||
- chore(versions): 😊 publish v0.20.0-alpha.9 [`2e7da6e`](https://github.com/nocobase/nocobase/commit/2e7da6e29bc75def06f59d8d3bb991e7e238c64b)
 | 
			
		||||
- fix: pagination error in roles collections resourcer [`023096b`](https://github.com/nocobase/nocobase/commit/023096b1a9ea6ccae364c81ba93ca32b077ccecc)
 | 
			
		||||
- chore: update changelog [`56fd24e`](https://github.com/nocobase/nocobase/commit/56fd24ef4b30717e12b2c0574d4df92210bac81c)
 | 
			
		||||
 | 
			
		||||
## [v0.20.0-alpha.8](https://github.com/nocobase/nocobase/compare/v0.20.0-alpha.7...v0.20.0-alpha.8) - 2024-03-11
 | 
			
		||||
 | 
			
		||||
### Merged
 | 
			
		||||
@ -597,7 +616,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
 | 
			
		||||
- fix: load field when source collection not found [`95bec22`](https://github.com/nocobase/nocobase/commit/95bec2278ff2f53dfb1307e47bc8aca90d5a606a)
 | 
			
		||||
- chore: update changelog [`34e026c`](https://github.com/nocobase/nocobase/commit/34e026cec5742c1a1347f2969a03446fa98c44c3)
 | 
			
		||||
 | 
			
		||||
## [v0.17.0-alpha.1](https://github.com/nocobase/nocobase/compare/v0.16.0-alpha.7...v0.17.0-alpha.1) - 2023-12-04
 | 
			
		||||
## [v0.17.0-alpha.1](https://github.com/nocobase/nocobase/compare/v0.16.0-alpha.6...v0.17.0-alpha.1) - 2023-12-04
 | 
			
		||||
 | 
			
		||||
### Merged
 | 
			
		||||
 | 
			
		||||
@ -606,16 +625,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
 | 
			
		||||
### Commits
 | 
			
		||||
 | 
			
		||||
- chore(versions): 😊 publish v0.17.0-alpha.1 [`1757a96`](https://github.com/nocobase/nocobase/commit/1757a96b51c7bb17f607b61467ab867e5add6567)
 | 
			
		||||
- chore(versions): 😊 publish v0.16.0-alpha.6 [`9d64430`](https://github.com/nocobase/nocobase/commit/9d644304c10be0f8404f2f3370a43d2dc00e8aed)
 | 
			
		||||
- chore: update changelog [`69abfc9`](https://github.com/nocobase/nocobase/commit/69abfc98327b36bbc6b7e225294835bb457518d6)
 | 
			
		||||
 | 
			
		||||
## [v0.16.0-alpha.7](https://github.com/nocobase/nocobase/compare/v0.16.0-alpha.6...v0.16.0-alpha.7) - 2023-12-04
 | 
			
		||||
 | 
			
		||||
### Commits
 | 
			
		||||
 | 
			
		||||
- chore(versions): 😊 publish v0.16.0-alpha.7 [`d077a17`](https://github.com/nocobase/nocobase/commit/d077a17ee8cafc901a995f1ec7271ca78e4c32c3)
 | 
			
		||||
- chore(versions): 😊 publish v [`7810332`](https://github.com/nocobase/nocobase/commit/78103320eb6ee01559609784e7ba1a4493399c2c)
 | 
			
		||||
 | 
			
		||||
## [v0.16.0-alpha.6](https://github.com/nocobase/nocobase/compare/v0.16.0-alpha.5...v0.16.0-alpha.6) - 2023-12-04
 | 
			
		||||
 | 
			
		||||
### Merged
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
{
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "npmClient": "yarn",
 | 
			
		||||
  "useWorkspaces": true,
 | 
			
		||||
  "npmClientArgs": ["--ignore-engines"],
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/acl",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "minimatch": "^5.1.1"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/actions",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.8"
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.9"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/app",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/preset-nocobase": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/server": "0.20.0-alpha.8"
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/preset-nocobase": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/server": "0.20.0-alpha.9"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@nocobase/client": "0.20.0-alpha.8"
 | 
			
		||||
    "@nocobase/client": "0.20.0-alpha.9"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/auth",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/actions": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/actions": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "@types/jsonwebtoken": "^8.5.8",
 | 
			
		||||
    "jsonwebtoken": "^8.5.1"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/build",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "Library build tool based on rollup.",
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ const external = [
 | 
			
		||||
  '@nocobase/cache',
 | 
			
		||||
  '@nocobase/client',
 | 
			
		||||
  '@nocobase/database',
 | 
			
		||||
  '@nocobase/data-source-manager',
 | 
			
		||||
  '@nocobase/evaluators',
 | 
			
		||||
  '@nocobase/logger',
 | 
			
		||||
  '@nocobase/resourcer',
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										2
									
								
								packages/core/cache/package.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								packages/core/cache/package.json
									
									
									
									
										vendored
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/cache",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/cli",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./src/index.js",
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
    "nocobase": "./bin/index.js"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/app": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/app": "0.20.0-alpha.9",
 | 
			
		||||
    "@types/fs-extra": "^11.0.1",
 | 
			
		||||
    "@umijs/utils": "3.5.20",
 | 
			
		||||
    "chalk": "^4.1.1",
 | 
			
		||||
@ -25,7 +25,7 @@
 | 
			
		||||
    "tsx": "^4.6.2"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@nocobase/devtools": "0.20.0-alpha.8"
 | 
			
		||||
    "@nocobase/devtools": "0.20.0-alpha.9"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/client",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "module": "es/index.mjs",
 | 
			
		||||
@ -26,9 +26,9 @@
 | 
			
		||||
    "@formily/reactive-react": "^2.2.27",
 | 
			
		||||
    "@formily/shared": "^2.2.27",
 | 
			
		||||
    "@formily/validator": "^2.2.27",
 | 
			
		||||
    "@nocobase/evaluators": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/sdk": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/evaluators": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/sdk": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "ahooks": "^3.7.2",
 | 
			
		||||
    "antd": "^5.12.8",
 | 
			
		||||
    "antd-style": "3.4.5",
 | 
			
		||||
 | 
			
		||||
@ -986,6 +986,11 @@ export const useBulkDestroyActionProps = () => {
 | 
			
		||||
        filterByTk: field.data?.selectedRowKeys,
 | 
			
		||||
      });
 | 
			
		||||
      field.data.selectedRowKeys = [];
 | 
			
		||||
      const currentPage = service.params[0]?.page;
 | 
			
		||||
      const totalPage = service.data?.meta?.totalPage;
 | 
			
		||||
      if (currentPage === totalPage) {
 | 
			
		||||
        service.params[0].page = currentPage - 1;
 | 
			
		||||
      }
 | 
			
		||||
      service?.refresh?.();
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
@ -132,10 +132,10 @@ export const useSelfAndChildrenCollections = (collectionName: string) => {
 | 
			
		||||
  return options;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useCollectionFilterOptions = (collection: any) => {
 | 
			
		||||
export const useCollectionFilterOptions = (collection: any, dataSource?: string) => {
 | 
			
		||||
  const { getCollectionFields, getInterface } = useCollectionManager_deprecated();
 | 
			
		||||
  return useMemo(() => {
 | 
			
		||||
    const fields = getCollectionFields(collection);
 | 
			
		||||
    const fields = getCollectionFields(collection, dataSource);
 | 
			
		||||
    const field2option = (field, depth) => {
 | 
			
		||||
      if (!field.interface) {
 | 
			
		||||
        return;
 | 
			
		||||
@ -165,7 +165,7 @@ export const useCollectionFilterOptions = (collection: any) => {
 | 
			
		||||
        option['children'] = children;
 | 
			
		||||
      }
 | 
			
		||||
      if (nested) {
 | 
			
		||||
        const targetFields = getCollectionFields(field.target);
 | 
			
		||||
        const targetFields = getCollectionFields(field.target, dataSource);
 | 
			
		||||
        const options = getOptions(targetFields, depth + 1).filter(Boolean);
 | 
			
		||||
        option['children'] = option['children'] || [];
 | 
			
		||||
        option['children'].push(...options);
 | 
			
		||||
@ -184,7 +184,7 @@ export const useCollectionFilterOptions = (collection: any) => {
 | 
			
		||||
    };
 | 
			
		||||
    const options = getOptions(fields, 1);
 | 
			
		||||
    return options;
 | 
			
		||||
  }, [_.isString(collection) ? collection : collection?.name]);
 | 
			
		||||
  }, [_.isString(collection) ? collection : collection?.name, dataSource]);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useCollectionFilterOptionsV2 = (collection: any) => {
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,9 @@ import {
 | 
			
		||||
  UpdatedByFieldInterface,
 | 
			
		||||
  UrlFieldInterface,
 | 
			
		||||
  SortFieldInterface,
 | 
			
		||||
  UUIDFieldInterface,
 | 
			
		||||
  NanoidFieldInterface,
 | 
			
		||||
  UnixTimestampFieldInterface,
 | 
			
		||||
} from './interfaces';
 | 
			
		||||
import {
 | 
			
		||||
  GeneralCollectionTemplate,
 | 
			
		||||
@ -155,6 +158,9 @@ export class CollectionPlugin extends Plugin {
 | 
			
		||||
      UpdatedByFieldInterface,
 | 
			
		||||
      UrlFieldInterface,
 | 
			
		||||
      SortFieldInterface,
 | 
			
		||||
      UUIDFieldInterface,
 | 
			
		||||
      NanoidFieldInterface,
 | 
			
		||||
      UnixTimestampFieldInterface,
 | 
			
		||||
    ]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,3 +25,4 @@ export * from './collectionPlugin';
 | 
			
		||||
export * from './mixins/InheritanceCollectionMixin';
 | 
			
		||||
export * from './sub-table';
 | 
			
		||||
export * from './CollectionHistoryProvider';
 | 
			
		||||
export * from './utils';
 | 
			
		||||
 | 
			
		||||
@ -34,3 +34,6 @@ export * from './updatedAt';
 | 
			
		||||
export * from './updatedBy';
 | 
			
		||||
export * from './url';
 | 
			
		||||
export * from './sort';
 | 
			
		||||
export * from './uuid';
 | 
			
		||||
export * from './nanoid';
 | 
			
		||||
export * from './unixTimestamp';
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,56 @@
 | 
			
		||||
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface';
 | 
			
		||||
import { operators } from './properties';
 | 
			
		||||
export class NanoidFieldInterface extends CollectionFieldInterface {
 | 
			
		||||
  name = 'nanoid';
 | 
			
		||||
  type = 'object';
 | 
			
		||||
  group = 'advanced';
 | 
			
		||||
  order = 0;
 | 
			
		||||
  title = '{{t("Nano ID")}}';
 | 
			
		||||
  hidden = false;
 | 
			
		||||
  sortable = true;
 | 
			
		||||
  default = {
 | 
			
		||||
    type: 'nanoid',
 | 
			
		||||
    uiSchema: {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      'x-component': 'NanoIDInput',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  availableTypes = ['string', 'uid'];
 | 
			
		||||
  properties = {
 | 
			
		||||
    'uiSchema.title': {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Field display name")}}',
 | 
			
		||||
      required: true,
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
    },
 | 
			
		||||
    name: {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Field name")}}',
 | 
			
		||||
      required: true,
 | 
			
		||||
      'x-disabled': true,
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
      description:
 | 
			
		||||
        "{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}",
 | 
			
		||||
    },
 | 
			
		||||
    customAlphabet: {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Alphabet")}}',
 | 
			
		||||
      default: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
    },
 | 
			
		||||
    size: {
 | 
			
		||||
      type: 'number',
 | 
			
		||||
      title: '{{t("Length")}}',
 | 
			
		||||
      default: 21,
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'InputNumber',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  filterable = {
 | 
			
		||||
    operators: operators.string,
 | 
			
		||||
  };
 | 
			
		||||
  titleUsable = true;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface';
 | 
			
		||||
import { dateTimeProps, defaultProps, operators } from './properties';
 | 
			
		||||
 | 
			
		||||
export class UnixTimestampFieldInterface extends CollectionFieldInterface {
 | 
			
		||||
  name = 'unixTimestamp';
 | 
			
		||||
  type = 'object';
 | 
			
		||||
  group = 'datetime';
 | 
			
		||||
  order = 1;
 | 
			
		||||
  title = '{{t("Unix Timestamp")}}';
 | 
			
		||||
  sortable = true;
 | 
			
		||||
  default = {
 | 
			
		||||
    type: 'bigInt',
 | 
			
		||||
    uiSchema: {
 | 
			
		||||
      type: 'number',
 | 
			
		||||
      'x-component': 'UnixTimestamp',
 | 
			
		||||
      'x-component-props': {
 | 
			
		||||
        accuracy: 'millisecond',
 | 
			
		||||
        showTime: true,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  availableTypes = ['integet', 'bigInt'];
 | 
			
		||||
  hasDefaultValue = true;
 | 
			
		||||
  properties = {
 | 
			
		||||
    ...defaultProps,
 | 
			
		||||
    'uiSchema.x-component-props.accuracy': {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Accuracy")}}',
 | 
			
		||||
      'x-component': 'Radio.Group',
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      default: 'millisecond',
 | 
			
		||||
      enum: [
 | 
			
		||||
        { value: 'millisecond', label: '{{t("Millisecond")}}' },
 | 
			
		||||
        { value: 'second', label: '{{t("Second")}}' },
 | 
			
		||||
      ],
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  filterable = {
 | 
			
		||||
    operators: operators.number,
 | 
			
		||||
  };
 | 
			
		||||
  titleUsable = true;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,44 @@
 | 
			
		||||
import { CollectionFieldInterface } from '../../data-source/collection-field-interface/CollectionFieldInterface';
 | 
			
		||||
import { operators } from './properties';
 | 
			
		||||
 | 
			
		||||
export class UUIDFieldInterface extends CollectionFieldInterface {
 | 
			
		||||
  name = 'uuid';
 | 
			
		||||
  type = 'object';
 | 
			
		||||
  group = 'advanced';
 | 
			
		||||
  order = 0;
 | 
			
		||||
  title = '{{t("UUID")}}';
 | 
			
		||||
  hidden = false;
 | 
			
		||||
  sortable = true;
 | 
			
		||||
  default = {
 | 
			
		||||
    type: 'uuid',
 | 
			
		||||
    uiSchema: {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
      'x-validator': 'uuid',
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  availableTypes = ['string', 'uid'];
 | 
			
		||||
  properties = {
 | 
			
		||||
    'uiSchema.title': {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Field display name")}}',
 | 
			
		||||
      required: true,
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
    },
 | 
			
		||||
    name: {
 | 
			
		||||
      type: 'string',
 | 
			
		||||
      title: '{{t("Field name")}}',
 | 
			
		||||
      required: true,
 | 
			
		||||
      'x-disabled': true,
 | 
			
		||||
      'x-decorator': 'FormItem',
 | 
			
		||||
      'x-component': 'Input',
 | 
			
		||||
      description:
 | 
			
		||||
        "{{t('Randomly generated and can be modified. Support letters, numbers and underscores, must start with an letter.')}}",
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
  filterable = {
 | 
			
		||||
    operators: operators.string,
 | 
			
		||||
  };
 | 
			
		||||
  titleUsable = true;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								packages/core/client/src/collection-manager/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								packages/core/client/src/collection-manager/utils.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
export function parseCollectionName(collection: string) {
 | 
			
		||||
  if (!collection) {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
  const dataSourceCollection = collection.split(':');
 | 
			
		||||
  const collectionName = dataSourceCollection.pop();
 | 
			
		||||
  const dataSourceName = dataSourceCollection[0] ?? 'main';
 | 
			
		||||
  return [dataSourceName, collectionName];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function joinCollectionName(dataSourceName: string, collectionName: string) {
 | 
			
		||||
  if (!dataSourceName || dataSourceName === 'main') {
 | 
			
		||||
    return collectionName;
 | 
			
		||||
  }
 | 
			
		||||
  return `${dataSourceName}:${collectionName}`;
 | 
			
		||||
}
 | 
			
		||||
@ -114,7 +114,7 @@ export const BlockRequestProvider: FC = ({ children }) => {
 | 
			
		||||
    <BlockRequestContext.Provider value={currentRequest}>
 | 
			
		||||
      {action !== 'list' ? (
 | 
			
		||||
        <CollectionRecordProvider
 | 
			
		||||
          isNew={action === undefined}
 | 
			
		||||
          isNew={action == null}
 | 
			
		||||
          record={currentRequest.data?.data}
 | 
			
		||||
          parentRecord={memoizedParentRecord}
 | 
			
		||||
        >
 | 
			
		||||
 | 
			
		||||
@ -851,7 +851,7 @@
 | 
			
		||||
  "loading": "加载中",
 | 
			
		||||
  "name is required": "名称不能为空",
 | 
			
		||||
  "The {{type}} \"{{name}}\" may have been deleted. Please remove this {{blockType}}.": "{{type}} \"{{name}}\" 可能已被删除。请删除当前{{blockType}}.",
 | 
			
		||||
  "data source": "数据源",
 | 
			
		||||
  "Data source": "数据源",
 | 
			
		||||
  "DataSource": "数据源",
 | 
			
		||||
  "Data model": "数据模型",
 | 
			
		||||
  "Security": "认证与安全",
 | 
			
		||||
@ -891,5 +891,12 @@
 | 
			
		||||
  "Owners": "负责人",
 | 
			
		||||
  "Plugin settings": "插件设置",
 | 
			
		||||
  "Menu": "菜单",
 | 
			
		||||
  "Drag and drop sorting field": "拖拽排序字段"
 | 
			
		||||
  "Drag and drop sorting field": "拖拽排序字段",
 | 
			
		||||
  "Alphabet": "字符",
 | 
			
		||||
  "Accuracy": "精确度",
 | 
			
		||||
  "Millisecond": "毫秒",
 | 
			
		||||
  "Second": "秒",
 | 
			
		||||
  "Unix Timestamp": "Unix 时间戳",
 | 
			
		||||
  "Field value do not meet the requirements": "字符不符合要求",
 | 
			
		||||
  "Field value size is": "字符长度要求"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,21 @@
 | 
			
		||||
import { test, expect } from '@nocobase/test/e2e';
 | 
			
		||||
import { T3529 } from './templatesOfBug';
 | 
			
		||||
 | 
			
		||||
test.describe('association form block', () => {
 | 
			
		||||
  // https://nocobase.height.app/T-3529
 | 
			
		||||
  test('should be created instead of updated', async ({ page, mockPage, mockRecord }) => {
 | 
			
		||||
    const nocoPage = await mockPage(T3529).waitForInit();
 | 
			
		||||
    await mockRecord('general');
 | 
			
		||||
    await nocoPage.goto();
 | 
			
		||||
 | 
			
		||||
    await page.getByLabel('action-Action.Link-View-view-general-table-0').click();
 | 
			
		||||
    void page.getByLabel('action-Action-Submit-submit-').click();
 | 
			
		||||
 | 
			
		||||
    const request = await page.waitForRequest((request) => {
 | 
			
		||||
      return request.url().includes('m2mField0:create');
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // 应该有包含 :create 的请求
 | 
			
		||||
    expect(request).toBeTruthy();
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
import { PageConfig, generalWithM2oSingleSelect } from '@nocobase/test/e2e';
 | 
			
		||||
import { PageConfig, generalWithM2oSingleSelect, generalWithMultiLevelM2mFields } from '@nocobase/test/e2e';
 | 
			
		||||
 | 
			
		||||
export const T2165 = {
 | 
			
		||||
  pageSchema: {
 | 
			
		||||
@ -5701,3 +5701,374 @@ export const T3469: PageConfig = {
 | 
			
		||||
    'x-async': true,
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// https://nocobase.height.app/T-3529
 | 
			
		||||
export const T3529: PageConfig = {
 | 
			
		||||
  collections: generalWithMultiLevelM2mFields,
 | 
			
		||||
  pageSchema: {
 | 
			
		||||
    _isJSONSchemaObject: true,
 | 
			
		||||
    version: '2.0',
 | 
			
		||||
    type: 'void',
 | 
			
		||||
    'x-component': 'Page',
 | 
			
		||||
    properties: {
 | 
			
		||||
      '5i47muli5of': {
 | 
			
		||||
        _isJSONSchemaObject: true,
 | 
			
		||||
        version: '2.0',
 | 
			
		||||
        type: 'void',
 | 
			
		||||
        'x-component': 'Grid',
 | 
			
		||||
        'x-initializer': 'BlockInitializers',
 | 
			
		||||
        properties: {
 | 
			
		||||
          l62athlwjbe: {
 | 
			
		||||
            _isJSONSchemaObject: true,
 | 
			
		||||
            version: '2.0',
 | 
			
		||||
            type: 'void',
 | 
			
		||||
            'x-component': 'Grid.Row',
 | 
			
		||||
            properties: {
 | 
			
		||||
              gv12rstt0n6: {
 | 
			
		||||
                _isJSONSchemaObject: true,
 | 
			
		||||
                version: '2.0',
 | 
			
		||||
                type: 'void',
 | 
			
		||||
                'x-component': 'Grid.Col',
 | 
			
		||||
                properties: {
 | 
			
		||||
                  '44sjepqege8': {
 | 
			
		||||
                    _isJSONSchemaObject: true,
 | 
			
		||||
                    version: '2.0',
 | 
			
		||||
                    type: 'void',
 | 
			
		||||
                    'x-decorator': 'TableBlockProvider',
 | 
			
		||||
                    'x-acl-action': 'general:list',
 | 
			
		||||
                    'x-decorator-props': {
 | 
			
		||||
                      collection: 'general',
 | 
			
		||||
                      dataSource: 'main',
 | 
			
		||||
                      resource: 'general',
 | 
			
		||||
                      action: 'list',
 | 
			
		||||
                      params: {
 | 
			
		||||
                        pageSize: 20,
 | 
			
		||||
                      },
 | 
			
		||||
                      rowKey: 'id',
 | 
			
		||||
                      showIndex: true,
 | 
			
		||||
                      dragSort: false,
 | 
			
		||||
                      disableTemplate: false,
 | 
			
		||||
                    },
 | 
			
		||||
                    'x-toolbar': 'BlockSchemaToolbar',
 | 
			
		||||
                    'x-settings': 'blockSettings:table',
 | 
			
		||||
                    'x-component': 'CardItem',
 | 
			
		||||
                    'x-filter-targets': [],
 | 
			
		||||
                    properties: {
 | 
			
		||||
                      actions: {
 | 
			
		||||
                        _isJSONSchemaObject: true,
 | 
			
		||||
                        version: '2.0',
 | 
			
		||||
                        type: 'void',
 | 
			
		||||
                        'x-initializer': 'TableActionInitializers',
 | 
			
		||||
                        'x-component': 'ActionBar',
 | 
			
		||||
                        'x-component-props': {
 | 
			
		||||
                          style: {
 | 
			
		||||
                            marginBottom: 'var(--nb-spacing)',
 | 
			
		||||
                          },
 | 
			
		||||
                        },
 | 
			
		||||
                        'x-uid': 'gcqzwfc98cz',
 | 
			
		||||
                        'x-async': false,
 | 
			
		||||
                        'x-index': 1,
 | 
			
		||||
                      },
 | 
			
		||||
                      cndkuudjlrn: {
 | 
			
		||||
                        _isJSONSchemaObject: true,
 | 
			
		||||
                        version: '2.0',
 | 
			
		||||
                        type: 'array',
 | 
			
		||||
                        'x-initializer': 'TableColumnInitializers',
 | 
			
		||||
                        'x-component': 'TableV2',
 | 
			
		||||
                        'x-component-props': {
 | 
			
		||||
                          rowKey: 'id',
 | 
			
		||||
                          rowSelection: {
 | 
			
		||||
                            type: 'checkbox',
 | 
			
		||||
                          },
 | 
			
		||||
                          useProps: '{{ useTableBlockProps }}',
 | 
			
		||||
                        },
 | 
			
		||||
                        properties: {
 | 
			
		||||
                          actions: {
 | 
			
		||||
                            _isJSONSchemaObject: true,
 | 
			
		||||
                            version: '2.0',
 | 
			
		||||
                            type: 'void',
 | 
			
		||||
                            title: '{{ t("Actions") }}',
 | 
			
		||||
                            'x-action-column': 'actions',
 | 
			
		||||
                            'x-decorator': 'TableV2.Column.ActionBar',
 | 
			
		||||
                            'x-component': 'TableV2.Column',
 | 
			
		||||
                            'x-designer': 'TableV2.ActionColumnDesigner',
 | 
			
		||||
                            'x-initializer': 'TableActionColumnInitializers',
 | 
			
		||||
                            properties: {
 | 
			
		||||
                              '7glkmum3znh': {
 | 
			
		||||
                                _isJSONSchemaObject: true,
 | 
			
		||||
                                version: '2.0',
 | 
			
		||||
                                type: 'void',
 | 
			
		||||
                                'x-decorator': 'DndContext',
 | 
			
		||||
                                'x-component': 'Space',
 | 
			
		||||
                                'x-component-props': {
 | 
			
		||||
                                  split: '|',
 | 
			
		||||
                                },
 | 
			
		||||
                                properties: {
 | 
			
		||||
                                  '34feo0sq1b1': {
 | 
			
		||||
                                    _isJSONSchemaObject: true,
 | 
			
		||||
                                    version: '2.0',
 | 
			
		||||
                                    type: 'void',
 | 
			
		||||
                                    title: '{{ t("View") }}',
 | 
			
		||||
                                    'x-action': 'view',
 | 
			
		||||
                                    'x-toolbar': 'ActionSchemaToolbar',
 | 
			
		||||
                                    'x-settings': 'actionSettings:view',
 | 
			
		||||
                                    'x-component': 'Action.Link',
 | 
			
		||||
                                    'x-component-props': {
 | 
			
		||||
                                      openMode: 'drawer',
 | 
			
		||||
                                    },
 | 
			
		||||
                                    'x-decorator': 'ACLActionProvider',
 | 
			
		||||
                                    'x-designer-props': {
 | 
			
		||||
                                      linkageAction: true,
 | 
			
		||||
                                    },
 | 
			
		||||
                                    properties: {
 | 
			
		||||
                                      drawer: {
 | 
			
		||||
                                        _isJSONSchemaObject: true,
 | 
			
		||||
                                        version: '2.0',
 | 
			
		||||
                                        type: 'void',
 | 
			
		||||
                                        title: '{{ t("View record") }}',
 | 
			
		||||
                                        'x-component': 'Action.Container',
 | 
			
		||||
                                        'x-component-props': {
 | 
			
		||||
                                          className: 'nb-action-popup',
 | 
			
		||||
                                        },
 | 
			
		||||
                                        properties: {
 | 
			
		||||
                                          tabs: {
 | 
			
		||||
                                            _isJSONSchemaObject: true,
 | 
			
		||||
                                            version: '2.0',
 | 
			
		||||
                                            type: 'void',
 | 
			
		||||
                                            'x-component': 'Tabs',
 | 
			
		||||
                                            'x-component-props': {},
 | 
			
		||||
                                            'x-initializer': 'TabPaneInitializers',
 | 
			
		||||
                                            properties: {
 | 
			
		||||
                                              tab1: {
 | 
			
		||||
                                                _isJSONSchemaObject: true,
 | 
			
		||||
                                                version: '2.0',
 | 
			
		||||
                                                type: 'void',
 | 
			
		||||
                                                title: '{{t("Details")}}',
 | 
			
		||||
                                                'x-component': 'Tabs.TabPane',
 | 
			
		||||
                                                'x-designer': 'Tabs.Designer',
 | 
			
		||||
                                                'x-component-props': {},
 | 
			
		||||
                                                properties: {
 | 
			
		||||
                                                  grid: {
 | 
			
		||||
                                                    _isJSONSchemaObject: true,
 | 
			
		||||
                                                    version: '2.0',
 | 
			
		||||
                                                    type: 'void',
 | 
			
		||||
                                                    'x-component': 'Grid',
 | 
			
		||||
                                                    'x-initializer': 'RecordBlockInitializers',
 | 
			
		||||
                                                    properties: {
 | 
			
		||||
                                                      '5ubuvb82lbu': {
 | 
			
		||||
                                                        _isJSONSchemaObject: true,
 | 
			
		||||
                                                        version: '2.0',
 | 
			
		||||
                                                        type: 'void',
 | 
			
		||||
                                                        'x-component': 'Grid.Row',
 | 
			
		||||
                                                        properties: {
 | 
			
		||||
                                                          pe6vly71p50: {
 | 
			
		||||
                                                            _isJSONSchemaObject: true,
 | 
			
		||||
                                                            version: '2.0',
 | 
			
		||||
                                                            type: 'void',
 | 
			
		||||
                                                            'x-component': 'Grid.Col',
 | 
			
		||||
                                                            properties: {
 | 
			
		||||
                                                              ls6i68y4q5r: {
 | 
			
		||||
                                                                _isJSONSchemaObject: true,
 | 
			
		||||
                                                                version: '2.0',
 | 
			
		||||
                                                                type: 'void',
 | 
			
		||||
                                                                'x-acl-action-props': {
 | 
			
		||||
                                                                  skipScopeCheck: true,
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                                'x-acl-action': 'general.m2mField0:create',
 | 
			
		||||
                                                                'x-decorator': 'FormBlockProvider',
 | 
			
		||||
                                                                'x-decorator-props': {
 | 
			
		||||
                                                                  useSourceId: '{{ useSourceIdFromParentRecord }}',
 | 
			
		||||
                                                                  useParams: '{{ useParamsFromRecord }}',
 | 
			
		||||
                                                                  action: null,
 | 
			
		||||
                                                                  dataSource: 'main',
 | 
			
		||||
                                                                  resource: 'general.m2mField0',
 | 
			
		||||
                                                                  collection: 'm2mField1',
 | 
			
		||||
                                                                  association: 'general.m2mField0',
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                                'x-toolbar': 'BlockSchemaToolbar',
 | 
			
		||||
                                                                'x-settings': 'blockSettings:createForm',
 | 
			
		||||
                                                                'x-component': 'CardItem',
 | 
			
		||||
                                                                'x-component-props': {},
 | 
			
		||||
                                                                properties: {
 | 
			
		||||
                                                                  '4g1wyduvzzq': {
 | 
			
		||||
                                                                    _isJSONSchemaObject: true,
 | 
			
		||||
                                                                    version: '2.0',
 | 
			
		||||
                                                                    type: 'void',
 | 
			
		||||
                                                                    'x-component': 'FormV2',
 | 
			
		||||
                                                                    'x-component-props': {
 | 
			
		||||
                                                                      useProps: '{{ useFormBlockProps }}',
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                    properties: {
 | 
			
		||||
                                                                      grid: {
 | 
			
		||||
                                                                        _isJSONSchemaObject: true,
 | 
			
		||||
                                                                        version: '2.0',
 | 
			
		||||
                                                                        type: 'void',
 | 
			
		||||
                                                                        'x-component': 'Grid',
 | 
			
		||||
                                                                        'x-initializer': 'FormItemInitializers',
 | 
			
		||||
                                                                        'x-uid': 'aigmsbzdyeb',
 | 
			
		||||
                                                                        'x-async': false,
 | 
			
		||||
                                                                        'x-index': 1,
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                      v5tx6a8ya3q: {
 | 
			
		||||
                                                                        _isJSONSchemaObject: true,
 | 
			
		||||
                                                                        version: '2.0',
 | 
			
		||||
                                                                        type: 'void',
 | 
			
		||||
                                                                        'x-initializer': 'CreateFormActionInitializers',
 | 
			
		||||
                                                                        'x-component': 'ActionBar',
 | 
			
		||||
                                                                        'x-component-props': {
 | 
			
		||||
                                                                          layout: 'one-column',
 | 
			
		||||
                                                                          style: {
 | 
			
		||||
                                                                            marginTop: 24,
 | 
			
		||||
                                                                          },
 | 
			
		||||
                                                                        },
 | 
			
		||||
                                                                        properties: {
 | 
			
		||||
                                                                          dhmchgjzu2d: {
 | 
			
		||||
                                                                            _isJSONSchemaObject: true,
 | 
			
		||||
                                                                            version: '2.0',
 | 
			
		||||
                                                                            title: '{{ t("Submit") }}',
 | 
			
		||||
                                                                            'x-action': 'submit',
 | 
			
		||||
                                                                            'x-component': 'Action',
 | 
			
		||||
                                                                            'x-toolbar': 'ActionSchemaToolbar',
 | 
			
		||||
                                                                            'x-settings': 'actionSettings:createSubmit',
 | 
			
		||||
                                                                            'x-component-props': {
 | 
			
		||||
                                                                              type: 'primary',
 | 
			
		||||
                                                                              htmlType: 'submit',
 | 
			
		||||
                                                                              useProps: '{{ useCreateActionProps }}',
 | 
			
		||||
                                                                            },
 | 
			
		||||
                                                                            'x-action-settings': {
 | 
			
		||||
                                                                              triggerWorkflows: [],
 | 
			
		||||
                                                                            },
 | 
			
		||||
                                                                            type: 'void',
 | 
			
		||||
                                                                            'x-uid': 'bgi90aunfbx',
 | 
			
		||||
                                                                            'x-async': false,
 | 
			
		||||
                                                                            'x-index': 1,
 | 
			
		||||
                                                                          },
 | 
			
		||||
                                                                        },
 | 
			
		||||
                                                                        'x-uid': '6m4zb9wz65e',
 | 
			
		||||
                                                                        'x-async': false,
 | 
			
		||||
                                                                        'x-index': 2,
 | 
			
		||||
                                                                      },
 | 
			
		||||
                                                                    },
 | 
			
		||||
                                                                    'x-uid': 'sbl64rh18y4',
 | 
			
		||||
                                                                    'x-async': false,
 | 
			
		||||
                                                                    'x-index': 1,
 | 
			
		||||
                                                                  },
 | 
			
		||||
                                                                },
 | 
			
		||||
                                                                'x-uid': 'z76kadyn2d8',
 | 
			
		||||
                                                                'x-async': false,
 | 
			
		||||
                                                                'x-index': 1,
 | 
			
		||||
                                                              },
 | 
			
		||||
                                                            },
 | 
			
		||||
                                                            'x-uid': 'kb89ln0xf6j',
 | 
			
		||||
                                                            'x-async': false,
 | 
			
		||||
                                                            'x-index': 1,
 | 
			
		||||
                                                          },
 | 
			
		||||
                                                        },
 | 
			
		||||
                                                        'x-uid': 'zyqb93i3dfg',
 | 
			
		||||
                                                        'x-async': false,
 | 
			
		||||
                                                        'x-index': 1,
 | 
			
		||||
                                                      },
 | 
			
		||||
                                                    },
 | 
			
		||||
                                                    'x-uid': 'zxthz54u0wr',
 | 
			
		||||
                                                    'x-async': false,
 | 
			
		||||
                                                    'x-index': 1,
 | 
			
		||||
                                                  },
 | 
			
		||||
                                                },
 | 
			
		||||
                                                'x-uid': '4vis0296ryj',
 | 
			
		||||
                                                'x-async': false,
 | 
			
		||||
                                                'x-index': 1,
 | 
			
		||||
                                              },
 | 
			
		||||
                                            },
 | 
			
		||||
                                            'x-uid': 'p23nq2w7s15',
 | 
			
		||||
                                            'x-async': false,
 | 
			
		||||
                                            'x-index': 1,
 | 
			
		||||
                                          },
 | 
			
		||||
                                        },
 | 
			
		||||
                                        'x-uid': 'zaqeevlcwap',
 | 
			
		||||
                                        'x-async': false,
 | 
			
		||||
                                        'x-index': 1,
 | 
			
		||||
                                      },
 | 
			
		||||
                                    },
 | 
			
		||||
                                    'x-uid': 'r1tzkph9sg3',
 | 
			
		||||
                                    'x-async': false,
 | 
			
		||||
                                    'x-index': 1,
 | 
			
		||||
                                  },
 | 
			
		||||
                                },
 | 
			
		||||
                                'x-uid': '2k7344qkff4',
 | 
			
		||||
                                'x-async': false,
 | 
			
		||||
                                'x-index': 1,
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                            'x-uid': 'jozmqdix3a6',
 | 
			
		||||
                            'x-async': false,
 | 
			
		||||
                            'x-index': 1,
 | 
			
		||||
                          },
 | 
			
		||||
                          exdcwiv8fnb: {
 | 
			
		||||
                            _isJSONSchemaObject: true,
 | 
			
		||||
                            version: '2.0',
 | 
			
		||||
                            type: 'void',
 | 
			
		||||
                            'x-decorator': 'TableV2.Column.Decorator',
 | 
			
		||||
                            'x-toolbar': 'TableColumnSchemaToolbar',
 | 
			
		||||
                            'x-settings': 'fieldSettings:TableColumn',
 | 
			
		||||
                            'x-component': 'TableV2.Column',
 | 
			
		||||
                            properties: {
 | 
			
		||||
                              m2mField0: {
 | 
			
		||||
                                _isJSONSchemaObject: true,
 | 
			
		||||
                                version: '2.0',
 | 
			
		||||
                                'x-collection-field': 'general.m2mField0',
 | 
			
		||||
                                'x-component': 'CollectionField',
 | 
			
		||||
                                'x-component-props': {
 | 
			
		||||
                                  fieldNames: {
 | 
			
		||||
                                    value: 'id',
 | 
			
		||||
                                    label: 'id',
 | 
			
		||||
                                  },
 | 
			
		||||
                                  ellipsis: true,
 | 
			
		||||
                                  size: 'small',
 | 
			
		||||
                                },
 | 
			
		||||
                                'x-read-pretty': true,
 | 
			
		||||
                                'x-decorator': null,
 | 
			
		||||
                                'x-decorator-props': {
 | 
			
		||||
                                  labelStyle: {
 | 
			
		||||
                                    display: 'none',
 | 
			
		||||
                                  },
 | 
			
		||||
                                },
 | 
			
		||||
                                'x-uid': 'gzktad04dhq',
 | 
			
		||||
                                'x-async': false,
 | 
			
		||||
                                'x-index': 1,
 | 
			
		||||
                              },
 | 
			
		||||
                            },
 | 
			
		||||
                            'x-uid': 'fulrpp42vr2',
 | 
			
		||||
                            'x-async': false,
 | 
			
		||||
                            'x-index': 2,
 | 
			
		||||
                          },
 | 
			
		||||
                        },
 | 
			
		||||
                        'x-uid': '6rucf9up8f4',
 | 
			
		||||
                        'x-async': false,
 | 
			
		||||
                        'x-index': 2,
 | 
			
		||||
                      },
 | 
			
		||||
                    },
 | 
			
		||||
                    'x-uid': 'izfl6h66ch4',
 | 
			
		||||
                    'x-async': false,
 | 
			
		||||
                    'x-index': 1,
 | 
			
		||||
                  },
 | 
			
		||||
                },
 | 
			
		||||
                'x-uid': 'i8m1l6l6qg5',
 | 
			
		||||
                'x-async': false,
 | 
			
		||||
                'x-index': 1,
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            'x-uid': 'v0y71zujt89',
 | 
			
		||||
            'x-async': false,
 | 
			
		||||
            'x-index': 1,
 | 
			
		||||
          },
 | 
			
		||||
        },
 | 
			
		||||
        'x-uid': 'vpa330z2xp5',
 | 
			
		||||
        'x-async': false,
 | 
			
		||||
        'x-index': 1,
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    'x-uid': 'l4kzvh7mdoa',
 | 
			
		||||
    'x-async': true,
 | 
			
		||||
    'x-index': 1,
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,22 @@
 | 
			
		||||
import { useFieldSchema } from '@formily/react';
 | 
			
		||||
import { SchemaSettings } from '../../../../application/schema-settings/SchemaSettings';
 | 
			
		||||
import { SchemaSettingsDateFormat } from '../../../../schema-settings/SchemaSettingsDateFormat';
 | 
			
		||||
import { useColumnSchema } from '../../../../schema-component/antd/table-v2/Table.Column.Decorator';
 | 
			
		||||
 | 
			
		||||
export const unixTimestampComponentFieldSettings = new SchemaSettings({
 | 
			
		||||
  name: 'fieldSettings:component:UnixTimestamp',
 | 
			
		||||
  items: [
 | 
			
		||||
    {
 | 
			
		||||
      name: 'dateDisplayFormat',
 | 
			
		||||
      Component: SchemaSettingsDateFormat as any,
 | 
			
		||||
      useComponentProps() {
 | 
			
		||||
        const schema = useFieldSchema();
 | 
			
		||||
        const { fieldSchema: tableColumnSchema } = useColumnSchema();
 | 
			
		||||
        const fieldSchema = tableColumnSchema || schema;
 | 
			
		||||
        return {
 | 
			
		||||
          fieldSchema,
 | 
			
		||||
        };
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  ],
 | 
			
		||||
});
 | 
			
		||||
@ -1,18 +1,20 @@
 | 
			
		||||
import { connect, mapReadPretty, observer, useField } from '@formily/react';
 | 
			
		||||
import { Select, SelectProps, Tag } from 'antd';
 | 
			
		||||
import React, { useContext } from 'react';
 | 
			
		||||
import { Cascader, Select, SelectProps, Tag } from 'antd';
 | 
			
		||||
import React, { useCallback, useContext, useMemo } from 'react';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
import { useSelfAndChildrenCollections } from '../../../collection-manager/action-hooks';
 | 
			
		||||
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../collection-manager/hooks';
 | 
			
		||||
import { useCompile } from '../../hooks';
 | 
			
		||||
import { FilterContext } from '../filter/context';
 | 
			
		||||
import { useDataSourceManager } from '../../../data-source';
 | 
			
		||||
import { parseCollectionName } from '../../../collection-manager';
 | 
			
		||||
 | 
			
		||||
export type CollectionSelectProps = SelectProps<any, any> & {
 | 
			
		||||
  filter?: (item: any, index: number, array: any[]) => boolean;
 | 
			
		||||
  isTableOid?: boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function useOptions({ filter, isTableOid }: CollectionSelectProps) {
 | 
			
		||||
function useCollectionOptions({ filter, isTableOid }: CollectionSelectProps) {
 | 
			
		||||
  const compile = useCompile();
 | 
			
		||||
  const field: any = useField();
 | 
			
		||||
  const ctx: any = useContext(FilterContext);
 | 
			
		||||
@ -29,20 +31,30 @@ function useOptions({ filter, isTableOid }: CollectionSelectProps) {
 | 
			
		||||
    typeof filter === 'function'
 | 
			
		||||
      ? ((inheritCollections || currentCollections) as any[]).filter(filter)
 | 
			
		||||
      : inheritCollections || currentCollections;
 | 
			
		||||
  return filtered
 | 
			
		||||
    .filter((item) => !item.hidden)
 | 
			
		||||
    .map((item) => ({
 | 
			
		||||
      label: compile(item.title || item.label),
 | 
			
		||||
      value: item.name || item.value,
 | 
			
		||||
      color: item.category?.color,
 | 
			
		||||
    }));
 | 
			
		||||
  return useMemo(
 | 
			
		||||
    () =>
 | 
			
		||||
      filtered
 | 
			
		||||
        .filter((item) => !item.hidden)
 | 
			
		||||
        .map((item) => ({
 | 
			
		||||
          label: compile(item.title || item.label),
 | 
			
		||||
          value: item.name || item.value,
 | 
			
		||||
          color: item.category?.color,
 | 
			
		||||
        })),
 | 
			
		||||
    [filtered],
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const CollectionSelect = connect(
 | 
			
		||||
  (props: CollectionSelectProps) => {
 | 
			
		||||
    const { filter, ...others } = props;
 | 
			
		||||
    const options = useOptions(props);
 | 
			
		||||
    const options = useCollectionOptions(props);
 | 
			
		||||
    const { t } = useTranslation();
 | 
			
		||||
    const optionFilter = useCallback(
 | 
			
		||||
      (input, option) =>
 | 
			
		||||
        (option?.label.toLowerCase() ?? '').includes(input.toLocaleLowerCase()) ||
 | 
			
		||||
        (option?.value.toString().toLowerCase() ?? '').includes(input.toLocaleLowerCase()),
 | 
			
		||||
      [],
 | 
			
		||||
    );
 | 
			
		||||
    return (
 | 
			
		||||
      <Select
 | 
			
		||||
        // @ts-ignore
 | 
			
		||||
@ -52,10 +64,7 @@ export const CollectionSelect = connect(
 | 
			
		||||
        popupMatchSelectWidth={false}
 | 
			
		||||
        {...others}
 | 
			
		||||
        showSearch
 | 
			
		||||
        filterOption={(input, option) =>
 | 
			
		||||
          (option?.label.toLowerCase() ?? '').includes(input.toLocaleLowerCase()) ||
 | 
			
		||||
          (option?.value.toString().toLowerCase() ?? '').includes(input.toLocaleLowerCase())
 | 
			
		||||
        }
 | 
			
		||||
        filterOption={optionFilter}
 | 
			
		||||
        options={options}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
@ -65,7 +74,7 @@ export const CollectionSelect = connect(
 | 
			
		||||
      (props: CollectionSelectProps) => {
 | 
			
		||||
        const { mode } = props;
 | 
			
		||||
        const compile = useCompile();
 | 
			
		||||
        const options = useOptions(props).filter((option) => {
 | 
			
		||||
        const options = useCollectionOptions(props).filter((option) => {
 | 
			
		||||
          if (mode === 'multiple') {
 | 
			
		||||
            return (props.value ?? []).includes(option.value);
 | 
			
		||||
          }
 | 
			
		||||
@ -86,3 +95,88 @@ export const CollectionSelect = connect(
 | 
			
		||||
    ),
 | 
			
		||||
  ),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
export type DataSourceSelectProps = SelectProps<any, any> & {
 | 
			
		||||
  filter?: (item: any, index: number, array: any[]) => boolean;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function useDataSourceOptions({ filter }: DataSourceSelectProps) {
 | 
			
		||||
  const compile = useCompile();
 | 
			
		||||
  const dataSourceManager = useDataSourceManager();
 | 
			
		||||
  const dataSources = dataSourceManager.getDataSources();
 | 
			
		||||
  return useMemo(
 | 
			
		||||
    () => [
 | 
			
		||||
      {
 | 
			
		||||
        label: compile('Main'),
 | 
			
		||||
        value: 'main',
 | 
			
		||||
      },
 | 
			
		||||
      ...(typeof filter === 'function' ? dataSources.filter(filter) : dataSources).map((item) => ({
 | 
			
		||||
        label: item.displayName,
 | 
			
		||||
        value: item.key,
 | 
			
		||||
      })),
 | 
			
		||||
    ],
 | 
			
		||||
    [dataSources, filter],
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const DataSourceSelect = connect((props: DataSourceSelectProps) => {
 | 
			
		||||
  const { filter, ...others } = props;
 | 
			
		||||
  const options = useDataSourceOptions(props);
 | 
			
		||||
  const { t } = useTranslation();
 | 
			
		||||
  const optionFilter = useCallback(
 | 
			
		||||
    (input, option) =>
 | 
			
		||||
      (option?.label.toLowerCase() ?? '').includes(input.toLocaleLowerCase()) ||
 | 
			
		||||
      (option?.value.toString().toLowerCase() ?? '').includes(input.toLocaleLowerCase()),
 | 
			
		||||
    [],
 | 
			
		||||
  );
 | 
			
		||||
  return (
 | 
			
		||||
    <Select
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      role="button"
 | 
			
		||||
      data-testid="select-datasource"
 | 
			
		||||
      placeholder={t('Select data source')}
 | 
			
		||||
      popupMatchSelectWidth={false}
 | 
			
		||||
      {...others}
 | 
			
		||||
      showSearch
 | 
			
		||||
      filterOption={optionFilter}
 | 
			
		||||
      options={options}
 | 
			
		||||
    />
 | 
			
		||||
  );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export const DataSourceCollectionCascader = connect((props) => {
 | 
			
		||||
  const dataSourceManager = useDataSourceManager();
 | 
			
		||||
  const compile = useCompile();
 | 
			
		||||
  const { value, onChange, dataSourceFilter, collectionFilter, ...others } = props;
 | 
			
		||||
  const [dataSourceName, collectionName] = parseCollectionName(value);
 | 
			
		||||
  const path = [dataSourceName, collectionName].filter(Boolean);
 | 
			
		||||
  const dataSources = dataSourceManager.getDataSources();
 | 
			
		||||
 | 
			
		||||
  const options = useMemo(() => {
 | 
			
		||||
    return (dataSourceFilter ? dataSources.filter(dataSourceFilter) : dataSources).map((dataSource) => {
 | 
			
		||||
      return {
 | 
			
		||||
        label: compile(dataSource.displayName),
 | 
			
		||||
        value: dataSource.key,
 | 
			
		||||
        children: dataSource.collectionManager.collectionInstancesArr
 | 
			
		||||
          .filter(collectionFilter ?? ((collection) => !collection.hidden))
 | 
			
		||||
          .map((collection) => {
 | 
			
		||||
            return {
 | 
			
		||||
              label: compile(collection.title),
 | 
			
		||||
              value: collection.name,
 | 
			
		||||
            };
 | 
			
		||||
          }),
 | 
			
		||||
      };
 | 
			
		||||
    });
 | 
			
		||||
  }, [dataSources, dataSourceFilter, collectionFilter]);
 | 
			
		||||
 | 
			
		||||
  const handleChange = useCallback(
 | 
			
		||||
    (value) => {
 | 
			
		||||
      if (!value) {
 | 
			
		||||
        return onChange(value);
 | 
			
		||||
      }
 | 
			
		||||
      onChange(value[0] === 'main' ? value[1] : value.join(':'));
 | 
			
		||||
    },
 | 
			
		||||
    [onChange],
 | 
			
		||||
  );
 | 
			
		||||
  return <Cascader showSearch {...others} options={options} value={path} onChange={handleChange} />;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,7 @@ const InternalRangePicker = connect(
 | 
			
		||||
export const DatePicker = (props) => {
 | 
			
		||||
  const { utc = true } = useDatePickerContext();
 | 
			
		||||
  const value = Array.isArray(props.value) ? props.value[0] : props.value;
 | 
			
		||||
  console.log(value);
 | 
			
		||||
  props = { utc, ...props };
 | 
			
		||||
  return <InternalDatePicker {...props} value={value} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -51,5 +51,7 @@ export * from './tree-select';
 | 
			
		||||
export * from './upload';
 | 
			
		||||
export * from './variable';
 | 
			
		||||
export * from './custom-cascader';
 | 
			
		||||
export * from './unixTimestamp';
 | 
			
		||||
export * from './nanoIDInput';
 | 
			
		||||
 | 
			
		||||
import './index.less';
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,46 @@
 | 
			
		||||
import { customAlphabet as Alphabet } from 'nanoid';
 | 
			
		||||
import React, { useEffect } from 'react';
 | 
			
		||||
import { LoadingOutlined } from '@ant-design/icons';
 | 
			
		||||
import { connect, mapProps, mapReadPretty, useForm } from '@formily/react';
 | 
			
		||||
import { Input as AntdInput } from 'antd';
 | 
			
		||||
import { ReadPretty } from '../input';
 | 
			
		||||
import { useCollectionField } from '../../../data-source/collection-field/CollectionFieldProvider';
 | 
			
		||||
import { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
export const NanoIDInput = Object.assign(
 | 
			
		||||
  connect(
 | 
			
		||||
    AntdInput,
 | 
			
		||||
    mapProps((props: any, field: any) => {
 | 
			
		||||
      const { size, customAlphabet } = useCollectionField();
 | 
			
		||||
      const { t } = useTranslation();
 | 
			
		||||
      const form = useForm();
 | 
			
		||||
      function isValidNanoid(value) {
 | 
			
		||||
        if (value.length !== size) {
 | 
			
		||||
          return t('Field value size is') + ` ${size}`;
 | 
			
		||||
        }
 | 
			
		||||
        for (let i = 0; i < value.length; i++) {
 | 
			
		||||
          if (customAlphabet.indexOf(value[i]) === -1) {
 | 
			
		||||
            return t(`Field value do not meet the requirements`);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      useEffect(() => {
 | 
			
		||||
        if (!field.initialValue) {
 | 
			
		||||
          field.setInitialValue(Alphabet(customAlphabet, size)());
 | 
			
		||||
        }
 | 
			
		||||
        form.setFieldState(field.props.name, (state) => {
 | 
			
		||||
          state.validator = isValidNanoid;
 | 
			
		||||
        });
 | 
			
		||||
      }, []);
 | 
			
		||||
      return {
 | 
			
		||||
        ...props,
 | 
			
		||||
        suffix: <span>{field?.['loading'] || field?.['validating'] ? <LoadingOutlined /> : props.suffix}</span>,
 | 
			
		||||
      };
 | 
			
		||||
    }),
 | 
			
		||||
    mapReadPretty(ReadPretty.Input),
 | 
			
		||||
  ),
 | 
			
		||||
  {
 | 
			
		||||
    ReadPretty: ReadPretty.Input,
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1 @@
 | 
			
		||||
export * from './NanoIDInput';
 | 
			
		||||
@ -21,9 +21,17 @@ Radio.__ANT_RADIO = true;
 | 
			
		||||
 | 
			
		||||
Radio.Group = connect(
 | 
			
		||||
  AntdRadio.Group,
 | 
			
		||||
  mapProps({
 | 
			
		||||
    dataSource: 'options',
 | 
			
		||||
  }),
 | 
			
		||||
  mapProps(
 | 
			
		||||
    {
 | 
			
		||||
      dataSource: 'options',
 | 
			
		||||
    },
 | 
			
		||||
    (props) => {
 | 
			
		||||
      return {
 | 
			
		||||
        ...props,
 | 
			
		||||
        value: props.value && typeof props.value !== 'boolean' ? props.value.toString() : props.value,
 | 
			
		||||
      };
 | 
			
		||||
    },
 | 
			
		||||
  ),
 | 
			
		||||
  mapReadPretty((props) => {
 | 
			
		||||
    if (!isValid(props.value)) {
 | 
			
		||||
      return <div></div>;
 | 
			
		||||
 | 
			
		||||
@ -9,11 +9,11 @@ import React from 'react';
 | 
			
		||||
const options = [
 | 
			
		||||
  {
 | 
			
		||||
    label: '男',
 | 
			
		||||
    value: 1,
 | 
			
		||||
    value: '1',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: '女',
 | 
			
		||||
    value: 2,
 | 
			
		||||
    value: '2',
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,12 +8,12 @@ import React from 'react';
 | 
			
		||||
const options = [
 | 
			
		||||
  {
 | 
			
		||||
    label: '男',
 | 
			
		||||
    value: 1,
 | 
			
		||||
    value: '1',
 | 
			
		||||
    color: 'blue',
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: '女',
 | 
			
		||||
    value: 2,
 | 
			
		||||
    value: '2',
 | 
			
		||||
    color: 'red',
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@ -122,7 +122,7 @@ const InternalSelect = connect(
 | 
			
		||||
        }
 | 
			
		||||
        return undefined;
 | 
			
		||||
      }
 | 
			
		||||
      return v;
 | 
			
		||||
      return v ? v.toString() : v;
 | 
			
		||||
    };
 | 
			
		||||
    return (
 | 
			
		||||
      <AntdSelect
 | 
			
		||||
 | 
			
		||||
@ -44,7 +44,10 @@ export function getCurrentOptions(values: string | string[], dataSource: any[],
 | 
			
		||||
    if (!options) return [];
 | 
			
		||||
    const current: Option[] = [];
 | 
			
		||||
    for (const value of arrValues) {
 | 
			
		||||
      const option = options.find((v) => v[fieldNames.value] === value) || { value, label: value };
 | 
			
		||||
      const option = options.find((v) => v[fieldNames.value] == value) || {
 | 
			
		||||
        value,
 | 
			
		||||
        label: value ? value.toString() : value,
 | 
			
		||||
      };
 | 
			
		||||
      current.push(option);
 | 
			
		||||
    }
 | 
			
		||||
    return current;
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,49 @@
 | 
			
		||||
import { connect, mapReadPretty } from '@formily/react';
 | 
			
		||||
import React, { useMemo } from 'react';
 | 
			
		||||
import { DatePicker } from '../date-picker';
 | 
			
		||||
import dayjs from 'dayjs';
 | 
			
		||||
 | 
			
		||||
const toValue = (value: any, accuracy) => {
 | 
			
		||||
  if (value) {
 | 
			
		||||
    return timestampToDate(value, accuracy);
 | 
			
		||||
  }
 | 
			
		||||
  return null;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function timestampToDate(timestamp, accuracy = 'millisecond') {
 | 
			
		||||
  if (accuracy === 'second') {
 | 
			
		||||
    timestamp *= 1000; // 如果精确度是秒级,则将时间戳乘以1000转换为毫秒级
 | 
			
		||||
  }
 | 
			
		||||
  return dayjs(timestamp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getTimestamp(date, accuracy = 'millisecond') {
 | 
			
		||||
  if (accuracy === 'second') {
 | 
			
		||||
    return dayjs(date).unix();
 | 
			
		||||
  } else {
 | 
			
		||||
    return dayjs(date).valueOf(); // 默认返回毫秒级时间戳
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const UnixTimestamp = connect(
 | 
			
		||||
  (props) => {
 | 
			
		||||
    const { value, onChange, accuracy } = props;
 | 
			
		||||
    const v = useMemo(() => toValue(value, accuracy), [value]);
 | 
			
		||||
    return (
 | 
			
		||||
      <DatePicker
 | 
			
		||||
        {...props}
 | 
			
		||||
        value={v}
 | 
			
		||||
        onChange={(v: any) => {
 | 
			
		||||
          if (onChange) {
 | 
			
		||||
            onChange(getTimestamp(v, accuracy));
 | 
			
		||||
          }
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
    );
 | 
			
		||||
  },
 | 
			
		||||
  mapReadPretty((props) => {
 | 
			
		||||
    const { value, accuracy } = props;
 | 
			
		||||
    const v = useMemo(() => toValue(value, accuracy), [value]);
 | 
			
		||||
    return <DatePicker.ReadPretty {...props} value={v} />;
 | 
			
		||||
  }),
 | 
			
		||||
);
 | 
			
		||||
@ -0,0 +1 @@
 | 
			
		||||
export * from './UnixTimestamp';
 | 
			
		||||
@ -43,6 +43,7 @@ import { subformPopoverComponentFieldSettings } from '../modules/fields/componen
 | 
			
		||||
import { selectComponentFieldSettings } from '../modules/fields/component/Select/selectComponentFieldSettings';
 | 
			
		||||
import { subTablePopoverComponentFieldSettings } from '../modules/fields/component/SubTable/subTablePopoverComponentFieldSettings';
 | 
			
		||||
import { tagComponentFieldSettings } from '../modules/fields/component/Tag/tagComponentFieldSettings';
 | 
			
		||||
import { unixTimestampComponentFieldSettings } from '../modules/fields/component/UnixTimestamp/unixTimestampComponentFieldSettings';
 | 
			
		||||
 | 
			
		||||
export class SchemaSettingsPlugin extends Plugin {
 | 
			
		||||
  async load() {
 | 
			
		||||
@ -91,6 +92,8 @@ export class SchemaSettingsPlugin extends Plugin {
 | 
			
		||||
    this.schemaSettingsManager.add(subformPopoverComponentFieldSettings);
 | 
			
		||||
    this.schemaSettingsManager.add(subTablePopoverComponentFieldSettings);
 | 
			
		||||
    this.schemaSettingsManager.add(datePickerComponentFieldSettings);
 | 
			
		||||
    this.schemaSettingsManager.add(unixTimestampComponentFieldSettings);
 | 
			
		||||
 | 
			
		||||
    this.schemaSettingsManager.add(fileManagerComponentFieldSettings);
 | 
			
		||||
    this.schemaSettingsManager.add(tagComponentFieldSettings);
 | 
			
		||||
    this.schemaSettingsManager.add(cascadeSelectComponentFieldSettings);
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "create-nocobase-app",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "src/index.js",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,16 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/data-source-manager",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/actions": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/actions": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/cache": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/database": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/resourcer": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "@types/jsonwebtoken": "^8.5.8",
 | 
			
		||||
    "jsonwebtoken": "^8.5.1"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -9,3 +9,4 @@ export * from './load-default-actions';
 | 
			
		||||
export * from './types';
 | 
			
		||||
 | 
			
		||||
export * from './data-source-with-database';
 | 
			
		||||
export * from './utils';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								packages/core/data-source-manager/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								packages/core/data-source-manager/src/utils.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
export function parseCollectionName(collection: string) {
 | 
			
		||||
  if (!collection) {
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
  const dataSourceCollection = collection.split(':');
 | 
			
		||||
  const collectionName = dataSourceCollection.pop();
 | 
			
		||||
  const dataSourceName = dataSourceCollection[0] ?? 'main';
 | 
			
		||||
  return [dataSourceName, collectionName];
 | 
			
		||||
}
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/database",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/logger": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/logger": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "async-mutex": "^0.3.2",
 | 
			
		||||
    "chalk": "^4.1.1",
 | 
			
		||||
    "cron-parser": "4.4.0",
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,39 @@
 | 
			
		||||
import { mockDatabase } from '../';
 | 
			
		||||
import { Database } from '../../database';
 | 
			
		||||
 | 
			
		||||
describe('nanoid field', () => {
 | 
			
		||||
  let db: Database;
 | 
			
		||||
 | 
			
		||||
  beforeEach(async () => {
 | 
			
		||||
    db = mockDatabase();
 | 
			
		||||
    await db.clean({ drop: true });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  afterEach(async () => {
 | 
			
		||||
    await db.close();
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create nanoid field type', async () => {
 | 
			
		||||
    const Test = db.collection({
 | 
			
		||||
      name: 'tests',
 | 
			
		||||
      autoGenId: false,
 | 
			
		||||
      fields: [
 | 
			
		||||
        {
 | 
			
		||||
          type: 'nanoid',
 | 
			
		||||
          name: 'id',
 | 
			
		||||
          primaryKey: true,
 | 
			
		||||
          size: 21,
 | 
			
		||||
          customAlphabet: '1234567890abcdef',
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          type: 'nanoid',
 | 
			
		||||
          name: 'id2',
 | 
			
		||||
        },
 | 
			
		||||
      ],
 | 
			
		||||
    });
 | 
			
		||||
    await Test.sync();
 | 
			
		||||
    const test = await Test.model.create();
 | 
			
		||||
    expect(test.id).toHaveLength(21);
 | 
			
		||||
    expect(test.id2).toHaveLength(12);
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@ -25,6 +25,7 @@ import { TimeFieldOptions } from './time-field';
 | 
			
		||||
import { UidFieldOptions } from './uid-field';
 | 
			
		||||
import { UUIDFieldOptions } from './uuid-field';
 | 
			
		||||
import { VirtualFieldOptions } from './virtual-field';
 | 
			
		||||
import { NanoidFieldOptions } from './nanoid-field';
 | 
			
		||||
 | 
			
		||||
export * from './array-field';
 | 
			
		||||
export * from './belongs-to-field';
 | 
			
		||||
@ -48,6 +49,7 @@ export * from './time-field';
 | 
			
		||||
export * from './uid-field';
 | 
			
		||||
export * from './uuid-field';
 | 
			
		||||
export * from './virtual-field';
 | 
			
		||||
export * from './nanoid-field';
 | 
			
		||||
 | 
			
		||||
export type FieldOptions =
 | 
			
		||||
  | BaseFieldOptions
 | 
			
		||||
@ -70,6 +72,7 @@ export type FieldOptions =
 | 
			
		||||
  | DateFieldOptions
 | 
			
		||||
  | UidFieldOptions
 | 
			
		||||
  | UUIDFieldOptions
 | 
			
		||||
  | NanoidFieldOptions
 | 
			
		||||
  | PasswordFieldOptions
 | 
			
		||||
  | ContextFieldOptions
 | 
			
		||||
  | BelongsToFieldOptions
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										40
									
								
								packages/core/database/src/fields/nanoid-field.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								packages/core/database/src/fields/nanoid-field.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,40 @@
 | 
			
		||||
import { DataTypes } from 'sequelize';
 | 
			
		||||
import { BaseColumnFieldOptions, Field } from './field';
 | 
			
		||||
import { customAlphabet, nanoid } from 'nanoid';
 | 
			
		||||
 | 
			
		||||
const DEFAULT_SIZE = 12;
 | 
			
		||||
export class NanoidField extends Field {
 | 
			
		||||
  get dataType() {
 | 
			
		||||
    return DataTypes.STRING;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init() {
 | 
			
		||||
    const { name, size, customAlphabet: customAlphabetOptions } = this.options;
 | 
			
		||||
 | 
			
		||||
    this.listener = async (instance) => {
 | 
			
		||||
      const value = instance.get(name);
 | 
			
		||||
      if (!value) {
 | 
			
		||||
        const nanoIdFunc = customAlphabetOptions ? customAlphabet(customAlphabetOptions) : nanoid;
 | 
			
		||||
        instance.set(name, nanoIdFunc(size || DEFAULT_SIZE));
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bind() {
 | 
			
		||||
    super.bind();
 | 
			
		||||
    this.on('beforeCreate', this.listener);
 | 
			
		||||
    this.on('beforeUpdate', this.listener);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  unbind() {
 | 
			
		||||
    super.unbind();
 | 
			
		||||
    this.off('beforeCreate', this.listener);
 | 
			
		||||
    this.off('beforeUpdate', this.listener);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface NanoidFieldOptions extends BaseColumnFieldOptions {
 | 
			
		||||
  type: 'nanoid';
 | 
			
		||||
  size?: number;
 | 
			
		||||
  customAlphabet?: string;
 | 
			
		||||
}
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
const postgres = {
 | 
			
		||||
  'character varying': 'string',
 | 
			
		||||
  varchar: 'string',
 | 
			
		||||
  'character varying': ['string', 'uuid', 'nanoid'],
 | 
			
		||||
  varchar: ['string', 'uuid', 'nanoid'],
 | 
			
		||||
  char: ['string', 'uuid', 'nanoid'],
 | 
			
		||||
 | 
			
		||||
  character: 'string',
 | 
			
		||||
  text: 'text',
 | 
			
		||||
  char: 'string',
 | 
			
		||||
  oid: 'string',
 | 
			
		||||
  name: 'string',
 | 
			
		||||
 | 
			
		||||
@ -29,7 +30,7 @@ const postgres = {
 | 
			
		||||
  path: 'json',
 | 
			
		||||
  polygon: 'json',
 | 
			
		||||
  circle: 'json',
 | 
			
		||||
  uuid: 'string',
 | 
			
		||||
  uuid: 'uuid',
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const mysql = {
 | 
			
		||||
@ -41,10 +42,10 @@ const mysql = {
 | 
			
		||||
  'tinyint unsigned': ['integer', 'boolean', 'sort'],
 | 
			
		||||
  'mediumint unsigned': ['integer', 'boolean', 'sort'],
 | 
			
		||||
 | 
			
		||||
  char: 'string',
 | 
			
		||||
  char: ['string', 'uuid', 'nanoid'],
 | 
			
		||||
  varchar: ['string', 'uuid', 'nanoid'],
 | 
			
		||||
  date: 'date',
 | 
			
		||||
  time: 'time',
 | 
			
		||||
  varchar: 'string',
 | 
			
		||||
  text: 'text',
 | 
			
		||||
  longtext: 'text',
 | 
			
		||||
  int: ['integer', 'sort'],
 | 
			
		||||
@ -64,7 +65,7 @@ const mysql = {
 | 
			
		||||
 | 
			
		||||
const sqlite = {
 | 
			
		||||
  text: 'text',
 | 
			
		||||
  varchar: 'string',
 | 
			
		||||
  varchar: ['string', 'uuid', 'nanoid'],
 | 
			
		||||
 | 
			
		||||
  integer: 'integer',
 | 
			
		||||
  real: 'real',
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/devtools",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./src/index.js",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/build": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/client": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/test": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/build": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/client": "0.20.0-alpha.9",
 | 
			
		||||
    "@nocobase/test": "0.20.0-alpha.9",
 | 
			
		||||
    "@types/koa": "^2.13.4",
 | 
			
		||||
    "@types/koa-bodyparser": "^4.3.4",
 | 
			
		||||
    "@types/lodash": "^4.14.177",
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/evaluators",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@formulajs/formulajs": "4.2.0",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "mathjs": "^10.6.0"
 | 
			
		||||
  },
 | 
			
		||||
  "repository": {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/logger",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "nocobase logging library",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/resourcer",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "deepmerge": "^4.2.2",
 | 
			
		||||
    "koa-compose": "^4.1.0",
 | 
			
		||||
    "lodash": "^4.17.21",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/sdk",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "types": "lib/index.d.ts",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
    "name": "@nocobase/server",
 | 
			
		||||
    "version": "0.20.0-alpha.8",
 | 
			
		||||
    "version": "0.20.0-alpha.9",
 | 
			
		||||
    "main": "lib/index.js",
 | 
			
		||||
    "types": "./lib/index.d.ts",
 | 
			
		||||
    "license": "Apache-2.0",
 | 
			
		||||
@ -10,18 +10,18 @@
 | 
			
		||||
        "@koa/cors": "^3.1.0",
 | 
			
		||||
        "@koa/multer": "^3.0.2",
 | 
			
		||||
        "@koa/router": "^9.4.0",
 | 
			
		||||
        "@nocobase/acl": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/actions": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/auth": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/cache": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/data-source-manager": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/database": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/evaluators": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/logger": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/resourcer": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/sdk": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/telemetry": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
        "@nocobase/acl": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/actions": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/auth": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/cache": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/data-source-manager": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/database": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/evaluators": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/logger": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/resourcer": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/sdk": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/telemetry": "0.20.0-alpha.9",
 | 
			
		||||
        "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
        "@types/decompress": "4.2.4",
 | 
			
		||||
        "@types/ini": "^1.3.31",
 | 
			
		||||
        "@types/koa-send": "^4.1.3",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/telemetry",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "nocobase telemetry library",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
  "main": "./lib/index.js",
 | 
			
		||||
@ -11,7 +11,7 @@
 | 
			
		||||
    "directory": "packages/telemetry"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/utils": "0.20.0-alpha.9",
 | 
			
		||||
    "@opentelemetry/api": "^1.7.0",
 | 
			
		||||
    "@opentelemetry/instrumentation": "^0.46.0",
 | 
			
		||||
    "@opentelemetry/resources": "^1.19.0",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/test",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "module": "./src/index.ts",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
@ -40,7 +40,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "@faker-js/faker": "8.1.0",
 | 
			
		||||
    "@nocobase/server": "0.20.0-alpha.8",
 | 
			
		||||
    "@nocobase/server": "0.20.0-alpha.9",
 | 
			
		||||
    "@playwright/test": "^1.42.1",
 | 
			
		||||
    "@testing-library/react": "^14.0.0",
 | 
			
		||||
    "@testing-library/user-event": "^14.4.3",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/utils",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "lib/index.js",
 | 
			
		||||
  "types": "./lib/index.d.ts",
 | 
			
		||||
  "license": "Apache-2.0",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "权限控制",
 | 
			
		||||
  "description": "Based on roles, resources, and actions, access control can precisely manage interface configuration permissions, data operation permissions, menu access permissions, and plugin permissions.",
 | 
			
		||||
  "description.zh-CN": "基于角色、资源和操作的权限控制,可以精确控制界面配置权限、数据操作权限、菜单访问权限、插件权限。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/acl",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-action-bulk-edit",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-bulk-edit",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-edit",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-action-bulk-update",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-bulk-update",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-bulk-update",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-action-duplicate",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-duplicate",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-duplicate",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-action-print",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-print",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-print",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-api-doc",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "API documentation",
 | 
			
		||||
  "displayName.zh-CN": "API 文档",
 | 
			
		||||
  "description": "An OpenAPI documentation generator for NocoBase HTTP API.",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "认证:API 密钥",
 | 
			
		||||
  "description": "Allows users to use API key to access application's HTTP API",
 | 
			
		||||
  "description.zh-CN": "允许用户使用 API 密钥访问应用的 HTTP API",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/api-keys",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-audit-logs",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "Audit logs (deprecated)",
 | 
			
		||||
  "displayName.zh-CN": "审计日志(废弃)",
 | 
			
		||||
  "description": "This plugin is deprecated. There will be a new audit log plugin in the future.",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-auth",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/auth",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "应用的备份与还原",
 | 
			
		||||
  "description": "Backup and restore applications for scenarios such as application replication, migration, and upgrades.",
 | 
			
		||||
  "description.zh-CN": "备份和还原应用,可用于应用的复制、迁移、升级等场景。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/backup-restore",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-calendar",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "Calendar",
 | 
			
		||||
  "displayName.zh-CN": "日历",
 | 
			
		||||
  "description": "Provides callendar collection template and block for managing date data, typically for date/time related information such as events, appointments, tasks, and so on.",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "认证:CAS",
 | 
			
		||||
  "description": "CAS authentication.",
 | 
			
		||||
  "description.zh-CN": "通过 CAS 协议认证身份。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/auth-cas",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "图表(废弃)",
 | 
			
		||||
  "description": "The plugin has been deprecated, please use the data visualization plugin instead.",
 | 
			
		||||
  "description.zh-CN": "已废弃插件,请使用数据可视化插件代替。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-china-region",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "Administrative divisions of China",
 | 
			
		||||
  "displayName.zh-CN": "中国行政区划",
 | 
			
		||||
  "description": "Provides data and field type for administrative divisions of China.",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "WEB 客户端",
 | 
			
		||||
  "description": "Provides a client interface for the NocoBase server",
 | 
			
		||||
  "description.zh-CN": "为 NocoBase 服务端提供客户端界面",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "数据源:主数据库",
 | 
			
		||||
  "description": "NocoBase main database, supports relational databases such as MySQL, PostgreSQL, SQLite and so on.",
 | 
			
		||||
  "description.zh-CN": "NocoBase 主数据库,支持 MySQL、PostgreSQL、SQLite 等关系型数据库。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/data-source-main",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/data-source-main",
 | 
			
		||||
 | 
			
		||||
@ -496,23 +496,16 @@ test.describe('form item & view form', () => {
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  test('field component', async ({ page, mockPage, mockRecords }) => {
 | 
			
		||||
    await (async (mockPage, mockRecords) => {
 | 
			
		||||
      const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
 | 
			
		||||
      const record = (await mockRecords('general', 1))[0];
 | 
			
		||||
      await nocoPage.goto();
 | 
			
		||||
  test('field component', async ({ page, mockPage, mockRecord }) => {
 | 
			
		||||
    const nocoPage = await mockPage(oneTableBlockWithAddNewAndViewAndEditAndAssociationFields).waitForInit();
 | 
			
		||||
    await mockRecord('general');
 | 
			
		||||
    await nocoPage.goto();
 | 
			
		||||
 | 
			
		||||
      return record;
 | 
			
		||||
    })(mockPage, mockRecords);
 | 
			
		||||
    await (async (page: Page) => {
 | 
			
		||||
      await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
 | 
			
		||||
    })(page);
 | 
			
		||||
    await (async (page: Page, fieldName: string) => {
 | 
			
		||||
      await page.getByLabel(`block-item-CollectionField-general-form-general.${fieldName}-${fieldName}`).hover();
 | 
			
		||||
      await page
 | 
			
		||||
        .getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.${fieldName}`)
 | 
			
		||||
        .hover();
 | 
			
		||||
    })(page, 'oneToMany');
 | 
			
		||||
    await page.getByLabel('action-Action.Link-View record-view-general-table-0').click();
 | 
			
		||||
    await page.getByLabel(`block-item-CollectionField-general-form-general.oneToMany-oneToMany`).hover();
 | 
			
		||||
    await page
 | 
			
		||||
      .getByLabel(`designer-schema-settings-CollectionField-FormItem.Designer-general-general.oneToMany`)
 | 
			
		||||
      .hover();
 | 
			
		||||
    await page.getByRole('menuitem', { name: 'Field component' }).click();
 | 
			
		||||
 | 
			
		||||
    // 断言支持的选项
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-custom-request",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-custom-request",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/action-custom-request",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-data-source-manager",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "displayName": "Data source manager",
 | 
			
		||||
  "displayName.zh-CN": "数据源管理",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-data-visualization",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "Data visualization",
 | 
			
		||||
  "displayName.zh-CN": "数据可视化",
 | 
			
		||||
  "description": "Provides data visualization feature, including chart block and chart filter block, support line charts, area charts, bar charts and more than a dozen kinds of charts, you can also extend more chart types.",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-disable-pm-add",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "peerDependencies": {
 | 
			
		||||
    "@nocobase/client": "0.x",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "错误处理器",
 | 
			
		||||
  "description": "Handling application errors and exceptions.",
 | 
			
		||||
  "description.zh-CN": "处理应用程序中的错误和异常。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-excel-formula-field",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "操作:导出记录",
 | 
			
		||||
  "description": "Export filtered records to excel, you can configure which fields to export.",
 | 
			
		||||
  "description.zh-CN": "导出筛选后的记录到 Excel 中,可以配置导出哪些字段。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-export",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-file-manager",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "File manager",
 | 
			
		||||
  "displayName.zh-CN": "文件管理器",
 | 
			
		||||
  "description": "Provides files storage services with files collection template and attachment field.",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "数据表字段:公式",
 | 
			
		||||
  "description": "Configure and store the results of calculations between multiple field values in the same record, supporting both Math.js and Excel formula functions.",
 | 
			
		||||
  "description.zh-CN": "可以配置并存储同一条记录的多字段值之间的计算结果,支持 Math.js 和 Excel formula functions 两种引擎",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/field-formula",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-gantt",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "displayName": "Block: Gantt",
 | 
			
		||||
  "displayName.zh-CN": "区块:甘特图",
 | 
			
		||||
  "description": "Provides Gantt block.",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "可视化数据表管理",
 | 
			
		||||
  "description": "An ER diagram-like tool. Currently only the Master database is supported.",
 | 
			
		||||
  "description.zh-CN": "类似 ER 图的工具,目前只支持主数据库。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/graph-collection-manager",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "区块:iframe",
 | 
			
		||||
  "description": "Create an iframe block on the page to embed and display external web pages or content.",
 | 
			
		||||
  "description.zh-CN": "在页面上创建和管理iframe,用于嵌入和展示外部网页或内容。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/block-iframe",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "操作:导入记录",
 | 
			
		||||
  "description": "Import records using excel templates. You can configure which fields to import and templates will be generated automatically.",
 | 
			
		||||
  "description.zh-CN": "使用 Excel 模板导入数据,可以配置导入哪些字段,自动生成模板。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/action-import",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-kanban",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/block-kanban",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/block-kanban",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-localization-management",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/localization-management",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/localization-management",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "日志",
 | 
			
		||||
  "description": "Server-side logs, mainly including API request logs and system runtime logs, and allows to package and download log files.",
 | 
			
		||||
  "description.zh-CN": "服务端日志,主要包括接口请求日志和系统运行日志,并支持打包和下载日志文件。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/logger",
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
  "name": "@nocobase/plugin-map",
 | 
			
		||||
  "displayName": "Block: Map",
 | 
			
		||||
  "displayName.zh-CN": "区块:地图",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "Map block, support Gaode map and Google map, you can also extend more map types.",
 | 
			
		||||
  "description.zh-CN": "地图区块,支持高德地图和 Google 地图,你也可以扩展更多地图类型。",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "数学公式字段",
 | 
			
		||||
  "description": "A powerful mathematical formula field plugin designed to provide flexible mathematical and formula calculation capabilities for databases or data management systems. It seamlessly integrates with various database systems such as MySQL, PostgreSQL, and offers an intuitive user interface for defining and executing mathematical formula fields.",
 | 
			
		||||
  "description.zh-CN": "一个功能强大的数学公式字段插件,旨在为数据库或数据管理系统提供灵活的数学计算和公式计算功能。它可以与各种数据库系统(如MySQL、PostgreSQL)无缝集成,并提供直观的用户界面来定义和执行数学公式字段。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-mobile-client",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/mobile-client",
 | 
			
		||||
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/mobile-client",
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
  "name": "@nocobase/plugin-mock-collections",
 | 
			
		||||
  "displayName": "mock-collections",
 | 
			
		||||
  "description": "mock-collections",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "peerDependencies": {
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "多应用管理器",
 | 
			
		||||
  "description": "Dynamically create multiple apps without separate deployments.",
 | 
			
		||||
  "description.zh-CN": "无需单独部署即可动态创建多个应用。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/multi-app-manager",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "多应用数据表共享",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "description.zh-CN": "",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@formily/react": "2.x",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-notifications",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "认证:OIDC",
 | 
			
		||||
  "description": "OIDC (OpenID Connect) authentication.",
 | 
			
		||||
  "description.zh-CN": "通过 OIDC (OpenID Connect) 协议认证身份。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/auth-oidc",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "认证:SAML 2.0",
 | 
			
		||||
  "description": "SAML 2.0 authentication.",
 | 
			
		||||
  "description.zh-CN": "通过 SAML 2.0 协议认证身份。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/auth-saml",
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@nocobase/plugin-sample-hello",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "displayName": "Hello",
 | 
			
		||||
  "displayName.zh-CN": "Hello",
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@
 | 
			
		||||
  "displayName.zh-CN": "数据表字段:自动编码",
 | 
			
		||||
  "description": "Automatically generate codes based on configured rules, supporting combinations of dates, numbers, and text.",
 | 
			
		||||
  "description.zh-CN": "根据配置的规则自动生成编码,支持日期、数字、文本的组合。",
 | 
			
		||||
  "version": "0.20.0-alpha.8",
 | 
			
		||||
  "version": "0.20.0-alpha.9",
 | 
			
		||||
  "license": "AGPL-3.0",
 | 
			
		||||
  "main": "./dist/server/index.js",
 | 
			
		||||
  "homepage": "https://docs.nocobase.com/handbook/field-sequence",
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user