Skip to content

Commit

Permalink
feat: add delete namespaces and keys functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
d-rita committed Dec 13, 2024
1 parent 09aa5fa commit 2e2c98f
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 41 deletions.
102 changes: 98 additions & 4 deletions src/components/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useDataEngine } from '@dhis2/app-runtime'
import {
DataTable,
DataTableCell,
Expand All @@ -6,8 +7,9 @@ import {
TableBody,
TableHead,
} from '@dhis2/ui'
import React from 'react'
import React, { useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import useCustomAlert from '../hooks/useCustomAlert'
import i18n from '../locales'
import TableActions from './actions/TableActions'

Expand All @@ -16,11 +18,86 @@ type TableProps = {
results: string[]
}
label: string
refetchList: () => void
}

const ItemsTable = ({ data, label }: TableProps) => {
const { namespace: currentNamespace } = useParams()
const ItemsTable = ({ data, label, refetchList }: TableProps) => {
const navigate = useNavigate()
const engine = useDataEngine()
const { store, namespace: currentNamespace } = useParams()
const [openDeleteModal, setOpenDeleteModal] = useState(false)

const { showError, showSuccess } = useCustomAlert()

const isKeyPage = Boolean(store && currentNamespace)
const isNamespacePage = Boolean(store && !currentNamespace)

const onEditButtonClick = ({ selectedItem }) => {
if (isKeyPage) {
navigate(`${selectedItem}`)
} else if (isNamespacePage) {
navigate(`edit/${selectedItem}`)
}
}

const onComplete = () => {
const message = i18n.t('Key deleted successfully')
showSuccess(message)
setOpenDeleteModal(false)
}

const onError = () => {
const message = i18n.t('There was an error deleting the key')
showError(message)
}

const handleDelete = async ({ selectedItem }) => {
let resource = `${store}`

if (isNamespacePage) {
await engine.mutate(
{
type: 'delete' as const,
resource: resource,
id: selectedItem,
},
{
onComplete: onComplete,
onError: onError,
}
)
refetchList()
} else if (isKeyPage) {
if (data?.results?.length > 1) {
resource = `${resource}/${currentNamespace}`
await engine.mutate(
{
type: 'delete' as const,
resource: resource,
id: selectedItem,
},
{
onComplete: onComplete,
onError: onError,
}
)
refetchList()
} else {
await engine.mutate(
{
type: 'delete' as const,
resource: resource,
id: currentNamespace,
},
{
onComplete: onComplete,
onError: onError,
}
)
navigate(`/${store}`)
}
}
}

return (
<div>
Expand Down Expand Up @@ -56,7 +133,24 @@ const ItemsTable = ({ data, label }: TableProps) => {
{item}
</DataTableCell>
<DataTableCell bordered width="12%">
<TableActions item={item} />
<TableActions
selectedItem={item}
rowsLength={
data.results.length
}
handleDeleteAction={
handleDelete
}
handleEditAction={
onEditButtonClick
}
openDeleteModal={
openDeleteModal
}
setOpenDeleteModal={
setOpenDeleteModal
}
/>
</DataTableCell>
</DataTableRow>
)
Expand Down
2 changes: 1 addition & 1 deletion src/components/actions/Buttons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function ContextButton() {
<Button
aria-label={i18n.t('More')}
icon={<IconMore16 />}
name="create"
name="more"
onClick={() => console.log('more')}
title={i18n.t('Delete')}
/>
Expand Down
9 changes: 9 additions & 0 deletions src/components/actions/DeleteModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import {
Modal,
ModalContent,
ModalActions,
ModalTitle,
Button,
ButtonStrip,
} from '@dhis2/ui'
import React from 'react'
import { useParams } from 'react-router-dom'
import i18n from '../../locales'

type DeleteModalProps = {
Expand All @@ -15,8 +17,15 @@ type DeleteModalProps = {
}

const DeleteModal = ({ children, deleteFn, closeModal }: DeleteModalProps) => {
const { store, namespace: currentNamespace } = useParams()
const isKeyPage = Boolean(store && currentNamespace)
const isNamespacePage = Boolean(store && !currentNamespace)
return (
<Modal position="middle">
<ModalTitle>
{isKeyPage && i18n.t('Delete Key')}
{isNamespacePage && i18n.t('Delete Namespace')}
</ModalTitle>
<ModalContent>{children}</ModalContent>
<ModalActions>
<ButtonStrip end>
Expand Down
81 changes: 61 additions & 20 deletions src/components/actions/TableActions.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,85 @@
import React, { useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import React from 'react'
import { useParams } from 'react-router-dom'
import i18n from '../../locales'
import classes from '../../Page.module.css'
import { ContextButton, EditButton } from './Buttons'
import DeleteButton from './DeleteButton'
import DeleteModal from './DeleteModal'

type TableActionProps = {
item: string
selectedItem: string
rowsLength: number
handleEditAction: (string) => void
handleDeleteAction: (string) => void
openDeleteModal: boolean
setOpenDeleteModal: React.Dispatch<React.SetStateAction<boolean>>
}

const TableActions = ({ item }: TableActionProps) => {
const navigate = useNavigate()
const { namespace } = useParams()
const TableActions = ({
selectedItem,
rowsLength,
handleDeleteAction,
handleEditAction,
openDeleteModal,
setOpenDeleteModal,
}: TableActionProps) => {
const { store, namespace: currentNamespace } = useParams()

const [openModal, setOpenModal] = useState(false)
const isKeyPage = Boolean(store && currentNamespace)
const isNamespacePage = Boolean(store && !currentNamespace)

const renderModalContent = () => {
return (
<>
{isNamespacePage && (
<>
<p>
{i18n.t(
`Are you sure you want to delete '${selectedItem}'?`
)}
</p>
<p>
{i18n.t(
`This will delete all the keys in this namespace`
)}
</p>
</>
)}
{isKeyPage && (
<>
{i18n.t(
`Are you sure you want to delete '${selectedItem}' in ${currentNamespace}?`
)}
{rowsLength < 2 && (
<p>
{i18n.t(
`This will also delete the namespace '${currentNamespace}'`
)}
</p>
)}
</>
)}
</>
)
}

return (
<>
<div className={classes.actionButtons}>
<EditButton
handleClick={() => {
if (namespace) {
navigate(`${item}`)
} else {
navigate(`edit/${item}`)
}
}}
handleClick={() => handleEditAction({ selectedItem })}
/>
<DeleteButton openModal={() => setOpenModal(true)} />
<DeleteButton openModal={() => setOpenDeleteModal(true)} />
<ContextButton />
</div>
{openModal && (
{openDeleteModal && (
<DeleteModal
closeModal={() => setOpenModal(false)}
closeModal={() => setOpenDeleteModal(false)}
deleteFn={() => {
console.log('immersion')
setOpenModal(false)
handleDeleteAction({ selectedItem })
}}
>
<p>Delete modal fields</p>
{renderModalContent()}
</DeleteModal>
)}
</>
Expand Down
8 changes: 3 additions & 5 deletions src/components/sections/KeysSections.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useDataEngine, useDataQuery } from '@dhis2/app-runtime'
import React, { useEffect, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useParams } from 'react-router-dom'
import MainSection from './MainSection'

interface QueryResults {
Expand All @@ -27,7 +27,6 @@ type FieldValue = {

export const DataStoreKeys = () => {
const engine = useDataEngine()
const navigate = useNavigate()
const { namespace: currentNamespace } = useParams()
const [values, setValues] = useState<FieldValue>({})

Expand All @@ -48,7 +47,6 @@ export const DataStoreKeys = () => {
})
refetch({ id: currentNamespace })
setValues({})
navigate(`${values?.key}`)
}

useEffect(() => {
Expand All @@ -64,13 +62,13 @@ export const DataStoreKeys = () => {
sectionType="key"
values={values}
setValues={setValues}
handleRefetch={() => refetch({ id: currentNamespace })}
/>
)
}

export const UserDataStoreKeys = () => {
const engine = useDataEngine()
const navigate = useNavigate()
const [values, setValues] = useState<FieldValue>({})
const { namespace: currentNamespace } = useParams()

Expand All @@ -91,7 +89,6 @@ export const UserDataStoreKeys = () => {
})
refetch({ id: currentNamespace })
setValues({})
navigate(`${values?.key}`)
}

useEffect(() => {
Expand All @@ -107,6 +104,7 @@ export const UserDataStoreKeys = () => {
sectionType="key"
values={values}
setValues={setValues}
handleRefetch={() => refetch({ id: currentNamespace })}
/>
)
}
31 changes: 22 additions & 9 deletions src/components/sections/MainSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type MainSectionProps = {
handleCreate?: () => void
values: FieldValues
setValues: React.Dispatch<React.SetStateAction<FieldValues>>
handleRefetch: () => void
}

const MainSection = ({
Expand All @@ -27,14 +28,8 @@ const MainSection = ({
handleCreate,
values,
setValues,
handleRefetch,
}: MainSectionProps) => {
const placeholder =
type === 'namespace'
? i18n.t('Search namespaces')
: i18n.t('Search keys in this namespace')
const tableLabel =
type === 'namespace' ? i18n.t('Namespace') : i18n.t('Key Name')

if (error) {
return (
<div
Expand All @@ -59,15 +54,33 @@ const MainSection = ({
return (
<>
<div className={classes.midSection}>
<SearchField placeholder={placeholder} />
<SearchField
placeholder={
type === 'namespace'
? i18n.t('Search namespaces')
: i18n.t('Search keys in this namespace')
}
/>
<CreateAction
values={values}
setValues={setValues}
type={type}
handleCreate={handleCreate}
/>
</div>
<div>{data && <ItemsTable data={data} label={tableLabel} />}</div>
<div>
{data && (
<ItemsTable
data={data}
label={
type === 'namespace'
? i18n.t('Namespace')
: i18n.t('Key Name')
}
refetchList={handleRefetch}
/>
)}
</div>
</>
)
}
Expand Down
Loading

0 comments on commit 2e2c98f

Please sign in to comment.