Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/components/people.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The `groups` array determines which page sections a person appears in:
|-------------|----------------------|----------------|
| `steeringCommittee` | Steering Committee / Board | Subscriptions with committee roles linked to "Steering Committee" PWCI |
| `administrativeTeam` | Our Team (staff) | GSF Team DB, Status = "Active" |
| `chairsAndLeads` | Chairs & Project Leads | Subscriptions with roles: WG Chair, Project Lead/Co-Lead, Committee Chair/Vice-Chair |
| `chairsAndLeads` | Chairs & Project Leads | Subscriptions with roles: WG Chair, Project Lead/Co-Lead, Chair/Vice Chair, Committee Chair/Vice-Chair |
| `organisationalLeads` | Organisation Leads | Subscriptions with Role = "Organization Lead" |

A person can belong to multiple groups and appears in each corresponding section.
Expand Down
20 changes: 20 additions & 0 deletions docs/notion.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,26 @@ Person data for subscription-based people (name, title, LinkedIn, member org) is
- `Subscription Status` (select) — must be "Active"
- Roll-up fields: `First Name`, `Surname`, `Title`, `LinkedIn`, `Member`, `Volunteer Status`

#### Distinguishing leadership on a standards page (e.g. Chair vs Vice Chair)

`fetchChairsAndLeads()` in `scripts/fetch-notion-data.cjs` maps `Role for Subscription` values to the `roleLabel` shown next to a project lead's name in `projects.json` (consumed by `TeamGrid` on standards pages):

| Role for Subscription | roleLabel shown on site |
|---|---|
| `Working Group Chair` | Chair |
| `Project Lead` | Lead |
| `Project Co-Lead` | Co-Lead |
| `Chair` | Project Lead (Chair) |
| `Vice Chair` | Vice Chair |
| `Project Chair` | Project Lead (Chair) |
| `Project Vice Chair` | Vice Chair |
| `Committee Chair` | Chair |
| `Committee Vice-Chair` | Vice-Chair |

When a project has multiple "Project Lead" subscriptions and needs to distinguish a Chair from a Vice Chair (as opposed to two equal leads), set one person's `Role for Subscription` to `Project Chair` and the other's to `Project Vice Chair` rather than leaving both as `Project Lead`.

**Careful when picking a value in Notion's select field:** typing a value that isn't an exact match for an existing option silently creates a *new* option instead of reusing one — this is how `Chair`/`Vice Chair`/`Project Chair`/`Project Vice Chair` all ended up coexisting as separate, easily-confused options. Always pick from the existing dropdown list rather than retyping the text. `Project Chair` and `Project Vice Chair` are the canonical values to use going forward; `Chair` and `Vice Chair` are kept mapped for compatibility but are unused stray options that could be deleted from the Notion schema.

### Volunteers DB

- `First Name`, `Last Name` (rich text)
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Each standards page is a long-form landing page for a specific GSF standard/proj
- **Project metadata** — imported from `src/data/projects.json`. Each page looks up its project by slug (e.g. `projects.find(p => p.slug === "sci")`)
- **Lifecycle stage** — displayed as a badge in the hero, read from `projects.json`
- **Parent working group** — resolved from `projects.json` to show "A [WG Name] Project"
- **Project leads** — the `leads` array from `projects.json` provides `fullName` and `roleLabel`
- **Project leads** — the `leads` array from `projects.json` provides `fullName` and `roleLabel`. Notion's query order isn't guaranteed, so pages that need a deterministic display order (e.g. Chair before Vice Chair) should sort the array by `roleLabel` in the page itself rather than relying on array order — see the `leadRoleRank()` helper in `src/pages/standards/swi/index.astro`

See [Notion doc](../notion.md) for how `projects.json` is populated from the PWCIs database.

Expand Down
8 changes: 8 additions & 0 deletions scripts/fetch-notion-data.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ async function fetchChairsAndLeads(memberById) {
"Working Group Chair",
"Project Lead",
"Project Co-Lead",
"Chair",
"Vice Chair",
"Project Chair",
"Project Vice Chair",
"Committee Chair",
"Committee Vice-Chair",
"Committee Member",
Expand Down Expand Up @@ -447,6 +451,10 @@ async function fetchChairsAndLeads(memberById) {
"Working Group Chair": "Chair",
"Project Lead": "Lead",
"Project Co-Lead": "Co-Lead",
"Chair": "Project Lead (Chair)",
"Vice Chair": "Vice Chair",
"Project Chair": "Project Lead (Chair)",
"Project Vice Chair": "Vice Chair",
"Committee Chair": "Chair",
"Committee Vice-Chair": "Vice-Chair",
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/standards/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const standardDefs = [
{ slug: "silo" },
{ slug: "wdpc" },
{ slug: "open19" },
{ slug: "see", urlSlug: "sei" },
{ slug: "sei" },
{ slug: "swe" },
];
const standardProjects = standardDefs
Expand Down
12 changes: 6 additions & 6 deletions src/pages/standards/sei/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ import ArticleCarousel from "@/components/article-carousel.astro";
import projects from "@/data/projects.json";
import { getCollection } from "astro:content";
import { articleUrl } from "@/lib/utils";
const seeProject = projects.find(p => p.slug === "see");
const parentWg = projects.find(p => p.name === seeProject?.parent);
const seiProject = projects.find(p => p.slug === "sei");
const parentWg = projects.find(p => p.name === seiProject?.parent);

const carouselArticles = (await getCollection("articles", (a) => a.data.published !== false))
.filter(a => (a.data.tags || []).map((t: string) => t.toLowerCase()).includes("see"))
.filter(a => (a.data.tags || []).map((t: string) => t.toLowerCase()).includes("sei"))
.sort((a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime())
.map(a => ({
title: a.data.title,
Expand Down Expand Up @@ -56,7 +56,7 @@ const carouselArticles = (await getCollection("articles", (a) => a.data.publishe
<Hero
badges={[
...(parentWg ? [{ text: `A ${parentWg.name} Project` }] : []),
...(seeProject?.lifecycle ? [{ text: seeProject.lifecycle, variant: "dark" as const }] : []),
...(seiProject?.lifecycle ? [{ text: seiProject.lifecycle, variant: "dark" as const }] : []),
]}
heading="Measure the Energy Intensity of"
headingAccent="Your Software"
Expand Down Expand Up @@ -211,9 +211,9 @@ const carouselArticles = (await getCollection("articles", (a) => a.data.publishe
<TeamGrid
heading="Project *Leadership*"
body={parentWg ? `Part of the ${parentWg.name}` : ""}
columns={seeProject?.leads?.length === 2 ? 2 : 3}
columns={seiProject?.leads?.length === 2 ? 2 : 3}
highlighted={[]}
members={(seeProject?.leads ?? []).map(lead => ({
members={(seiProject?.leads ?? []).map(lead => ({
fullName: lead.fullName,
role: lead.roleLabel,
}))}
Expand Down
17 changes: 13 additions & 4 deletions src/pages/standards/swi/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ import { articleUrl } from "@/lib/utils";
const sweProject = projects.find(p => p.slug === "swe");
const parentWg = projects.find(p => p.name === sweProject?.parent);

// Chair before Vice Chair before other lead roles, regardless of Notion query order
function leadRoleRank(roleLabel: string): number {
if (/chair/i.test(roleLabel) && !/vice/i.test(roleLabel)) return 0;
if (/vice.?chair/i.test(roleLabel)) return 1;
return 2;
}

const carouselArticles = (await getCollection("articles", (a) => a.data.published !== false))
.filter(a => (a.data.tags || []).map((t: string) => t.toLowerCase()).includes("swe"))
.sort((a, b) => new Date(b.data.date).getTime() - new Date(a.data.date).getTime())
Expand Down Expand Up @@ -184,10 +191,12 @@ const carouselArticles = (await getCollection("articles", (a) => a.data.publishe
body={parentWg ? `Part of the ${parentWg.name}` : ""}
columns={sweProject.leads.length === 2 ? 2 : 3}
highlighted={[]}
members={sweProject.leads.map(lead => ({
fullName: lead.fullName,
role: lead.roleLabel,
}))}
members={[...sweProject.leads]
.sort((a, b) => leadRoleRank(a.roleLabel) - leadRoleRank(b.roleLabel))
.map(lead => ({
fullName: lead.fullName,
role: lead.roleLabel,
}))}
bgClass="bg-white"
/>
)}
Expand Down
Loading