parent
b01ed166be
commit
5c25f23082
@ -1,7 +1,6 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
|
||||
import { useRequest } from '../api-client';
|
||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||
|
||||
export const CurrentAppInfoContext = createContext(null);
|
||||
CurrentAppInfoContext.displayName = 'CurrentAppInfoContext';
|
||||
@ -18,12 +17,11 @@ export const useCurrentAppInfo = () => {
|
||||
}>(CurrentAppInfoContext);
|
||||
};
|
||||
export const CurrentAppInfoProvider = (props) => {
|
||||
const { render } = useAppSpin();
|
||||
const result = useRequest({
|
||||
url: 'app:getInfo',
|
||||
});
|
||||
if (result.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
return <CurrentAppInfoContext.Provider value={result.data}>{props.children}</CurrentAppInfoContext.Provider>;
|
||||
};
|
||||
|
@ -1,9 +1,11 @@
|
||||
import { render, sleep, screen, waitFor } from '@tachybase/test/client';
|
||||
import React from 'react';
|
||||
import { render, screen, sleep, waitFor } from '@tachybase/test/client';
|
||||
|
||||
import { describe } from 'vitest';
|
||||
|
||||
import { Application } from '../Application';
|
||||
import { useApp, usePlugin, useRouter } from '../hooks';
|
||||
import { Plugin } from '../Plugin';
|
||||
import { useApp, usePlugin, useRouter, useAppSpin } from '../hooks';
|
||||
|
||||
describe('Application Hooks', () => {
|
||||
describe('useApp()', () => {
|
||||
@ -59,37 +61,4 @@ describe('Application Hooks', () => {
|
||||
await sleep(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('useAppSpin()', () => {
|
||||
test('no app, should render ant-design Spin', async () => {
|
||||
const Demo = () => {
|
||||
const spin = useAppSpin();
|
||||
return spin.render();
|
||||
};
|
||||
|
||||
render(<Demo />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(document.querySelector('.ant-spin')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
test('has app, should render AppSpin Component', () => {
|
||||
const Demo = () => {
|
||||
const spin = useAppSpin();
|
||||
return spin.render();
|
||||
};
|
||||
|
||||
const app = new Application({
|
||||
providers: [Demo],
|
||||
components: {
|
||||
AppSpin: () => <div data-testid="content">test</div>,
|
||||
},
|
||||
});
|
||||
const Root = app.getRootComponent();
|
||||
render(<Root></Root>);
|
||||
expect(document.querySelector('.ant-spin')).toBeFalsy();
|
||||
expect(screen.getByTestId('content')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { FC } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import { MainComponent } from './MainComponent';
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
export * from './useApp';
|
||||
export * from './usePlugin';
|
||||
export * from './useRouter';
|
||||
export * from './useAppSpin';
|
||||
|
@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Spin } from 'antd';
|
||||
|
||||
import { useApp } from './useApp';
|
||||
|
||||
export const useAppSpin = () => {
|
||||
const app = useApp();
|
||||
return {
|
||||
render: () => (app?.renderComponent ? app?.renderComponent?.('AppSpin') : React.createElement(Spin)),
|
||||
};
|
||||
};
|
@ -6,7 +6,6 @@ import { Navigate } from 'react-router-dom';
|
||||
|
||||
import { useAPIClient, useRequest } from '../../api-client';
|
||||
import { useApp } from '../../application';
|
||||
import { useAppSpin } from '../../application/hooks/useAppSpin';
|
||||
import { useBlockRequestContext } from '../../block-provider/BlockProvider';
|
||||
import { useCollection_deprecated, useCollectionManager_deprecated } from '../../collection-manager';
|
||||
import { useResourceActionContext } from '../../collection-manager/ResourceActionProvider';
|
||||
@ -38,7 +37,6 @@ const getRouteUrl = (props) => {
|
||||
export const ACLRolesCheckProvider = (props) => {
|
||||
const route = getRouteUrl(props.children.props);
|
||||
const { setDesignable } = useDesignable();
|
||||
const { render } = useAppSpin();
|
||||
const api = useAPIClient();
|
||||
const app = useApp();
|
||||
const result = useRequest<{
|
||||
@ -68,7 +66,7 @@ export const ACLRolesCheckProvider = (props) => {
|
||||
},
|
||||
);
|
||||
if (result.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
if (result.error) {
|
||||
return <Navigate replace to={'/signin'} />;
|
||||
|
@ -22,7 +22,6 @@ import {
|
||||
useRequest,
|
||||
useSystemSettings,
|
||||
} from '../..';
|
||||
import { useAppSpin } from '../../application/hooks/useAppSpin';
|
||||
import { Plugin } from '../../application/Plugin';
|
||||
import { VariablesProvider } from '../../variables';
|
||||
|
||||
@ -202,7 +201,6 @@ const MenuEditor = (props) => {
|
||||
setCurrent(schema);
|
||||
navigate(`/admin/${schema['x-uid']}`);
|
||||
};
|
||||
const { render } = useAppSpin();
|
||||
const adminSchemaUid = useAdminSchemaUid();
|
||||
const { data, loading } = useRequest<{
|
||||
data: any;
|
||||
@ -320,7 +318,7 @@ const MenuEditor = (props) => {
|
||||
);
|
||||
|
||||
if (loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
return (
|
||||
<SchemaIdContext.Provider value={defaultSelectedUid}>
|
||||
|
@ -36,8 +36,18 @@ interface AppStatusProps {
|
||||
}
|
||||
|
||||
const AppSpin = () => {
|
||||
// TODO: better loading and mobile loading fix
|
||||
return (
|
||||
<Spin style={{ position: 'fixed', top: '50%', left: '50%', fontSize: 72, transform: 'translate(-50%, -50%)' }} />
|
||||
<Spin
|
||||
size="large"
|
||||
style={{
|
||||
position: 'fixed',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
fontSize: 72 * (window.devicePixelRatio || 1),
|
||||
transform: 'translate(-50%, -50%)',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,6 @@ import React, { createContext, ReactNode, useContext } from 'react';
|
||||
import { Result } from 'ahooks/es/useRequest/src/types';
|
||||
|
||||
import { useRequest } from '../../api-client';
|
||||
import { useAppSpin } from '../../application/hooks/useAppSpin';
|
||||
|
||||
export const SystemSettingsContext = createContext<Result<any, any>>(null);
|
||||
SystemSettingsContext.displayName = 'SystemSettingsContext';
|
||||
@ -13,12 +12,11 @@ export const useSystemSettings = () => {
|
||||
};
|
||||
|
||||
export const SystemSettingsProvider: React.FC<{ children?: ReactNode }> = (props) => {
|
||||
const { render } = useAppSpin();
|
||||
const result = useRequest({
|
||||
url: 'systemSettings:get/1?appends=logo',
|
||||
});
|
||||
if (result.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
|
||||
return <SystemSettingsContext.Provider value={result}>{props.children}</SystemSettingsContext.Provider>;
|
||||
|
@ -3,7 +3,6 @@ import React, { createContext, useContext, useEffect } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
|
||||
import { useAPIClient, useRequest } from '../api-client';
|
||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||
|
||||
export interface CollectionHistoryContextValue {
|
||||
historyCollections: any[];
|
||||
@ -42,7 +41,6 @@ export const CollectionHistoryProvider = (props) => {
|
||||
|
||||
const isAdminPage = location.pathname.startsWith('/admin');
|
||||
const token = api.auth.getToken() || '';
|
||||
const { render } = useAppSpin();
|
||||
|
||||
useEffect(() => {
|
||||
if (isAdminPage && token) {
|
||||
@ -58,7 +56,7 @@ export const CollectionHistoryProvider = (props) => {
|
||||
};
|
||||
|
||||
if (service.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import { useAPIClient, useRequest } from '../api-client';
|
||||
import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider';
|
||||
import { CollectionCategroriesContext } from './context';
|
||||
import { CollectionManagerOptions } from './types';
|
||||
import { CollectionManagerProvider } from '../data-source/collection/CollectionManagerProvider';
|
||||
import { useDataSourceManager } from '../data-source/data-source/DataSourceManagerProvider';
|
||||
import { useCollectionHistory } from './CollectionHistoryProvider';
|
||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||
import { CollectionManagerSchemaComponentProvider } from './CollectionManagerSchemaComponentProvider';
|
||||
import { CollectionCategroriesContext } from './context';
|
||||
import { CollectionManagerOptions } from './types';
|
||||
|
||||
/**
|
||||
* @deprecated use `CollectionManagerProvider` instead
|
||||
@ -40,9 +40,8 @@ export const RemoteCollectionManagerProvider = (props: any) => {
|
||||
data: any;
|
||||
}>(coptions);
|
||||
|
||||
const { render } = useAppSpin();
|
||||
if (service.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
|
||||
const refreshCategory = async () => {
|
||||
|
@ -12,7 +12,6 @@ import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { FormDialog } from '..';
|
||||
import { useToken } from '../__builtins__';
|
||||
import { useAppSpin } from '../../../application/hooks/useAppSpin';
|
||||
import { useStyles as useAClStyles } from '../../../built-in/acl/style';
|
||||
import { useDocumentTitle } from '../../../built-in/document-title';
|
||||
import { FilterBlockProvider } from '../../../filter-provider/FilterProvider';
|
||||
@ -202,10 +201,9 @@ function PageContent(
|
||||
props: any,
|
||||
): React.ReactNode {
|
||||
const { token } = useToken();
|
||||
const { render } = useAppSpin();
|
||||
|
||||
if (loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
|
||||
return !disablePageHeader && enablePageTabs ? (
|
||||
|
@ -3,7 +3,6 @@ import React, { createContext, useContext, useMemo } from 'react';
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
|
||||
import { ReturnTypeOfUseRequest, useRequest } from '../api-client';
|
||||
import { useAppSpin } from '../application/hooks/useAppSpin';
|
||||
import { useACLRoleContext } from '../built-in/acl';
|
||||
import { useCompile } from '../schema-component';
|
||||
|
||||
@ -33,13 +32,12 @@ export const useCurrentRoles = () => {
|
||||
};
|
||||
|
||||
export const CurrentUserProvider = (props) => {
|
||||
const { render } = useAppSpin();
|
||||
const result = useRequest<any>({
|
||||
url: 'auth:check',
|
||||
});
|
||||
|
||||
if (result.loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
|
||||
return <CurrentUserContext.Provider value={result}>{props.children}</CurrentUserContext.Provider>;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { useAppSpin, useRequest } from '@tachybase/client';
|
||||
import { useRequest } from '@tachybase/client';
|
||||
|
||||
import { Carousel, Image } from 'antd';
|
||||
|
||||
@ -7,7 +7,6 @@ import { useStyles } from './style';
|
||||
|
||||
export const HomePage: React.FC<{}> = () => {
|
||||
const { styles } = useStyles();
|
||||
const { render } = useAppSpin();
|
||||
const { data, loading } = useRequest<{ data: any }>({
|
||||
url: 'home_page_presentations:list',
|
||||
params: {
|
||||
@ -16,7 +15,7 @@ export const HomePage: React.FC<{}> = () => {
|
||||
});
|
||||
|
||||
if (loading) {
|
||||
return render();
|
||||
return;
|
||||
}
|
||||
const date = new Date();
|
||||
const year = date.getFullYear();
|
||||
|
@ -2,11 +2,7 @@ import React from 'react';
|
||||
import { CurrentAppInfoProvider, SchemaComponentOptions } from '@tachybase/client';
|
||||
|
||||
export const DuplicatorProvider = function (props) {
|
||||
return (
|
||||
<CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions>{props.children}</SchemaComponentOptions>
|
||||
</CurrentAppInfoProvider>
|
||||
);
|
||||
return <SchemaComponentOptions>{props.children}</SchemaComponentOptions>;
|
||||
};
|
||||
|
||||
DuplicatorProvider.displayName = 'DuplicatorProvider';
|
||||
|
@ -16,16 +16,14 @@ Gantt.Designer = GanttDesigner;
|
||||
Gantt.Event = Event;
|
||||
export { Gantt };
|
||||
|
||||
const GanttProvider = React.memo((props) => {
|
||||
const GanttProvider = React.memo((props: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions
|
||||
components={{ Gantt, GanttBlockInitializer, GanttBlockProvider }}
|
||||
scope={{ useGanttBlockProps }}
|
||||
>
|
||||
{props.children}
|
||||
</SchemaComponentOptions>
|
||||
</CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions
|
||||
components={{ Gantt, GanttBlockInitializer, GanttBlockProvider }}
|
||||
scope={{ useGanttBlockProps }}
|
||||
>
|
||||
{props.children}
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -19,16 +19,14 @@ Kanban.Designer = KanbanDesigner;
|
||||
|
||||
const KanbanV2 = Kanban;
|
||||
|
||||
const KanbanPluginProvider = React.memo((props) => {
|
||||
const KanbanPluginProvider = React.memo((props: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions
|
||||
components={{ Kanban, KanbanBlockProvider, KanbanV2, KanbanBlockInitializer }}
|
||||
scope={{ useKanbanBlockProps }}
|
||||
>
|
||||
{props.children}
|
||||
</SchemaComponentOptions>
|
||||
</CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions
|
||||
components={{ Kanban, KanbanBlockProvider, KanbanV2, KanbanBlockInitializer }}
|
||||
scope={{ useKanbanBlockProps }}
|
||||
>
|
||||
{props.children}
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
});
|
||||
KanbanPluginProvider.displayName = 'KanbanPluginProvider';
|
||||
|
@ -6,7 +6,7 @@ import { MapBlockDesigner } from './MapBlockDesigner';
|
||||
import { MapBlockInitializer } from './MapBlockInitializer';
|
||||
import { MapBlockProvider, useMapBlockProps } from './MapBlockProvider';
|
||||
|
||||
export const MapBlockOptions: React.FC = (props) => {
|
||||
export const MapBlockOptions = (props) => {
|
||||
return (
|
||||
<SchemaComponentOptions
|
||||
scope={{ useMapBlockProps }}
|
||||
|
@ -9,13 +9,11 @@ import { Configuration, Map } from './components';
|
||||
import { fields } from './fields';
|
||||
import { generateNTemplate, NAMESPACE } from './locale';
|
||||
|
||||
const MapProvider = React.memo((props) => {
|
||||
const MapProvider = React.memo((props: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions components={{ Map }}>
|
||||
<MapBlockOptions>{props.children}</MapBlockOptions>
|
||||
</SchemaComponentOptions>
|
||||
</CurrentAppInfoProvider>
|
||||
<SchemaComponentOptions components={{ Map }}>
|
||||
<MapBlockOptions>{props.children}</MapBlockOptions>
|
||||
</SchemaComponentOptions>
|
||||
);
|
||||
});
|
||||
MapProvider.displayName = 'MapProvider';
|
||||
|
@ -1,11 +1,10 @@
|
||||
import React from 'react';
|
||||
import { css } from '@tachybase/client';
|
||||
import { connect, mapProps, mapReadPretty } from '@tachybase/schema';
|
||||
|
||||
import { Input, InputProps, TextArea, TextAreaProps } from 'antd-mobile';
|
||||
|
||||
type ComposedInput = React.FC<InputProps> & {
|
||||
TextArea?: React.FC<TextAreaProps>;
|
||||
type ComposedInput = ((props: InputProps) => React.ReactNode) & {
|
||||
TextArea?: (props: TextAreaProps) => React.ReactNode;
|
||||
};
|
||||
|
||||
export const MInput: ComposedInput = connect(
|
||||
@ -14,7 +13,7 @@ export const MInput: ComposedInput = connect(
|
||||
return { placeholder: '请输入内容', clearable: true, ...props, style: { '--font-size': '12px' } };
|
||||
}),
|
||||
mapReadPretty((props) => {
|
||||
return <text style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{props.value}</text>;
|
||||
return <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>{props.value}</span>;
|
||||
}),
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user