Skip to content

Commit

Permalink
Added bulk actions for podcast management (#905)
Browse files Browse the repository at this point in the history
Co-authored-by: Samuel Schwanzer <[email protected]>
  • Loading branch information
2 people authored and Samuel Schwanzer committed Aug 29, 2024
1 parent 3cff57a commit b4a42ee
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 44 deletions.
2 changes: 1 addition & 1 deletion ui/src/components/CustomCheckbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type CustomCheckboxProps = {
className?: string,
id?: string,
name?: string,
onChange?: any,
onChange?: (checked: Checkbox.CheckedState)=>void,
value?: Checkbox.CheckedState
}

Expand Down
110 changes: 67 additions & 43 deletions ui/src/components/SettingsPodcastDelete.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { FC, useEffect } from 'react'
import {FC, Fragment, useEffect, useState} from 'react'
import { useTranslation } from 'react-i18next'
import axios from 'axios'
import { enqueueSnackbar } from 'notistack'
import useCommon, { Podcast} from '../store/CommonSlice'
import { CustomButtonSecondary } from './CustomButtonSecondary'
import useModal from "../store/ModalSlice";
import {CustomCheckbox} from "./CustomCheckbox";

export const SettingsPodcastDelete: FC = () => {
const podcasts = useCommon(state => state.podcasts)
Expand All @@ -13,7 +14,7 @@ export const SettingsPodcastDelete: FC = () => {
const setConfirmModalData = useCommon(state => state.setConfirmModalData)
const setPodcasts = useCommon(state => state.setPodcasts)
const podcastDeleted = useCommon(state => state.podcastDeleted)

const [selectedPodcasts, setSelectedPodcasts] = useState<Podcast[]>([])

useEffect(() => {
if (podcasts.length === 0) {
Expand All @@ -24,54 +25,77 @@ export const SettingsPodcastDelete: FC = () => {
}
}, [])

const deletePodcast = (withFiles: boolean, podcast_id: number, p: Podcast) => {
axios.delete( '/podcast/' + podcast_id, { data: { delete_files: withFiles }})
.then(() => {
enqueueSnackbar(t('podcast-deleted', { name: p.name }), { variant: 'success' })
podcastDeleted(podcast_id)
})
const deletePodcast = (withFiles: boolean) => {
selectedPodcasts.forEach(p=>{
axios.delete( '/podcast/' + p.id, { data: { delete_files: withFiles }})
.then(() => {
enqueueSnackbar(t('podcast-deleted', { name: p.name }), { variant: 'success' })
podcastDeleted(p.id)
})
})

}

return (
<div className="grid grid-cols-1 lg:grid-cols-[1fr_auto_auto] items-center gap-6">
<CustomCheckbox value={selectedPodcasts.length === podcasts.length} onChange={(v)=>{
if (v.valueOf() === true) {
setSelectedPodcasts(podcasts)
} else {
setSelectedPodcasts([])
}
}}/>

<CustomButtonSecondary disabled={selectedPodcasts.length === 0} onClick={() => {
setConfirmModalData({
headerText: t('delete-podcast-with-files'),
onAccept:()=>{
deletePodcast(true)
setModalOpen(false)
},
onReject: ()=>{
setModalOpen(false)
},
acceptText: t('delete-podcast-confirm'),
rejectText: t('cancel'),
bodyText: t('delete-podcast-with-files-body', {name: [selectedPodcasts.map(a=>a.name).join(', ')]})
})
setModalOpen(true)
}}>{t('delete-podcast-with-files')}</CustomButtonSecondary>

<CustomButtonSecondary disabled={selectedPodcasts.length === 0} onClick={() => {
setConfirmModalData({
headerText: t('delete-podcast-without-files'),
onAccept:()=>{
deletePodcast(false)
setModalOpen(false)
},
onReject: ()=>{
setModalOpen(false)
},
acceptText: t('delete-podcast-confirm'),
rejectText: t('cancel'),
bodyText: t('delete-podcast-without-files-body', {name: [selectedPodcasts.map(a=>a.name).join(', ')]})
})
setModalOpen(true)
}}>{t('delete-podcast-without-files')}</CustomButtonSecondary>
<hr className="col-span-1 lg:col-span-3"/>
{podcasts.map((p) => (
<div className="grid grid-cols-1 xs:grid-cols-[auto_1fr] justify-items-start gap-2 lg:contents mb-4" key={p.id}>
<span className="xs:col-span-2 lg:col-span-1 text-[--fg-color]">{p.name}</span>

<CustomButtonSecondary onClick={() => {
setConfirmModalData({
headerText: t('delete-podcast-with-files'),
onAccept:()=>{
deletePodcast(true, p.id, p)
setModalOpen(false)
},
onReject: ()=>{
setModalOpen(false)
},
acceptText: t('delete-podcast-confirm'),
rejectText: t('cancel'),
bodyText: t('delete-podcast-with-files-body', {name: p.name})
})
setModalOpen(true)
}}>{t('delete-podcast-with-files')}</CustomButtonSecondary>
<Fragment key={p.id}>
<CustomCheckbox value={selectedPodcasts.includes(p)} onChange={(v)=>{
let isChecked = v.valueOf() as boolean

<CustomButtonSecondary onClick={() => {
setConfirmModalData({
headerText: t('delete-podcast-without-files'),
onAccept:()=>{
deletePodcast(false, p.id, p)
setModalOpen(false)
},
onReject: ()=>{
setModalOpen(false)
},
acceptText: t('delete-podcast-confirm'),
rejectText: t('cancel'),
bodyText: t('delete-podcast-without-files-body', {name: p.name})
})
setModalOpen(true)
}}>{t('delete-podcast-without-files')}</CustomButtonSecondary>
</div>
if (isChecked) {
if (!selectedPodcasts.includes(p)) {
setSelectedPodcasts([...selectedPodcasts, p])
}
} else {
setSelectedPodcasts(selectedPodcasts.filter(pod=>pod !== p))
}
}}/>
<span className="xs:col-span-2 lg:col-span-2 text-[--fg-color]">{p.name}</span>
</Fragment>
))}
</div>
)
Expand Down

0 comments on commit b4a42ee

Please sign in to comment.