Skip to content

Commit

Permalink
Merge branch 'main' into dp/vite
Browse files Browse the repository at this point in the history
  • Loading branch information
DafyddLlyr authored Aug 26, 2024
2 parents c712f92 + 0dbb6d4 commit cac0464
Show file tree
Hide file tree
Showing 60 changed files with 992 additions and 770 deletions.
2 changes: 1 addition & 1 deletion doc/how-to/how-to-add-a-list-component-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The ideal maintainers of these schemas are still the services team though, rathe

2. **GitHub** - In the `.ts` file, ensure the schema has this basic structure:
```ts
import { Schema } from "@planx/components/List/model";
import { Schema } from "@planx/component/shared/Schema/model";

export const YourSchemasName: Schema = {
type: "Title (singular if no max, plural if max = 1)",
Expand Down
61 changes: 61 additions & 0 deletions doc/how-to/how-to-setup-metabase-for-a-new-team-or-service.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# How to setup a Metabase collection for a new team

## What is Metabase?
[Metabase](https://www.metabase.com/) is an open source BI service which we self-host as part of PlanX. It allows teams to view and self-serve analytics dashboards related to their flows, applications, and users.

Metabase is set up and running on both Staging and Production environments, but only the Production instance (with Production data) has dashboards maintained and curated for teams.

## Context
The Metabase analytics dashboards are currently created per-published service.

We would like to automate this process as much as possible, but currently it is _all manual_.

This means that each time a council goes live with a service, they let us know (eg via Slack) and we go through the process below.

## Process

To do any of the below, you will need to be logged into the Production Metabase service at https://metabase.editor.planx.uk/. Login details are stored on the OSL 1Password account.

### Setting up Metabase for a new team

_This happens only if a team is new / about to publish their first live service._

1. Check if a team Collection (folder) already exists in Metabase. If not, create a new one.

![Screenshot - Add a Collection](./images/setup-metabase/new_collection.png)

### Setting up Metabase for a new Service

_This happens after a team lets us know that a service is going live._

1. Enter the 'Templates' Collection using the navigation bar on the left and duplicate the relevant template, replacing 'Template' with the council name. Duplicate it into the relevant team's Collection (folder).

![Screenshot - Templates Collection](./images/setup-metabase/templates.png)
![Screenshot - Duplicate the dashboard](./images/setup-metabase/duplicate_a_dashboard.png)

* Ensure "Only duplicate the dashboard" is selected. This avoids unecessarily duplicating the visualisations which we maintain, and also means if we need to update anything, the changes will propagate across the dashboards.

![Screenshot - Only duplicate the dashboard](./images/setup-metabase/only_duplicate_dashboard.png)

* Not all teams host the same services on PlanX. Ensure you only duplicate Dashboards for public, live flows. This can be checked via the PlanX Editor. We currently only have templates for three services: Find Out If You Need Planning Permission, Apply for a Lawful Development Service, and Report a Breach.

2. Navigate to the new Dashboard to update the team slug and service slug default value variables.

![Screenshot - Team slug variable](./images/setup-metabase/team_slug_default_value.png)
![Screenshot - Service slug variable](./images/setup-metabase/service_slug_default_value.png)

* Edit Dashboard > \['Team slug' or 'Service slug'\] > Default Value > Enter > Done > Save*

* This variable ensures that the dashboard is looking at analytics and statistics for the correct flow.

3. You should now see the chart update, and the variables in the top left match the slugs for the new team's flow.
![Screenshot - Default values are being filtered for](./images/setup-metabase/default_values_filtered.png)

4. Enable sharing by turning the 'Public' link on.

![Screenshot - Enable sharing](./images/setup-metabase/enable_sharing.png)
![Screenshot - Share Dashboard link with team by turning 'Public' link on.](./images/setup-metabase/share_with_team.png)

5. Add the dashboard, private and public links to the OSL internal 'Analytics overview' Notion page (PlanX > Analytics overview).

6. To add the link to the editor, update the `flows.analytics_link` column in Hasura with the public URL (generated in step 4), for each flow a dashboard has been generated for.
61 changes: 0 additions & 61 deletions doc/how-to/how-to-setup-metabase-for-a-new-team.md

This file was deleted.

Binary file removed doc/how-to/images/setup-metabase/default_value.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file removed doc/how-to/images/setup-metabase/flow_id.png
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/how-to/images/setup-metabase/templates.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ vi.mock("@opensystemslab/planx-core", () => {
it("should not have any accessibility violations", async () => {
const { container } = setup(
<ConfirmationComponent
color={{ text: "#000", background: "rgba(1, 99, 96, 0.1)" }}
heading="heading"
description="description"
nextSteps={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,19 @@ describe("slotSchema", () => {
expect(result).toBe(false);
});

it("rejects slots which failed to upload", async () => {
const mockSlots = [
{ status: "error" },
{ status: "success" },
] as FileUploadSlot[];

const result = await slotsSchema.isValid(mockSlots, {
context: { fileList: mockFileList },
});

expect(result).toBe(false);
});

it("allows slots with all files uploaded", async () => {
const mockSlots = [
{ status: "success" },
Expand All @@ -197,6 +210,40 @@ describe("slotSchema", () => {

expect(result).toBe(true);
});

it("allows users to proceed if there are no required files", async () => {
const mockSlots: FileUploadSlot[] = [];

const result = await slotsSchema.isValid(mockSlots, {
context: {
fileList: {
required: [],
recommended: [
{ ...mockFileTypes.AlwaysRecommended, slots: [{ id: "123" }] },
],
optional: [{ ...mockFileTypes.NotRequired, slots: [{ id: "456" }] }],
},
},
});

expect(result).toBe(true);
});

it("allows users to proceed if there are no required files, and they have not uploaded any optional or recommended files", async () => {
const mockSlots: FileUploadSlot[] = [];

const result = await slotsSchema.isValid(mockSlots, {
context: {
fileList: {
required: [],
recommended: [{ ...mockFileTypes.AlwaysRecommended }],
optional: [{ ...mockFileTypes.NotRequired }],
},
},
});

expect(result).toBe(true);
});
});

describe("fileLabelSchema", () => {
Expand Down
16 changes: 6 additions & 10 deletions editor.planx.uk/src/@planx/components/FileUploadAndLabel/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,11 @@ export const slotsSchema = array()
if (!slots) throw new Error("Missing slots for slotsSchema");

const { fileList } = context as SlotsSchemaTestContext;
const allFilesOptional =
!fileList.recommended.length && !fileList.required.length;
const isMinFileUploadCountSatisfied =
allFilesOptional || slots.length > 0;
const noFilesAreRequired = Boolean(!fileList.required.length);
if (noFilesAreRequired) return true;

return isMinFileUploadCountSatisfied;
const isAtLeastOneFileUploaded = slots.length > 0;
return isAtLeastOneFileUploaded;
},
})
.test({
Expand All @@ -101,11 +100,8 @@ export const slotsSchema = array()
name: "errorStatus",
message: "Remove files which failed to upload",
test: (slots?: Array<FileUploadSlot>) => {
return Boolean(
slots &&
slots.length > 0 &&
!slots.some((slot) => slot.status === "error"),
);
const didAnyUploadFail = slots?.some((slot) => slot.status === "error");
return !didAnyUploadFail;
},
});

Expand Down
Loading

0 comments on commit cac0464

Please sign in to comment.