feat: support embed page (#786)
Co-authored-by: sealday <sealday@gmail.com> Reviewed-on: daoyoucloud/tachybase#786
This commit is contained in:
parent
cd9c2e1e8c
commit
4bc1eb5ac2
@ -0,0 +1,30 @@
|
||||
import { css } from '@nocobase/client';
|
||||
import { Layout } from 'antd';
|
||||
import React from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
|
||||
export const EmbedLayout = () => (
|
||||
<Layout style={{ height: '100%' }}>
|
||||
<Layout.Content
|
||||
className={css`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
> div {
|
||||
position: relative;
|
||||
}
|
||||
.ant-layout-footer {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
padding: 0px 50px;
|
||||
}
|
||||
`}
|
||||
>
|
||||
<Outlet />
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
);
|
@ -0,0 +1,33 @@
|
||||
import { AdminProvider } from '@nocobase/client';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useLocation, useMatch, useNavigate } from 'react-router-dom';
|
||||
import { NotAuthorityResult } from './NotAuthorityResult';
|
||||
import { EmbedLayout } from './EmbedLayout';
|
||||
import { useEmbedToken } from './useEmbedToken';
|
||||
|
||||
export const EmbedPage = () => {
|
||||
const embedToken = useEmbedToken();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const match = useMatch('/embed/:name');
|
||||
// FIXME
|
||||
useEffect(
|
||||
() => () => {
|
||||
setTimeout(() => {
|
||||
match &&
|
||||
setTimeout(() => {
|
||||
window.location.pathname !== location.pathname && navigate('/embed/not-authorized');
|
||||
});
|
||||
});
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[],
|
||||
);
|
||||
return !embedToken || location.pathname === '/embed/not-authorized' ? (
|
||||
<NotAuthorityResult />
|
||||
) : (
|
||||
<AdminProvider>
|
||||
<EmbedLayout />
|
||||
</AdminProvider>
|
||||
);
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
import { RemoteSchemaComponent } from '@nocobase/client';
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
export function EmbedSchemaComponent() {
|
||||
const params = useParams();
|
||||
return <RemoteSchemaComponent uid={params.name} />;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { Result } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export function NotAuthorityResult() {
|
||||
return <Result status="403" title="403" subTitle="Sorry, you are not authorized to access this page." />;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import { Plugin } from '@nocobase/client';
|
||||
import { usePageSettingsProps } from './usePageSettingsProps';
|
||||
import { EmbedSchemaComponent } from './EmbedSchemaComponent';
|
||||
import { EmbedPage } from './EmbedPage';
|
||||
|
||||
const keyEmbed = 'embed';
|
||||
const pathEmbed = `/${keyEmbed}`;
|
||||
export class EmbedPlugin extends Plugin {
|
||||
async load() {
|
||||
this.router.add(keyEmbed, { path: pathEmbed, Component: EmbedPage });
|
||||
this.router.add(`${keyEmbed}.page`, { path: `${pathEmbed}/:name`, Component: EmbedSchemaComponent });
|
||||
this.router.add(`${keyEmbed}.notAuthorized`, { path: `${pathEmbed}/not-authorized`, element: null });
|
||||
this.schemaSettingsManager.addItem('PageSettings', keyEmbed, {
|
||||
type: 'item',
|
||||
useComponentProps: usePageSettingsProps,
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { useAPIClient } from '@nocobase/client';
|
||||
|
||||
export function useEmbedToken() {
|
||||
const url = new URL(window.location.href);
|
||||
const api = useAPIClient();
|
||||
const token = url.searchParams.get('token');
|
||||
return token && api.auth.setToken(token), api.auth.getToken();
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import { useFieldSchema } from '@nocobase/schema';
|
||||
import { App } from 'antd';
|
||||
import { useMatch } from 'react-router-dom';
|
||||
import { useTranslation } from '../locale';
|
||||
|
||||
export function usePageSettingsProps() {
|
||||
const isAdmin = useMatch('/admin/:name');
|
||||
const isEmbed = useMatch('/embed/:name');
|
||||
const currentRoute = isAdmin || isEmbed;
|
||||
const fieldSchema = useFieldSchema();
|
||||
const { message, notification } = App.useApp();
|
||||
const { t } = useTranslation();
|
||||
return {
|
||||
title: t('Copy embedded link'),
|
||||
onClick: () => {
|
||||
const link = window.location.href
|
||||
.replace('/admin', '/embed')
|
||||
.replace(currentRoute.params.name, fieldSchema['x-uid'])
|
||||
.replace(window.location.search || '', '');
|
||||
navigator.clipboard
|
||||
.writeText(link)
|
||||
.then(() => {
|
||||
message.success(t('Copy successful'));
|
||||
})
|
||||
.catch((error) => {
|
||||
notification.error({ message: t('Copy Failed'), description: error.message, placement: 'topRight' });
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
@ -74,6 +74,7 @@ import {
|
||||
useCustomPresets1,
|
||||
} from './schema-settings/SchemaSettingsDatePresets';
|
||||
import { SchemaSettingsSubmitDataType } from './schema-settings/SchemaSettingsSubmitDataType';
|
||||
import { EmbedPlugin } from './embed';
|
||||
export { usePDFViewerRef } from './schema-initializer';
|
||||
export * from './components/custom-components/custom-components';
|
||||
|
||||
@ -82,6 +83,7 @@ export class PluginCoreClient extends Plugin {
|
||||
|
||||
async afterAdd() {
|
||||
await this.app.pm.add(GroupBlockPlugin);
|
||||
await this.app.pm.add(EmbedPlugin);
|
||||
}
|
||||
|
||||
async registerSettings() {
|
||||
|
Loading…
Reference in New Issue
Block a user