Chore: Mark up User Profile page for translation (#43874)

* Mark up User profile page for translation

* Extract new messages

* updated selectors

* update selectors

* wip TestProvider

* update tests

* fix field labels

* extract new messages

* don't store date objects in redux state

* don't store date objects in redux state
This commit is contained in:
Josh Hunt 2022-01-17 16:58:49 +00:00 committed by GitHub
parent 6d072ad84d
commit 36983d8d3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 629 additions and 66 deletions

View File

@ -2,7 +2,8 @@
"locales": [
"en",
"fr",
"es"
"es",
"pseudo-LOCALE"
],
"catalogs": [
{
@ -11,14 +12,18 @@
"public/app"
],
"exclude": [
"**/*.d.ts",
"**/*.test.ts",
"**/node_modules/**",
"public/app/plugins"
]
}
],
"fallbackLocales": {
"pseudo-LOCALE": "en",
"default": "en"
},
"pseudoLocale": "pseudo-LOCALE",
"sourceLocale": "en",
"format": "po",
"formatOptions": {

View File

@ -322,4 +322,10 @@ export const Components = {
DashboardRow: {
title: (title: string) => `data-testid dashboard-row-title-${title}`,
},
UserProfile: {
profileSaveButton: 'data-testid-user-profile-save',
preferencesSaveButton: 'data-testid-shared-prefs-save',
orgsTable: 'data-testid-user-orgs-table',
sessionsTable: 'data-testid-user-sessions-table',
},
};

View File

@ -21,6 +21,7 @@ import { selectors } from '@grafana/e2e-selectors';
import { DashboardSearchHit, DashboardSearchItemType } from 'app/features/search/types';
import { backendSrv } from 'app/core/services/backend_srv';
import { PreferencesService } from 'app/core/services/PreferencesService';
import { t, Trans } from '@lingui/macro';
export interface Props {
resourceUri: string;
@ -36,9 +37,9 @@ export interface State {
}
const themes: SelectableValue[] = [
{ value: '', label: 'Default' },
{ value: 'dark', label: 'Dark' },
{ value: 'light', label: 'Light' },
{ value: '', label: t({ id: 'shared-preferences.theme.default-label', message: 'Default' }) },
{ value: 'dark', label: t({ id: 'shared-preferences.theme.dark-label', message: 'Dark' }) },
{ value: 'light', label: t({ id: 'shared-preferences.theme.light-label', message: 'Light' }) },
];
export class SharedPreferences extends PureComponent<Props, State> {
@ -130,12 +131,24 @@ export class SharedPreferences extends PureComponent<Props, State> {
const { disabled } = this.props;
const styles = getStyles();
const homeDashboardTooltip = (
<Tooltip
content={
<Trans id="shared-preferences.fields.home-dashboard-tooltip">
Not finding the dashboard you want? Star it first, then it should appear in this select box.
</Trans>
}
>
<Icon name="info-circle" />
</Tooltip>
);
return (
<Form onSubmit={this.onSubmitForm}>
{() => {
return (
<FieldSet label="Preferences" disabled={disabled}>
<Field label="UI Theme">
<FieldSet label={<Trans id="shared-preferences.title">Preferences</Trans>} disabled={disabled}>
<Field label={t({ id: 'shared-preferences.fields.theme-label', message: 'UI Theme' })}>
<RadioButtonGroup
options={themes}
value={themes.find((item) => item.value === theme)?.value}
@ -146,10 +159,11 @@ export class SharedPreferences extends PureComponent<Props, State> {
<Field
label={
<Label htmlFor="home-dashboard-select">
<span className={styles.labelText}>Home Dashboard</span>
<Tooltip content="Not finding the dashboard you want? Star it first, then it should appear in this select box.">
<Icon name="info-circle" />
</Tooltip>
<span className={styles.labelText}>
<Trans id="shared-preferences.fields.home-dashboard-label">Home Dashboard</Trans>
</span>
{homeDashboardTooltip}
</Label>
}
data-testid="User preferences home dashboard drop down"
@ -163,30 +177,40 @@ export class SharedPreferences extends PureComponent<Props, State> {
this.onHomeDashboardChanged(dashboard.id)
}
options={dashboards}
placeholder="Choose default dashboard"
placeholder={t({
id: 'shared-preferences.fields.home-dashboard-placeholder',
message: 'Choose default dashboard',
})}
inputId="home-dashboard-select"
/>
</Field>
<Field label="Timezone" data-testid={selectors.components.TimeZonePicker.containerV2}>
<Field
label={t({ id: 'shared-dashboard.fields.timezone-label', message: 'Timezone' })}
data-testid={selectors.components.TimeZonePicker.containerV2}
>
<TimeZonePicker
includeInternal={true}
value={timezone}
onChange={this.onTimeZoneChanged}
inputId={'shared-preferences-timezone-picker'}
inputId="shared-preferences-timezone-picker"
/>
</Field>
<Field label="Week start" data-testid={selectors.components.WeekStartPicker.containerV2}>
<Field
label={t({ id: 'shared-preferences.fields.week-start-label', message: 'Week start' })}
data-testid={selectors.components.WeekStartPicker.containerV2}
>
<WeekStartPicker
value={weekStart}
onChange={this.onWeekStartChanged}
inputId={'shared-preferences-week-start-picker'}
/>
</Field>
<div className="gf-form-button-row">
<Button variant="primary" aria-label="User preferences save button">
Save
<Button variant="primary" data-testid={selectors.components.UserProfile.preferencesSaveButton}>
<Trans id="common.save">Save</Trans>
</Button>
</div>
</FieldSet>

View File

@ -3,8 +3,9 @@ import { css } from '@emotion/css';
import { ConfirmButton, ConfirmModal, Button } from '@grafana/ui';
import { AccessControlAction, UserSession } from 'app/types';
import { contextSrv } from 'app/core/core';
import { withI18n, withI18nProps } from '@lingui/react';
interface Props {
interface Props extends withI18nProps {
sessions: UserSession[];
onSessionRevoke: (id: number) => void;
@ -15,7 +16,7 @@ interface State {
showLogoutModal: boolean;
}
export class UserSessions extends PureComponent<Props, State> {
class BaseUserSessions extends PureComponent<Props, State> {
forceAllLogoutButton = React.createRef<HTMLButtonElement>();
state: State = {
showLogoutModal: false,
@ -43,7 +44,7 @@ export class UserSessions extends PureComponent<Props, State> {
};
render() {
const { sessions } = this.props;
const { sessions, i18n } = this.props;
const { showLogoutModal } = this.state;
const logoutFromAllDevicesClass = css`
@ -71,7 +72,7 @@ export class UserSessions extends PureComponent<Props, State> {
sessions.map((session, index) => (
<tr key={`${session.id}-${index}`}>
<td>{session.isActive ? 'Now' : session.seenAt}</td>
<td>{session.createdAt}</td>
<td>{i18n.date(session.createdAt, { dateStyle: 'long' })}</td>
<td>{session.clientIp}</td>
<td>{`${session.browser} on ${session.os} ${session.osVersion}`}</td>
<td>
@ -113,3 +114,5 @@ export class UserSessions extends PureComponent<Props, State> {
);
}
}
export const UserSessions = withI18n()(BaseUserSessions);

View File

@ -1,5 +1,5 @@
import config from 'app/core/config';
import { dateTimeFormat, dateTimeFormatTimeAgo } from '@grafana/data';
import { dateTimeFormatTimeAgo } from '@grafana/data';
import { featureEnabled, getBackendSrv, locationService } from '@grafana/runtime';
import { ThunkResult, LdapUser, UserSession, UserDTO, AccessControlAction, UserFilter } from 'app/types';
@ -144,12 +144,13 @@ export function loadUserSessions(userId: number): ThunkResult<void> {
const tokens = await getBackendSrv().get(`/api/admin/users/${userId}/auth-tokens`);
tokens.reverse();
const sessions = tokens.map((session: UserSession) => {
return {
id: session.id,
isActive: session.isActive,
seenAt: dateTimeFormatTimeAgo(session.seenAt),
createdAt: dateTimeFormat(session.createdAt, { format: 'MMMM DD, YYYY' }),
createdAt: session.createdAt,
clientIp: session.clientIp,
browser: session.browser,
browserVersion: session.browserVersion,
@ -158,6 +159,7 @@ export function loadUserSessions(userId: number): ThunkResult<void> {
device: session.device,
};
});
dispatch(userSessionsLoadedAction(sessions));
};
}

View File

@ -1,6 +1,8 @@
import React, { PureComponent } from 'react';
import { UserDTO, UserOrg } from 'app/types';
import { Button, LoadingPlaceholder } from '@grafana/ui';
import { Trans } from '@lingui/macro';
import { selectors } from '@grafana/e2e-selectors';
export interface Props {
user: UserDTO | null;
@ -23,13 +25,20 @@ export class UserOrganizations extends PureComponent<Props> {
return (
<div>
<h3 className="page-sub-heading">Organizations</h3>
<h3 className="page-sub-heading">
<Trans id="user-orgs.title">Organizations</Trans>
</h3>
<div className="gf-form-group">
<table className="filter-table form-inline" aria-label="User organizations table">
<table className="filter-table form-inline" data-testid={selectors.components.UserProfile.orgsTable}>
<thead>
<tr>
<th>Name</th>
<th>Role</th>
<th>
<Trans id="user-orgs.name-column">Name</Trans>
</th>
<th>
<Trans id="user-orgs.role-column">Role</Trans>
</th>
<th />
</tr>
</thead>
@ -42,7 +51,7 @@ export class UserOrganizations extends PureComponent<Props> {
<td className="text-right">
{org.orgId === user?.orgId ? (
<Button variant="secondary" size="sm" disabled>
Current
<Trans id="user-orgs.current-org-button">Current</Trans>
</Button>
) : (
<Button
@ -51,9 +60,8 @@ export class UserOrganizations extends PureComponent<Props> {
onClick={() => {
this.props.setUserOrg(org);
}}
aria-label={`Switch to the organization named ${org.name}`}
>
Select
<Trans id="user-orgs.select-org-button">Select organisation</Trans>
</Button>
)}
</td>

View File

@ -1,6 +1,7 @@
import React, { FC } from 'react';
import { Trans } from '@lingui/macro';
import { Trans, t } from '@lingui/macro';
import { Button, Field, FieldSet, Form, Icon, Input, Tooltip } from '@grafana/ui';
import { selectors } from '@grafana/e2e-selectors';
import { UserDTO } from 'app/types';
import config from 'app/core/config';
import { ProfileUpdateFields } from './types';
@ -22,37 +23,57 @@ export const UserProfileEditForm: FC<Props> = ({ user, isSavingUser, updateProfi
<Form onSubmit={onSubmitProfileUpdate} validateOn="onBlur">
{({ register, errors }) => {
return (
<FieldSet label={<Trans id="edit-user-profile.title">Edit profile</Trans>}>
<Field label="Name" invalid={!!errors.name} error="Name is required" disabled={disableLoginForm}>
<FieldSet label={<Trans id="user-profile.title">Edit profile</Trans>}>
<Field
label={t({ id: 'user-profile.fields.name-label', message: 'Name' })}
invalid={!!errors.name}
error={<Trans id="user-profile.fields.name-error">Name is required</Trans>}
disabled={disableLoginForm}
>
<Input
{...register('name', { required: true })}
id="edit-user-profile-name"
placeholder="Name"
placeholder={t({ id: 'user-profile.fields.name-label', message: 'Name' })}
defaultValue={user?.name ?? ''}
suffix={<InputSuffix />}
/>
</Field>
<Field label="Email" invalid={!!errors.email} error="Email is required" disabled={disableLoginForm}>
<Field
label={t({ id: 'user-profile.fields.email-label', message: 'Email' })}
invalid={!!errors.email}
error={<Trans id="user-profile.fields.email-error">Email is required</Trans>}
disabled={disableLoginForm}
>
<Input
{...register('email', { required: true })}
id="edit-user-profile-email"
placeholder="Email"
placeholder={t({ id: 'user-profile.fields.email-label', message: 'Email' })}
defaultValue={user?.email ?? ''}
suffix={<InputSuffix />}
/>
</Field>
<Field label="Username" disabled={disableLoginForm}>
<Field
label={t({ id: 'user-profile.fields.username-label', message: 'Username' })}
disabled={disableLoginForm}
>
<Input
{...register('login')}
id="edit-user-profile-username"
defaultValue={user?.login ?? ''}
placeholder="Username"
placeholder={t({ id: 'user-profile.fields.username-label', message: 'Username' })}
suffix={<InputSuffix />}
/>
</Field>
<div className="gf-form-button-row">
<Button variant="primary" disabled={isSavingUser} aria-label="Edit user profile save button">
Save
<Button
variant="primary"
disabled={isSavingUser}
data-testid={selectors.components.UserProfile.profileSaveButton}
>
<Trans id="common.save">Save</Trans>
</Button>
</div>
</FieldSet>

View File

@ -4,6 +4,7 @@ import userEvent from '@testing-library/user-event';
import { within } from '@testing-library/dom';
import { OrgRole } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import TestProvider from '../../../test/helpers/TestProvider';
import { Props, UserProfileEditPage } from './UserProfileEditPage';
import { initialUserState } from './state/reducers';
@ -90,28 +91,28 @@ function getSelectors() {
const dashboardSelect = () => screen.getByTestId('User preferences home dashboard drop down');
const timepickerSelect = () => screen.getByTestId(selectors.components.TimeZonePicker.containerV2);
const teamsTable = () => screen.getByRole('table', { name: /user teams table/i });
const orgsTable = () => screen.getByRole('table', { name: /user organizations table/i });
const sessionsTable = () => screen.getByRole('table', { name: /user sessions table/i });
const orgsTable = () => screen.getByTestId(selectors.components.UserProfile.orgsTable);
const sessionsTable = () => screen.getByTestId(selectors.components.UserProfile.sessionsTable);
return {
name: () => screen.getByRole('textbox', { name: /^name$/i }),
email: () => screen.getByRole('textbox', { name: /email/i }),
username: () => screen.getByRole('textbox', { name: /username/i }),
saveProfile: () => screen.getByRole('button', { name: /edit user profile save button/i }),
saveProfile: () => screen.getByTestId(selectors.components.UserProfile.profileSaveButton),
dashboardSelect,
dashboardValue: () => within(dashboardSelect()).getByText(/default/i),
timepickerSelect,
timepickerValue: () => within(timepickerSelect()).getByText(/coordinated universal time/i),
savePreferences: () => screen.getByRole('button', { name: /user preferences save button/i }),
savePreferences: () => screen.getByTestId(selectors.components.UserProfile.preferencesSaveButton),
teamsTable,
teamsRow: () => within(teamsTable()).getByRole('row', { name: /team one team.one@test\.com 2000/i }),
orgsTable,
orgsEditorRow: () => within(orgsTable()).getByRole('row', { name: /main editor current/i }),
orgsViewerRow: () => within(orgsTable()).getByRole('row', { name: /second viewer select/i }),
orgsAdminRow: () => within(orgsTable()).getByRole('row', { name: /third admin select/i }),
orgsViewerRow: () => within(orgsTable()).getByRole('row', { name: /second viewer select organisation/i }),
orgsAdminRow: () => within(orgsTable()).getByRole('row', { name: /third admin select organisation/i }),
sessionsTable,
sessionsRow: () =>
within(sessionsTable()).getByRole('row', {
name: /now 2021-01-01 04:00:00 localhost chrome on mac os x 11/i,
name: /now January 1, 2021 localhost chrome on mac os x 11/i,
}),
};
}
@ -125,7 +126,11 @@ async function getTestContext(overrides: Partial<Props> = {}) {
const searchSpy = jest.spyOn(backendSrv, 'search').mockResolvedValue([]);
const props = { ...defaultProps, ...overrides };
const { rerender } = render(<UserProfileEditPage {...props} />);
const { rerender } = render(
<TestProvider>
<UserProfileEditPage {...props} />
</TestProvider>
);
await waitFor(() => expect(props.initUserProfilePage).toHaveBeenCalledTimes(1));
@ -253,7 +258,7 @@ describe('UserProfileEditPage', () => {
const { props } = await getTestContext();
const orgsAdminSelectButton = () =>
within(getSelectors().orgsAdminRow()).getByRole('button', {
name: /switch to the organization named Third/i,
name: /select organisation/i,
});
userEvent.click(orgsAdminSelectButton());

View File

@ -1,19 +1,22 @@
import React, { PureComponent } from 'react';
import { UserSession } from 'app/types';
import { Button, Icon, LoadingPlaceholder } from '@grafana/ui';
import { withI18n, withI18nProps } from '@lingui/react';
import { t, Trans } from '@lingui/macro';
import { selectors } from '@grafana/e2e-selectors';
export interface Props {
interface Props extends withI18nProps {
sessions: UserSession[];
isLoading: boolean;
revokeUserSession: (tokenId: number) => void;
}
export class UserSessions extends PureComponent<Props> {
class UserSessions extends PureComponent<Props> {
render() {
const { isLoading, sessions, revokeUserSession } = this.props;
const { isLoading, sessions, revokeUserSession, i18n } = this.props;
if (isLoading) {
return <LoadingPlaceholder text="Loading sessions..." />;
return <LoadingPlaceholder text={<Trans id="user-sessions.loading">Loading sessions...</Trans>} />;
}
return (
@ -22,13 +25,21 @@ export class UserSessions extends PureComponent<Props> {
<>
<h3 className="page-sub-heading">Sessions</h3>
<div className="gf-form-group">
<table className="filter-table form-inline" aria-label="User sessions table">
<table className="filter-table form-inline" data-testid={selectors.components.UserProfile.sessionsTable}>
<thead>
<tr>
<th>Last seen</th>
<th>Logged on</th>
<th>IP address</th>
<th>Browser &amp; OS</th>
<th>
<Trans id="user-session.seen-at-column">Last seen</Trans>
</th>
<th>
<Trans id="user-session.created-at-column">Logged on</Trans>
</th>
<th>
<Trans id="user-session.ip-column">IP address</Trans>
</th>
<th>
<Trans id="user-session.browser-column">Browser &amp; OS</Trans>
</th>
<th></th>
</tr>
</thead>
@ -36,7 +47,7 @@ export class UserSessions extends PureComponent<Props> {
{sessions.map((session: UserSession, index) => (
<tr key={index}>
{session.isActive ? <td>Now</td> : <td>{session.seenAt}</td>}
<td>{session.createdAt}</td>
<td>{i18n.date(session.createdAt, { dateStyle: 'long' })}</td>
<td>{session.clientIp}</td>
<td>
{session.browser} on {session.os} {session.osVersion}
@ -46,7 +57,7 @@ export class UserSessions extends PureComponent<Props> {
size="sm"
variant="destructive"
onClick={() => revokeUserSession(session.id)}
aria-label="Revoke user session"
aria-label={t({ id: 'user-session.revoke', message: 'Revoke user session' })}
>
<Icon name="power" />
</Button>
@ -63,4 +74,4 @@ export class UserSessions extends PureComponent<Props> {
}
}
export default UserSessions;
export default withI18n()(UserSessions);

View File

@ -166,7 +166,7 @@ describe('userReducer', () => {
browserVersion: '90',
osVersion: '95',
clientIp: '192.168.1.1',
createdAt: 'December 31, 2020',
createdAt: '2021-01-01 04:00:00',
device: 'Computer',
os: 'Windows',
isActive: false,

View File

@ -1,6 +1,6 @@
import { isEmpty, isString, set } from 'lodash';
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { dateTimeFormat, dateTimeFormatTimeAgo, setWeekStart, TimeZone } from '@grafana/data';
import { dateTimeFormatTimeAgo, setWeekStart, TimeZone } from '@grafana/data';
import { Team, ThunkResult, UserDTO, UserOrg, UserSession } from 'app/types';
import config from 'app/core/config';
@ -78,7 +78,7 @@ export const slice = createSlice({
id: session.id,
isActive: session.isActive,
seenAt: dateTimeFormatTimeAgo(session.seenAt),
createdAt: dateTimeFormat(session.createdAt, { format: 'MMMM DD, YYYY' }),
createdAt: session.createdAt,
clientIp: session.clientIp,
browser: session.browser,
browserVersion: session.browserVersion,

View File

@ -13,6 +13,118 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "edit-user-profile.title"
msgid "common.save"
msgstr "Save"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-dashboard.fields.timezone-label"
msgstr "Timezone"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-label"
msgstr "Home Dashboard"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-placeholder"
msgstr "Choose default dashboard"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-tooltip"
msgstr "Not finding the dashboard you want? Star it first, then it should appear in this select box."
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.theme-label"
msgstr "UI Theme"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.week-start-label"
msgstr "Week start"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.dark-label"
msgstr "Dark"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.default-label"
msgstr "Default"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.light-label"
msgstr "Light"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.title"
msgstr "Preferences"
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.current-org-button"
msgstr "Current"
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.name-column"
msgstr "Name"
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.role-column"
msgstr "Role"
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.select-org-button"
msgstr "Select"
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.title"
msgstr "Organizations"
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-error"
msgstr "Email is required"
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-label"
msgstr "Email"
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-error"
msgstr "Name is required"
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-label"
msgstr "Name"
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.username-label"
msgstr "Username"
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.title"
msgstr "Edit profile"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.browser-column"
msgstr "Browser & OS"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.created-at-column"
msgstr "Logged on"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.ip-column"
msgstr "IP address"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.revoke"
msgstr "Revoke user session"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.seen-at-column"
msgstr "Last seen"
#: public/app/features/profile/UserSessions.tsx
msgid "user-sessions.loading"
msgstr "Loading sessions..."

View File

@ -13,6 +13,118 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "edit-user-profile.title"
msgid "common.save"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-dashboard.fields.timezone-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-placeholder"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-tooltip"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.theme-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.week-start-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.dark-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.default-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.light-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.title"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.current-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.name-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.role-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.select-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.title"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.username-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.title"
msgstr "Editar perfil"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.browser-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.created-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.ip-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.revoke"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.seen-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-sessions.loading"
msgstr ""

View File

@ -13,6 +13,118 @@ msgstr ""
"Language-Team: \n"
"Plural-Forms: \n"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "edit-user-profile.title"
msgid "common.save"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-dashboard.fields.timezone-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-placeholder"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-tooltip"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.theme-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.week-start-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.dark-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.default-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.light-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.title"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.current-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.name-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.role-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.select-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.title"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.username-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.title"
msgstr "Editer le profil"
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.browser-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.created-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.ip-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.revoke"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.seen-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-sessions.loading"
msgstr ""

View File

@ -0,0 +1,130 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2022-01-10 10:42+0000\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: pseudo-LOCALE\n"
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
"Plural-Forms: \n"
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "common.save"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-dashboard.fields.timezone-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-placeholder"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.home-dashboard-tooltip"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.theme-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.fields.week-start-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.dark-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.default-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.theme.light-label"
msgstr ""
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
msgid "shared-preferences.title"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.current-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.name-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.role-column"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.select-org-button"
msgstr ""
#: public/app/features/profile/UserOrganizations.tsx
msgid "user-orgs.title"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.email-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-error"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.name-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.fields.username-label"
msgstr ""
#: public/app/features/profile/UserProfileEditForm.tsx
msgid "user-profile.title"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.browser-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.created-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.ip-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.revoke"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-session.seen-at-column"
msgstr ""
#: public/app/features/profile/UserSessions.tsx
msgid "user-sessions.loading"
msgstr ""

View File

@ -0,0 +1,8 @@
import React from 'react';
import { I18nProvider } from '../../app/core/localisation';
const TestProvider: React.FC = ({ children }) => {
return <I18nProvider>{children}</I18nProvider>;
};
export default TestProvider;

View File

@ -15,3 +15,7 @@ export const Select: React.FC = () => {
export const SelectOrdinal: React.FC = () => {
throw new Error('SelectOrdinal mock not implemented yet');
};
export const t = (msg: string | { message: string }) => {
return typeof msg === 'string' ? msg : msg.message;
};