diff --git a/demo/admin/src/common/MasterMenu.tsx b/demo/admin/src/common/MasterMenu.tsx
index 9905291e59..562c8f6691 100644
--- a/demo/admin/src/common/MasterMenu.tsx
+++ b/demo/admin/src/common/MasterMenu.tsx
@@ -32,7 +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 { WarningsPage } from "@src/warnings/WarningsPage";
import { FormattedMessage } from "react-intl";
import { Redirect, RouteComponentProps } from "react-router-dom";
diff --git a/demo/admin/src/warnings/WarningsGrid.tsx b/demo/admin/src/warnings/WarningsGrid.tsx
new file mode 100644
index 0000000000..1bb90e502c
--- /dev/null
+++ b/demo/admin/src/warnings/WarningsGrid.tsx
@@ -0,0 +1,152 @@
+import { gql, useQuery } from "@apollo/client";
+import {
+ DataGridToolbar,
+ GridColDef,
+ GridFilterButton,
+ MainContent,
+ muiGridFilterToGql,
+ muiGridSortToGql,
+ ToolbarItem,
+ useBufferedRowCount,
+ useDataGridRemote,
+ usePersistentColumnState,
+} from "@comet/admin";
+import { WarningSolid } from "@comet/admin-icons";
+import { Chip } from "@mui/material";
+import { DataGrid, GridToolbarQuickFilter } from "@mui/x-data-grid";
+import { GQLWarningLevel } from "@src/graphql.generated";
+import * as React from "react";
+import { FormattedDate, FormattedTime, useIntl } from "react-intl";
+
+import { GQLWarningsGridQuery, GQLWarningsGridQueryVariables, GQLWarningsListFragment } from "./WarningsGrid.generated";
+
+const warningsFragment = gql`
+ fragment WarningsList on Warning {
+ id
+ createdAt
+ updatedAt
+ type
+ level
+ state
+ }
+`;
+
+const warningsQuery = gql`
+ query WarningsGrid($offset: Int, $limit: Int, $sort: [WarningSort!], $search: String, $filter: WarningFilter) {
+ warnings(offset: $offset, limit: $limit, sort: $sort, search: $search, filter: $filter) {
+ nodes {
+ ...WarningsList
+ }
+ totalCount
+ }
+ }
+ ${warningsFragment}
+`;
+
+function WarningsGridToolbar() {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
+
+export function WarningsGrid(): React.ReactElement {
+ const intl = useIntl();
+ const dataGridProps = {
+ ...useDataGridRemote({ initialFilter: { items: [{ columnField: "state", operatorValue: "is", value: "open" }] } }),
+ ...usePersistentColumnState("WarningsGrid"),
+ };
+
+ const columns: GridColDef[] = [
+ {
+ field: "createdAt",
+ headerName: intl.formatMessage({ id: "warning.dateTime", defaultMessage: "Date / Time" }),
+ type: "dateTime",
+ renderCell: (params) => (
+ <>
+
+ >
+ ),
+ width: 200,
+ },
+ {
+ field: "level",
+ headerName: intl.formatMessage({ id: "warning.level", defaultMessage: "Level" }),
+ type: "singleSelect",
+ valueOptions: [
+ { value: "critical", label: intl.formatMessage({ id: "warning.level.critical", defaultMessage: "Critical" }) },
+ { value: "high", label: intl.formatMessage({ id: "warning.level.high", defaultMessage: "High" }) },
+ { value: "low", label: intl.formatMessage({ id: "warning.level.low", defaultMessage: "Low" }) },
+ ],
+ width: 150,
+ renderCell: (params) => {
+ const colorMapping: Record = {
+ critical: "error",
+ high: "warning",
+ low: "default",
+ };
+ return (
+ : undefined}
+ color={colorMapping[params.value as GQLWarningLevel]}
+ label={params.value}
+ />
+ );
+ },
+ },
+ {
+ field: "type",
+ headerName: intl.formatMessage({ id: "warning.type", defaultMessage: "Type" }),
+ width: 150,
+ renderCell: (params) => ,
+ },
+ {
+ field: "state",
+ headerName: intl.formatMessage({ id: "warning.state", defaultMessage: "State" }),
+ type: "singleSelect",
+ valueOptions: [
+ { value: "open", label: intl.formatMessage({ id: "warning.state.open", defaultMessage: "Open" }) },
+ { value: "resolved", label: intl.formatMessage({ id: "warning.state.resolved", defaultMessage: "Resolved" }) },
+ { value: "ignored", label: intl.formatMessage({ id: "warning.state.ignored", defaultMessage: "Ignored" }) },
+ ],
+ width: 150,
+ },
+ ];
+
+ const { filter: gqlFilter, search: gqlSearch } = muiGridFilterToGql(columns, dataGridProps.filterModel);
+
+ const { data, loading, error } = useQuery(warningsQuery, {
+ variables: {
+ filter: gqlFilter,
+ search: gqlSearch,
+ offset: dataGridProps.page * dataGridProps.pageSize,
+ limit: dataGridProps.pageSize,
+ sort: muiGridSortToGql(dataGridProps.sortModel),
+ },
+ });
+ const rowCount = useBufferedRowCount(data?.warnings.totalCount);
+ if (error) throw error;
+ const rows = data?.warnings.nodes ?? [];
+
+ return (
+
+
+
+ );
+}
diff --git a/demo/admin/src/warnings/WarningsPage.tsx b/demo/admin/src/warnings/WarningsPage.tsx
new file mode 100644
index 0000000000..f1880abe57
--- /dev/null
+++ b/demo/admin/src/warnings/WarningsPage.tsx
@@ -0,0 +1,14 @@
+import { Stack } from "@comet/admin";
+import * as React from "react";
+import { useIntl } from "react-intl";
+
+import { WarningsGrid } from "./WarningsGrid";
+
+export function WarningsPage(): React.ReactElement {
+ const intl = useIntl();
+ return (
+
+
+
+ );
+}
diff --git a/demo/admin/src/warnings/generated/WarningForm.gql.ts b/demo/admin/src/warnings/generated/WarningForm.gql.ts
deleted file mode 100644
index 4faa2364ef..0000000000
--- a/demo/admin/src/warnings/generated/WarningForm.gql.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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}
-`;
diff --git a/demo/admin/src/warnings/generated/WarningForm.tsx b/demo/admin/src/warnings/generated/WarningForm.tsx
deleted file mode 100644
index 1b031ed650..0000000000
--- a/demo/admin/src/warnings/generated/WarningForm.tsx
+++ /dev/null
@@ -1,182 +0,0 @@
-// 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();
- const stackSwitchApi = useStackSwitchApi();
-
- const { data, error, loading, refetch } = useQuery(
- warningFormQuery,
- id ? { variables: { id } } : { skip: true },
- );
-
- const initialValues = React.useMemo>(
- () =>
- data?.warning
- ? {
- ...filterByFragment(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, 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({
- mutation: updateWarningMutation,
- variables: { id, input: output },
- });
- } else {
- const { data: mutationResponse } = await client.mutate({
- 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 ;
- }
-
- return (
- apiRef={formApiRef} onSubmit={handleSubmit} mode={mode} initialValues={initialValues}>
- {({ values }) => (
- <>
- {saveConflict.dialogs}
- }>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }
- />
- }>
- {(props) => (
-
-
-
-
-
- )}
-
- }>
- {(props) => (
-
-
-
-
-
- )}
-
-
- >
- )}
-
- );
-}
diff --git a/demo/admin/src/warnings/generated/WarningsGrid.tsx b/demo/admin/src/warnings/generated/WarningsGrid.tsx
deleted file mode 100644
index b5f7552fdb..0000000000
--- a/demo/admin/src/warnings/generated/WarningsGrid.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-// 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, useApolloClient, useQuery } from "@apollo/client";
-import {
- CrudContextMenu,
- DataGridToolbar,
- GridColDef,
- GridFilterButton,
- MainContent,
- muiGridFilterToGql,
- muiGridSortToGql,
- StackLink,
- ToolbarActions,
- ToolbarFillSpace,
- ToolbarItem,
- useBufferedRowCount,
- useDataGridRemote,
- usePersistentColumnState,
-} from "@comet/admin";
-import { Add as AddIcon, Edit } from "@comet/admin-icons";
-import { Button, IconButton } from "@mui/material";
-import { DataGridPro, GridToolbarQuickFilter } from "@mui/x-data-grid-pro";
-import * as React from "react";
-import { FormattedMessage, useIntl } from "react-intl";
-
-import {
- GQLCreateWarningMutation,
- GQLCreateWarningMutationVariables,
- GQLDeleteWarningMutation,
- GQLDeleteWarningMutationVariables,
- GQLWarningsGridQuery,
- GQLWarningsGridQueryVariables,
- GQLWarningsListFragment,
-} from "./WarningsGrid.generated";
-
-const warningsFragment = gql`
- fragment WarningsList on Warning {
- id
- createdAt
- updatedAt
- type
- level
- state
- }
-`;
-
-const warningsQuery = gql`
- query WarningsGrid($offset: Int, $limit: Int, $sort: [WarningSort!], $search: String, $filter: WarningFilter) {
- warnings(offset: $offset, limit: $limit, sort: $sort, search: $search, filter: $filter) {
- nodes {
- ...WarningsList
- }
- totalCount
- }
- }
- ${warningsFragment}
-`;
-
-const deleteWarningMutation = gql`
- mutation DeleteWarning($id: ID!) {
- deleteWarning(id: $id)
- }
-`;
-
-const createWarningMutation = gql`
- mutation CreateWarning($input: WarningInput!) {
- createWarning(input: $input) {
- id
- }
- }
-`;
-
-function WarningsGridToolbar() {
- return (
-
-
-
-
-
-
-
-
-
- } component={StackLink} pageName="add" payload="add" variant="contained" color="primary">
-
-
-
-
- );
-}
-
-export function WarningsGrid(): React.ReactElement {
- const client = useApolloClient();
- const intl = useIntl();
- const dataGridProps = { ...useDataGridRemote(), ...usePersistentColumnState("WarningsGrid") };
-
- const columns: GridColDef[] = [
- {
- field: "createdAt",
- headerName: intl.formatMessage({ id: "warning.createdAt", defaultMessage: "Created At" }),
- type: "dateTime",
- valueGetter: ({ value }) => value && new Date(value),
- width: 150,
- },
- {
- field: "updatedAt",
- headerName: intl.formatMessage({ id: "warning.updatedAt", defaultMessage: "Updated At" }),
- type: "dateTime",
- valueGetter: ({ value }) => value && new Date(value),
- width: 150,
- },
- { field: "type", headerName: intl.formatMessage({ id: "warning.type", defaultMessage: "Type" }), width: 150 },
- {
- field: "level",
- headerName: intl.formatMessage({ id: "warning.level", defaultMessage: "Level" }),
- type: "singleSelect",
- valueOptions: [
- { value: "critical", label: intl.formatMessage({ id: "warning.level.critical", defaultMessage: "Critical" }) },
- { value: "high", label: intl.formatMessage({ id: "warning.level.high", defaultMessage: "High" }) },
- { value: "low", label: intl.formatMessage({ id: "warning.level.low", defaultMessage: "Low" }) },
- ],
- width: 150,
- },
- {
- field: "state",
- headerName: intl.formatMessage({ id: "warning.state", defaultMessage: "State" }),
- type: "singleSelect",
- valueOptions: [
- { value: "open", label: intl.formatMessage({ id: "warning.state.open", defaultMessage: "Open" }) },
- { value: "resolved", label: intl.formatMessage({ id: "warning.state.resolved", defaultMessage: "Resolved" }) },
- { value: "ignored", label: intl.formatMessage({ id: "warning.state.ignored", defaultMessage: "Ignored" }) },
- ],
- width: 150,
- },
- {
- field: "actions",
- headerName: "",
- sortable: false,
- filterable: false,
- type: "actions",
- renderCell: (params) => {
- return (
- <>
-
-
-
- {
- const row = params.row;
- return {
- type: row.type,
- level: row.level,
- state: row.state,
- };
- }}
- onPaste={async ({ input }) => {
- await client.mutate({
- mutation: createWarningMutation,
- variables: { input },
- });
- }}
- onDelete={async () => {
- await client.mutate({
- mutation: deleteWarningMutation,
- variables: { id: params.row.id },
- });
- }}
- refetchQueries={[warningsQuery]}
- />
- >
- );
- },
- },
- ];
-
- const { filter: gqlFilter, search: gqlSearch } = muiGridFilterToGql(columns, dataGridProps.filterModel);
-
- const { data, loading, error } = useQuery(warningsQuery, {
- variables: {
- filter: gqlFilter,
- search: gqlSearch,
- offset: dataGridProps.page * dataGridProps.pageSize,
- limit: dataGridProps.pageSize,
- sort: muiGridSortToGql(dataGridProps.sortModel),
- },
- });
- const rowCount = useBufferedRowCount(data?.warnings.totalCount);
- if (error) throw error;
- const rows = data?.warnings.nodes ?? [];
-
- return (
-
-
-
- );
-}
diff --git a/demo/admin/src/warnings/generated/WarningsPage.tsx b/demo/admin/src/warnings/generated/WarningsPage.tsx
deleted file mode 100644
index d639b8e19b..0000000000
--- a/demo/admin/src/warnings/generated/WarningsPage.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 { Stack, StackPage, StackSwitch, StackToolbar } from "@comet/admin";
-import { ContentScopeIndicator } from "@comet/cms-admin";
-import * as React from "react";
-import { useIntl } from "react-intl";
-
-import { WarningForm } from "./WarningForm";
-import { WarningsGrid } from "./WarningsGrid";
-
-export function WarningsPage(): React.ReactElement {
- const intl = useIntl();
- return (
-
-
-
- } />
-
-
-
- {(selectedId) => }
-
-
-
-
-
-
- );
-}