Skip to content

ServiceProvidersPage 抽屉缺少保存按钮

背景

ProviderSheet.tsx 中,点击编辑提供商时弹出的抽屉(Sheet)底部有"取消"和"保存"按钮。但在 ServiceProvidersPage.tsx 中,点击编辑按钮弹出的抽屉没有底部保存按钮,用户无法通过点击按钮提交表单。

问题原因

ProviderSheet.tsx 第 186 行,<Sheet> 组件通过 footer prop 传入了底部按钮区域(取消 + 保存/创建按钮)。

ServiceProvidersPage.tsx 第 1127 行,<Sheet> 没有传入 footer prop,所以抽屉底部没有任何操作按钮。

ProviderSheet.tsx 有 footer:

tsx
<Sheet
  open={state.open}
  onClose={onClose}
  footer={footer}   // ← 有 footer prop
>

ServiceProvidersPage.tsx 没有 footer:

tsx
<Sheet
  open={sheetOpen}
  onClose={() => setSheetOpen(false)}
  title={t('providersPage.detail.title')}
>                      // ← 没有 footer prop

修改方案

只需修改 ServiceProvidersPage.tsx 一个文件,共 4 处改动:

改动 1:添加 useId 到 React import(第 1 行)

diff
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
+ import { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';

改动 2:导入 sharedForm.module.scss 样式(第 32 行后)

复用 ProviderSheet.tsx 中已使用的 footer 按钮样式(.footerBtn.footerBtnGhost.footerBtnPrimary)。

diff
+ import formStyles from '@/features/providers/sheets/forms/sharedForm.module.scss';
  import styles from './ServiceProvidersPage.module.scss';

改动 3:添加 editSubmitting 状态和 editFormId(第 231 行后)

diff
  const [sheetOpen, setSheetOpen] = useState(false);
+ const [editSubmitting, setEditSubmitting] = useState(false);
+ const editFormId = useId();
  const [editTarget, setEditTarget] = useState<{
  • editSubmitting:追踪表单提交中状态,提交时禁用按钮并显示加载图标
  • editFormId:用 useId() 生成唯一表单 ID,替代硬编码的 "sp-edit-form"

将原来的:

tsx
<Sheet
  open={sheetOpen}
  onClose={() => setSheetOpen(false)}
  title={t('providersPage.detail.title')}
>
  <BaseProviderForm
    brand="openaiCompatibility"
    resource={buildEditResource(editTarget.provider, editTarget.providerIdx)}
    mode="edit"
    mutating={false}
    formId="sp-edit-form"
    onSubmit={handleFormSubmit}
    renderEntryCardExtra={(realIdx) => (
      <MoveDropdown
        provider={editTarget.provider}
        allProviders={providers}
        onMove={(target) => handleMoveFromDrawer(realIdx, target)}
        disabled={false}
      />
    )}
  />
</Sheet>

替换为:

tsx
<Sheet
  open={sheetOpen}
  onClose={() => setSheetOpen(false)}
  title={t('providersPage.form.editEyebrow')}
  footer={
    <>
      <button
        type="button"
        className={`${formStyles.footerBtn} ${formStyles.footerBtnGhost}`}
        onClick={() => setSheetOpen(false)}
        disabled={editSubmitting}
      >
        {t('providersPage.actions.cancel')}
      </button>
      <button
        type="submit"
        form={editFormId}
        className={`${formStyles.footerBtn} ${formStyles.footerBtnPrimary}`}
        disabled={editSubmitting}
      >
        {editSubmitting ? (
          <IconLoader2 size={14} />
        ) : null}
        {t('providersPage.actions.save')}
      </button>
    </>
  }
  closeDisabled={editSubmitting}
>
  <BaseProviderForm
    brand="openaiCompatibility"
    resource={buildEditResource(editTarget.provider, editTarget.providerIdx)}
    mode="edit"
    mutating={editSubmitting}
    formId={editFormId}
    onSubmit={async (input) => {
      setEditSubmitting(true);
      try {
        await handleFormSubmit(input);
      } finally {
        setEditSubmitting(false);
      }
    }}
    renderEntryCardExtra={(realIdx) => (
      <MoveDropdown
        provider={editTarget.provider}
        allProviders={providers}
        onMove={(target) => handleMoveFromDrawer(realIdx, target)}
        disabled={false}
      />
    )}
  />
</Sheet>

改动要点说明

改动点说明
footer prop添加取消 + 保存按钮,与 ProviderSheet.tsx 保持一致
closeDisabled={editSubmitting}提交中禁止关闭抽屉,防止数据丢失
mutating={editSubmitting}将提交状态传递给 BaseProviderForm,禁用表单输入
formId={editFormId}使用 useId() 生成唯一 ID,避免硬编码字符串冲突
onSubmit 包装在原有 handleFormSubmit 外包一层 setEditSubmitting 状态管理
title 改为 t('providersPage.form.editEyebrow')ProviderSheet.tsx 的编辑模式标题保持一致