fix: ssh key, template test

This commit is contained in:
jialin
2026-05-11 19:49:21 +08:00
committed by jialin
parent 63ac4e0e75
commit fc900c8ce6
45 changed files with 1027 additions and 1090 deletions
@@ -1,3 +1,18 @@
.mask {
position: fixed;
inset: 0;
z-index: 1004;
height: 100%;
background-color: var(--ant-color-bg-mask);
opacity: 0;
transition: opacity var(--ant-motion-duration-slow)
var(--ant-motion-ease-in-out);
}
.maskOpen {
opacity: 1;
}
.overlay {
position: fixed;
top: 0;
@@ -15,6 +30,13 @@
-6px 0 16px 0 rgb(0 0 0 / 8%),
-3px 0 6px -4px rgb(0 0 0 / 12%),
-9px 0 28px 8px rgb(0 0 0 / 5%);
transform: translateX(100%);
transition: transform var(--ant-motion-duration-slow)
var(--ant-motion-ease-in-out);
}
.overlayOpen {
transform: translateX(0);
}
.header {
+70 -38
View File
@@ -1,5 +1,6 @@
import { ColumnWrapper, IconFont } from '@gpustack/core-ui';
import { Button, Tag } from 'antd';
import classNames from 'classnames';
import React from 'react';
import { createPortal } from 'react-dom';
import styles from './form-overlay-view.module.less';
@@ -15,6 +16,7 @@ type FormOverlayViewProps = {
width?: number | string;
className?: string;
style?: React.CSSProperties;
maskClosable?: boolean;
getContainer?: () => HTMLElement | null | undefined;
};
@@ -29,60 +31,90 @@ const FormOverlayView: React.FC<FormOverlayViewProps> = ({
width = 600,
className,
style,
maskClosable = false,
getContainer
}) => {
const [container, setContainer] = React.useState<HTMLElement | null>(null);
const [mounted, setMounted] = React.useState(false);
const [active, setActive] = React.useState(false);
React.useEffect(() => {
if (!open) {
setContainer(null);
if (open) {
setContainer(getContainer?.() ?? null);
setMounted(true);
return;
}
setContainer(getContainer?.() ?? null);
setActive(false);
}, [getContainer, open]);
if (!open) {
return null;
}
React.useEffect(() => {
if (!mounted || !container) {
return;
}
if (!container) {
const id = requestAnimationFrame(() => setActive(true));
return () => cancelAnimationFrame(id);
}, [mounted, container]);
const handleTransitionEnd = (e: React.TransitionEvent<HTMLDivElement>) => {
if (e.target !== e.currentTarget || e.propertyName !== 'transform') {
return;
}
if (!open && !active) {
setMounted(false);
setContainer(null);
}
};
if (!mounted || !container) {
return null;
}
return createPortal(
<div
className={[styles.overlay, className].filter(Boolean).join(' ')}
style={{ width, ...style }}
role="dialog"
aria-modal="true"
>
<div className={styles.header}>
<Button
type="text"
size="small"
style={{ fontWeight: 600, fontSize: 16 }}
icon={<IconFont type="icon-down2" rotate={90} />}
onClick={onCancel}
/>
<div className={styles.title}>
{title}
{subTitle && (
<Tag variant="outlined" className={styles.subTitle}>
{subTitle}
</Tag>
)}
</div>
</div>
<ColumnWrapper
styles={{
container: { paddingBlock: 16 }
}}
footer={footer}
<>
<div
className={classNames(styles.mask, { [styles.maskOpen]: active })}
onClick={maskClosable ? onCancel : undefined}
/>
<div
className={classNames(
styles.overlay,
{ [styles.overlayOpen]: active },
className
)}
style={{ width, ...style }}
role="dialog"
aria-modal="true"
onTransitionEnd={handleTransitionEnd}
>
{children}
</ColumnWrapper>
</div>,
<div className={styles.header}>
<Button
type="text"
size="small"
style={{ fontWeight: 600, fontSize: 16 }}
icon={<IconFont type="icon-down2" rotate={90} />}
onClick={onCancel}
/>
<div className={styles.title}>
{title}
{subTitle && (
<Tag variant="outlined" className={styles.subTitle}>
{subTitle}
</Tag>
)}
</div>
</div>
<ColumnWrapper
styles={{
container: { paddingBlock: 16 }
}}
footer={footer}
>
{children}
</ColumnWrapper>
</div>
</>,
container
);
};