Skip to content

Commit a021bd9

Browse files
authored
GitHub syncer tweaks (exercism#7903)
* Sort tracks * Tweak delete flow * Delete unused line
1 parent 2e0ea07 commit a021bd9

File tree

5 files changed

+19
-17
lines changed

5 files changed

+19
-17
lines changed

app/controllers/settings/github_syncer_controller.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,5 @@ def callback
7474

7575
def destroy
7676
current_user.github_solution_syncer&.destroy
77-
redirect_to settings_github_syncer_path, notice: "GitHub disconnected"
7877
end
7978
end

app/helpers/react_components/settings/github_syncer_form.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def syncer = current_user.github_solution_syncer
3838

3939
memoize
4040
def tracks
41-
current_user.tracks.select(:slug, :title).map do |track|
41+
current_user.tracks.select(:slug, :title).order(:slug).map do |track|
4242
{
4343
slug: track.slug,
4444
title: track.title,

app/javascript/components/settings/github-syncer/GitHubSyncerForm.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ type GitHubSyncerContextType = Omit<
3535
> & {
3636
isSyncingEnabled: boolean
3737
setIsSyncingEnabled: React.Dispatch<SetStateAction<boolean>>
38+
isUserConnected: boolean
39+
setIsUserConnected: React.Dispatch<SetStateAction<boolean>>
3840
}
3941

4042
export const GitHubSyncerContext = React.createContext<GitHubSyncerContextType>(
@@ -47,6 +49,7 @@ export default function GitHubSyncerForm(
4749
const [isSyncingEnabled, setIsSyncingEnabled] = useState(
4850
data.syncer?.enabled || false
4951
)
52+
const [isUserConnected, setIsUserConnected] = useState(data.isUserConnected)
5053
return (
5154
<GitHubSyncerContext.Provider
5255
value={{
@@ -58,9 +61,11 @@ export default function GitHubSyncerForm(
5861
defaultPathTemplate: data.defaultPathTemplate,
5962
isSyncingEnabled,
6063
setIsSyncingEnabled,
64+
isUserConnected,
65+
setIsUserConnected,
6166
}}
6267
>
63-
{data.isUserConnected ? <ConnectedSection /> : <ConnectToGithubSection />}
68+
{isUserConnected ? <ConnectedSection /> : <ConnectToGithubSection />}
6469
<Toaster position="bottom-right" />
6570
</GitHubSyncerContext.Provider>
6671
)

app/javascript/components/settings/github-syncer/common/ConfirmationModal.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type ConfirmationModalProps = Omit<ModalProps, 'className'> & {
1010
onConfirm: () => void
1111
onDecline?: () => void
1212
confirmButtonClass?: string
13+
isConfirmButtonDisabled?: boolean
1314
}
1415

1516
export const ConfirmationModal = ({
@@ -21,6 +22,7 @@ export const ConfirmationModal = ({
2122
onDecline,
2223
onClose,
2324
confirmButtonClass = 'btn-warning',
25+
isConfirmButtonDisabled = false,
2426
...props
2527
}: ConfirmationModalProps): JSX.Element => {
2628
const handleClose = useCallback(() => {
@@ -49,6 +51,7 @@ export const ConfirmationModal = ({
4951
</button>
5052
<button
5153
type="button"
54+
disabled={isConfirmButtonDisabled}
5255
className="btn-enhanced btn-s"
5356
onClick={handleClose}
5457
>

app/javascript/components/settings/github-syncer/sections/ConnectedSection/DangerZoneSection.tsx

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import React, { useState, useCallback } from 'react'
22
import toast from 'react-hot-toast'
33
import { ConfirmationModal } from '../../common/ConfirmationModal'
4-
import { fetchWithParams } from '../../fetchWithParams'
4+
import { fetchWithParams, handleJsonErrorResponse } from '../../fetchWithParams'
55
import { GitHubSyncerContext } from '../../GitHubSyncerForm'
66
import { GraphicalIcon } from '@/components/common'
77

88
export function DangerZoneSection() {
9-
const { links, isSyncingEnabled, setIsSyncingEnabled } =
9+
const { links, isSyncingEnabled, setIsSyncingEnabled, setIsUserConnected } =
1010
React.useContext(GitHubSyncerContext)
1111

12+
const [isDeleting, setIsDeleting] = useState(false)
13+
1214
const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] =
1315
useState(false)
1416
const handleDeleteConfirmationModalClose = useCallback(() => {
@@ -45,24 +47,15 @@ export function DangerZoneSection() {
4547
}, [links.settings])
4648

4749
const handleDelete = useCallback(() => {
50+
setIsDeleting(true)
4851
fetchWithParams({ url: links.settings, method: 'DELETE' })
4952
.then(async (response) => {
5053
if (response.ok) {
5154
toast.success('GitHub sync deleted successfully')
55+
setIsUserConnected(false)
5256
setDeleteConfirmationModalOpen(false)
5357
} else {
54-
const text = await response.text()
55-
try {
56-
const data = JSON.parse(text)
57-
toast.error(
58-
`Failed to delete GitHub sync: ${
59-
data.error?.message || 'Unknown error'
60-
}`
61-
)
62-
} catch {
63-
console.error('Expected JSON, but received:', text)
64-
toast.error('Failed to delete GitHub sync.')
65-
}
58+
handleJsonErrorResponse(response, 'Failed to delete GitHub sync.')
6659
}
6760
})
6861
.catch((error) => {
@@ -71,6 +64,7 @@ export function DangerZoneSection() {
7164
)
7265
console.error('Error:', error)
7366
})
67+
.finally(() => setIsDeleting(false))
7468
}, [links.settings])
7569

7670
return (
@@ -128,6 +122,7 @@ export function DangerZoneSection() {
128122
description="This action cannot be undone."
129123
confirmLabel="Disconnect Syncer"
130124
confirmButtonClass="btn-alert"
125+
isConfirmButtonDisabled={isDeleting}
131126
declineLabel="Cancel"
132127
onConfirm={handleDelete}
133128
open={isDeleteConfirmationModalOpen}

0 commit comments

Comments
 (0)