From 8c04c3d67977def158f9a346bf36279f36269e01 Mon Sep 17 00:00:00 2001 From: fichtnerma <72387685+fichtnerma@users.noreply.github.com> Date: Mon, 15 Jul 2024 11:12:35 +0200 Subject: [PATCH] Remove Products Content from Demo for easier updates (#50) Co-authored-by: Markus Fichtner Co-authored-by: Thomas Dax --- demo/admin/src/Routes.tsx | 2 - demo/admin/src/common/MasterMenu.tsx | 8 +- demo/admin/src/products/ProductForm.gql.ts | 36 ----- demo/admin/src/products/ProductForm.tsx | 101 ------------- demo/admin/src/products/ProductsGrid.tsx | 142 ------------------ demo/admin/src/products/ProductsPage.tsx | 26 ---- demo/api/schema.gql | 46 ------ demo/api/src/app.module.ts | 2 - demo/api/src/db/fixtures/fixtures.console.ts | 7 +- demo/api/src/db/fixtures/fixtures.module.ts | 4 +- .../db/fixtures/generators/product.fixture.ts | 26 ---- .../db/migrations/Migration20220721123033.ts | 10 -- .../src/products/dto/paginated-products.ts | 8 - demo/api/src/products/dto/product.filter.ts | 43 ------ demo/api/src/products/dto/product.input.ts | 16 -- demo/api/src/products/dto/product.sort.ts | 24 --- demo/api/src/products/dto/products.args.ts | 26 ---- .../src/products/entities/product.entity.ts | 42 ------ .../api/src/products/product.crud.resolver.ts | 93 ------------ demo/api/src/products/products.console.ts | 22 --- demo/api/src/products/products.module.ts | 14 -- demo/api/src/products/products.service.ts | 24 --- 22 files changed, 3 insertions(+), 719 deletions(-) delete mode 100644 demo/admin/src/products/ProductForm.gql.ts delete mode 100644 demo/admin/src/products/ProductForm.tsx delete mode 100644 demo/admin/src/products/ProductsGrid.tsx delete mode 100644 demo/admin/src/products/ProductsPage.tsx delete mode 100644 demo/api/src/db/fixtures/generators/product.fixture.ts delete mode 100644 demo/api/src/db/migrations/Migration20220721123033.ts delete mode 100644 demo/api/src/products/dto/paginated-products.ts delete mode 100644 demo/api/src/products/dto/product.filter.ts delete mode 100644 demo/api/src/products/dto/product.input.ts delete mode 100644 demo/api/src/products/dto/product.sort.ts delete mode 100644 demo/api/src/products/dto/products.args.ts delete mode 100644 demo/api/src/products/entities/product.entity.ts delete mode 100644 demo/api/src/products/product.crud.resolver.ts delete mode 100644 demo/api/src/products/products.console.ts delete mode 100644 demo/api/src/products/products.module.ts delete mode 100644 demo/api/src/products/products.service.ts diff --git a/demo/admin/src/Routes.tsx b/demo/admin/src/Routes.tsx index 7ed9f0f4..5ea0664c 100644 --- a/demo/admin/src/Routes.tsx +++ b/demo/admin/src/Routes.tsx @@ -19,7 +19,6 @@ import { DashboardPage } from "./dashboard/DashboardPage"; import { Link } from "./documents/links/Link"; import { Page } from "./documents/pages/Page"; import { EmailCampaignContentBlock } from "./emailCampaigns/blocks/EmailCampaignContentBlock"; -import { ProductsPage } from "./products/ProductsPage"; const RedirectsPage = createRedirectsPage(); @@ -100,7 +99,6 @@ export const Routes: React.FC = () => { - diff --git a/demo/admin/src/common/MasterMenu.tsx b/demo/admin/src/common/MasterMenu.tsx index f71f8e97..5281c6eb 100644 --- a/demo/admin/src/common/MasterMenu.tsx +++ b/demo/admin/src/common/MasterMenu.tsx @@ -1,5 +1,5 @@ import { Menu, MenuCollapsibleItem, MenuContext, MenuItemRouterLink, useWindowSize } from "@comet/admin"; -import { Assets, Dashboard, Data, Mail, PageTree, Wrench } from "@comet/admin-icons"; +import { Assets, Dashboard, Mail, PageTree, Wrench } from "@comet/admin-icons"; import * as React from "react"; import { useIntl } from "react-intl"; import { useRouteMatch } from "react-router"; @@ -49,12 +49,6 @@ export const MasterMenu: React.FC = () => { to={`${match.url}/newsletter/email-campaigns`} /> - }> - - } diff --git a/demo/admin/src/products/ProductForm.gql.ts b/demo/admin/src/products/ProductForm.gql.ts deleted file mode 100644 index 0e757169..00000000 --- a/demo/admin/src/products/ProductForm.gql.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { gql } from "@apollo/client"; - -export const productFormFragment = gql` - fragment ProductForm on Product { - id - name - description - } -`; - -export const productQuery = gql` - query Product($id: ID!) { - product(id: $id) { - ...ProductForm - } - } - ${productFormFragment} -`; - -export const createProductMutation = gql` - mutation CreateProduct($input: ProductInput!) { - createProduct(input: $input) { - ...ProductForm - } - } - ${productFormFragment} -`; - -export const updateProductMutation = gql` - mutation UpdateProduct($id: ID!, $input: ProductInput!) { - updateProduct(id: $id, input: $input) { - ...ProductForm - } - } - ${productFormFragment} -`; diff --git a/demo/admin/src/products/ProductForm.tsx b/demo/admin/src/products/ProductForm.tsx deleted file mode 100644 index f6583965..00000000 --- a/demo/admin/src/products/ProductForm.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useMutation, useQuery } from "@apollo/client"; -import { - Field, - FinalForm, - FinalFormInput, - FinalFormSaveSplitButton, - Loading, - MainContent, - Toolbar, - ToolbarActions, - ToolbarBackButton, - ToolbarFillSpace, -} from "@comet/admin"; -import { Card, CardContent } from "@mui/material"; -import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; - -import { createProductMutation, productQuery, updateProductMutation } from "./ProductForm.gql"; -import { - GQLCreateProductMutation, - GQLCreateProductMutationVariables, - GQLProductFormFragment, - GQLProductQuery, - GQLProductQueryVariables, - GQLUpdateProductMutation, - GQLUpdateProductMutationVariables, -} from "./ProductForm.gql.generated"; - -type FormValues = GQLProductFormFragment; - -const useSubmitMutation = (id?: string) => { - const [create] = useMutation(createProductMutation); - const [update] = useMutation(updateProductMutation); - - if (id) { - return ({ name, description }: FormValues) => { - return update({ variables: { id, input: { name, description } } }); - }; - } - - return ({ name, description }: FormValues) => { - return create({ variables: { input: { name, description } } }); - }; -}; - -interface FormProps { - id?: string; -} - -export function ProductForm({ id }: FormProps): React.ReactElement { - const intl = useIntl(); - const mode = id ? "edit" : "add"; - - const submit = useSubmitMutation(id); - - const { data, error, loading } = useQuery(productQuery, id ? { variables: { id } } : { skip: true }); - - if (error) { - return ; - } - - if (loading) { - return ; - } - - const initialValues: Partial = data?.product ?? {}; - - return ( - mode={mode} onSubmit={submit} initialValues={initialValues}> - - - - - - - - - - - - - - - - - ); -} diff --git a/demo/admin/src/products/ProductsGrid.tsx b/demo/admin/src/products/ProductsGrid.tsx deleted file mode 100644 index 637883ef..00000000 --- a/demo/admin/src/products/ProductsGrid.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { gql, useQuery } from "@apollo/client"; -import { - GridFilterButton, - MainContent, - muiGridFilterToGql, - muiGridPagingToGql, - muiGridSortToGql, - StackLink, - TableDeleteButton, - Toolbar, - ToolbarActions, - ToolbarAutomaticTitleItem, - ToolbarFillSpace, - ToolbarItem, - useDataGridRemote, - usePersistentColumnState, -} from "@comet/admin"; -import { Add, Delete, Edit } from "@comet/admin-icons"; -import { Button, IconButton } from "@mui/material"; -import { DataGrid, GridColDef, GridToolbarQuickFilter } from "@mui/x-data-grid"; -import { parseISO } from "date-fns"; -import React from "react"; -import { FormattedMessage, useIntl } from "react-intl"; - -import { GQLProductGridItemFragment, GQLProductsQuery, GQLProductsQueryVariables } from "./ProductsGrid.generated"; - -const productFragment = gql` - fragment ProductGridItem on Product { - id - name - description - createdAt - } -`; - -const productsQuery = gql` - query Products($offset: Int, $limit: Int, $search: String, $filter: ProductFilter, $sort: [ProductSort!]) { - products(offset: $offset, limit: $limit, search: $search, filter: $filter, sort: $sort) { - nodes { - ...ProductGridItem - } - totalCount - } - } - ${productFragment} -`; - -const deleteProductMutation = gql` - mutation DeleteProduct($id: ID!) { - deleteProduct(id: $id) - } -`; - -function ProductsToolbar(): React.ReactElement { - return ( - - - - - - - - - - - - - - ); -} - -export function ProductsGrid(): React.ReactElement { - const dataGridProps = { ...useDataGridRemote(), ...usePersistentColumnState("ProductsGrid") }; - const intl = useIntl(); - - const columns: GridColDef[] = [ - { - field: "createdAt", - flex: 1, - headerName: intl.formatMessage({ id: "product.createdAt", defaultMessage: "Created at" }), - renderCell: ({ row }) => intl.formatDate(parseISO(row.createdAt)), - }, - { - field: "name", - flex: 1, - headerName: intl.formatMessage({ id: "product.name", defaultMessage: "Name" }), - }, - { - field: "description", - flex: 2, - sortable: false, - headerName: intl.formatMessage({ id: "product.description", defaultMessage: "Description" }), - }, - { - field: "actions", - flex: 0.5, - headerName: "", - sortable: false, - filterable: false, - align: "right", - renderCell: ({ row }) => ( - <> - - - - } mutation={deleteProductMutation} selectedId={row.id} text="" /> - - ), - }, - ]; - - const { data, loading, error } = useQuery(productsQuery, { - variables: { - ...muiGridFilterToGql(columns, dataGridProps.filterModel), - ...muiGridPagingToGql({ page: dataGridProps.page, pageSize: dataGridProps.pageSize }), - sort: muiGridSortToGql(dataGridProps.sortModel), - }, - }); - - if (error) throw new Error(error.message); - - const rows = data?.products.nodes ?? []; - const rowCount = data?.products.totalCount; - - return ( - - - - ); -} diff --git a/demo/admin/src/products/ProductsPage.tsx b/demo/admin/src/products/ProductsPage.tsx deleted file mode 100644 index f8bb9247..00000000 --- a/demo/admin/src/products/ProductsPage.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { Stack, StackPage, StackSwitch } from "@comet/admin"; -import * as React from "react"; -import { useIntl } from "react-intl"; - -import { ProductForm } from "./ProductForm"; -import { ProductsGrid } from "./ProductsGrid"; - -export function ProductsPage(): React.ReactElement { - const intl = useIntl(); - - return ( - - - - - - - {(selectedId) => } - - - - - - - ); -} diff --git a/demo/api/schema.gql b/demo/api/schema.gql index 0db959c7..fb23286f 100644 --- a/demo/api/schema.gql +++ b/demo/api/schema.gql @@ -203,16 +203,6 @@ type BrevoApiCampaignStatistics { viewed: Int! } -type Product { - id: ID! - creatorId: String! - name: String! - description: String! - createdAt: DateTime! - updatedAt: DateTime - sales: Int! -} - type Link implements DocumentInterface { id: ID! updatedAt: DateTime! @@ -287,11 +277,6 @@ input DependentFilter { rootColumnName: String } -type PaginatedProducts { - nodes: [Product!]! - totalCount: Int! -} - type BrevoContactAttributes { LASTNAME: String! FIRSTNAME: String! @@ -530,8 +515,6 @@ type Query { damFoldersList(offset: Int! = 0, limit: Int! = 25, sortColumnName: String, sortDirection: SortDirection! = ASC, scope: DamScopeInput! = {}, parentId: ID, includeArchived: Boolean, filter: FolderFilterInput): PaginatedDamFolders! damFolder(id: ID!): DamFolder! damFolderByNameAndParentId(scope: DamScopeInput! = {}, name: String!, parentId: ID): DamFolder - product(id: ID!): Product! - products(offset: Int! = 0, limit: Int! = 25, search: String, filter: ProductFilter, sort: [ProductSort!]): PaginatedProducts! mainMenu(scope: PageTreeNodeScopeInput!): [PageTreeNode!]! brevoContact(id: Int!, scope: EmailCampaignContentScopeInput!): BrevoContact! brevoContacts(targetGroupId: ID, email: String, scope: EmailCampaignContentScopeInput!, offset: Int! = 0, limit: Int! = 25): PaginatedBrevoContacts! @@ -667,27 +650,6 @@ input FolderFilterInput { searchText: String } -input ProductFilter { - creatorId: StringFilter - name: StringFilter - description: StringFilter - createdAt: DateFilter - updatedAt: DateFilter - and: [ProductFilter!] - or: [ProductFilter!] -} - -input ProductSort { - field: ProductSortField! - direction: SortDirection! = ASC -} - -enum ProductSortField { - name - createdAt - updatedAt -} - input EmailCampaignFilter { createdAt: DateFilter updatedAt: DateFilter @@ -765,9 +727,6 @@ type Mutation { updateDamFolder(id: ID!, input: UpdateDamFolderInput!): DamFolder! moveDamFolders(folderIds: [ID!]!, targetFolderId: ID, scope: DamScopeInput! = {}): [DamFolder!]! deleteDamFolder(id: ID!): Boolean! - createProduct(input: ProductInput!): Product! - updateProduct(id: ID!, input: ProductInput!, lastUpdatedAt: DateTime): Product! - deleteProduct(id: ID!): Boolean! updateBrevoContact(id: Int!, scope: EmailCampaignContentScopeInput!, input: BrevoContactUpdateInput!): BrevoContact! createBrevoContact(scope: EmailCampaignContentScopeInput!, input: BrevoContactInput!): SubscribeResponse! deleteBrevoContact(id: Int!, scope: EmailCampaignContentScopeInput!): Boolean! @@ -909,11 +868,6 @@ input UpdateDamFolderInput { archived: Boolean } -input ProductInput { - name: String! - description: String! -} - input BrevoContactUpdateInput { blocked: Boolean! attributes: BrevoContactAttributesInput diff --git a/demo/api/src/app.module.ts b/demo/api/src/app.module.ts index ef0d9667..6a659a4b 100644 --- a/demo/api/src/app.module.ts +++ b/demo/api/src/app.module.ts @@ -25,7 +25,6 @@ import { Page } from "@src/documents/pages/entities/page.entity"; import { PagesModule } from "@src/documents/pages/pages.module"; import { PageTreeNodeScope } from "@src/page-tree/dto/page-tree-node-scope"; import { PageTreeNode } from "@src/page-tree/entities/page-tree-node.entity"; -import { ProductsModule } from "@src/products/products.module"; import { Request } from "express"; import { AccessControlService } from "./auth/access-control.service"; @@ -133,7 +132,6 @@ export class AppModule { imgproxyConfig: config.imgproxy, }), StatusModule, - ProductsModule, MenusModule, DependenciesModule, BrevoModule.register({ diff --git a/demo/api/src/db/fixtures/fixtures.console.ts b/demo/api/src/db/fixtures/fixtures.console.ts index a7882b6c..726f62c5 100644 --- a/demo/api/src/db/fixtures/fixtures.console.ts +++ b/demo/api/src/db/fixtures/fixtures.console.ts @@ -1,9 +1,5 @@ import { MikroORM, UseRequestContext } from "@mikro-orm/core"; -import { InjectRepository } from "@mikro-orm/nestjs"; -import { EntityRepository } from "@mikro-orm/postgresql"; import { Injectable, Logger } from "@nestjs/common"; -import { generateProducts } from "@src/db/fixtures/generators/product.fixture"; -import { Product } from "@src/products/entities/product.entity"; import { MultiBar, Options, Presets } from "cli-progress"; import { Command, Console } from "nestjs-console"; @@ -12,7 +8,7 @@ import { Command, Console } from "nestjs-console"; export class FixturesConsole { private readonly logger = new Logger(FixturesConsole.name); - constructor(private readonly orm: MikroORM, @InjectRepository(Product) private readonly productsRepository: EntityRepository) {} + constructor(private readonly orm: MikroORM) {} barOptions: Options = { format: `{bar} {percentage}% | {value}/{total} {title} | ETA: {eta_formatted} | Duration: {duration_formatted}`, @@ -41,7 +37,6 @@ export class FixturesConsole { await migrator.up(); const multiBar = new MultiBar(this.barOptions, Presets.shades_classic); - await Promise.all([generateProducts({ repository: this.productsRepository, bar: multiBar.create(total, 0), total })]); multiBar.stop(); await this.orm.em.flush(); diff --git a/demo/api/src/db/fixtures/fixtures.module.ts b/demo/api/src/db/fixtures/fixtures.module.ts index 04f6a4e4..37a6d50d 100644 --- a/demo/api/src/db/fixtures/fixtures.module.ts +++ b/demo/api/src/db/fixtures/fixtures.module.ts @@ -1,12 +1,10 @@ -import { MikroOrmModule } from "@mikro-orm/nestjs"; import { Module } from "@nestjs/common"; import { ConfigModule } from "@nestjs/config"; import { FixturesConsole } from "@src/db/fixtures/fixtures.console"; -import { Product } from "@src/products/entities/product.entity"; import { ConsoleModule } from "nestjs-console"; @Module({ - imports: [MikroOrmModule.forFeature([Product]), ConfigModule, ConsoleModule], + imports: [ConfigModule, ConsoleModule], providers: [FixturesConsole], exports: [], }) diff --git a/demo/api/src/db/fixtures/generators/product.fixture.ts b/demo/api/src/db/fixtures/generators/product.fixture.ts deleted file mode 100644 index 89f8f81e..00000000 --- a/demo/api/src/db/fixtures/generators/product.fixture.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { faker } from "@faker-js/faker"; -import { EntityRepository } from "@mikro-orm/postgresql"; -import { Product } from "@src/products/entities/product.entity"; -import { mapLimit } from "async"; -import { SingleBar } from "cli-progress"; - -interface GenerateProducts { - repository: EntityRepository; - bar: SingleBar; - total: number; -} - -export const generateProducts = async ({ repository, bar, total }: GenerateProducts): Promise => { - const generateRandomProduct = async (): Promise => { - const product = repository.create({ name: faker.lorem.word(), description: faker.lorem.words(), creatorId: faker.string.uuid() }); - repository.persist(product); - - bar.increment(1, { - title: "Product", - }); - - return product; - }; - - return mapLimit(Array(total), 100, async () => generateRandomProduct()); -}; diff --git a/demo/api/src/db/migrations/Migration20220721123033.ts b/demo/api/src/db/migrations/Migration20220721123033.ts deleted file mode 100644 index d1562cce..00000000 --- a/demo/api/src/db/migrations/Migration20220721123033.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Migration } from "@mikro-orm/migrations"; - -export class Migration20220721123033 extends Migration { - async up(): Promise { - this.addSql( - 'create table "Product" ("id" uuid not null, "creatorId" uuid not null, "name" text not null, "description" text not null, "createdAt" timestamp with time zone not null, "updatedAt" timestamp with time zone not null);', - ); - this.addSql('alter table "Product" add constraint "Product_pkey" primary key ("id");'); - } -} diff --git a/demo/api/src/products/dto/paginated-products.ts b/demo/api/src/products/dto/paginated-products.ts deleted file mode 100644 index 2d5ea3f4..00000000 --- a/demo/api/src/products/dto/paginated-products.ts +++ /dev/null @@ -1,8 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { PaginatedResponseFactory } from "@comet/cms-api"; -import { ObjectType } from "@nestjs/graphql"; - -import { Product } from "../entities/product.entity"; - -@ObjectType() -export class PaginatedProducts extends PaginatedResponseFactory.create(Product) {} diff --git a/demo/api/src/products/dto/product.filter.ts b/demo/api/src/products/dto/product.filter.ts deleted file mode 100644 index 845699bd..00000000 --- a/demo/api/src/products/dto/product.filter.ts +++ /dev/null @@ -1,43 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { DateFilter, StringFilter } from "@comet/cms-api"; -import { Field, InputType } from "@nestjs/graphql"; -import { Type } from "class-transformer"; -import { ValidateNested } from "class-validator"; - -@InputType() -export class ProductFilter { - @Field(() => StringFilter, { nullable: true }) - @ValidateNested() - @Type(() => StringFilter) - creatorId?: StringFilter; - - @Field(() => StringFilter, { nullable: true }) - @ValidateNested() - @Type(() => StringFilter) - name?: StringFilter; - - @Field(() => StringFilter, { nullable: true }) - @ValidateNested() - @Type(() => StringFilter) - description?: StringFilter; - - @Field(() => DateFilter, { nullable: true }) - @ValidateNested() - @Type(() => DateFilter) - createdAt?: DateFilter; - - @Field(() => DateFilter, { nullable: true }) - @ValidateNested() - @Type(() => DateFilter) - updatedAt?: DateFilter; - - @Field(() => [ProductFilter], { nullable: true }) - @Type(() => ProductFilter) - @ValidateNested({ each: true }) - and?: ProductFilter[]; - - @Field(() => [ProductFilter], { nullable: true }) - @Type(() => ProductFilter) - @ValidateNested({ each: true }) - or?: ProductFilter[]; -} diff --git a/demo/api/src/products/dto/product.input.ts b/demo/api/src/products/dto/product.input.ts deleted file mode 100644 index 4625c8c2..00000000 --- a/demo/api/src/products/dto/product.input.ts +++ /dev/null @@ -1,16 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { Field, InputType } from "@nestjs/graphql"; -import { IsNotEmpty, IsString } from "class-validator"; - -@InputType() -export class ProductInput { - @IsNotEmpty() - @IsString() - @Field() - name: string; - - @IsNotEmpty() - @IsString() - @Field() - description: string; -} diff --git a/demo/api/src/products/dto/product.sort.ts b/demo/api/src/products/dto/product.sort.ts deleted file mode 100644 index c2a7e9ff..00000000 --- a/demo/api/src/products/dto/product.sort.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { SortDirection } from "@comet/cms-api"; -import { Field, InputType, registerEnumType } from "@nestjs/graphql"; -import { IsEnum } from "class-validator"; - -export enum ProductSortField { - name = "name", - createdAt = "createdAt", - updatedAt = "updatedAt", -} -registerEnumType(ProductSortField, { - name: "ProductSortField", -}); - -@InputType() -export class ProductSort { - @Field(() => ProductSortField) - @IsEnum(ProductSortField) - field: ProductSortField; - - @Field(() => SortDirection, { defaultValue: SortDirection.ASC }) - @IsEnum(SortDirection) - direction: SortDirection = SortDirection.ASC; -} diff --git a/demo/api/src/products/dto/products.args.ts b/demo/api/src/products/dto/products.args.ts deleted file mode 100644 index aa4d7e2c..00000000 --- a/demo/api/src/products/dto/products.args.ts +++ /dev/null @@ -1,26 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { OffsetBasedPaginationArgs } from "@comet/cms-api"; -import { ArgsType, Field } from "@nestjs/graphql"; -import { Type } from "class-transformer"; -import { IsOptional, IsString, ValidateNested } from "class-validator"; - -import { ProductFilter } from "./product.filter"; -import { ProductSort } from "./product.sort"; - -@ArgsType() -export class ProductsArgs extends OffsetBasedPaginationArgs { - @Field({ nullable: true }) - @IsOptional() - @IsString() - search?: string; - - @Field(() => ProductFilter, { nullable: true }) - @ValidateNested() - @Type(() => ProductFilter) - filter?: ProductFilter; - - @Field(() => [ProductSort], { nullable: true }) - @ValidateNested({ each: true }) - @Type(() => ProductSort) - sort?: ProductSort[]; -} diff --git a/demo/api/src/products/entities/product.entity.ts b/demo/api/src/products/entities/product.entity.ts deleted file mode 100644 index ee4babc2..00000000 --- a/demo/api/src/products/entities/product.entity.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { BaseEntity, Entity, OptionalProps, PrimaryKey, Property } from "@mikro-orm/core"; -import { Field, ID, ObjectType } from "@nestjs/graphql"; -import { v4 } from "uuid"; - -@ObjectType() -@Entity() -export class Product extends BaseEntity { - [OptionalProps]?: "createdAt" | "updatedAt"; - - @Field(() => ID) - @PrimaryKey({ type: "uuid" }) - id: string = v4(); - - @Field() - @Property({ columnType: "uuid" }) - creatorId: string; - - @Field() - @Property({ - columnType: "text", - }) - name: string; - - @Field() - @Property({ - columnType: "text", - }) - description: string; - - @Field() - @Property({ - columnType: "timestamp with time zone", - }) - createdAt: Date = new Date(); - - @Field({ nullable: true }) - @Property({ - columnType: "timestamp with time zone", - onUpdate: () => new Date(), - }) - updatedAt: Date = new Date(); -} diff --git a/demo/api/src/products/product.crud.resolver.ts b/demo/api/src/products/product.crud.resolver.ts deleted file mode 100644 index 101629cd..00000000 --- a/demo/api/src/products/product.crud.resolver.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { AffectedEntity, CurrentUser, GetCurrentUser, RequiredPermission, validateNotModified } from "@comet/cms-api"; -import { FindOptions } from "@mikro-orm/core"; -import { InjectRepository } from "@mikro-orm/nestjs"; -import { EntityRepository } from "@mikro-orm/postgresql"; -import { Args, ID, Int, Mutation, Query, ResolveField, Resolver } from "@nestjs/graphql"; - -import { PaginatedProducts } from "./dto/paginated-products"; -import { ProductInput } from "./dto/product.input"; -import { ProductsArgs } from "./dto/products.args"; -import { Product } from "./entities/product.entity"; -import { ProductsService } from "./products.service"; - -@Resolver(() => Product) -@RequiredPermission(["products"]) -export class ProductCrudResolver { - constructor( - private readonly productsService: ProductsService, - @InjectRepository(Product) private readonly repository: EntityRepository, - ) {} - - @Query(() => Product) - @AffectedEntity(Product) - async product(@Args("id", { type: () => ID }) id: string): Promise { - const product = await this.repository.findOneOrFail(id); - return product; - } - - @Query(() => PaginatedProducts) - async products(@Args() { search, filter, sort, offset, limit }: ProductsArgs): Promise { - const where = this.productsService.getFindCondition({ search, filter }); - - const options: FindOptions = { offset, limit }; - - if (sort) { - options.orderBy = sort.map((sortItem) => { - return { - [sortItem.field]: sortItem.direction, - }; - }); - } - - const [entities, totalCount] = await this.repository.findAndCount(where, options); - return new PaginatedProducts(entities, totalCount); - } - - @Mutation(() => Product) - async createProduct(@GetCurrentUser() user: CurrentUser, @Args("input", { type: () => ProductInput }) input: ProductInput): Promise { - const product = this.repository.create({ - ...input, - creatorId: user.id, - }); - - await this.repository.persistAndFlush(product); - return product; - } - - @Mutation(() => Product) - @AffectedEntity(Product) - async updateProduct( - @GetCurrentUser() user: CurrentUser, - @Args("id", { type: () => ID }) id: string, - @Args("input", { type: () => ProductInput }) input: ProductInput, - @Args("lastUpdatedAt", { type: () => Date, nullable: true }) lastUpdatedAt?: Date, - ): Promise { - const product = await this.repository.findOneOrFail(id); - if (lastUpdatedAt) { - validateNotModified(product, lastUpdatedAt); - } - product.assign({ - ...input, - }); - - await this.repository.persistAndFlush(product); - - return product; - } - - @Mutation(() => Boolean) - @AffectedEntity(Product) - async deleteProduct(@GetCurrentUser() user: CurrentUser, @Args("id", { type: () => ID }) id: string): Promise { - const product = await this.repository.findOneOrFail(id); - - await this.repository.removeAndFlush(product); - - return true; - } - - @ResolveField(() => Int) - sales(): number { - return 0; - } -} diff --git a/demo/api/src/products/products.console.ts b/demo/api/src/products/products.console.ts deleted file mode 100644 index 4d6f1892..00000000 --- a/demo/api/src/products/products.console.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { MikroORM, UseRequestContext } from "@mikro-orm/core"; -import { Injectable, Logger } from "@nestjs/common"; -import { Command, Console } from "nestjs-console"; - -@Injectable() -@Console() -export class ProductsConsole { - private readonly logger = new Logger(ProductsConsole.name); - - constructor( - private readonly orm: MikroORM, // MikroORM is injected so we can use the request context - ) {} - - @Command({ - command: "demo-command", - description: "Demo-Command for cronjob-deployment", - }) - @UseRequestContext() - async demoCommand(): Promise { - this.logger.log("Execute demo-command."); - } -} diff --git a/demo/api/src/products/products.module.ts b/demo/api/src/products/products.module.ts deleted file mode 100644 index 0d06c49d..00000000 --- a/demo/api/src/products/products.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { MikroOrmModule } from "@mikro-orm/nestjs"; -import { Module } from "@nestjs/common"; - -import { Product } from "./entities/product.entity"; -import { ProductCrudResolver } from "./product.crud.resolver"; -import { ProductsConsole } from "./products.console"; -import { ProductsService } from "./products.service"; - -@Module({ - imports: [MikroOrmModule.forFeature([Product])], - providers: [ProductsService, ProductCrudResolver, ProductsConsole], - exports: [ProductsService], -}) -export class ProductsModule {} diff --git a/demo/api/src/products/products.service.ts b/demo/api/src/products/products.service.ts deleted file mode 100644 index b9bce6d5..00000000 --- a/demo/api/src/products/products.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -// Scaffolded by the CRUD generator on 2023-03-20. -import { filtersToMikroOrmQuery, searchToMikroOrmQuery } from "@comet/cms-api"; -import { ObjectQuery } from "@mikro-orm/core"; -import { Injectable } from "@nestjs/common"; - -import { ProductFilter } from "./dto/product.filter"; -import { Product } from "./entities/product.entity"; - -@Injectable() -export class ProductsService { - getFindCondition(options: { search?: string; filter?: ProductFilter }): ObjectQuery { - const andFilters = []; - - if (options.search) { - andFilters.push(searchToMikroOrmQuery(options.search, ["name", "description"])); - } - - if (options.filter) { - andFilters.push(filtersToMikroOrmQuery(options.filter)); - } - - return andFilters.length > 0 ? { $and: andFilters } : {}; - } -}