Skip to content

Commit

Permalink
fix(portal-web): 修复门户系统前后端数据不一致导致渲染报错的问题 (#1287)
Browse files Browse the repository at this point in the history
### 问题背景

在获取能否使用桌面功能时在前端调用的函数中使用了后端才能获取的RuntimeConfig.PORTAL_CONFIG的数据
导致本地开发时浏览器前后端渲染不一致,出现Hydration报错


### 修复前

![image](https://github.com/PKUHPC/SCOW/assets/43978285/295e93eb-7ffe-47ed-96d6-9fd15322c77c)

### 修复后
解决了hydration报错问题
桌面路由相关本地开发环境与部署环境均正确渲染
并更新 ClusterInfoStore中的是否可以使用桌面功能/是否可以使用文件传输功能 需监听当前在线集群
58部署环境各页面测试通过
  • Loading branch information
piccaSun authored Jun 10, 2024
1 parent a9d7a84 commit fec0a57
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-adults-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@scow/portal-web": patch
---

修复了本地开发环境出现 Hydration 报错的问题
14 changes: 13 additions & 1 deletion apps/portal-web/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ interface ExtraProps {
initialLanguage: string;
clusterConfigs: { [clusterId: string]: ClusterConfigSchema };
initialCurrentClusters: Cluster[];
// 用于获取桌面功能是否可用,如集群配置文件中没有配置则判断门户的配置文件,需要通过SSR进行传递
initialPortalRuntimeDesktopEnabled: boolean;
}

type Props = AppProps & { extra: ExtraProps };
Expand All @@ -162,7 +164,11 @@ function MyApp({ Component, pageProps, extra }: Props) {
});

const clusterInfoStore = useConstant(() => {
return createStore(ClusterInfoStore, extra.clusterConfigs, extra.initialCurrentClusters);
return createStore(ClusterInfoStore,
extra.clusterConfigs,
extra.initialCurrentClusters,
extra.initialPortalRuntimeDesktopEnabled,
);
});

const loginNodeStore = useConstant(() => createStore(LoginNodeStore, loginNodes,
Expand Down Expand Up @@ -233,6 +239,9 @@ MyApp.getInitialProps = async (appContext: AppContext) => {
initialLanguage: "",
clusterConfigs: {},
initialCurrentClusters: [],
// 通过SSR获取门户系统配置文件中是否可用桌面功能
// enabled: Type.Boolean({ description: "是否启动登录节点上的桌面功能", default: true }),
initialPortalRuntimeDesktopEnabled: true,
};

// This is called on server on first load, and on client on every page transition
Expand Down Expand Up @@ -264,6 +273,9 @@ MyApp.getInitialProps = async (appContext: AppContext) => {
if (clusterConfigs && Object.keys(clusterConfigs).length > 0) {

extra.clusterConfigs = clusterConfigs;

extra.initialPortalRuntimeDesktopEnabled = runtimeConfig.PORTAL_CONFIG.loginDesktop.enabled;

const publicConfigClusters
= Object.values(getPublicConfigClusters(clusterConfigs));

Expand Down
41 changes: 32 additions & 9 deletions apps/portal-web/src/stores/ClusterInfoStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import { ClusterConfigSchema } from "@scow/config/build/cluster";
import { getSortedClusterIds } from "@scow/lib-web/build/utils/cluster";
import { useLocalStorage } from "@scow/lib-web/build/utils/hooks";
import { useEffect, useState } from "react";
import { Cluster, getDesktopEnabled, getPublicConfigClusters } from "src/utils/cluster";
import { Cluster, getDesktopEnabled, getFileTransferEnabled, getPublicConfigClusters } from "src/utils/cluster";
import { publicConfig } from "src/utils/config";

const SCOW_DEFAULT_CLUSTER_ID = "SCOW_DEFAULT_CLUSTER_ID";

export function ClusterInfoStore(
clusterConfigs: {[clusterId: string]: ClusterConfigSchema},
initialCurrentClusters: Cluster[],
// 用于获取桌面功能是否可用,如集群配置文件中没有配置则判断门户的配置文件
portalRuntimeDesktopEnabled: boolean,
) {

// 配置文件集群信息
Expand Down Expand Up @@ -57,13 +59,41 @@ export function ClusterInfoStore(
}
};

// ENABLE_LOGIN_DESKTOP
const initialEnableLoginDesktop = getDesktopEnabled(clusterConfigs, portalRuntimeDesktopEnabled);
const [enableLoginDesktop, setEnableLoginDesktop] = useState<boolean>(initialEnableLoginDesktop);


// CROSS_CLUSTER_FILE_TRANSFER_ENABLED
const initialEnableFileTransfer = getFileTransferEnabled(clusterConfigs);
const [crossClusterFileTransferEnabled, setCrossClusterFileTransferEnabled]
= useState<boolean>(initialEnableFileTransfer);


useEffect(() => {

if (publicConfig.MIS_DEPLOYED) {
// 可用集群不存在时
if (currentClusters.length === 0) {
setDefaultCluster(undefined);
setEnableLoginDesktop(false);
setCrossClusterFileTransferEnabled(false);
} else {

const currentClusterIds = currentClusters.map((x) => x.id);
const specifiedClusterConfigs = Object.fromEntries(
Object.entries(clusterConfigs).filter(([clusterId]) => currentClusterIds.includes(clusterId)),
);

// set桌面功能是否可用
const currentEnableLoginDesktop = getDesktopEnabled(clusterConfigs, portalRuntimeDesktopEnabled);
setEnableLoginDesktop(currentEnableLoginDesktop);

// set文件传输功能是否可用
const currentCrossClusterFileTransferEnabled = getFileTransferEnabled(specifiedClusterConfigs);
setCrossClusterFileTransferEnabled(currentCrossClusterFileTransferEnabled);

// set默认集群
// 上一次记录的集群为undefined的情况,使用可用集群中的某一个集群作为新的默认集群
if (!defaultCluster?.id) {
setDefaultCluster(currentClusters[0]);
Expand All @@ -78,14 +108,7 @@ export function ClusterInfoStore(
}
}

}, [currentClusters]);

// ENABLE_LOGIN_DESKTOP
const enableLoginDesktop = getDesktopEnabled(clusterConfigs);

// CROSS_CLUSTER_FILE_TRANSFER_ENABLED
const crossClusterFileTransferEnabled = Object.values(clusterConfigs).filter(
(cluster) => cluster.crossClusterFileTransfer?.enabled).length > 1;
}, [currentClusters, clusterConfigs, portalRuntimeDesktopEnabled]);

return {
publicConfigClusters,
Expand Down
19 changes: 15 additions & 4 deletions apps/portal-web/src/utils/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,33 @@ import { runtimeConfig } from "./config";
* @returns {boolean} desktop login enable
*/
export function getDesktopEnabled(
clusters: Record<string, ClusterConfigSchema>) {

clusters: Record<string, ClusterConfigSchema>,
portalRuntimeDesktopEnabled: boolean) {
const clusterDesktopEnabled = Object.keys(clusters).reduce(
((pre, cur) => {
const curClusterDesktopEnabled = clusters?.[cur]?.loginDesktop?.enabled !== undefined
? !!clusters[cur]?.loginDesktop?.enabled
: runtimeConfig.PORTAL_CONFIG?.loginDesktop?.enabled;

: portalRuntimeDesktopEnabled;
return pre || curClusterDesktopEnabled;
}), false,
);

return clusterDesktopEnabled;
}

/**
* 当两个以上(含两个)集群下都配置了文件传输功能时,才开启
* @param {Record<String, import("@scow/config/build/cluster").ClusterConfigSchema>} clusters
* @returns {boolean} fileTransferEnabled
*/
export function getFileTransferEnabled(
clusters: Record<string, ClusterConfigSchema>) {

const fileTransferEnabled = Object.values(clusters).filter(
(cluster) => cluster.crossClusterFileTransfer?.enabled).length > 1;

return fileTransferEnabled;
}

export type Cluster = { id: string; name: I18nStringType; }

Expand Down

0 comments on commit fec0a57

Please sign in to comment.