Bulk deletion of pages
This commit is contained in:
parent
24e2527c1b
commit
08e1467bb1
@ -2,6 +2,7 @@ export type Nullable<T> = { [P in keyof T]: T[P] | null }
|
||||
|
||||
export type Subset<T> = { [K in keyof T]?: Subset<T[K]> }
|
||||
export type Dictionary<T> = { [key: string]: T };
|
||||
export type OneOrMany<T> = T | T[];
|
||||
|
||||
export type Index = string | symbol | number;
|
||||
|
||||
@ -27,7 +28,7 @@ export function throttle<TArgs extends any[]>(decorated: (...args: TArgs) => voi
|
||||
}
|
||||
}
|
||||
|
||||
export function encapsulate<T>(value: T|T[]): T[] {
|
||||
export function encapsulate<T>(value: OneOrMany<T>): T[] {
|
||||
if (value instanceof Array) {
|
||||
return value;
|
||||
}
|
||||
@ -35,7 +36,7 @@ export function encapsulate<T>(value: T|T[]): T[] {
|
||||
return [ value ];
|
||||
}
|
||||
|
||||
export function one<T>(value: T|T[]): T {
|
||||
export function one<T>(value: OneOrMany<T>): T {
|
||||
if (value instanceof Array) {
|
||||
return value[0];
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import pageDtoTransformer, { PageDTO } from "@/api/dto/page";
|
||||
import { axios } from "@/api";
|
||||
import { STATIC_PAGE_ENDPOINT } from "@/api/page";
|
||||
import { prepare } from "@/routing";
|
||||
import { encapsulate, OneOrMany } from "@/helpers";
|
||||
|
||||
const STATIC_PAGE_INDEX_ENDPOINT = "/staticPage";
|
||||
|
||||
@ -13,8 +14,10 @@ export async function all(): Promise<Page[]> {
|
||||
return response.data.map(dto => pageDtoTransformer.transform(dto));
|
||||
}
|
||||
|
||||
export async function remove(page: Pick<Page, "slug">): Promise<void> {
|
||||
await axios.delete(prepare(STATIC_PAGE_ENDPOINT, { slug: page.slug }));
|
||||
export async function remove(page: OneOrMany<Pick<Page, "slug">>): Promise<void> {
|
||||
const pages = encapsulate(page);
|
||||
|
||||
await Promise.all(pages.map(page => axios.delete(prepare(STATIC_PAGE_ENDPOINT, { slug: page.slug }))));
|
||||
}
|
||||
|
||||
export async function save(page: Page): Promise<Page> {
|
||||
|
@ -9,7 +9,7 @@ import { Async } from "@/components/async";
|
||||
import MaterialTable, { Action, Column } from "material-table";
|
||||
import { default as StaticPage } from "@/data/page";
|
||||
import { Delete, FileFind, Pencil, Refresh } from "mdi-material-ui";
|
||||
import { encapsulate, one } from "@/helpers";
|
||||
import { encapsulate, one, OneOrMany } from "@/helpers";
|
||||
import { Actions } from "@/components";
|
||||
import { useSpacing } from "@/styles";
|
||||
import { useHistory } from "react-router-dom";
|
||||
@ -21,6 +21,7 @@ import { Confirm } from "@/components/confirm";
|
||||
export const StaticPageManagement = () => {
|
||||
const { t } = useTranslation("management");
|
||||
const [ result, setPagesPromise ] = useAsyncState<StaticPage[]>();
|
||||
const [ selected, setSelected ] = useState<StaticPage[]>([]);
|
||||
const spacing = useSpacing(2);
|
||||
|
||||
const updatePageList = () => {
|
||||
@ -67,20 +68,28 @@ export const StaticPageManagement = () => {
|
||||
</>
|
||||
}
|
||||
|
||||
const DeleteStaticPageAction = ({ page }: { page: StaticPage }) => {
|
||||
const DeleteStaticPageAction = ({ page, children }: { page: OneOrMany<StaticPage>, children?: (action: any) => React.ReactNode }) => {
|
||||
const handlePageDeletion = async () => {
|
||||
await api.page.remove(page);
|
||||
updatePageList();
|
||||
}
|
||||
|
||||
const confirmation = <>
|
||||
<Trans i18nKey="page.confirm.delete">
|
||||
Czy na pewno chcesz usunąć stronę <strong>{ page.title.pl }</strong>?
|
||||
</Trans>
|
||||
{ !Array.isArray(page)
|
||||
? <Trans i18nKey="page.confirm.delete">
|
||||
Czy na pewno chcesz usunąć stronę <strong>{ page.title.pl }</strong>?
|
||||
</Trans>
|
||||
: <>
|
||||
{ t("page.confirm.bulk-delete") }
|
||||
<ul>
|
||||
{ page.map(page => <li key={ page.slug }>{ page.title.pl }</li>) }
|
||||
</ul>
|
||||
</>
|
||||
}
|
||||
</>;
|
||||
|
||||
return <Confirm onConfirm={ handlePageDeletion } content={ confirmation }>
|
||||
{ action => <Tooltip title={ t("actions.delete") as string }><IconButton onClick={ action }><Delete /></IconButton></Tooltip> }
|
||||
{ action => children ? children(action) : <Tooltip title={ t("actions.delete") as string }><IconButton onClick={ action }><Delete /></IconButton></Tooltip> }
|
||||
</Confirm>;
|
||||
}
|
||||
|
||||
@ -143,12 +152,19 @@ export const StaticPageManagement = () => {
|
||||
<CreateStaticPageAction />
|
||||
<Button onClick={ updatePageList } startIcon={ <Refresh /> }>{ t("refresh") }</Button>
|
||||
</Actions>
|
||||
{ selected.length > 0 && <Actions>
|
||||
<DeleteStaticPageAction page={ selected }>
|
||||
{ action => <Button startIcon={ <Delete /> } onClick={ action }>{ t("actions.delete") }</Button> }
|
||||
</DeleteStaticPageAction>
|
||||
</Actions> }
|
||||
<Async async={ result } keepValue>{
|
||||
pages => <MaterialTable
|
||||
title={ <div style={{ display: "flex", alignItems: "center" }}>{ t("page.index.title") } { result.isLoading && <CircularProgress size="1.5rem" style={{ marginLeft: "1rem" }}/> }</div> }
|
||||
columns={ columns }
|
||||
data={ pages }
|
||||
detailPanel={ page => <PagePreview page={ page } /> }
|
||||
onSelectionChange={ pages => setSelected(pages) }
|
||||
options={{ selection: true }}
|
||||
/>
|
||||
}</Async>
|
||||
</Container>
|
||||
|
@ -31,3 +31,5 @@ page:
|
||||
title: Utwórz stronę statyczną
|
||||
edit:
|
||||
title: Zmień stronę statyczną
|
||||
confirm:
|
||||
bulk-delete: Czy na pewno chcesz usunąć wszystkie wybrane strony?
|
||||
|
Loading…
Reference in New Issue
Block a user