fix: hoist status badge components to module level
Inline badge components captured the styles object on every render, tripping noComponentHookFactories; move them out and pass styles as a prop. Also autofix useMathMinMax and unused-variable findings.
This commit is contained in:
parent
77aac58f22
commit
bd3e592598
@ -73,7 +73,7 @@ const AvatarList: React.FC<AvatarListProps> & {
|
||||
} = ({ children, size, maxLength = 5, excessItemsStyle, ...other }) => {
|
||||
const { styles } = useStyles();
|
||||
const numOfChildren = React.Children.count(children);
|
||||
const numToShow = maxLength >= numOfChildren ? numOfChildren : maxLength;
|
||||
const numToShow = Math.min(maxLength, numOfChildren);
|
||||
const childrenArray = React.Children.toArray(
|
||||
children,
|
||||
) as React.ReactElement<AvatarItemProps>[];
|
||||
|
||||
@ -348,6 +348,22 @@ const STATUS_TEXT: Record<BtnStatus, string> = {
|
||||
draft: '草稿',
|
||||
};
|
||||
|
||||
type PageStyles = ReturnType<typeof useStyles>['styles'];
|
||||
const StatusBadge: React.FC<{ status: number; styles: PageStyles }> = ({
|
||||
status,
|
||||
styles,
|
||||
}) => {
|
||||
const s = STATUS_MAP[status] ?? 'draft';
|
||||
const cls = s === 'published' ? styles.badgeSuccess : styles.badgeWarning;
|
||||
const dot = s === 'published' ? BF.green500 : BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const fmtTime = (ts?: number) =>
|
||||
ts ? dayjs(ts).format('YYYY-MM-DD HH:mm') : '—';
|
||||
|
||||
@ -393,18 +409,6 @@ const ButtonPage: React.FC = () => {
|
||||
});
|
||||
}, [allButtons, activeTab, search]);
|
||||
|
||||
const StatusBadge: React.FC<{ status: number }> = ({ status }) => {
|
||||
const s = STATUS_MAP[status] ?? 'draft';
|
||||
const cls = s === 'published' ? styles.badgeSuccess : styles.badgeWarning;
|
||||
const dot = s === 'published' ? BF.green500 : BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
const openCreate = () => setCreateOpen(true);
|
||||
|
||||
@ -493,7 +497,7 @@ const ButtonPage: React.FC = () => {
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.cell}>
|
||||
<StatusBadge status={b.status} />
|
||||
<StatusBadge status={b.status} styles={styles} />
|
||||
</div>
|
||||
<div className={`${styles.cell} ${styles.cellFaint}`}>
|
||||
{fmtTime(b.createdAt)}
|
||||
|
||||
@ -461,6 +461,32 @@ const STATUS_TEXT: Record<FormStatus, string> = {
|
||||
draft: '草稿',
|
||||
};
|
||||
|
||||
type PageStyles = ReturnType<typeof useStyles>['styles'];
|
||||
const StatusBadge: React.FC<{ status: number; styles: PageStyles }> = ({
|
||||
status,
|
||||
styles,
|
||||
}) => {
|
||||
const s = STATUS_MAP[status] ?? 'draft';
|
||||
const cls =
|
||||
s === 'published'
|
||||
? styles.badgeSuccess
|
||||
: s === 'disabled'
|
||||
? styles.badgeDanger
|
||||
: styles.badgeWarning;
|
||||
const dotColor =
|
||||
s === 'published'
|
||||
? BF.green500
|
||||
: s === 'disabled'
|
||||
? BF.red500
|
||||
: BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dotColor }} />
|
||||
{STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const fmtTime = (ts?: number) =>
|
||||
ts ? dayjs(ts).format('YYYY-MM-DD HH:mm') : '—';
|
||||
|
||||
@ -519,28 +545,6 @@ const FormList: React.FC = () => {
|
||||
});
|
||||
}, [allForms, activeTab, search]);
|
||||
|
||||
const StatusBadge: React.FC<{ status: number }> = ({ status }) => {
|
||||
const s = STATUS_MAP[status] ?? 'draft';
|
||||
const cls =
|
||||
s === 'published'
|
||||
? styles.badgeSuccess
|
||||
: s === 'disabled'
|
||||
? styles.badgeDanger
|
||||
: styles.badgeWarning;
|
||||
const dotColor =
|
||||
s === 'published'
|
||||
? BF.green500
|
||||
: s === 'disabled'
|
||||
? BF.red500
|
||||
: BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dotColor }} />
|
||||
{STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const toggleSelect = (key: string) => {
|
||||
setSelectedKeys((prev) => {
|
||||
const next = new Set(prev);
|
||||
@ -689,7 +693,7 @@ const FormList: React.FC = () => {
|
||||
<span className={styles.version}>
|
||||
{f.version != null ? `v${f.version}` : '—'}
|
||||
</span>
|
||||
<StatusBadge status={f.status} />
|
||||
<StatusBadge status={f.status} styles={styles} />
|
||||
</div>
|
||||
<div className={styles.cardRow}>
|
||||
<span style={{ fontSize: 12, color: BF.gray400 }}>
|
||||
@ -760,7 +764,7 @@ const FormList: React.FC = () => {
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<StatusBadge status={f.status} />
|
||||
<StatusBadge status={f.status} styles={styles} />
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
{st !== 'published' && (
|
||||
|
||||
@ -408,6 +408,31 @@ const STATUS_TEXT: Record<FnStatus, string> = {
|
||||
disabled: '已停用',
|
||||
};
|
||||
|
||||
type PageStyles = ReturnType<typeof useStyles>['styles'];
|
||||
const StatusBadge: React.FC<{ status: FnStatus; styles: PageStyles }> = ({
|
||||
status,
|
||||
styles,
|
||||
}) => {
|
||||
const cls =
|
||||
status === 'enabled'
|
||||
? styles.badgeSuccess
|
||||
: status === 'draft'
|
||||
? styles.badgeWarning
|
||||
: styles.badgeDanger;
|
||||
const dot =
|
||||
status === 'enabled'
|
||||
? BF.green600
|
||||
: status === 'draft'
|
||||
? BF.amber500
|
||||
: BF.red500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{STATUS_TEXT[status]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
/** 从 Code 字符串提取一个简短的首行预览,避免整段代码塞进列表。 */
|
||||
function codePreview(code: string): string {
|
||||
if (!code) return '';
|
||||
@ -482,27 +507,6 @@ const FunctionPage: React.FC = () => {
|
||||
});
|
||||
}, [allItems, activeTab, search]);
|
||||
|
||||
const StatusBadge: React.FC<{ status: FnStatus }> = ({ status }) => {
|
||||
const cls =
|
||||
status === 'enabled'
|
||||
? styles.badgeSuccess
|
||||
: status === 'draft'
|
||||
? styles.badgeWarning
|
||||
: styles.badgeDanger;
|
||||
const dot =
|
||||
status === 'enabled'
|
||||
? BF.green600
|
||||
: status === 'draft'
|
||||
? BF.amber500
|
||||
: BF.red500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{STATUS_TEXT[status]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
/* ---- 新建函数弹窗 ---- */
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
const [createForm] = Form.useForm<{
|
||||
@ -699,7 +703,7 @@ const FunctionPage: React.FC = () => {
|
||||
<span className={styles.mono}>{r.returns}</span>
|
||||
</div>
|
||||
<div className={styles.cell}>
|
||||
<StatusBadge status={r.status} />
|
||||
<StatusBadge status={r.status} styles={styles} />
|
||||
</div>
|
||||
</div>
|
||||
));
|
||||
|
||||
@ -370,7 +370,7 @@ const Knowledge: React.FC = () => {
|
||||
});
|
||||
}, [editing, editForm]);
|
||||
|
||||
const openEdit = (kb: KbDto) => setEditing(kb);
|
||||
const _openEdit = (kb: KbDto) => setEditing(kb);
|
||||
|
||||
const closeEdit = () => {
|
||||
if (editSaving) return;
|
||||
|
||||
@ -380,6 +380,57 @@ const INST_STATUS_TEXT: Record<InstStatus, string> = {
|
||||
terminated: '已终止',
|
||||
};
|
||||
|
||||
type PageStyles = ReturnType<typeof useStyles>['styles'];
|
||||
const DefStatusBadge: React.FC<{ status: number; styles: PageStyles }> = ({
|
||||
status,
|
||||
styles,
|
||||
}) => {
|
||||
const s = DEF_STATUS_MAP[status] ?? 'draft';
|
||||
const cls =
|
||||
s === 'published'
|
||||
? styles.badgeSuccess
|
||||
: s === 'disabled'
|
||||
? styles.badgeDanger
|
||||
: styles.badgeWarning;
|
||||
const dot =
|
||||
s === 'published'
|
||||
? BF.green500
|
||||
: s === 'disabled'
|
||||
? BF.red500
|
||||
: BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{DEF_STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const InstStatusBadge: React.FC<{ status: number; styles: PageStyles }> = ({
|
||||
status,
|
||||
styles,
|
||||
}) => {
|
||||
const s = INST_STATUS_MAP[status] ?? 'pending';
|
||||
let cls = styles.badgeNeutral;
|
||||
let dot: string = BF.gray400;
|
||||
if (s === 'running' || s === 'completed') {
|
||||
cls = styles.badgeSuccess;
|
||||
dot = BF.green500;
|
||||
} else if (s === 'waiting' || s === 'suspended') {
|
||||
cls = styles.badgeWarning;
|
||||
dot = BF.amber500;
|
||||
} else if (s === 'failed') {
|
||||
cls = styles.badgeDanger;
|
||||
dot = BF.red500;
|
||||
}
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{INST_STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const fmtTime = (ts?: number) =>
|
||||
ts ? dayjs(ts).format('YYYY-MM-DD HH:mm') : '—';
|
||||
|
||||
@ -499,51 +550,6 @@ const Workflow: React.FC = () => {
|
||||
});
|
||||
}, [instList, activeTab, search]);
|
||||
|
||||
/* ---- badges ---- */
|
||||
const DefStatusBadge: React.FC<{ status: number }> = ({ status }) => {
|
||||
const s = DEF_STATUS_MAP[status] ?? 'draft';
|
||||
const cls =
|
||||
s === 'published'
|
||||
? styles.badgeSuccess
|
||||
: s === 'disabled'
|
||||
? styles.badgeDanger
|
||||
: styles.badgeWarning;
|
||||
const dot =
|
||||
s === 'published'
|
||||
? BF.green500
|
||||
: s === 'disabled'
|
||||
? BF.red500
|
||||
: BF.amber500;
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{DEF_STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
const InstStatusBadge: React.FC<{ status: number }> = ({ status }) => {
|
||||
const s = INST_STATUS_MAP[status] ?? 'pending';
|
||||
let cls = styles.badgeNeutral;
|
||||
let dot: string = BF.gray400;
|
||||
if (s === 'running' || s === 'completed') {
|
||||
cls = styles.badgeSuccess;
|
||||
dot = BF.green500;
|
||||
} else if (s === 'waiting' || s === 'suspended') {
|
||||
cls = styles.badgeWarning;
|
||||
dot = BF.amber500;
|
||||
} else if (s === 'failed') {
|
||||
cls = styles.badgeDanger;
|
||||
dot = BF.red500;
|
||||
}
|
||||
return (
|
||||
<span className={`${styles.badge} ${cls}`}>
|
||||
<span className={styles.badgeDot} style={{ background: dot }} />
|
||||
{INST_STATUS_TEXT[s]}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
/* ---- actions ---- */
|
||||
const navigate = useNavigate();
|
||||
const [createOpen, setCreateOpen] = useState(false);
|
||||
@ -727,7 +733,7 @@ const Workflow: React.FC = () => {
|
||||
<div className={styles.cellStrong}>{i.definitionName || '—'}</div>
|
||||
</div>
|
||||
<div className={styles.cell}>
|
||||
<InstStatusBadge status={i.status} />
|
||||
<InstStatusBadge status={i.status} styles={styles} />
|
||||
</div>
|
||||
<div className={`${styles.cell} ${styles.cellMuted}`}>
|
||||
{i.currentTask || '—'}
|
||||
@ -801,7 +807,7 @@ const Workflow: React.FC = () => {
|
||||
) : null}
|
||||
</div>
|
||||
<div className={styles.cell}>
|
||||
<DefStatusBadge status={d.status} />
|
||||
<DefStatusBadge status={d.status} styles={styles} />
|
||||
</div>
|
||||
<div className={`${styles.cell} ${styles.cellMuted}`}>
|
||||
{d.version != null ? `v${d.version}` : '—'}
|
||||
|
||||
@ -149,7 +149,7 @@ const Register: FC = () => {
|
||||
<Progress
|
||||
status={passwordProgressMap[passwordStatus]}
|
||||
size={6}
|
||||
percent={value.length * 10 > 100 ? 100 : value.length * 10}
|
||||
percent={Math.min(value.length * 10, 100)}
|
||||
showInfo={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user