From aa63cca53487fa7cbc4efac11869befae650a2f7 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:59:29 +0300 Subject: [PATCH 01/22] Update Datasets page Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../src/components/Dataset/Dataset.js | 35 ++++++++++--------- .../src/components/Dataset/Dataset.snap.js | 26 +++++++------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/apps/charterafrica/src/components/Dataset/Dataset.js b/apps/charterafrica/src/components/Dataset/Dataset.js index 9e2298c32..13636baf0 100644 --- a/apps/charterafrica/src/components/Dataset/Dataset.js +++ b/apps/charterafrica/src/components/Dataset/Dataset.js @@ -122,6 +122,24 @@ function Dataset({ ))} ) : null} + {labels.backToDatasets} - renders unchanged 1`] = ` +
@@ -69,19 +82,6 @@ exports[` renders unchanged 1`] = ` > Back to Datasets -
From 00d90d46fd01941748f8d35766e81af3cea8833e Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 15 Feb 2024 13:48:37 +0300 Subject: [PATCH 02/22] Update contributor Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../src/components/Entity/Entity.js | 33 ++++++++++++++++--- .../src/components/Entity/Entity.snap.js | 32 ++++++++---------- .../src/components/Entity/Entity.test.js | 16 +++++++-- .../data/common/processPageContributors.js | 16 ++++++--- .../src/lib/ecosystem/airtable/processData.js | 5 +++ .../src/payload/collections/Contributors.js | 20 +++++++++++ .../src/payload/globals/Ecosystem.js | 20 +++++++++++ apps/charterafrica/src/theme/index.js | 1 + mongo-keyfile | 16 +++++++++ 9 files changed, 130 insertions(+), 29 deletions(-) create mode 100644 mongo-keyfile diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index dbab1de15..f07165227 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -62,7 +62,16 @@ const SocialMediaLink = React.forwardRef(function SocialMediaLink(props, ref) { }); const Entity = React.forwardRef(function Entity(props, ref) { - const { name, location, description, image, tools, toolsTitle } = props; + const { + name, + location, + description, + image, + tools, + toolsTitle, + role, + currentOrganisation, + } = props; const icons = getIcons(props); return ( @@ -97,7 +106,7 @@ const Entity = React.forwardRef(function Entity(props, ref) { {name} @@ -106,14 +115,30 @@ const Entity = React.forwardRef(function Entity(props, ref) { textAlign={{ xs: "center", sm: "left" }} color="neutral.dark" sx={{ mt: 2.5, width: "100%" }} - variant="h4Small" + variant="p4" > - {location} + {role} + + + {currentOrganisation} + {location} + + {description} diff --git a/apps/charterafrica/src/components/Entity/Entity.snap.js b/apps/charterafrica/src/components/Entity/Entity.snap.js index adab90081..fc70fbf0e 100644 --- a/apps/charterafrica/src/components/Entity/Entity.snap.js +++ b/apps/charterafrica/src/components/Entity/Entity.snap.js @@ -35,17 +35,27 @@ exports[` renders unchanged 1`] = ` class="MuiGrid-root MuiGrid-item MuiGrid-grid-xs-12 MuiGrid-grid-sm-8 css-6q6fhx-MuiGrid-root" >
John Doe
+ Developer +
+
+ Charter Africa +
+
San Francisco, CA
Full-stack web developer with over 5 years of experience.
@@ -66,22 +76,6 @@ exports[` renders unchanged 1`] = ` />
-
diff --git a/apps/charterafrica/src/components/Entity/Entity.test.js b/apps/charterafrica/src/components/Entity/Entity.test.js index 54590acc6..6d0ba19cc 100644 --- a/apps/charterafrica/src/components/Entity/Entity.test.js +++ b/apps/charterafrica/src/components/Entity/Entity.test.js @@ -12,8 +12,18 @@ const defaultProps = { name: "John Doe", location: "San Francisco, CA", description: "Full-stack web developer with over 5 years of experience.", - twitter: "https://twitter.com/johndoe", - github: "https://github.com/johndoe", + socilaMedia: [ + { + name: "twitter", + link: "https://twitter.com/johndoe", + id: 1, + }, + { + name: "github", + link: "https://github.com/johndoe", + id: 2, + }, + ], email: "johndoe@example.com", image: "/static/images/avatar/1.jpg", tools: [ @@ -36,6 +46,8 @@ const defaultProps = { }, ], toolsTitle: "Favorite Tools", + role: "Developer", + currentOrganisation: "Charter Africa", }; describe("", () => { diff --git a/apps/charterafrica/src/lib/data/common/processPageContributors.js b/apps/charterafrica/src/lib/data/common/processPageContributors.js index 7fafbd62c..67ec33fea 100644 --- a/apps/charterafrica/src/lib/data/common/processPageContributors.js +++ b/apps/charterafrica/src/lib/data/common/processPageContributors.js @@ -91,6 +91,15 @@ async function processPagePerson(page, api, context) { }; }); + const { socialMedia = [] } = contributor; + if (contributor.source === "github") { + const github = { + link: `https://github.com/${contributor?.externalId || ""}`, + name: "gitHub", + }; + socialMedia.push(github); + } + return { ...page, blocks: [ @@ -99,6 +108,8 @@ async function processPagePerson(page, api, context) { id: block.id ?? null, image: contributor.avatarUrl ?? null, name: contributor?.fullName ?? contributor?.externalId ?? null, + role: contributor.role ?? null, + currentOrganisation: contributor.currentOrganisation ?? null, location: contributor.location ?? null, description: contributor.description ?? null, email: contributor.email ?? null, @@ -106,11 +117,8 @@ async function processPagePerson(page, api, context) { lastActive: contributor.lastActive ? formatDateTime(contributor.lastActive, {}) : null, - github: - contributor.source === "github" - ? `https://github.com/${contributor?.externalId || ""}` - : "", tools, + socialMedia, }, ], }; diff --git a/apps/charterafrica/src/lib/ecosystem/airtable/processData.js b/apps/charterafrica/src/lib/ecosystem/airtable/processData.js index 140e19fa6..2843d0de7 100644 --- a/apps/charterafrica/src/lib/ecosystem/airtable/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/airtable/processData.js @@ -170,6 +170,11 @@ export function processContributor(item, config) { return { airtableId: data.id, classification: getValue(data, contributorTableColumns.classification), + role: getValue(data, contributorTableColumns.role), + currentOrganisation: getValue( + data, + contributorTableColumns.currentOrganisation, + ), externalId, repoLink, socialMedia, diff --git a/apps/charterafrica/src/payload/collections/Contributors.js b/apps/charterafrica/src/payload/collections/Contributors.js index 62faec402..c76607f79 100644 --- a/apps/charterafrica/src/payload/collections/Contributors.js +++ b/apps/charterafrica/src/payload/collections/Contributors.js @@ -48,6 +48,26 @@ const Contributors = { readOnly: true, }, }, + { + name: "role", + type: "text", + label: { en: "Role", fr: "Rôle", pt: "Função" }, + admin: { + readOnly: true, + }, + }, + { + name: "currentOrganisation", + type: "text", + label: { + en: "Current Organization", + fr: "Organisation actuelle", + pt: "Organização atual", + }, + admin: { + readOnly: true, + }, + }, { name: "classification", type: "text", diff --git a/apps/charterafrica/src/payload/globals/Ecosystem.js b/apps/charterafrica/src/payload/globals/Ecosystem.js index 191bb54dc..97a0eeea3 100644 --- a/apps/charterafrica/src/payload/globals/Ecosystem.js +++ b/apps/charterafrica/src/payload/globals/Ecosystem.js @@ -369,6 +369,26 @@ const Ecosystem = { }, }, }), + airtableColumnSelect({ + schema, + tableField: "contributorTableId", + overrides: { + name: "role", + label: { en: "Role", fr: "Rôle", pt: "Função" }, + }, + }), + airtableColumnSelect({ + schema, + tableField: "contributorTableId", + overrides: { + name: "currentOrganisation", + label: { + en: "Current Organisation", + fr: "Organisation actuelle", + pt: "Organização atual", + }, + }, + }), airtableColumnSelect({ schema, tableField: "contributorTableId", diff --git a/apps/charterafrica/src/theme/index.js b/apps/charterafrica/src/theme/index.js index 7e5ff961d..893441e04 100644 --- a/apps/charterafrica/src/theme/index.js +++ b/apps/charterafrica/src/theme/index.js @@ -110,6 +110,7 @@ const theme = createTheme({ p2SemiBold: initializeTypographyVariant(16, 19, 600), p3: initializeTypographyVariant(18, 21.6), p3SemiBold: initializeTypographyVariant(18, 21.6, 600), + p4: initializeTypographyVariant(23, 28), body1: undefined, body2: undefined, caption: initializeTypographyVariant(12, 14), diff --git a/mongo-keyfile b/mongo-keyfile new file mode 100644 index 000000000..86e04bb2f --- /dev/null +++ b/mongo-keyfile @@ -0,0 +1,16 @@ +TsAdpaam/g3odJWCrVnKJ4xo0gdhTrXEJhNfqOB4ohK18ap6CY3nHL2KvpbpQjpk +NsyZrmaVIOt7E2wWq/8bEc8KgM3V1Maupize7CYrAjq/P8mfQsP1pH0cy4YucRi7 +/kqsH2VvKiYMBZzsWRZYng6k2x/BZCEJHlu5s/noLqcylAXOVMYKKexaAbFaSXcF +9rbF97E/vCCXrCRLpNINgpMiq3EmiLapQ4T7nT54BbJFtbCEhMayo+6kgZCh3jHp +LX2Nijddc9Brt7MKsKjvZKLc+c6NoKZqOhHU8I9YHrKf1wY577u47CUePvpUl4FX +D3IlGb2ZTily2LgPYwodNaxBbj+b4E0+4SR/oUvvIgLhwmbHlJXAUOpo1dMlx4ba +NIQJXXX3TKOkmMpfwfZPpM4XpgzobxON9dI4+K/7boXprdOj86lBGUaIfis5qTSv +2/A0P/HSn86vex7dzUWAs+lHAa0Q5PK1NdzzwPVlXJ4GDof0N6DzZ9l7+kR3U+ZZ +Gc5tRs6pTo6uex96fFAH7+02+qzxFe/GQzc/58cvoVt+eKI1UNij4CPEY7J4POxL +RRk2Z/MLh0aJnjzaWiTVwB2+AihG1KRCCgYX5EhxEay97/WkXpXNKL3eqDS0DyY1 +W49yoQjfEwEDuHdFC7wOe6Ni58qRmYW0L2aIa/X8ztCTZt1/O1blcUqufW7TJWBP +4VA/kFo9ckN9/IoqvQN05GbwUVtP9MzYQ4AS/7L60PS22aqbdqTFmOdRcrO+dVu9 +ELYtC+aW0eR+jScpiYM6y7RSiQDG0lFyiNjiAvibho5F0Y26dpdwgCY9oDSlLp2B +AhgfsKZXp6FZwNx0QQPDG1ojTpCGzqYlX66IaWrGSRtdtad5QavWqJGpAaqxGNxW +phJVZGhPeinK1pzxH25HnvQ+MGNNwc5xT72giM7dd9Hre81vkNcFeovEXrLCRf81 +TNQrv/8xLva6EwLpiHXyT2g5KhuO6GbbBQlvejAq64f/M596lCAgIZHV/i9ohhCd From 5b87b5c36c4e4115f3c4fd2df5f6cb8c16eb01c9 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:39:05 +0300 Subject: [PATCH 03/22] Remove keyfile Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- mongo-keyfile | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 mongo-keyfile diff --git a/mongo-keyfile b/mongo-keyfile deleted file mode 100644 index 86e04bb2f..000000000 --- a/mongo-keyfile +++ /dev/null @@ -1,16 +0,0 @@ -TsAdpaam/g3odJWCrVnKJ4xo0gdhTrXEJhNfqOB4ohK18ap6CY3nHL2KvpbpQjpk -NsyZrmaVIOt7E2wWq/8bEc8KgM3V1Maupize7CYrAjq/P8mfQsP1pH0cy4YucRi7 -/kqsH2VvKiYMBZzsWRZYng6k2x/BZCEJHlu5s/noLqcylAXOVMYKKexaAbFaSXcF -9rbF97E/vCCXrCRLpNINgpMiq3EmiLapQ4T7nT54BbJFtbCEhMayo+6kgZCh3jHp -LX2Nijddc9Brt7MKsKjvZKLc+c6NoKZqOhHU8I9YHrKf1wY577u47CUePvpUl4FX -D3IlGb2ZTily2LgPYwodNaxBbj+b4E0+4SR/oUvvIgLhwmbHlJXAUOpo1dMlx4ba -NIQJXXX3TKOkmMpfwfZPpM4XpgzobxON9dI4+K/7boXprdOj86lBGUaIfis5qTSv -2/A0P/HSn86vex7dzUWAs+lHAa0Q5PK1NdzzwPVlXJ4GDof0N6DzZ9l7+kR3U+ZZ -Gc5tRs6pTo6uex96fFAH7+02+qzxFe/GQzc/58cvoVt+eKI1UNij4CPEY7J4POxL -RRk2Z/MLh0aJnjzaWiTVwB2+AihG1KRCCgYX5EhxEay97/WkXpXNKL3eqDS0DyY1 -W49yoQjfEwEDuHdFC7wOe6Ni58qRmYW0L2aIa/X8ztCTZt1/O1blcUqufW7TJWBP -4VA/kFo9ckN9/IoqvQN05GbwUVtP9MzYQ4AS/7L60PS22aqbdqTFmOdRcrO+dVu9 -ELYtC+aW0eR+jScpiYM6y7RSiQDG0lFyiNjiAvibho5F0Y26dpdwgCY9oDSlLp2B -AhgfsKZXp6FZwNx0QQPDG1ojTpCGzqYlX66IaWrGSRtdtad5QavWqJGpAaqxGNxW -phJVZGhPeinK1pzxH25HnvQ+MGNNwc5xT72giM7dd9Hre81vkNcFeovEXrLCRf81 -TNQrv/8xLva6EwLpiHXyT2g5KhuO6GbbBQlvejAq64f/M596lCAgIZHV/i9ohhCd From 9551d07f832bc887f6f5895402e77b07ce5e9d15 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:04:21 +0300 Subject: [PATCH 04/22] Fetch Repos Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../src/lib/ecosystem/github/processData.js | 102 +++++++++++++----- .../src/payload/collections/Contributors.js | 40 +++++++ 2 files changed, 114 insertions(+), 28 deletions(-) diff --git a/apps/charterafrica/src/lib/ecosystem/github/processData.js b/apps/charterafrica/src/lib/ecosystem/github/processData.js index e113a7725..63eb7d4bd 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/github/processData.js @@ -47,7 +47,32 @@ const GET_REPOSITORY = `query($repositoryOwner: String!, $repositoryName: String } }`; -async function fetchRepository(variables) { +const GET_USER = `query($username: String!) { + user(login: $username) { + name + avatarUrl + url + email + location + login + websiteUrl + repositories(first: 3, orderBy: {field: STARGAZERS, direction: DESC}) { + edges { + node { + name + description + stargazers { + totalCount + } + visibility + url + } + } + } + } +}`; + +async function fetchGithubGraphqlApi(query, variables) { const url = `${BASE_URL}/graphql`; const headers = { "Content-Type": "application/json", @@ -55,15 +80,15 @@ async function fetchRepository(variables) { }; const data = { variables, - query: GET_REPOSITORY, + query, }; const res = await fetchJson.post(url, { data, headers }); - if (res?.data?.repository) { - return res.data.repository; + if (res?.data) { + return res.data; } - const message = `Unable to fetch ${variables.repositoryOwner}/${ - variables.repositoryName - } from github errors ${JSON.stringify(res.errors)}`; + const message = `Unable to fetch from github errors ${JSON.stringify( + res.errors, + )}`; Sentry.captureException(message); throw new FetchError(message, res.errors, 500); } @@ -108,29 +133,31 @@ export async function fetchTool({ externalId }) { return null; } - const data = await fetchRepository({ + const data = await fetchGithubGraphqlApi(GET_REPOSITORY, { repositoryOwner, repositoryName, }); - const techSkills = data.languages?.nodes?.map((language) => ({ + const { repository } = data; + + const techSkills = repository.languages?.nodes?.map((language) => ({ language: language?.name, })); - const commit = data?.defaultBranchRef?.target.history.edges?.[0]?.node; + const commit = repository?.defaultBranchRef?.target.history.edges?.[0]?.node; return { externalId, - repoLink: data.url, - link: data.homepageUrl, + repoLink: repository.url, + link: repository.homepageUrl, techSkills, lastCommit: { author: commit?.author?.name, committedDate: commit?.committedDate, message: commit?.message, }, - stars: data?.stargazers?.totalCount, - views: data?.watchers?.totalCount, - forks: data?.forks?.totalCount, + stars: repository?.stargazers?.totalCount, + views: repository?.watchers?.totalCount, + forks: repository?.forks?.totalCount, source: "github", - sourceUpdatedAt: new Date(data.updatedAt), + sourceUpdatedAt: new Date(repository.updatedAt), }; } @@ -150,19 +177,38 @@ export async function fetchOrganisation({ externalId, eTag }) { }; } -export async function fetchContributor({ externalId, eTag }) { - const data = await fetchGithubApi(`users/${externalId}`, eTag); - if (!data) { - return null; - } +export async function fetchContributor({ externalId }) { + const data = await fetchGithubGraphqlApi(GET_USER, { + username: externalId, + }); + const { + user: { name, avatarUrl, url, email, location, websiteUrl, repositories }, + } = data; + + const repos = repositories?.edges?.map((edge) => { + const { + name: repoName, + description, + stargazers, + visibility, + url: repoURL, + } = edge?.node ?? {}; + return { + name: repoName, + description, + stargazers: stargazers?.totalCount, + visibility, + url: repoURL, + }; + }); return { - fullName: data.name, - avatarUrl: data.avatar_url, - repoLink: data.html_url, - location: data.location, - website: data.blog, - email: data.email, - eTag: data.eTag, + fullName: name, + avatarUrl, + repoLink: url, + location, + website: websiteUrl, + email, + repositories: repos, }; } diff --git a/apps/charterafrica/src/payload/collections/Contributors.js b/apps/charterafrica/src/payload/collections/Contributors.js index c76607f79..24e0277d1 100644 --- a/apps/charterafrica/src/payload/collections/Contributors.js +++ b/apps/charterafrica/src/payload/collections/Contributors.js @@ -193,6 +193,46 @@ const Contributors = { position: "sidebar", }, }, + { + name: "repositories", + type: "array", + admin: { + readOnly: true, + initCollapsed: true, + }, + label: { + en: "Repositories", + fr: "Dépôts", + pt: "Repositórios", + }, + fields: [ + { + name: "name", + type: "text", + label: { en: "Name", fr: "Nom", pt: "Nome" }, + }, + { + name: "description", + type: "textarea", + label: { en: "Description", fr: "Description", pt: "Descrição" }, + }, + { + name: "stargazers", + type: "number", + label: { en: "Stargazers", fr: "Stargazers", pt: "Stargazers" }, + }, + { + name: "visibility", + type: "text", + label: { en: "Visibility", fr: "Visibilité", pt: "Visibilidade" }, + }, + { + name: "url", + type: "text", + label: { en: "URL", fr: "URL", pt: "URL" }, + }, + ], + }, ], hooks: { afterRead: [ From f2d9339003ce58376be9b9d13263b3ad9ab95e18 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:04:14 +0300 Subject: [PATCH 05/22] Render repositories --- .../src/components/Entity/Entity.js | 21 +++++ .../RepositoryCard/RepositoryCard.js | 81 +++++++++++++++++++ .../src/components/RepositoryCard/index.js | 3 + .../data/common/processPageContributors.js | 6 +- .../src/lib/ecosystem/github/processData.js | 17 ++++ .../src/payload/blocks/Contributors.js | 11 +++ .../src/payload/collections/Contributors.js | 18 +++++ 7 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js create mode 100644 apps/charterafrica/src/components/RepositoryCard/index.js diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index f07165227..88439cb76 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -4,6 +4,8 @@ import { Grid, SvgIcon, Box } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; +import RepositoryCard from "../RepositoryCard"; + import FacebookIcon from "@/charterafrica/assets/icons/Type=facebook, Size=24, Color=CurrentColor.svg"; import GithubIcon from "@/charterafrica/assets/icons/Type=github, Size=24, Color=CurrentColor.svg"; import LinkedInIcon from "@/charterafrica/assets/icons/Type=linkedin, Size=24, Color=CurrentColor.svg"; @@ -71,6 +73,8 @@ const Entity = React.forwardRef(function Entity(props, ref) { toolsTitle, role, currentOrganisation, + repositories, + repositoriesTitle, } = props; const icons = getIcons(props); return ( @@ -159,6 +163,23 @@ const Entity = React.forwardRef(function Entity(props, ref) { + {repositories.length ? ( + <> + + {repositoriesTitle} + + + {repositories.map((repo) => ( + + ))} + + + ) : null} {tools.length ? ( <> + + + + + {name} + + + {description} + + + {techSkills} + + + {updatedDate} + + + + + + {stargazers} + + + + + + + ); +}); + +export default RepositoryCard; diff --git a/apps/charterafrica/src/components/RepositoryCard/index.js b/apps/charterafrica/src/components/RepositoryCard/index.js new file mode 100644 index 000000000..5a53c0eaf --- /dev/null +++ b/apps/charterafrica/src/components/RepositoryCard/index.js @@ -0,0 +1,3 @@ +import RepositoryCard from "./RepositoryCard"; + +export default RepositoryCard; diff --git a/apps/charterafrica/src/lib/data/common/processPageContributors.js b/apps/charterafrica/src/lib/data/common/processPageContributors.js index 67ec33fea..c973e8c1b 100644 --- a/apps/charterafrica/src/lib/data/common/processPageContributors.js +++ b/apps/charterafrica/src/lib/data/common/processPageContributors.js @@ -69,9 +69,7 @@ async function processPagePerson(page, api, context) { return null; } - const block = blocks.findIndex( - ({ slug: bSlug }) => bSlug === "our-contributors", - ); + const block = blocks.find(({ slug: bSlug }) => bSlug === "our-contributors"); const contributor = docs[0] || {}; const { docs: toolDocs } = await api.getCollection(TOOL_COLLECTION, { locale, @@ -119,6 +117,8 @@ async function processPagePerson(page, api, context) { : null, tools, socialMedia, + repositories: contributor.repositories ?? null, + repositoriesTitle: block?.repositoriesTitle ?? null, }, ], }; diff --git a/apps/charterafrica/src/lib/ecosystem/github/processData.js b/apps/charterafrica/src/lib/ecosystem/github/processData.js index 63eb7d4bd..56c8489e1 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/github/processData.js @@ -66,6 +66,14 @@ const GET_USER = `query($username: String!) { } visibility url + updatedAt + languages(first:5) { + edges { + node { + name + } + } + } } } } @@ -192,13 +200,22 @@ export async function fetchContributor({ externalId }) { stargazers, visibility, url: repoURL, + updatedAt, + languages, } = edge?.node ?? {}; + + const techSkills = languages?.edges + ?.map((language) => language?.node?.name) + .join(", "); + return { name: repoName, description, stargazers: stargazers?.totalCount, visibility, url: repoURL, + updatedAt, + techSkills, }; }); diff --git a/apps/charterafrica/src/payload/blocks/Contributors.js b/apps/charterafrica/src/payload/blocks/Contributors.js index 23047d40b..0204846a2 100644 --- a/apps/charterafrica/src/payload/blocks/Contributors.js +++ b/apps/charterafrica/src/payload/blocks/Contributors.js @@ -56,6 +56,17 @@ const Contributors = { required: true, localized: true, }, + { + type: "text", + label: { + en: "Repositories Title", + fr: "Titre des dépôts", + pt: "Título dos repositórios", + }, + name: "repositoriesTitle", + required: true, + localized: true, + }, ], }; export default Contributors; diff --git a/apps/charterafrica/src/payload/collections/Contributors.js b/apps/charterafrica/src/payload/collections/Contributors.js index 24e0277d1..a0a506ea6 100644 --- a/apps/charterafrica/src/payload/collections/Contributors.js +++ b/apps/charterafrica/src/payload/collections/Contributors.js @@ -231,6 +231,24 @@ const Contributors = { type: "text", label: { en: "URL", fr: "URL", pt: "URL" }, }, + { + name: "techSkills", + type: "text", + label: { + en: "Tech Skills", + fr: "Compétences techniques", + pt: "Habilidades técnicas", + }, + }, + { + name: "updatedAt", + type: "date", + label: { + en: "Updated At", + fr: "Mis à jour", + pt: "Atualizado em", + }, + }, ], }, ], From 6c6804b0d6ac12cb4dd28daaab93b21fefd405d2 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:20:39 +0300 Subject: [PATCH 06/22] Fetch user organisations --- .../src/components/Entity/Entity.js | 2 +- .../RepositoryCard/RepositoryCard.js | 13 ++------ .../src/lib/ecosystem/airtable/processData.js | 2 ++ .../lib/ecosystem/ecosystem/processData.js | 11 ++++++- .../src/payload/collections/Contributors.js | 31 +++++++++++-------- .../src/payload/globals/Ecosystem.js | 12 +++++++ 6 files changed, 45 insertions(+), 26 deletions(-) diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index 88439cb76..cf821e02a 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -73,7 +73,7 @@ const Entity = React.forwardRef(function Entity(props, ref) { toolsTitle, role, currentOrganisation, - repositories, + repositories = [], repositoriesTitle, } = props; const icons = getIcons(props); diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js index d383371e7..06ad89114 100644 --- a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js +++ b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js @@ -1,6 +1,6 @@ import { RichTypography } from "@commons-ui/core"; import { Link } from "@commons-ui/next"; -import { Button, Grid } from "@mui/material"; +import { Grid, Chip } from "@mui/material"; import React from "react"; import StarIcon from "@/charterafrica/assets/icons/Type=Star, Size=24, Color=CurrentColor.svg"; @@ -61,16 +61,7 @@ const RepositoryCard = React.forwardRef(function Tools(props, ref) { /> {stargazers} - + diff --git a/apps/charterafrica/src/lib/ecosystem/airtable/processData.js b/apps/charterafrica/src/lib/ecosystem/airtable/processData.js index 2843d0de7..7880e3f32 100644 --- a/apps/charterafrica/src/lib/ecosystem/airtable/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/airtable/processData.js @@ -153,6 +153,7 @@ export function processContributor(item, config) { contributorTableColumns.socialMediaColumns, data, ); + const organisations = getValue(data, contributorTableColumns.organisations); const foundDescription = locales.reduce((acc, curr) => { const val = getValue(data, contributorTableColumns.description[curr]); if (val) { @@ -179,6 +180,7 @@ export function processContributor(item, config) { repoLink, socialMedia, description, + organisations, }; } diff --git a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js index 2b4854a0a..f2d3d6498 100644 --- a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js @@ -15,7 +15,16 @@ export async function prepareContributors(airtableData, config) { const { contributors } = airtableData; await bulkMarkDeleted(CONTRIBUTORS_COLLECTION, contributors); const toProcess = airtableData?.contributors?.map(async (item) => { - return createCollection(CONTRIBUTORS_COLLECTION, item, config); + const rawOrganisations = item?.organisations || []; + const organisations = await getCollectionIdsPerAirtableId( + ORGANIZATION_COLLECTION, + rawOrganisations, + ); + const toCreate = { + ...item, + organisations, + }; + return createCollection(CONTRIBUTORS_COLLECTION, toCreate, config); }); return Promise.allSettled(toProcess); } diff --git a/apps/charterafrica/src/payload/collections/Contributors.js b/apps/charterafrica/src/payload/collections/Contributors.js index a0a506ea6..f339b617b 100644 --- a/apps/charterafrica/src/payload/collections/Contributors.js +++ b/apps/charterafrica/src/payload/collections/Contributors.js @@ -2,7 +2,10 @@ import avatarUrl from "../fields/avatarUrl"; import dateField from "../fields/dateField"; import slug from "../fields/slug"; import source from "../fields/source"; -import { CONTRIBUTORS_COLLECTION } from "../utils/collections"; +import { + CONTRIBUTORS_COLLECTION, + ORGANIZATION_COLLECTION, +} from "../utils/collections"; import nestCollectionUnderPage from "../utils/nestCollectionUnderPage"; function useFullNameOrExternalId({ doc }) { @@ -103,18 +106,6 @@ const Contributors = { readOnly: true, }, }, - { - name: "twitter", - type: "text", - label: { - en: "Twitter handle", - fr: "Twitter de la personne", - pt: "Twitter da Pessoa", - }, - admin: { - readOnly: true, - }, - }, { name: "email", type: "email", @@ -193,6 +184,20 @@ const Contributors = { position: "sidebar", }, }, + { + name: "organisations", + type: "relationship", + hasMany: true, + admin: { + readOnly: true, + }, + relationTo: ORGANIZATION_COLLECTION, + label: { + en: "Organizations", + fr: "Organisations", + pt: "Organizações", + }, + }, { name: "repositories", type: "array", diff --git a/apps/charterafrica/src/payload/globals/Ecosystem.js b/apps/charterafrica/src/payload/globals/Ecosystem.js index 97a0eeea3..7811d37f8 100644 --- a/apps/charterafrica/src/payload/globals/Ecosystem.js +++ b/apps/charterafrica/src/payload/globals/Ecosystem.js @@ -389,6 +389,18 @@ const Ecosystem = { }, }, }), + airtableColumnSelect({ + schema, + tableField: "contributorTableId", + overrides: { + name: "organisations", + label: { + en: "Organisations", + fr: "Organisations", + pt: "Organizações", + }, + }, + }), airtableColumnSelect({ schema, tableField: "contributorTableId", From af41b0a5864db9337991186c951bd3de1205b11a Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:33:03 +0300 Subject: [PATCH 07/22] Fix Organisation Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../icons/Property 1=icons8-discord 1.svg | 3 + .../icons/Property 1=icons8-telegram 1.svg | 3 + .../icons/Property 1=icons8-tiktok 1.svg | 3 + .../icons/Property 1=icons8-whatsapp 1.svg | 10 ++ .../Type=instagram, Size=24, Color=Black.svg | 5 + .../Type=youtube, Size=24, Color=Black.svg | 4 + .../src/components/Entity/Entity.js | 92 ++++++++++++++----- .../OrganisationCard/OrganisationImageCard.js | 52 +++++++++++ .../src/components/OrganisationCard/index.js | 2 + .../data/common/processPageContributors.js | 12 ++- .../src/payload/blocks/Contributors.js | 11 +++ 11 files changed, 173 insertions(+), 24 deletions(-) create mode 100644 apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg create mode 100644 apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg create mode 100644 apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg create mode 100644 apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg create mode 100644 apps/charterafrica/src/assets/icons/Type=instagram, Size=24, Color=Black.svg create mode 100644 apps/charterafrica/src/assets/icons/Type=youtube, Size=24, Color=Black.svg create mode 100644 apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.js diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg b/apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg new file mode 100644 index 000000000..1ac8b1261 --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg b/apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg new file mode 100644 index 000000000..747673fa2 --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg b/apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg new file mode 100644 index 000000000..d5c9f1f92 --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg b/apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg new file mode 100644 index 000000000..6cde08baf --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/charterafrica/src/assets/icons/Type=instagram, Size=24, Color=Black.svg b/apps/charterafrica/src/assets/icons/Type=instagram, Size=24, Color=Black.svg new file mode 100644 index 000000000..b7f68a541 --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Type=instagram, Size=24, Color=Black.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/charterafrica/src/assets/icons/Type=youtube, Size=24, Color=Black.svg b/apps/charterafrica/src/assets/icons/Type=youtube, Size=24, Color=Black.svg new file mode 100644 index 000000000..3b461f2d6 --- /dev/null +++ b/apps/charterafrica/src/assets/icons/Type=youtube, Size=24, Color=Black.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index cf821e02a..c1fe74c70 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -1,18 +1,24 @@ import { Section, RichTypography } from "@commons-ui/core"; import { Figure, Link } from "@commons-ui/next"; -import { Grid, SvgIcon, Box } from "@mui/material"; +import { Grid, SvgIcon, Box, Container } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; +import OrganisationImageCard from "../OrganisationCard/OrganisationImageCard"; import RepositoryCard from "../RepositoryCard"; +import DiscordIcon from "@/charterafrica/assets/icons/Property 1=icons8-discord 1.svg"; +import TelegramIcon from "@/charterafrica/assets/icons/Property 1=icons8-telegram 1.svg"; +import TikTokIcon from "@/charterafrica/assets/icons/Property 1=icons8-tiktok 1.svg"; +import WhatsAppIcon from "@/charterafrica/assets/icons/Property 1=icons8-whatsapp 1.svg"; import FacebookIcon from "@/charterafrica/assets/icons/Type=facebook, Size=24, Color=CurrentColor.svg"; import GithubIcon from "@/charterafrica/assets/icons/Type=github, Size=24, Color=CurrentColor.svg"; +import InstagramIcon from "@/charterafrica/assets/icons/Type=instagram, Size=24, Color=Black.svg"; import LinkedInIcon from "@/charterafrica/assets/icons/Type=linkedin, Size=24, Color=CurrentColor.svg"; import EmailIcon from "@/charterafrica/assets/icons/Type=mail, Size=24, Color=CurrentColor.svg"; import SlackIcon from "@/charterafrica/assets/icons/Type=slack, Size=24, Color=CurrentColor.svg"; -import TelegramIcon from "@/charterafrica/assets/icons/Type=telegram, Size=24, Color=CurrentColor.svg"; import TwitterIcon from "@/charterafrica/assets/icons/Type=twitter, Size=24, Color=CurrentColor.svg"; +import YouTubeIcon from "@/charterafrica/assets/icons/Type=youtube, Size=24, Color=Black.svg"; import ToolCard from "@/charterafrica/components/ToolCard"; function getIcons({ socialMedia, email, github }) { @@ -45,9 +51,20 @@ const SocialMediaLink = React.forwardRef(function SocialMediaLink(props, ref) { slack: SlackIcon, linkedin: LinkedInIcon, telegram: TelegramIcon, + discord: DiscordIcon, + tiktok: TikTokIcon, + whatsapp: WhatsAppIcon, + instagram: InstagramIcon, + youtube: YouTubeIcon, }; return href && icons[variant] ? ( - + -
- - +
+ +
{role} {currentOrganisation} {location} {description} @@ -151,20 +175,44 @@ const Entity = React.forwardRef(function Entity(props, ref) { item xs="auto" container - sx={{ mt: 3, width: "100%" }} - justifyContent={{ xs: "center", sm: "flex-start" }} + sx={{ width: "100%" }} + justifyContent="left" columnSpacing={2} > {icons.map((icon) => ( - + ))} + {organisations.length ? ( + <> + + {organisationsTitle} + + + {organisations.map((org) => ( + + ))} + + + ) : null} {repositories.length ? ( - <> + ))} - + ) : null} {tools.length ? ( <> diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.js new file mode 100644 index 000000000..6d373159e --- /dev/null +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.js @@ -0,0 +1,52 @@ +import { RichTypography } from "@commons-ui/core"; +import { Link, Figure } from "@commons-ui/next"; +import { Grid } from "@mui/material"; +import PropTypes from "prop-types"; +import React from "react"; + +const OrganisationImageCard = React.forwardRef( + function OrganisationImageCard(props, ref) { + const { avatarUrl: image, link, name } = props; + + return ( + + +
+ + {name} + + + + ); + }, +); + +OrganisationImageCard.propTypes = { + name: PropTypes.string, + avatarUrl: PropTypes.string, +}; + +OrganisationImageCard.defaultProps = { + name: undefined, + avatarUrl: undefined, +}; + +export default OrganisationImageCard; diff --git a/apps/charterafrica/src/components/OrganisationCard/index.js b/apps/charterafrica/src/components/OrganisationCard/index.js index 8b775635d..9aa98a05b 100644 --- a/apps/charterafrica/src/components/OrganisationCard/index.js +++ b/apps/charterafrica/src/components/OrganisationCard/index.js @@ -1,3 +1,5 @@ import OrganisationCard from "./OrganisationCard"; +import OrganisationImageCard from "./OrganisationImageCard"; export default OrganisationCard; +export { OrganisationImageCard }; diff --git a/apps/charterafrica/src/lib/data/common/processPageContributors.js b/apps/charterafrica/src/lib/data/common/processPageContributors.js index c973e8c1b..415f2fca5 100644 --- a/apps/charterafrica/src/lib/data/common/processPageContributors.js +++ b/apps/charterafrica/src/lib/data/common/processPageContributors.js @@ -97,6 +97,13 @@ async function processPagePerson(page, api, context) { }; socialMedia.push(github); } + if (contributor.email) { + const email = { + link: `mailto:${contributor.email}`, + name: "email", + }; + socialMedia.push(email); + } return { ...page, @@ -110,15 +117,16 @@ async function processPagePerson(page, api, context) { currentOrganisation: contributor.currentOrganisation ?? null, location: contributor.location ?? null, description: contributor.description ?? null, - email: contributor.email ?? null, toolsTitle: block?.toolsTitle ?? null, lastActive: contributor.lastActive ? formatDateTime(contributor.lastActive, {}) : null, tools, socialMedia, - repositories: contributor.repositories ?? null, + repositories: contributor.repositories ?? [], repositoriesTitle: block?.repositoriesTitle ?? null, + organisations: contributor.organisations ?? [], + organisationsTitle: block?.organisationsTitle ?? null, }, ], }; diff --git a/apps/charterafrica/src/payload/blocks/Contributors.js b/apps/charterafrica/src/payload/blocks/Contributors.js index 0204846a2..5d6e1defb 100644 --- a/apps/charterafrica/src/payload/blocks/Contributors.js +++ b/apps/charterafrica/src/payload/blocks/Contributors.js @@ -67,6 +67,17 @@ const Contributors = { required: true, localized: true, }, + { + type: "text", + label: { + en: "Organisations Title", + fr: "Titre des organisations", + pt: "Título das organizações", + }, + name: "organisationsTitle", + required: true, + localized: true, + }, ], }; export default Contributors; From 85348c1f8d4115394d0c3e4a6e9514005966ec2c Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:46:50 +0300 Subject: [PATCH 08/22] regenarate snapshot --- .../src/components/Entity/Entity.snap.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/charterafrica/src/components/Entity/Entity.snap.js b/apps/charterafrica/src/components/Entity/Entity.snap.js index fc70fbf0e..e99afadef 100644 --- a/apps/charterafrica/src/components/Entity/Entity.snap.js +++ b/apps/charterafrica/src/components/Entity/Entity.snap.js @@ -6,13 +6,13 @@ exports[` renders unchanged 1`] = ` class="MuiBox-root css-1k9ek97" >
renders unchanged 1`] = `
John Doe
Developer
Charter Africa
San Francisco, CA
Full-stack web developer with over 5 years of experience.
Date: Fri, 16 Feb 2024 16:32:26 +0300 Subject: [PATCH 09/22] Update tests --- .../src/components/Entity/Entity.js | 5 +- .../src/components/Entity/Entity.snap.js | 295 ++++++++++++++++++ .../src/components/Entity/Entity.test.js | 20 ++ .../OrganisationImageCard.snap.js | 37 +++ .../OrganisationImageCard.test.js | 24 ++ .../RepositoryCard/RepositoryCard.js | 64 ++-- .../RepositoryCard/RepositoryCard.snap.js | 66 ++++ .../RepositoryCard/RepositoryCard.test.js | 27 ++ 8 files changed, 503 insertions(+), 35 deletions(-) create mode 100644 apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js create mode 100644 apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.test.js create mode 100644 apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js create mode 100644 apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index c1fe74c70..44e781969 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -4,9 +4,6 @@ import { Grid, SvgIcon, Box, Container } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; -import OrganisationImageCard from "../OrganisationCard/OrganisationImageCard"; -import RepositoryCard from "../RepositoryCard"; - import DiscordIcon from "@/charterafrica/assets/icons/Property 1=icons8-discord 1.svg"; import TelegramIcon from "@/charterafrica/assets/icons/Property 1=icons8-telegram 1.svg"; import TikTokIcon from "@/charterafrica/assets/icons/Property 1=icons8-tiktok 1.svg"; @@ -19,6 +16,8 @@ import EmailIcon from "@/charterafrica/assets/icons/Type=mail, Size=24, Color=Cu import SlackIcon from "@/charterafrica/assets/icons/Type=slack, Size=24, Color=CurrentColor.svg"; import TwitterIcon from "@/charterafrica/assets/icons/Type=twitter, Size=24, Color=CurrentColor.svg"; import YouTubeIcon from "@/charterafrica/assets/icons/Type=youtube, Size=24, Color=Black.svg"; +import OrganisationImageCard from "@/charterafrica/components/OrganisationCard/OrganisationImageCard"; +import RepositoryCard from "@/charterafrica/components/RepositoryCard"; import ToolCard from "@/charterafrica/components/ToolCard"; function getIcons({ socialMedia, email, github }) { diff --git a/apps/charterafrica/src/components/Entity/Entity.snap.js b/apps/charterafrica/src/components/Entity/Entity.snap.js index e99afadef..300a28599 100644 --- a/apps/charterafrica/src/components/Entity/Entity.snap.js +++ b/apps/charterafrica/src/components/Entity/Entity.snap.js @@ -77,6 +77,301 @@ exports[` renders unchanged 1`] = `
+
+ Organisations +
+ +
+
+
+
+ Repositories +
+
+ +
+
+
+ Repository 0 +
+
+ Charter Africa website +
+
+ React, Next.js, TypeScript +
+
+ October 1, 2021 +
+
+
+
+
+
+ 100 +
+
+
+ + PUBLIC + +
+
+
+
+ +
({ + id: 1, + name: `Repository ${i}`, + stargazers: 100, + visibility: "PUBLIC", + description: "Charter Africa website", + url: "https://charter.africa", + updatedAt: "2021-10-01T00:00:00Z", + techSkills: "React, Next.js, TypeScript", + })), + repositoriesTitle: "Repositories", + organisations: Array.from({ length: 3 }, (_, i) => ({ + id: 1, + name: `Organisation ${i}`, + avatarUrl: "/static/images/charterafrica.png", + link: { + href: "https://charter.africa", + }, + })), + organisationsTitle: "Organisations", }; describe("", () => { diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js new file mode 100644 index 000000000..a3f5cd0a6 --- /dev/null +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders unchanged 1`] = ` + +`; diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.test.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.test.js new file mode 100644 index 000000000..c57047003 --- /dev/null +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.test.js @@ -0,0 +1,24 @@ +import { createRender } from "@commons-ui/testing-library"; +import React from "react"; + +import OrganisationImageCard from "./OrganisationImageCard"; + +import theme from "@/charterafrica/theme"; + +// eslint-disable-next-line testing-library/render-result-naming-convention +const render = createRender({ theme }); + +const defaultProps = { + name: "Organisation Name", + avatarUrl: "/static/images/avatar/1.jpg", + link: { + href: "https://charter.africa", + }, +}; + +describe("", () => { + it("renders unchanged", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js index 06ad89114..73a17f941 100644 --- a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js +++ b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js @@ -5,7 +5,6 @@ import React from "react"; import StarIcon from "@/charterafrica/assets/icons/Type=Star, Size=24, Color=CurrentColor.svg"; import { neutral } from "@/charterafrica/colors"; -import Card, { StyledActionArea } from "@/charterafrica/components/StyledCard"; import formatDateTime from "@/charterafrica/utils/formatDate"; const RepositoryCard = React.forwardRef(function Tools(props, ref) { @@ -22,9 +21,11 @@ const RepositoryCard = React.forwardRef(function Tools(props, ref) { const updatedDate = formatDateTime(updatedAt, { includeTime: false }); return ( - - - - - - {name} - - - {description} - - - {techSkills} - - - {updatedDate} - - - - - - {stargazers} - - + + + + {name} + + + {description} + + + {techSkills} + + + {updatedDate} + + + + + + {stargazers} + - - + + ); }); diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js new file mode 100644 index 000000000..c1000463c --- /dev/null +++ b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders unchanged 1`] = ` +
+ + +`; diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js new file mode 100644 index 000000000..ef3bb966f --- /dev/null +++ b/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js @@ -0,0 +1,27 @@ +import { createRender } from "@commons-ui/testing-library"; +import React from "react"; + +import RepositoryCard from "./RepositoryCard"; + +import theme from "@/charterafrica/theme"; + +// eslint-disable-next-line testing-library/render-result-naming-convention +const render = createRender({ theme }); + +const defaultProps = { + id: 1, + name: "Repository 1", + stargazers: 100, + visibility: "PUBLIC", + description: "Charter Africa website", + url: "https://charter.africa", + updatedAt: "2021-10-01T00:00:00Z", + techSkills: "React, Next.js, TypeScript", +}; + +describe("", () => { + it("renders unchanged", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); From a8631627990a39a14fb07b99f4c7457ee77dac43 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:53:46 +0300 Subject: [PATCH 10/22] Fix UI --- .../src/components/Entity/Entity.js | 4 +- .../src/components/Entity/Entity.snap.js | 38 +++++++++++++++++-- .../src/components/Entity/Entity.test.js | 2 +- ...nImageCard.js => OrganisationImageLink.js} | 16 ++++---- ....snap.js => OrganisationImageLink.snap.js} | 2 +- ....test.js => OrganisationImageLink.test.js} | 4 +- .../src/components/OrganisationCard/index.js | 4 +- 7 files changed, 51 insertions(+), 19 deletions(-) rename apps/charterafrica/src/components/OrganisationCard/{OrganisationImageCard.js => OrganisationImageLink.js} (75%) rename apps/charterafrica/src/components/OrganisationCard/{OrganisationImageCard.snap.js => OrganisationImageLink.snap.js} (94%) rename apps/charterafrica/src/components/OrganisationCard/{OrganisationImageCard.test.js => OrganisationImageLink.test.js} (81%) diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index 44e781969..079d96063 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -16,7 +16,7 @@ import EmailIcon from "@/charterafrica/assets/icons/Type=mail, Size=24, Color=Cu import SlackIcon from "@/charterafrica/assets/icons/Type=slack, Size=24, Color=CurrentColor.svg"; import TwitterIcon from "@/charterafrica/assets/icons/Type=twitter, Size=24, Color=CurrentColor.svg"; import YouTubeIcon from "@/charterafrica/assets/icons/Type=youtube, Size=24, Color=Black.svg"; -import OrganisationImageCard from "@/charterafrica/components/OrganisationCard/OrganisationImageCard"; +import { OrganisationImageLink } from "@/charterafrica/components/OrganisationCard"; import RepositoryCard from "@/charterafrica/components/RepositoryCard"; import ToolCard from "@/charterafrica/components/ToolCard"; @@ -196,7 +196,7 @@ const Entity = React.forwardRef(function Entity(props, ref) { {organisations.map((org) => ( - + ))} diff --git a/apps/charterafrica/src/components/Entity/Entity.snap.js b/apps/charterafrica/src/components/Entity/Entity.snap.js index 300a28599..b3b9875eb 100644 --- a/apps/charterafrica/src/components/Entity/Entity.snap.js +++ b/apps/charterafrica/src/components/Entity/Entity.snap.js @@ -62,6 +62,38 @@ exports[` renders unchanged 1`] = `
+
+ + +
+ +
@@ -92,7 +124,7 @@ exports[` renders unchanged 1`] = ` target="_blank" >
renders unchanged 1`] = ` target="_blank" >
renders unchanged 1`] = ` target="_blank" >
- +
{name} - + ); }, ); -OrganisationImageCard.propTypes = { +OrganisationImageLink.propTypes = { name: PropTypes.string, avatarUrl: PropTypes.string, }; -OrganisationImageCard.defaultProps = { +OrganisationImageLink.defaultProps = { name: undefined, avatarUrl: undefined, }; -export default OrganisationImageCard; +export default OrganisationImageLink; diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js similarity index 94% rename from apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js rename to apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js index a3f5cd0a6..0ff10b0f2 100644 --- a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageCard.snap.js +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js @@ -9,7 +9,7 @@ exports[` renders unchanged 1`] = ` target="_blank" >
", () => { it("renders unchanged", () => { - const { container } = render(); + const { container } = render(); expect(container).toMatchSnapshot(); }); }); diff --git a/apps/charterafrica/src/components/OrganisationCard/index.js b/apps/charterafrica/src/components/OrganisationCard/index.js index 9aa98a05b..ed50bf468 100644 --- a/apps/charterafrica/src/components/OrganisationCard/index.js +++ b/apps/charterafrica/src/components/OrganisationCard/index.js @@ -1,5 +1,5 @@ import OrganisationCard from "./OrganisationCard"; -import OrganisationImageCard from "./OrganisationImageCard"; +import OrganisationImageLink from "./OrganisationImageLink"; export default OrganisationCard; -export { OrganisationImageCard }; +export { OrganisationImageLink }; From 5a8145766ca2d41e4fb227160711fd2c33aa6e16 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:00:30 +0300 Subject: [PATCH 11/22] Separate github api calls Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../src/lib/ecosystem/github/github.js | 58 +++++++++++++++++++ .../src/lib/ecosystem/github/processData.js | 57 ++---------------- apps/charterafrica/src/lib/ecosystem/index.js | 1 + 3 files changed, 63 insertions(+), 53 deletions(-) create mode 100644 apps/charterafrica/src/lib/ecosystem/github/github.js diff --git a/apps/charterafrica/src/lib/ecosystem/github/github.js b/apps/charterafrica/src/lib/ecosystem/github/github.js new file mode 100644 index 000000000..b20de6018 --- /dev/null +++ b/apps/charterafrica/src/lib/ecosystem/github/github.js @@ -0,0 +1,58 @@ +import * as Sentry from "@sentry/nextjs"; + +import fetchJson, { FetchError } from "@/charterafrica/utils/fetchJson"; + +const BASE_URL = "https://api.github.com"; + +async function graphQuery(query, variables) { + const url = `${BASE_URL}/graphql`; + const headers = { + "Content-Type": "application/json", + Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, + }; + const data = { + variables, + query, + }; + const res = await fetchJson.post(url, { data, headers }); + if (res?.data) { + return res.data; + } + const message = `Unable to fetch from github errors ${JSON.stringify( + res.errors, + )}`; + Sentry.captureException(message); + throw new FetchError(message, res.errors, 500); +} + +async function restQuery(path, tag) { + const url = `${BASE_URL}/${path}`; + const headers = { + "If-None-Match": tag, + Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, + }; + try { + const res = await fetch(url, { headers }); + if (res.ok) { + const response = await res.json(); + const eTag = res.headers.get("ETag"); + return { ...response, eTag }; + } + if (res.status !== 304) { + const response = await res.json(); + const message = `Error fetching "${url}" from github errors ${JSON.stringify( + response, + )}`; + throw new FetchError(message, res, 500); + } + return null; + } catch (e) { + Sentry.captureException(e); + return null; + } +} + +export default { + graphQuery, + restQuery, +}; diff --git a/apps/charterafrica/src/lib/ecosystem/github/processData.js b/apps/charterafrica/src/lib/ecosystem/github/processData.js index 56c8489e1..f0725f138 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/github/processData.js @@ -1,8 +1,7 @@ import * as Sentry from "@sentry/nextjs"; -import fetchJson, { FetchError } from "@/charterafrica/utils/fetchJson"; +import github from "./github"; -const BASE_URL = "https://api.github.com"; const GET_REPOSITORY = `query($repositoryOwner: String!, $repositoryName: String!) { repository(owner: $repositoryOwner, name: $repositoryName) { name @@ -80,54 +79,6 @@ const GET_USER = `query($username: String!) { } }`; -async function fetchGithubGraphqlApi(query, variables) { - const url = `${BASE_URL}/graphql`; - const headers = { - "Content-Type": "application/json", - Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, - }; - const data = { - variables, - query, - }; - const res = await fetchJson.post(url, { data, headers }); - if (res?.data) { - return res.data; - } - const message = `Unable to fetch from github errors ${JSON.stringify( - res.errors, - )}`; - Sentry.captureException(message); - throw new FetchError(message, res.errors, 500); -} - -async function fetchGithubApi(path, tag) { - const url = `${BASE_URL}/${path}`; - const headers = { - "If-None-Match": tag, - Authorization: `Bearer ${process.env.GITHUB_TOKEN}`, - }; - try { - const res = await fetch(url, { headers }); - if (res.ok) { - const response = await res.json(); - const eTag = res.headers.get("ETag"); - return { ...response, eTag }; - } - if (res.status !== 304) { - const response = await res.json(); - const message = `Error fetching "${url}" from github errors ${JSON.stringify( - response, - )}`; - throw new FetchError(message, res, 500); - } - return null; - } catch (e) { - Sentry.captureException(e); - return null; - } -} - export async function fetchTool({ externalId }) { let [repositoryOwner, repositoryName] = externalId .replace(/^https?:\/\/github\.com\//, "") @@ -141,7 +92,7 @@ export async function fetchTool({ externalId }) { return null; } - const data = await fetchGithubGraphqlApi(GET_REPOSITORY, { + const data = await github.graphQuery(GET_REPOSITORY, { repositoryOwner, repositoryName, }); @@ -170,7 +121,7 @@ export async function fetchTool({ externalId }) { } export async function fetchOrganisation({ externalId, eTag }) { - const data = await fetchGithubApi(`orgs/${externalId}`, eTag); + const data = await github.restQuery(`orgs/${externalId}`, eTag); if (!data) { return null; } @@ -186,7 +137,7 @@ export async function fetchOrganisation({ externalId, eTag }) { } export async function fetchContributor({ externalId }) { - const data = await fetchGithubGraphqlApi(GET_USER, { + const data = await github.graphQuery(GET_USER, { username: externalId, }); const { diff --git a/apps/charterafrica/src/lib/ecosystem/index.js b/apps/charterafrica/src/lib/ecosystem/index.js index fd325134e..8fe41a7d6 100644 --- a/apps/charterafrica/src/lib/ecosystem/index.js +++ b/apps/charterafrica/src/lib/ecosystem/index.js @@ -35,6 +35,7 @@ export async function updateList() { level: "info", }); const data = await airtable.data(config); + // console.log() await prepareContributors(data, config); await prepareTools(data, config); await prepareOrganisations(data, config); From 700d4422063c5a8cbefe6450bc0d35dfa71a72aa Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:07:54 +0300 Subject: [PATCH 12/22] Fix conditional fields --- .../src/components/Entity/Entity.js | 36 ++++++++++--------- apps/charterafrica/src/lib/ecosystem/index.js | 1 - 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index 079d96063..31d745579 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -138,22 +138,26 @@ const Entity = React.forwardRef(function Entity(props, ref) { > {name} - - {role} - - - {currentOrganisation} - + {role ? ( + + {role} + + ) : null} + {currentOrganisation ? ( + + {currentOrganisation} + + ) : null} Date: Wed, 21 Feb 2024 17:02:01 +0300 Subject: [PATCH 13/22] Disable pagination --- .../src/lib/ecosystem/ecosystem/processData.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js index f2d3d6498..14a3595c1 100644 --- a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js @@ -66,7 +66,9 @@ export async function prepareTools(airtableData, config) { } export async function updateContributor(forceUpdate) { - const { docs } = await api.getCollection(CONTRIBUTORS_COLLECTION); + const { docs } = await api.getCollection(CONTRIBUTORS_COLLECTION, { + pagination: false, + }); const updatePromises = docs.map(async (item) => { const itemToFetch = forceUpdate ? { ...item, eTag: null } : item; const updated = await github.fetchContributor(itemToFetch); @@ -76,7 +78,9 @@ export async function updateContributor(forceUpdate) { } export async function updateOrganisation(forceUpdate) { - const { docs } = await api.getCollection(ORGANIZATION_COLLECTION); + const { docs } = await api.getCollection(ORGANIZATION_COLLECTION, { + pagination: false, + }); const updatePromises = docs.map(async (item) => { const itemToFetch = forceUpdate ? { ...item, eTag: null } : item; const updated = await github.fetchOrganisation(itemToFetch); @@ -86,7 +90,9 @@ export async function updateOrganisation(forceUpdate) { } export async function updateTool(forceUpdate) { - const { docs } = await api.getCollection(TOOL_COLLECTION); + const { docs } = await api.getCollection(TOOL_COLLECTION, { + pagination: false, + }); const updatePromises = docs.map(async (item) => { const itemToFetch = forceUpdate ? { ...item, eTag: null } : item; const updated = await github.fetchTool(itemToFetch); From 62243fcd6dc68444ac3dc9f5df0e7d0129782ecf Mon Sep 17 00:00:00 2001 From: Kevin Koech Date: Thu, 22 Feb 2024 13:26:37 +0300 Subject: [PATCH 14/22] Update UI --- .../src/components/Dataset/Dataset.js | 12 +- .../src/components/Dataset/Dataset.snap.js | 4 +- .../src/components/Entity/Entity.js | 28 +- .../src/components/Entity/Entity.snap.js | 447 ++++++++++-------- .../components/FlourishChart/FlourishChart.js | 11 +- .../OrganisationCard/OrganisationImageLink.js | 12 +- .../OrganisationImageLink.snap.js | 3 +- 7 files changed, 279 insertions(+), 238 deletions(-) diff --git a/apps/charterafrica/src/components/Dataset/Dataset.js b/apps/charterafrica/src/components/Dataset/Dataset.js index 13636baf0..b8310045a 100644 --- a/apps/charterafrica/src/components/Dataset/Dataset.js +++ b/apps/charterafrica/src/components/Dataset/Dataset.js @@ -125,16 +125,16 @@ function Dataset({
@@ -224,186 +239,198 @@ exports[` renders unchanged 1`] = ` + +
{ const handleMessageEvent = (event) => { - const { sender, context, ...message } = JSON.parse(event.data) || {}; - if (sender === "Flourish" && context === "iframe.resize") { - setHeight(Math.ceil(message.height)); + try { + const { sender, context, ...message } = JSON.parse(event.data) || {}; + if (sender === "Flourish" && context === "iframe.resize") { + return setHeight(Math.ceil(message.height)); + } + return null; + } catch (error) { + return null; } }; window.addEventListener("message", handleMessageEvent); diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.js index 7c284f757..13b8e0451 100644 --- a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.js +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.js @@ -1,6 +1,6 @@ import { RichTypography } from "@commons-ui/core"; import { Link, Figure } from "@commons-ui/next"; -import { Stack } from "@mui/material"; +import { Button, Stack } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; @@ -9,7 +9,13 @@ const OrganisationImageLink = React.forwardRef( const { avatarUrl: image, link, name } = props; return ( - + ); }, ); diff --git a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js index 0ff10b0f2..9faad6639 100644 --- a/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js +++ b/apps/charterafrica/src/components/OrganisationCard/OrganisationImageLink.snap.js @@ -3,9 +3,10 @@ exports[` renders unchanged 1`] = `
Date: Fri, 23 Feb 2024 12:06:16 +0300 Subject: [PATCH 15/22] Reduce graphql API calls --- .../lib/ecosystem/ecosystem/processData.js | 8 +- .../src/lib/ecosystem/github/index.js | 8 +- .../src/lib/ecosystem/github/processData.js | 104 ++++++++++++------ 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js index 14a3595c1..39d1d9473 100644 --- a/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/ecosystem/processData.js @@ -65,13 +65,15 @@ export async function prepareTools(airtableData, config) { return Promise.allSettled(toProcess); } -export async function updateContributor(forceUpdate) { +export async function updateContributor() { const { docs } = await api.getCollection(CONTRIBUTORS_COLLECTION, { pagination: false, }); + const githubContributors = await github.bulkFetchContributors( + docs.map(({ externalId }) => externalId), + ); const updatePromises = docs.map(async (item) => { - const itemToFetch = forceUpdate ? { ...item, eTag: null } : item; - const updated = await github.fetchContributor(itemToFetch); + const updated = githubContributors[item.externalId]; return api.updateCollection(CONTRIBUTORS_COLLECTION, item.id, updated); }); return Promise.allSettled(updatePromises); diff --git a/apps/charterafrica/src/lib/ecosystem/github/index.js b/apps/charterafrica/src/lib/ecosystem/github/index.js index a07565e17..db76597f0 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/index.js +++ b/apps/charterafrica/src/lib/ecosystem/github/index.js @@ -1,7 +1,11 @@ -import { fetchTool, fetchOrganisation, fetchContributor } from "./processData"; +import { + bulkFetchContributors, + fetchTool, + fetchOrganisation, +} from "./processData"; export default { fetchTool, fetchOrganisation, - fetchContributor, + bulkFetchContributors, }; diff --git a/apps/charterafrica/src/lib/ecosystem/github/processData.js b/apps/charterafrica/src/lib/ecosystem/github/processData.js index f0725f138..4514fb749 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/github/processData.js @@ -46,31 +46,30 @@ const GET_REPOSITORY = `query($repositoryOwner: String!, $repositoryName: String } }`; -const GET_USER = `query($username: String!) { - user(login: $username) { - name - avatarUrl - url - email - location - login - websiteUrl - repositories(first: 3, orderBy: {field: STARGAZERS, direction: DESC}) { - edges { - node { - name - description - stargazers { - totalCount - } - visibility - url - updatedAt - languages(first:5) { - edges { - node { - name - } +function createUserQuery(username) { + return `user(login: $${username}) { + name + avatarUrl + url + email + location + login + websiteUrl + repositories(first: 3, orderBy: {field: STARGAZERS, direction: DESC}) { + edges { + node { + name + description + stargazers { + totalCount + } + visibility + url + updatedAt + languages(first:5) { + edges { + node { + name } } } @@ -78,6 +77,10 @@ const GET_USER = `query($username: String!) { } } }`; +} +const GET_USER = `query($username: String!) { + ${createUserQuery("username")} +}`; export async function fetchTool({ externalId }) { let [repositoryOwner, repositoryName] = externalId @@ -136,13 +139,12 @@ export async function fetchOrganisation({ externalId, eTag }) { }; } -export async function fetchContributor({ externalId }) { - const data = await github.graphQuery(GET_USER, { - username: externalId, - }); - const { - user: { name, avatarUrl, url, email, location, websiteUrl, repositories }, - } = data; +function processGithubContributor(data) { + if (!data) { + return null; + } + const { name, avatarUrl, url, email, location, websiteUrl, repositories } = + data; const repos = repositories?.edges?.map((edge) => { const { @@ -180,3 +182,41 @@ export async function fetchContributor({ externalId }) { repositories: repos, }; } +export async function fetchContributor({ externalId }) { + const data = await github.graphQuery(GET_USER, { + username: externalId, + }); + return processGithubContributor(data.user); +} + +function chunkArray(array, chunkSize) { + return Array.from( + { length: Math.ceil(array.length / chunkSize) }, + (_, index) => array.slice(index * chunkSize, (index + 1) * chunkSize), + ); +} + +export async function bulkFetchContributors(externalIds) { + const contributors = {}; + const chunkedArrays = chunkArray(externalIds, 80); + const promises = chunkedArrays.map(async (arr) => { + const variables = arr.reduce((acc, currentValue) => { + acc[currentValue?.replaceAll("-", "_")] = currentValue; + return acc; + }, {}); + const sanitizedIds = Object.keys(variables); + let query = `query($${sanitizedIds.join(" : String!, $")} : String!){`; + sanitizedIds.forEach((id) => { + query += `\n${id}: ${createUserQuery(id)}`; + }); + query += "\n}"; + const data = await github.graphQuery(query, variables); + Object.keys(data || {}).forEach((externalId) => { + contributors[variables[externalId]] = processGithubContributor( + data[externalId], + ); + }); + }); + await Promise.allSettled(promises); + return contributors; +} From ed47037ee0b8a94543160f573a528c1368ff7f1c Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:21:26 +0300 Subject: [PATCH 16/22] Small fix --- .../src/components/Dataset/Dataset.js | 5 -- .../src/lib/ecosystem/github/processData.js | 64 +++++++++++-------- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/apps/charterafrica/src/components/Dataset/Dataset.js b/apps/charterafrica/src/components/Dataset/Dataset.js index b8310045a..64d5e4d1d 100644 --- a/apps/charterafrica/src/components/Dataset/Dataset.js +++ b/apps/charterafrica/src/components/Dataset/Dataset.js @@ -130,11 +130,6 @@ function Dataset({ href={url} target="_blank" sx={{ - // width: { - // xs: "100%", - // sm: "200px", - // }, - // height: "50px", mt: 4, }} > diff --git a/apps/charterafrica/src/lib/ecosystem/github/processData.js b/apps/charterafrica/src/lib/ecosystem/github/processData.js index 4514fb749..000299153 100644 --- a/apps/charterafrica/src/lib/ecosystem/github/processData.js +++ b/apps/charterafrica/src/lib/ecosystem/github/processData.js @@ -46,7 +46,7 @@ const GET_REPOSITORY = `query($repositoryOwner: String!, $repositoryName: String } }`; -function createUserQuery(username) { +function fetchUserQuery(username) { return `user(login: $${username}) { name avatarUrl @@ -78,9 +78,6 @@ function createUserQuery(username) { } }`; } -const GET_USER = `query($username: String!) { - ${createUserQuery("username")} -}`; export async function fetchTool({ externalId }) { let [repositoryOwner, repositoryName] = externalId @@ -182,12 +179,6 @@ function processGithubContributor(data) { repositories: repos, }; } -export async function fetchContributor({ externalId }) { - const data = await github.graphQuery(GET_USER, { - username: externalId, - }); - return processGithubContributor(data.user); -} function chunkArray(array, chunkSize) { return Array.from( @@ -196,26 +187,45 @@ function chunkArray(array, chunkSize) { ); } +function constructGraphQLQuery(ids) { + const queryParts = ids.map((id) => { + const queryPart = fetchUserQuery(id); + return `${id}: ${queryPart}`; + }); + return `query(${ids + .map((id) => `$${id}: String!`) + .join(", ")}){\n${queryParts.join("\n")}\n}`; +} + +async function fetchContributorsData(users) { + const variables = users.reduce((acc, id) => { + const sanitizedId = id.replaceAll("-", "_"); + acc[sanitizedId] = id; + return acc; + }, {}); + + const query = constructGraphQLQuery(Object.keys(variables)); + const data = await github.graphQuery(query, variables); + + return Object.keys(data || {}).reduce((acc, key) => { + acc[variables[key]] = processGithubContributor(data[key]); + return acc; + }, {}); +} + +const USER_QUERY_LIMIT = 80; + export async function bulkFetchContributors(externalIds) { const contributors = {}; - const chunkedArrays = chunkArray(externalIds, 80); + const chunkedArrays = chunkArray(externalIds, USER_QUERY_LIMIT); + const promises = chunkedArrays.map(async (arr) => { - const variables = arr.reduce((acc, currentValue) => { - acc[currentValue?.replaceAll("-", "_")] = currentValue; - return acc; - }, {}); - const sanitizedIds = Object.keys(variables); - let query = `query($${sanitizedIds.join(" : String!, $")} : String!){`; - sanitizedIds.forEach((id) => { - query += `\n${id}: ${createUserQuery(id)}`; - }); - query += "\n}"; - const data = await github.graphQuery(query, variables); - Object.keys(data || {}).forEach((externalId) => { - contributors[variables[externalId]] = processGithubContributor( - data[externalId], - ); - }); + try { + const data = await fetchContributorsData(arr); + Object.assign(contributors, data); + } catch (error) { + Sentry.captureMessage(error.message); + } }); await Promise.allSettled(promises); return contributors; From ce5ab7ddbc5f95692408df64cc5d542a36bf47c7 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:39:34 +0300 Subject: [PATCH 17/22] Rename icons --- ...scord 1.svg => Type=discord, Size=25, Color=Black.svg} | 0 ...gram 1.svg => Type=telegram, Size=25, Color=Black.svg} | 0 ...tiktok 1.svg => Type=tiktok, Size=25, Color=Black.svg} | 0 ...sapp 1.svg => Type=whatsapp, Size=25, Color=Black.svg} | 0 apps/charterafrica/src/components/Entity/Entity.js | 8 ++++---- 5 files changed, 4 insertions(+), 4 deletions(-) rename apps/charterafrica/src/assets/icons/{Property 1=icons8-discord 1.svg => Type=discord, Size=25, Color=Black.svg} (100%) rename apps/charterafrica/src/assets/icons/{Property 1=icons8-telegram 1.svg => Type=telegram, Size=25, Color=Black.svg} (100%) rename apps/charterafrica/src/assets/icons/{Property 1=icons8-tiktok 1.svg => Type=tiktok, Size=25, Color=Black.svg} (100%) rename apps/charterafrica/src/assets/icons/{Property 1=icons8-whatsapp 1.svg => Type=whatsapp, Size=25, Color=Black.svg} (100%) diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg b/apps/charterafrica/src/assets/icons/Type=discord, Size=25, Color=Black.svg similarity index 100% rename from apps/charterafrica/src/assets/icons/Property 1=icons8-discord 1.svg rename to apps/charterafrica/src/assets/icons/Type=discord, Size=25, Color=Black.svg diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg b/apps/charterafrica/src/assets/icons/Type=telegram, Size=25, Color=Black.svg similarity index 100% rename from apps/charterafrica/src/assets/icons/Property 1=icons8-telegram 1.svg rename to apps/charterafrica/src/assets/icons/Type=telegram, Size=25, Color=Black.svg diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg b/apps/charterafrica/src/assets/icons/Type=tiktok, Size=25, Color=Black.svg similarity index 100% rename from apps/charterafrica/src/assets/icons/Property 1=icons8-tiktok 1.svg rename to apps/charterafrica/src/assets/icons/Type=tiktok, Size=25, Color=Black.svg diff --git a/apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg b/apps/charterafrica/src/assets/icons/Type=whatsapp, Size=25, Color=Black.svg similarity index 100% rename from apps/charterafrica/src/assets/icons/Property 1=icons8-whatsapp 1.svg rename to apps/charterafrica/src/assets/icons/Type=whatsapp, Size=25, Color=Black.svg diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index 32ba2663e..4490f34f2 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -4,17 +4,17 @@ import { Grid, SvgIcon, Box, Container } from "@mui/material"; import PropTypes from "prop-types"; import React from "react"; -import DiscordIcon from "@/charterafrica/assets/icons/Property 1=icons8-discord 1.svg"; -import TelegramIcon from "@/charterafrica/assets/icons/Property 1=icons8-telegram 1.svg"; -import TikTokIcon from "@/charterafrica/assets/icons/Property 1=icons8-tiktok 1.svg"; -import WhatsAppIcon from "@/charterafrica/assets/icons/Property 1=icons8-whatsapp 1.svg"; +import DiscordIcon from "@/charterafrica/assets/icons/Type=discord, Size=25, Color=Black.svg"; import FacebookIcon from "@/charterafrica/assets/icons/Type=facebook, Size=24, Color=CurrentColor.svg"; import GithubIcon from "@/charterafrica/assets/icons/Type=github, Size=24, Color=CurrentColor.svg"; import InstagramIcon from "@/charterafrica/assets/icons/Type=instagram, Size=24, Color=Black.svg"; import LinkedInIcon from "@/charterafrica/assets/icons/Type=linkedin, Size=24, Color=CurrentColor.svg"; import EmailIcon from "@/charterafrica/assets/icons/Type=mail, Size=24, Color=CurrentColor.svg"; import SlackIcon from "@/charterafrica/assets/icons/Type=slack, Size=24, Color=CurrentColor.svg"; +import TelegramIcon from "@/charterafrica/assets/icons/Type=telegram, Size=25, Color=Black.svg"; +import TikTokIcon from "@/charterafrica/assets/icons/Type=tiktok, Size=25, Color=Black.svg"; import TwitterIcon from "@/charterafrica/assets/icons/Type=twitter, Size=24, Color=CurrentColor.svg"; +import WhatsAppIcon from "@/charterafrica/assets/icons/Type=whatsapp, Size=25, Color=Black.svg"; import YouTubeIcon from "@/charterafrica/assets/icons/Type=youtube, Size=24, Color=Black.svg"; import { OrganisationImageLink } from "@/charterafrica/components/OrganisationCard"; import RepositoryCard from "@/charterafrica/components/RepositoryCard"; From 83680acabc9de20a48e2a5ca1654277d91a97421 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Fri, 23 Feb 2024 17:03:52 +0300 Subject: [PATCH 18/22] Add svg viewbox Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- apps/charterafrica/src/components/Entity/Entity.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index 4490f34f2..ccab3dd85 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -67,6 +67,7 @@ const SocialMediaLink = React.forwardRef(function SocialMediaLink(props, ref) { Date: Mon, 26 Feb 2024 16:51:59 +0300 Subject: [PATCH 19/22] Rename RepositoryCard to Repository Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- apps/charterafrica/src/components/Entity/Entity.js | 4 ++-- .../RepositoryCard.js => Repository/Repository.js} | 4 ++-- .../Repository.snap.js} | 0 .../Repository.test.js} | 6 +++--- apps/charterafrica/src/components/Repository/index.js | 3 +++ apps/charterafrica/src/components/RepositoryCard/index.js | 3 --- 6 files changed, 10 insertions(+), 10 deletions(-) rename apps/charterafrica/src/components/{RepositoryCard/RepositoryCard.js => Repository/Repository.js} (94%) rename apps/charterafrica/src/components/{RepositoryCard/RepositoryCard.snap.js => Repository/Repository.snap.js} (100%) rename apps/charterafrica/src/components/{RepositoryCard/RepositoryCard.test.js => Repository/Repository.test.js} (78%) create mode 100644 apps/charterafrica/src/components/Repository/index.js delete mode 100644 apps/charterafrica/src/components/RepositoryCard/index.js diff --git a/apps/charterafrica/src/components/Entity/Entity.js b/apps/charterafrica/src/components/Entity/Entity.js index ccab3dd85..e52b22533 100644 --- a/apps/charterafrica/src/components/Entity/Entity.js +++ b/apps/charterafrica/src/components/Entity/Entity.js @@ -17,7 +17,7 @@ import TwitterIcon from "@/charterafrica/assets/icons/Type=twitter, Size=24, Col import WhatsAppIcon from "@/charterafrica/assets/icons/Type=whatsapp, Size=25, Color=Black.svg"; import YouTubeIcon from "@/charterafrica/assets/icons/Type=youtube, Size=24, Color=Black.svg"; import { OrganisationImageLink } from "@/charterafrica/components/OrganisationCard"; -import RepositoryCard from "@/charterafrica/components/RepositoryCard"; +import Repository from "@/charterafrica/components/Repository"; import ToolCard from "@/charterafrica/components/ToolCard"; function getIcons({ socialMedia, email, github }) { @@ -228,7 +228,7 @@ const Entity = React.forwardRef(function Entity(props, ref) { {repositories.map((repo) => ( - + ))} diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js b/apps/charterafrica/src/components/Repository/Repository.js similarity index 94% rename from apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js rename to apps/charterafrica/src/components/Repository/Repository.js index 73a17f941..9606b774e 100644 --- a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.js +++ b/apps/charterafrica/src/components/Repository/Repository.js @@ -7,7 +7,7 @@ import StarIcon from "@/charterafrica/assets/icons/Type=Star, Size=24, Color=Cur import { neutral } from "@/charterafrica/colors"; import formatDateTime from "@/charterafrica/utils/formatDate"; -const RepositoryCard = React.forwardRef(function Tools(props, ref) { +const Repository = React.forwardRef(function Tools(props, ref) { const { name, stargazers, @@ -69,4 +69,4 @@ const RepositoryCard = React.forwardRef(function Tools(props, ref) { ); }); -export default RepositoryCard; +export default Repository; diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js b/apps/charterafrica/src/components/Repository/Repository.snap.js similarity index 100% rename from apps/charterafrica/src/components/RepositoryCard/RepositoryCard.snap.js rename to apps/charterafrica/src/components/Repository/Repository.snap.js diff --git a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js b/apps/charterafrica/src/components/Repository/Repository.test.js similarity index 78% rename from apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js rename to apps/charterafrica/src/components/Repository/Repository.test.js index ef3bb966f..38010a89b 100644 --- a/apps/charterafrica/src/components/RepositoryCard/RepositoryCard.test.js +++ b/apps/charterafrica/src/components/Repository/Repository.test.js @@ -1,7 +1,7 @@ import { createRender } from "@commons-ui/testing-library"; import React from "react"; -import RepositoryCard from "./RepositoryCard"; +import Repository from "./Repository"; import theme from "@/charterafrica/theme"; @@ -19,9 +19,9 @@ const defaultProps = { techSkills: "React, Next.js, TypeScript", }; -describe("", () => { +describe("", () => { it("renders unchanged", () => { - const { container } = render(); + const { container } = render(); expect(container).toMatchSnapshot(); }); }); diff --git a/apps/charterafrica/src/components/Repository/index.js b/apps/charterafrica/src/components/Repository/index.js new file mode 100644 index 000000000..ca287922a --- /dev/null +++ b/apps/charterafrica/src/components/Repository/index.js @@ -0,0 +1,3 @@ +import Repository from "./Repository"; + +export default Repository; diff --git a/apps/charterafrica/src/components/RepositoryCard/index.js b/apps/charterafrica/src/components/RepositoryCard/index.js deleted file mode 100644 index 5a53c0eaf..000000000 --- a/apps/charterafrica/src/components/RepositoryCard/index.js +++ /dev/null @@ -1,3 +0,0 @@ -import RepositoryCard from "./RepositoryCard"; - -export default RepositoryCard; From 1d63200b5be92626028aa0dd538476090ab2fde1 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:02:04 +0300 Subject: [PATCH 20/22] Fix Flourish charts Signed-off-by: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> --- .../src/components/FlourishChart/FlourishChart.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/apps/charterafrica/src/components/FlourishChart/FlourishChart.js b/apps/charterafrica/src/components/FlourishChart/FlourishChart.js index 482b5f9d0..e314266b5 100644 --- a/apps/charterafrica/src/components/FlourishChart/FlourishChart.js +++ b/apps/charterafrica/src/components/FlourishChart/FlourishChart.js @@ -9,14 +9,9 @@ const FlourishChart = React.forwardRef(function FlourishChart(props, ref) { useEffect(() => { const handleMessageEvent = (event) => { - try { - const { sender, context, ...message } = JSON.parse(event.data) || {}; - if (sender === "Flourish" && context === "iframe.resize") { - return setHeight(Math.ceil(message.height)); - } - return null; - } catch (error) { - return null; + const { sender, context, ...message } = JSON.parse(event.data) || {}; + if (sender === "Flourish" && context === "iframe.resize") { + setHeight(Math.ceil(message.height)); } }; window.addEventListener("message", handleMessageEvent); From be04f53982f8a3bf6ef1cf50a29405bd9689ae19 Mon Sep 17 00:00:00 2001 From: Kipruto <43873157+kelvinkipruto@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:11:09 +0300 Subject: [PATCH 21/22] Regenerate snapshots --- apps/charterafrica/src/components/Repository/Repository.snap.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/charterafrica/src/components/Repository/Repository.snap.js b/apps/charterafrica/src/components/Repository/Repository.snap.js index c1000463c..1aadefc2d 100644 --- a/apps/charterafrica/src/components/Repository/Repository.snap.js +++ b/apps/charterafrica/src/components/Repository/Repository.snap.js @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` renders unchanged 1`] = ` +exports[` renders unchanged 1`] = `