Skip to content

Commit

Permalink
feat(app-trash-bin): add trash bin to app-headless-cms (#4059)
Browse files Browse the repository at this point in the history
  • Loading branch information
leopuleo committed Apr 10, 2024
1 parent 7f3380f commit 517c703
Show file tree
Hide file tree
Showing 219 changed files with 4,292 additions and 66 deletions.
4 changes: 3 additions & 1 deletion packages/app-aco/src/config/AcoConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { FieldRendererConfig as AdvancedSearchFieldRendererConfig } from "./adva
export { ActionConfig as RecordActionConfig } from "./record/Action";
export { ActionConfig as FolderActionConfig } from "./folder/Action";
export { ColumnConfig as TableColumnConfig } from "./table/Column";
export { SortingConfig as TableSortingConfig } from "./table/Sorting";

const base = createConfigurableComponent<AcoConfig>("AcoConfig");

Expand Down Expand Up @@ -46,7 +47,8 @@ export function useAcoConfig() {
},
table: {
...table,
columns: [...(table.columns || [])]
columns: [...(table.columns || [])],
sorting: [...(table.sorting || [])]
}
}),
[config]
Expand Down
27 changes: 27 additions & 0 deletions packages/app-aco/src/config/table/Sorting.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import { Property, useIdGenerator } from "@webiny/react-properties";

export interface SortingConfig {
field: string;
order: "asc" | "desc";
}

export interface SortingProps {
name: string;
field: string;
order?: "asc" | "desc";
}

export const Sorting = ({ name, field, order = "desc" }: SortingProps) => {
const getId = useIdGenerator("tableSorting");

return (
<Property id="table" name={"table"}>
<Property id={getId(name)} name={"sorting"} array={true}>
<Property id={getId(name, "name")} name={"name"} value={name} />
<Property id={getId(name, "field")} name={"field"} value={field} />
<Property id={getId(name, "order")} name={"order"} value={order} />
</Property>
</Property>
);
};
6 changes: 4 additions & 2 deletions packages/app-aco/src/config/table/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Column, ColumnConfig } from "./Column";

import { Sorting, SortingConfig } from "./Sorting";
export interface TableConfig {
columns: ColumnConfig[];
sorting: SortingConfig[];
}

export const Table = {
Column
Column,
Sorting
};
2 changes: 1 addition & 1 deletion packages/app-admin/src/components/BulkActions/Worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface CallbackParams<T> {
export interface Result {
title: string;
status: "success" | "failure";
message?: string;
message?: string | React.ReactElement;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ export interface ShowResultsDialogParams {
results: Result[];
title?: string;
message?: string;
onCancel?: () => Promise<void>;
}

export interface UseDialogWithReportResponse {
showConfirmationDialog: (params: ShowConfirmationDialogParams) => void;
showResultsDialog: (results: ShowResultsDialogParams) => void;
hideResultsDialog: () => void;
}

export const useDialogWithReport = (): UseDialogWithReportResponse => {
Expand Down Expand Up @@ -80,8 +82,15 @@ export const useDialogWithReport = (): UseDialogWithReportResponse => {
}, 10);
};

const hideResultsDialog = () => {
ui.setState(ui => {
return { ...ui, dialog: null };
});
};

return {
showConfirmationDialog,
showResultsDialog
showResultsDialog,
hideResultsDialog
};
};
6 changes: 3 additions & 3 deletions packages/app-admin/src/components/SplitView/SplitView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,23 @@ const grid = css({
const RightPanelWrapper = styled("div")({
backgroundColor: "var(--mdc-theme-background)",
overflow: "auto",
height: "calc(100vh - 70px)"
height: "calc(100vh - 64px)"
});

export const leftPanel = css({
backgroundColor: "var(--mdc-theme-surface)",
">.webiny-data-list": {
display: "flex",
flexDirection: "column",
height: "calc(100vh - 70px)",
height: "calc(100vh - 64px)",
".mdc-list": {
overflow: "auto"
}
},
">.mdc-list": {
display: "flex",
flexDirection: "column",
maxHeight: "calc(100vh - 70px)",
maxHeight: "calc(100vh - 64px)",
overflow: "auto"
}
});
Expand Down
62 changes: 54 additions & 8 deletions packages/app-headless-cms-common/src/entries.graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ const CONTENT_ENTRY_SYSTEM_FIELDS = /* GraphQL */ `
entryId
createdOn
savedOn
modifiedOn
modifiedOn,
deletedOn
firstPublishedOn
lastPublishedOn
createdBy {
Expand All @@ -45,6 +46,11 @@ const CONTENT_ENTRY_SYSTEM_FIELDS = /* GraphQL */ `
type
displayName
}
deletedBy {
id
type
displayName
}
firstPublishedBy {
id
type
Expand All @@ -58,6 +64,7 @@ const CONTENT_ENTRY_SYSTEM_FIELDS = /* GraphQL */ `
revisionCreatedOn
revisionSavedOn
revisionModifiedOn
revisionDeletedOn
revisionFirstPublishedOn
revisionLastPublishedOn
revisionCreatedBy {
Expand All @@ -75,6 +82,11 @@ const CONTENT_ENTRY_SYSTEM_FIELDS = /* GraphQL */ `
type
displayName
}
revisionDeletedBy {
id
type
displayName
}
revisionFirstPublishedBy {
id
type
Expand Down Expand Up @@ -213,14 +225,18 @@ export interface CmsEntriesListQueryVariables {
after?: string;
}

export const createListQuery = (model: CmsEditorContentModel, fields?: CmsModelField[]) => {
export const createListQuery = (
model: CmsEditorContentModel,
fields?: CmsModelField[],
deleted?: boolean
) => {
const queryName = deleted ? `Deleted${model.pluralApiName}` : model.pluralApiName;

return gql`
query CmsEntriesList${model.pluralApiName}($where: ${
model.singularApiName
}ListWhereInput, $sort: [${
query CmsEntriesList${queryName}($where: ${model.singularApiName}ListWhereInput, $sort: [${
model.singularApiName
}ListSorter], $limit: Int, $after: String, $search: String) {
content: list${model.pluralApiName}(
content: list${queryName}(
where: $where
sort: $sort
limit: $limit
Expand Down Expand Up @@ -256,19 +272,49 @@ export interface CmsEntryDeleteMutationResponse {

export interface CmsEntryDeleteMutationVariables {
revision: string;
permanently?: boolean;
}

export const createDeleteMutation = (model: CmsEditorContentModel) => {
return gql`
mutation CmsEntriesDelete${model.singularApiName}($revision: ID!) {
content: delete${model.singularApiName}(revision: $revision) {
mutation CmsEntriesDelete${model.singularApiName}($revision: ID!, $permanently: Boolean) {
content: delete${model.singularApiName}(revision: $revision, options: {permanently: $permanently}) {
data
error ${ERROR_FIELD}
}
}
`;
};

/**
* ############################################
* Restore Mutation
*/
export interface CmsEntryRestoreMutationResponse {
content: {
data: CmsContentEntry | null;
error: CmsErrorResponse | null;
};
}

export interface CmsEntryRestoreMutationVariables {
revision: string;
}

export const createRestoreMutation = (model: CmsEditorContentModel) => {
return gql`
mutation CmsEntriesRestore${model.singularApiName}($revision: ID!) {
content: restore${model.singularApiName}(revision: $revision) {
data {
${CONTENT_ENTRY_SYSTEM_FIELDS}
${createFieldsList({ model, fields: model.fields })}
}
error ${ERROR_FIELD}
}
}
`;
};

/**
* ############################################
* Create Mutation
Expand Down
8 changes: 8 additions & 0 deletions packages/app-headless-cms-common/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,8 @@ export interface CmsContentEntry {
savedBy: CmsIdentity;
modifiedOn: string | null;
modifiedBy: CmsIdentity | null;
deletedOn: string | null;
deletedBy: CmsIdentity | null;
firstPublishedOn: string | null;
firstPublishedBy: CmsIdentity | null;
lastPublishedOn: string | null;
Expand All @@ -361,6 +363,8 @@ export interface CmsContentEntry {
revisionSavedBy: CmsIdentity;
revisionModifiedOn: string | null;
revisionModifiedBy: CmsIdentity | null;
revisionDeletedOn: string | null;
revisionDeletedBy: CmsIdentity | null;
revisionFirstPublishedOn: string | null;
revisionFirstPublishedBy: CmsIdentity | null;
revisionLastPublishedOn: string | null;
Expand All @@ -381,17 +385,21 @@ export interface CmsContentEntryRevision {
id: string;
modelId: string;
savedOn: string;
deletedOn: string | null;
firstPublishedOn: string | null;
lastPublishedOn: string | null;
createdBy: CmsIdentity;
deletedBy: CmsIdentity | null;
revisionCreatedOn: string;
revisionSavedOn: string;
revisionModifiedOn: string;
revisionDeletedOn: string | null;
revisionFirstPublishedOn: string;
revisionLastPublishedOn: string;
revisionCreatedBy: CmsIdentity;
revisionSavedBy: CmsIdentity;
revisionModifiedBy: CmsIdentity;
revisionDeletedBy: CmsIdentity | null;
revisionFirstPublishedBy: CmsIdentity;
revisionLastPublishedBy: CmsIdentity;
wbyAco_location: Location;
Expand Down
1 change: 1 addition & 0 deletions packages/app-headless-cms/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@webiny/app-i18n": "0.0.0",
"@webiny/app-plugin-admin-welcome-screen": "0.0.0",
"@webiny/app-security": "0.0.0",
"@webiny/app-trash-bin": "0.0.0",
"@webiny/error": "0.0.0",
"@webiny/feature-flags": "0.0.0",
"@webiny/form": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export const ActionDelete = observer(() => {

const openDeleteEntriesDialog = () =>
showConfirmationDialog({
title: "Delete entries",
message: `You are about to delete ${entriesLabel}. Are you sure you want to continue?`,
title: "Trash entries",
message: `You are about to trash ${entriesLabel}. Are you sure you want to continue?`,
loadingLabel: `Processing ${entriesLabel}`,
execute: async () => {
await worker.processInSeries(async ({ item, report }) => {
Expand All @@ -44,15 +44,15 @@ export const ActionDelete = observer(() => {

if (error) {
throw new Error(
error.message || "Unknown error while deleting the entry"
error.message || "Unknown error while trashing the entry."
);
}

removeRecordFromCache(item.id);

report.success({
title: `${item.meta.title}`,
message: "Entry successfully deleted."
message: "Entry successfully trashed."
});
} catch (e) {
report.error({
Expand All @@ -66,8 +66,8 @@ export const ActionDelete = observer(() => {

showResultsDialog({
results: worker.results,
title: "Delete entries",
message: "Finished deleting entries! See full report below:"
title: "Trash entries",
message: "Finished trashing entries! See full report below:"
});
}
});
Expand All @@ -76,7 +76,7 @@ export const ActionDelete = observer(() => {
<IconButton
icon={<DeleteIcon />}
onAction={openDeleteEntriesDialog}
label={`Delete ${entriesLabel}`}
label={`Trash ${entriesLabel}`}
tooltipPlacement={"bottom"}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const DeleteEntry = () => {
return (
<OptionsMenuItem
icon={<Delete />}
label={"Delete"}
label={"Trash"}
onAction={openDialogDeleteEntry}
data-testid={"aco.actions.entry.delete"}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ApolloClient } from "apollo-client";
import { ITrashBinDeleteItemGateway } from "@webiny/app-trash-bin";
import { CmsModel } from "@webiny/app-headless-cms-common/types";
import {
CmsEntryDeleteMutationResponse,
CmsEntryDeleteMutationVariables,
createDeleteMutation
} from "@webiny/app-headless-cms-common";

export class TrashBinDeleteItemGraphQLGateway implements ITrashBinDeleteItemGateway {
private client: ApolloClient<any>;
private model: CmsModel;

constructor(client: ApolloClient<any>, model: CmsModel) {
this.client = client;
this.model = model;
}

async execute(id: string) {
const { data: response } = await this.client.mutate<
CmsEntryDeleteMutationResponse,
CmsEntryDeleteMutationVariables
>({
mutation: createDeleteMutation(this.model),
variables: {
revision: id,
permanently: true
}
});

if (!response) {
throw new Error("Network error while deleting entry.");
}

const { data, error } = response.content;

if (!data) {
throw new Error(error?.message || "Could not delete the entry.");
}

return true;
}
}
Loading

0 comments on commit 517c703

Please sign in to comment.