Skip to content

Commit

Permalink
add basic warning entity
Browse files Browse the repository at this point in the history
  • Loading branch information
raphaelblum committed Sep 4, 2024
1 parent 2ab7b68 commit 17a88d6
Show file tree
Hide file tree
Showing 19 changed files with 886 additions and 0 deletions.
5 changes: 5 additions & 0 deletions demo/admin/crud-generator-config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CrudGeneratorConfig } from "@comet/cms-admin";

export default [
{
target: "src/products/generated",
Expand All @@ -8,4 +9,8 @@ export default [
target: "src/news/generated",
entityName: "News",
},
{
target: "src/warnings/generated",
entityName: "Warning",
},
] satisfies CrudGeneratorConfig[];
10 changes: 10 additions & 0 deletions demo/admin/src/common/MasterMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { ProductsPage } from "@src/products/generated/ProductsPage";
import { ManufacturersPage as ManufacturersHandmadePage } from "@src/products/ManufacturersPage";
import ProductsHandmadePage from "@src/products/ProductsPage";
import ProductTagsPage from "@src/products/tags/ProductTagsPage";
import { WarningsPage } from "@src/warnings/generated/WarningsPage";
import { FormattedMessage } from "react-intl";
import { Redirect, RouteComponentProps } from "react-router-dom";

Expand Down Expand Up @@ -175,6 +176,15 @@ export const masterMenuData: MasterMenuData = [
},
requiredPermission: "pageTree",
},
{
type: "route",
primary: <FormattedMessage id="menu.warnings" defaultMessage="Warnings" />,
route: {
path: "/system/warnings",
component: WarningsPage,
},
requiredPermission: "pageTree",
},
],
requiredPermission: "pageTree",
},
Expand Down
53 changes: 53 additions & 0 deletions demo/admin/src/warnings/generated/WarningForm.gql.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// This file has been generated by comet admin-generator.
// You may choose to use this file as scaffold by moving this file out of generated folder and removing this comment.

import { gql } from "@apollo/client";

export const warningFormFragment = gql`
fragment WarningForm on Warning {
type
level
state
}
`;

export const warningFormQuery = gql`
query WarningForm($id: ID!) {
warning(id: $id) {
id
updatedAt
...WarningForm
}
}
${warningFormFragment}
`;

export const warningFormCheckForChangesQuery = gql`
query WarningFormCheckForChanges($id: ID!) {
warning(id: $id) {
updatedAt
}
}
`;

export const createWarningMutation = gql`
mutation CreateWarning($input: WarningInput!) {
createWarning(input: $input) {
id
updatedAt
...WarningForm
}
}
${warningFormFragment}
`;

export const updateWarningMutation = gql`
mutation UpdateWarning($id: ID!, $input: WarningUpdateInput!) {
updateWarning(id: $id, input: $input) {
id
updatedAt
...WarningForm
}
}
${warningFormFragment}
`;
182 changes: 182 additions & 0 deletions demo/admin/src/warnings/generated/WarningForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
// This file has been generated by comet admin-generator.
// You may choose to use this file as scaffold by moving this file out of generated folder and removing this comment.

import { useApolloClient, useQuery } from "@apollo/client";
import {
Field,
filterByFragment,
FinalForm,
FinalFormSaveButton,
FinalFormSelect,
FinalFormSubmitEvent,
Loading,
MainContent,
TextField,
Toolbar,
ToolbarActions,
ToolbarFillSpace,
ToolbarItem,
ToolbarTitleItem,
useFormApiRef,
useStackApi,
useStackSwitchApi,
} from "@comet/admin";
import { ArrowLeft } from "@comet/admin-icons";
import { ContentScopeIndicator, queryUpdatedAt, resolveHasSaveConflict, useFormSaveConflict } from "@comet/cms-admin";
import { IconButton, MenuItem } from "@mui/material";
import { FormApi } from "final-form";
import React from "react";
import { FormattedMessage } from "react-intl";

import { createWarningMutation, updateWarningMutation, warningFormFragment, warningFormQuery } from "./WarningForm.gql";
import {
GQLCreateWarningMutation,
GQLCreateWarningMutationVariables,
GQLUpdateWarningMutation,
GQLUpdateWarningMutationVariables,
GQLWarningFormFragment,
GQLWarningFormQuery,
GQLWarningFormQueryVariables,
} from "./WarningForm.gql.generated";

type FormValues = GQLWarningFormFragment;

interface FormProps {
id?: string;
}

export function WarningForm({ id }: FormProps): React.ReactElement {
const stackApi = useStackApi();
const client = useApolloClient();
const mode = id ? "edit" : "add";
const formApiRef = useFormApiRef<FormValues>();
const stackSwitchApi = useStackSwitchApi();

const { data, error, loading, refetch } = useQuery<GQLWarningFormQuery, GQLWarningFormQueryVariables>(
warningFormQuery,
id ? { variables: { id } } : { skip: true },
);

const initialValues = React.useMemo<Partial<FormValues>>(
() =>
data?.warning
? {
...filterByFragment<GQLWarningFormFragment>(warningFormFragment, data.warning),
}
: {},
[data],
);

const saveConflict = useFormSaveConflict({
checkConflict: async () => {
const updatedAt = await queryUpdatedAt(client, "warning", id);
return resolveHasSaveConflict(data?.warning.updatedAt, updatedAt);
},
formApiRef,
loadLatestVersion: async () => {
await refetch();
},
});

const handleSubmit = async (state: FormValues, form: FormApi<FormValues>, event: FinalFormSubmitEvent) => {
if (await saveConflict.checkForConflicts()) {
throw new Error("Conflicts detected");
}

const output = {
...state,
};

if (mode === "edit") {
if (!id) {
throw new Error("Missing id in edit mode");
}
await client.mutate<GQLUpdateWarningMutation, GQLUpdateWarningMutationVariables>({
mutation: updateWarningMutation,
variables: { id, input: output },
});
} else {
const { data: mutationResponse } = await client.mutate<GQLCreateWarningMutation, GQLCreateWarningMutationVariables>({
mutation: createWarningMutation,
variables: { input: output },
});
if (!event.navigatingBack) {
const id = mutationResponse?.createWarning.id;
if (id) {
setTimeout(() => {
stackSwitchApi.activatePage("edit", id);
});
}
}
}
};

if (error) throw error;

if (loading) {
return <Loading behavior="fillPageHeight" />;
}

return (
<FinalForm<FormValues> apiRef={formApiRef} onSubmit={handleSubmit} mode={mode} initialValues={initialValues}>
{({ values }) => (
<>
{saveConflict.dialogs}
<Toolbar scopeIndicator={<ContentScopeIndicator global />}>
<ToolbarItem>
<IconButton onClick={stackApi?.goBack}>
<ArrowLeft />
</IconButton>
</ToolbarItem>
<ToolbarTitleItem>
<FormattedMessage id="warnings.Warning" defaultMessage="Warning" />
</ToolbarTitleItem>
<ToolbarFillSpace />
<ToolbarActions>
<FinalFormSaveButton hasConflict={saveConflict.hasConflict} />
</ToolbarActions>
</Toolbar>
<MainContent>
<TextField
required
variant="horizontal"
fullWidth
name="type"
label={<FormattedMessage id="warning.type" defaultMessage="Type" />}
/>
<Field variant="horizontal" fullWidth name="level" label={<FormattedMessage id="warning.level" defaultMessage="Level" />}>
{(props) => (
<FinalFormSelect {...props}>
<MenuItem value="critical">
<FormattedMessage id="warning.level.critical" defaultMessage="Critical" />
</MenuItem>
<MenuItem value="high">
<FormattedMessage id="warning.level.high" defaultMessage="High" />
</MenuItem>
<MenuItem value="low">
<FormattedMessage id="warning.level.low" defaultMessage="Low" />
</MenuItem>
</FinalFormSelect>
)}
</Field>
<Field variant="horizontal" fullWidth name="state" label={<FormattedMessage id="warning.state" defaultMessage="State" />}>
{(props) => (
<FinalFormSelect {...props}>
<MenuItem value="open">
<FormattedMessage id="warning.state.open" defaultMessage="Open" />
</MenuItem>
<MenuItem value="resolved">
<FormattedMessage id="warning.state.resolved" defaultMessage="Resolved" />
</MenuItem>
<MenuItem value="ignored">
<FormattedMessage id="warning.state.ignored" defaultMessage="Ignored" />
</MenuItem>
</FinalFormSelect>
)}
</Field>
</MainContent>
</>
)}
</FinalForm>
);
}
Loading

0 comments on commit 17a88d6

Please sign in to comment.