From 1219205407bbdbbe182df61ae286cecc3ff221ef Mon Sep 17 00:00:00 2001 From: Benjamin Paige Date: Mon, 10 Jul 2023 10:13:05 -0600 Subject: [PATCH] rmv issues and update dashboard (#52) * rmv issues updt dashboard * package to record --- serverless-compose.yml | 3 - src/packages/shared-types/seatoolData.ts | 6 + src/services/api/handlers/createIssue.ts | 31 ---- src/services/api/handlers/deleteIssue.ts | 35 ---- src/services/api/handlers/getIssue.ts | 42 ----- src/services/api/handlers/getIssues.ts | 27 --- .../api/handlers/tests/createIssue.test.ts | 18 -- .../api/handlers/tests/deleteIssue.test.ts | 32 ---- .../api/handlers/tests/getIssue.test.ts | 26 --- .../api/handlers/tests/getIssues.test.ts | 14 -- .../api/handlers/tests/updateIssue.test.ts | 29 --- src/services/api/handlers/updateIssue.ts | 32 ---- src/services/api/serverless.yml | 62 ------- src/services/api/services/issueService.ts | 91 ---------- src/services/database/.eslintrc.js | 4 - src/services/database/.gitignore | 6 - .../database/handlers/seeddatabase.ts | 28 --- .../database/handlers/testDataLoader.ts | 26 --- src/services/database/package.json | 25 --- src/services/database/serverless.yml | 104 ----------- .../database/src/reference/items.json | 18 -- src/services/database/tsconfig.json | 14 -- .../ui/e2e/tests/issues/issues.spec.ts | 57 ------ src/services/ui/src/api/index.ts | 4 +- src/services/ui/src/api/useCreateIssue.ts | 28 --- src/services/ui/src/api/useDeleteIssue.ts | 15 -- src/services/ui/src/api/useGetIssue.ts | 16 -- src/services/ui/src/api/useGetIssues.ts | 16 -- src/services/ui/src/api/useGetSeatool.ts | 2 +- src/services/ui/src/api/useUpdateIssue.ts | 30 ---- .../ui/src/components/AddIssueForm/index.tsx | 165 ------------------ src/services/ui/src/components/index.tsx | 1 - src/services/ui/src/hooks/index.ts | 1 + src/services/ui/src/hooks/useQuery.ts | 8 + src/services/ui/src/pages/dashboard/index.tsx | 33 +++- src/services/ui/src/pages/index.ts | 4 +- src/services/ui/src/pages/issue/list.tsx | 99 ----------- src/services/ui/src/pages/issue/view.tsx | 70 -------- .../ui/src/pages/{issue => record}/index.ts | 1 - src/services/ui/src/pages/record/view.tsx | 15 ++ src/services/ui/src/router.tsx | 5 +- 41 files changed, 66 insertions(+), 1177 deletions(-) delete mode 100644 src/services/api/handlers/createIssue.ts delete mode 100644 src/services/api/handlers/deleteIssue.ts delete mode 100644 src/services/api/handlers/getIssue.ts delete mode 100644 src/services/api/handlers/getIssues.ts delete mode 100644 src/services/api/handlers/tests/createIssue.test.ts delete mode 100644 src/services/api/handlers/tests/deleteIssue.test.ts delete mode 100644 src/services/api/handlers/tests/getIssue.test.ts delete mode 100644 src/services/api/handlers/tests/getIssues.test.ts delete mode 100644 src/services/api/handlers/tests/updateIssue.test.ts delete mode 100644 src/services/api/handlers/updateIssue.ts delete mode 100644 src/services/api/services/issueService.ts delete mode 100644 src/services/database/.eslintrc.js delete mode 100644 src/services/database/.gitignore delete mode 100644 src/services/database/handlers/seeddatabase.ts delete mode 100644 src/services/database/handlers/testDataLoader.ts delete mode 100644 src/services/database/package.json delete mode 100644 src/services/database/serverless.yml delete mode 100644 src/services/database/src/reference/items.json delete mode 100644 src/services/database/tsconfig.json delete mode 100644 src/services/ui/e2e/tests/issues/issues.spec.ts delete mode 100644 src/services/ui/src/api/useCreateIssue.ts delete mode 100644 src/services/ui/src/api/useDeleteIssue.ts delete mode 100644 src/services/ui/src/api/useGetIssue.ts delete mode 100644 src/services/ui/src/api/useGetIssues.ts delete mode 100644 src/services/ui/src/api/useUpdateIssue.ts delete mode 100644 src/services/ui/src/components/AddIssueForm/index.tsx create mode 100644 src/services/ui/src/hooks/index.ts create mode 100644 src/services/ui/src/hooks/useQuery.ts delete mode 100644 src/services/ui/src/pages/issue/list.tsx delete mode 100644 src/services/ui/src/pages/issue/view.tsx rename src/services/ui/src/pages/{issue => record}/index.ts (50%) create mode 100644 src/services/ui/src/pages/record/view.tsx diff --git a/serverless-compose.yml b/serverless-compose.yml index 1b9b1c947..a94523360 100644 --- a/serverless-compose.yml +++ b/serverless-compose.yml @@ -3,14 +3,11 @@ services: path: src/services/alerts dashboard: path: src/services/dashboard - database: - path: src/services/database seatool: path: src/services/seatool api: path: src/services/api params: - issuesTableName: ${database.IssuesTableName} seatoolTableName: ${seatool.TableName} ui-infra: path: src/services/ui-infra diff --git a/src/packages/shared-types/seatoolData.ts b/src/packages/shared-types/seatoolData.ts index 145784e59..90b0ef31c 100644 --- a/src/packages/shared-types/seatoolData.ts +++ b/src/packages/shared-types/seatoolData.ts @@ -3,4 +3,10 @@ export type SeatoolData = { SUBMISSION_DATE: number; PLAN_TYPE: string; // should be enum STATE_CODE: string; // should be enum + STATE_PLAN: { + SUMMARY_MEMO?: string; + }; + SPW_STATUS?: { + SPW_STATUS_DESC: string; + }[]; }; diff --git a/src/services/api/handlers/createIssue.ts b/src/services/api/handlers/createIssue.ts deleted file mode 100644 index fb9b7026f..000000000 --- a/src/services/api/handlers/createIssue.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { APIGatewayEvent } from "aws-lambda"; -import { response } from "../libs/handler"; -import { createIssueSchema } from "shared-types"; -import { IssueService } from "../services/issueService"; -import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; - -const dynamoInstance = new DynamoDBClient({ region: process.env.region }); - -export const createIssue = async (event: APIGatewayEvent) => { - try { - const validIssue = createIssueSchema.parse(JSON.parse(event.body)); - - const newIssue = await new IssueService(dynamoInstance).createIssue({ - issue: validIssue, - tableName: process.env.tableName, - }); - - return response({ - statusCode: 201, - body: newIssue, - }); - } catch (error) { - console.error({ error }); - return response({ - statusCode: 404, - body: error, - }); - } -}; - -export const handler = createIssue; diff --git a/src/services/api/handlers/deleteIssue.ts b/src/services/api/handlers/deleteIssue.ts deleted file mode 100644 index c4dd0918c..000000000 --- a/src/services/api/handlers/deleteIssue.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { z, ZodError } from "zod"; -import { response } from "../libs/handler"; -import { IssueService } from "../services/issueService"; -import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; - -const dynamoInstance = new DynamoDBClient({ region: process.env.region }); - -export const deleteIssue = async ({ pathParameters }) => { - try { - const validParams = z.object({ - id: z.string().uuid(), - }); - - const params = validParams.parse(pathParameters); - - await new IssueService(dynamoInstance).deleteIssue({ - id: params.id, - tableName: process.env.tableName, - }); - - return response({ - statusCode: 204, - }); - } catch (error) { - console.error({ error }); - if (error instanceof ZodError) { - return response({ - statusCode: 404, - body: { message: error }, - }); - } - } -}; - -export const handler = deleteIssue; diff --git a/src/services/api/handlers/getIssue.ts b/src/services/api/handlers/getIssue.ts deleted file mode 100644 index e8c4307a1..000000000 --- a/src/services/api/handlers/getIssue.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { z, ZodError } from "zod"; -import { response } from "../libs/handler"; -import { IssueService } from "../services/issueService"; -import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; - -const dynamoInstance = new DynamoDBClient({ region: process.env.region }); - -export const getIssue = async ({ pathParameters }) => { - try { - const validParams = z.object({ - id: z.string().uuid(), - }); - - const params = validParams.parse(pathParameters); - - const input = { - id: params.id, - tableName: process.env.tableName, - }; - const foundIssue = await new IssueService(dynamoInstance).getIssue(input); - - return response({ - statusCode: 200, - body: foundIssue, - }); - } catch (error) { - console.error({ error }); - if (error instanceof ZodError) { - return response({ - statusCode: 404, - body: { message: error }, - }); - } - - return response({ - statusCode: 404, - body: { message: "Issue not found" }, - }); - } -}; - -export const handler = getIssue; diff --git a/src/services/api/handlers/getIssues.ts b/src/services/api/handlers/getIssues.ts deleted file mode 100644 index 049d1ff26..000000000 --- a/src/services/api/handlers/getIssues.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { response } from "../libs/handler"; -import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; -import { IssueService } from "../services/issueService"; -import { Issue } from "shared-types"; - -const dynamoInstance = new DynamoDBClient({ region: process.env.region }); - -export const getIssues = async () => { - try { - const issues = await new IssueService(dynamoInstance).getIssues({ - tableName: process.env.tableName, - }); - - return response({ - statusCode: 200, - body: issues, - }); - } catch (error) { - console.error({ error }); - return response({ - statusCode: 404, - body: { message: JSON.stringify(error) }, - }); - } -}; - -export const handler = getIssues; diff --git a/src/services/api/handlers/tests/createIssue.test.ts b/src/services/api/handlers/tests/createIssue.test.ts deleted file mode 100644 index 9b4ea3873..000000000 --- a/src/services/api/handlers/tests/createIssue.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { it, describe, expect, vi, afterAll } from "vitest"; -import type { APIGatewayEvent } from "aws-lambda"; -import { createIssue } from "../createIssue"; - -const mockEvent: APIGatewayEvent = {} as APIGatewayEvent; - -describe("creatIssue", () => { - afterAll(() => { - vi.resetAllMocks(); - }); - - it("returns a 201 status code and an empty issue object", async () => { - const response = await createIssue(mockEvent); - - expect(response.statusCode).toBe(201); - expect(response.body).toEqual(JSON.stringify({ issue: {} })); - }); -}); diff --git a/src/services/api/handlers/tests/deleteIssue.test.ts b/src/services/api/handlers/tests/deleteIssue.test.ts deleted file mode 100644 index 8506d98f6..000000000 --- a/src/services/api/handlers/tests/deleteIssue.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { it, describe, expect, vi, afterAll } from "vitest"; -import { deleteIssue } from "../deleteIssue"; - -describe("deleteIssue", () => { - afterAll(() => { - vi.resetAllMocks(); - }); - - it("returns 400 if pathParameters is undefined", async () => { - const event = { pathParameters: null }; - const response = await deleteIssue(event); - expect(response.statusCode).toEqual(400); - expect(JSON.parse(response.body)).toEqual({ message: "Invalid request" }); - }); - - it("returns 400 if pathParameters.id is undefined", async () => { - const event = { pathParameters: {} }; - const response = await deleteIssue(event); - expect(response.statusCode).toEqual(400); - expect(JSON.parse(response.body)).toEqual({ message: "Invalid request" }); - }); - - it("returns 200 with correct message if pathParameters.id is defined", async () => { - const id = "123"; - const event = { pathParameters: { id } }; - const response = await deleteIssue(event); - expect(response.statusCode).toEqual(200); - expect(JSON.parse(response.body)).toEqual({ - issue: `Issue with ${id} was deleted`, - }); - }); -}); diff --git a/src/services/api/handlers/tests/getIssue.test.ts b/src/services/api/handlers/tests/getIssue.test.ts deleted file mode 100644 index 5c37d6909..000000000 --- a/src/services/api/handlers/tests/getIssue.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { it, describe, expect, vi, afterAll } from "vitest"; -import { getIssue } from "../getIssue"; - -describe("getIssue", () => { - afterAll(() => { - vi.resetAllMocks(); - }); - it("should return 400 Bad Request if id is missing", async () => { - const event = { pathParameters: {} }; - const result = await getIssue(event); - expect(result.statusCode).toEqual(400); - expect(JSON.parse(result.body)).toEqual({ message: "Invalid request" }); - }); - - it("should return 200 OK with the issue id", async () => { - const event = { pathParameters: { id: "123" } }; - const result = await getIssue(event); - expect(result.statusCode).toEqual(200); - expect(JSON.parse(result.body)).toEqual({ - issue: { - id: "123", - title: "My first issue", - }, - }); - }); -}); diff --git a/src/services/api/handlers/tests/getIssues.test.ts b/src/services/api/handlers/tests/getIssues.test.ts deleted file mode 100644 index a7fdcfd45..000000000 --- a/src/services/api/handlers/tests/getIssues.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { it, describe, expect, vi, afterAll } from "vitest"; -import { getIssues } from "../getIssues"; - -describe("getIssues", () => { - afterAll(() => { - vi.resetAllMocks(); - }); - - it("should return 200 OK with the issues", async () => { - const result = await getIssues(); - expect(result.statusCode).toEqual(200); - expect(JSON.parse(result.body)).toEqual([]); - }); -}); diff --git a/src/services/api/handlers/tests/updateIssue.test.ts b/src/services/api/handlers/tests/updateIssue.test.ts deleted file mode 100644 index d6b4bb7f5..000000000 --- a/src/services/api/handlers/tests/updateIssue.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { it, describe, expect, vi, afterAll } from "vitest"; -import { updateIssue } from "../updateIssue"; - -describe("updateIssue", () => { - afterAll(() => { - vi.resetAllMocks(); - }); - - it("should return 400 status code and error message when request body is missing or empty", async () => { - const event = { pathParameters: { id: "123" }, body: "" }; - const response = await updateIssue(event); - expect(response.statusCode).toBe(400); - expect(response.body).toEqual( - JSON.stringify({ message: "Invalid request" }) - ); - }); - - it("should return 200 status code and success message when issue is updated", async () => { - const event = { - pathParameters: { id: "123" }, - body: "{\"title\": \"Updated Title\", \"content\": \"Updated Content\"}", - }; - const response = await updateIssue(event); - expect(response.statusCode).toBe(200); - expect(response.body).toEqual( - JSON.stringify({ message: "Issue with 123 was updated" }) - ); - }); -}); diff --git a/src/services/api/handlers/updateIssue.ts b/src/services/api/handlers/updateIssue.ts deleted file mode 100644 index 2ac6ccd41..000000000 --- a/src/services/api/handlers/updateIssue.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { response } from "../libs/handler"; -import { issueSchema } from "shared-types"; -import { IssueService } from "../services/issueService"; -import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; - -const dynamoInstance = new DynamoDBClient({ region: process.env.region }); - -export const updateIssue = async ({ pathParameters, body }) => { - const { id } = pathParameters; - - try { - const validIssue = issueSchema.parse(JSON.parse(body)); - - await new IssueService(dynamoInstance).editIssue({ - id, - issue: validIssue, - tableName: process.env.tableName, - }); - - return response({ - statusCode: 200, - }); - } catch (error) { - console.error({ error }); - return response({ - statusCode: 404, - body: { message: error }, - }); - } -}; - -export const handler = updateIssue; diff --git a/src/services/api/serverless.yml b/src/services/api/serverless.yml index 8091be735..f6f7ce621 100644 --- a/src/services/api/serverless.yml +++ b/src/services/api/serverless.yml @@ -10,8 +10,6 @@ plugins: provider: name: aws runtime: nodejs18.x - environment: - issuesTable: ${param:issuesTableName} logs: restApi: true region: ${env:REGION_A} @@ -54,18 +52,6 @@ custom: bundle: linting: false functions: - getIssues: - handler: handlers/getIssues.handler - maximumRetryAttempts: 0 - environment: - tableName: ${param:issuesTableName} - region: ${self:provider.region} - events: - - http: - path: /issues - method: get - cors: true - authorizer: aws_iam getSeaTool: handler: handlers/getSeatoolData.handler maximumRetryAttempts: 0 @@ -78,54 +64,6 @@ functions: method: get cors: true authorizer: aws_iam - getIssue: - handler: handlers/getIssue.handler - maximumRetryAttempts: 0 - environment: - tableName: ${param:issuesTableName} - region: ${self:provider.region} - events: - - http: - path: /issues/{id} - method: get - cors: true - authorizer: aws_iam - createIssue: - handler: handlers/createIssue.handler - maximumRetryAttempts: 0 - environment: - tableName: ${param:issuesTableName} - region: ${self:provider.region} - events: - - http: - path: /issues - method: post - cors: true - authorizer: aws_iam - deleteIssue: - handler: handlers/deleteIssue.handler - maximumRetryAttempts: 0 - environment: - tableName: ${param:issuesTableName} - region: ${self:provider.region} - events: - - http: - path: /issues/{id} - method: delete - cors: true - authorizer: aws_iam - updateIssue: - handler: handlers/updateIssue.handler - maximumRetryAttempts: 0 - environment: - tableName: ${param:issuesTableName} - region: ${self:provider.region} - events: - - http: - path: /issues/{id} - method: put - cors: true - authorizer: aws_iam resources: Resources: GatewayResponseDefault4XX: diff --git a/src/services/api/services/issueService.ts b/src/services/api/services/issueService.ts deleted file mode 100644 index 6e9b16ddb..000000000 --- a/src/services/api/services/issueService.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { v4 } from "uuid"; -import { CreateIssue, Issue } from "shared-types"; -import { - DynamoDBClient, - PutItemCommand, - DeleteItemCommand, - GetItemCommand, - ScanCommand, -} from "@aws-sdk/client-dynamodb"; -import { marshall, unmarshall } from "@aws-sdk/util-dynamodb"; - -export class IssueService { - #dynamoInstance: DynamoDBClient; - - constructor(dynamoInstance: DynamoDBClient) { - this.#dynamoInstance = dynamoInstance; - } - - async createIssue({ - issue, - tableName, - }: { - issue: CreateIssue; - tableName: string; - }) { - const id = v4(); - const createdAt = Date.now(); - - const input = { - Item: marshall({ ...issue, id, createdAt }), - TableName: tableName, - }; - - return await this.#dynamoInstance.send(new PutItemCommand(input)); - } - - async getIssue({ id, tableName }: { id: string; tableName: string }) { - const input = new GetItemCommand({ - Key: marshall({ id }), - TableName: tableName, - }); - - const result = await this.#dynamoInstance.send(input); - - return unmarshall(result.Item); - } - - async getIssues({ tableName }: { tableName: string }) { - let items: Issue[] = []; - let isLastPage = false; - let lastEvaluatedKey = null; - while (!isLastPage) { - const data = await this.#dynamoInstance.send( - new ScanCommand({ - TableName: tableName, - ExclusiveStartKey: lastEvaluatedKey, - }) - ); - items = [...items, ...data.Items.map((item) => unmarshall(item))]; - lastEvaluatedKey = data.LastEvaluatedKey; - isLastPage = !lastEvaluatedKey; - } - return items; - } - - async deleteIssue({ id, tableName }: { id: string; tableName: string }) { - const input = { Key: marshall({ id }), TableName: tableName }; - - return await this.#dynamoInstance.send(new DeleteItemCommand(input)); - } - - async editIssue({ - id, - issue, - tableName, - }: { - id: string; - issue: Omit; - tableName: string; - }) { - const updatedAt = Date.now(); - - const input = { - Item: marshall({ ...issue, id, updatedAt }), - TableName: tableName, - }; - const result = await this.#dynamoInstance.send(new PutItemCommand(input)); - - return result; - } -} diff --git a/src/services/database/.eslintrc.js b/src/services/database/.eslintrc.js deleted file mode 100644 index 2308ff968..000000000 --- a/src/services/database/.eslintrc.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - root: true, - extends: ["custom-server"], -}; diff --git a/src/services/database/.gitignore b/src/services/database/.gitignore deleted file mode 100644 index 2b48c8bd5..000000000 --- a/src/services/database/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# package directories -node_modules -jspm_packages - -# Serverless directories -.serverless \ No newline at end of file diff --git a/src/services/database/handlers/seeddatabase.ts b/src/services/database/handlers/seeddatabase.ts deleted file mode 100644 index 14b6bfa35..000000000 --- a/src/services/database/handlers/seeddatabase.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { send, SUCCESS, FAILED } from "cfn-response-async"; -import { putItem } from "../../../libs"; -import * as items from "../src/reference/items.json"; -import type { CloudFormationCustomResourceEvent, Context } from "aws-lambda"; - -declare type ResponseStatus = typeof SUCCESS | typeof FAILED; - -exports.handler = async function ( - event: CloudFormationCustomResourceEvent, - context: Context -) { - console.log("Request:", JSON.stringify(event, undefined, 2)); - const responseData = {}; - let responseStatus: ResponseStatus = SUCCESS; - try { - for await (const item of items) { - putItem({ - tableName: event.ResourceProperties.DynamoTableName, - item: { id: item.id, state: item.state }, - }); - } - } catch (error) { - console.error(error); - responseStatus = FAILED; - } finally { - await send(event, context, responseStatus, responseData, "static"); - } -}; diff --git a/src/services/database/handlers/testDataLoader.ts b/src/services/database/handlers/testDataLoader.ts deleted file mode 100644 index 8610fdd97..000000000 --- a/src/services/database/handlers/testDataLoader.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as dynamodb from "../../../libs/dynamodb-lib"; -import { generateMock } from "@anatine/zod-mock"; -import { issueSchema } from "shared-types"; -exports.handler = async () => { - try { - if (!process.env.tableName) { - throw "ERROR: env variable 'tableName' should exist"; - } - const tableName = process.env.tableName; - console.log("Putting test data..."); - - for (let i = 0; i < 5; i++) { - const mockData = generateMock(issueSchema, { - seed: 100 + i, - }); - await dynamodb.putItem({ - tableName, - item: { ...mockData, createdAt: Date.now() }, - }); - } - return "SUCCESS"; - } catch (error) { - console.log(error); - throw "ERROR"; - } -}; diff --git a/src/services/database/package.json b/src/services/database/package.json deleted file mode 100644 index 0ecdb5805..000000000 --- a/src/services/database/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "database", - "description": "", - "private": true, - "version": "0.0.0", - "main": "index.js", - "author": "", - "license": "CC0-1.0", - "devDependencies": { - "@typescript-eslint/eslint-plugin": "^5.59.0", - "@typescript-eslint/parser": "^5.59.0", - "eslint": "^8.38.0", - "eslint-config-custom-server": "*" - }, - "dependencies": { - "@anatine/zod-mock": "^3.12.0", - "@faker-js/faker": "^8.0.2", - "cfn-response-async": "^1.0.0", - "shared-types": "*", - "zod": "^3.21.4" - }, - "scripts": { - "lint": "eslint '**/*.{ts,js}'" - } -} diff --git a/src/services/database/serverless.yml b/src/services/database/serverless.yml deleted file mode 100644 index 63300e6dc..000000000 --- a/src/services/database/serverless.yml +++ /dev/null @@ -1,104 +0,0 @@ -service: ${self:custom.project}-database - -frameworkVersion: "3" - -package: - individually: true - -plugins: - - serverless-stack-termination-protection - - "@stratiformdigital/serverless-s3-security-helper" - - "@stratiformdigital/serverless-iam-helper" - - serverless-bundle - - serverless-plugin-scripts - -provider: - name: aws - region: us-east-1 - iam: - role: - path: /delegatedadmin/developer/ - permissionsBoundary: arn:aws:iam::${aws:accountId}:policy/cms-cloud-admin/developer-boundary-policy - statements: - - Effect: Allow - Action: - - dynamodb:Query - - dynamodb:Scan - - dynamodb:GetItem - - dynamodb:PutItem - - dynamodb:UpdateItem - - dynamodb:DeleteItem - - dynamodb:Get* - - dynamodb:BatchWrite* - - dynamodb:BatchGet* - Resource: "arn:aws:dynamodb:*:*:table/${self:custom.issuesTableName}" - - stackTags: - PROJECT: ${self:custom.project} - SERVICE: ${self:service} - -custom: - project: ${env:PROJECT} - referenceDataHash: ${file(./src/reference/items.json)} - serverlessTerminationProtection: - stages: # Apply CloudFormation termination protection for these stages - - master - - val - - production - bundle: - linting: false - issuesTableName: ${self:service}-${sls:stage}-issues - scripts: - commands: - seed: | - set -e - echo 'Loading test data...' - call=`aws lambda invoke --region ${self:provider.region} --function-name ${self:service}-${sls:stage}-testDataLoader --invocation-type RequestResponse --log Tail /dev/null` - error=`echo $call | jq 'select(.FunctionError != null)'` - if [ "$error" != "null" -a -n "$error" ]; then - echo "An error occured while loading test data. Error below" - echo `echo $call | jq -r '.LogResult'` | base64 --decode - exit 1 - fi - -functions: - seeddatabase: - handler: handlers/seeddatabase.handler - environment: - region: ${self:provider.region} - testDataLoader: - handler: handlers/testDataLoader.handler - environment: - region: ${self:provider.region} - tableName: !Ref IssuesTable - -resources: - Resources: - IssuesTable: - Type: AWS::DynamoDB::Table - Properties: - AttributeDefinitions: - - AttributeName: id - AttributeType: S - KeySchema: - - AttributeName: id - KeyType: HASH - PointInTimeRecoverySpecification: - PointInTimeRecoveryEnabled: true - ProvisionedThroughput: - ReadCapacityUnits: 1 - WriteCapacityUnits: 1 - TableName: ${self:custom.issuesTableName} - # InitializeDynamoDB: - # Type: Custom::InitFunction - # DependsOn: IssuesTable - # Properties: - # ServiceToken: - # Fn::GetAtt: [SeeddatabaseLambdaFunction, "Arn"] - # DynamoTableName: - # Ref: IssuesTable - # # Trigger: ${self:custom.referenceDataHash} - Outputs: - IssuesTableName: - Description: database table name for issues - Value: ${self:custom.issuesTableName} diff --git a/src/services/database/src/reference/items.json b/src/services/database/src/reference/items.json deleted file mode 100644 index 75ddea4bc..000000000 --- a/src/services/database/src/reference/items.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "id": "67-tyuiop", - "state": "CA" - }, - { - "id": "76-SeargentBrianwasHere", - "state": "OH" - }, - { - "id": "96-kings", - "state": "DE" - }, - { - "id": "45-dialect", - "state": "UT" - } -] \ No newline at end of file diff --git a/src/services/database/tsconfig.json b/src/services/database/tsconfig.json deleted file mode 100644 index 8625c1d4b..000000000 --- a/src/services/database/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "exclude": [ - "./docs/**/*", - "./src/services/**/*", - "./src/libs/**/*", - "./src/tests/**/**" - ], - "compilerOptions": { - "resolveJsonModule": true, - "target": "es5", - "module": "commonjs", - "strict": true - } -} diff --git a/src/services/ui/e2e/tests/issues/issues.spec.ts b/src/services/ui/e2e/tests/issues/issues.spec.ts deleted file mode 100644 index bdb09d5de..000000000 --- a/src/services/ui/e2e/tests/issues/issues.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { test, expect, Page } from "@playwright/test"; -import { v4 as uuidv4 } from "uuid"; -import * as $ from "@/selectors"; - -async function goToIssuesPage(page: Page) { - const navSelectors = new $.NavSelectors(page); - await page.goto("/"); - - // Click the issues link. - await navSelectors.issuesDropDown.click(); - await navSelectors.allIssuesLink.click(); -} - -test("create issue should require description", async ({ page }) => { - const addIssuesFormSelectors = new $.AddIssueFormSelectors(page); - goToIssuesPage(page); - - // fills in all inputs except description - await addIssuesFormSelectors.addButton.click(); - await addIssuesFormSelectors.titleInput.fill("Here is a test title"); - await addIssuesFormSelectors.prioritySelect.selectOption("medium"); - await addIssuesFormSelectors.typeSelect.selectOption("other"); - await addIssuesFormSelectors.submitButton.click(); - - // expects required error to be displayed - await expect(page.getByText("Description is required")).toBeVisible(); -}); - -test("should be able to create and delete an issue", async ({ page }) => { - const addIssuesFormSelectors = new $.AddIssueFormSelectors(page); - - const testDesc = uuidv4(); - goToIssuesPage(page); - - // completes and submits new issues form - await addIssuesFormSelectors.addButton.click(); - await addIssuesFormSelectors.titleInput.fill("Here is a test title"); - await addIssuesFormSelectors.descriptionInput.fill(testDesc); - await addIssuesFormSelectors.prioritySelect.selectOption("medium"); - await addIssuesFormSelectors.typeSelect.selectOption("other"); - await addIssuesFormSelectors.submitButton.click(); - - // expect the page to be rerouted - await expect(page).toHaveURL(/.*issues/); - - // expect the issue row to exist - await expect(page.getByRole("cell", { name: testDesc })).toBeVisible(); - - // Select the "Delete" button using a single XPath selector - const buttonSelector = `//td[text()='${testDesc}']/following-sibling::td/button[@aria-label='Delete button']`; - - // Click the "Delete" button - await page.click(buttonSelector); - - // expect the row to be deleted - await expect(page.getByRole("cell", { name: testDesc })).not.toBeVisible(); -}); diff --git a/src/services/ui/src/api/index.ts b/src/services/ui/src/api/index.ts index cb7c326f5..328d88b3d 100644 --- a/src/services/ui/src/api/index.ts +++ b/src/services/ui/src/api/index.ts @@ -1,3 +1 @@ -export * from "./useCreateIssue"; -export * from "./useGetIssue"; -export * from "./useGetIssues"; +export * from "./useGetSeatool"; diff --git a/src/services/ui/src/api/useCreateIssue.ts b/src/services/ui/src/api/useCreateIssue.ts deleted file mode 100644 index c1b2e26b3..000000000 --- a/src/services/ui/src/api/useCreateIssue.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { CreateIssue, validateCreateIssue } from "shared-types"; -import { API } from "aws-amplify"; - -export const useCreateIssue = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: async (issue: CreateIssue) => { - const validIssue = validateCreateIssue(issue); - - try { - return await API.post("issues", "/issues", { body: validIssue }); - } catch (err: any) { - console.log(err); - throw { - messages: err?.response?.issues || [ - { message: "An Error has occured" }, - ], - }; - } - }, - onSuccess: () => { - queryClient.invalidateQueries(["issues"]); - }, - onError: (err: { messages: [{ message: string }] }) => err, - }); -}; diff --git a/src/services/ui/src/api/useDeleteIssue.ts b/src/services/ui/src/api/useDeleteIssue.ts deleted file mode 100644 index af0052142..000000000 --- a/src/services/ui/src/api/useDeleteIssue.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { API } from "aws-amplify"; - -export const useDeleteIssue = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: async (id: string) => { - return await API.del("issues", `/issues/${id}`, {}); - }, - onSuccess: () => { - queryClient.invalidateQueries(["issues"]); - }, - }); -}; diff --git a/src/services/ui/src/api/useGetIssue.ts b/src/services/ui/src/api/useGetIssue.ts deleted file mode 100644 index 134cbadc9..000000000 --- a/src/services/ui/src/api/useGetIssue.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { validateIssue } from "shared-types"; -import { API } from "aws-amplify"; - -export const getIssue = async (id: string) => { - const issue = await API.get("issues", `/issues/${id}`, {}); - const validIssue = validateIssue(issue); - - return validIssue; -}; - -export const useGetIssue = (id: string) => - useQuery({ - queryFn: () => getIssue(id), - queryKey: ["issues", id], - }); diff --git a/src/services/ui/src/api/useGetIssues.ts b/src/services/ui/src/api/useGetIssues.ts deleted file mode 100644 index 8dfc62c6d..000000000 --- a/src/services/ui/src/api/useGetIssues.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { useQuery } from "@tanstack/react-query"; -import { validateListIssues } from "shared-types"; -import { API } from "aws-amplify"; - -export const getIssues = async () => { - const issues = await API.get("issues", "/issues", {}); - const validIssues = validateListIssues(issues); - - return validIssues; -}; - -export const useGetIssues = () => - useQuery({ - queryKey: ["issues"], - queryFn: getIssues, - }); diff --git a/src/services/ui/src/api/useGetSeatool.ts b/src/services/ui/src/api/useGetSeatool.ts index 85e48b274..fe588da7f 100644 --- a/src/services/ui/src/api/useGetSeatool.ts +++ b/src/services/ui/src/api/useGetSeatool.ts @@ -5,7 +5,7 @@ import { SeatoolData, ReactQueryApiError } from "shared-types"; export const getSeaToolData = async ( stateCode: string ): Promise => { - const seaToolData = await API.get("issues", `/seatool/${stateCode}`, {}); + const seaToolData = await API.get("seatool", `/seatool/${stateCode}`, {}); return seaToolData; }; diff --git a/src/services/ui/src/api/useUpdateIssue.ts b/src/services/ui/src/api/useUpdateIssue.ts deleted file mode 100644 index 9b5305f84..000000000 --- a/src/services/ui/src/api/useUpdateIssue.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { Issue, validateIssue } from "shared-types"; -import { API } from "aws-amplify"; - -export const useUpdateissue = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: async (issue: Issue) => { - const validIssue = validateIssue(issue); - - try { - await API.put("issues", `/issues/${validIssue.id}`, { - body: validIssue, - }); - return validIssue; - } catch (err: any) { - throw { - messages: err?.response?.issues || [ - { message: "An Error has occured" }, - ], - }; - } - }, - onSuccess: (e) => { - queryClient.refetchQueries(["issues", e.id]); - }, - onError: (err: { messages: [{ message: string }] }) => err, - }); -}; diff --git a/src/services/ui/src/components/AddIssueForm/index.tsx b/src/services/ui/src/components/AddIssueForm/index.tsx deleted file mode 100644 index 5529299a9..000000000 --- a/src/services/ui/src/components/AddIssueForm/index.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { useForm } from "react-hook-form"; -import { zodResolver } from "@hookform/resolvers/zod"; -import * as UI from "@enterprise-cmcs/macpro-ux-lib"; -import { ErrorMessage } from "@hookform/error-message"; -import { CreateIssue, createIssueSchema } from "shared-types"; -import { useCreateIssue } from "../../api"; -import { useNavigate } from "react-router-dom"; - -export function AddIssueForm({ callback }: { callback?: () => void }) { - const { - register, - handleSubmit, - formState: { errors }, - } = useForm({ resolver: zodResolver(createIssueSchema) }); - const { isLoading, mutateAsync, error } = useCreateIssue(); - const navigate = useNavigate(); - const onSubmit = async (data: CreateIssue) => { - try { - await mutateAsync(data); - navigate("/issues"); - if (callback) { - callback(); - } - } catch (err) { - console.log(err); - } - }; - - return ( -
- <> - {error && - error.messages.map(({ message }) => ( -
- -
- ))} -
-
- - - ( - - {message} - - )} - /> -
-
- -