diff --git a/apps/studio/components/grid/components/footer/pagination/Pagination.tsx b/apps/studio/components/grid/components/footer/pagination/Pagination.tsx index bc866bad1b0..5df372be147 100644 --- a/apps/studio/components/grid/components/footer/pagination/Pagination.tsx +++ b/apps/studio/components/grid/components/footer/pagination/Pagination.tsx @@ -190,34 +190,30 @@ const Pagination = ({ isLoading: isLoadingRows = false }: PaginationProps) => { setIsConfirmPreviousModalOpen(false)} - onSelectConfirm={() => { + title="Confirm moving to previous page" + confirmLabel="Confirm" + onCancel={() => setIsConfirmPreviousModalOpen(false)} + onConfirm={() => { onConfirmPreviousPage() }} > - -

- The currently selected lines will be deselected, do you want to proceed? -

-
+

+ The currently selected lines will be deselected, do you want to proceed? +

setIsConfirmNextModalOpen(false)} - onSelectConfirm={() => { + title="Confirm moving to next page" + confirmLabel="Confirm" + onCancel={() => setIsConfirmNextModalOpen(false)} + onConfirm={() => { onConfirmNextPage() }} > - -

- The currently selected lines will be deselected, do you want to proceed? -

-
+

+ The currently selected lines will be deselected, do you want to proceed? +

)} diff --git a/apps/studio/components/interfaces/Account/AccessTokenList.tsx b/apps/studio/components/interfaces/Account/AccessTokenList.tsx index 190c1141c38..f5aaca879d6 100644 --- a/apps/studio/components/interfaces/Account/AccessTokenList.tsx +++ b/apps/studio/components/interfaces/Account/AccessTokenList.tsx @@ -77,20 +77,18 @@ const AccessTokenList = () => { setIsOpen(false)} - onSelectConfirm={() => { + variant={'destructive'} + title="Confirm to delete" + confirmLabel="Delete" + confirmLabelLoading="Deleting" + onCancel={() => setIsOpen(false)} + onConfirm={() => { if (token) onDeleteToken(token.id) }} > - -

- {`This action cannot be undone. Are you sure you want to delete "${token?.name}" token?`} -

-
+

+ {`This action cannot be undone. Are you sure you want to delete "${token?.name}" token?`} +

) diff --git a/apps/studio/components/interfaces/Account/TOTPFactors/AddNewFactorModal.tsx b/apps/studio/components/interfaces/Account/TOTPFactors/AddNewFactorModal.tsx index 62d943f4895..c425c0276c2 100644 --- a/apps/studio/components/interfaces/Account/TOTPFactors/AddNewFactorModal.tsx +++ b/apps/studio/components/interfaces/Account/TOTPFactors/AddNewFactorModal.tsx @@ -64,29 +64,27 @@ const FirstStep = ({ visible, name, enroll, setName, isEnrolling, onClose }: Fir { + onCancel={onClose} + onConfirm={() => { enroll({ factorType: 'totp', friendlyName: name, }) }} > - -
- setName(e.target.value)} - /> -
-
+
+ setName(e.target.value)} + /> +
) } @@ -152,65 +150,63 @@ const SecondStep = ({ { + onCancel={() => { // If a factor has been created (but not verified), unenroll it. This will be run as a // side effect so that it's not confusing to the user why the modal stays open while // unenrolling. if (factor) unenroll({ factorId: factor.id }) }} - onSelectConfirm={() => factor && challengeAndVerify({ factorId: factor.id, code })} + onConfirm={() => factor && challengeAndVerify({ factorId: factor.id, code })} > - - <> -
- - Use an authenticator app to scan the following QR code, and provide the code from the - app to complete the enrolment. - + <> +
+ + Use an authenticator app to scan the following QR code, and provide the code from the + app to complete the enrolment. + +
+ {isLoading && ( +
+
- {isLoading && ( -
- + )} + {factor && ( + <> +
+
+ {factor.totp.uri} +
- )} - {factor && ( - <> -
-
- {factor.totp.uri} -
-
-
- - } - /> -
-
- setCode(e.target.value)} - /> -
- - )} - - +
+ + } + /> +
+
+ setCode(e.target.value)} + /> +
+ + )} + ) } diff --git a/apps/studio/components/interfaces/Account/TOTPFactors/DeleteFactorModal.tsx b/apps/studio/components/interfaces/Account/TOTPFactors/DeleteFactorModal.tsx index 37fb4319ee9..9aed5f1f80b 100644 --- a/apps/studio/components/interfaces/Account/TOTPFactors/DeleteFactorModal.tsx +++ b/apps/studio/components/interfaces/Account/TOTPFactors/DeleteFactorModal.tsx @@ -34,45 +34,36 @@ const DeleteFactorModal = ({ factorId && unenroll({ factorId })} + onCancel={onClose} + onConfirm={() => factorId && unenroll({ factorId })} + alert={{ + title: lastFactorToBeDeleted + ? 'Multi-factor authentication will be disabled' + : 'This action cannot be undone', + description: lastFactorToBeDeleted + ? 'There are no other factors that are set up once you delete this factor, as such your account will no longer be guarded by multi-factor authentication' + : 'You will no longer be able to use this authenticator app for multi-factor authentication when signing in to the dashboard', + }} > - - - - - {lastFactorToBeDeleted - ? 'Multi-factor authentication will be disabled' - : 'This action cannot be undone'} - - - {lastFactorToBeDeleted - ? 'There are no other factors that are set up once you delete this factor, as such your account will no longer be guarded by multi-factor authentication' - : 'You will no longer be able to use this authenticator app for multi-factor authentication when signing in to the dashboard'} - - -
-

Before deleting this factor, consider:

-
    - {lastFactorToBeDeleted ? ( - <> -
  • Adding another authenticator app as a factor prior to deleting
  • -
  • Ensure that your account does not need multi-factor authentication
  • - - ) : ( - <> -
  • Your backup authenticator app is still available to use
  • -
  • Adding another authenticator app thereafter as a backup
  • - - )} -
-
-
+

Before deleting this factor, consider:

+
    + {lastFactorToBeDeleted ? ( + <> +
  • Adding another authenticator app as a factor prior to deleting
  • +
  • Ensure that your account does not need multi-factor authentication
  • + + ) : ( + <> +
  • Your backup authenticator app is still available to use
  • +
  • Adding another authenticator app thereafter as a backup
  • + + )} +
) } diff --git a/apps/studio/components/interfaces/Auth/Policies/AIPolicyEditorPanel/index.tsx b/apps/studio/components/interfaces/Auth/Policies/AIPolicyEditorPanel/index.tsx index 9f73aa4ced0..616c8d14015 100644 --- a/apps/studio/components/interfaces/Auth/Policies/AIPolicyEditorPanel/index.tsx +++ b/apps/studio/components/interfaces/Auth/Policies/AIPolicyEditorPanel/index.tsx @@ -843,22 +843,20 @@ export const AIPolicyEditorPanel = memo(function ({ { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => { setIsClosingPolicyEditorPanel(false) }} - onSelectConfirm={() => { + onConfirm={() => { onSelectCancel() setIsClosingPolicyEditorPanel(false) }} > - -

- Are you sure you want to close the editor? Any unsaved changes on your policy and - conversations with the Assistant will be lost. -

-
+

+ Are you sure you want to close the editor? Any unsaved changes on your policy and + conversations with the Assistant will be lost. +

) diff --git a/apps/studio/components/interfaces/Auth/Policies/PolicyEditorModal/index.tsx b/apps/studio/components/interfaces/Auth/Policies/PolicyEditorModal/index.tsx index 39681d19b41..9c7fd55179b 100644 --- a/apps/studio/components/interfaces/Auth/Policies/PolicyEditorModal/index.tsx +++ b/apps/studio/components/interfaces/Auth/Policies/PolicyEditorModal/index.tsx @@ -187,21 +187,19 @@ const PolicyEditorModal = ({
setIsClosingPolicyEditorModal(false)} - onSelectConfirm={() => { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => setIsClosingPolicyEditorModal(false)} + onConfirm={() => { onSelectCancel() setIsClosingPolicyEditorModal(false) setIsDirty(false) }} > - -

- There are unsaved changes. Are you sure you want to close the editor? Your changes - will be lost. -

-
+

+ There are unsaved changes. Are you sure you want to close the editor? Your changes will + be lost. +

{view === POLICY_MODAL_VIEWS.SELECTION ? ( setIsDeleteModalOpen(false)} - onSelectConfirm={() => { + title="Confirm to delete" + confirmLabel="Delete" + onCancel={() => setIsDeleteModalOpen(false)} + onConfirm={() => { handleDelete() }} > - -

- This is permanent! Are you sure you want to delete user {user.email}? -

-
+

+ This is permanent! Are you sure you want to delete user {user.email}? +

setIsDeleteFactorsModalOpen(false)} - onSelectConfirm={() => { + title="Confirm to delete" + confirmLabel="Delete" + onCancel={() => setIsDeleteFactorsModalOpen(false)} + onConfirm={() => { handleDeleteFactors() }} > - -

- This is permanent! Are you sure you want to delete the user's MFA factors? -

-
+

+ This is permanent! Are you sure you want to delete the user's MFA factors? +

) diff --git a/apps/studio/components/interfaces/BranchManagement/BranchManagement.tsx b/apps/studio/components/interfaces/BranchManagement/BranchManagement.tsx index 5dfd87fe071..e9983ef50ce 100644 --- a/apps/studio/components/interfaces/BranchManagement/BranchManagement.tsx +++ b/apps/studio/components/interfaces/BranchManagement/BranchManagement.tsx @@ -344,44 +344,28 @@ const BranchManagement = () => { /> onConfirmDisableBranching()} - onSelectCancel={() => setShowDisableBranching(false)} + title="Confirm disable branching for project" + confirmLabel="Confirm disable branching" + confirmLabelLoading="Disabling branching..." + onConfirm={() => onConfirmDisableBranching()} + onCancel={() => setShowDisableBranching(false)} + alert={{ + title: 'This action cannot be undone', + description: + 'All database preview branches will be removed upon disabling branching. You may still re-enable branching again thereafter, but your existing preview branches will not be restored.', + }} > - -
- - - This action cannot be undone - - All database preview branches will be removed upon disabling branching. You may - still re-enable branching again thereafter, but your existing preview branches will - not be restored. - - -
    -
  • -
    - Before you disable branching, consider: -
      -
    • - Your project no longer requires database previews. -
    • -
    • - None of your database previews are currently being used in any app. -
    • -
    -
    -
  • -
-
-
+

Before you disable branching, consider:

+
    +
  • Your project no longer requires database previews.
  • +
  • + None of your database previews are currently being used in any app. +
  • +
setShowCreateBranch(false)} /> diff --git a/apps/studio/components/interfaces/BranchManagement/BranchPanels.tsx b/apps/studio/components/interfaces/BranchManagement/BranchPanels.tsx index 3f0823ad92a..e2652c18984 100644 --- a/apps/studio/components/interfaces/BranchManagement/BranchPanels.tsx +++ b/apps/studio/components/interfaces/BranchManagement/BranchPanels.tsx @@ -244,22 +244,19 @@ export const BranchRow = ({ { + onCancel={() => { setShowConfirmResetModal(false) }} - onSelectConfirm={onConfirmReset} + onConfirm={onConfirmReset} > - -

- Are you sure you want to reset the "{branch.name}" branch? All data will be - deleted. -

-
+

+ Are you sure you want to reset the "{branch.name}" branch? All data will be deleted. +

)} diff --git a/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx b/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx index cf631b5419b..99e30235aa5 100644 --- a/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx +++ b/apps/studio/components/interfaces/Database/Backups/BackupsList.tsx @@ -107,26 +107,22 @@ const BackupsList = () => {
setSelectedBackup(undefined)} - onSelectConfirm={() => { + onCancel={() => setSelectedBackup(undefined)} + onConfirm={() => { if (selectedBackup === undefined) return console.error('Backup required') restoreFromBackup({ ref: projectRef, backup: selectedBackup }) }} > - -
-

- Are you sure you want to restore from - {dayjs(selectedBackup?.inserted_at).format('DD MMM YYYY')}? This will destroy any new - data written since this backup was made. -

-
-
+

+ Are you sure you want to restore from + {dayjs(selectedBackup?.inserted_at).format('DD MMM YYYY')}? This will destroy any new data + written since this backup was made. +

) diff --git a/apps/studio/components/interfaces/Database/EnumeratedTypes/DeleteEnumeratedTypeModal.tsx b/apps/studio/components/interfaces/Database/EnumeratedTypes/DeleteEnumeratedTypeModal.tsx index 543d9c03522..5d54690663d 100644 --- a/apps/studio/components/interfaces/Database/EnumeratedTypes/DeleteEnumeratedTypeModal.tsx +++ b/apps/studio/components/interfaces/Database/EnumeratedTypes/DeleteEnumeratedTypeModal.tsx @@ -46,40 +46,32 @@ const DeleteEnumeratedTypeModal = ({ return ( Confirm to delete enumerated type{' '} {selectedEnumeratedType?.name} } - buttonLabel="Confirm delete" - buttonLoadingLabel="Deleting..." - onSelectConfirm={() => onConfirmDeleteType()} - onSelectCancel={onClose} + confirmLabel="Confirm delete" + confirmLabelLoading="Deleting..." + onCancel={onClose} + onConfirm={() => onConfirmDeleteType()} + alert={{ + title: 'This action cannot be undone', + description: + 'You will need to re-create the enumerated type if you want to revert the deletion.', + }} > - -
- - - This action cannot be undone - - You will need to re-create the enumerated type if you want to revert the deletion. - - -
- Before deleting this enumerated type, consider: -
    -
  • - This enumerated type is no longer in use in any tables or functions -
  • -
-
-
-
+

Before deleting this enumerated type, consider:

+
    +
  • + This enumerated type is no longer in use in any tables or functions +
  • +
) } diff --git a/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx b/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx index 2600bc9d264..820fec90bf2 100644 --- a/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx +++ b/apps/studio/components/interfaces/Database/Extensions/ExtensionCard.tsx @@ -139,17 +139,15 @@ const ExtensionCard = ({ extension }: ExtensionCardProps) => { /> setIsDisableModalOpen(false)} - onSelectConfirm={() => onConfirmDisable()} + title="Confirm to disable extension" + confirmLabel="Disable" + confirmLabelLoading="Disabling" + onCancel={() => setIsDisableModalOpen(false)} + onConfirm={() => onConfirmDisable()} > - -

- Are you sure you want to turn OFF the "{extension.name}" extension? -

-
+

+ Are you sure you want to turn OFF the "{extension.name}" extension? +

) diff --git a/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx b/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx index 7a80bf93977..22b26ae53ac 100644 --- a/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx +++ b/apps/studio/components/interfaces/Database/Functions/CreateFunction/index.tsx @@ -405,20 +405,18 @@ const CreateFunction = ({ func, visible, setVisible }: CreateFunctionProps) => { ) : null} setIsClosingPanel(false)} - onSelectConfirm={() => { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => setIsClosingPanel(false)} + onConfirm={() => { setIsClosingPanel(false) setVisible(!visible) }} > - -

- There are unsaved changes. Are you sure you want to close the panel? Your changes will - be lost. -

-
+

+ There are unsaved changes. Are you sure you want to close the panel? Your changes will + be lost. +

diff --git a/apps/studio/components/interfaces/Database/Hooks/EditHookPanel.tsx b/apps/studio/components/interfaces/Database/Hooks/EditHookPanel.tsx index c978ecc60d5..facc120d93e 100644 --- a/apps/studio/components/interfaces/Database/Hooks/EditHookPanel.tsx +++ b/apps/studio/components/interfaces/Database/Hooks/EditHookPanel.tsx @@ -310,21 +310,19 @@ const EditHookPanel = ({ visible, selectedHook, onClose }: EditHookPanelProps) = setIsClosingPanel(false)} - onSelectConfirm={() => { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => setIsClosingPanel(false)} + onConfirm={() => { setIsClosingPanel(false) setIsEdited(false) onClose() }} > - -

- There are unsaved changes. Are you sure you want to close the panel? Your changes will - be lost. -

-
+

+ There are unsaved changes. Are you sure you want to close the panel? Your changes will be + lost. +

) diff --git a/apps/studio/components/interfaces/Database/Indexes/Indexes.tsx b/apps/studio/components/interfaces/Database/Indexes/Indexes.tsx index b6cd32c80f7..bcf10959d40 100644 --- a/apps/studio/components/interfaces/Database/Indexes/Indexes.tsx +++ b/apps/studio/components/interfaces/Database/Indexes/Indexes.tsx @@ -278,48 +278,41 @@ const Indexes = () => { setShowCreateIndex(false)} /> Confirm to delete index {selectedIndexToDelete?.name} } - buttonLabel="Confirm delete" - buttonLoadingLabel="Deleting..." - onSelectConfirm={() => + confirmLabel="Confirm delete" + confirmLabelLoading="Deleting..." + onConfirm={() => selectedIndexToDelete !== undefined ? onConfirmDeleteIndex(selectedIndexToDelete) : {} } - onSelectCancel={() => setSelectedIndexToDelete(undefined)} + onCancel={() => setSelectedIndexToDelete(undefined)} + alert={{ + title: 'This action cannot be undone', + description: + 'Deleting an index that is still in use will cause queries to slow down, and in some cases causing significant performance issues.', + }} > - -
- - - This action cannot be undone - - Deleting an index that is still in use will cause queries to slow down, and in some - cases causing significant performance issues. - - -
    -
  • -
    - Before deleting this index, consider: -
      -
    • This index is no longer in use
    • -
    • - The table which the index is on is not currently in use, as dropping an index - requires a short exclusive access lock on the table. -
    • -
    -
    -
  • -
-
-
+
    +
  • +
    + Before deleting this index, consider: +
      +
    • This index is no longer in use
    • +
    • + The table which the index is on is not currently in use, as dropping an index + requires a short exclusive access lock on the table. +
    • +
    +
    +
  • +
) diff --git a/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx b/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx index c4bfac6985b..f527c5de428 100644 --- a/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx +++ b/apps/studio/components/interfaces/Database/Publications/PublicationsList.tsx @@ -173,21 +173,19 @@ const PublicationsList = ({ onSelectPublication = noop }: PublicationsListProps) setToggleListenEventValue(null)} - onSelectConfirm={() => { + title={`Confirm to toggle sending ${toggleListenEventValue?.event.event.toLowerCase()} events`} + confirmLabel="Confirm" + confirmLabelLoading="Updating" + onCancel={() => setToggleListenEventValue(null)} + onConfirm={() => { toggleListenEvent() }} > - -

- Are you sure you want to {toggleListenEventValue?.currentStatus ? 'stop' : 'start'}{' '} - sending {toggleListenEventValue?.event.event.toLowerCase()} events for{' '} - {toggleListenEventValue?.publication.name}? -

-
+

+ Are you sure you want to {toggleListenEventValue?.currentStatus ? 'stop' : 'start'}{' '} + sending {toggleListenEventValue?.event.event.toLowerCase()} events for{' '} + {toggleListenEventValue?.publication.name}? +

) diff --git a/apps/studio/components/interfaces/Database/Triggers/CreateTrigger.tsx b/apps/studio/components/interfaces/Database/Triggers/CreateTrigger.tsx index a06d5df1acb..17a8499e988 100644 --- a/apps/studio/components/interfaces/Database/Triggers/CreateTrigger.tsx +++ b/apps/studio/components/interfaces/Database/Triggers/CreateTrigger.tsx @@ -383,20 +383,18 @@ const CreateTrigger = ({ trigger, visible, setVisible }: CreateTriggerProps) => setIsClosingPanel(false)} - onSelectConfirm={() => { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => setIsClosingPanel(false)} + onConfirm={() => { setIsClosingPanel(false) setVisible(!visible) }} > - -

- There are unsaved changes. Are you sure you want to close the panel? Your changes - will be lost. -

-
+

+ There are unsaved changes. Are you sure you want to close the panel? Your changes + will be lost. +

) : ( diff --git a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx index 53bd9781550..00c93883347 100644 --- a/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx +++ b/apps/studio/components/interfaces/Functions/EdgeFunctionSecrets/EdgeFunctionSecrets.tsx @@ -121,22 +121,20 @@ const EdgeFunctionSecrets = () => { setSelectedSecret(undefined)} - onSelectConfirm={() => { + confirmLabel="Delete secret" + confirmLabelLoading="Deleting secret" + title={`Confirm to delete secret "${selectedSecret?.name}"`} + onCancel={() => setSelectedSecret(undefined)} + onConfirm={() => { if (selectedSecret !== undefined) { deleteSecret({ projectRef, secrets: [selectedSecret.name] }) } }} > - -

- Before removing this secret, do ensure that none of your edge functions are currently - actively using this secret. This action cannot be undone. -

-
+

+ Before removing this secret, do ensure that none of your edge functions are currently + actively using this secret. This action cannot be undone. +

) diff --git a/apps/studio/components/interfaces/Integrations/IntegrationConnection.tsx b/apps/studio/components/interfaces/Integrations/IntegrationConnection.tsx index 3f4974ec761..e050d242b16 100644 --- a/apps/studio/components/interfaces/Integrations/IntegrationConnection.tsx +++ b/apps/studio/components/interfaces/Integrations/IntegrationConnection.tsx @@ -137,29 +137,26 @@ const IntegrationConnectionItem = forwardRef - - {type === 'GitHub' && isBranchingEnabled && ( - - - Branching will be disabled for this project - - Deleting this GitHub connection will remove all preview branches on this project, - and also disable branching for {project.name} - - - )} -

- This action cannot be undone. Are you sure you want to delete this {type} connection? -

-
+

+ This action cannot be undone. Are you sure you want to delete this {type} connection? +

) diff --git a/apps/studio/components/interfaces/Organization/Documents/SOC2.tsx b/apps/studio/components/interfaces/Organization/Documents/SOC2.tsx index 675fe63790b..c2417c023b8 100644 --- a/apps/studio/components/interfaces/Organization/Documents/SOC2.tsx +++ b/apps/studio/components/interfaces/Organization/Documents/SOC2.tsx @@ -73,53 +73,46 @@ const SOC2 = () => { )} setIsOpen(false)} size="large" - onSelectConfirm={() => { + title="Non-Disclosure Agreement to access Supabase's SOC2 Report" + confirmLabel="I agree" + confirmLabelLoading="Downloading" + onCancel={() => setIsOpen(false)} + onConfirm={() => { if (slug) fetchSOC2(slug) }} > - -
-
    -
  1. The information that you are about to access is confidential.
  2. +
      +
    1. The information that you are about to access is confidential.
    2. +
    3. + Your access to our SOC 2 materials is governed by confidentiality obligations + contained in the agreement between Supabase, Inc ("Supabase", "we", "our" or "us") and + the Supabase customer that has authorized you to access our platform to obtain this + information (our "Customer"). +
    4. +
    5. + You must ensure that you treat the information in our SOC 2 materials in accordance + with those confidentiality obligations, as communicated to you by the Customer. +
    6. +
    7. + By clicking "I agree" below or otherwise accessing our SOC 2 materials, you: +
        +
      1. acknowledge that you have read and understood this Confidentiality Notice;
      2. - Your access to our SOC 2 materials is governed by confidentiality obligations - contained in the agreement between Supabase, Inc ("Supabase", "we", "our" or "us") - and the Supabase customer that has authorized you to access our platform to obtain - this information (our "Customer"). -
      3. -
      4. - You must ensure that you treat the information in our SOC 2 materials in - accordance with those confidentiality obligations, as communicated to you by the - Customer. -
      5. -
      6. - By clicking "I agree" below or otherwise accessing our SOC 2 materials, you: -
          -
        1. - acknowledge that you have read and understood this Confidentiality Notice; -
        2. -
        3. - confirm that you have been authorized by the Customer to access this - information, and your use of our SOC 2 materials is subject to the - confidentiality obligations owed by the Customer to us. -
        4. -
        -
      7. -
      8. - This Confidentiality Notice does not substitute or supersede any agreement between - us and the Customer, or any internal rules or policies that the Customer requires - you to comply with in your access to and use of confidential information. However, - your failure to comply with this Confidentiality Notice may be used to determine - whether the Customer has complied with its confidentiality obligations to us. + confirm that you have been authorized by the Customer to access this information, + and your use of our SOC 2 materials is subject to the confidentiality obligations + owed by the Customer to us.
      -
-
+ +
  • + This Confidentiality Notice does not substitute or supersede any agreement between us + and the Customer, or any internal rules or policies that the Customer requires you to + comply with in your access to and use of confidential information. However, your + failure to comply with this Confidentiality Notice may be used to determine whether + the Customer has complied with its confidentiality obligations to us. +
  • +
    diff --git a/apps/studio/components/interfaces/Organization/TeamSettings/MemberActions.tsx b/apps/studio/components/interfaces/Organization/TeamSettings/MemberActions.tsx index 3d0dc8ea63a..e905e0ff003 100644 --- a/apps/studio/components/interfaces/Organization/TeamSettings/MemberActions.tsx +++ b/apps/studio/components/interfaces/Organization/TeamSettings/MemberActions.tsx @@ -190,18 +190,16 @@ const MemberActions = ({ member, roles }: MemberActionsProps) => { setIsDeleteModalOpen(false)} - onSelectConfirm={() => { + title="Confirm to remove" + confirmLabel="Remove" + onCancel={() => setIsDeleteModalOpen(false)} + onConfirm={() => { handleMemberDelete() }} > - -

    - This is permanent! Are you sure you want to remove {member.primary_email} -

    -
    +

    + This is permanent! Are you sure you want to remove {member.primary_email} +

    ) diff --git a/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx b/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx index cebaac3d4f0..7c48c266479 100644 --- a/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx +++ b/apps/studio/components/interfaces/Organization/TeamSettings/TeamSettings.tsx @@ -143,18 +143,16 @@ const TeamSettings = () => { setIsLeaveTeamModalOpen(false)} - onSelectConfirm={() => { + title="Are you sure?" + confirmLabel="Leave" + onCancel={() => setIsLeaveTeamModalOpen(false)} + onConfirm={() => { leaveTeam() }} > - -

    - Are you sure you want to leave this organization? This is permanent. -

    -
    +

    + Are you sure you want to leave this organization? This is permanent. +

    ) diff --git a/apps/studio/components/interfaces/Realtime/Inspector/ApplyConfigModal.tsx b/apps/studio/components/interfaces/Realtime/Inspector/ApplyConfigModal.tsx deleted file mode 100644 index 45cdf42973c..00000000000 --- a/apps/studio/components/interfaces/Realtime/Inspector/ApplyConfigModal.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { Modal } from 'ui' - -import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' - -interface ApplyConfigModalProps { - visible: boolean - onSelectCancel: () => void - onSelectConfirm: () => void -} - -export const ApplyConfigModal = (props: ApplyConfigModalProps) => { - return ( - - -
    -

    -

    - The realtime inspector will clear currently collected messages and start listening for - new messages matching the updated filters. -

    -
    -
    -
    - ) -} diff --git a/apps/studio/components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx b/apps/studio/components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx index f0d5a1accfc..62d4c522a09 100644 --- a/apps/studio/components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx +++ b/apps/studio/components/interfaces/Realtime/Inspector/RealtimeFilterPopover/index.tsx @@ -18,10 +18,10 @@ import { } from 'ui' import Telemetry from 'lib/telemetry' -import { ApplyConfigModal } from '../ApplyConfigModal' import { RealtimeConfig } from '../useRealtimeMessages' import { FilterSchema } from './FilterSchema' import { FilterTable } from './FilterTable' +import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' interface RealtimeFilterPopoverProps { config: RealtimeConfig @@ -194,10 +194,14 @@ export const RealtimeFilterPopover = ({ config, onChangeConfig }: RealtimeFilter - setApplyConfigOpen(false)} - onSelectConfirm={() => { + onCancel={() => setApplyConfigOpen(false)} + onConfirm={() => { Telemetry.sendEvent( { category: 'realtime_inspector', @@ -211,7 +215,12 @@ export const RealtimeFilterPopover = ({ config, onChangeConfig }: RealtimeFilter setApplyConfigOpen(false) setOpen(false) }} - /> + > +

    + The realtime inspector will clear currently collected messages and start listening for new + messages matching the updated filters. +

    +
    ) } diff --git a/apps/studio/components/interfaces/Settings/API/JWTSettings.tsx b/apps/studio/components/interfaces/Settings/API/JWTSettings.tsx index cec5547d958..e967351ba96 100644 --- a/apps/studio/components/interfaces/Settings/API/JWTSettings.tsx +++ b/apps/studio/components/interfaces/Settings/API/JWTSettings.tsx @@ -213,32 +213,31 @@ const JWTSettings = () => { setIsGeneratingKey(false)} - onSelectConfirm={() => handleJwtSecretUpdate('ROLL', setIsGeneratingKey)} - > - - - - This will invalidate all existing API keys - + title="Confirm to generate a new JWT secret" + confirmLabel="Generate new secret" + confirmLabelLoading="Generating" + onCancel={() => setIsGeneratingKey(false)} + onConfirm={() => handleJwtSecretUpdate('ROLL', setIsGeneratingKey)} + alert={{ + title: 'This will invalidate all existing API keys', + description: ( + <> Generating a new JWT secret will invalidate all of your API keys, including your service_role and{' '} anon keys. Your project will also be restarted during this process, which will terminate any existing connections. You may receive API errors for up to 2 minutes while the new secret is deployed. - - -

    - This action cannot be undone and the old JWT secret will be lost. All existing API keys - will be invalidated, and any open connections will be terminated. -

    -
    + + ), + }} + > +

    + This action cannot be undone and the old JWT secret will be lost. All existing API keys + will be invalidated, and any open connections will be terminated. +

    { setShowUnban(false)} - > - -
    - - - This action cannot be undone - - Are you sure you want to unban this IP address {selectedIPToUnban}? - - -
    -
    -
    + title="Confirm Unban IP" + confirmLabel="Confirm Unban" + confirmLabelLoading="Unbanning..." + onCancel={() => setShowUnban(false)} + onConfirm={onConfirmUnbanIP} + alert={{ + title: 'This action cannot be undone', + description: `Are you sure you want to unban this IP address ${selectedIPToUnban}?`, + }} + /> ) } diff --git a/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainActivate.tsx b/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainActivate.tsx index 74959f2a485..758fb335633 100644 --- a/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainActivate.tsx +++ b/apps/studio/components/interfaces/Settings/General/CustomDomainConfig/CustomDomainActivate.tsx @@ -147,20 +147,18 @@ const CustomDomainActivate = ({ projectRef, customDomain }: CustomDomainActivate size="small" loading={isCheckingRecord || isActivating} visible={isActivateConfirmModalVisible} - header={ -
    + title={ + <> Are you sure you want to activate the custom domain{' '} {customDomain.hostname} for the project? -
    + } - buttonLabel="Activate" - buttonLoadingLabel="Activating" - onSelectCancel={() => setIsActivateConfirmModalVisible(false)} - onSelectConfirm={onActivateCustomDomain} + confirmLabel="Activate" + confirmLabelLoading="Activating" + onCancel={() => setIsActivateConfirmModalVisible(false)} + onConfirm={onActivateCustomDomain} > - -

    The existing Supabase subdomain will be deactivated.

    -
    +

    The existing Supabase subdomain will be deactivated.

    ) diff --git a/apps/studio/components/interfaces/Settings/General/Infrastructure/PauseProjectButton.tsx b/apps/studio/components/interfaces/Settings/General/Infrastructure/PauseProjectButton.tsx index 82d7d190067..53bc74a3069 100644 --- a/apps/studio/components/interfaces/Settings/General/Infrastructure/PauseProjectButton.tsx +++ b/apps/studio/components/interfaces/Settings/General/Infrastructure/PauseProjectButton.tsx @@ -94,22 +94,19 @@ const PauseProjectButton = () => { ) : null} setIsModalOpen(false)} - onSelectConfirm={requestPauseProject} + title="Pause this project?" + confirmLabel="Pause project" + confirmLabelLoading="Pausing project" + onCancel={() => setIsModalOpen(false)} + onConfirm={requestPauseProject} > - -

    - Are you sure you want to pause this project? It will not be accessible until you unpause - it. -

    -
    +

    + Are you sure you want to pause this project? It will not be accessible until you unpause + it. +

    ) diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropAllReplicasConfirmationModal.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropAllReplicasConfirmationModal.tsx index 76e71c4117d..f3b973fc212 100644 --- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropAllReplicasConfirmationModal.tsx +++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropAllReplicasConfirmationModal.tsx @@ -59,31 +59,24 @@ const DropAllReplicasConfirmationModal = ({ return ( onCancel()} - onSelectConfirm={() => onConfirmRemove()} + title="Confirm to drop all read replicas?" + confirmLabel="Drop all replicas" + confirmLabelLoading="Dropping all replicas" + onCancel={() => onCancel()} + onConfirm={() => onConfirmRemove()} + alert={{ + title: 'This action cannot be undone', + description: 'You may still deploy new replicas in this region thereafter', + }} > - - - - This action cannot be undone - - You may still deploy new replicas in this region thereafter - - -
    -

    Before deleting all replicas, consider:

    -
      -
    • Network traffic from this region may slow down
    • -
    -
    -
    +

    Before deleting all replicas, consider:

    +
    ) } diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropReplicaConfirmationModal.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropReplicaConfirmationModal.tsx index 50ea8ea2e21..096b5196991 100644 --- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropReplicaConfirmationModal.tsx +++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/DropReplicaConfirmationModal.tsx @@ -43,34 +43,27 @@ const DropReplicaConfirmationModal = ({ return ( onCancel()} - onSelectConfirm={() => onConfirmRemove()} + title={`Confirm to drop selected replica? (ID: ${formattedId})`} + confirmLabel="Drop replica" + confirmLabelLoading="Dropping replica" + onCancel={() => onCancel()} + onConfirm={() => onConfirmRemove()} + alert={{ + title: 'This action cannot be undone', + description: 'You may still deploy a new replica in this region thereafter', + }} > - - - - This action cannot be undone - - You may still deploy a new replica in this region thereafter - - -
    -

    Before deleting this replica, consider:

    -
      -
    • - Network traffic from this region may slow down, especially if you have no other - replicas in this region -
    • -
    -
    -
    +

    Before deleting this replica, consider:

    +
    ) } diff --git a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx index cbe5fb1cf77..3d9d7be27be 100644 --- a/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx +++ b/apps/studio/components/interfaces/Settings/Infrastructure/InfrastructureConfiguration/InstanceConfiguration.tsx @@ -285,24 +285,22 @@ const InstanceConfigurationUI = () => { {/* setSelectedReplicaToRestart(undefined)} - onSelectConfirm={() => onConfirmRestartReplica()} + title="Confirm to restart selected replica?" + confirmLabel="Restart replica" + confirmLabelLoading="Restarting replica" + onCancel={() => setSelectedReplicaToRestart(undefined)} + onConfirm={() => onConfirmRestartReplica()} > - -

    Before restarting the replica, consider:

    -
      -
    • - Network traffic from this region may slow down while the replica is restarting, - especially if you have no other replicas in this region -
    • -
    -

    - Are you sure you want to restart this replica (ID: {selectedReplicaToRestart?.id}) now?{' '} -

    -
    +

    Before restarting the replica, consider:

    + +

    + Are you sure you want to restart this replica (ID: {selectedReplicaToRestart?.id}) now?{' '} +

    */} ) diff --git a/apps/studio/components/interfaces/Settings/Logs/Logs.SavedQueriesItem.tsx b/apps/studio/components/interfaces/Settings/Logs/Logs.SavedQueriesItem.tsx index 0b4fa8195c0..c72039b9996 100644 --- a/apps/studio/components/interfaces/Settings/Logs/Logs.SavedQueriesItem.tsx +++ b/apps/studio/components/interfaces/Settings/Logs/Logs.SavedQueriesItem.tsx @@ -132,20 +132,18 @@ const SavedQueriesItem = ({ item }: SavedQueriesItemProps) => { { + confirmLabel="Delete query" + title="Confirm to delete saved query" + onCancel={() => { setShowConfirmModal(false) }} - onSelectConfirm={onConfirmDelete} + onConfirm={onConfirmDelete} > - -

    - Are you sure you want to delete {item.name}? -

    -
    +

    + Are you sure you want to delete {item.name}? +

    { + confirmLabel="Delete" + confirmLabelLoading="Deleting" + onCancel={() => { snap.closeConfirmationDialog() }} - onSelectConfirm={onConfirmDeleteColumn} + onConfirm={onConfirmDeleteColumn} > - -
    -

    - Are you sure you want to delete the selected column? This action cannot be undone. -

    - snap.toggleConfirmationIsWithCascade()} - /> - {isDeleteWithCascade && ( - -

    - All dependent objects will be removed, as will any objects that depend on them, - recursively. -

    +
    +

    + Are you sure you want to delete the selected column? This action cannot be undone. +

    + snap.toggleConfirmationIsWithCascade()} + /> + {isDeleteWithCascade && ( + + + All dependent objects will be removed, as will any objects that depend on them, + recursively. + + - - )} -
    - + + + )} +
    {`Confirm deletion of table "${selectedTable?.name}"`} } - buttonLabel="Delete" - buttonLoadingLabel="Deleting" - onSelectCancel={() => { + confirmLabel="Delete" + confirmLabelLoading="Deleting" + onCancel={() => { snap.closeConfirmationDialog() }} - onSelectConfirm={onConfirmDeleteTable} + onConfirm={onConfirmDeleteTable} > - -
    -

    - Are you sure you want to delete the selected table? This action cannot be undone. -

    - snap.toggleConfirmationIsWithCascade(!isDeleteWithCascade)} - /> - {isDeleteWithCascade && ( - -

    - All dependent objects will be removed, as will any objects that depend on them, - recursively. -

    - -
    - )} -
    -
    +
    +

    + Are you sure you want to delete the selected table? This action cannot be undone. +

    + snap.toggleConfirmationIsWithCascade(!isDeleteWithCascade)} + /> + {isDeleteWithCascade && ( + +

    + All dependent objects will be removed, as will any objects that depend on them, + recursively. +

    + +
    + )} +
    Confirm to delete the selected row{numRows > 1 && 's'} } - buttonLabel="Delete" - buttonLoadingLabel="Deleting" - onSelectCancel={() => snap.closeConfirmationDialog()} - onSelectConfirm={() => onConfirmDeleteRow()} + confirmLabel="Delete" + confirmLabelLoading="Deleting" + onCancel={() => snap.closeConfirmationDialog()} + onConfirm={() => onConfirmDeleteRow()} > - -
    -

    - Are you sure you want to delete {isAllRowsSelected ? 'all' : 'the selected'}{' '} - {numRows > 1 && `${numRows} `}row - {numRows > 1 && 's'}? This action cannot be undone. -

    -
    -
    +
    +

    + Are you sure you want to delete {isAllRowsSelected ? 'all' : 'the selected'}{' '} + {numRows > 1 && `${numRows} `}row + {numRows > 1 && 's'}? This action cannot be undone. +

    +
    ) diff --git a/apps/studio/components/interfaces/TableGridEditor/GridHeaderActions.tsx b/apps/studio/components/interfaces/TableGridEditor/GridHeaderActions.tsx index 363bd9a890e..0bd784d291c 100644 --- a/apps/studio/components/interfaces/TableGridEditor/GridHeaderActions.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/GridHeaderActions.tsx @@ -267,13 +267,13 @@ const GridHeaderActions = ({ table, isViewSelected, isTableSelected }: GridHeade setShowEnableRealtime(false)} - onSelectConfirm={() => toggleRealtime()} + title={`${isRealtimeEnabled ? 'Disable' : 'Enable'} realtime for ${table.name}`} + confirmLabel={`${isRealtimeEnabled ? 'Disable' : 'Enable'} realtime`} + confirmLabelLoading={`${isRealtimeEnabled ? 'Disabling' : 'Enabling'} realtime`} + onCancel={() => setShowEnableRealtime(false)} + onConfirm={() => toggleRealtime()} > - +

    Once realtime has been {isRealtimeEnabled ? 'disabled' : 'enabled'}, the table will{' '} {isRealtimeEnabled ? 'no longer ' : ''}broadcast any changes to authorized subscribers. @@ -287,7 +287,7 @@ const GridHeaderActions = ({ table, isViewSelected, isTableSelected }: GridHeade settings.

    )} - +
    setIsClosingPanel(false)} - onSelectConfirm={() => { + title="Discard changes" + confirmLabel="Discard" + onCancel={() => setIsClosingPanel(false)} + onConfirm={() => { setIsClosingPanel(false) setIsEdited(false) snap.closeSidePanel() }} > - -

    - There are unsaved changes. Are you sure you want to close the panel? Your changes will - be lost. -

    -
    +

    + There are unsaved changes. Are you sure you want to close the panel? Your changes will be + lost. +

    ) diff --git a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx index aac92fe2d89..fb40e8e7a05 100644 --- a/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx +++ b/apps/studio/components/interfaces/TableGridEditor/SidePanelEditor/TableEditor/TableEditor.tsx @@ -402,18 +402,16 @@ const TableEditor = ({ setRlsConfirmVisible(false)} - onSelectConfirm={() => { + onCancel={() => setRlsConfirmVisible(false)} + onConfirm={() => { onUpdateField({ isRLSEnabled: !tableFields.isRLSEnabled }) setRlsConfirmVisible(false) }} > - - - + diff --git a/apps/studio/components/layouts/ReportsLayout/ReportsMenu.tsx b/apps/studio/components/layouts/ReportsLayout/ReportsMenu.tsx index 681b221152e..ee465c45186 100644 --- a/apps/studio/components/layouts/ReportsLayout/ReportsMenu.tsx +++ b/apps/studio/components/layouts/ReportsLayout/ReportsMenu.tsx @@ -287,13 +287,14 @@ const ReportsMenu = () => { }} /> { + onCancel={() => setDeleteModalOpen(false)} + onConfirm={async () => { if (selectedReport) { if (!selectedReport.id) return await deleteReport.mutateAsync({ @@ -305,17 +306,12 @@ const ReportsMenu = () => { } setDeleteModalOpen(false) }} - onSelectCancel={() => setDeleteModalOpen(false)} > - -
    -
    -
    -

    Are you sure you want to delete '{selectedReport?.name}'?

    -
    -
    +
    +
    +

    Are you sure you want to delete '{selectedReport?.name}'?

    - +
    setRenameModalOpen(false)} /> setDeleteModalOpen(false)} + variant={'destructive'} + onCancel={() => setDeleteModalOpen(false)} + onConfirm={onConfirmDelete} + alert={ + visibility === 'project' + ? { + title: 'This SQL snippet will be lost forever', + description: + 'Deleting this query will remove it for all members of the project team.', + } + : {} + } > - - {visibility === 'project' && ( - - - This SQL snippet will be lost forever - - Deleting this query will remove it for all members of the project team. - - - )} -

    Are you sure you want to delete '{name}'?

    -
    +

    Are you sure you want to delete '{name}'?

    setShareModalOpen(false)} + onCancel={() => setShareModalOpen(false)} + onConfirm={onConfirmShare} + alert={{ + title: 'This SQL query will become public to all team members', + description: 'Anyone with access to the project can view it', + }} > - - - - - This SQL query will become public to all team members - - - Anyone with access to the project can view it - - -
      -
    • - - Project members will have read-only access to this query. -
    • -
    • - - Anyone will be able to duplicate it to their personal snippets. -
    • -
    -
    +
      +
    • + + Project members will have read-only access to this query. +
    • +
    • + + Anyone will be able to duplicate it to their personal snippets. +
    • +
    {
    1 ? 'ies' : 'y'}`} - buttonLoadingLabel="Deleting query" + title="Confirm to delete query" + confirmLabel={`Delete ${selectedQueries.length.toLocaleString()} quer${selectedQueries.length > 1 ? 'ies' : 'y'}`} + confirmLabelLoading="Deleting query" size="medium" loading={isDeleting} visible={showDeleteModal} - onSelectConfirm={onConfirmDelete} - onSelectCancel={() => setShowDeleteModal(false)} - danger + onConfirm={onConfirmDelete} + onCancel={() => setShowDeleteModal(false)} + variant={'destructive'} + alert={{ + title: 'This action cannot be undone', + description: 'The selected SQL snippets cannot be recovered once deleted', + }} > - -
    -
    -
    - - - This action cannot be undone - - The selected SQL snippets cannot be recovered once deleted - - -

    - Are you sure you want to delete the selected {selectedQueries.length} quer - {selectedQueries.length > 1 ? 'ies' : 'y'}? -

    -
    -
    -
    -
    +

    + Are you sure you want to delete the selected {selectedQueries.length} quer + {selectedQueries.length > 1 ? 'ies' : 'y'}? +

    ) diff --git a/apps/studio/components/to-be-cleaned/Storage/EmptyBucketModal.tsx b/apps/studio/components/to-be-cleaned/Storage/EmptyBucketModal.tsx index c8ec9060e0c..4ea1860f3fe 100644 --- a/apps/studio/components/to-be-cleaned/Storage/EmptyBucketModal.tsx +++ b/apps/studio/components/to-be-cleaned/Storage/EmptyBucketModal.tsx @@ -40,24 +40,19 @@ export const EmptyBucketModal = ({ visible = false, bucket, onClose }: EmptyBuck return ( onClose()} - onSelectConfirm={onEmptyBucket} - header={`Confirm to delete all contents from ${bucket?.name}`} - buttonLabel="Empty bucket" + onCancel={() => onClose()} + onConfirm={onEmptyBucket} + alert={{ + title: 'This action cannot be undone', + description: 'The contents of your bucket cannot be recovered once deleted', + }} > - - - - This action cannot be undone - - The contents of your bucket cannot be recovered once deleted - - -

    Are you sure you want to empty the bucket "{bucket?.name}"?

    -
    +

    Are you sure you want to empty the bucket "{bucket?.name}"?

    ) } diff --git a/packages/ui-patterns/Dialogs/ConfirmationModal.tsx b/packages/ui-patterns/Dialogs/ConfirmationModal.tsx index 4a3f41fd176..e6069034ade 100644 --- a/packages/ui-patterns/Dialogs/ConfirmationModal.tsx +++ b/packages/ui-patterns/Dialogs/ConfirmationModal.tsx @@ -1,80 +1,135 @@ -import { MouseEventHandler, PropsWithChildren, useEffect, useState } from 'react' -import { Button, Modal } from 'ui' +'use client' + +import { MouseEventHandler, forwardRef, useEffect, useState } from 'react' +import { + Admonition, + Alert_Shadcn_, + Button, + Dialog, + DialogContent, + DialogSection, + DialogSectionSeparator, + DialogTitle, + cn, +} from 'ui' +import { DialogHeader } from 'ui/src/components/shadcn/ui/dialog' export interface ConfirmationModalProps { - visible: boolean - danger?: boolean loading?: boolean - header: string | JSX.Element - description?: string - size?: 'small' | 'tiny' | 'medium' | 'large' - buttonLabel: string - buttonLoadingLabel?: string - buttonDisabled?: boolean - onSelectCancel: () => void - onSelectConfirm: () => void -} - -const ConfirmationModal = ({ - visible = false, - loading: loading_ = false, - danger = false, - header = '', - description = '', - size = 'small', - buttonLabel = '', - buttonLoadingLabel = '', - buttonDisabled = false, - onSelectCancel = () => {}, - onSelectConfirm = () => {}, - children, -}: PropsWithChildren) => { - useEffect(() => { - if (visible) { - setLoading(false) - } - }, [visible]) - - useEffect(() => { - setLoading(loading_) - }, [loading_]) - - const [loading, setLoading] = useState(false) - - const onConfirm: MouseEventHandler = (e) => { - e.preventDefault() - e.stopPropagation() - setLoading(true) - onSelectConfirm() + visible: boolean + title: string | React.ReactNode + size?: React.ComponentProps['size'] + confirmLabel?: string + confirmLabelLoading?: string + cancelLabel?: string + onConfirm: () => void + onCancel: () => void + disabled?: boolean + variant?: React.ComponentProps['variant'] + alert?: { + base?: React.ComponentProps + title?: string + description?: string | React.ReactNode } - - return ( - - - - - } - > - {children} - - ) } +const ConfirmationModal = forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & ConfirmationModalProps +>( + ( + { + title, + size = 'small', + visible, + onCancel, + onConfirm, + loading: loading_ = false, + cancelLabel = 'Cancel', + confirmLabel = 'Submit', + confirmLabelLoading, + alert, + children, + variant = 'default', + disabled, + ...props + }, + ref + ) => { + useEffect(() => { + if (visible) { + setLoading(false) + } + }, [visible]) + + useEffect(() => { + setLoading(loading_) + }, [loading_]) + + const [loading, setLoading] = useState(false) + + const onSubmit: MouseEventHandler = (e) => { + e.preventDefault() + e.stopPropagation() + setLoading(true) + onConfirm() + } + + return ( + { + if (visible) { + onCancel() + } + }} + > + + + {title} + + {alert && ( + + )} + {children && ( + <> + {children} + + + )} +
    + + + +
    +
    +
    + ) + } +) + +ConfirmationModal.displayName = 'ConfirmationModal' + export default ConfirmationModal diff --git a/packages/ui-patterns/Dialogs/TextConfirmModal.tsx b/packages/ui-patterns/Dialogs/TextConfirmModal.tsx index a2f3cfb7360..d3eb1129454 100644 --- a/packages/ui-patterns/Dialogs/TextConfirmModal.tsx +++ b/packages/ui-patterns/Dialogs/TextConfirmModal.tsx @@ -5,15 +5,13 @@ import { ReactNode, forwardRef } from 'react' import { useForm } from 'react-hook-form' import { Admonition, - AlertDescription_Shadcn_, - AlertTitle_Shadcn_, Alert_Shadcn_, Button, - DialogContent, - DialogSectionSeparator, - DialogSection, - DialogTitle, Dialog, + DialogContent, + DialogSection, + DialogSectionSeparator, + DialogTitle, FormControl_Shadcn_, FormDescription_Shadcn_, FormField_Shadcn_, @@ -21,15 +19,10 @@ import { FormLabel_Shadcn_, FormMessage_Shadcn_, Form_Shadcn_, - IconAlertCircle, Input_Shadcn_, cn, } from 'ui' -import { - DIALOG_PADDING_X_SMALL, - DIALOG_PADDING_Y_SMALL, - DialogHeader, -} from 'ui/src/components/shadcn/ui/dialog' +import { DialogHeader } from 'ui/src/components/shadcn/ui/dialog' import { z } from 'zod' export interface TextConfirmModalProps { diff --git a/packages/ui/src/components/Admonition/index.tsx b/packages/ui/src/components/Admonition/index.tsx index 9b9e9d9b311..e551f721ff0 100644 --- a/packages/ui/src/components/Admonition/index.tsx +++ b/packages/ui/src/components/Admonition/index.tsx @@ -1,5 +1,5 @@ import { cva } from 'class-variance-authority' -import { forwardRef } from 'react' +import React, { forwardRef } from 'react' import { cn } from '../../lib/utils/cn' import { Alert, AlertDescription, AlertTitle } from './../shadcn/ui/alert' @@ -15,7 +15,7 @@ export interface AdmonitionProps { | 'warning' label?: string title?: string - description?: string + description?: string | React.ReactNode } const admonitionToAlertMapping: Record<