diff --git a/api.planx.uk/package.json b/api.planx.uk/package.json index bb7322e82b..0b18173107 100644 --- a/api.planx.uk/package.json +++ b/api.planx.uk/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@airbrake/node": "^2.1.8", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#95b54b3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#a70159d", "@types/isomorphic-fetch": "^0.0.36", "adm-zip": "^0.5.10", "aws-sdk": "^2.1467.0", diff --git a/api.planx.uk/pnpm-lock.yaml b/api.planx.uk/pnpm-lock.yaml index 492566fb10..e05b8160ce 100644 --- a/api.planx.uk/pnpm-lock.yaml +++ b/api.planx.uk/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^2.1.8 version: 2.1.8 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#95b54b3 - version: github.com/theopensystemslab/planx-core/95b54b3 + specifier: git+https://github.com/theopensystemslab/planx-core#a70159d + version: github.com/theopensystemslab/planx-core/a70159d '@types/isomorphic-fetch': specifier: ^0.0.36 version: 0.0.36 @@ -8714,8 +8714,8 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - github.com/theopensystemslab/planx-core/95b54b3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/95b54b3} + github.com/theopensystemslab/planx-core/a70159d: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/a70159d} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/e2e/tests/api-driven/package.json b/e2e/tests/api-driven/package.json index 6fedc20130..90676c8452 100644 --- a/e2e/tests/api-driven/package.json +++ b/e2e/tests/api-driven/package.json @@ -6,7 +6,7 @@ }, "dependencies": { "@cucumber/cucumber": "^9.3.0", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#95b54b3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#a70159d", "axios": "^1.6.0", "dotenv": "^16.3.1", "dotenv-expand": "^10.0.0", diff --git a/e2e/tests/api-driven/pnpm-lock.yaml b/e2e/tests/api-driven/pnpm-lock.yaml index 9e5b84862d..0c5e3c95f0 100644 --- a/e2e/tests/api-driven/pnpm-lock.yaml +++ b/e2e/tests/api-driven/pnpm-lock.yaml @@ -9,8 +9,8 @@ dependencies: specifier: ^9.3.0 version: 9.3.0 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#95b54b3 - version: github.com/theopensystemslab/planx-core/95b54b3 + specifier: git+https://github.com/theopensystemslab/planx-core#a70159d + version: github.com/theopensystemslab/planx-core/a70159d axios: specifier: ^1.6.0 version: 1.6.0 @@ -2821,8 +2821,8 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - github.com/theopensystemslab/planx-core/95b54b3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/95b54b3} + github.com/theopensystemslab/planx-core/a70159d: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/a70159d} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/e2e/tests/ui-driven/package.json b/e2e/tests/ui-driven/package.json index 6c26eecc28..e2def13698 100644 --- a/e2e/tests/ui-driven/package.json +++ b/e2e/tests/ui-driven/package.json @@ -8,7 +8,7 @@ "postinstall": "./install-dependencies.sh" }, "dependencies": { - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#95b54b3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#a70159d", "axios": "^1.6.2", "dotenv": "^16.3.1", "eslint": "^8.56.0", diff --git a/e2e/tests/ui-driven/pnpm-lock.yaml b/e2e/tests/ui-driven/pnpm-lock.yaml index dedc834860..a19091e4a5 100644 --- a/e2e/tests/ui-driven/pnpm-lock.yaml +++ b/e2e/tests/ui-driven/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#95b54b3 - version: github.com/theopensystemslab/planx-core/95b54b3 + specifier: git+https://github.com/theopensystemslab/planx-core#a70159d + version: github.com/theopensystemslab/planx-core/a70159d axios: specifier: ^1.6.2 version: 1.6.2 @@ -2568,8 +2568,8 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - github.com/theopensystemslab/planx-core/95b54b3: - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/95b54b3} + github.com/theopensystemslab/planx-core/a70159d: + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/a70159d} name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/editor.planx.uk/package.json b/editor.planx.uk/package.json index 6c2b7ab765..4108e046f7 100644 --- a/editor.planx.uk/package.json +++ b/editor.planx.uk/package.json @@ -14,7 +14,7 @@ "@mui/styles": "^5.14.5", "@mui/utils": "^5.14.5", "@opensystemslab/map": "^0.7.5", - "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#95b54b3", + "@opensystemslab/planx-core": "git+https://github.com/theopensystemslab/planx-core#a70159d", "@tiptap/core": "^2.0.3", "@tiptap/extension-bold": "^2.0.3", "@tiptap/extension-bubble-menu": "^2.1.13", diff --git a/editor.planx.uk/pnpm-lock.yaml b/editor.planx.uk/pnpm-lock.yaml index b667561e0c..2d5af7ad3f 100644 --- a/editor.planx.uk/pnpm-lock.yaml +++ b/editor.planx.uk/pnpm-lock.yaml @@ -45,8 +45,8 @@ dependencies: specifier: ^0.7.5 version: 0.7.5 '@opensystemslab/planx-core': - specifier: git+https://github.com/theopensystemslab/planx-core#95b54b3 - version: github.com/theopensystemslab/planx-core/95b54b3(@types/react@18.2.45) + specifier: git+https://github.com/theopensystemslab/planx-core#a70159d + version: github.com/theopensystemslab/planx-core/a70159d(@types/react@18.2.45) '@tiptap/core': specifier: ^2.0.3 version: 2.0.3(@tiptap/pm@2.0.3) @@ -6209,7 +6209,7 @@ packages: '@storybook/core-common': 7.1.1 '@storybook/node-logger': 7.1.1 '@storybook/types': 7.1.1 - '@types/node': 16.18.66 + '@types/node': 16.18.68 ts-dedent: 2.2.0 transitivePeerDependencies: - encoding @@ -20934,9 +20934,9 @@ packages: use-sync-external-store: 1.2.0(react@18.2.0) dev: false - github.com/theopensystemslab/planx-core/95b54b3(@types/react@18.2.45): - resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/95b54b3} - id: github.com/theopensystemslab/planx-core/95b54b3 + github.com/theopensystemslab/planx-core/a70159d(@types/react@18.2.45): + resolution: {tarball: https://codeload.github.com/theopensystemslab/planx-core/tar.gz/a70159d} + id: github.com/theopensystemslab/planx-core/a70159d name: '@opensystemslab/planx-core' version: 1.0.0 prepare: true diff --git a/editor.planx.uk/src/components/Header.test.tsx b/editor.planx.uk/src/components/Header.test.tsx index ac64dcebc0..a10b3b9b9c 100644 --- a/editor.planx.uk/src/components/Header.test.tsx +++ b/editor.planx.uk/src/components/Header.test.tsx @@ -18,6 +18,9 @@ const mockTeam1: Team = { slug: "opensystemslab", theme: { logo: "logo.jpg", + primary: "#0010A4", + secondary: null, + favicon: null, }, }; diff --git a/editor.planx.uk/src/components/Header.tsx b/editor.planx.uk/src/components/Header.tsx index 8e112c4ebf..17157ecc37 100644 --- a/editor.planx.uk/src/components/Header.tsx +++ b/editor.planx.uk/src/components/Header.tsx @@ -183,7 +183,7 @@ const TeamLogo: React.FC = () => { const altText = teamSettings?.homepage ? `${teamName} Homepage (opens in a new tab)` : `${teamName} Logo`; - const logo = ; + const logo = ; return teamSettings?.homepage ? ( {logo} diff --git a/editor.planx.uk/src/routes/views/published.tsx b/editor.planx.uk/src/routes/views/published.tsx index ac121b0c26..f583bfcedc 100644 --- a/editor.planx.uk/src/routes/views/published.tsx +++ b/editor.planx.uk/src/routes/views/published.tsx @@ -71,7 +71,12 @@ const fetchDataForPublishedView = async ( ) { id team { - theme + theme { + primary: primary_colour + secondary: secondary_colour + logo + favicon + } name settings slug diff --git a/editor.planx.uk/src/routes/views/standalone.tsx b/editor.planx.uk/src/routes/views/standalone.tsx index 9169cde616..71452b5033 100644 --- a/editor.planx.uk/src/routes/views/standalone.tsx +++ b/editor.planx.uk/src/routes/views/standalone.tsx @@ -59,7 +59,12 @@ const fetchDataForStandaloneView = async ( ) { id team { - theme + theme { + primary: primary_colour + secondary: secondary_colour + logo + favicon + } name settings slug diff --git a/editor.planx.uk/src/routes/views/unpublished.tsx b/editor.planx.uk/src/routes/views/unpublished.tsx index d4de06d5d2..1495df6059 100644 --- a/editor.planx.uk/src/routes/views/unpublished.tsx +++ b/editor.planx.uk/src/routes/views/unpublished.tsx @@ -62,7 +62,12 @@ const fetchDataForUnpublishedView = async ( ) { id team { - theme + theme { + primary: primary_colour + secondary: secondary_colour + logo + favicon + } name settings slug diff --git a/editor.planx.uk/src/types.ts b/editor.planx.uk/src/types.ts index a5521603c1..63450fe9fa 100644 --- a/editor.planx.uk/src/types.ts +++ b/editor.planx.uk/src/types.ts @@ -27,8 +27,10 @@ export interface Team { } export interface TeamTheme { - primary?: string; - logo?: string; + primary: string; + secondary: string | null; + logo: string | null; + favicon: string | null; } export interface TeamSettings { diff --git a/hasura.planx.uk/metadata/tables.yaml b/hasura.planx.uk/metadata/tables.yaml index 78080c7f4d..b39c99b7e8 100644 --- a/hasura.planx.uk/metadata/tables.yaml +++ b/hasura.planx.uk/metadata/tables.yaml @@ -1364,6 +1364,75 @@ - role: platformAdmin permission: filter: {} +- table: + name: team_themes + schema: public + select_permissions: + - role: api + permission: + columns: + - id + - team_id + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + comment: "" + - role: platformAdmin + permission: + columns: + - id + - team_id + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + comment: "" + - role: public + permission: + columns: + - id + - team_id + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + comment: "" + - role: teamEditor + permission: + columns: + - id + - team_id + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + comment: "" + update_permissions: + - role: platformAdmin + permission: + columns: + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + check: null + comment: "" + - role: teamEditor + permission: + columns: + - favicon + - logo + - primary_colour + - secondary_colour + filter: {} + check: null + comment: "" - table: name: teams schema: public @@ -1375,6 +1444,13 @@ table: name: team_integrations schema: public + - name: theme + using: + foreign_key_constraint_on: + column: team_id + table: + name: team_themes + schema: public array_relationships: - name: flows using: @@ -1411,7 +1487,6 @@ - settings - slug - submission_email - - theme - updated_at select_permissions: - role: api @@ -1427,7 +1502,6 @@ - settings - slug - submission_email - - theme - updated_at computed_fields: - boundary_bbox @@ -1443,7 +1517,6 @@ - reference_code - settings - slug - - theme - updated_at computed_fields: - boundary_bbox @@ -1460,7 +1533,6 @@ - reference_code - settings - slug - - theme - updated_at computed_fields: - boundary_bbox @@ -1476,7 +1548,6 @@ - reference_code - settings - slug - - theme - updated_at computed_fields: - boundary_bbox @@ -1491,7 +1562,6 @@ - settings - slug - submission_email - - theme filter: {} check: null - table: diff --git a/hasura.planx.uk/migrations/1703240593405_squashed/down.sql b/hasura.planx.uk/migrations/1703240593405_squashed/down.sql new file mode 100644 index 0000000000..562f65d546 --- /dev/null +++ b/hasura.planx.uk/migrations/1703240593405_squashed/down.sql @@ -0,0 +1,13 @@ +COMMENT ON COLUMN "public"."team_themes"."secondary_colour" IS NULL; + +COMMENT ON COLUMN "public"."team_themes"."primary_colour" IS NULL; + +ALTER TABLE "public"."team_themes" DROP CONSTRAINT "team_themes_team_id_key"; + +DROP TABLE "public"."team_themes"; + +ALTER TABLE "public"."teams" ADD COLUMN "theme" JSONB; + +ALTER TABLE "public"."teams" ALTER COLUMN "theme" SET DEFAULT '{}'::JSONB; + +ALTER TABLE "public"."teams" ALTER COLUMN "theme" DROP NOT NULL; \ No newline at end of file diff --git a/hasura.planx.uk/migrations/1703240593405_squashed/up.sql b/hasura.planx.uk/migrations/1703240593405_squashed/up.sql new file mode 100644 index 0000000000..848c01a062 --- /dev/null +++ b/hasura.planx.uk/migrations/1703240593405_squashed/up.sql @@ -0,0 +1,30 @@ +CREATE TABLE "public"."team_themes" ( + "id" serial NOT NULL, + "team_id" integer NOT NULL, + "primary_colour" text NOT NULL DEFAULT '#0010A4', + "secondary_colour" text, + "logo" text, + "favicon" text, + PRIMARY KEY ("id"), + FOREIGN KEY ("team_id") REFERENCES "public"."teams"("id") ON UPDATE cascade ON DELETE cascade +); + +ALTER TABLE + "public"."team_themes" +ADD + CONSTRAINT "team_themes_team_id_key" UNIQUE ("team_id"); + +COMMENT ON COLUMN "public"."team_themes"."primary_colour" IS E'Must be hex triplet (e.g. #112233)'; + +COMMENT ON COLUMN "public"."team_themes"."secondary_colour" IS E'Must be hex triplet (e.g. #112233)'; + +INSERT INTO + team_themes (team_id, primary_colour, logo) +SELECT + id AS team_id, + COALESCE(theme ->> 'primary', '#0010A4') AS primary_colour, + COALESCE(theme ->> 'logo', NULL) AS logo +FROM + teams; + +ALTER TABLE "public"."teams" DROP COLUMN "theme" CASCADE; \ No newline at end of file diff --git a/hasura.planx.uk/tests/team_themes.test.js b/hasura.planx.uk/tests/team_themes.test.js new file mode 100644 index 0000000000..e89ac77fc7 --- /dev/null +++ b/hasura.planx.uk/tests/team_themes.test.js @@ -0,0 +1,95 @@ +const { introspectAs } = require("./utils"); + +describe("team_themes", () => { + describe("public", () => { + let i; + beforeAll(async () => { + i = await introspectAs("public"); + }); + + test("can query team_themes", () => { + expect(i.queries).toContain("team_themes"); + }); + + test("cannot create, update, or delete team_themes", () => { + expect(i).toHaveNoMutationsFor("team_themes"); + }); + }); + + describe("admin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("admin"); + }); + + test("can query team_themes and team members", () => { + expect(i.queries).toContain("team_themes"); + }); + }); + + describe("platformAdmin", () => { + let i; + beforeAll(async () => { + i = await introspectAs("platformAdmin"); + }); + + test("can query team_themes", () => { + expect(i.queries).toContain("team_themes"); + }); + + test("cannot insert team_themes", () => { + expect(i.queries).not.toContain("insert_team_themes"); + }); + + test("can query team_themes", async () => { + expect(i.queries).toContain("team_themes"); + }); + + test("can mutate team_themes", async () => { + expect(i.mutations).toContain("update_team_themes"); + expect(i.mutations).toContain("update_team_themes_by_pk"); + }); + + test("cannot delete team_themes", async () => { + expect(i.mutations).not.toContain("delete_team_themes"); + }); + }); + + describe("teamEditor", () => { + beforeAll(async () => { + i = await introspectAs("teamEditor"); + }); + + test("can query team_themes", () => { + expect(i.queries).toContain("team_themes"); + }); + + test("can update team_themes", () => { + expect(i.mutations).toContain("update_team_themes"); + expect(i.mutations).toContain("update_team_themes_by_pk"); + }); + + test("cannot delete team_themes", async () => { + expect(i.mutations).not.toContain("delete_team_themes"); + }); + + test("cannot insert team_themes", async () => { + expect(i.mutations).not.toContain("insert_team_themes"); + }); + }); + + describe("api", () => { + let i; + beforeAll(async () => { + i = await introspectAs("api"); + }); + + test("can query team_themes", () => { + expect(i.queries).toContain("team_themes"); + }); + + test("cannot create, update, or delete team_themes", () => { + expect(i).toHaveNoMutationsFor("team_themes"); + }); + }); +}); diff --git a/scripts/seed-database/write/teams.sql b/scripts/seed-database/write/teams.sql index 1ffd5914a4..fcecd7cc85 100644 --- a/scripts/seed-database/write/teams.sql +++ b/scripts/seed-database/write/teams.sql @@ -3,6 +3,7 @@ CREATE TEMPORARY TABLE sync_teams ( id integer, name text, slug text, + -- TODO: Drop this and fetch from team_themes theme jsonb, created_at timestamptz, updated_at timestamptz, @@ -20,7 +21,6 @@ INSERT INTO teams ( id, name, slug, - theme, settings, notify_personalisation, boundary, @@ -30,7 +30,6 @@ SELECT id, name, slug, - theme, settings, notify_personalisation, boundary, @@ -40,7 +39,6 @@ ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, slug = EXCLUDED.slug, - theme = EXCLUDED.theme, settings = EXCLUDED.settings, notify_personalisation = EXCLUDED.notify_personalisation, boundary = EXCLUDED.boundary,