From 49e8153934615cdcb62b50b59527057cadfe77c4 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 3 Aug 2023 18:18:56 +0000 Subject: [PATCH 1/7] Add parameters --- .../TemplateInsightsPage.stories.tsx | 122 +++++++++++++++++- .../TemplateInsightsPage.tsx | 110 ++++++++++++++++ 2 files changed, 231 insertions(+), 1 deletion(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx index 49678eef08375..50bb6ab6c4a8c 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx @@ -83,7 +83,127 @@ export const Loaded: Story = { seconds: 1020900, }, ], - parameters_usage: [], + parameters_usage: [ + { + template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + display_name: "", + name: "Coder Repository Directory", + values: [ + { + value: "${HOME}/src/coder/coder", + count: 1, + }, + { + value: "~/coder", + count: 16, + }, + { + value: "~/go/src/github.com/coder/coder", + count: 1, + }, + { + value: "~/projects/coder/coder", + count: 1, + }, + { + value: "~/repos/coder", + count: 1, + }, + ], + }, + { + template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + display_name: "", + name: "Dotfiles URL", + values: [ + { + value: " ", + count: 11, + }, + { + value: " git@github.com:jsjoeio/dotfiles.git", + count: 1, + }, + { + value: "git@github.com:Emyrk/dotfiles.git", + count: 1, + }, + { + value: "git@github.com:ericpaulsen/dot-v2.git", + count: 1, + }, + { + value: "git@github.com:johnstcn/dotfiles-coder.git", + count: 2, + }, + { + value: "git@github.com:spikecurtis/dotfiles.git", + count: 1, + }, + { + value: "https://github.com/bpmct/dot", + count: 1, + }, + { + value: "https://github.com/spikecurtis/dotfiles.git", + count: 1, + }, + { + value: "https://phorcys.net/dotfiles", + count: 1, + }, + ], + }, + { + template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + display_name: "", + name: "Region", + options: [ + { + name: "Pittsburgh", + description: "", + value: "us-pittsburgh", + icon: "/emojis/1f1fa-1f1f8.png", + }, + { + name: "Helsinki", + description: "", + value: "eu-helsinki", + icon: "/emojis/1f1eb-1f1ee.png", + }, + { + name: "Sydney", + description: "", + value: "ap-sydney", + icon: "/emojis/1f1e6-1f1fa.png", + }, + { + name: "São Paulo", + description: "", + value: "sa-saopaulo", + icon: "/emojis/1f1e7-1f1f7.png", + }, + ], + values: [ + { + value: "ap-sydney", + count: 1, + }, + { + value: "eu-helsinki", + count: 5, + }, + { + value: "sa-saopaulo", + count: 3, + }, + { + value: "us-pittsburgh", + count: 11, + }, + ], + }, + ], }, interval_reports: [ { diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 210458a6f2f44..32e561835fe82 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -80,6 +80,10 @@ export const TemplateInsightsPageView = ({ sx={{ gridColumn: "span 3" }} data={templateInsights?.report.apps_usage} /> + ) } @@ -260,6 +264,112 @@ const TemplateUsagePanel = ({ ) } +const TemplateParametersUsagePanel = ({ + data, + ...panelProps +}: PanelProps & { + data: TemplateInsightsResponse["report"]["parameters_usage"] | undefined +}) => { + return ( + + + Parameters usage + Last 7 days + + + {!data && } + {data && data.length === 0 && } + {data && + data.length > 0 && + data.map((parameter) => { + const label = + parameter.display_name !== "" + ? parameter.display_name + : parameter.name + return ( + `1px solid ${theme.palette.divider}`, + width: (theme) => `calc(100% + ${theme.spacing(6)})`, + "&:first-child": { + borderTop: 0, + }, + }} + > + {label} + + {parameter.values + .sort((a, b) => b.count - a.count) + .map((value) => { + const icon = parameter.options + ? parameter.options.find((o) => o.value === value.value) + ?.icon + : undefined + const label = + value.value.trim() !== "" ? ( + value.value + ) : ( + theme.palette.text.secondary, + }} + > + Not set + + ) + return ( + + + {icon && ( + + + + )} + {label} + + {value.count} + + ) + })} + + + ) + })} + + + ) +} + const Panel = styled(Box)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: `1px solid ${theme.palette.divider}`, From c24cb8830165f0bdc7ac3f58fde6ad3d55db74d7 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Thu, 3 Aug 2023 18:30:06 +0000 Subject: [PATCH 2/7] Add behind experiments --- coderd/apidoc/docs.go | 6 ++++-- coderd/apidoc/swagger.json | 6 ++++-- codersdk/deployment.go | 4 ++++ docs/api/schemas.md | 1 + site/src/api/typesGenerated.ts | 2 ++ .../TemplateInsightsPage.tsx | 17 +++++++++++++---- 6 files changed, 28 insertions(+), 8 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index f202d5903f2b7..0a9a32ed5b626 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -8024,7 +8024,8 @@ const docTemplate = `{ "tailnet_pg_coordinator", "single_tailnet", "template_restart_requirement", - "deployment_health_page" + "deployment_health_page", + "template_parameters_insights" ], "x-enum-varnames": [ "ExperimentMoons", @@ -8032,7 +8033,8 @@ const docTemplate = `{ "ExperimentTailnetPGCoordinator", "ExperimentSingleTailnet", "ExperimentTemplateRestartRequirement", - "ExperimentDeploymentHealthPage" + "ExperimentDeploymentHealthPage", + "ExperimentTemplateParametersInsights" ] }, "codersdk.Feature": { diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index bf25c827c44c3..f61180cb382b1 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -7185,7 +7185,8 @@ "tailnet_pg_coordinator", "single_tailnet", "template_restart_requirement", - "deployment_health_page" + "deployment_health_page", + "template_parameters_insights" ], "x-enum-varnames": [ "ExperimentMoons", @@ -7193,7 +7194,8 @@ "ExperimentTailnetPGCoordinator", "ExperimentSingleTailnet", "ExperimentTemplateRestartRequirement", - "ExperimentDeploymentHealthPage" + "ExperimentDeploymentHealthPage", + "ExperimentTemplateParametersInsights" ] }, "codersdk.Feature": { diff --git a/codersdk/deployment.go b/codersdk/deployment.go index af861138e6d7d..ad4848a9435fc 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -1871,6 +1871,9 @@ const ( // Deployment health page ExperimentDeploymentHealthPage Experiment = "deployment_health_page" + // Template parameters insights + ExperimentTemplateParametersInsights Experiment = "template_parameters_insights" + // Add new experiments here! // ExperimentExample Experiment = "example" ) @@ -1881,6 +1884,7 @@ const ( // not be included here and will be essentially hidden. var ExperimentsAll = Experiments{ ExperimentDeploymentHealthPage, + ExperimentTemplateParametersInsights, } // Experiments is a list of experiments that are enabled for the deployment. diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 767b99b66e031..8fdfbe1822c8a 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2677,6 +2677,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in | `single_tailnet` | | `template_restart_requirement` | | `deployment_health_page` | +| `template_parameters_insights` | ## codersdk.Feature diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index d23b2e2f2694f..1cbf49c17a72b 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1583,6 +1583,7 @@ export type Experiment = | "moons" | "single_tailnet" | "tailnet_pg_coordinator" + | "template_parameters_insights" | "template_restart_requirement" | "workspace_actions" export const Experiments: Experiment[] = [ @@ -1590,6 +1591,7 @@ export const Experiments: Experiment[] = [ "moons", "single_tailnet", "tailnet_pg_coordinator", + "template_parameters_insights", "template_restart_requirement", "workspace_actions", ] diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 32e561835fe82..284058a614ee5 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -25,6 +25,7 @@ import { } from "api/typesGenerated" import { ComponentProps } from "react" import subDays from "date-fns/subDays" +import { useDashboard } from "components/Dashboard/DashboardProvider" export default function TemplateInsightsPage() { const { template } = useTemplateLayoutContext() @@ -41,6 +42,7 @@ export default function TemplateInsightsPage() { queryKey: ["templates", template.id, "user-latency"], queryFn: () => getInsightsUserLatency(insightsFilter), }) + const dashboard = useDashboard() return ( <> @@ -50,6 +52,9 @@ export default function TemplateInsightsPage() { ) @@ -58,9 +63,11 @@ export default function TemplateInsightsPage() { export const TemplateInsightsPageView = ({ templateInsights, userLatency, + shouldDisplayParameters, }: { templateInsights: TemplateInsightsResponse | undefined userLatency: UserLatencyInsightsResponse | undefined + shouldDisplayParameters: boolean }) => { return ( - + {shouldDisplayParameters && ( + + )} ) } From 78cb2b89a1784550a6ee3c5caf7b51012837e9e8 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 4 Aug 2023 15:23:45 +0000 Subject: [PATCH 3/7] Improve option and link display --- .../TemplateInsightsPage.tsx | 156 +++++++++++------- 1 file changed, 96 insertions(+), 60 deletions(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 284058a614ee5..2c4490bf27b76 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -21,11 +21,15 @@ import { Loader } from "components/Loader/Loader" import { DAUsResponse, TemplateInsightsResponse, + TemplateParameterUsage, + TemplateParameterValue, UserLatencyInsightsResponse, } from "api/typesGenerated" import { ComponentProps } from "react" import subDays from "date-fns/subDays" import { useDashboard } from "components/Dashboard/DashboardProvider" +import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined" +import Link from "@mui/material/Link" export default function TemplateInsightsPage() { const { template } = useTemplateLayoutContext() @@ -43,6 +47,9 @@ export default function TemplateInsightsPage() { queryFn: () => getInsightsUserLatency(insightsFilter), }) const dashboard = useDashboard() + const shouldDisplayParameters = + dashboard.experiments.includes("template_parameters_insights") || + process.env.NODE_ENV === "development" return ( <> @@ -52,9 +59,7 @@ export default function TemplateInsightsPage() { ) @@ -290,7 +295,7 @@ const TemplateParametersUsagePanel = ({ {data && data.length === 0 && } {data && data.length > 0 && - data.map((parameter) => { + data.map((parameter, parameterIndex) => { const label = parameter.display_name !== "" ? parameter.display_name @@ -314,62 +319,20 @@ const TemplateParametersUsagePanel = ({ {parameter.values .sort((a, b) => b.count - a.count) - .map((value) => { - const icon = parameter.options - ? parameter.options.find((o) => o.value === value.value) - ?.icon - : undefined - const label = - value.value.trim() !== "" ? ( - value.value - ) : ( - theme.palette.text.secondary, - }} - > - Not set - - ) - return ( - - - {icon && ( - - - - )} - {label} - - {value.count} - - ) - })} + .map((value, valueIndex) => ( + + + {value.count} + + ))} ) @@ -379,6 +342,79 @@ const TemplateParametersUsagePanel = ({ ) } +const ValueLabel = ({ + value, + parameter, +}: { + value: TemplateParameterValue + parameter: TemplateParameterUsage +}) => { + if (value.value.trim() === "") { + return ( + theme.palette.text.secondary, + }} + > + Not set + + ) + } + + if (parameter.options) { + const option = parameter.options.find((o) => o.value === value.value)! + const icon = option.icon + const label = option.name + + return ( + + {icon && ( + + + + )} + {label} + + ) + } + + if (value.value.startsWith("http")) { + return ( + theme.palette.text.primary, + }} + > + + {value.value} + + ) + } + + return {value.value} +} + const Panel = styled(Box)(({ theme }) => ({ borderRadius: theme.shape.borderRadius, border: `1px solid ${theme.palette.divider}`, From de122b77950c6400b2ebdd61190c4caf4214ac79 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 4 Aug 2023 17:50:45 +0000 Subject: [PATCH 4/7] Fix date filter --- .../TemplateInsightsPage/TemplateInsightsPage.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 2c4490bf27b76..34868972ae1dc 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -26,7 +26,7 @@ import { UserLatencyInsightsResponse, } from "api/typesGenerated" import { ComponentProps } from "react" -import subDays from "date-fns/subDays" +import { subDays, addHours, startOfHour } from "date-fns" import { useDashboard } from "components/Dashboard/DashboardProvider" import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined" import Link from "@mui/material/Link" @@ -35,8 +35,8 @@ export default function TemplateInsightsPage() { const { template } = useTemplateLayoutContext() const insightsFilter = { template_ids: template.id, - start_time: toTimeFilter(sevenDaysAgo()), - end_time: toTimeFilter(new Date()), + start_time: toStartTimeFilter(sevenDaysAgo()), + end_time: startOfHour(addHours(new Date(), 1)).toISOString(), } const { data: templateInsights } = useQuery({ queryKey: ["templates", template.id, "usage"], @@ -478,12 +478,11 @@ function mapToDAUsResponse( } } -function toTimeFilter(date: Date) { +function toStartTimeFilter(date: Date) { date.setHours(0, 0, 0, 0) const year = date.getUTCFullYear() const month = String(date.getUTCMonth() + 1).padStart(2, "0") const day = String(date.getUTCDate()).padStart(2, "0") - return `${year}-${month}-${day}T00:00:00Z` } From 352f9dab95e942cdbdb49601c4398d2f37873eff Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 4 Aug 2023 18:11:25 +0000 Subject: [PATCH 5/7] Support boolean and array values --- .../TemplateInsightsPage.tsx | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 34868972ae1dc..a51cb3d3a3952 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -30,6 +30,8 @@ import { subDays, addHours, startOfHour } from "date-fns" import { useDashboard } from "components/Dashboard/DashboardProvider" import OpenInNewOutlined from "@mui/icons-material/OpenInNewOutlined" import Link from "@mui/material/Link" +import CheckCircleOutlined from "@mui/icons-material/CheckCircleOutlined" +import CancelOutlined from "@mui/icons-material/CancelOutlined" export default function TemplateInsightsPage() { const { template } = useTemplateLayoutContext() @@ -327,6 +329,7 @@ const TemplateParametersUsagePanel = ({ alignItems: "baseline", justifyContent: "space-between", py: 0.5, + gap: 5, }} > @@ -412,6 +415,71 @@ const ValueLabel = ({ ) } + if (value.value.startsWith("[")) { + const values = JSON.parse(value.value) as string[] + return ( + + {values.map((v, i) => { + return ( + theme.spacing(0.25, 1.5), + borderRadius: 999, + background: (theme) => theme.palette.divider, + whiteSpace: "nowrap", + }} + > + {v} + + ) + })} + + ) + } + + if (value.value === "false") { + return ( + + theme.palette.error.light, + }} + /> + False + + ) + } + + if (value.value === "true") { + return ( + + theme.palette.success.light, + }} + /> + True + + ) + } + return {value.value} } From f6797126ad058db49b915f8c349312710c4cb854 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Fri, 4 Aug 2023 18:13:56 +0000 Subject: [PATCH 6/7] Add better storybook --- .../TemplateInsightsPage.stories.tsx | 328 +++++++++++++++--- 1 file changed, 276 insertions(+), 52 deletions(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx index 50bb6ab6c4a8c..4ba4180522688 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx @@ -85,121 +85,345 @@ export const Loaded: Story = { ], parameters_usage: [ { - template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", - name: "Coder Repository Directory", + name: "Compute instances", values: [ { - value: "${HOME}/src/coder/coder", - count: 1, + value: "3", + count: 2, + }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "", + name: "Docker Image", + values: [ + { + value: "ghcr.io/harrison-ai/coder-dev:base", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Very random string", + name: "Optional random string", + values: [ { - value: "~/coder", - count: 16, + value: "ksjdlkajs;djálskd'l ;a k;aosdk ;oaids ;li", + count: 1, }, { - value: "~/go/src/github.com/coder/coder", + value: "some other any string here", count: 1, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "", + name: "Region", + options: [ + { + name: "US Central", + description: "Select for central!", + value: "us-central1-a", + icon: "/icon/goland.svg", + }, + { + name: "US East", + description: "Select for east!", + value: "us-east1-a", + icon: "/icon/folder.svg", + }, + { + name: "US West", + description: "Select for west!", + value: "us-west2-a", + icon: "", + }, + ], + values: [ { - value: "~/projects/coder/coder", + value: "us-central1-a", count: 1, }, { - value: "~/repos/coder", + value: "us-west2-a", count: 1, }, ], }, { - template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", - name: "Dotfiles URL", + name: "Security groups", values: [ { - value: " ", - count: 11, + value: + '["Web Server Security Group","Database Security Group","Backend Security Group"]', + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Very random string", + name: "buggy-1", + values: [ { - value: " git@github.com:jsjoeio/dotfiles.git", - count: 1, + value: "", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Force rebuild", + name: "force-rebuild", + values: [ { - value: "git@github.com:Emyrk/dotfiles.git", - count: 1, + value: "false", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Location", + name: "location", + options: [ { - value: "git@github.com:ericpaulsen/dot-v2.git", - count: 1, + name: "US (Virginia)", + description: "", + value: "eastus", + icon: "/emojis/1f1fa-1f1f8.png", }, { - value: "git@github.com:johnstcn/dotfiles-coder.git", - count: 2, + name: "US (Virginia) 2", + description: "", + value: "eastus2", + icon: "/emojis/1f1fa-1f1f8.png", }, { - value: "git@github.com:spikecurtis/dotfiles.git", - count: 1, + name: "US (Texas)", + description: "", + value: "southcentralus", + icon: "/emojis/1f1fa-1f1f8.png", }, { - value: "https://github.com/bpmct/dot", - count: 1, + name: "US (Washington)", + description: "", + value: "westus2", + icon: "/emojis/1f1fa-1f1f8.png", }, { - value: "https://github.com/spikecurtis/dotfiles.git", + name: "US (Arizona)", + description: "", + value: "westus3", + icon: "/emojis/1f1fa-1f1f8.png", + }, + { + name: "US (Iowa)", + description: "", + value: "centralus", + icon: "/emojis/1f1fa-1f1f8.png", + }, + { + name: "Canada (Toronto)", + description: "", + value: "canadacentral", + icon: "/emojis/1f1e8-1f1e6.png", + }, + { + name: "Brazil (Sao Paulo)", + description: "", + value: "brazilsouth", + icon: "/emojis/1f1e7-1f1f7.png", + }, + { + name: "East Asia (Hong Kong)", + description: "", + value: "eastasia", + icon: "/emojis/1f1f0-1f1f7.png", + }, + { + name: "Southeast Asia (Singapore)", + description: "", + value: "southeastasia", + icon: "/emojis/1f1f0-1f1f7.png", + }, + { + name: "Australia (New South Wales)", + description: "", + value: "australiaeast", + icon: "/emojis/1f1e6-1f1fa.png", + }, + { + name: "China (Hebei)", + description: "", + value: "chinanorth3", + icon: "/emojis/1f1e8-1f1f3.png", + }, + { + name: "India (Pune)", + description: "", + value: "centralindia", + icon: "/emojis/1f1ee-1f1f3.png", + }, + { + name: "Japan (Tokyo)", + description: "", + value: "japaneast", + icon: "/emojis/1f1ef-1f1f5.png", + }, + { + name: "Korea (Seoul)", + description: "", + value: "koreacentral", + icon: "/emojis/1f1f0-1f1f7.png", + }, + { + name: "Europe (Ireland)", + description: "", + value: "northeurope", + icon: "/emojis/1f1ea-1f1fa.png", + }, + { + name: "Europe (Netherlands)", + description: "", + value: "westeurope", + icon: "/emojis/1f1ea-1f1fa.png", + }, + { + name: "France (Paris)", + description: "", + value: "francecentral", + icon: "/emojis/1f1eb-1f1f7.png", + }, + { + name: "Germany (Frankfurt)", + description: "", + value: "germanywestcentral", + icon: "/emojis/1f1e9-1f1ea.png", + }, + { + name: "Norway (Oslo)", + description: "", + value: "norwayeast", + icon: "/emojis/1f1f3-1f1f4.png", + }, + { + name: "Sweden (Gävle)", + description: "", + value: "swedencentral", + icon: "/emojis/1f1f8-1f1ea.png", + }, + { + name: "Switzerland (Zurich)", + description: "", + value: "switzerlandnorth", + icon: "/emojis/1f1e8-1f1ed.png", + }, + { + name: "Qatar (Doha)", + description: "", + value: "qatarcentral", + icon: "/emojis/1f1f6-1f1e6.png", + }, + { + name: "UAE (Dubai)", + description: "", + value: "uaenorth", + icon: "/emojis/1f1e6-1f1ea.png", + }, + { + name: "South Africa (Johannesburg)", + description: "", + value: "southafricanorth", + icon: "/emojis/1f1ff-1f1e6.png", + }, + { + name: "UK (London)", + description: "", + value: "uksouth", + icon: "/emojis/1f1ec-1f1e7.png", + }, + ], + values: [ + { + value: "brazilsouth", count: 1, }, { - value: "https://phorcys.net/dotfiles", + value: "switzerlandnorth", count: 1, }, ], }, { - template_ids: ["0d286645-29aa-4eaf-9b52-cc5d2740c90b"], + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", - name: "Region", + name: "mtojek_region", options: [ { - name: "Pittsburgh", + name: "Los Angeles, CA", description: "", - value: "us-pittsburgh", - icon: "/emojis/1f1fa-1f1f8.png", + value: "Los Angeles, CA", + icon: "", }, { - name: "Helsinki", + name: "Moncks Corner, SC", description: "", - value: "eu-helsinki", - icon: "/emojis/1f1eb-1f1ee.png", + value: "Moncks Corner, SC", + icon: "", }, { - name: "Sydney", + name: "Eemshaven, NL", description: "", - value: "ap-sydney", - icon: "/emojis/1f1e6-1f1fa.png", - }, - { - name: "São Paulo", - description: "", - value: "sa-saopaulo", - icon: "/emojis/1f1e7-1f1f7.png", + value: "Eemshaven, NL", + icon: "", }, ], values: [ { - value: "ap-sydney", - count: 1, + value: "Los Angeles, CA", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "My Project ID", + name: "project_id", + values: [ { - value: "eu-helsinki", - count: 5, + value: "12345", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Force devcontainer rebuild", + name: "rebuild_devcontainer", + values: [ { - value: "sa-saopaulo", - count: 3, + value: "false", + count: 2, }, + ], + }, + { + template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], + display_name: "Git Repo URL", + name: "repo_url", + values: [ { - value: "us-pittsburgh", - count: 11, + value: "https://github.com/mtojek/coder", + count: 2, }, ], }, From 157a9ee8b747d1eefb7745bdf829c76e2d3937c2 Mon Sep 17 00:00:00 2001 From: BrunoQuaresma Date: Mon, 7 Aug 2023 17:07:06 +0000 Subject: [PATCH 7/7] Add improvements --- .../TemplateInsightsPage.stories.tsx | 25 +++++ .../TemplateInsightsPage.tsx | 102 ++++++++++-------- 2 files changed, 81 insertions(+), 46 deletions(-) diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx index 4ba4180522688..4fb65c0b2b5f1 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.stories.tsx @@ -88,6 +88,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", name: "Compute instances", + type: "number", + description: "Let's set the expected number of instances.", values: [ { value: "3", @@ -99,6 +101,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", name: "Docker Image", + type: "string", + description: "Docker image for the development container", values: [ { value: "ghcr.io/harrison-ai/coder-dev:base", @@ -110,6 +114,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Very random string", name: "Optional random string", + type: "string", + description: "This string is optional", values: [ { value: "ksjdlkajs;djálskd'l ;a k;aosdk ;oaids ;li", @@ -125,6 +131,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", name: "Region", + type: "string", + description: "These are options.", options: [ { name: "US Central", @@ -160,6 +168,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", name: "Security groups", + type: "list(string)", + description: "Select appropriate security groups.", values: [ { value: @@ -172,6 +182,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Very random string", name: "buggy-1", + type: "string", + description: "This string is buggy", values: [ { value: "", @@ -183,6 +195,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Force rebuild", name: "force-rebuild", + type: "bool", + description: "Rebuild the project code", values: [ { value: "false", @@ -194,6 +208,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Location", name: "location", + type: "string", + description: "What location should your workspace live in?", options: [ { name: "US (Virginia)", @@ -367,6 +383,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "", name: "mtojek_region", + type: "string", + description: "What region should your workspace live in?", options: [ { name: "Los Angeles, CA", @@ -398,6 +416,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "My Project ID", name: "project_id", + type: "string", + description: "This is the Project ID.", values: [ { value: "12345", @@ -409,6 +429,8 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Force devcontainer rebuild", name: "rebuild_devcontainer", + type: "bool", + description: "", values: [ { value: "false", @@ -420,6 +442,9 @@ export const Loaded: Story = { template_ids: ["7dd1d090-3e23-4ada-8894-3945affcad42"], display_name: "Git Repo URL", name: "repo_url", + type: "string", + description: + "See sample projects (https://github.com/microsoft/vscode-dev-containers#sample-projects)", values: [ { value: "https://github.com/mtojek/coder", diff --git a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx index 18eb67034bc69..77bf66a0759e9 100644 --- a/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx +++ b/site/src/pages/TemplatePage/TemplateInsightsPage/TemplateInsightsPage.tsx @@ -318,13 +318,26 @@ const TemplateParametersUsagePanel = ({ }, }} > - {label} + + {label} + theme.palette.text.secondary, + maxWidth: 400, + margin: 0, + }} + > + {parameter.description} + + {parameter.values .sort((a, b) => b.count - a.count) - .map((value, valueIndex) => ( + .map((usage, usageIndex) => ( - - {value.count} + + {usage.count} ))} @@ -346,14 +362,14 @@ const TemplateParametersUsagePanel = ({ ) } -const ValueLabel = ({ - value, +const ParameterUsageLabel = ({ + usage, parameter, }: { - value: TemplateParameterValue + usage: TemplateParameterValue parameter: TemplateParameterUsage }) => { - if (value.value.trim() === "") { + if (usage.value.trim() === "") { return ( o.value === value.value)! + const option = parameter.options.find((o) => o.value === usage.value)! const icon = option.icon const label = option.name @@ -397,10 +413,10 @@ const ValueLabel = ({ ) } - if (value.value.startsWith("http")) { + if (usage.value.startsWith("http")) { return ( - {value.value} + {usage.value} ) } - if (value.value.startsWith("[")) { - const values = JSON.parse(value.value) as string[] + if (parameter.type === "list(string)") { + const values = JSON.parse(usage.value) as string[] return ( {values.map((v, i) => { @@ -439,28 +455,7 @@ const ValueLabel = ({ ) } - if (value.value === "false") { - return ( - - theme.palette.error.light, - }} - /> - False - - ) - } - - if (value.value === "true") { + if (parameter.type === "bool") { return ( - theme.palette.success.light, - }} - /> - True + {usage.value === "false" ? ( + <> + theme.palette.error.light, + }} + /> + False + + ) : ( + <> + theme.palette.success.light, + }} + /> + True + + )} ) } - return {value.value} + return {usage.value} } const Panel = styled(Box)(({ theme }) => ({