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,