Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fbfe2f7

Browse files
committed
Switch to i18n - wip
1 parent 8fd2a7a commit fbfe2f7

File tree

7 files changed

+63
-61
lines changed

7 files changed

+63
-61
lines changed

site/src/i18n/en/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import agent from "./agent.json"
88
import buildPage from "./buildPage.json"
99
import workspacesPage from "./workspacesPage.json"
1010
import usersPage from "./usersPage.json"
11+
import templateSettingsPage from "./templateSettingsPage.json"
1112
import templateVersionPage from "./templateVersionPage.json"
1213
import loginPage from "./loginPage.json"
1314
import workspaceChangeVersionPage from "./workspaceChangeVersionPage.json"
@@ -23,6 +24,7 @@ export const en = {
2324
buildPage,
2425
workspacesPage,
2526
usersPage,
27+
templateSettingsPage,
2628
templateVersionPage,
2729
loginPage,
2830
workspaceChangeVersionPage,

site/src/i18n/en/templatePage.json

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
11
{
22
"deleteSuccess": "Template successfully deleted.",
3-
"createdVersion": "created the version",
4-
"templateSettings": {
5-
"title": "Template settings",
6-
"dangerZone": {
7-
"dangerZoneHeader": "Danger Zone",
8-
"deleteTemplateHeader": "Delete this template",
9-
"deleteTemplateCaption": "Do you want to permanently delete this template?",
10-
"deleteCta": "Delete Template"
11-
}
12-
},
13-
"displayNameLabel": "Display name",
14-
"allowUserCancelWorkspaceJobsLabel": "Allow users to cancel in-progress workspace jobs.",
15-
"allowUserCancelWorkspaceJobsNotice": "Depending on your template, canceling builds may leave workspaces in an unhealthy state. This option isn't recommended for most use cases."
3+
"createdVersion": "created the version"
164
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"title": "Template settings",
3+
"nameLabel": "Name",
4+
"displayNameLabel": "Display name",
5+
"descriptionLabel": "Description",
6+
"descriptionMaxError": "Please enter a description that is less than or equal to 128 characters.",
7+
"defaultTtlLabel": "Auto-stop default",
8+
"iconLabel": "Icon",
9+
"formAriaLabel": "Template settings form",
10+
"selectEmoji": "Select emoji",
11+
"ttlMaxError": "Please enter a limit that is less than or equal to 168 hours (7 days).",
12+
"ttlMinError": "Default time until auto-stop must not be less than 0.",
13+
"ttlHelperText_zero": "Workspaces created from this template will run until stopped manually.",
14+
"ttlHelperText_one": "Workspaces created from this template will default to stopping after {{count}} hour.",
15+
"ttlHelperText_other": "Workspaces created from this template will default to stopping after {{count}} hours.",
16+
"allowUserCancelWorkspaceJobsLabel": "Allow users to cancel in-progress workspace jobs.",
17+
"allowUserCancelWorkspaceJobsNotice": "Depending on your template, canceling builds may leave workspaces in an unhealthy state. This option isn't recommended for most use cases.",
18+
"dangerZone": {
19+
"dangerZoneHeader": "Danger Zone",
20+
"deleteTemplateHeader": "Delete this template",
21+
"deleteTemplateCaption": "Do you want to permanently delete this template?",
22+
"deleteCta": "Delete Template"
23+
}
24+
}

site/src/pages/TemplateSettingsPage/TemplateSettingsForm.tsx

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -24,50 +24,41 @@ import {
2424
import * as Yup from "yup"
2525
import i18next from "i18next"
2626
import { useTranslation } from "react-i18next"
27+
import { Maybe } from "components/Conditionals/Maybe"
2728

28-
export const Language = {
29-
nameLabel: "Name",
30-
descriptionLabel: "Description",
31-
defaultTtlLabel: "Auto-stop default",
32-
iconLabel: "Icon",
33-
formAriaLabel: "Template settings form",
34-
selectEmoji: "Select emoji",
35-
ttlMaxError:
36-
"Please enter a limit that is less than or equal to 168 hours (7 days).",
37-
descriptionMaxError:
38-
"Please enter a description that is less than or equal to 128 characters.",
39-
ttlHelperText: (ttl: number): string =>
40-
ttl === 1
41-
? `Workspaces created from this template will default to stopping after ${ttl} hour.`
42-
: `Workspaces created from this template will default to stopping after ${ttl} hours.`,
43-
noTTL:
44-
"Workspaces created from this template will run until stopped manually.",
29+
const TTLHelperText = ({ ttl }: { ttl?: number }) => {
30+
const { t } = useTranslation("templateSettingsPage")
31+
const count = typeof ttl !== "number" ? 0 : ttl
32+
return (
33+
// no helper text if ttl is negative - error will show once field is considered touched
34+
<Maybe condition={count >= 0}>
35+
<span>{t("ttlHelperText", { count })}</span>
36+
</Maybe>
37+
)
4538
}
4639

47-
const TTLHelperText = ({ ttl }: { ttl?: number }) =>
48-
ttl !== undefined ? (
49-
<span>{ttl === 0 ? Language.noTTL : Language.ttlHelperText(ttl)}</span>
50-
) : null
51-
5240
const MAX_DESCRIPTION_CHAR_LIMIT = 128
5341
const MAX_TTL_DAYS = 7
5442
const MS_HOUR_CONVERSION = 3600000
5543

5644
export const validationSchema = Yup.object({
57-
name: nameValidator(Language.nameLabel),
45+
name: nameValidator(i18next.t("nameLabel", { ns: "templateSettingsPage" })),
5846
display_name: templateDisplayNameValidator(
5947
i18next.t("displayNameLabel", {
60-
ns: "templatePage",
48+
ns: "templateSettingsPage",
6149
}),
6250
),
6351
description: Yup.string().max(
6452
MAX_DESCRIPTION_CHAR_LIMIT,
65-
Language.descriptionMaxError,
53+
i18next.t("descriptionMaxError", { ns: "templateSettingsPage" }),
6654
),
6755
default_ttl_ms: Yup.number()
6856
.integer()
69-
.min(0)
70-
.max(24 * MAX_TTL_DAYS /* 7 days in hours */, Language.ttlMaxError),
57+
.min(0, i18next.t("ttlMinError", { ns: "templateSettingsPage" }))
58+
.max(
59+
24 * MAX_TTL_DAYS /* 7 days in hours */,
60+
i18next.t("ttlMaxError", { ns: "templateSettingsPage" }),
61+
),
7162
allow_user_cancel_workspace_jobs: Yup.boolean(),
7263
})
7364

@@ -119,18 +110,18 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
119110
const hasIcon = form.values.icon && form.values.icon !== ""
120111
const emojiButtonRef = useRef<HTMLButtonElement>(null)
121112

122-
const { t } = useTranslation("templatePage")
113+
const { t } = useTranslation("templateSettingsPage")
123114

124115
return (
125-
<form onSubmit={form.handleSubmit} aria-label={Language.formAriaLabel}>
116+
<form onSubmit={form.handleSubmit} aria-label={t("formAriaLabel")}>
126117
<Stack>
127118
<TextField
128119
{...getFieldHelpers("name")}
129120
disabled={isSubmitting}
130121
onChange={onChangeTrimmed(form)}
131122
autoFocus
132123
fullWidth
133-
label={Language.nameLabel}
124+
label={t("nameLabel")}
134125
variant="outlined"
135126
/>
136127

@@ -147,7 +138,7 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
147138
multiline
148139
disabled={isSubmitting}
149140
fullWidth
150-
label={Language.descriptionLabel}
141+
label={t("descriptionLabel")}
151142
variant="outlined"
152143
rows={2}
153144
/>
@@ -157,7 +148,7 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
157148
{...getFieldHelpers("icon")}
158149
disabled={isSubmitting}
159150
fullWidth
160-
label={Language.iconLabel}
151+
label={t("iconLabel")}
161152
variant="outlined"
162153
InputProps={{
163154
endAdornment: hasIcon ? (
@@ -186,7 +177,7 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
186177
setIsEmojiPickerOpen((v) => !v)
187178
}}
188179
>
189-
{Language.selectEmoji}
180+
{t("selectEmoji")}
190181
</Button>
191182

192183
<Popover
@@ -216,12 +207,11 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
216207
{...getFieldHelpers(
217208
"default_ttl_ms",
218209
<TTLHelperText ttl={form.values.default_ttl_ms} />,
219-
"Time until auto-stop",
220210
)}
221211
disabled={isSubmitting}
222212
fullWidth
223213
inputProps={{ min: 0, step: 1 }}
224-
label={Language.defaultTtlLabel}
214+
label={t("defaultTtlLabel")}
225215
variant="outlined"
226216
type="number"
227217
/>

site/src/pages/TemplateSettingsPage/TemplateSettingsPage.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ import { useMachine } from "@xstate/react"
22
import { useOrganizationId } from "hooks/useOrganizationId"
33
import { FC } from "react"
44
import { Helmet } from "react-helmet-async"
5+
import { useTranslation } from "react-i18next"
56
import { useNavigate, useParams } from "react-router-dom"
67
import { pageTitle } from "util/page"
78
import { templateSettingsMachine } from "xServices/templateSettings/templateSettingsXService"
89
import { TemplateSettingsPageView } from "./TemplateSettingsPageView"
910

10-
const Language = {
11-
title: "Template Settings",
12-
}
13-
1411
export const TemplateSettingsPage: FC = () => {
1512
const { template: templateName } = useParams() as { template: string }
13+
const { t } = useTranslation("templateSettingsPage")
1614
const navigate = useNavigate()
1715
const organizationId = useOrganizationId()
1816
const [state, send] = useMachine(templateSettingsMachine, {
@@ -34,7 +32,7 @@ export const TemplateSettingsPage: FC = () => {
3432
return (
3533
<>
3634
<Helmet>
37-
<title>{pageTitle(Language.title)}</title>
35+
<title>{pageTitle(t("title"))}</title>
3836
</Helmet>
3937
<TemplateSettingsPageView
4038
isSubmitting={state.hasTag("submitting")}

site/src/pages/TemplateSettingsPage/TemplateSettingsPageView.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ export const TemplateSettingsPageView: FC<TemplateSettingsPageViewProps> = ({
4747
}) => {
4848
const classes = useStyles()
4949
const isLoading = !template && !errors.getTemplateError
50-
const { t } = useTranslation("templatePage")
50+
const { t } = useTranslation("templateSettingsPage")
5151

5252
if (isDeleted) {
5353
return <Navigate to="/templates" />
5454
}
5555

5656
return (
57-
<FullPageForm title={t("templateSettings.title")} onCancel={onCancel}>
57+
<FullPageForm title={t("title")} onCancel={onCancel}>
5858
{Boolean(errors.getTemplateError) && (
5959
<Stack className={classes.errorContainer}>
6060
<AlertBanner severity="error" error={errors.getTemplateError} />
@@ -78,24 +78,24 @@ export const TemplateSettingsPageView: FC<TemplateSettingsPageViewProps> = ({
7878
/>
7979
<Stack className={classes.dangerContainer}>
8080
<div className={classes.dangerHeader}>
81-
{t("templateSettings.dangerZone.dangerZoneHeader")}
81+
{t("dangerZone.dangerZoneHeader")}
8282
</div>
8383

8484
<Stack className={classes.dangerBorder}>
8585
<Stack spacing={0}>
8686
<p className={classes.deleteTemplateHeader}>
87-
{t("templateSettings.dangerZone.deleteTemplateHeader")}
87+
{t("dangerZone.deleteTemplateHeader")}
8888
</p>
8989
<span>
90-
{t("templateSettings.dangerZone.deleteTemplateCaption")}
90+
{t("dangerZone.deleteTemplateCaption")}
9191
</span>
9292
</Stack>
9393
<Button
9494
className={classes.deleteButton}
9595
onClick={onDelete}
96-
aria-label={t("templateSettings.dangerZone.deleteCta")}
96+
aria-label={t("dangerZone.deleteCta")}
9797
>
98-
{t("templateSettings.dangerZone.deleteCta")}
98+
{t("dangerZone.deleteCta")}
9999
</Button>
100100
</Stack>
101101
</Stack>

site/src/util/formUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import * as Yup from "yup"
1414

1515
export const Language = {
1616
nameRequired: (name: string): string => {
17-
return `Please enter a ${name.toLowerCase()}.`
17+
return name ? `Please enter a ${name.toLowerCase()}.` : "Required"
1818
},
1919
nameInvalidChars: (name: string): string => {
2020
return `${name} must start with a-Z or 0-9 and can contain a-Z, 0-9 or -`

0 commit comments

Comments
 (0)