From 6290d69c1e575593f1df3732680028b2b4832f0e Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Thu, 7 Dec 2023 13:46:29 -0500 Subject: [PATCH 1/6] feat: add Reporting Periods page --- .../migration.sql | 51 ++ api/db/schema.prisma | 50 +- api/src/graphql/inputTemplates.sdl.ts | 41 ++ api/src/graphql/outputTemplates.sdl.ts | 41 ++ api/src/graphql/reportingPeriods.sdl.ts | 55 ++ api/src/graphql/roles.sdl.ts | 28 + api/src/graphql/users.sdl.ts | 43 ++ .../inputTemplates.scenarios.ts | 27 + .../inputTemplates/inputTemplates.test.ts | 74 +++ .../services/inputTemplates/inputTemplates.ts | 51 ++ .../outputTemplates.scenarios.ts | 27 + .../outputTemplates/outputTemplates.test.ts | 79 +++ .../outputTemplates/outputTemplates.ts | 47 ++ .../reportingPeriods.scenarios.ts | 57 ++ .../reportingPeriods/reportingPeriods.test.ts | 85 +++ .../reportingPeriods/reportingPeriods.ts | 57 ++ api/src/services/roles/roles.scenarios.ts | 11 + api/src/services/roles/roles.test.ts | 50 ++ api/src/services/roles/roles.ts | 42 ++ api/src/services/users/users.scenarios.ts | 23 + api/src/services/users/users.test.ts | 55 ++ api/src/services/users/users.ts | 51 ++ api/types/graphql.d.ts | 499 +++++++++++++++++- web/src/Routes.tsx | 2 + .../ReportingPeriodCell.mock.ts | 6 + .../ReportingPeriodCell.stories.tsx | 34 ++ .../ReportingPeriodCell.test.tsx | 41 ++ .../ReportingPeriodCell.tsx | 34 ++ .../ReportingPeriodsCell.mock.ts | 4 + .../ReportingPeriodsCell.stories.tsx | 34 ++ .../ReportingPeriodsCell.test.tsx | 41 ++ .../ReportingPeriodsCell.tsx | 78 +++ .../ReportingPeriodsPage.stories.tsx | 13 + .../ReportingPeriodsPage.test.tsx | 14 + .../ReportingPeriodsPage.tsx | 16 + .../UploadTemplatePage.stories.tsx | 13 + .../UploadTemplatePage.test.tsx | 14 + .../UploadTemplatePage/UploadTemplatePage.tsx | 38 ++ web/types/graphql.d.ts | 288 ++++++++++ 39 files changed, 2207 insertions(+), 7 deletions(-) create mode 100644 api/db/migrations/20231207184509_add_templates_and_reporting_periods/migration.sql create mode 100644 api/src/graphql/inputTemplates.sdl.ts create mode 100644 api/src/graphql/outputTemplates.sdl.ts create mode 100644 api/src/graphql/reportingPeriods.sdl.ts create mode 100644 api/src/graphql/roles.sdl.ts create mode 100644 api/src/graphql/users.sdl.ts create mode 100644 api/src/services/inputTemplates/inputTemplates.scenarios.ts create mode 100644 api/src/services/inputTemplates/inputTemplates.test.ts create mode 100644 api/src/services/inputTemplates/inputTemplates.ts create mode 100644 api/src/services/outputTemplates/outputTemplates.scenarios.ts create mode 100644 api/src/services/outputTemplates/outputTemplates.test.ts create mode 100644 api/src/services/outputTemplates/outputTemplates.ts create mode 100644 api/src/services/reportingPeriods/reportingPeriods.scenarios.ts create mode 100644 api/src/services/reportingPeriods/reportingPeriods.test.ts create mode 100644 api/src/services/reportingPeriods/reportingPeriods.ts create mode 100644 api/src/services/roles/roles.scenarios.ts create mode 100644 api/src/services/roles/roles.test.ts create mode 100644 api/src/services/roles/roles.ts create mode 100644 api/src/services/users/users.scenarios.ts create mode 100644 api/src/services/users/users.test.ts create mode 100644 api/src/services/users/users.ts create mode 100644 web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts create mode 100644 web/src/components/ReportingPeriodCell/ReportingPeriodCell.stories.tsx create mode 100644 web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx create mode 100644 web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx create mode 100644 web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.mock.ts create mode 100644 web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.stories.tsx create mode 100644 web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx create mode 100644 web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx create mode 100644 web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.stories.tsx create mode 100644 web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx create mode 100644 web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx create mode 100644 web/src/pages/UploadTemplatePage/UploadTemplatePage.stories.tsx create mode 100644 web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx create mode 100644 web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx diff --git a/api/db/migrations/20231207184509_add_templates_and_reporting_periods/migration.sql b/api/db/migrations/20231207184509_add_templates_and_reporting_periods/migration.sql new file mode 100644 index 00000000..1992ba28 --- /dev/null +++ b/api/db/migrations/20231207184509_add_templates_and_reporting_periods/migration.sql @@ -0,0 +1,51 @@ +-- CreateTable +CREATE TABLE "InputTemplate" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "version" TEXT NOT NULL, + "effectiveDate" DATE NOT NULL, + "rulesGeneratedAt" TIMESTAMPTZ(6), + "createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMPTZ(6) NOT NULL, + + CONSTRAINT "InputTemplate_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "OutputTemplate" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "version" TEXT NOT NULL, + "effectiveDate" DATE NOT NULL, + "rulesGeneratedAt" TIMESTAMPTZ(6), + "createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMPTZ(6) NOT NULL, + + CONSTRAINT "OutputTemplate_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ReportingPeriod" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "startDate" DATE NOT NULL, + "endDate" DATE NOT NULL, + "certifiedAt" TIMESTAMPTZ(6), + "certifiedById" INTEGER, + "inputTemplateId" INTEGER NOT NULL, + "outputTemplateId" INTEGER NOT NULL, + "isCurrentPeriod" BOOLEAN NOT NULL DEFAULT false, + "createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMPTZ(6) NOT NULL, + + CONSTRAINT "ReportingPeriod_pkey" PRIMARY KEY ("id") +); + +-- AddForeignKey +ALTER TABLE "ReportingPeriod" ADD CONSTRAINT "ReportingPeriod_certifiedById_fkey" FOREIGN KEY ("certifiedById") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "ReportingPeriod" ADD CONSTRAINT "ReportingPeriod_inputTemplateId_fkey" FOREIGN KEY ("inputTemplateId") REFERENCES "InputTemplate"("id") ON DELETE NO ACTION ON UPDATE NO ACTION; + +-- AddForeignKey +ALTER TABLE "ReportingPeriod" ADD CONSTRAINT "ReportingPeriod_outputTemplateId_fkey" FOREIGN KEY ("outputTemplateId") REFERENCES "OutputTemplate"("id") ON DELETE NO ACTION ON UPDATE NO ACTION; diff --git a/api/db/schema.prisma b/api/db/schema.prisma index 6f87b3b1..c516b21a 100644 --- a/api/db/schema.prisma +++ b/api/db/schema.prisma @@ -26,17 +26,18 @@ model Organization { } model User { - id Int @id @default(autoincrement()) + id Int @id @default(autoincrement()) email String name String? agencyId Int? organizationId Int roleId Int? - createdAt DateTime @default(now()) + createdAt DateTime @default(now()) updatedAt DateTime - agency Agency? @relation(fields: [agencyId], references: [id]) - organization Organization @relation(fields: [organizationId], references: [id]) - role Role? @relation(fields: [roleId], references: [id]) + agency Agency? @relation(fields: [agencyId], references: [id]) + organization Organization @relation(fields: [organizationId], references: [id]) + role Role? @relation(fields: [roleId], references: [id]) + certified ReportingPeriod[] } model Role { @@ -46,3 +47,42 @@ model Role { updatedAt DateTime users User[] } + +model InputTemplate { + id Int @id @default(autoincrement()) + name String + version String + effectiveDate DateTime @db.Date + rulesGeneratedAt DateTime? @db.Timestamptz(6) + createdAt DateTime @default(now()) @db.Timestamptz(6) + updatedAt DateTime @db.Timestamptz(6) + reportingPeriods ReportingPeriod[] +} + +model OutputTemplate { + id Int @id @default(autoincrement()) + name String + version String + effectiveDate DateTime @db.Date + rulesGeneratedAt DateTime? @db.Timestamptz(6) + createdAt DateTime @default(now()) @db.Timestamptz(6) + updatedAt DateTime @db.Timestamptz(6) + reportingPeriods ReportingPeriod[] +} + +model ReportingPeriod { + id Int @id @default(autoincrement()) + name String + startDate DateTime @db.Date + endDate DateTime @db.Date + certifiedAt DateTime? @db.Timestamptz(6) + certifiedById Int? + certifiedBy User? @relation(fields: [certifiedById], references: [id], onDelete: NoAction, onUpdate: NoAction) + inputTemplateId Int + inputTemplate InputTemplate @relation(fields: [inputTemplateId], references: [id], onDelete: NoAction, onUpdate: NoAction) + outputTemplateId Int + outputTemplate OutputTemplate @relation(fields: [outputTemplateId], references: [id], onDelete: NoAction, onUpdate: NoAction) + isCurrentPeriod Boolean @default(false) + createdAt DateTime @default(now()) @db.Timestamptz(6) + updatedAt DateTime @db.Timestamptz(6) +} diff --git a/api/src/graphql/inputTemplates.sdl.ts b/api/src/graphql/inputTemplates.sdl.ts new file mode 100644 index 00000000..d5abf527 --- /dev/null +++ b/api/src/graphql/inputTemplates.sdl.ts @@ -0,0 +1,41 @@ +export const schema = gql` + type InputTemplate { + id: Int! + name: String! + version: String! + effectiveDate: DateTime! + rulesGeneratedAt: DateTime! + createdAt: DateTime! + updatedAt: DateTime! + reportingPeriods: [ReportingPeriod]! + } + + type Query { + inputTemplates: [InputTemplate!]! @requireAuth + inputTemplate(id: Int!): InputTemplate @requireAuth + } + + input CreateInputTemplateInput { + name: String! + version: String! + effectiveDate: DateTime! + rulesGeneratedAt: DateTime! + } + + input UpdateInputTemplateInput { + name: String + version: String + effectiveDate: DateTime + rulesGeneratedAt: DateTime + } + + type Mutation { + createInputTemplate(input: CreateInputTemplateInput!): InputTemplate! + @requireAuth + updateInputTemplate( + id: Int! + input: UpdateInputTemplateInput! + ): InputTemplate! @requireAuth + deleteInputTemplate(id: Int!): InputTemplate! @requireAuth + } +` diff --git a/api/src/graphql/outputTemplates.sdl.ts b/api/src/graphql/outputTemplates.sdl.ts new file mode 100644 index 00000000..8d1c6fbd --- /dev/null +++ b/api/src/graphql/outputTemplates.sdl.ts @@ -0,0 +1,41 @@ +export const schema = gql` + type OutputTemplate { + id: Int! + name: String! + version: String! + effectiveDate: DateTime! + rulesGeneratedAt: DateTime! + createdAt: DateTime! + updatedAt: DateTime! + reportingPeriods: [ReportingPeriod]! + } + + type Query { + outputTemplates: [OutputTemplate!]! @requireAuth + outputTemplate(id: Int!): OutputTemplate @requireAuth + } + + input CreateOutputTemplateInput { + name: String! + version: String! + effectiveDate: DateTime! + rulesGeneratedAt: DateTime! + } + + input UpdateOutputTemplateInput { + name: String + version: String + effectiveDate: DateTime + rulesGeneratedAt: DateTime + } + + type Mutation { + createOutputTemplate(input: CreateOutputTemplateInput!): OutputTemplate! + @requireAuth + updateOutputTemplate( + id: Int! + input: UpdateOutputTemplateInput! + ): OutputTemplate! @requireAuth + deleteOutputTemplate(id: Int!): OutputTemplate! @requireAuth + } +` diff --git a/api/src/graphql/reportingPeriods.sdl.ts b/api/src/graphql/reportingPeriods.sdl.ts new file mode 100644 index 00000000..13e7f334 --- /dev/null +++ b/api/src/graphql/reportingPeriods.sdl.ts @@ -0,0 +1,55 @@ +export const schema = gql` + type ReportingPeriod { + id: Int! + name: String! + startDate: DateTime! + endDate: DateTime! + certifiedAt: DateTime + certifiedById: Int + certifiedBy: User + inputTemplateId: Int! + inputTemplate: InputTemplate! + outputTemplateId: Int! + outputTemplate: OutputTemplate! + isCurrentPeriod: Boolean! + createdAt: DateTime! + updatedAt: DateTime! + } + + type Query { + reportingPeriods: [ReportingPeriod!]! @requireAuth + reportingPeriod(id: Int!): ReportingPeriod @requireAuth + } + + input CreateReportingPeriodInput { + name: String! + startDate: DateTime! + endDate: DateTime! + certifiedAt: DateTime + certifiedById: Int + inputTemplateId: Int! + outputTemplateId: Int! + isCurrentPeriod: Boolean! + } + + input UpdateReportingPeriodInput { + name: String + startDate: DateTime + endDate: DateTime + certifiedAt: DateTime + certifiedById: Int + inputTemplateId: Int + outputTemplateId: Int + isCurrentPeriod: Boolean + } + + type Mutation { + createReportingPeriod(input: CreateReportingPeriodInput!): ReportingPeriod! + @requireAuth + updateReportingPeriod( + id: Int! + input: UpdateReportingPeriodInput! + ): ReportingPeriod! @requireAuth + deleteReportingPeriod(id: Int!): ReportingPeriod! @requireAuth + } +` diff --git a/api/src/graphql/roles.sdl.ts b/api/src/graphql/roles.sdl.ts new file mode 100644 index 00000000..bba4595a --- /dev/null +++ b/api/src/graphql/roles.sdl.ts @@ -0,0 +1,28 @@ +export const schema = gql` + type Role { + id: Int! + name: String! + createdAt: DateTime! + updatedAt: DateTime! + users: [User]! + } + + type Query { + roles: [Role!]! @requireAuth + role(id: Int!): Role @requireAuth + } + + input CreateRoleInput { + name: String! + } + + input UpdateRoleInput { + name: String + } + + type Mutation { + createRole(input: CreateRoleInput!): Role! @requireAuth + updateRole(id: Int!, input: UpdateRoleInput!): Role! @requireAuth + deleteRole(id: Int!): Role! @requireAuth + } +` diff --git a/api/src/graphql/users.sdl.ts b/api/src/graphql/users.sdl.ts new file mode 100644 index 00000000..7773b75b --- /dev/null +++ b/api/src/graphql/users.sdl.ts @@ -0,0 +1,43 @@ +export const schema = gql` + type User { + id: Int! + email: String! + name: String + agencyId: Int + organizationId: Int! + roleId: Int + createdAt: DateTime! + updatedAt: DateTime! + agency: Agency + organization: Organization! + role: Role + certified: [ReportingPeriod]! + } + + type Query { + users: [User!]! @requireAuth + user(id: Int!): User @requireAuth + } + + input CreateUserInput { + email: String! + name: String + agencyId: Int + organizationId: Int! + roleId: Int + } + + input UpdateUserInput { + email: String + name: String + agencyId: Int + organizationId: Int + roleId: Int + } + + type Mutation { + createUser(input: CreateUserInput!): User! @requireAuth + updateUser(id: Int!, input: UpdateUserInput!): User! @requireAuth + deleteUser(id: Int!): User! @requireAuth + } +` diff --git a/api/src/services/inputTemplates/inputTemplates.scenarios.ts b/api/src/services/inputTemplates/inputTemplates.scenarios.ts new file mode 100644 index 00000000..088bbfd9 --- /dev/null +++ b/api/src/services/inputTemplates/inputTemplates.scenarios.ts @@ -0,0 +1,27 @@ +import type { Prisma, InputTemplate } from '@prisma/client' +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + inputTemplate: { + one: { + data: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:24.389Z', + rulesGeneratedAt: '2023-12-07T18:17:24.389Z', + updatedAt: '2023-12-07T18:17:24.389Z', + }, + }, + two: { + data: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:24.389Z', + rulesGeneratedAt: '2023-12-07T18:17:24.389Z', + updatedAt: '2023-12-07T18:17:24.389Z', + }, + }, + }, +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/services/inputTemplates/inputTemplates.test.ts b/api/src/services/inputTemplates/inputTemplates.test.ts new file mode 100644 index 00000000..d65c08c1 --- /dev/null +++ b/api/src/services/inputTemplates/inputTemplates.test.ts @@ -0,0 +1,74 @@ +import type { InputTemplate } from '@prisma/client' + +import { + inputTemplates, + inputTemplate, + createInputTemplate, + updateInputTemplate, + deleteInputTemplate, +} from './inputTemplates' +import type { StandardScenario } from './inputTemplates.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('inputTemplates', () => { + scenario('returns all inputTemplates', async (scenario: StandardScenario) => { + const result = await inputTemplates() + + expect(result.length).toEqual(Object.keys(scenario.inputTemplate).length) + }) + + scenario( + 'returns a single inputTemplate', + async (scenario: StandardScenario) => { + const result = await inputTemplate({ id: scenario.inputTemplate.one.id }) + + expect(result).toEqual(scenario.inputTemplate.one) + } + ) + + scenario('creates a inputTemplate', async () => { + const result = await createInputTemplate({ + input: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:24.374Z', + rulesGeneratedAt: '2023-12-07T18:17:24.374Z', + updatedAt: '2023-12-07T18:17:24.374Z', + }, + }) + + expect(result.name).toEqual('String') + expect(result.version).toEqual('String') + expect(result.effectiveDate).toEqual(new Date('2023-12-07T18:17:24.374Z')) + expect(result.rulesGeneratedAt).toEqual( + new Date('2023-12-07T18:17:24.374Z') + ) + expect(result.updatedAt).toEqual(new Date('2023-12-07T18:17:24.374Z')) + }) + + scenario('updates a inputTemplate', async (scenario: StandardScenario) => { + const original = (await inputTemplate({ + id: scenario.inputTemplate.one.id, + })) as InputTemplate + const result = await updateInputTemplate({ + id: original.id, + input: { name: 'String2' }, + }) + + expect(result.name).toEqual('String2') + }) + + scenario('deletes a inputTemplate', async (scenario: StandardScenario) => { + const original = (await deleteInputTemplate({ + id: scenario.inputTemplate.one.id, + })) as InputTemplate + const result = await inputTemplate({ id: original.id }) + + expect(result).toEqual(null) + }) +}) diff --git a/api/src/services/inputTemplates/inputTemplates.ts b/api/src/services/inputTemplates/inputTemplates.ts new file mode 100644 index 00000000..1583a69d --- /dev/null +++ b/api/src/services/inputTemplates/inputTemplates.ts @@ -0,0 +1,51 @@ +import type { + QueryResolvers, + MutationResolvers, + InputTemplateRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const inputTemplates: QueryResolvers['inputTemplates'] = () => { + return db.inputTemplate.findMany() +} + +export const inputTemplate: QueryResolvers['inputTemplate'] = ({ id }) => { + return db.inputTemplate.findUnique({ + where: { id }, + }) +} + +export const createInputTemplate: MutationResolvers['createInputTemplate'] = ({ + input, +}) => { + return db.inputTemplate.create({ + data: input, + }) +} + +export const updateInputTemplate: MutationResolvers['updateInputTemplate'] = ({ + id, + input, +}) => { + return db.inputTemplate.update({ + data: input, + where: { id }, + }) +} + +export const deleteInputTemplate: MutationResolvers['deleteInputTemplate'] = ({ + id, +}) => { + return db.inputTemplate.delete({ + where: { id }, + }) +} + +export const InputTemplate: InputTemplateRelationResolvers = { + reportingPeriods: (_obj, { root }) => { + return db.inputTemplate + .findUnique({ where: { id: root?.id } }) + .reportingPeriods() + }, +} diff --git a/api/src/services/outputTemplates/outputTemplates.scenarios.ts b/api/src/services/outputTemplates/outputTemplates.scenarios.ts new file mode 100644 index 00000000..ac941191 --- /dev/null +++ b/api/src/services/outputTemplates/outputTemplates.scenarios.ts @@ -0,0 +1,27 @@ +import type { Prisma, OutputTemplate } from '@prisma/client' +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + outputTemplate: { + one: { + data: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:34.973Z', + rulesGeneratedAt: '2023-12-07T18:17:34.973Z', + updatedAt: '2023-12-07T18:17:34.973Z', + }, + }, + two: { + data: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:34.973Z', + rulesGeneratedAt: '2023-12-07T18:17:34.973Z', + updatedAt: '2023-12-07T18:17:34.973Z', + }, + }, + }, +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/services/outputTemplates/outputTemplates.test.ts b/api/src/services/outputTemplates/outputTemplates.test.ts new file mode 100644 index 00000000..62680e6a --- /dev/null +++ b/api/src/services/outputTemplates/outputTemplates.test.ts @@ -0,0 +1,79 @@ +import type { OutputTemplate } from '@prisma/client' + +import { + outputTemplates, + outputTemplate, + createOutputTemplate, + updateOutputTemplate, + deleteOutputTemplate, +} from './outputTemplates' +import type { StandardScenario } from './outputTemplates.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('outputTemplates', () => { + scenario( + 'returns all outputTemplates', + async (scenario: StandardScenario) => { + const result = await outputTemplates() + + expect(result.length).toEqual(Object.keys(scenario.outputTemplate).length) + } + ) + + scenario( + 'returns a single outputTemplate', + async (scenario: StandardScenario) => { + const result = await outputTemplate({ + id: scenario.outputTemplate.one.id, + }) + + expect(result).toEqual(scenario.outputTemplate.one) + } + ) + + scenario('creates a outputTemplate', async () => { + const result = await createOutputTemplate({ + input: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:17:34.958Z', + rulesGeneratedAt: '2023-12-07T18:17:34.958Z', + updatedAt: '2023-12-07T18:17:34.958Z', + }, + }) + + expect(result.name).toEqual('String') + expect(result.version).toEqual('String') + expect(result.effectiveDate).toEqual(new Date('2023-12-07T18:17:34.958Z')) + expect(result.rulesGeneratedAt).toEqual( + new Date('2023-12-07T18:17:34.958Z') + ) + expect(result.updatedAt).toEqual(new Date('2023-12-07T18:17:34.958Z')) + }) + + scenario('updates a outputTemplate', async (scenario: StandardScenario) => { + const original = (await outputTemplate({ + id: scenario.outputTemplate.one.id, + })) as OutputTemplate + const result = await updateOutputTemplate({ + id: original.id, + input: { name: 'String2' }, + }) + + expect(result.name).toEqual('String2') + }) + + scenario('deletes a outputTemplate', async (scenario: StandardScenario) => { + const original = (await deleteOutputTemplate({ + id: scenario.outputTemplate.one.id, + })) as OutputTemplate + const result = await outputTemplate({ id: original.id }) + + expect(result).toEqual(null) + }) +}) diff --git a/api/src/services/outputTemplates/outputTemplates.ts b/api/src/services/outputTemplates/outputTemplates.ts new file mode 100644 index 00000000..0a1a866b --- /dev/null +++ b/api/src/services/outputTemplates/outputTemplates.ts @@ -0,0 +1,47 @@ +import type { + QueryResolvers, + MutationResolvers, + OutputTemplateRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const outputTemplates: QueryResolvers['outputTemplates'] = () => { + return db.outputTemplate.findMany() +} + +export const outputTemplate: QueryResolvers['outputTemplate'] = ({ id }) => { + return db.outputTemplate.findUnique({ + where: { id }, + }) +} + +export const createOutputTemplate: MutationResolvers['createOutputTemplate'] = + ({ input }) => { + return db.outputTemplate.create({ + data: input, + }) + } + +export const updateOutputTemplate: MutationResolvers['updateOutputTemplate'] = + ({ id, input }) => { + return db.outputTemplate.update({ + data: input, + where: { id }, + }) + } + +export const deleteOutputTemplate: MutationResolvers['deleteOutputTemplate'] = + ({ id }) => { + return db.outputTemplate.delete({ + where: { id }, + }) + } + +export const OutputTemplate: OutputTemplateRelationResolvers = { + reportingPeriods: (_obj, { root }) => { + return db.outputTemplate + .findUnique({ where: { id: root?.id } }) + .reportingPeriods() + }, +} diff --git a/api/src/services/reportingPeriods/reportingPeriods.scenarios.ts b/api/src/services/reportingPeriods/reportingPeriods.scenarios.ts new file mode 100644 index 00000000..3a8df1aa --- /dev/null +++ b/api/src/services/reportingPeriods/reportingPeriods.scenarios.ts @@ -0,0 +1,57 @@ +import type { Prisma, ReportingPeriod } from '@prisma/client' +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + reportingPeriod: { + one: { + data: { + name: 'String', + startDate: '2023-12-07T18:38:12.356Z', + endDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + inputTemplate: { + create: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + }, + }, + outputTemplate: { + create: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + }, + }, + }, + }, + two: { + data: { + name: 'String', + startDate: '2023-12-07T18:38:12.356Z', + endDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + inputTemplate: { + create: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + }, + }, + outputTemplate: { + create: { + name: 'String', + version: 'String', + effectiveDate: '2023-12-07T18:38:12.356Z', + updatedAt: '2023-12-07T18:38:12.356Z', + }, + }, + }, + }, + }, +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/services/reportingPeriods/reportingPeriods.test.ts b/api/src/services/reportingPeriods/reportingPeriods.test.ts new file mode 100644 index 00000000..729d8071 --- /dev/null +++ b/api/src/services/reportingPeriods/reportingPeriods.test.ts @@ -0,0 +1,85 @@ +import type { ReportingPeriod } from '@prisma/client' + +import { + reportingPeriods, + reportingPeriod, + createReportingPeriod, + updateReportingPeriod, + deleteReportingPeriod, +} from './reportingPeriods' +import type { StandardScenario } from './reportingPeriods.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('reportingPeriods', () => { + scenario( + 'returns all reportingPeriods', + async (scenario: StandardScenario) => { + const result = await reportingPeriods() + + expect(result.length).toEqual( + Object.keys(scenario.reportingPeriod).length + ) + } + ) + + scenario( + 'returns a single reportingPeriod', + async (scenario: StandardScenario) => { + const result = await reportingPeriod({ + id: scenario.reportingPeriod.one.id, + }) + + expect(result).toEqual(scenario.reportingPeriod.one) + } + ) + + scenario('creates a reportingPeriod', async (scenario: StandardScenario) => { + const result = await createReportingPeriod({ + input: { + name: 'String', + startDate: '2023-12-07T18:38:12.341Z', + endDate: '2023-12-07T18:38:12.341Z', + inputTemplateId: scenario.reportingPeriod.two.inputTemplateId, + outputTemplateId: scenario.reportingPeriod.two.outputTemplateId, + updatedAt: '2023-12-07T18:38:12.341Z', + }, + }) + + expect(result.name).toEqual('String') + expect(result.startDate).toEqual(new Date('2023-12-07T18:38:12.341Z')) + expect(result.endDate).toEqual(new Date('2023-12-07T18:38:12.341Z')) + expect(result.inputTemplateId).toEqual( + scenario.reportingPeriod.two.inputTemplateId + ) + expect(result.outputTemplateId).toEqual( + scenario.reportingPeriod.two.outputTemplateId + ) + expect(result.updatedAt).toEqual(new Date('2023-12-07T18:38:12.341Z')) + }) + + scenario('updates a reportingPeriod', async (scenario: StandardScenario) => { + const original = (await reportingPeriod({ + id: scenario.reportingPeriod.one.id, + })) as ReportingPeriod + const result = await updateReportingPeriod({ + id: original.id, + input: { name: 'String2' }, + }) + + expect(result.name).toEqual('String2') + }) + + scenario('deletes a reportingPeriod', async (scenario: StandardScenario) => { + const original = (await deleteReportingPeriod({ + id: scenario.reportingPeriod.one.id, + })) as ReportingPeriod + const result = await reportingPeriod({ id: original.id }) + + expect(result).toEqual(null) + }) +}) diff --git a/api/src/services/reportingPeriods/reportingPeriods.ts b/api/src/services/reportingPeriods/reportingPeriods.ts new file mode 100644 index 00000000..4156493f --- /dev/null +++ b/api/src/services/reportingPeriods/reportingPeriods.ts @@ -0,0 +1,57 @@ +import type { + QueryResolvers, + MutationResolvers, + ReportingPeriodRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const reportingPeriods: QueryResolvers['reportingPeriods'] = () => { + return db.reportingPeriod.findMany() +} + +export const reportingPeriod: QueryResolvers['reportingPeriod'] = ({ id }) => { + return db.reportingPeriod.findUnique({ + where: { id }, + }) +} + +export const createReportingPeriod: MutationResolvers['createReportingPeriod'] = + ({ input }) => { + return db.reportingPeriod.create({ + data: input, + }) + } + +export const updateReportingPeriod: MutationResolvers['updateReportingPeriod'] = + ({ id, input }) => { + return db.reportingPeriod.update({ + data: input, + where: { id }, + }) + } + +export const deleteReportingPeriod: MutationResolvers['deleteReportingPeriod'] = + ({ id }) => { + return db.reportingPeriod.delete({ + where: { id }, + }) + } + +export const ReportingPeriod: ReportingPeriodRelationResolvers = { + certifiedBy: (_obj, { root }) => { + return db.reportingPeriod + .findUnique({ where: { id: root?.id } }) + .certifiedBy() + }, + inputTemplate: (_obj, { root }) => { + return db.reportingPeriod + .findUnique({ where: { id: root?.id } }) + .inputTemplate() + }, + outputTemplate: (_obj, { root }) => { + return db.reportingPeriod + .findUnique({ where: { id: root?.id } }) + .outputTemplate() + }, +} diff --git a/api/src/services/roles/roles.scenarios.ts b/api/src/services/roles/roles.scenarios.ts new file mode 100644 index 00000000..938e1d94 --- /dev/null +++ b/api/src/services/roles/roles.scenarios.ts @@ -0,0 +1,11 @@ +import type { Prisma, Role } from '@prisma/client' +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + role: { + one: { data: { name: 'String', updatedAt: '2023-12-07T18:20:00.186Z' } }, + two: { data: { name: 'String', updatedAt: '2023-12-07T18:20:00.186Z' } }, + }, +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/services/roles/roles.test.ts b/api/src/services/roles/roles.test.ts new file mode 100644 index 00000000..1cd39802 --- /dev/null +++ b/api/src/services/roles/roles.test.ts @@ -0,0 +1,50 @@ +import type { Role } from '@prisma/client' + +import { roles, role, createRole, updateRole, deleteRole } from './roles' +import type { StandardScenario } from './roles.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('roles', () => { + scenario('returns all roles', async (scenario: StandardScenario) => { + const result = await roles() + + expect(result.length).toEqual(Object.keys(scenario.role).length) + }) + + scenario('returns a single role', async (scenario: StandardScenario) => { + const result = await role({ id: scenario.role.one.id }) + + expect(result).toEqual(scenario.role.one) + }) + + scenario('creates a role', async () => { + const result = await createRole({ + input: { name: 'String', updatedAt: '2023-12-07T18:20:00.167Z' }, + }) + + expect(result.name).toEqual('String') + expect(result.updatedAt).toEqual(new Date('2023-12-07T18:20:00.167Z')) + }) + + scenario('updates a role', async (scenario: StandardScenario) => { + const original = (await role({ id: scenario.role.one.id })) as Role + const result = await updateRole({ + id: original.id, + input: { name: 'String2' }, + }) + + expect(result.name).toEqual('String2') + }) + + scenario('deletes a role', async (scenario: StandardScenario) => { + const original = (await deleteRole({ id: scenario.role.one.id })) as Role + const result = await role({ id: original.id }) + + expect(result).toEqual(null) + }) +}) diff --git a/api/src/services/roles/roles.ts b/api/src/services/roles/roles.ts new file mode 100644 index 00000000..ea2c29f8 --- /dev/null +++ b/api/src/services/roles/roles.ts @@ -0,0 +1,42 @@ +import type { + QueryResolvers, + MutationResolvers, + RoleRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const roles: QueryResolvers['roles'] = () => { + return db.role.findMany() +} + +export const role: QueryResolvers['role'] = ({ id }) => { + return db.role.findUnique({ + where: { id }, + }) +} + +export const createRole: MutationResolvers['createRole'] = ({ input }) => { + return db.role.create({ + data: input, + }) +} + +export const updateRole: MutationResolvers['updateRole'] = ({ id, input }) => { + return db.role.update({ + data: input, + where: { id }, + }) +} + +export const deleteRole: MutationResolvers['deleteRole'] = ({ id }) => { + return db.role.delete({ + where: { id }, + }) +} + +export const Role: RoleRelationResolvers = { + users: (_obj, { root }) => { + return db.role.findUnique({ where: { id: root?.id } }).users() + }, +} diff --git a/api/src/services/users/users.scenarios.ts b/api/src/services/users/users.scenarios.ts new file mode 100644 index 00000000..dc69a77a --- /dev/null +++ b/api/src/services/users/users.scenarios.ts @@ -0,0 +1,23 @@ +import type { Prisma, User } from '@prisma/client' +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + user: { + one: { + data: { + email: 'String', + updatedAt: '2023-12-07T18:20:20.679Z', + organization: { create: { name: 'String' } }, + }, + }, + two: { + data: { + email: 'String', + updatedAt: '2023-12-07T18:20:20.679Z', + organization: { create: { name: 'String' } }, + }, + }, + }, +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/services/users/users.test.ts b/api/src/services/users/users.test.ts new file mode 100644 index 00000000..db6e89e8 --- /dev/null +++ b/api/src/services/users/users.test.ts @@ -0,0 +1,55 @@ +import type { User } from '@prisma/client' + +import { users, user, createUser, updateUser, deleteUser } from './users' +import type { StandardScenario } from './users.scenarios' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-services +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('users', () => { + scenario('returns all users', async (scenario: StandardScenario) => { + const result = await users() + + expect(result.length).toEqual(Object.keys(scenario.user).length) + }) + + scenario('returns a single user', async (scenario: StandardScenario) => { + const result = await user({ id: scenario.user.one.id }) + + expect(result).toEqual(scenario.user.one) + }) + + scenario('creates a user', async (scenario: StandardScenario) => { + const result = await createUser({ + input: { + email: 'String', + organizationId: scenario.user.two.organizationId, + updatedAt: '2023-12-07T18:20:20.664Z', + }, + }) + + expect(result.email).toEqual('String') + expect(result.organizationId).toEqual(scenario.user.two.organizationId) + expect(result.updatedAt).toEqual(new Date('2023-12-07T18:20:20.664Z')) + }) + + scenario('updates a user', async (scenario: StandardScenario) => { + const original = (await user({ id: scenario.user.one.id })) as User + const result = await updateUser({ + id: original.id, + input: { email: 'String2' }, + }) + + expect(result.email).toEqual('String2') + }) + + scenario('deletes a user', async (scenario: StandardScenario) => { + const original = (await deleteUser({ id: scenario.user.one.id })) as User + const result = await user({ id: original.id }) + + expect(result).toEqual(null) + }) +}) diff --git a/api/src/services/users/users.ts b/api/src/services/users/users.ts new file mode 100644 index 00000000..55873686 --- /dev/null +++ b/api/src/services/users/users.ts @@ -0,0 +1,51 @@ +import type { + QueryResolvers, + MutationResolvers, + UserRelationResolvers, +} from 'types/graphql' + +import { db } from 'src/lib/db' + +export const users: QueryResolvers['users'] = () => { + return db.user.findMany() +} + +export const user: QueryResolvers['user'] = ({ id }) => { + return db.user.findUnique({ + where: { id }, + }) +} + +export const createUser: MutationResolvers['createUser'] = ({ input }) => { + return db.user.create({ + data: input, + }) +} + +export const updateUser: MutationResolvers['updateUser'] = ({ id, input }) => { + return db.user.update({ + data: input, + where: { id }, + }) +} + +export const deleteUser: MutationResolvers['deleteUser'] = ({ id }) => { + return db.user.delete({ + where: { id }, + }) +} + +export const User: UserRelationResolvers = { + agency: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).agency() + }, + organization: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).organization() + }, + role: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).role() + }, + certified: (_obj, { root }) => { + return db.user.findUnique({ where: { id: root?.id } }).certified() + }, +} diff --git a/api/types/graphql.d.ts b/api/types/graphql.d.ts index f2bbcefc..a5384bf9 100644 --- a/api/types/graphql.d.ts +++ b/api/types/graphql.d.ts @@ -1,6 +1,6 @@ import { Prisma } from "@prisma/client" import { MergePrismaWithSdlTypes, MakeRelationsOptional } from '@redwoodjs/api' -import { Agency as PrismaAgency, Organization as PrismaOrganization, User as PrismaUser, Role as PrismaRole } from '@prisma/client' +import { Agency as PrismaAgency, Organization as PrismaOrganization, User as PrismaUser, Role as PrismaRole, InputTemplate as PrismaInputTemplate, OutputTemplate as PrismaOutputTemplate, ReportingPeriod as PrismaReportingPeriod } from '@prisma/client' import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql'; import { RedwoodGraphQLContext } from '@redwoodjs/graphql-server/dist/types'; export type Maybe = T | null; @@ -52,18 +52,82 @@ export type CreateAgencyInput = { name: Scalars['String']; }; +export type CreateInputTemplateInput = { + effectiveDate: Scalars['DateTime']; + name: Scalars['String']; + rulesGeneratedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + export type CreateOrganizationInput = { name: Scalars['String']; }; +export type CreateOutputTemplateInput = { + effectiveDate: Scalars['DateTime']; + name: Scalars['String']; + rulesGeneratedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + +export type CreateReportingPeriodInput = { + certifiedAt?: InputMaybe; + certifiedById?: InputMaybe; + endDate: Scalars['DateTime']; + inputTemplateId: Scalars['Int']; + isCurrentPeriod: Scalars['Boolean']; + name: Scalars['String']; + outputTemplateId: Scalars['Int']; + startDate: Scalars['DateTime']; +}; + +export type CreateRoleInput = { + name: Scalars['String']; +}; + +export type CreateUserInput = { + agencyId?: InputMaybe; + email: Scalars['String']; + name?: InputMaybe; + organizationId: Scalars['Int']; + roleId?: InputMaybe; +}; + +export type InputTemplate = { + __typename?: 'InputTemplate'; + createdAt: Scalars['DateTime']; + effectiveDate: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + reportingPeriods: Array>; + rulesGeneratedAt: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + export type Mutation = { __typename?: 'Mutation'; createAgency: Agency; + createInputTemplate: InputTemplate; createOrganization: Organization; + createOutputTemplate: OutputTemplate; + createReportingPeriod: ReportingPeriod; + createRole: Role; + createUser: User; deleteAgency: Agency; + deleteInputTemplate: InputTemplate; deleteOrganization: Organization; + deleteOutputTemplate: OutputTemplate; + deleteReportingPeriod: ReportingPeriod; + deleteRole: Role; + deleteUser: User; updateAgency: Agency; + updateInputTemplate: InputTemplate; updateOrganization: Organization; + updateOutputTemplate: OutputTemplate; + updateReportingPeriod: ReportingPeriod; + updateRole: Role; + updateUser: User; }; @@ -72,32 +136,112 @@ export type MutationcreateAgencyArgs = { }; +export type MutationcreateInputTemplateArgs = { + input: CreateInputTemplateInput; +}; + + export type MutationcreateOrganizationArgs = { input: CreateOrganizationInput; }; +export type MutationcreateOutputTemplateArgs = { + input: CreateOutputTemplateInput; +}; + + +export type MutationcreateReportingPeriodArgs = { + input: CreateReportingPeriodInput; +}; + + +export type MutationcreateRoleArgs = { + input: CreateRoleInput; +}; + + +export type MutationcreateUserArgs = { + input: CreateUserInput; +}; + + export type MutationdeleteAgencyArgs = { id: Scalars['Int']; }; +export type MutationdeleteInputTemplateArgs = { + id: Scalars['Int']; +}; + + export type MutationdeleteOrganizationArgs = { id: Scalars['Int']; }; +export type MutationdeleteOutputTemplateArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteReportingPeriodArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteRoleArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteUserArgs = { + id: Scalars['Int']; +}; + + export type MutationupdateAgencyArgs = { id: Scalars['Int']; input: UpdateAgencyInput; }; +export type MutationupdateInputTemplateArgs = { + id: Scalars['Int']; + input: UpdateInputTemplateInput; +}; + + export type MutationupdateOrganizationArgs = { id: Scalars['Int']; input: UpdateOrganizationInput; }; + +export type MutationupdateOutputTemplateArgs = { + id: Scalars['Int']; + input: UpdateOutputTemplateInput; +}; + + +export type MutationupdateReportingPeriodArgs = { + id: Scalars['Int']; + input: UpdateReportingPeriodInput; +}; + + +export type MutationupdateRoleArgs = { + id: Scalars['Int']; + input: UpdateRoleInput; +}; + + +export type MutationupdateUserArgs = { + id: Scalars['Int']; + input: UpdateUserInput; +}; + export type Organization = { __typename?: 'Organization'; agencies: Array>; @@ -105,16 +249,38 @@ export type Organization = { name: Scalars['String']; }; +export type OutputTemplate = { + __typename?: 'OutputTemplate'; + createdAt: Scalars['DateTime']; + effectiveDate: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + reportingPeriods: Array>; + rulesGeneratedAt: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + /** About the Redwood queries. */ export type Query = { __typename?: 'Query'; agencies: Array; agenciesByOrganization: Array; agency?: Maybe; + inputTemplate?: Maybe; + inputTemplates: Array; organization?: Maybe; organizations: Array; + outputTemplate?: Maybe; + outputTemplates: Array; /** Fetches the Redwood root schema. */ redwood?: Maybe; + reportingPeriod?: Maybe; + reportingPeriods: Array; + role?: Maybe; + roles: Array; + user?: Maybe; + users: Array; }; @@ -130,11 +296,41 @@ export type QueryagencyArgs = { }; +/** About the Redwood queries. */ +export type QueryinputTemplateArgs = { + id: Scalars['Int']; +}; + + /** About the Redwood queries. */ export type QueryorganizationArgs = { id: Scalars['Int']; }; + +/** About the Redwood queries. */ +export type QueryoutputTemplateArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryreportingPeriodArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryroleArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryuserArgs = { + id: Scalars['Int']; +}; + /** * The RedwoodJS Root Schema * @@ -150,18 +346,98 @@ export type Redwood = { version?: Maybe; }; +export type ReportingPeriod = { + __typename?: 'ReportingPeriod'; + certifiedAt?: Maybe; + certifiedBy?: Maybe; + certifiedById?: Maybe; + createdAt: Scalars['DateTime']; + endDate: Scalars['DateTime']; + id: Scalars['Int']; + inputTemplate: InputTemplate; + inputTemplateId: Scalars['Int']; + isCurrentPeriod: Scalars['Boolean']; + name: Scalars['String']; + outputTemplate: OutputTemplate; + outputTemplateId: Scalars['Int']; + startDate: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; +}; + +export type Role = { + __typename?: 'Role'; + createdAt: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + updatedAt: Scalars['DateTime']; + users: Array>; +}; + export type UpdateAgencyInput = { abbreviation?: InputMaybe; code?: InputMaybe; name?: InputMaybe; }; +export type UpdateInputTemplateInput = { + effectiveDate?: InputMaybe; + name?: InputMaybe; + rulesGeneratedAt?: InputMaybe; + version?: InputMaybe; +}; + export type UpdateOrganizationInput = { name?: InputMaybe; }; +export type UpdateOutputTemplateInput = { + effectiveDate?: InputMaybe; + name?: InputMaybe; + rulesGeneratedAt?: InputMaybe; + version?: InputMaybe; +}; + +export type UpdateReportingPeriodInput = { + certifiedAt?: InputMaybe; + certifiedById?: InputMaybe; + endDate?: InputMaybe; + inputTemplateId?: InputMaybe; + isCurrentPeriod?: InputMaybe; + name?: InputMaybe; + outputTemplateId?: InputMaybe; + startDate?: InputMaybe; +}; + +export type UpdateRoleInput = { + name?: InputMaybe; +}; + +export type UpdateUserInput = { + agencyId?: InputMaybe; + email?: InputMaybe; + name?: InputMaybe; + organizationId?: InputMaybe; + roleId?: InputMaybe; +}; + +export type User = { + __typename?: 'User'; + agency?: Maybe; + agencyId?: Maybe; + certified: Array>; + createdAt: Scalars['DateTime']; + email: Scalars['String']; + id: Scalars['Int']; + name?: Maybe; + organization: Organization; + organizationId: Scalars['Int']; + role?: Maybe; + roleId?: Maybe; + updatedAt: Scalars['DateTime']; +}; + type MaybeOrArrayOfMaybe = T | Maybe | Maybe[]; -type AllMappedModels = MaybeOrArrayOfMaybe +type AllMappedModels = MaybeOrArrayOfMaybe export type ResolverTypeWrapper = Promise | T; @@ -226,20 +502,35 @@ export type ResolversTypes = { BigInt: ResolverTypeWrapper; Boolean: ResolverTypeWrapper; CreateAgencyInput: CreateAgencyInput; + CreateInputTemplateInput: CreateInputTemplateInput; CreateOrganizationInput: CreateOrganizationInput; + CreateOutputTemplateInput: CreateOutputTemplateInput; + CreateReportingPeriodInput: CreateReportingPeriodInput; + CreateRoleInput: CreateRoleInput; + CreateUserInput: CreateUserInput; Date: ResolverTypeWrapper; DateTime: ResolverTypeWrapper; + InputTemplate: ResolverTypeWrapper, AllMappedModels>>; Int: ResolverTypeWrapper; JSON: ResolverTypeWrapper; JSONObject: ResolverTypeWrapper; Mutation: ResolverTypeWrapper<{}>; Organization: ResolverTypeWrapper, AllMappedModels>>; + OutputTemplate: ResolverTypeWrapper, AllMappedModels>>; Query: ResolverTypeWrapper<{}>; Redwood: ResolverTypeWrapper; + ReportingPeriod: ResolverTypeWrapper, AllMappedModels>>; + Role: ResolverTypeWrapper, AllMappedModels>>; String: ResolverTypeWrapper; Time: ResolverTypeWrapper; UpdateAgencyInput: UpdateAgencyInput; + UpdateInputTemplateInput: UpdateInputTemplateInput; UpdateOrganizationInput: UpdateOrganizationInput; + UpdateOutputTemplateInput: UpdateOutputTemplateInput; + UpdateReportingPeriodInput: UpdateReportingPeriodInput; + UpdateRoleInput: UpdateRoleInput; + UpdateUserInput: UpdateUserInput; + User: ResolverTypeWrapper, AllMappedModels>>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -248,20 +539,35 @@ export type ResolversParentTypes = { BigInt: Scalars['BigInt']; Boolean: Scalars['Boolean']; CreateAgencyInput: CreateAgencyInput; + CreateInputTemplateInput: CreateInputTemplateInput; CreateOrganizationInput: CreateOrganizationInput; + CreateOutputTemplateInput: CreateOutputTemplateInput; + CreateReportingPeriodInput: CreateReportingPeriodInput; + CreateRoleInput: CreateRoleInput; + CreateUserInput: CreateUserInput; Date: Scalars['Date']; DateTime: Scalars['DateTime']; + InputTemplate: MergePrismaWithSdlTypes, AllMappedModels>; Int: Scalars['Int']; JSON: Scalars['JSON']; JSONObject: Scalars['JSONObject']; Mutation: {}; Organization: MergePrismaWithSdlTypes, AllMappedModels>; + OutputTemplate: MergePrismaWithSdlTypes, AllMappedModels>; Query: {}; Redwood: Redwood; + ReportingPeriod: MergePrismaWithSdlTypes, AllMappedModels>; + Role: MergePrismaWithSdlTypes, AllMappedModels>; String: Scalars['String']; Time: Scalars['Time']; UpdateAgencyInput: UpdateAgencyInput; + UpdateInputTemplateInput: UpdateInputTemplateInput; UpdateOrganizationInput: UpdateOrganizationInput; + UpdateOutputTemplateInput: UpdateOutputTemplateInput; + UpdateReportingPeriodInput: UpdateReportingPeriodInput; + UpdateRoleInput: UpdateRoleInput; + UpdateUserInput: UpdateUserInput; + User: MergePrismaWithSdlTypes, AllMappedModels>; }; export type requireAuthDirectiveArgs = { @@ -304,6 +610,30 @@ export interface DateTimeScalarConfig extends GraphQLScalarTypeConfig = { + createdAt: OptArgsResolverFn; + effectiveDate: OptArgsResolverFn; + id: OptArgsResolverFn; + name: OptArgsResolverFn; + reportingPeriods: OptArgsResolverFn>, ParentType, ContextType>; + rulesGeneratedAt: OptArgsResolverFn; + updatedAt: OptArgsResolverFn; + version: OptArgsResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type InputTemplateRelationResolvers = { + createdAt?: RequiredResolverFn; + effectiveDate?: RequiredResolverFn; + id?: RequiredResolverFn; + name?: RequiredResolverFn; + reportingPeriods?: RequiredResolverFn>, ParentType, ContextType>; + rulesGeneratedAt?: RequiredResolverFn; + updatedAt?: RequiredResolverFn; + version?: RequiredResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface JSONScalarConfig extends GraphQLScalarTypeConfig { name: 'JSON'; } @@ -314,20 +644,50 @@ export interface JSONObjectScalarConfig extends GraphQLScalarTypeConfig = { createAgency: Resolver>; + createInputTemplate: Resolver>; createOrganization: Resolver>; + createOutputTemplate: Resolver>; + createReportingPeriod: Resolver>; + createRole: Resolver>; + createUser: Resolver>; deleteAgency: Resolver>; + deleteInputTemplate: Resolver>; deleteOrganization: Resolver>; + deleteOutputTemplate: Resolver>; + deleteReportingPeriod: Resolver>; + deleteRole: Resolver>; + deleteUser: Resolver>; updateAgency: Resolver>; + updateInputTemplate: Resolver>; updateOrganization: Resolver>; + updateOutputTemplate: Resolver>; + updateReportingPeriod: Resolver>; + updateRole: Resolver>; + updateUser: Resolver>; }; export type MutationRelationResolvers = { createAgency?: RequiredResolverFn>; + createInputTemplate?: RequiredResolverFn>; createOrganization?: RequiredResolverFn>; + createOutputTemplate?: RequiredResolverFn>; + createReportingPeriod?: RequiredResolverFn>; + createRole?: RequiredResolverFn>; + createUser?: RequiredResolverFn>; deleteAgency?: RequiredResolverFn>; + deleteInputTemplate?: RequiredResolverFn>; deleteOrganization?: RequiredResolverFn>; + deleteOutputTemplate?: RequiredResolverFn>; + deleteReportingPeriod?: RequiredResolverFn>; + deleteRole?: RequiredResolverFn>; + deleteUser?: RequiredResolverFn>; updateAgency?: RequiredResolverFn>; + updateInputTemplate?: RequiredResolverFn>; updateOrganization?: RequiredResolverFn>; + updateOutputTemplate?: RequiredResolverFn>; + updateReportingPeriod?: RequiredResolverFn>; + updateRole?: RequiredResolverFn>; + updateUser?: RequiredResolverFn>; }; export type OrganizationResolvers = { @@ -344,22 +704,66 @@ export type OrganizationRelationResolvers; }; +export type OutputTemplateResolvers = { + createdAt: OptArgsResolverFn; + effectiveDate: OptArgsResolverFn; + id: OptArgsResolverFn; + name: OptArgsResolverFn; + reportingPeriods: OptArgsResolverFn>, ParentType, ContextType>; + rulesGeneratedAt: OptArgsResolverFn; + updatedAt: OptArgsResolverFn; + version: OptArgsResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type OutputTemplateRelationResolvers = { + createdAt?: RequiredResolverFn; + effectiveDate?: RequiredResolverFn; + id?: RequiredResolverFn; + name?: RequiredResolverFn; + reportingPeriods?: RequiredResolverFn>, ParentType, ContextType>; + rulesGeneratedAt?: RequiredResolverFn; + updatedAt?: RequiredResolverFn; + version?: RequiredResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type QueryResolvers = { agencies: OptArgsResolverFn, ParentType, ContextType>; agenciesByOrganization: Resolver, ParentType, ContextType, RequireFields>; agency: Resolver, ParentType, ContextType, RequireFields>; + inputTemplate: Resolver, ParentType, ContextType, RequireFields>; + inputTemplates: OptArgsResolverFn, ParentType, ContextType>; organization: Resolver, ParentType, ContextType, RequireFields>; organizations: OptArgsResolverFn, ParentType, ContextType>; + outputTemplate: Resolver, ParentType, ContextType, RequireFields>; + outputTemplates: OptArgsResolverFn, ParentType, ContextType>; redwood: OptArgsResolverFn, ParentType, ContextType>; + reportingPeriod: Resolver, ParentType, ContextType, RequireFields>; + reportingPeriods: OptArgsResolverFn, ParentType, ContextType>; + role: Resolver, ParentType, ContextType, RequireFields>; + roles: OptArgsResolverFn, ParentType, ContextType>; + user: Resolver, ParentType, ContextType, RequireFields>; + users: OptArgsResolverFn, ParentType, ContextType>; }; export type QueryRelationResolvers = { agencies?: RequiredResolverFn, ParentType, ContextType>; agenciesByOrganization?: RequiredResolverFn, ParentType, ContextType, RequireFields>; agency?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + inputTemplate?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + inputTemplates?: RequiredResolverFn, ParentType, ContextType>; organization?: RequiredResolverFn, ParentType, ContextType, RequireFields>; organizations?: RequiredResolverFn, ParentType, ContextType>; + outputTemplate?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + outputTemplates?: RequiredResolverFn, ParentType, ContextType>; redwood?: RequiredResolverFn, ParentType, ContextType>; + reportingPeriod?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + reportingPeriods?: RequiredResolverFn, ParentType, ContextType>; + role?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + roles?: RequiredResolverFn, ParentType, ContextType>; + user?: RequiredResolverFn, ParentType, ContextType, RequireFields>; + users?: RequiredResolverFn, ParentType, ContextType>; }; export type RedwoodResolvers = { @@ -376,22 +780,113 @@ export type RedwoodRelationResolvers; }; +export type ReportingPeriodResolvers = { + certifiedAt: OptArgsResolverFn, ParentType, ContextType>; + certifiedBy: OptArgsResolverFn, ParentType, ContextType>; + certifiedById: OptArgsResolverFn, ParentType, ContextType>; + createdAt: OptArgsResolverFn; + endDate: OptArgsResolverFn; + id: OptArgsResolverFn; + inputTemplate: OptArgsResolverFn; + inputTemplateId: OptArgsResolverFn; + isCurrentPeriod: OptArgsResolverFn; + name: OptArgsResolverFn; + outputTemplate: OptArgsResolverFn; + outputTemplateId: OptArgsResolverFn; + startDate: OptArgsResolverFn; + updatedAt: OptArgsResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type ReportingPeriodRelationResolvers = { + certifiedAt?: RequiredResolverFn, ParentType, ContextType>; + certifiedBy?: RequiredResolverFn, ParentType, ContextType>; + certifiedById?: RequiredResolverFn, ParentType, ContextType>; + createdAt?: RequiredResolverFn; + endDate?: RequiredResolverFn; + id?: RequiredResolverFn; + inputTemplate?: RequiredResolverFn; + inputTemplateId?: RequiredResolverFn; + isCurrentPeriod?: RequiredResolverFn; + name?: RequiredResolverFn; + outputTemplate?: RequiredResolverFn; + outputTemplateId?: RequiredResolverFn; + startDate?: RequiredResolverFn; + updatedAt?: RequiredResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type RoleResolvers = { + createdAt: OptArgsResolverFn; + id: OptArgsResolverFn; + name: OptArgsResolverFn; + updatedAt: OptArgsResolverFn; + users: OptArgsResolverFn>, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type RoleRelationResolvers = { + createdAt?: RequiredResolverFn; + id?: RequiredResolverFn; + name?: RequiredResolverFn; + updatedAt?: RequiredResolverFn; + users?: RequiredResolverFn>, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}; + export interface TimeScalarConfig extends GraphQLScalarTypeConfig { name: 'Time'; } +export type UserResolvers = { + agency: OptArgsResolverFn, ParentType, ContextType>; + agencyId: OptArgsResolverFn, ParentType, ContextType>; + certified: OptArgsResolverFn>, ParentType, ContextType>; + createdAt: OptArgsResolverFn; + email: OptArgsResolverFn; + id: OptArgsResolverFn; + name: OptArgsResolverFn, ParentType, ContextType>; + organization: OptArgsResolverFn; + organizationId: OptArgsResolverFn; + role: OptArgsResolverFn, ParentType, ContextType>; + roleId: OptArgsResolverFn, ParentType, ContextType>; + updatedAt: OptArgsResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + +export type UserRelationResolvers = { + agency?: RequiredResolverFn, ParentType, ContextType>; + agencyId?: RequiredResolverFn, ParentType, ContextType>; + certified?: RequiredResolverFn>, ParentType, ContextType>; + createdAt?: RequiredResolverFn; + email?: RequiredResolverFn; + id?: RequiredResolverFn; + name?: RequiredResolverFn, ParentType, ContextType>; + organization?: RequiredResolverFn; + organizationId?: RequiredResolverFn; + role?: RequiredResolverFn, ParentType, ContextType>; + roleId?: RequiredResolverFn, ParentType, ContextType>; + updatedAt?: RequiredResolverFn; + __isTypeOf?: IsTypeOfResolverFn; +}; + export type Resolvers = { Agency: AgencyResolvers; BigInt: GraphQLScalarType; Date: GraphQLScalarType; DateTime: GraphQLScalarType; + InputTemplate: InputTemplateResolvers; JSON: GraphQLScalarType; JSONObject: GraphQLScalarType; Mutation: MutationResolvers; Organization: OrganizationResolvers; + OutputTemplate: OutputTemplateResolvers; Query: QueryResolvers; Redwood: RedwoodResolvers; + ReportingPeriod: ReportingPeriodResolvers; + Role: RoleResolvers; Time: GraphQLScalarType; + User: UserResolvers; }; export type DirectiveResolvers = { diff --git a/web/src/Routes.tsx b/web/src/Routes.tsx index 2aa4d0df..e03570e8 100644 --- a/web/src/Routes.tsx +++ b/web/src/Routes.tsx @@ -29,6 +29,8 @@ const Routes = () => { + + diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts new file mode 100644 index 00000000..f7b26eb3 --- /dev/null +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts @@ -0,0 +1,6 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + reportingPeriod: { + id: 42, + }, +}) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.stories.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.stories.tsx new file mode 100644 index 00000000..fdacd37a --- /dev/null +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Empty, Failure, Success } from './ReportingPeriodCell' +import { standard } from './ReportingPeriodCell.mock' + +const meta: Meta = { + title: 'Cells/ReportingPeriodCell', +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const empty: StoryObj = { + render: () => { + return Empty ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx new file mode 100644 index 00000000..369fa8cd --- /dev/null +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx @@ -0,0 +1,41 @@ +import { render } from '@redwoodjs/testing/web' +import { Loading, Empty, Failure, Success } from './ReportingPeriodCell' +import { standard } from './ReportingPeriodCell.mock' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float and DateTime types. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-cells +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('ReportingPeriodCell', () => { + it('renders Loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + + it('renders Empty successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) + + it('renders Failure successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) + + // When you're ready to test the actual output of your component render + // you could test that, for example, certain text is present: + // + // 1. import { screen } from '@redwoodjs/testing/web' + // 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument() + + it('renders Success successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx new file mode 100644 index 00000000..116350c7 --- /dev/null +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx @@ -0,0 +1,34 @@ +import type { + FindReportingPeriodQuery, + FindReportingPeriodQueryVariables, +} from 'types/graphql' + +import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web' + +export const QUERY = gql` + query FindReportingPeriodQuery($id: Int!) { + reportingPeriod: reportingPeriod(id: $id) { + id + name + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () =>
Empty
+ +export const Failure = ({ + error, +}: CellFailureProps) => ( +
Error: {error?.message}
+) + +export const Success = ({ + reportingPeriod, +}: CellSuccessProps< + FindReportingPeriodQuery, + FindReportingPeriodQueryVariables +>) => { + return {reportingPeriod.name} +} diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.mock.ts b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.mock.ts new file mode 100644 index 00000000..4f4c5a8a --- /dev/null +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.mock.ts @@ -0,0 +1,4 @@ +// Define your own mock data here: +export const standard = (/* vars, { ctx, req } */) => ({ + reportingPeriods: [{ id: 42 }, { id: 43 }, { id: 44 }], +}) diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.stories.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.stories.tsx new file mode 100644 index 00000000..d3f59a9b --- /dev/null +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import { Loading, Empty, Failure, Success } from './ReportingPeriodsCell' +import { standard } from './ReportingPeriodsCell.mock' + +const meta: Meta = { + title: 'Cells/ReportingPeriodsCell', +} + +export default meta + +export const loading: StoryObj = { + render: () => { + return Loading ? : <> + }, +} + +export const empty: StoryObj = { + render: () => { + return Empty ? : <> + }, +} + +export const failure: StoryObj = { + render: (args) => { + return Failure ? : <> + }, +} + +export const success: StoryObj = { + render: (args) => { + return Success ? : <> + }, +} diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx new file mode 100644 index 00000000..547f0c07 --- /dev/null +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx @@ -0,0 +1,41 @@ +import { render } from '@redwoodjs/testing/web' +import { Loading, Empty, Failure, Success } from './ReportingPeriodsCell' +import { standard } from './ReportingPeriodsCell.mock' + +// Generated boilerplate tests do not account for all circumstances +// and can fail without adjustments, e.g. Float and DateTime types. +// Please refer to the RedwoodJS Testing Docs: +// https://redwoodjs.com/docs/testing#testing-cells +// https://redwoodjs.com/docs/testing#jest-expect-type-considerations + +describe('ReportingPeriodsCell', () => { + it('renders Loading successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) + + it('renders Empty successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) + + it('renders Failure successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) + + // When you're ready to test the actual output of your component render + // you could test that, for example, certain text is present: + // + // 1. import { screen } from '@redwoodjs/testing/web' + // 2. Add test: expect(screen.getByText('Hello, world')).toBeInTheDocument() + + it('renders Success successfully', async () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx new file mode 100644 index 00000000..3cc5ec5e --- /dev/null +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx @@ -0,0 +1,78 @@ +import type { ReportingPeriodsQuery } from 'types/graphql' + +import { Link, routes } from '@redwoodjs/router' +import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web' + +export const QUERY = gql` + query ReportingPeriodsQuery { + reportingPeriods { + id + startDate + endDate + isCurrentPeriod + certifiedAt + certifiedBy { + email + } + inputTemplate { + name + } + } + } +` + +export const Loading = () =>
Loading...
+ +export const Empty = () =>
Empty
+ +export const Failure = ({ error }: CellFailureProps) => ( +
Error: {error?.message}
+) + +export const Success = ({ + reportingPeriods, +}: CellSuccessProps) => { + return ( + + + + + + + + + + + {reportingPeriods.map((item) => { + return ( + + + + + + + ) + })} +
Start DateEnd DateTemplateCertified At
{item.startDate}{item.endDate} + {item.inputTemplate.name} + {!item.certifiedAt && ( + + {' '} + + Upload Template + + + )} + + {item.isCurrentPeriod ? ( + + ) : ( + item.certifiedAt && ( + + {item.certifiedAt} by {item.certifiedBy} + + ) + )} +
+ ) +} diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.stories.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.stories.tsx new file mode 100644 index 00000000..e2dce403 --- /dev/null +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import ReportingPeriodsPage from './ReportingPeriodsPage' + +const meta: Meta = { + component: ReportingPeriodsPage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx new file mode 100644 index 00000000..66c06ad1 --- /dev/null +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import ReportingPeriodsPage from './ReportingPeriodsPage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('ReportingPeriodsPage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx new file mode 100644 index 00000000..187239fd --- /dev/null +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx @@ -0,0 +1,16 @@ +import { MetaTags } from '@redwoodjs/web' + +import ReportingPeriodsCell from 'src/components/ReportingPeriodsCell' + +const ReportingPeriodsPage = () => { + return ( + <> + + +

Reporting Periods

+ + + ) +} + +export default ReportingPeriodsPage diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.stories.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.stories.tsx new file mode 100644 index 00000000..0e52cbfe --- /dev/null +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.stories.tsx @@ -0,0 +1,13 @@ +import type { Meta, StoryObj } from '@storybook/react' + +import UploadTemplatePage from './UploadTemplatePage' + +const meta: Meta = { + component: UploadTemplatePage, +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx new file mode 100644 index 00000000..44850821 --- /dev/null +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx @@ -0,0 +1,14 @@ +import { render } from '@redwoodjs/testing/web' + +import UploadTemplatePage from './UploadTemplatePage' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-pages-layouts + +describe('UploadTemplatePage', () => { + it('renders successfully', () => { + expect(() => { + render() + }).not.toThrow() + }) +}) diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx new file mode 100644 index 00000000..312c18cb --- /dev/null +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx @@ -0,0 +1,38 @@ +import { Form, FileField, HiddenField, Submit } from '@redwoodjs/forms' +import { Link, routes } from '@redwoodjs/router' +import { MetaTags } from '@redwoodjs/web' + +import ReportingPeriodCell from 'src/components/ReportingPeriodCell' + +const UploadTemplatePage = ({ id }) => { + const onSubmit = (data) => { + console.log(data) + } + + return ( + <> + + +

Upload Period Template

+

+ This upload will be used as the template for period{' '} + +

+
+ + + Upload + +

+ Find me in{' '} + ./web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx +

+

+ My default route is named uploadTemplate, link to me with ` + UploadTemplate` +

+ + ) +} + +export default UploadTemplatePage diff --git a/web/types/graphql.d.ts b/web/types/graphql.d.ts index eb4eb5fb..0520f946 100644 --- a/web/types/graphql.d.ts +++ b/web/types/graphql.d.ts @@ -34,18 +34,82 @@ export type CreateAgencyInput = { name: Scalars['String']; }; +export type CreateInputTemplateInput = { + effectiveDate: Scalars['DateTime']; + name: Scalars['String']; + rulesGeneratedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + export type CreateOrganizationInput = { name: Scalars['String']; }; +export type CreateOutputTemplateInput = { + effectiveDate: Scalars['DateTime']; + name: Scalars['String']; + rulesGeneratedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + +export type CreateReportingPeriodInput = { + certifiedAt?: InputMaybe; + certifiedById?: InputMaybe; + endDate: Scalars['DateTime']; + inputTemplateId: Scalars['Int']; + isCurrentPeriod: Scalars['Boolean']; + name: Scalars['String']; + outputTemplateId: Scalars['Int']; + startDate: Scalars['DateTime']; +}; + +export type CreateRoleInput = { + name: Scalars['String']; +}; + +export type CreateUserInput = { + agencyId?: InputMaybe; + email: Scalars['String']; + name?: InputMaybe; + organizationId: Scalars['Int']; + roleId?: InputMaybe; +}; + +export type InputTemplate = { + __typename?: 'InputTemplate'; + createdAt: Scalars['DateTime']; + effectiveDate: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + reportingPeriods: Array>; + rulesGeneratedAt: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + export type Mutation = { __typename?: 'Mutation'; createAgency: Agency; + createInputTemplate: InputTemplate; createOrganization: Organization; + createOutputTemplate: OutputTemplate; + createReportingPeriod: ReportingPeriod; + createRole: Role; + createUser: User; deleteAgency: Agency; + deleteInputTemplate: InputTemplate; deleteOrganization: Organization; + deleteOutputTemplate: OutputTemplate; + deleteReportingPeriod: ReportingPeriod; + deleteRole: Role; + deleteUser: User; updateAgency: Agency; + updateInputTemplate: InputTemplate; updateOrganization: Organization; + updateOutputTemplate: OutputTemplate; + updateReportingPeriod: ReportingPeriod; + updateRole: Role; + updateUser: User; }; @@ -54,32 +118,112 @@ export type MutationcreateAgencyArgs = { }; +export type MutationcreateInputTemplateArgs = { + input: CreateInputTemplateInput; +}; + + export type MutationcreateOrganizationArgs = { input: CreateOrganizationInput; }; +export type MutationcreateOutputTemplateArgs = { + input: CreateOutputTemplateInput; +}; + + +export type MutationcreateReportingPeriodArgs = { + input: CreateReportingPeriodInput; +}; + + +export type MutationcreateRoleArgs = { + input: CreateRoleInput; +}; + + +export type MutationcreateUserArgs = { + input: CreateUserInput; +}; + + export type MutationdeleteAgencyArgs = { id: Scalars['Int']; }; +export type MutationdeleteInputTemplateArgs = { + id: Scalars['Int']; +}; + + export type MutationdeleteOrganizationArgs = { id: Scalars['Int']; }; +export type MutationdeleteOutputTemplateArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteReportingPeriodArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteRoleArgs = { + id: Scalars['Int']; +}; + + +export type MutationdeleteUserArgs = { + id: Scalars['Int']; +}; + + export type MutationupdateAgencyArgs = { id: Scalars['Int']; input: UpdateAgencyInput; }; +export type MutationupdateInputTemplateArgs = { + id: Scalars['Int']; + input: UpdateInputTemplateInput; +}; + + export type MutationupdateOrganizationArgs = { id: Scalars['Int']; input: UpdateOrganizationInput; }; + +export type MutationupdateOutputTemplateArgs = { + id: Scalars['Int']; + input: UpdateOutputTemplateInput; +}; + + +export type MutationupdateReportingPeriodArgs = { + id: Scalars['Int']; + input: UpdateReportingPeriodInput; +}; + + +export type MutationupdateRoleArgs = { + id: Scalars['Int']; + input: UpdateRoleInput; +}; + + +export type MutationupdateUserArgs = { + id: Scalars['Int']; + input: UpdateUserInput; +}; + export type Organization = { __typename?: 'Organization'; agencies: Array>; @@ -87,16 +231,38 @@ export type Organization = { name: Scalars['String']; }; +export type OutputTemplate = { + __typename?: 'OutputTemplate'; + createdAt: Scalars['DateTime']; + effectiveDate: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + reportingPeriods: Array>; + rulesGeneratedAt: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; + version: Scalars['String']; +}; + /** About the Redwood queries. */ export type Query = { __typename?: 'Query'; agencies: Array; agenciesByOrganization: Array; agency?: Maybe; + inputTemplate?: Maybe; + inputTemplates: Array; organization?: Maybe; organizations: Array; + outputTemplate?: Maybe; + outputTemplates: Array; /** Fetches the Redwood root schema. */ redwood?: Maybe; + reportingPeriod?: Maybe; + reportingPeriods: Array; + role?: Maybe; + roles: Array; + user?: Maybe; + users: Array; }; @@ -112,11 +278,41 @@ export type QueryagencyArgs = { }; +/** About the Redwood queries. */ +export type QueryinputTemplateArgs = { + id: Scalars['Int']; +}; + + /** About the Redwood queries. */ export type QueryorganizationArgs = { id: Scalars['Int']; }; + +/** About the Redwood queries. */ +export type QueryoutputTemplateArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryreportingPeriodArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryroleArgs = { + id: Scalars['Int']; +}; + + +/** About the Redwood queries. */ +export type QueryuserArgs = { + id: Scalars['Int']; +}; + /** * The RedwoodJS Root Schema * @@ -132,16 +328,96 @@ export type Redwood = { version?: Maybe; }; +export type ReportingPeriod = { + __typename?: 'ReportingPeriod'; + certifiedAt?: Maybe; + certifiedBy?: Maybe; + certifiedById?: Maybe; + createdAt: Scalars['DateTime']; + endDate: Scalars['DateTime']; + id: Scalars['Int']; + inputTemplate: InputTemplate; + inputTemplateId: Scalars['Int']; + isCurrentPeriod: Scalars['Boolean']; + name: Scalars['String']; + outputTemplate: OutputTemplate; + outputTemplateId: Scalars['Int']; + startDate: Scalars['DateTime']; + updatedAt: Scalars['DateTime']; +}; + +export type Role = { + __typename?: 'Role'; + createdAt: Scalars['DateTime']; + id: Scalars['Int']; + name: Scalars['String']; + updatedAt: Scalars['DateTime']; + users: Array>; +}; + export type UpdateAgencyInput = { abbreviation?: InputMaybe; code?: InputMaybe; name?: InputMaybe; }; +export type UpdateInputTemplateInput = { + effectiveDate?: InputMaybe; + name?: InputMaybe; + rulesGeneratedAt?: InputMaybe; + version?: InputMaybe; +}; + export type UpdateOrganizationInput = { name?: InputMaybe; }; +export type UpdateOutputTemplateInput = { + effectiveDate?: InputMaybe; + name?: InputMaybe; + rulesGeneratedAt?: InputMaybe; + version?: InputMaybe; +}; + +export type UpdateReportingPeriodInput = { + certifiedAt?: InputMaybe; + certifiedById?: InputMaybe; + endDate?: InputMaybe; + inputTemplateId?: InputMaybe; + isCurrentPeriod?: InputMaybe; + name?: InputMaybe; + outputTemplateId?: InputMaybe; + startDate?: InputMaybe; +}; + +export type UpdateRoleInput = { + name?: InputMaybe; +}; + +export type UpdateUserInput = { + agencyId?: InputMaybe; + email?: InputMaybe; + name?: InputMaybe; + organizationId?: InputMaybe; + roleId?: InputMaybe; +}; + +export type User = { + __typename?: 'User'; + agency?: Maybe; + agencyId?: Maybe; + certified: Array>; + createdAt: Scalars['DateTime']; + email: Scalars['String']; + id: Scalars['Int']; + name?: Maybe; + organization: Organization; + organizationId: Scalars['Int']; + role?: Maybe; + roleId?: Maybe; + updatedAt: Scalars['DateTime']; +}; + export type FindAgenciesByOrganizationIdVariables = Exact<{ organizationId: Scalars['Int']; }>; @@ -225,3 +501,15 @@ export type FindOrganizationsVariables = Exact<{ [key: string]: never; }>; export type FindOrganizations = { __typename?: 'Query', organizations: Array<{ __typename?: 'Organization', id: number, name: string }> }; + +export type FindReportingPeriodQueryVariables = Exact<{ + id: Scalars['Int']; +}>; + + +export type FindReportingPeriodQuery = { __typename?: 'Query', reportingPeriod?: { __typename?: 'ReportingPeriod', id: number } | null }; + +export type ReportingPeriodsQueryVariables = Exact<{ [key: string]: never; }>; + + +export type ReportingPeriodsQuery = { __typename?: 'Query', reportingPeriods: Array<{ __typename?: 'ReportingPeriod', id: number, startDate: string, endDate: string, isCurrentPeriod: boolean, certifiedAt?: string | null, certifiedBy?: { __typename?: 'User', email: string } | null, inputTemplate: { __typename?: 'InputTemplate', name: string } }> }; From 29dd07dcf3de4f3b3a4ce733231817c8b4943d41 Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Thu, 7 Dec 2023 14:23:59 -0500 Subject: [PATCH 2/6] fix: get these db tests to pass --- api/src/services/inputTemplates/inputTemplates.test.ts | 2 +- api/src/services/outputTemplates/outputTemplates.test.ts | 2 +- api/src/services/reportingPeriods/reportingPeriods.test.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/src/services/inputTemplates/inputTemplates.test.ts b/api/src/services/inputTemplates/inputTemplates.test.ts index d65c08c1..a311e608 100644 --- a/api/src/services/inputTemplates/inputTemplates.test.ts +++ b/api/src/services/inputTemplates/inputTemplates.test.ts @@ -44,7 +44,7 @@ describe('inputTemplates', () => { expect(result.name).toEqual('String') expect(result.version).toEqual('String') - expect(result.effectiveDate).toEqual(new Date('2023-12-07T18:17:24.374Z')) + expect(result.effectiveDate).toEqual(new Date('2023-12-07T00:00:00.000Z')) expect(result.rulesGeneratedAt).toEqual( new Date('2023-12-07T18:17:24.374Z') ) diff --git a/api/src/services/outputTemplates/outputTemplates.test.ts b/api/src/services/outputTemplates/outputTemplates.test.ts index 62680e6a..04a86a45 100644 --- a/api/src/services/outputTemplates/outputTemplates.test.ts +++ b/api/src/services/outputTemplates/outputTemplates.test.ts @@ -49,7 +49,7 @@ describe('outputTemplates', () => { expect(result.name).toEqual('String') expect(result.version).toEqual('String') - expect(result.effectiveDate).toEqual(new Date('2023-12-07T18:17:34.958Z')) + expect(result.effectiveDate).toEqual(new Date('2023-12-07T00:00:00.000Z')) expect(result.rulesGeneratedAt).toEqual( new Date('2023-12-07T18:17:34.958Z') ) diff --git a/api/src/services/reportingPeriods/reportingPeriods.test.ts b/api/src/services/reportingPeriods/reportingPeriods.test.ts index 729d8071..f01d5806 100644 --- a/api/src/services/reportingPeriods/reportingPeriods.test.ts +++ b/api/src/services/reportingPeriods/reportingPeriods.test.ts @@ -51,8 +51,8 @@ describe('reportingPeriods', () => { }) expect(result.name).toEqual('String') - expect(result.startDate).toEqual(new Date('2023-12-07T18:38:12.341Z')) - expect(result.endDate).toEqual(new Date('2023-12-07T18:38:12.341Z')) + expect(result.startDate).toEqual(new Date('2023-12-07T00:00:00.000Z')) + expect(result.endDate).toEqual(new Date('2023-12-07T00:00:00.000Z')) expect(result.inputTemplateId).toEqual( scenario.reportingPeriod.two.inputTemplateId ) From 41eb2668e65379e029995d821737b760b0a4a631 Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Thu, 7 Dec 2023 15:55:13 -0500 Subject: [PATCH 3/6] fix: working on front-end test failures --- .../ReportingPeriodCell.tsx | 1 - .../ReportingPeriodsCell.tsx | 59 ++++++++++--------- .../UploadTemplatePage.test.tsx | 2 +- web/types/graphql.d.ts | 4 +- 4 files changed, 33 insertions(+), 33 deletions(-) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx index 116350c7..40672d3d 100644 --- a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx @@ -8,7 +8,6 @@ import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web' export const QUERY = gql` query FindReportingPeriodQuery($id: Int!) { reportingPeriod: reportingPeriod(id: $id) { - id name } } diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx index 3cc5ec5e..336e5b28 100644 --- a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx @@ -42,37 +42,38 @@ export const Success = ({ Certified At - - {reportingPeriods.map((item) => { - return ( - - {item.startDate} - {item.endDate} - - {item.inputTemplate.name} - {!item.certifiedAt && ( - - {' '} - - Upload Template - - - )} - - - {item.isCurrentPeriod ? ( - - ) : ( - item.certifiedAt && ( + + {reportingPeriods.map((item) => { + return ( + + {item.startDate} + {item.endDate} + + {item.inputTemplate && item.inputTemplate.name} + {!item.certifiedAt && ( - {item.certifiedAt} by {item.certifiedBy} + {' '} + + Upload Template + - ) - )} - - - ) - })} + )} + + + {item.isCurrentPeriod ? ( + + ) : ( + item.certifiedAt && ( + + {item.certifiedAt} by {item.certifiedBy.email} + + ) + )} + + + ) + })} + ) } diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx index 44850821..059da35e 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx @@ -8,7 +8,7 @@ import UploadTemplatePage from './UploadTemplatePage' describe('UploadTemplatePage', () => { it('renders successfully', () => { expect(() => { - render() + render() }).not.toThrow() }) }) diff --git a/web/types/graphql.d.ts b/web/types/graphql.d.ts index 0520f946..96581de1 100644 --- a/web/types/graphql.d.ts +++ b/web/types/graphql.d.ts @@ -507,9 +507,9 @@ export type FindReportingPeriodQueryVariables = Exact<{ }>; -export type FindReportingPeriodQuery = { __typename?: 'Query', reportingPeriod?: { __typename?: 'ReportingPeriod', id: number } | null }; +export type FindReportingPeriodQuery = { __typename?: 'Query', reportingPeriod?: { __typename?: 'ReportingPeriod', id: number, name: string } | null }; export type ReportingPeriodsQueryVariables = Exact<{ [key: string]: never; }>; -export type ReportingPeriodsQuery = { __typename?: 'Query', reportingPeriods: Array<{ __typename?: 'ReportingPeriod', id: number, startDate: string, endDate: string, isCurrentPeriod: boolean, certifiedAt?: string | null, certifiedBy?: { __typename?: 'User', email: string } | null, inputTemplate: { __typename?: 'InputTemplate', name: string } }> }; +export type ReportingPeriodsQuery = { __typename?: 'Query', reportingPeriods: Array<{ __typename?: 'ReportingPeriod', id: number, startDate: string, endDate: string, isCurrentPeriod: boolean, certifiedAt?: string | null, inputTemplate: { __typename?: 'InputTemplate', name: string }, certifiedBy?: { __typename?: 'User', email: string } | null }> }; From 3e52fa4049ff75dff065a34ae05b1efc970ef166 Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Thu, 7 Dec 2023 16:47:46 -0500 Subject: [PATCH 4/6] fix: comment out the cells, since they throw this error --- .../ReportingPeriodCell/ReportingPeriodCell.mock.ts | 1 + .../components/ReportingPeriodsCell/ReportingPeriodsCell.tsx | 4 ++-- web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx | 2 +- web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx | 2 +- web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx | 2 +- web/types/graphql.d.ts | 4 ++-- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts index f7b26eb3..2e17d1fd 100644 --- a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.mock.ts @@ -2,5 +2,6 @@ export const standard = (/* vars, { ctx, req } */) => ({ reportingPeriod: { id: 42, + name: 'Q423', }, }) diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx index 336e5b28..e54953dc 100644 --- a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.tsx @@ -49,7 +49,7 @@ export const Success = ({ {item.startDate} {item.endDate} - {item.inputTemplate && item.inputTemplate.name} + {item.inputTemplate?.name} {!item.certifiedAt && ( {' '} @@ -65,7 +65,7 @@ export const Success = ({ ) : ( item.certifiedAt && ( - {item.certifiedAt} by {item.certifiedBy.email} + {item.certifiedAt} by {item.certifiedBy?.email} ) )} diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx index 187239fd..d76f5c0e 100644 --- a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx @@ -8,7 +8,7 @@ const ReportingPeriodsPage = () => {

Reporting Periods

- + {/* */} ) } diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx index 059da35e..7b9f8601 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx @@ -8,7 +8,7 @@ import UploadTemplatePage from './UploadTemplatePage' describe('UploadTemplatePage', () => { it('renders successfully', () => { expect(() => { - render() + render() }).not.toThrow() }) }) diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx index 312c18cb..505b13fe 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx @@ -16,7 +16,7 @@ const UploadTemplatePage = ({ id }) => {

Upload Period Template

This upload will be used as the template for period{' '} - + {/* */}

diff --git a/web/types/graphql.d.ts b/web/types/graphql.d.ts index 96581de1..738745f0 100644 --- a/web/types/graphql.d.ts +++ b/web/types/graphql.d.ts @@ -507,9 +507,9 @@ export type FindReportingPeriodQueryVariables = Exact<{ }>; -export type FindReportingPeriodQuery = { __typename?: 'Query', reportingPeriod?: { __typename?: 'ReportingPeriod', id: number, name: string } | null }; +export type FindReportingPeriodQuery = { __typename?: 'Query', reportingPeriod?: { __typename?: 'ReportingPeriod', name: string } | null }; export type ReportingPeriodsQueryVariables = Exact<{ [key: string]: never; }>; -export type ReportingPeriodsQuery = { __typename?: 'Query', reportingPeriods: Array<{ __typename?: 'ReportingPeriod', id: number, startDate: string, endDate: string, isCurrentPeriod: boolean, certifiedAt?: string | null, inputTemplate: { __typename?: 'InputTemplate', name: string }, certifiedBy?: { __typename?: 'User', email: string } | null }> }; +export type ReportingPeriodsQuery = { __typename?: 'Query', reportingPeriods: Array<{ __typename?: 'ReportingPeriod', id: number, startDate: string, endDate: string, isCurrentPeriod: boolean, certifiedAt?: string | null, certifiedBy?: { __typename?: 'User', email: string } | null, inputTemplate: { __typename?: 'InputTemplate', name: string } }> }; From 2f203616ad9304563cc6890e2d9381673bd77e86 Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Thu, 7 Dec 2023 16:59:49 -0500 Subject: [PATCH 5/6] fix: take care of linter errors --- .../components/ReportingPeriodCell/ReportingPeriodCell.test.tsx | 1 + .../ReportingPeriodsCell/ReportingPeriodsCell.test.tsx | 1 + web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx | 2 +- web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx index 369fa8cd..4b99d83f 100644 --- a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.test.tsx @@ -1,4 +1,5 @@ import { render } from '@redwoodjs/testing/web' + import { Loading, Empty, Failure, Success } from './ReportingPeriodCell' import { standard } from './ReportingPeriodCell.mock' diff --git a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx index 547f0c07..b9a8f6b8 100644 --- a/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx +++ b/web/src/components/ReportingPeriodsCell/ReportingPeriodsCell.test.tsx @@ -1,4 +1,5 @@ import { render } from '@redwoodjs/testing/web' + import { Loading, Empty, Failure, Success } from './ReportingPeriodsCell' import { standard } from './ReportingPeriodsCell.mock' diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx index d76f5c0e..47e56e2d 100644 --- a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx @@ -1,6 +1,6 @@ import { MetaTags } from '@redwoodjs/web' -import ReportingPeriodsCell from 'src/components/ReportingPeriodsCell' +// import ReportingPeriodsCell from 'src/components/ReportingPeriodsCell' const ReportingPeriodsPage = () => { return ( diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx index 505b13fe..85621fca 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx @@ -2,7 +2,7 @@ import { Form, FileField, HiddenField, Submit } from '@redwoodjs/forms' import { Link, routes } from '@redwoodjs/router' import { MetaTags } from '@redwoodjs/web' -import ReportingPeriodCell from 'src/components/ReportingPeriodCell' +// import ReportingPeriodCell from 'src/components/ReportingPeriodCell' const UploadTemplatePage = ({ id }) => { const onSubmit = (data) => { From e547db1093d703cf6bd24ae2a254d0470843211f Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Fri, 8 Dec 2023 09:15:18 -0500 Subject: [PATCH 6/6] fix: add RedwoodApolloProvider to page tests --- .../ReportingPeriodCell/ReportingPeriodCell.tsx | 6 +++++- .../ReportingPeriodsPage/ReportingPeriodsPage.test.tsx | 6 +++++- .../pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx | 4 ++-- .../pages/UploadTemplatePage/UploadTemplatePage.test.tsx | 6 +++++- web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx | 8 +++----- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx index 40672d3d..54613791 100644 --- a/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx +++ b/web/src/components/ReportingPeriodCell/ReportingPeriodCell.tsx @@ -29,5 +29,9 @@ export const Success = ({ FindReportingPeriodQuery, FindReportingPeriodQueryVariables >) => { - return {reportingPeriod.name} + return ( +

+ This upload will be used as the template for period {reportingPeriod.name} +

+ ) } diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx index 66c06ad1..b1aecd87 100644 --- a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.test.tsx @@ -1,14 +1,18 @@ import { render } from '@redwoodjs/testing/web' +import { RedwoodApolloProvider } from '@redwoodjs/web/apollo' import ReportingPeriodsPage from './ReportingPeriodsPage' // Improve this test with help from the Redwood Testing Doc: // https://redwoodjs.com/docs/testing#testing-pages-layouts +function apolloProvider(children) { + return {children} +} describe('ReportingPeriodsPage', () => { it('renders successfully', () => { expect(() => { - render() + render(apolloProvider()) }).not.toThrow() }) }) diff --git a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx index 47e56e2d..187239fd 100644 --- a/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx +++ b/web/src/pages/ReportingPeriodsPage/ReportingPeriodsPage.tsx @@ -1,6 +1,6 @@ import { MetaTags } from '@redwoodjs/web' -// import ReportingPeriodsCell from 'src/components/ReportingPeriodsCell' +import ReportingPeriodsCell from 'src/components/ReportingPeriodsCell' const ReportingPeriodsPage = () => { return ( @@ -8,7 +8,7 @@ const ReportingPeriodsPage = () => {

Reporting Periods

- {/* */} + ) } diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx index 7b9f8601..acc9e4b0 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.test.tsx @@ -1,14 +1,18 @@ import { render } from '@redwoodjs/testing/web' +import { RedwoodApolloProvider } from '@redwoodjs/web/apollo' import UploadTemplatePage from './UploadTemplatePage' // Improve this test with help from the Redwood Testing Doc: // https://redwoodjs.com/docs/testing#testing-pages-layouts +function apolloProvider(children) { + return {children} +} describe('UploadTemplatePage', () => { it('renders successfully', () => { expect(() => { - render() + render(apolloProvider()) }).not.toThrow() }) }) diff --git a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx index 85621fca..b1c26101 100644 --- a/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx +++ b/web/src/pages/UploadTemplatePage/UploadTemplatePage.tsx @@ -2,7 +2,7 @@ import { Form, FileField, HiddenField, Submit } from '@redwoodjs/forms' import { Link, routes } from '@redwoodjs/router' import { MetaTags } from '@redwoodjs/web' -// import ReportingPeriodCell from 'src/components/ReportingPeriodCell' +import ReportingPeriodCell from 'src/components/ReportingPeriodCell' const UploadTemplatePage = ({ id }) => { const onSubmit = (data) => { @@ -14,10 +14,8 @@ const UploadTemplatePage = ({ id }) => {

Upload Period Template

-

- This upload will be used as the template for period{' '} - {/* */} -

+ +