feat:新增广船嵌入操作

main
陈炎群 7 months ago
parent c0507ac1b7
commit f8ad71384b

@ -32,6 +32,35 @@ export type IAppDetailLayoutProps = {
appId: string appId: string
} }
const useIframeHeader = () => {
const [show, setShow] = useState(true);
useEffect(() => {
// 监听父级指定操作
const handler = (event: MessageEvent) => {
// if (event.origin !== "https://gcgj.ngsk.tech:7001") return;
if (event.data.type === "HIDDEN") setShow(() => false);
};
// 初始化完成后提示iframe操作
window.parent.postMessage(
{
type: "SIDEBA",
},
"*"
);
window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler);
}, []);
return {
show,
};
};
const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => { const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const { const {
children, children,
@ -56,6 +85,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
icon: NavIcon icon: NavIcon
selectedIcon: NavIcon selectedIcon: NavIcon
}>>([]) }>>([])
const { show } = useIframeHeader()
const getNavigations = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => { const getNavigations = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
const navs = [ const navs = [
@ -160,9 +190,9 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
return ( return (
<div className={cn(s.app, 'relative flex', 'overflow-hidden')}> <div className={cn(s.app, 'relative flex', 'overflow-hidden')}>
{appDetail && ( {show ? appDetail && (
<AppSideBar title={appDetail.name} icon={appDetail.icon} icon_background={appDetail.icon_background as string} desc={appDetail.mode} navigation={navigation} /> <AppSideBar title={appDetail.name} icon={appDetail.icon} icon_background={appDetail.icon_background as string} desc={appDetail.mode} navigation={navigation} />
)} ): ''}
<div className="grow overflow-hidden bg-components-panel-bg"> <div className="grow overflow-hidden bg-components-panel-bg">
{children} {children}
</div> </div>

@ -1,5 +1,5 @@
'use client' 'use client'
import React, { useState } from 'react' import React, { useState, useEffect } from "react";
import { usePathname } from 'next/navigation' import { usePathname } from 'next/navigation'
import s from './index.module.css' import s from './index.module.css'
import { useEventEmitterContextContext } from '@/context/event-emitter' import { useEventEmitterContextContext } from '@/context/event-emitter'
@ -9,6 +9,33 @@ type HeaderWrapperProps = {
children: React.ReactNode children: React.ReactNode
} }
const useIframeHeader = () => {
const [show, setShow] = useState(true);
useEffect(() => {
// 监听父级指定操作
const handler = (event: MessageEvent) => {
// if (event.origin !== "https://gcgj.ngsk.tech:7001") return;
if (event.data.type === "HIDDEN") setShow(() => false);
};
// 初始化完成后提示iframe操作
window.parent.postMessage(
{
type: "HEADER",
},
"*"
);
window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler);
}, []);
return {
show,
};
};
const HeaderWrapper = ({ const HeaderWrapper = ({
children, children,
}: HeaderWrapperProps) => { }: HeaderWrapperProps) => {
@ -19,6 +46,7 @@ const HeaderWrapper = ({
const workflowCanvasMaximize = localStorage.getItem('workflow-canvas-maximize') === 'true' const workflowCanvasMaximize = localStorage.getItem('workflow-canvas-maximize') === 'true'
const [hideHeader, setHideHeader] = useState(workflowCanvasMaximize) const [hideHeader, setHideHeader] = useState(workflowCanvasMaximize)
const { eventEmitter } = useEventEmitterContextContext() const { eventEmitter } = useEventEmitterContextContext()
const { show } = useIframeHeader();
eventEmitter?.useSubscription((v: any) => { eventEmitter?.useSubscription((v: any) => {
if (v?.type === 'workflow-canvas-maximize') if (v?.type === 'workflow-canvas-maximize')
@ -26,15 +54,22 @@ const HeaderWrapper = ({
}) })
return ( return (
<div className={classNames( <>
'sticky left-0 right-0 top-0 z-[15] flex min-h-[56px] shrink-0 grow-0 basis-auto flex-col', {show ? (
s.header, <div
isBordered ? 'border-b border-divider-regular' : '', className={classNames(
hideHeader && inWorkflowCanvas && 'hidden', "sticky left-0 right-0 top-0 z-[15] flex min-h-[56px] shrink-0 grow-0 basis-auto flex-col",
)} s.header,
> isBordered ? "border-b border-divider-regular" : "",
{children} hideHeader && inWorkflowCanvas && "hidden"
</div> )}
) >
{children}
</div>
) : (
""
)}
</>
);
} }
export default HeaderWrapper export default HeaderWrapper

@ -15,6 +15,37 @@ import Toast from '@/app/components/base/toast'
import { IS_CE_EDITION } from '@/config' import { IS_CE_EDITION } from '@/config'
import { useGlobalPublicStore } from '@/context/global-public-context' import { useGlobalPublicStore } from '@/context/global-public-context'
const useIframeToken = () => {
const router = useRouter();
useEffect(() => {
// 监听父级指定操作
const handler = (event: MessageEvent) => {
// if (event.origin !== "https://gcgj.ngsk.tech:7001") return;
if (
event.data.type === "LOGIN_AND_WORKFLOW_INTO" &&
event.data.tokens &&
event.data.workflowUrl
) {
localStorage.setItem("console_token", event.data.tokens.console_token);
localStorage.setItem("refresh_token", event.data.tokens.refresh_token);
router.replace(event.data.workflowUrl);
}
};
// 首页初始化完成后提示iframe操作
window.parent.postMessage(
{
type: "LOGIN_AND_WORKFLOW",
},
"*"
);
window.addEventListener("message", handler);
return () => window.removeEventListener("message", handler);
}, []);
};
const NormalForm = () => { const NormalForm = () => {
const { t } = useTranslation() const { t } = useTranslation()
const router = useRouter() const router = useRouter()
@ -29,6 +60,7 @@ const NormalForm = () => {
const [showORLine, setShowORLine] = useState(false) const [showORLine, setShowORLine] = useState(false)
const [allMethodsAreDisabled, setAllMethodsAreDisabled] = useState(false) const [allMethodsAreDisabled, setAllMethodsAreDisabled] = useState(false)
const [workspaceName, setWorkSpaceName] = useState('') const [workspaceName, setWorkSpaceName] = useState('')
useIframeToken();
const isInviteLink = Boolean(invite_token && invite_token !== 'null') const isInviteLink = Boolean(invite_token && invite_token !== 'null')

@ -27,30 +27,41 @@ const nextConfig = {
basePath, basePath,
assetPrefix, assetPrefix,
webpack: (config, { dev, isServer }) => { webpack: (config, { dev, isServer }) => {
config.plugins.push(codeInspectorPlugin({ bundler: 'webpack' })) config.plugins.push(codeInspectorPlugin({ bundler: "webpack" }));
return config return config;
}, },
productionBrowserSourceMaps: false, // enable browser source map generation during the production build productionBrowserSourceMaps: false, // enable browser source map generation during the production build
// Configure pageExtensions to include md and mdx // Configure pageExtensions to include md and mdx
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'], pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"],
// https://nextjs.org/docs/messages/next-image-unconfigured-host // https://nextjs.org/docs/messages/next-image-unconfigured-host
images: { images: {
remotePatterns: remoteImageURLs.map(remoteImageURL => ({ remotePatterns: remoteImageURLs.map((remoteImageURL) => ({
protocol: remoteImageURL.protocol.replace(':', ''), protocol: remoteImageURL.protocol.replace(":", ""),
hostname: remoteImageURL.hostname, hostname: remoteImageURL.hostname,
port: remoteImageURL.port, port: remoteImageURL.port,
pathname: remoteImageURL.pathname, pathname: remoteImageURL.pathname,
search: '', search: "",
})), })),
}, },
experimental: { experimental: {},
},
// fix all before production. Now it slow the develop speed. // fix all before production. Now it slow the develop speed.
eslint: { eslint: {
// Warning: This allows production builds to successfully complete even if // Warning: This allows production builds to successfully complete even if
// your project has ESLint errors. // your project has ESLint errors.
ignoreDuringBuilds: true, ignoreDuringBuilds: true,
dirs: ['app', 'bin', 'config', 'context', 'hooks', 'i18n', 'models', 'service', 'test', 'types', 'utils'], dirs: [
"app",
"bin",
"config",
"context",
"hooks",
"i18n",
"models",
"service",
"test",
"types",
"utils",
],
}, },
typescript: { typescript: {
// https://nextjs.org/docs/api-reference/next.config.js/ignoring-typescript-errors // https://nextjs.org/docs/api-reference/next.config.js/ignoring-typescript-errors
@ -60,13 +71,30 @@ const nextConfig = {
async redirects() { async redirects() {
return [ return [
{ {
source: '/', source: "/",
destination: '/apps', destination: "/apps",
permanent: false, permanent: false,
}, },
] ];
},
output: "standalone",
async headers() {
return [
{
source: "/(.*)", // 匹配所有路由
headers: [
{
key: "X-Frame-Options",
value: "ALLOWALL", // 或 ALLOWALL更宽松
},
{
key: "Content-Security-Policy",
value: `default-src 'none'`, //允许所有
},
],
},
];
}, },
output: 'standalone', };
}
module.exports = withBundleAnalyzer(withMDX(nextConfig)) module.exports = withBundleAnalyzer(withMDX(nextConfig))

Loading…
Cancel
Save