diff --git a/packages/core/acl/package.json b/packages/core/acl/package.json index e4eb3b469..4f7540967 100644 --- a/packages/core/acl/package.json +++ b/packages/core/acl/package.json @@ -13,6 +13,7 @@ "minimatch": "^5.1.1" }, "devDependencies": { - "@types/lodash": "4.17.0" + "@types/lodash": "4.17.0", + "@types/node": "^20.12.12" } } diff --git a/packages/core/acl/tsconfig.json b/packages/core/acl/tsconfig.json new file mode 100644 index 000000000..f81087962 --- /dev/null +++ b/packages/core/acl/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "typeRoots": ["./node_modules/@types"] + } +} diff --git a/packages/core/build/package.json b/packages/core/build/package.json index fffcf5fd2..a853cfc0c 100755 --- a/packages/core/build/package.json +++ b/packages/core/build/package.json @@ -20,7 +20,7 @@ "@hapi/topo": "^6.0.0", "@pnpm/find-workspace-dir": "^6.0.3", "@pnpm/workspace.find-packages": "^1.1.12", - "@types/gulp": "^4.0.13", + "@types/fs-extra": "11.0.4", "@types/tar": "^6.1.5", "@vercel/ncc": "0.36.1", "@vitejs/plugin-react": "^4.0.0", @@ -29,8 +29,6 @@ "execa": "^5.1.1", "fast-glob": "^3.3.1", "fs-extra": "^11.1.1", - "gulp": "4.0.2", - "gulp-typescript": "6.0.0-alpha.1", "sass": "^1.75.0", "tar": "^6.2.0", "tsup": "7.2.0", diff --git a/packages/core/build/src/build.ts b/packages/core/build/src/build.ts index e55890df0..c1e0704b8 100755 --- a/packages/core/build/src/build.ts +++ b/packages/core/build/src/build.ts @@ -1,29 +1,46 @@ -import execa from 'execa'; -import chalk from 'chalk'; +import { EventEmitter } from 'events'; import path from 'path'; -import { - PACKAGES_PATH, - getPluginPackages, - CORE_CLIENT, - CORE_APP, - getCjsPackages, - getPresetsPackages, - ROOT_PATH, - ESM_PACKAGES, -} from './constant'; -import { buildClient } from './buildClient'; -import { buildCjs } from './buildCjs'; -import { buildPlugin } from './buildPlugin'; -import { buildDeclaration } from './buildDeclaration'; -import { PkgLog, getPkgLog, toUnixPath, getPackageJson, getUserConfig, UserConfig, writeToCache, readFromCache } from './utils'; -import { getPackages } from './utils/getPackages'; + import type { Project } from '@pnpm/workspace.find-packages'; -import { tarPlugin } from './tarPlugin' +import chalk from 'chalk'; +import execa from 'execa'; + +import { buildCjs } from './buildCjs'; +import { buildClient } from './buildClient'; +import { buildDeclaration } from './buildDeclaration'; import { buildEsm } from './buildEsm'; +import { buildPlugin } from './buildPlugin'; +import { + CORE_APP, + CORE_CLIENT, + ESM_PACKAGES, + getCjsPackages, + getPluginPackages, + getPresetsPackages, + PACKAGES_PATH, + ROOT_PATH, +} from './constant'; +import { tarPlugin } from './tarPlugin'; +import { + getPackageJson, + getPkgLog, + getUserConfig, + PkgLog, + readFromCache, + toUnixPath, + UserConfig, + writeToCache, +} from './utils'; +import { getPackages } from './utils/getPackages'; const BUILD_ERROR = 'build-error'; +global.__bus = new EventEmitter(); export async function build(pkgs: string[]) { + const messages = []; + (global.__bus as EventEmitter).on('build:errors', (message) => { + messages.push(message); + }); const isDev = process.argv.includes('--development'); process.env.NODE_ENV = isDev ? 'development' : 'production'; @@ -35,9 +52,9 @@ export async function build(pkgs: string[]) { if (packages.length === 0) { let msg = ''; if (pkgs.length) { - msg = `'${pkgs.join(', ')}' did not match any packages` + msg = `'${pkgs.join(', ')}' did not match any packages`; } else { - msg = 'No package matched' + msg = 'No package matched'; } console.warn(chalk.yellow(`[@tachybase/build]: ${msg}`)); return; @@ -53,7 +70,7 @@ export async function build(pkgs: string[]) { if (clientCore) { await buildPackage(clientCore, 'es', buildClient); } - const esmPackages = cjsPackages.filter(pkg => ESM_PACKAGES.includes(pkg.manifest.name)); + const esmPackages = cjsPackages.filter((pkg) => ESM_PACKAGES.includes(pkg.manifest.name)); await buildPackages(esmPackages, 'es', buildEsm); // plugins/*、samples/* @@ -70,6 +87,16 @@ export async function build(pkgs: string[]) { }); } writeToCache(BUILD_ERROR, {}); + if (messages.length > 0) { + console.log('❌ build errors:'); + messages.forEach((message) => { + console.log('🐛 ', message); + }); + + setTimeout(() => { + throw new Error('build error.'); + }, 0); + } } export async function buildPackages( @@ -78,7 +105,7 @@ export async function buildPackages( doBuildPackage: (cwd: string, userConfig: UserConfig, sourcemap: boolean, log?: PkgLog) => Promise, ) { for await (const pkg of packages) { - writeToCache(BUILD_ERROR, { pkg: pkg.manifest.name}) + writeToCache(BUILD_ERROR, { pkg: pkg.manifest.name }); await buildPackage(pkg, targetDir, doBuildPackage); } } diff --git a/packages/core/build/src/buildDeclaration.ts b/packages/core/build/src/buildDeclaration.ts index fef85ac16..74816c24e 100644 --- a/packages/core/build/src/buildDeclaration.ts +++ b/packages/core/build/src/buildDeclaration.ts @@ -1,35 +1,66 @@ -import gulp from 'gulp'; -import gulpTs from 'gulp-typescript'; +import type { EventEmitter } from 'events'; import path from 'path'; -import { ROOT_PATH } from './constant'; + +import fg from 'fast-glob'; +import fs from 'fs-extra'; +import ts from 'typescript'; + +import { globExcludeFiles, ROOT_PATH } from './constant'; export const buildDeclaration = (cwd: string, targetDir: string) => { - return new Promise((resolve, reject) => { - const srcPath = path.join(cwd, 'src'); - const targetPath = path.join(cwd, targetDir); + return new Promise<{ exitCode: 1 | 0; messages: string[] }>((resolve, reject) => { + const localTsConfigPath = path.join(cwd, 'tsconfig.json'); - const tsConfig = gulpTs.createProject(path.join(ROOT_PATH, 'tsconfig.json')); - delete tsConfig.config.compilerOptions.paths; - const patterns = [ - path.join(srcPath, '**/*.{ts,tsx}'), - `!${path.join(srcPath, '**/fixtures{,/**}')}`, - `!${path.join(srcPath, '**/demos{,/**}')}`, - `!${path.join(srcPath, '**/__test__{,/**}')}`, - `!${path.join(srcPath, '**/__tests__{,/**}')}`, - `!${path.join(srcPath, '**/__e2e__{,/**}')}`, - `!${path.join(srcPath, '**/*.mdx')}`, - `!${path.join(srcPath, '**/*.md')}`, - `!${path.join(srcPath, '**/*.+(test|e2e|spec).+(js|jsx|ts|tsx)')}`, - `!${path.join(srcPath, '**/tsconfig{,.*}.json')}`, - `!${path.join(srcPath, '.umi{,-production,-test}{,/**}')}`, - ]; - gulp - .src(patterns, { base: srcPath, allowEmpty: true }) - .pipe(gulpTs(tsConfig.config.compilerOptions)) - .on('error', () => { - console.log('errors in build declareation.'); - }) - .dts.pipe(gulp.dest(targetPath)) - .on('end', resolve); + // 读取 tsconfig.json 文件路径 + const configPath = fs.existsSync(localTsConfigPath) ? localTsConfigPath : path.join(ROOT_PATH, 'tsconfig.json'); + + // 读取并解析 tsconfig.json + const configFile = ts.readConfigFile(configPath, ts.sys.readFile); + + if (configFile.error) { + const message = ts.flattenDiagnosticMessageText(configFile.error.messageText, '\n'); + return reject(`Error reading tsconfig.json: ${message}`); + } + + // 解析 tsconfig.json 配置 + const parsedCommandLine = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath)); + parsedCommandLine.options.paths = {}; + + // 更新编译选项,设置输出目录为 lib,启用声明文件生成 + parsedCommandLine.options.outDir = path.join(cwd, targetDir); + parsedCommandLine.options.declaration = true; + parsedCommandLine.options.emitDeclarationOnly = true; + + parsedCommandLine.fileNames = fg.globSync(['src/**/*.{ts,tsx}', ...globExcludeFiles], { cwd, absolute: true }); + parsedCommandLine.options.rootDir = path.join(cwd, 'src'); + + // 编译 + const program = ts.createProgram(parsedCommandLine.fileNames, parsedCommandLine.options); + const emitResult = program.emit(); + + // 处理编译错误 + const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + const messages = []; + allDiagnostics.forEach((diagnostic) => { + try { + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + (global.__bus as EventEmitter).emit( + 'build:errors', + `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`, + ); + console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); + } else { + (global.__bus as EventEmitter).emit('build:errors', ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + } catch (e) { + console.log(e); + } + }); + + const exitCode = emitResult.emitSkipped ? 1 : 0; + resolve({ exitCode, messages }); }); }; diff --git a/packages/core/cache/src/cache-manager.ts b/packages/core/cache/src/cache-manager.ts index a334630bb..011ad2d3a 100644 --- a/packages/core/cache/src/cache-manager.ts +++ b/packages/core/cache/src/cache-manager.ts @@ -1,13 +1,16 @@ -import { FactoryStore, Store, caching, Cache as BasicCache } from 'cache-manager'; -import { Cache } from './cache'; -import lodash from 'lodash'; +import { Cache as BasicCache, caching, FactoryStore, Store } from 'cache-manager'; import { RedisStore, redisStore } from 'cache-manager-redis-yet'; import deepmerge from 'deepmerge'; -import { MemoryBloomFilter } from './bloom-filter/memory-bloom-filter'; -import { BloomFilter } from './bloom-filter'; -import { RedisBloomFilter } from './bloom-filter/redis-bloom-filter'; +import lodash from 'lodash'; -type StoreOptions = { +import { BloomFilter } from './bloom-filter'; +import { MemoryBloomFilter } from './bloom-filter/memory-bloom-filter'; +import { RedisBloomFilter } from './bloom-filter/redis-bloom-filter'; +import { Cache } from './cache'; + +export type { FactoryStore } from 'cache-manager'; + +export type StoreOptions = { store?: 'memory' | FactoryStore; close?: (store: Store) => Promise; // global config diff --git a/packages/core/client/package.json b/packages/core/client/package.json index b99c1c93d..558f173de 100644 --- a/packages/core/client/package.json +++ b/packages/core/client/package.json @@ -13,9 +13,9 @@ "@antv/g2plot": "^2.4.18", "@ctrl/tinycolor": "^3.6.0", "@dnd-kit/accessibility": "^3.1.0", - "@dnd-kit/core": "^5.0.1", - "@dnd-kit/modifiers": "^6.0.0", - "@dnd-kit/sortable": "^6.0.0", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/modifiers": "^7.0.0", + "@dnd-kit/sortable": "^8.0.0", "@dnd-kit/utilities": "^3.2.2", "@emotion/css": "^11.7.1", "@tachybase/components": "workspace:*", diff --git a/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx b/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx index 1b46c83a1..6d0755491 100644 --- a/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx +++ b/packages/core/client/src/acl/Configuration/ConfigureCenter.tsx @@ -1,13 +1,15 @@ -import { Checkbox, message, Table } from 'antd'; import React, { createContext, useContext, useMemo, useState } from 'react'; + +import { Checkbox, message, Table } from 'antd'; +import { omit } from 'lodash'; import { useTranslation } from 'react-i18next'; + import { useAPIClient, useRequest } from '../../api-client'; +import { useApp } from '../../application'; import { SettingsCenterContext } from '../../pm'; import { useRecord } from '../../record-provider'; -import { useStyles } from '../style'; -import { useApp } from '../../application'; import { useCompile } from '../../schema-component'; -import { omit } from 'lodash'; +import { useStyles } from '../style'; const getParentKeys = (tree, func, path = []) => { if (!tree) return []; @@ -87,7 +89,7 @@ export const SettingsCenterConfigure = () => { message.success(t('Saved successfully')); }; return ( - className={styles} loading={loading} rowKey={'key'} diff --git a/packages/core/client/src/acl/Configuration/MenuConfigure.tsx b/packages/core/client/src/acl/Configuration/MenuConfigure.tsx index 4f64db6d6..114a40def 100644 --- a/packages/core/client/src/acl/Configuration/MenuConfigure.tsx +++ b/packages/core/client/src/acl/Configuration/MenuConfigure.tsx @@ -1,7 +1,9 @@ +import React, { useState } from 'react'; + import { Checkbox, message, Table } from 'antd'; import { uniq } from 'lodash'; -import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; + import { useAPIClient, useRequest } from '../../api-client'; import { useRecord } from '../../record-provider'; import { useStyles } from '../style'; @@ -105,7 +107,7 @@ export const MenuConfigure = () => { }; return ( -
className={styles} loading={loading} rowKey={'uid'} diff --git a/packages/core/client/src/acl/Configuration/RoleTable.tsx b/packages/core/client/src/acl/Configuration/RoleTable.tsx index e9b2adf10..56effd260 100644 --- a/packages/core/client/src/acl/Configuration/RoleTable.tsx +++ b/packages/core/client/src/acl/Configuration/RoleTable.tsx @@ -1,5 +1,7 @@ -import { Spin } from 'antd'; import React, { createContext, useContext } from 'react'; + +import { Spin } from 'antd'; + import { useRequest } from '../../api-client'; import { SchemaComponent, SchemaComponentContext } from '../../schema-component'; import { MenuItemsProvider } from '../Configuration/MenuItemsProvider'; @@ -9,7 +11,7 @@ import { roleSchema } from './schemas/roles'; const AvailableActionsContext = createContext([]); AvailableActionsContext.displayName = 'AvailableActionsContext'; -const AvailableActionsProver: React.FC = (props) => { +const AvailableActionsProver = (props) => { const { data, loading } = useRequest<{ data: any[]; }>({ diff --git a/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx b/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx index bfd2eb550..d90ca5452 100644 --- a/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx +++ b/packages/core/client/src/acl/Configuration/RolesResourcesActions.tsx @@ -1,10 +1,11 @@ +import React, { createContext } from 'react'; import { FormItem, FormLayout } from '@tachybase/components'; -import { ArrayField } from '@tachybase/schema'; -import { connect, useField, useForm } from '@tachybase/schema'; +import { ArrayField, connect, useField, useForm } from '@tachybase/schema'; + import { Checkbox, Table, Tag } from 'antd'; import { isEmpty } from 'lodash'; -import React, { createContext } from 'react'; import { useTranslation } from 'react-i18next'; + import { useCollectionManager_deprecated, useCompile, useRecord } from '../..'; import { useStyles } from '../style'; import { useAvailableActions } from './RoleTable'; @@ -93,7 +94,7 @@ export const RolesResourcesActions = connect((props) => { -
className={styles} size={'small'} pagination={false} @@ -157,7 +158,7 @@ export const RolesResourcesActions = connect((props) => { /> -
className={styles} pagination={false} dataSource={fieldPermissions} diff --git a/packages/core/client/src/acl/Configuration/ScopeSelect.tsx b/packages/core/client/src/acl/Configuration/ScopeSelect.tsx index f27ae7e94..fb54f3b1f 100644 --- a/packages/core/client/src/acl/Configuration/ScopeSelect.tsx +++ b/packages/core/client/src/acl/Configuration/ScopeSelect.tsx @@ -1,12 +1,13 @@ -import { createForm } from '@tachybase/schema'; import React, { createContext, useContext, useMemo, useState } from 'react'; +import { createForm } from '@tachybase/schema'; + import { FormProvider, SchemaComponent } from '../../schema-component'; import { scopesSchema } from './schemas/scopes'; const RolesResourcesScopesSelectedRowKeysContext = createContext(null); RolesResourcesScopesSelectedRowKeysContext.displayName = 'RolesResourcesScopesSelectedRowKeysContext'; -const RolesResourcesScopesSelectedRowKeysProvider: React.FC = (props) => { +const RolesResourcesScopesSelectedRowKeysProvider = (props) => { const [keys, setKeys] = useState([]); return ( diff --git a/packages/core/client/src/acl/Configuration/StrategyActions.tsx b/packages/core/client/src/acl/Configuration/StrategyActions.tsx index 89c92217e..2191d3bc3 100644 --- a/packages/core/client/src/acl/Configuration/StrategyActions.tsx +++ b/packages/core/client/src/acl/Configuration/StrategyActions.tsx @@ -1,8 +1,9 @@ -import { ArrayField } from '@tachybase/schema'; -import { connect, useField } from '@tachybase/schema'; -import { Checkbox, Select, Table, Tag } from 'antd'; import React from 'react'; +import { ArrayField, connect, useField } from '@tachybase/schema'; + +import { Checkbox, Select, Table, Tag } from 'antd'; import { useTranslation } from 'react-i18next'; + import { useCompile } from '../..'; import { useAvailableActions } from './RoleTable'; @@ -42,7 +43,7 @@ export const StrategyActions = connect((props) => { const scopes = toScopes(field.value); return (
-
size={'small'} pagination={false} columns={[ diff --git a/packages/core/client/src/application/RouterManager.tsx b/packages/core/client/src/application/RouterManager.tsx index 405dc37aa..40a988fba 100644 --- a/packages/core/client/src/application/RouterManager.tsx +++ b/packages/core/client/src/application/RouterManager.tsx @@ -1,5 +1,6 @@ -import { get, set } from 'lodash'; import React, { ComponentType } from 'react'; + +import { get, set } from 'lodash'; import { BrowserRouter, BrowserRouterProps, @@ -10,6 +11,7 @@ import { RouteObject, useRoutes, } from 'react-router-dom'; + import { Application } from './Application'; import { BlankComponent, RouterContextCleaner } from './components'; @@ -128,7 +130,12 @@ export class RouterManager { return element; }; - const RenderRouter: React.FC<{ BaseLayout?: ComponentType }> = ({ BaseLayout = BlankComponent }) => { + const RenderRouter = ({ + BaseLayout = BlankComponent, + }: { + BaseLayout?: ComponentType; + children?: React.ReactNode; + }) => { return ( diff --git a/packages/core/client/src/application/components/BlankComponent.tsx b/packages/core/client/src/application/components/BlankComponent.tsx index 535f64eb1..321caf4dc 100644 --- a/packages/core/client/src/application/components/BlankComponent.tsx +++ b/packages/core/client/src/application/components/BlankComponent.tsx @@ -1,3 +1,3 @@ -import React, { FC, ReactNode } from 'react'; +import React, { ReactNode } from 'react'; -export const BlankComponent: FC<{ children?: ReactNode }> = ({ children }) => <>{children}; +export const BlankComponent = ({ children }: { children?: ReactNode }) => <>{children}; diff --git a/packages/core/client/src/application/components/MainComponent.tsx b/packages/core/client/src/application/components/MainComponent.tsx index e64ab0b11..bb75584c7 100644 --- a/packages/core/client/src/application/components/MainComponent.tsx +++ b/packages/core/client/src/application/components/MainComponent.tsx @@ -1,4 +1,5 @@ import React, { useMemo } from 'react'; + import { useApp } from '../hooks'; export const MainComponent = React.memo(() => { diff --git a/packages/core/client/src/application/schema-initializer/components/SchemaInitializerSubMenu.tsx b/packages/core/client/src/application/schema-initializer/components/SchemaInitializerSubMenu.tsx index 4f2d06525..457518467 100644 --- a/packages/core/client/src/application/schema-initializer/components/SchemaInitializerSubMenu.tsx +++ b/packages/core/client/src/application/schema-initializer/components/SchemaInitializerSubMenu.tsx @@ -56,7 +56,7 @@ export const useSchemaInitializerSubMenuContext = () => { return React.useContext(SchemaInitializerSubMenuContext); }; -export const SchemaInitializerMenu: FC = (props) => { +export const SchemaInitializerMenu = (props: MenuProps) => { const { componentCls, hashId } = useSchemaInitializerStyles(); const { items, ...others } = props; const { token } = theme.useToken(); diff --git a/packages/core/client/src/application/utils/index.tsx b/packages/core/client/src/application/utils/index.tsx index 14c41009e..9161d092e 100644 --- a/packages/core/client/src/application/utils/index.tsx +++ b/packages/core/client/src/application/utils/index.tsx @@ -1,4 +1,5 @@ import React, { ComponentType, FC } from 'react'; + import { BlankComponent } from '../components'; export function normalizeContainer(container: Element | ShadowRoot | string): Element | null { @@ -21,9 +22,9 @@ export function normalizeContainer(container: Element | ShadowRoot | string): El } export const compose = (...components: [ComponentType, any][]) => { - const Component = components.reduce((Parent, child) => { + const Component = components.reduce>((Parent, child) => { const [Child, childProps] = child; - const ComposeComponent: FC = ({ children }) => ( + const ComposeComponent = ({ children }) => ( {children} diff --git a/packages/core/client/src/async-data-provider/index.tsx b/packages/core/client/src/async-data-provider/index.tsx index 128738226..c25996230 100644 --- a/packages/core/client/src/async-data-provider/index.tsx +++ b/packages/core/client/src/async-data-provider/index.tsx @@ -1,5 +1,7 @@ -import { Result } from 'ahooks/es/useRequest/src/types'; import React, { createContext, useContext } from 'react'; + +import { Result } from 'ahooks/es/useRequest/src/types'; + import { useRequest } from '../api-client'; export const AsyncDataContext = createContext & { state?: any; setState?: any }>(null); @@ -10,9 +12,10 @@ export interface AsyncDataProviderProps { request?: any; uid?: string; onSuccess?: (data, params) => void; + children: React.ReactNode; } -export const AsyncDataProvider: React.FC = (props) => { +export const AsyncDataProvider = (props: AsyncDataProviderProps) => { const { value, request, children, ...others } = props; const result = useRequest(request, { ...others }); if (value) { diff --git a/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx b/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx index d7d8afbed..428dc3758 100644 --- a/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx +++ b/packages/core/client/src/block-provider/BlockSchemaComponentProvider.tsx @@ -1,39 +1,40 @@ import React from 'react'; + import { Plugin } from '../application/Plugin'; import { ActionSchemaToolbar } from '../modules/actions/ActionSchemaToolbar'; import { BlockSchemaToolbar } from '../modules/blocks/BlockSchemaToolbar'; +import { useDetailsWithPaginationDecoratorProps } from '../modules/blocks/data-blocks/details-multi/hooks/useDetailsWithPaginationDecoratorProps'; +import { useDetailsWithPaginationProps } from '../modules/blocks/data-blocks/details-multi/hooks/useDetailsWithPaginationProps'; +import { useDetailsDecoratorProps } from '../modules/blocks/data-blocks/details-single/hooks/useDetailsDecoratorProps'; +import { useDetailsProps } from '../modules/blocks/data-blocks/details-single/hooks/useDetailsProps'; import { FormItemSchemaToolbar } from '../modules/blocks/data-blocks/form/FormItemSchemaToolbar'; import { useCreateFormBlockDecoratorProps } from '../modules/blocks/data-blocks/form/hooks/useCreateFormBlockDecoratorProps'; import { useCreateFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useCreateFormBlockProps'; import { useEditFormBlockDecoratorProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockDecoratorProps'; import { useEditFormBlockProps } from '../modules/blocks/data-blocks/form/hooks/useEditFormBlockProps'; +import { useGridCardBlockDecoratorProps } from '../modules/blocks/data-blocks/grid-card/hooks/useGridCardBlockDecoratorProps'; +import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps'; +import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps'; +import { useTableBlockDecoratorProps } from '../modules/blocks/data-blocks/table/hooks/useTableBlockDecoratorProps'; +import { useTableBlockProps } from '../modules/blocks/data-blocks/table/hooks/useTableBlockProps'; import { TableColumnSchemaToolbar } from '../modules/blocks/data-blocks/table/TableColumnSchemaToolbar'; import { CollapseItemSchemaToolbar } from '../modules/blocks/filter-blocks/collapse/CollapseItemSchemaToolbar'; +import { useCollapseBlockDecoratorProps } from '../modules/blocks/filter-blocks/collapse/hooks/useCollapseBlockDecoratorProps'; +import { useFilterFormBlockDecoratorProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockDecoratorProps'; +import { useFilterFormBlockProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockProps'; import { SchemaComponentOptions } from '../schema-component'; import { RecordLink, useParamsFromRecord, useSourceIdFromParentRecord, useSourceIdFromRecord } from './BlockProvider'; import { DetailsBlockProvider, useDetailsBlockProps } from './DetailsBlockProvider'; import { FilterFormBlockProvider } from './FilterFormBlockProvider'; import { FormBlockProvider, useFormBlockProps } from './FormBlockProvider'; import { FormFieldProvider, useFormFieldProps } from './FormFieldProvider'; +import * as bp from './hooks'; import { TableBlockProvider } from './TableBlockProvider'; -import { useTableBlockProps } from '../modules/blocks/data-blocks/table/hooks/useTableBlockProps'; import { TableFieldProvider, useTableFieldProps } from './TableFieldProvider'; import { TableSelectorProvider, useTableSelectorProps } from './TableSelectorProvider'; -import * as bp from './hooks'; -import { useTableBlockDecoratorProps } from '../modules/blocks/data-blocks/table/hooks/useTableBlockDecoratorProps'; -import { useListBlockDecoratorProps } from '../modules/blocks/data-blocks/list/hooks/useListBlockDecoratorProps'; -import { useTableSelectorDecoratorProps } from '../modules/blocks/data-blocks/table-selector/hooks/useTableSelectorDecoratorProps'; -import { useCollapseBlockDecoratorProps } from '../modules/blocks/filter-blocks/collapse/hooks/useCollapseBlockDecoratorProps'; -import { useFilterFormBlockProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockProps'; -import { useFilterFormBlockDecoratorProps } from '../modules/blocks/filter-blocks/form/hooks/useFilterFormBlockDecoratorProps'; -import { useGridCardBlockDecoratorProps } from '../modules/blocks/data-blocks/grid-card/hooks/useGridCardBlockDecoratorProps'; -import { useDetailsProps } from '../modules/blocks/data-blocks/details-single/hooks/useDetailsProps'; -import { useDetailsWithPaginationProps } from '../modules/blocks/data-blocks/details-multi/hooks/useDetailsWithPaginationProps'; -import { useDetailsDecoratorProps } from '../modules/blocks/data-blocks/details-single/hooks/useDetailsDecoratorProps'; -import { useDetailsWithPaginationDecoratorProps } from '../modules/blocks/data-blocks/details-multi/hooks/useDetailsWithPaginationDecoratorProps'; // TODO: delete this, replaced by `BlockSchemaComponentPlugin` -export const BlockSchemaComponentProvider: React.FC = (props) => { +export const BlockSchemaComponentProvider = (props) => { return ( ({ }); CollectionHistoryContext.displayName = 'CollectionHistoryContext'; -export const CollectionHistoryProvider: React.FC = (props) => { +export const CollectionHistoryProvider = (props) => { const api = useAPIClient(); const options = { diff --git a/packages/core/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx b/packages/core/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx index 70194df24..8dcda424d 100644 --- a/packages/core/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx +++ b/packages/core/client/src/collection-manager/CollectionManagerSchemaComponentProvider.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import { SchemaComponentOptions } from '..'; + import { CollectionProvider_deprecated, ResourceActionProvider, useDataSourceFromRAC } from '.'; +import { SchemaComponentOptions } from '..'; import * as hooks from './action-hooks'; import { DataSourceProvider_deprecated, ds, SubFieldDataSourceProvider_deprecated } from './sub-table'; -export const CollectionManagerSchemaComponentProvider: React.FC = (props) => { +export const CollectionManagerSchemaComponentProvider = (props) => { return ( = (props) => { +export const SQLRequestProvider = (props: { manual?: boolean; children: React.ReactNode }) => { const api = useAPIClient(); const form = useForm(); const record = useRecord(); diff --git a/packages/core/client/src/collection-manager/templates/expression.tsx b/packages/core/client/src/collection-manager/templates/expression.tsx index 1d3206a39..6cd24f911 100644 --- a/packages/core/client/src/collection-manager/templates/expression.tsx +++ b/packages/core/client/src/collection-manager/templates/expression.tsx @@ -1,6 +1,7 @@ import { getOptions } from '@tachybase/evaluators/client'; -import { getConfigurableProperties } from './properties'; + import { CollectionTemplate } from '../../data-source/collection-template/CollectionTemplate'; +import { getConfigurableProperties } from './properties'; export class ExpressionCollectionTemplate extends CollectionTemplate { name = 'expression'; diff --git a/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx b/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx index a682d0ad4..7a2b50a19 100644 --- a/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx +++ b/packages/core/client/src/data-source/data-block/DataBlockProvider.tsx @@ -1,4 +1,4 @@ -import React, { createContext, FC, ReactNode, useContext, useMemo } from 'react'; +import React, { createContext, ReactNode, useContext, useMemo } from 'react'; import { ACLCollectionProvider } from '../../acl/ACLProvider'; import { UseRequestOptions, UseRequestService } from '../../api-client'; @@ -134,8 +134,8 @@ export const AssociationOrCollectionProvider = (props: { ); }; -export const DataBlockProvider: FC = withDynamicSchemaProps( - (props) => { +export const DataBlockProvider = withDynamicSchemaProps( + (props: DataBlockProviderProps & { children?: ReactNode }) => { const { collection, association, dataSource, children, layoutDirection, ...resets } = props as Partial; const configSetting = { diff --git a/packages/core/client/src/data-source/data-block/DataBlockRequestProvider.tsx b/packages/core/client/src/data-source/data-block/DataBlockRequestProvider.tsx index 7572dcc09..9f432ecb3 100644 --- a/packages/core/client/src/data-source/data-block/DataBlockRequestProvider.tsx +++ b/packages/core/client/src/data-source/data-block/DataBlockRequestProvider.tsx @@ -1,4 +1,4 @@ -import React, { createContext, FC, useContext, useMemo } from 'react'; +import React, { createContext, useContext, useMemo } from 'react'; import { useDeepCompareEffect, useUpdateEffect } from 'ahooks'; @@ -77,7 +77,7 @@ function useParentRequest(options: Omit) { ); } -export const BlockRequestProvider: FC = ({ children }) => { +export const BlockRequestProvider = ({ children }: { children: React.ReactNode }) => { const props = useDataBlockProps(); const { action, diff --git a/packages/core/client/src/document-title/index.tsx b/packages/core/client/src/document-title/index.tsx index 1b0db6e97..2bd0ba374 100644 --- a/packages/core/client/src/document-title/index.tsx +++ b/packages/core/client/src/document-title/index.tsx @@ -1,6 +1,8 @@ import React, { createContext, useContext, useEffect, useState } from 'react'; + import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; + import { Plugin } from '../application/Plugin'; import { useSystemSettings } from '../system-settings'; @@ -15,7 +17,11 @@ export const DocumentTitleContext = createContext({ }); DocumentTitleContext.displayName = 'DocumentTitleContext'; -export const DocumentTitleProvider: React.FC<{ addonBefore?: string; addonAfter?: string }> = (props) => { +export const DocumentTitleProvider = (props: { + addonBefore?: string; + addonAfter?: string; + children: React.ReactNode; +}) => { const { addonBefore, addonAfter } = props; const { t } = useTranslation(); const [title, setTitle] = useState(''); @@ -37,7 +43,7 @@ export const DocumentTitleProvider: React.FC<{ addonBefore?: string; addonAfter? ); }; -export const RemoteDocumentTitleProvider: React.FC = (props) => { +export const RemoteDocumentTitleProvider = (props) => { const ctx = useSystemSettings(); return {props.children}; }; diff --git a/packages/core/client/src/filter-provider/FilterProvider.tsx b/packages/core/client/src/filter-provider/FilterProvider.tsx index 138fc2ed6..008e29aed 100644 --- a/packages/core/client/src/filter-provider/FilterProvider.tsx +++ b/packages/core/client/src/filter-provider/FilterProvider.tsx @@ -1,12 +1,13 @@ -import { useField, useFieldSchema } from '@tachybase/schema'; -import { uniqBy } from 'lodash'; import React, { createContext, useCallback, useEffect, useRef } from 'react'; +import { useField, useFieldSchema } from '@tachybase/schema'; + +import { uniqBy } from 'lodash'; + import { useBlockRequestContext } from '../block-provider/BlockProvider'; import { CollectionFieldOptions_deprecated, useCollection_deprecated } from '../collection-manager'; +import { useDataLoadingMode } from '../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; import { removeNullCondition } from '../schema-component'; import { mergeFilter, useAssociatedFields } from './utils'; -import { useDataLoadingMode } from '../modules/blocks/data-blocks/details-multi/setDataLoadingModeSettingsItem'; -import { GeneralField } from '@tachybase/schema'; enum FILTER_OPERATOR { AND = '$and', @@ -74,7 +75,7 @@ FilterContext.displayName = 'FilterContext'; * @param props * @returns */ -export const FilterBlockProvider: React.FC = ({ children }) => { +export const FilterBlockProvider = ({ children }) => { const [dataBlocks, setDataBlocks] = React.useState([]); return {children}; }; diff --git a/packages/core/client/src/icon/Icon.tsx b/packages/core/client/src/icon/Icon.tsx index 8b9a226e7..d535de617 100644 --- a/packages/core/client/src/icon/Icon.tsx +++ b/packages/core/client/src/icon/Icon.tsx @@ -1,6 +1,7 @@ +import React from 'react'; + import * as antIcons from '@ant-design/icons'; import AntdIcon, { createFromIconfontCN } from '@ant-design/icons'; -import React from 'react'; let IconFont: any; @@ -35,7 +36,7 @@ interface IconProps { [key: string]: any; } -export const Icon = (props: IconProps) => { +export const Icon = (props: IconProps): React.ReactNode => { const { type = '', component, ...restProps } = props; if (component) { return ; diff --git a/packages/core/client/src/modules/blocks/data-blocks/form/fieldSettingsFormItem.tsx b/packages/core/client/src/modules/blocks/data-blocks/form/fieldSettingsFormItem.tsx index f0fd17608..d2aa7ed11 100644 --- a/packages/core/client/src/modules/blocks/data-blocks/form/fieldSettingsFormItem.tsx +++ b/packages/core/client/src/modules/blocks/data-blocks/form/fieldSettingsFormItem.tsx @@ -1,4 +1,3 @@ -import { useContextConfigSetting } from '@tachybase/client'; import { ArrayCollapse, FormLayout } from '@tachybase/components'; import { Field, ISchema, useField, useFieldSchema } from '@tachybase/schema'; @@ -10,6 +9,7 @@ import { SchemaSettings } from '../../../../application/schema-settings/SchemaSe import { useFormBlockContext } from '../../../../block-provider'; import { useCollection_deprecated, useCollectionManager_deprecated } from '../../../../collection-manager'; import { useFieldComponentName } from '../../../../common/useFieldComponentName'; +import { useContextConfigSetting } from '../../../../data-source'; import { useDesignable, useValidateSchema } from '../../../../schema-component'; import { useIsFormReadPretty } from '../../../../schema-component/antd/form-item/FormItem.Settings'; import { getTempFieldState } from '../../../../schema-component/antd/form-v2/utils'; diff --git a/packages/core/client/src/modules/blocks/useSourceId.tsx b/packages/core/client/src/modules/blocks/useSourceId.tsx index f67eaf228..8fa6bbeb2 100644 --- a/packages/core/client/src/modules/blocks/useSourceId.tsx +++ b/packages/core/client/src/modules/blocks/useSourceId.tsx @@ -1,5 +1,4 @@ -import { useDataBlockProps } from '../..'; -import { useDataBlockParentRecord } from '../../block-provider/hooks/useDataBlockParentRecord'; +import { useDataBlockParentRecord, useDataBlockProps } from '../..'; import { useSourceKey } from './useSourceKey'; export const useSourceId = () => { diff --git a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx index dea04d23c..a78fcf3ca 100644 --- a/packages/core/client/src/schema-component/antd/action/ActionBar.tsx +++ b/packages/core/client/src/schema-component/antd/action/ActionBar.tsx @@ -23,13 +23,14 @@ export interface ActionBarContextValue { */ forceProps?: ActionBarContextForceProps; parentComponents?: string[]; + children?: React.ReactNode; } const ActionBarContext = React.createContext({ container: null, }); -export const ActionBarProvider: React.FC = ({ children, ...props }) => { +export const ActionBarProvider = ({ children, ...props }: ActionBarContextValue) => { return {children}; }; diff --git a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx index 0ceef816a..6a4fde971 100644 --- a/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx +++ b/packages/core/client/src/schema-component/antd/association-filter/AssociationFilter.Item.tsx @@ -1,16 +1,18 @@ -import { CloseOutlined, SearchOutlined } from '@ant-design/icons'; +import React, { ChangeEvent, MouseEvent, useMemo, useState } from 'react'; import { useFieldSchema } from '@tachybase/schema'; + +import { CloseOutlined, SearchOutlined } from '@ant-design/icons'; import { Col, Collapse, Input, Row, Tree } from 'antd'; import cls from 'classnames'; -import React, { ChangeEvent, MouseEvent, useMemo, useState } from 'react'; + +import { useToken } from '../__builtins__'; +import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; import { SortableItem } from '../../common'; import { useCompile, useDesigner, useProps } from '../../hooks'; -import { useToken } from '../__builtins__'; import { EllipsisWithTooltip } from '../input'; import { getLabelFormatValue, useLabelUiSchema } from '../record-picker'; import { AssociationFilter } from './AssociationFilter'; import useStyles from './AssociationFilter.Item.style'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; const { Panel } = Collapse; @@ -94,6 +96,7 @@ export const AssociationFilterItem = withDynamicSchemaProps( return wrapSSR( + {/* @ts-ignore upstream type error */} null : undefined}> } + // @ts-ignore upstream type error key={defaultActiveKeyCollapse[0]} > ; diff --git a/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx b/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx index 4570fd0fa..f70829001 100644 --- a/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx +++ b/packages/core/client/src/schema-component/antd/date-picker/DatePicker.tsx @@ -1,14 +1,16 @@ +import React from 'react'; import { connect, mapProps, mapReadPretty } from '@tachybase/schema'; + import { DatePicker as AntdDatePicker } from 'antd'; import type { DatePickerProps as AntdDatePickerProps, RangePickerProps as AntdRangePickerProps, } from 'antd/es/date-picker'; -import React from 'react'; +import dayjs from 'dayjs'; import { useTranslation } from 'react-i18next'; + import { ReadPretty } from './ReadPretty'; import { getDateRanges, mapDatePicker, mapRangePicker } from './util'; -import dayjs from 'dayjs'; interface IDatePickerProps { utc?: boolean; @@ -24,6 +26,7 @@ const DatePickerContext = React.createContext({ utc: true }); export const useDatePickerContext = () => React.useContext(DatePickerContext); export const DatePickerProvider = DatePickerContext.Provider; +// @ts-ignore const InternalDatePicker: ComposedDatePicker = connect( AntdDatePicker, mapProps(mapDatePicker()), diff --git a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx index d5aa06ede..d11865fd7 100644 --- a/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx +++ b/packages/core/client/src/schema-component/antd/grid-card/GridCard.Item.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { useCollection } from '@tachybase/client'; import { ObjectField, useField, useFieldSchema } from '@tachybase/schema'; import { Card } from 'antd'; @@ -7,6 +6,7 @@ import { createStyles } from 'antd-style'; import { useNavigate } from 'react-router-dom'; import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import { useCollection } from '../../../data-source'; import { useCollectionParentRecordData } from '../../../data-source/collection-record/CollectionRecordProvider'; import { RecordProvider } from '../../../record-provider'; import { useGridCardDetailUrl } from './hooks'; diff --git a/packages/core/client/src/schema-component/antd/grid/Grid.tsx b/packages/core/client/src/schema-component/antd/grid/Grid.tsx index ddb757e67..8f8a05846 100644 --- a/packages/core/client/src/schema-component/antd/grid/Grid.tsx +++ b/packages/core/client/src/schema-component/antd/grid/Grid.tsx @@ -1,15 +1,16 @@ +import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import { ISchema, observer, RecursionField, Schema, uid, useField, useFieldSchema } from '@tachybase/schema'; + import { TinyColor } from '@ctrl/tinycolor'; import { useDndContext, useDndMonitor, useDraggable, useDroppable } from '@dnd-kit/core'; -import { ISchema, RecursionField, Schema, observer, useField, useFieldSchema } from '@tachybase/schema'; -import { uid } from '@tachybase/schema'; import cls from 'classnames'; -import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react'; +import _ from 'lodash'; + +import { useToken } from '../__builtins__'; import { useDesignable, useFormBlockContext, useSchemaInitializerRender } from '../../../'; import { useFormBlockType } from '../../../block-provider'; import { DndContext } from '../../common/dnd-context'; -import { useToken } from '../__builtins__'; import useStyles from './Grid.style'; -import _ from 'lodash'; const GridRowContext = createContext({}); GridRowContext.displayName = 'GridRowContext'; @@ -77,7 +78,7 @@ const ColDivider = (props) => { if (!isDragging) { return; } - dragIdRef.current = event.active.id; + dragIdRef.current = event.active.id as string; const el = dividerRef.current; const prev = el.previousElementSibling as HTMLDivElement; const next = el.nextElementSibling as HTMLDivElement; @@ -98,7 +99,7 @@ const ColDivider = (props) => { }, onDragEnd(event) { if (!dragIdRef.current) return; - if (dragIdRef.current?.startsWith(event.active.id)) { + if (dragIdRef.current?.startsWith(event.active.id as string)) { if (!dragIdRef.current.endsWith('_move')) { return; } diff --git a/packages/core/client/src/schema-component/antd/input/Input.tsx b/packages/core/client/src/schema-component/antd/input/Input.tsx index 9c3c86c77..f99a10319 100644 --- a/packages/core/client/src/schema-component/antd/input/Input.tsx +++ b/packages/core/client/src/schema-component/antd/input/Input.tsx @@ -1,9 +1,11 @@ -import { LoadingOutlined } from '@ant-design/icons'; +import React from 'react'; import { connect, mapProps, mapReadPretty } from '@tachybase/schema'; + +import { LoadingOutlined } from '@ant-design/icons'; import { Input as AntdInput } from 'antd'; import { InputProps, TextAreaProps } from 'antd/es/input'; -import React from 'react'; -import { JSONTextAreaProps, Json } from './Json'; + +import { Json, JSONTextAreaProps } from './Json'; import { ReadPretty } from './ReadPretty'; export { ReadPretty as InputReadPretty } from './ReadPretty'; diff --git a/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx b/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx index 8a48a2a89..ec8d45946 100644 --- a/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx +++ b/packages/core/client/src/schema-component/antd/input/ReadPretty.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { usePrefixCls } from '@tachybase/components'; +import { css } from '@emotion/css'; import { Typography } from 'antd'; import { InputProps, TextAreaProps } from 'antd/es/input'; import cls from 'classnames'; @@ -122,8 +123,30 @@ const _URL = (props: InputProps) => { ); }; +const _JSON = (props) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const prefixCls = usePrefixCls('json', props); + return ( +
+      {props.value != null ? JSON.stringify(props.value, null, props.space ?? 2) : ''}
+    
+ ); +}; + ReadPretty.Input = _Input; ReadPretty.TextArea = _TextArea; ReadPretty.URL = _URL; ReadPretty.Html = _Html; ReadPretty.TextArea = _TextArea; +ReadPretty.JSON = _JSON; diff --git a/packages/core/client/src/schema-component/antd/time-picker/TimePicker.tsx b/packages/core/client/src/schema-component/antd/time-picker/TimePicker.tsx index 8c2258f14..24064b5d8 100644 --- a/packages/core/client/src/schema-component/antd/time-picker/TimePicker.tsx +++ b/packages/core/client/src/schema-component/antd/time-picker/TimePicker.tsx @@ -1,8 +1,10 @@ import { dayjsable, formatDayjsValue } from '@tachybase/components'; import { connect, mapProps, mapReadPretty } from '@tachybase/schema'; -import dayjs from 'dayjs'; + import { TimePicker as AntdTimePicker } from 'antd'; import { TimePickerProps as AntdTimePickerProps, TimeRangePickerProps } from 'antd/es/time-picker'; +import dayjs from 'dayjs'; + import { ReadPretty } from './ReadPretty'; type ComposedTimePicker = React.FC & { @@ -26,6 +28,7 @@ const mapTimeFormat = function () { }; }; +// @ts-ignore export const TimePicker: ComposedTimePicker = connect( AntdTimePicker, mapProps(mapTimeFormat()), diff --git a/packages/core/client/src/schema-component/antd/upload/Upload.tsx b/packages/core/client/src/schema-component/antd/upload/Upload.tsx index 496d58eb3..a55e33ca2 100644 --- a/packages/core/client/src/schema-component/antd/upload/Upload.tsx +++ b/packages/core/client/src/schema-component/antd/upload/Upload.tsx @@ -1,18 +1,21 @@ -import { DeleteOutlined, DownloadOutlined, InboxOutlined, LoadingOutlined, PlusOutlined } from '@ant-design/icons'; +import React, { useEffect, useRef, useState } from 'react'; import { connect, mapProps, mapReadPretty } from '@tachybase/schema'; + +import { DeleteOutlined, DownloadOutlined, InboxOutlined, LoadingOutlined, PlusOutlined } from '@ant-design/icons'; import { Upload as AntdUpload, Button, Modal, Progress, Space, UploadFile } from 'antd'; import cls from 'classnames'; import { saveAs } from 'file-saver'; -import React, { useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import LightBox from 'react-image-lightbox'; + import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app + +import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; +import { useProps } from '../../hooks/useProps'; import { ReadPretty } from './ReadPretty'; import { isImage, isPdf, toArr, toFileList, toItem, toValue, useUploadProps } from './shared'; import { useStyles } from './style'; import type { ComposedUpload, DraggerProps, DraggerV2Props, UploadProps } from './type'; -import { withDynamicSchemaProps } from '../../../application/hoc/withDynamicSchemaProps'; -import { useProps } from '../../hooks/useProps'; export const Upload: ComposedUpload = connect( (props: UploadProps) => { @@ -324,6 +327,7 @@ Upload.DraggerV2 = withDynamicSchemaProps( return wrapSSR(
+ {/* @ts-ignore */}

{loading ? : } diff --git a/packages/core/client/src/schema-component/antd/variable/TextArea.tsx b/packages/core/client/src/schema-component/antd/variable/TextArea.tsx index eb5857f2d..e94b66f71 100644 --- a/packages/core/client/src/schema-component/antd/variable/TextArea.tsx +++ b/packages/core/client/src/schema-component/antd/variable/TextArea.tsx @@ -188,7 +188,7 @@ function getCurrentRange(element: HTMLElement): RangeIndexes { return result; } -const useStyles2 = createStyles(({ css }) => { +const useStyles2 = createStyles(({ css }, { multiline }) => { return { container: css` &.ant-input-group.ant-input-group-compact { @@ -241,7 +241,7 @@ export function TextArea(props) { const inputRef = useRef(null); const [options, setOptions] = useState([]); const form = useForm(); - const { styles } = useStyles2(); + const { styles } = useStyles2({ multiline }); const keyLabelMap = useMemo(() => createOptionsValueLabelMap(options), [options]); const [ime, setIME] = useState(false); const [changed, setChanged] = useState(false); diff --git a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx index 68d6e5f50..1e1a6bde4 100644 --- a/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx +++ b/packages/core/client/src/schema-initializer/components/CreateRecordAction.tsx @@ -56,6 +56,45 @@ const useStyles = createStyles(({ css }) => { } } `, + actionDesigner: css` + position: relative; + &:hover { + .general-schema-designer { + display: block; + } + } + .general-schema-designer { + position: absolute; + z-index: 999; + top: 0; + bottom: 0; + left: 0; + right: 0; + display: none; + background: var(--colorBgSettingsHover); + border: 0; + top: 0; + bottom: 0; + left: 0; + right: 0; + pointer-events: none; + > .general-schema-designer-icons { + position: absolute; + right: 2px; + top: 2px; + line-height: 16px; + pointer-events: all; + .ant-space-item { + background-color: var(--colorSettings); + color: #fff; + line-height: 16px; + width: 16px; + padding-left: 1px; + align-self: stretch; + } + } + } + `, }; }); @@ -237,7 +276,7 @@ export const CreateAction = observer( }); }, [field, linkageRules, localVariables, variables]); return ( -

+
{ +const InternalField = (props) => { const field = useField(); const fieldSchema = useFieldSchema(); const { uiSchema } = useCollectionField_deprecated(); diff --git a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx index 8023c907f..70d9fdaaa 100644 --- a/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx +++ b/packages/core/client/src/schema-initializer/items/DataBlockInitializer.tsx @@ -1,19 +1,21 @@ +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; + import { TableOutlined } from '@ant-design/icons'; import { Divider, Empty, Input, MenuProps, Spin } from 'antd'; -import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; + import { SchemaInitializerItem, SchemaInitializerMenu, useGetSchemaInitializerMenuItems, useSchemaInitializer, } from '../../application'; +import { DataSource } from '../../data-source'; import { Collection, CollectionFieldOptions } from '../../data-source/collection/Collection'; +import { Icon } from '../../icon'; import { useCompile } from '../../schema-component'; import { useSchemaTemplateManager } from '../../schema-templates'; import { useCollectionDataSourceItems } from '../utils'; -import { DataSource } from '../../data-source'; -import { Icon } from '../../icon'; const MENU_ITEM_HEIGHT = 40; const STEP = 15; @@ -356,7 +358,7 @@ export const DataBlockInitializer = (props: DataBlockInitializerProps) => { { key: name, label: compile(title), - icon: typeof icon === 'string' ? : icon, + icon: typeof icon === 'string' ? : (icon as React.ReactNode), onClick: (info) => { if (info.key !== name) return; onClick({ ...info, item: props }); diff --git a/packages/core/components/package.json b/packages/core/components/package.json index 326a01ee0..a22f437c9 100644 --- a/packages/core/components/package.json +++ b/packages/core/components/package.json @@ -7,8 +7,9 @@ "dependencies": { "@ant-design/cssinjs": "^1.20.0", "@ant-design/icons": "^5.3.6", - "@dnd-kit/core": "^5.0.1", - "@dnd-kit/sortable": "^6.0.0", + "@dnd-kit/core": "^6.1.0", + "@dnd-kit/sortable": "^8.0.0", + "@dnd-kit/utilities": "^3.2.2", "@formily/core": "2.2.27", "@formily/grid": "2.2.27", "@formily/json-schema": "2.2.27", @@ -22,5 +23,11 @@ "classnames": "^2.5.1", "dayjs": "^1.11.11", "react-sticky-box": "^1.0.2" + }, + "devDependencies": { + "rc-cascader": "3.24.1", + "rc-input-number": "9.0.0", + "rc-picker": "4.3.0", + "rc-tree-select": "5.19.0" } } diff --git a/packages/core/components/src/__builtins__/moment.ts b/packages/core/components/src/__builtins__/moment.ts deleted file mode 100644 index 766bec668..000000000 --- a/packages/core/components/src/__builtins__/moment.ts +++ /dev/null @@ -1,62 +0,0 @@ -// FOR: https://github.com/ant-design/antd-moment-webpack-plugin -import { isArr, isFn, isEmpty } from '@formily/shared'; -import moment, { MomentInput, Moment } from 'moment'; - -export function dayjsable(value: MomentInput, format?: string): Moment; -export function dayjsable(value: MomentInput[], format?: string): Moment[]; - -export function dayjsable(value: MomentInput | MomentInput[], format?: string): any { - if (!value) return value; - if (Array.isArray(value)) { - return value.map((val) => { - const date = moment(val, format); - if (date.isValid()) return date; - const _date = moment(val); - return _date.isValid() ? _date : val; - }); - } else { - const date = moment(value, format); - if (date.isValid()) return date; - const _date = moment(value); - return _date.isValid() ? _date : value; - } -} - -export const formatDayjsValue = (value: any, format: any, placeholder?: string): string | string[] => { - const validFormatDate = (date: any, format: any) => { - if (typeof date === 'number') { - return moment(date).format(format); - } - const _date = moment(date, format); - return _date.isValid() ? _date.format(format) : date; - }; - - const formatDate = (date: any, format: any, i = 0) => { - if (!date) return placeholder; - if (isArr(format)) { - const _format = format[i]; - if (isFn(_format)) { - return _format(date); - } - if (isEmpty(_format)) { - return date; - } - return validFormatDate(date, _format); - } else { - if (isFn(format)) { - return format(date); - } - if (isEmpty(format)) { - return date; - } - return validFormatDate(date, format); - } - }; - if (isArr(value)) { - return value.map((val, index) => { - return formatDate(val, format, index); - }); - } else { - return value ? formatDate(value, format) : value || placeholder; - } -}; diff --git a/packages/core/components/src/__builtins__/render.ts b/packages/core/components/src/__builtins__/render.ts index f1e04482f..0b90e8d4f 100644 --- a/packages/core/components/src/__builtins__/render.ts +++ b/packages/core/components/src/__builtins__/render.ts @@ -1,4 +1,5 @@ import { ReactElement } from 'react'; + import * as ReactDOM from 'react-dom'; import type { Root } from 'react-dom/client'; diff --git a/packages/core/components/src/__builtins__/sort.tsx b/packages/core/components/src/__builtins__/sort.tsx index 174916939..19f068ec0 100644 --- a/packages/core/components/src/__builtins__/sort.tsx +++ b/packages/core/components/src/__builtins__/sort.tsx @@ -1,7 +1,10 @@ +import React, { createContext, useContext, useMemo } from 'react'; + import { DndContext, DragEndEvent, DragStartEvent } from '@dnd-kit/core'; import { SortableContext, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable'; import { ReactFC } from '@formily/reactive-react'; -import React, { createContext, useContext, useMemo } from 'react'; + +export type { Transform } from '@dnd-kit/utilities'; export interface ISortableContainerProps { list: any[]; diff --git a/packages/core/components/src/array-base/index.tsx b/packages/core/components/src/array-base/index.tsx index a11935fde..b4b38fcd8 100644 --- a/packages/core/components/src/array-base/index.tsx +++ b/packages/core/components/src/array-base/index.tsx @@ -1,10 +1,12 @@ +import React, { createContext, forwardRef, useContext } from 'react'; + import { CopyOutlined, DeleteOutlined, DownOutlined, MenuOutlined, PlusOutlined, UpOutlined } from '@ant-design/icons'; import { ArrayField } from '@formily/core'; import { ReactFC, RecordScope, RecordsScope, Schema, useField, useFieldSchema } from '@formily/react'; import { clone, isUndef, isValid } from '@formily/shared'; import { Button, ButtonProps } from 'antd'; import cls from 'classnames'; -import React, { createContext, forwardRef, useContext } from 'react'; + import { SortableHandle, usePrefixCls } from '../__builtins__'; import useStyle from './style'; @@ -182,7 +184,7 @@ const Copy = forwardRef((props, ref) => { if (array.field?.pattern !== 'editable') return null; return wrapSSR(