From f6ccfcc5cf78d70cc2a9231c0a9d284f717c7990 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Mon, 27 May 2024 13:29:02 -0700 Subject: [PATCH 01/21] feat: change twu scoring --- src/shared/lib/resources/opportunity/team-with-us.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/lib/resources/opportunity/team-with-us.ts b/src/shared/lib/resources/opportunity/team-with-us.ts index c544deff4..e37f000ad 100644 --- a/src/shared/lib/resources/opportunity/team-with-us.ts +++ b/src/shared/lib/resources/opportunity/team-with-us.ts @@ -9,8 +9,8 @@ export { Addendum } from "shared/lib/resources/addendum"; export const DEFAULT_OPPORTUNITY_TITLE = "Untitled"; export const DEFAULT_QUESTIONS_WEIGHT = 25; -export const DEFAULT_CODE_CHALLENGE_WEIGHT = 50; -export const DEFAULT_PRICE_WEIGHT = 25; +export const DEFAULT_CODE_CHALLENGE_WEIGHT = 65; +export const DEFAULT_PRICE_WEIGHT = 10; export const MAX_RESOURCE_QUESTIONS = 100; export const MAX_RESOURCE_QUESTION_WORD_LIMIT = 3000; export const DEFAULT_RESOURCE_QUESTION_RESPONSE_WORD_LIMIT = 300; From 93c3d41a6f38fa233c5a066665b27b04b69ef851 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Thu, 6 Jun 2024 15:04:41 -0700 Subject: [PATCH 02/21] fix: allow admins to delete under review twu opps --- src/back-end/lib/resources/opportunity/team-with-us.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/back-end/lib/resources/opportunity/team-with-us.ts b/src/back-end/lib/resources/opportunity/team-with-us.ts index 5fdb3ef40..5b02a3629 100644 --- a/src/back-end/lib/resources/opportunity/team-with-us.ts +++ b/src/back-end/lib/resources/opportunity/team-with-us.ts @@ -1185,7 +1185,12 @@ const delete_: crud.Delete< if (isInvalid(validatedTWUOpportunity)) { return invalid({ notFound: ["Opportunity not found."] }); } - if (validatedTWUOpportunity.value.status !== TWUOpportunityStatus.Draft) { + if ( + ![ + TWUOpportunityStatus.Draft, + TWUOpportunityStatus.UnderReview + ].includes(validatedTWUOpportunity.value.status) + ) { return invalid({ permissions: [permissions.ERROR_MESSAGE] }); } return valid(validatedTWUOpportunity.value.id); From b4cb82afcbdf20afe46e0b5a5ac80de3cb686894 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Tue, 25 Jun 2024 16:30:41 -0700 Subject: [PATCH 03/21] fix: type change for existing counters query --- src/back-end/lib/db/counter.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/back-end/lib/db/counter.ts b/src/back-end/lib/db/counter.ts index f223f86a3..6e98a4f67 100644 --- a/src/back-end/lib/db/counter.ts +++ b/src/back-end/lib/db/counter.ts @@ -5,14 +5,16 @@ import { Counter } from "shared/lib/resources/counter"; export const incrementCounters = tryDb<[string[]], Record>( async (connection, names) => { // Update existing counters - const existingCounters: string[] = await connection("viewCounters") + const existingCounters: { name: string }[] = await connection( + "viewCounters" + ) .whereIn("name", names) .increment("count") .update({}, "name"); // Create new counters where applicable for (const name of names) { - if (!existingCounters.includes(name)) { + if (!existingCounters.some(({ name: eName }) => eName === name)) { await connection("viewCounters").insert({ name, count: 1 From 524753900bfbce2a7fe16bc8302390747280333a Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Wed, 26 Jun 2024 11:23:53 -0700 Subject: [PATCH 04/21] feat: test organization create --- .../resources/organization.test.ts | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 tests/back-end/integration/resources/organization.test.ts diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts new file mode 100644 index 000000000..210d3cfd0 --- /dev/null +++ b/tests/back-end/integration/resources/organization.test.ts @@ -0,0 +1,87 @@ +import { app } from "back-end/index"; +import { clearTestDatabase } from "tests/back-end/integration/helpers"; +import { + insertUserWithActiveSession, + requestWithCookie +} from "tests/back-end/integration/helpers/user"; +import { omit } from "lodash"; +import { connection } from "tests/back-end/setup-server.jest"; +import CAPABILITY_NAMES_ONLY from "shared/lib/data/capabilities"; +import { CreateRequestBody } from "shared/lib/resources/organization"; +import { UserType } from "shared/lib/resources/user"; +import { agent } from "supertest"; +import { buildOrganization } from "tests/utils/generate/organization"; +import { buildCreateUserParams } from "tests/utils/generate/user"; + +async function setup() { + const [testUser1, testUser1Session] = await insertUserWithActiveSession( + buildCreateUserParams({ + type: UserType.Vendor, + capabilities: CAPABILITY_NAMES_ONLY + }), + connection + ); + const [testUser2, testUser2Session] = await insertUserWithActiveSession( + buildCreateUserParams({ + type: UserType.Vendor, + capabilities: CAPABILITY_NAMES_ONLY + }), + connection + ); + const [testAdmin, testAdminSession] = await insertUserWithActiveSession( + buildCreateUserParams({ type: UserType.Admin }), + connection + ); + + if (!(testAdminSession && testUser1Session && testUser2Session)) { + throw new Error("Failed to create test sessions"); + } + + const user1AppAgent = agent(app); + const user2AppAgent = agent(app); + const adminAppAgent = agent(app); + return { + testUser1, + testUser2, + testUser1Session, + testUser2Session, + testAdmin, + testAdminSession, + user1AppAgent, + user2AppAgent, + adminAppAgent + }; +} + +afterEach(async () => { + await clearTestDatabase(connection); +}); + +test("organization crud", async () => { + const { testUser1Session, user1AppAgent } = await setup(); + + const body: CreateRequestBody = omit(buildOrganization(), [ + "id", + "createdAt", + "updatedAt", + "logoImageFile", + "active", + "owner", + "acceptedSWUTerms", + "acceptedTWUTerms", + "possessAllCapabilities", + "possessOneServiceArea", + "numTeamMembers", + "serviceAreas" + ]); + + const createRequest = user1AppAgent.post("/api/organizations").send(body); + + const createResult = await requestWithCookie(createRequest, testUser1Session); + + expect(createResult.status).toEqual(201); + expect(createResult.body).toMatchObject({ + ...body, + contactEmail: body.contactEmail.toLowerCase() + }); +}); From 932cbe220b858686980b00928468f5660c469488 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Wed, 26 Jun 2024 11:25:12 -0700 Subject: [PATCH 05/21] feat: test organization read --- tests/back-end/integration/resources/organization.test.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 210d3cfd0..3f5d86d4a 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -84,4 +84,12 @@ test("organization crud", async () => { ...body, contactEmail: body.contactEmail.toLowerCase() }); + + const organizationId = createResult.body.id; + const organizationIdUrl = `/api/organizations/${organizationId}`; + + const readResult = await user1AppAgent.get(organizationIdUrl); + + expect(readResult.status).toEqual(200); + expect(readResult.body).toEqual(createResult.body); }); From 0940c23324af9eb97e01d027d1ef3ded1048a509 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Wed, 26 Jun 2024 11:34:48 -0700 Subject: [PATCH 06/21] feat: test organization edit --- .../integration/resources/organization.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 3f5d86d4a..105dfd22b 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -12,6 +12,7 @@ import { UserType } from "shared/lib/resources/user"; import { agent } from "supertest"; import { buildOrganization } from "tests/utils/generate/organization"; import { buildCreateUserParams } from "tests/utils/generate/user"; +import { adt } from "shared/lib/types"; async function setup() { const [testUser1, testUser1Session] = await insertUserWithActiveSession( @@ -92,4 +93,16 @@ test("organization crud", async () => { expect(readResult.status).toEqual(200); expect(readResult.body).toEqual(createResult.body); + + const editedBody = { ...body, legalName: "Updated Name" }; + const editResult = await user1AppAgent + .put(organizationIdUrl) + .send(adt("updateProfile", editedBody)); + + expect(editResult.status).toEqual(200); + expect(editResult.body).toMatchObject({ + ...readResult.body, + legalName: editedBody.legalName, + updatedAt: expect.any(String) + }); }); From 49b78c68e711a9d23f4194c19f78798792caaca5 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Thu, 27 Jun 2024 15:25:54 -0700 Subject: [PATCH 07/21] feat: test organization accept swu terms --- .../integration/resources/organization.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 105dfd22b..ba868a25a 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -105,4 +105,15 @@ test("organization crud", async () => { legalName: editedBody.legalName, updatedAt: expect.any(String) }); + + const acceptSWUTermsResult = await user1AppAgent + .put(organizationIdUrl) + .send(adt("acceptSWUTerms")); + + expect(acceptSWUTermsResult.status).toEqual(200); + expect(acceptSWUTermsResult.body).toMatchObject({ + ...editResult.body, + acceptedSWUTerms: expect.any(String), + updatedAt: expect.any(String) + }); }); From 843d841613ee339081bca30f1df3c02e74ff8ee3 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Thu, 27 Jun 2024 15:43:52 -0700 Subject: [PATCH 08/21] feat: organization accept twu terms --- .../integration/resources/organization.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index ba868a25a..5f97b3095 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -116,4 +116,15 @@ test("organization crud", async () => { acceptedSWUTerms: expect.any(String), updatedAt: expect.any(String) }); + + const acceptTWUTermsResult = await user1AppAgent + .put(organizationIdUrl) + .send(adt("acceptTWUTerms")); + + expect(acceptTWUTermsResult.status).toEqual(200); + expect(acceptTWUTermsResult.body).toMatchObject({ + ...acceptSWUTermsResult.body, + acceptedTWUTerms: expect.any(String), + updatedAt: expect.any(String) + }); }); From 10117d9a0fd23cb3f5c13efa51cf686a333fdc48 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Thu, 27 Jun 2024 16:34:48 -0700 Subject: [PATCH 09/21] feat: test organization qualify service areas --- .../resources/organization.test.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 5f97b3095..0aea4ee7d 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -7,6 +7,7 @@ import { import { omit } from "lodash"; import { connection } from "tests/back-end/setup-server.jest"; import CAPABILITY_NAMES_ONLY from "shared/lib/data/capabilities"; +import ALL_SERVICE_AREAS from "shared/lib/data/service-areas"; import { CreateRequestBody } from "shared/lib/resources/organization"; import { UserType } from "shared/lib/resources/user"; import { agent } from "supertest"; @@ -59,7 +60,8 @@ afterEach(async () => { }); test("organization crud", async () => { - const { testUser1Session, user1AppAgent } = await setup(); + const { testUser1Session, testAdminSession, user1AppAgent, adminAppAgent } = + await setup(); const body: CreateRequestBody = omit(buildOrganization(), [ "id", @@ -127,4 +129,29 @@ test("organization crud", async () => { acceptedTWUTerms: expect.any(String), updatedAt: expect.any(String) }); + + const qualifyServiceAreasRequest = adminAppAgent + .put(organizationIdUrl) + .send(adt("qualifyServiceAreas", ALL_SERVICE_AREAS)); + + const qualifyServiceAreasResult = await requestWithCookie( + qualifyServiceAreasRequest, + testAdminSession + ); + + expect(qualifyServiceAreasResult.status).toEqual(200); + expect(qualifyServiceAreasResult.body).toMatchObject({ + ...acceptTWUTermsResult.body, + possessOneServiceArea: true, + serviceAreas: expect.arrayContaining( + ALL_SERVICE_AREAS.map((serviceArea) => + expect.objectContaining({ + id: expect.any(Number), + serviceArea, + name: expect.any(String) + }) + ) + ), + updatedAt: expect.any(String) + }); }); From b272691d09857a8089800d880b3388541c923b12 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 10:29:16 -0700 Subject: [PATCH 10/21] feat: test organization read many --- .../resources/organization.test.ts | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 0aea4ee7d..4298e53af 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -59,9 +59,17 @@ afterEach(async () => { await clearTestDatabase(connection); }); +const endpoint = "/api/organizations"; + test("organization crud", async () => { - const { testUser1Session, testAdminSession, user1AppAgent, adminAppAgent } = - await setup(); + const { + testUser1Session, + testUser2Session, + testAdminSession, + user1AppAgent, + user2AppAgent, + adminAppAgent + } = await setup(); const body: CreateRequestBody = omit(buildOrganization(), [ "id", @@ -78,7 +86,7 @@ test("organization crud", async () => { "serviceAreas" ]); - const createRequest = user1AppAgent.post("/api/organizations").send(body); + const createRequest = user1AppAgent.post(endpoint).send(body); const createResult = await requestWithCookie(createRequest, testUser1Session); @@ -89,7 +97,7 @@ test("organization crud", async () => { }); const organizationId = createResult.body.id; - const organizationIdUrl = `/api/organizations/${organizationId}`; + const organizationIdUrl = `${endpoint}/${organizationId}`; const readResult = await user1AppAgent.get(organizationIdUrl); @@ -154,4 +162,31 @@ test("organization crud", async () => { ), updatedAt: expect.any(String) }); + + const createForDeleteBody: CreateRequestBody = omit(buildOrganization(), [ + "id", + "createdAt", + "updatedAt", + "logoImageFile", + "active", + "owner", + "acceptedSWUTerms", + "acceptedTWUTerms", + "possessAllCapabilities", + "possessOneServiceArea", + "numTeamMembers", + "serviceAreas" + ]); + + const createForDeleteRequest = user2AppAgent + .post(endpoint) + .send(createForDeleteBody); + + await requestWithCookie(createForDeleteRequest, testUser2Session); + + const readManyBeforeDeleteResult = await adminAppAgent.get( + `${endpoint}?page=1&pageSize=50` + ); + expect(readManyBeforeDeleteResult.status).toEqual(200); + expect(readManyBeforeDeleteResult.body.items).toHaveLength(2); }); From b9f559e7fe71be5f9279740e75f6f2827778a080 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:06:34 -0700 Subject: [PATCH 11/21] test: organization delete --- .../resources/organization.test.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 4298e53af..5bf1b4b36 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -14,6 +14,7 @@ import { agent } from "supertest"; import { buildOrganization } from "tests/utils/generate/organization"; import { buildCreateUserParams } from "tests/utils/generate/user"; import { adt } from "shared/lib/types"; +import { MembershipType } from "shared/lib/resources/affiliation"; async function setup() { const [testUser1, testUser1Session] = await insertUserWithActiveSession( @@ -63,6 +64,8 @@ const endpoint = "/api/organizations"; test("organization crud", async () => { const { + testUser1, + testUser2, testUser1Session, testUser2Session, testAdminSession, @@ -187,6 +190,29 @@ test("organization crud", async () => { const readManyBeforeDeleteResult = await adminAppAgent.get( `${endpoint}?page=1&pageSize=50` ); + expect(readManyBeforeDeleteResult.status).toEqual(200); expect(readManyBeforeDeleteResult.body.items).toHaveLength(2); + + // Add affiliation to test deletion with events + await user1AppAgent.post("/api/affiliations").send({ + userEmail: testUser2.email, + organization: organizationId, + membershipType: MembershipType.Member + }); + + const deleteResult = await user1AppAgent.delete(organizationIdUrl); + + expect(deleteResult.status).toEqual(200); + expect(deleteResult.body).toMatchObject({ + ...qualifyServiceAreasResult.body, + possessAllCapabilities: false, // Don't think this is specified anywhere + active: false, + deactivatedOn: expect.any(String), + deactivatedBy: testUser1.id, + updatedAt: expect.any(String) + }); + + const readDeletedResult = await user1AppAgent.get(organizationIdUrl); + expect(readDeletedResult.status).toEqual(404); }); From 43b4ebac3700fa8cf88cee1571b86b3d43a7e029 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:09:34 -0700 Subject: [PATCH 12/21] feat: test organization read many after delete --- tests/back-end/integration/resources/organization.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/back-end/integration/resources/organization.test.ts b/tests/back-end/integration/resources/organization.test.ts index 5bf1b4b36..5a714e737 100644 --- a/tests/back-end/integration/resources/organization.test.ts +++ b/tests/back-end/integration/resources/organization.test.ts @@ -215,4 +215,10 @@ test("organization crud", async () => { const readDeletedResult = await user1AppAgent.get(organizationIdUrl); expect(readDeletedResult.status).toEqual(404); + + const readManyAfterDeleteResult = await adminAppAgent.get( + `${endpoint}?page=1&pageSize=50` + ); + expect(readManyAfterDeleteResult.status).toEqual(200); + expect(readManyAfterDeleteResult.body.items).toHaveLength(1); }); From 761e360a9e2c33cb374c5bc8dc65ea0800d760c2 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:11:32 -0700 Subject: [PATCH 13/21] refactor: add ability to convert inactive raw affiliations --- src/back-end/lib/db/affiliation.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/back-end/lib/db/affiliation.ts b/src/back-end/lib/db/affiliation.ts index 8702946d3..9282c5a76 100644 --- a/src/back-end/lib/db/affiliation.ts +++ b/src/back-end/lib/db/affiliation.ts @@ -47,11 +47,12 @@ export interface RawHistoryRecord async function rawAffiliationToAffiliation( connection: Connection, - params: RawAffiliation + params: RawAffiliation, + allowInactive = false ): Promise { const { user: userId, organization: orgId } = params; const organization = getValidValue( - await readOneOrganization(connection, orgId, false), + await readOneOrganization(connection, orgId, allowInactive), null ); const user = getValidValue(await readOneUser(connection, userId), null); From de3edd0b12401355926c98f269bf937912f2594d Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:12:39 -0700 Subject: [PATCH 14/21] refactor: optionally read inactive affiliations by id --- src/back-end/lib/db/affiliation.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/back-end/lib/db/affiliation.ts b/src/back-end/lib/db/affiliation.ts index 9282c5a76..680aac57b 100644 --- a/src/back-end/lib/db/affiliation.ts +++ b/src/back-end/lib/db/affiliation.ts @@ -137,8 +137,8 @@ export const readOneAffiliation = tryDb<[Id, Id], Affiliation | null>( ); export const readOneAffiliationById = tryDb<[Id, boolean?], Affiliation | null>( - async (connection, id, activeOnly = true) => { - const result = await connection("affiliations") + async (connection, id, allowInactive = false) => { + let query = connection("affiliations") .join( "organizations", "affiliations.organization", @@ -147,16 +147,21 @@ export const readOneAffiliationById = tryDb<[Id, boolean?], Affiliation | null>( ) .select("affiliations.*") .where({ "affiliations.id": id }) - .andWhereNot({ - ...(activeOnly - ? { "affiliations.membershipStatus": MembershipStatus.Inactive } - : {}), - "organizations.active": false - }) .first(); + if (!allowInactive) { + query = query.andWhereNot({ + "affiliations.membershipStatus": MembershipStatus.Inactive, + "organizations.active": false + }); + } + + const result = await query; + return valid( - result ? await rawAffiliationToAffiliation(connection, result) : null + result + ? await rawAffiliationToAffiliation(connection, result, allowInactive) + : null ); } ); From 49d74e9e72c909d92bbfce403ae3765ea15756d0 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:13:43 -0700 Subject: [PATCH 15/21] fix: read inactive affiliations for org history --- src/back-end/lib/db/organization.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back-end/lib/db/organization.ts b/src/back-end/lib/db/organization.ts index 6cc7d98b7..0d458298a 100644 --- a/src/back-end/lib/db/organization.ts +++ b/src/back-end/lib/db/organization.ts @@ -171,7 +171,7 @@ async function rawHistoryRecordToHistoryRecord( const { affiliation: affilationId, event: type, ...restOfRaw } = value; const affiliation = getValidValue( - await readOneAffiliationById(connection, affilationId, false), + await readOneAffiliationById(connection, affilationId, true), null ); From d8a9aba4aa8eb4809d01b10c1c88c1900c0670ca Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:15:29 -0700 Subject: [PATCH 16/21] fix: don't attempt to destructure before result is defined --- src/back-end/lib/db/organization.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/back-end/lib/db/organization.ts b/src/back-end/lib/db/organization.ts index 0d458298a..963e2c321 100644 --- a/src/back-end/lib/db/organization.ts +++ b/src/back-end/lib/db/organization.ts @@ -365,15 +365,14 @@ export const readOneOrganization = tryDb< query = query.andWhere({ "organizations.active": true }); } - const resultWithViewerIsOrgAdmin = await query.first< - RawOrganization & { viewerIsOrgAdmin: boolean } + const result = await query.first< + RawOrganization & { viewerIsOrgAdmin?: boolean } >(); - const { viewerIsOrgAdmin, ...result } = resultWithViewerIsOrgAdmin; if (result) { if ( !session || (isVendor(session) && - !(result.owner === session.user?.id || viewerIsOrgAdmin)) + !(result.owner === session.user?.id || result.viewerIsOrgAdmin)) ) { delete result.owner; delete result.numTeamMembers; @@ -412,6 +411,7 @@ export const readOneOrganization = tryDb< ) ) ); + delete result.viewerIsOrgAdmin; } } return valid( From d8a429ad875d58d09af33933cf383e4324e87368 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 11:18:12 -0700 Subject: [PATCH 17/21] fix: read inactive organizations for proponent orgs --- src/back-end/lib/db/proposal/code-with-us.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/back-end/lib/db/proposal/code-with-us.ts b/src/back-end/lib/db/proposal/code-with-us.ts index decac62cf..7aad98d1c 100644 --- a/src/back-end/lib/db/proposal/code-with-us.ts +++ b/src/back-end/lib/db/proposal/code-with-us.ts @@ -180,7 +180,7 @@ async function rawCWUProposalSlimToCWUProposalSlim( : null; const proponentOrganization = proponentOrganizationId ? getValidValue( - await readOneOrganization(connection, proponentOrganizationId), + await readOneOrganization(connection, proponentOrganizationId, true), undefined ) : null; From 9c57fcfac2609ef57f41246b0b3dcf256d08d7ba Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 14:15:21 -0700 Subject: [PATCH 18/21] fix: attempt to use proposal organization on review tab swu --- .../lib/pages/proposal/sprint-with-us/lib/components/form.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/front-end/typescript/lib/pages/proposal/sprint-with-us/lib/components/form.tsx b/src/front-end/typescript/lib/pages/proposal/sprint-with-us/lib/components/form.tsx index d41a5d9a5..3303ff1e9 100644 --- a/src/front-end/typescript/lib/pages/proposal/sprint-with-us/lib/components/form.tsx +++ b/src/front-end/typescript/lib/pages/proposal/sprint-with-us/lib/components/form.tsx @@ -1248,7 +1248,8 @@ const ReviewProposalView: component_.base.View = ({ dispatch }) => { const phaseMembers = Team.getAddedMembers(state.team); - const organization = getSelectedOrganization(state); + const organization = + state.proposal?.organization ?? getSelectedOrganization(state); const opportunity = state.opportunity; return ( From 28617f6f8068dca1f227e699b39b66e86f2c571e Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Fri, 28 Jun 2024 14:15:46 -0700 Subject: [PATCH 19/21] fix: attempt to use proposal organization on review tab twu --- .../lib/pages/proposal/team-with-us/lib/components/form.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/front-end/typescript/lib/pages/proposal/team-with-us/lib/components/form.tsx b/src/front-end/typescript/lib/pages/proposal/team-with-us/lib/components/form.tsx index aa40a29a5..8382a98be 100644 --- a/src/front-end/typescript/lib/pages/proposal/team-with-us/lib/components/form.tsx +++ b/src/front-end/typescript/lib/pages/proposal/team-with-us/lib/components/form.tsx @@ -758,7 +758,8 @@ const ReviewProposalView: component_.base.View = ({ state, dispatch }) => { - const organization = getSelectedOrganization(state); + const organization = + state.proposal?.organization ?? getSelectedOrganization(state); const team = Team.getValues(state.team); const resourcesWithMemberSelections = state.opportunity.resources.map( (resource) => { From 1c9e910aa61a97192eff2b9933246ad4d58cd96b Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Tue, 2 Jul 2024 10:11:59 -0700 Subject: [PATCH 20/21] Revert "feat: twu banner display logic" This reverts commit e8b263e8fd48d3db23a6df92d5dbf3ddcdf61f54. --- src/front-end/typescript/config.ts | 2 -- src/front-end/typescript/lib/app/init.ts | 7 +------ src/front-end/typescript/lib/app/types.ts | 2 -- src/front-end/typescript/lib/app/update.ts | 19 +------------------ 4 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/front-end/typescript/config.ts b/src/front-end/typescript/config.ts index 8c9710c89..0296a26b7 100644 --- a/src/front-end/typescript/config.ts +++ b/src/front-end/typescript/config.ts @@ -65,5 +65,3 @@ export const CWU_PAYMENT_OPTIONS_URL = export const TWU_BC_BID_URL = "https://bcbid.gov.bc.ca/page.aspx/en/bpm/process_manage_extranet/176305"; - -export const TWU_BANNER_ACKNOWLEDGED = "twu-banner-acknowledged"; diff --git a/src/front-end/typescript/lib/app/init.ts b/src/front-end/typescript/lib/app/init.ts index b91fa361c..d9a081abe 100644 --- a/src/front-end/typescript/lib/app/init.ts +++ b/src/front-end/typescript/lib/app/init.ts @@ -1,4 +1,3 @@ -import { TWU_BANNER_ACKNOWLEDGED } from "front-end/config"; import { State, Msg } from "front-end/lib/app/types"; import * as Nav from "front-end/lib/app/view/nav"; import * as AcceptNewTerms from "front-end/lib/components/accept-new-app-terms"; @@ -16,7 +15,6 @@ const init: component.base.Init = () => { const [navState, navCmds] = Nav.init(null); return [ { - showTWUBanner: false, ready: false, incomingRoute: null, toasts: [], @@ -35,10 +33,7 @@ const init: component.base.Init = () => { acceptNewTermsCmds, (msg) => adt("acceptNewTerms", msg) as Msg ), - ...component.cmd.mapMany(navCmds, (msg) => adt("nav", msg) as Msg), - component.cmd.localStorage.getItem(TWU_BANNER_ACKNOWLEDGED, (msg) => - adt("setShowTWUBanner", !msg) - ) + ...component.cmd.mapMany(navCmds, (msg) => adt("nav", msg) as Msg) ] ]; }; diff --git a/src/front-end/typescript/lib/app/types.ts b/src/front-end/typescript/lib/app/types.ts index 706daa7aa..e84708632 100644 --- a/src/front-end/typescript/lib/app/types.ts +++ b/src/front-end/typescript/lib/app/types.ts @@ -146,7 +146,6 @@ export type ModalId = "acceptNewTerms"; export interface State { //App Internal State ready: boolean; - showTWUBanner: boolean; incomingRoute: router.IncomingRoute | null; activeRoute: Route; //Toasts @@ -229,7 +228,6 @@ export type InnerMsg = | ADT<"submitAcceptNewTerms"> | ADT<"onAcceptNewTermsResponse", AcceptNewTerms.AcceptNewTermsResponse> | ADT<"nav", Nav.Msg> - | ADT<"setShowTWUBanner", boolean> | ADT<"pageLanding", PageLanding.Msg> | ADT<"pageDashboard", PageDashboard.Msg> | ADT<"pageOpportunities", PageOpportunities.Msg> diff --git a/src/front-end/typescript/lib/app/update.ts b/src/front-end/typescript/lib/app/update.ts index 837685b5f..346c2e94a 100644 --- a/src/front-end/typescript/lib/app/update.ts +++ b/src/front-end/typescript/lib/app/update.ts @@ -1,7 +1,4 @@ -import { - TOAST_AUTO_DISMISS_DURATION, - TWU_BANNER_ACKNOWLEDGED -} from "front-end/config"; +import { TOAST_AUTO_DISMISS_DURATION } from "front-end/config"; import { makeStartLoading, makeStopLoading } from "front-end/lib"; import router from "front-end/lib/app/router"; import { @@ -915,20 +912,6 @@ const update: component.base.Update = ({ state, msg }) => { mapChildMsg: adtCurried>("nav") }); - case "setShowTWUBanner": - return [ - state.set("showTWUBanner", msg.value), - !msg.value - ? [ - component.cmd.localStorage.setItem( - TWU_BANNER_ACKNOWLEDGED, - TWU_BANNER_ACKNOWLEDGED, - adt("noop") as Msg - ) - ] - : [] - ]; - case "pageOrgEdit": return component.app.updatePage({ ...defaultPageUpdateParams, From d88f336a8fea10a566c1256b090dd7b6f32bd6d6 Mon Sep 17 00:00:00 2001 From: IanFonzie Date: Tue, 2 Jul 2024 10:25:03 -0700 Subject: [PATCH 21/21] Revert "feat: display twu banner" This reverts commit 34ce3565bbf6384c44ef3feffdf50967b2c81f79. --- src/front-end/sass/index.scss | 6 --- .../typescript/lib/app/view/index.tsx | 5 -- .../typescript/lib/app/view/twu-banner.tsx | 46 ------------------- 3 files changed, 57 deletions(-) delete mode 100644 src/front-end/typescript/lib/app/view/twu-banner.tsx diff --git a/src/front-end/sass/index.scss b/src/front-end/sass/index.scss index c48152a96..3efda61a2 100644 --- a/src/front-end/sass/index.scss +++ b/src/front-end/sass/index.scss @@ -964,12 +964,6 @@ nav.navbar .nav-link:hover { } } -.twu-banner { - background-color: $c-banner-bg; - padding: 0.75rem 0 0.75rem; - z-index: 1001; // Above nav, below modals -} - .li-paren { counter-reset: list; & > li { diff --git a/src/front-end/typescript/lib/app/view/index.tsx b/src/front-end/typescript/lib/app/view/index.tsx index 13f99f834..d414ab509 100644 --- a/src/front-end/typescript/lib/app/view/index.tsx +++ b/src/front-end/typescript/lib/app/view/index.tsx @@ -88,7 +88,6 @@ import { SHOW_TEST_INDICATOR } from "shared/config"; import { hasAcceptedTermsOrIsAnonymous } from "shared/lib/resources/session"; import { UserType } from "shared/lib/resources/user"; import { ADT, adt, adtCurried } from "shared/lib/types"; -import TWUBannner from "front-end/lib/app/view/twu-banner"; function makeViewPageProps( props: component_.base.ComponentViewProps, @@ -890,10 +889,6 @@ const view: component_.base.ComponentView = (props) => { navProps.contextualActions ? "contextual-actions-visible" : "" } app d-flex flex-column`} style={{ minHeight: "100vh" }}> - dispatch(adt("setShowTWUBanner", false))} - /> {viewPageProps.component.simpleNav ? null :