BulkAddToGroupModal.tsx 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { useEffect, useState } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import { AutoComplete, Form, Modal, message } from 'antd';
  4. import { FormProvider, useForm, useWatch } from 'react-hook-form';
  5. import { FormField } from '@/components/form/rhf';
  6. type GroupFormValues = { group: string };
  7. const EMPTY: GroupFormValues = { group: '' };
  8. interface BulkAddToGroupModalProps {
  9. open: boolean;
  10. count: number;
  11. groups: string[];
  12. onOpenChange: (open: boolean) => void;
  13. onSubmit: (group: string) => Promise<{ affected?: number } | null>;
  14. }
  15. export default function BulkAddToGroupModal({
  16. open,
  17. count,
  18. groups,
  19. onOpenChange,
  20. onSubmit,
  21. }: BulkAddToGroupModalProps) {
  22. const { t } = useTranslation();
  23. const [messageApi, messageContextHolder] = message.useMessage();
  24. const [submitting, setSubmitting] = useState(false);
  25. const methods = useForm<GroupFormValues>({ defaultValues: EMPTY });
  26. const group = useWatch({ control: methods.control, name: 'group' });
  27. useEffect(() => {
  28. if (open) methods.reset(EMPTY);
  29. }, [open, methods]);
  30. async function submit() {
  31. const next = (methods.getValues().group ?? '').trim();
  32. if (!next) return;
  33. setSubmitting(true);
  34. try {
  35. const result = await onSubmit(next);
  36. if (result) {
  37. const affected = result.affected ?? 0;
  38. messageApi.success(t('pages.clients.addToGroupSuccessToast', { count: affected, group: next }));
  39. onOpenChange(false);
  40. }
  41. } finally {
  42. setSubmitting(false);
  43. }
  44. }
  45. return (
  46. <>
  47. {messageContextHolder}
  48. <Modal
  49. open={open}
  50. title={t('pages.clients.addToGroupTitle', { count })}
  51. okText={t('add')}
  52. cancelText={t('cancel')}
  53. confirmLoading={submitting}
  54. okButtonProps={{ disabled: !(group ?? '').trim() }}
  55. onCancel={() => onOpenChange(false)}
  56. onOk={submit}
  57. destroyOnHidden
  58. >
  59. <FormProvider {...methods}>
  60. <Form layout="vertical">
  61. <FormField
  62. name="group"
  63. label={t('pages.clients.group')}
  64. tooltip={t('pages.clients.addToGroupTooltip')}
  65. transform={{ output: (v) => v ?? '' }}
  66. >
  67. <AutoComplete
  68. placeholder={t('pages.clients.groupName')}
  69. options={groups.map((g) => ({ value: g }))}
  70. allowClear
  71. autoFocus
  72. />
  73. </FormField>
  74. </Form>
  75. </FormProvider>
  76. </Modal>
  77. </>
  78. );
  79. }