0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-03 22:15:32 -05:00

fix(console,phrases): fix a batch of organization invitation console ui issues (#5614)

This commit is contained in:
Charles Zhao 2024-04-02 18:12:08 +08:00 committed by GitHub
parent e38e3c1bd0
commit a4f8199e92
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 107 additions and 58 deletions

View file

@ -1,3 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10.6666 7.38666H5.33331C4.80288 7.38666 4.29417 7.59737 3.9191 7.97244C3.54403 8.34751 3.33331 8.85622 3.33331 9.38666V12.72C3.33331 13.2504 3.54403 13.7591 3.9191 14.1342C4.29417 14.5093 4.80288 14.72 5.33331 14.72H10.6666C11.1971 14.72 11.7058 14.5093 12.0809 14.1342C12.4559 13.7591 12.6666 13.2504 12.6666 12.72V9.38666C12.6666 8.85622 12.4559 8.34751 12.0809 7.97244C11.7058 7.59737 11.1971 7.38666 10.6666 7.38666ZM10.3866 8.71999L8.46665 10.6667C8.34203 10.7888 8.17448 10.8572 7.99998 10.8572C7.82548 10.8572 7.65793 10.7888 7.53331 10.6667L5.61331 8.71999H10.3866ZM11.3333 12.72C11.3333 12.8968 11.2631 13.0664 11.1381 13.1914C11.013 13.3164 10.8435 13.3867 10.6666 13.3867H5.33331C5.1565 13.3867 4.98693 13.3164 4.86191 13.1914C4.73688 13.0664 4.66665 12.8968 4.66665 12.72V9.65999L6.58665 11.58C6.96165 11.9545 7.46998 12.1649 7.99998 12.1649C8.52998 12.1649 9.03831 11.9545 9.41331 11.58L11.3333 9.65999V12.72ZM7.13998 3.74666L7.33331 3.55332V5.38666C7.33331 5.56347 7.40355 5.73304 7.52858 5.85806C7.6536 5.98308 7.82317 6.05332 7.99998 6.05332C8.17679 6.05332 8.34636 5.98308 8.47138 5.85806C8.59641 5.73304 8.66665 5.56347 8.66665 5.38666V3.55332L8.85998 3.74666C8.9217 3.80881 8.99506 3.85821 9.07587 3.89202C9.15668 3.92582 9.24336 3.94338 9.33096 3.94369C9.41855 3.944 9.50535 3.92706 9.5864 3.89382C9.66745 3.86058 9.74115 3.81171 9.80331 3.74999C9.86547 3.68827 9.91487 3.61491 9.94867 3.5341C9.98248 3.45329 10 3.36661 10.0004 3.27901C10.0007 3.19142 9.98371 3.10462 9.95048 3.02357C9.91724 2.94252 9.86837 2.86881 9.80665 2.80666L8.47331 1.47332C8.41134 1.41084 8.3376 1.36124 8.25636 1.32739C8.17512 1.29355 8.08799 1.27612 7.99998 1.27612C7.91197 1.27612 7.82483 1.29355 7.7436 1.32739C7.66236 1.36124 7.58862 1.41084 7.52665 1.47332L6.19331 2.80666C6.06915 2.93156 5.99945 3.10053 5.99945 3.27666C5.99945 3.45278 6.06915 3.62175 6.19331 3.74666C6.25529 3.80914 6.32902 3.85874 6.41026 3.89258C6.4915 3.92643 6.57864 3.94385 6.66665 3.94385C6.75465 3.94385 6.84179 3.92643 6.92303 3.89258C7.00427 3.85874 7.078 3.80914 7.13998 3.74666Z" fill="currentColor"/>
<path d="M13.6667 9.33335C13.4899 9.33335 13.3203 9.40358 13.1953 9.52861C13.0702 9.65363 13 9.8232 13 10V12.6667C13 12.8435 12.9298 13.0131 12.8047 13.1381C12.6797 13.2631 12.5101 13.3333 12.3333 13.3333H3C2.82319 13.3333 2.65362 13.2631 2.5286 13.1381C2.40357 13.0131 2.33333 12.8435 2.33333 12.6667V6.27335L6.25333 10.2C6.62833 10.5745 7.13666 10.7849 7.66667 10.7849C8.19667 10.7849 8.705 10.5745 9.08 10.2L10.1733 9.10668C10.2989 8.98114 10.3694 8.81088 10.3694 8.63335C10.3694 8.45581 10.2989 8.28555 10.1733 8.16001C10.0478 8.03448 9.87753 7.96395 9.7 7.96395C9.52247 7.96395 9.3522 8.03448 9.22667 8.16001L8.13333 9.25335C8.00871 9.3755 7.84117 9.44392 7.66667 9.44392C7.49216 9.44392 7.32462 9.3755 7.2 9.25335L3.27333 5.33335H7.66667C7.84348 5.33335 8.01305 5.26311 8.13807 5.13808C8.26309 5.01306 8.33333 4.84349 8.33333 4.66668C8.33333 4.48987 8.26309 4.3203 8.13807 4.19527C8.01305 4.07025 7.84348 4.00001 7.66667 4.00001H3C2.46957 4.00001 1.96086 4.21073 1.58579 4.5858C1.21071 4.96087 1 5.46958 1 6.00001V12.6667C1 13.1971 1.21071 13.7058 1.58579 14.0809C1.96086 14.456 2.46957 14.6667 3 14.6667H12.3333C12.8638 14.6667 13.3725 14.456 13.7475 14.0809C14.1226 13.7058 14.3333 13.1971 14.3333 12.6667V10C14.3333 9.8232 14.2631 9.65363 14.1381 9.52861C14.013 9.40358 13.8435 9.33335 13.6667 9.33335ZM14.8067 3.52668L12.8067 1.52668C12.7433 1.46599 12.6685 1.41841 12.5867 1.38668C12.4244 1.32 12.2423 1.32 12.08 1.38668C11.9982 1.41841 11.9234 1.46599 11.86 1.52668L9.86 3.52668C9.73446 3.65221 9.66394 3.82248 9.66394 4.00001C9.66394 4.17755 9.73446 4.34781 9.86 4.47335C9.98554 4.59888 10.1558 4.66941 10.3333 4.66941C10.5109 4.66941 10.6811 4.59888 10.8067 4.47335L11.6667 3.60668V7.33335C11.6667 7.51016 11.7369 7.67973 11.8619 7.80475C11.987 7.92977 12.1565 8.00001 12.3333 8.00001C12.5101 8.00001 12.6797 7.92977 12.8047 7.80475C12.9298 7.67973 13 7.51016 13 7.33335V3.60668L13.86 4.47335C13.922 4.53583 13.9957 4.58543 14.0769 4.61927C14.1582 4.65312 14.2453 4.67054 14.3333 4.67054C14.4213 4.67054 14.5085 4.65312 14.5897 4.61927C14.671 4.58543 14.7447 4.53583 14.8067 4.47335C14.8692 4.41137 14.9187 4.33764 14.9526 4.2564C14.9864 4.17516 15.0039 4.08802 15.0039 4.00001C15.0039 3.912 14.9864 3.82487 14.9526 3.74363C14.9187 3.66239 14.8692 3.58865 14.8067 3.52668Z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -5,7 +5,7 @@
flex-direction: column;
height: 100%;
min-height: 600px;
background: var(--color-surface-1);
background: var(--color-base);
align-items: center;
justify-content: center;
overflow-y: auto;
@ -16,17 +16,11 @@
width: 540px;
padding: _.unit(20) _.unit(17.5);
gap: _.unit(6);
background: var(--color-bg-float);
background: var(--color-layer-1);
border-radius: 16px;
box-shadow: var(--shadow-1);
white-space: pre-wrap;
.icon {
width: 40px;
height: 40px;
flex-shrink: 0;
}
.title {
font: var(--font-headline-2);
}

View file

@ -2,11 +2,12 @@ import { OrganizationInvitationStatus, getTenantIdFromOrganizationId } from '@lo
import { useContext, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Icon from '@/assets/icons/organization-preview.svg';
import OrganizationIcon from '@/assets/icons/organization-preview.svg';
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
import { type TenantResponse, type InvitationListResponse } from '@/cloud/types/router';
import CreateTenantModal from '@/components/CreateTenantModal';
import TenantEnvTag from '@/components/TenantEnvTag';
import ThemedIcon from '@/components/ThemedIcon';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button';
import Spacer from '@/ds-components/Spacer';
@ -32,7 +33,7 @@ function InvitationList({ invitations }: Props) {
<div className={styles.description}>{t('invitation.find_tenants_description')}</div>
{invitations.map(({ id, organizationId, tenantName, tenantTag }) => (
<div key={id} className={styles.tenant}>
<Icon className={styles.icon} />
<ThemedIcon for={OrganizationIcon} size={40} />
<span className={styles.name}>{tenantName}</span>
<TenantEnvTag isAbbreviated className={styles.tag} tag={tenantTag} />
<Spacer />

View file

@ -31,9 +31,12 @@
.title {
display: block;
font: var(--font-body-2);
color: var(--color-text-link);
text-decoration: none;
@include _.text-ellipsis;
&.withLink {
color: var(--color-text-link);
}
}
.subtitle {

View file

@ -27,7 +27,7 @@ function ItemPreview({ title, subtitle, icon, to, size = 'default', suffix, toTa
<div className={styles.meta}>
{to && (
<Link
className={styles.title}
className={classNames(styles.title, styles.withLink)}
to={getTo(to)}
target={toTarget}
onClick={(event) => {

View file

@ -19,6 +19,7 @@ $dropdown-item-height: 40px;
position: relative;
border: none;
background-color: transparent;
gap: _.unit(2);
&:hover {
cursor: pointer;
@ -31,12 +32,14 @@ $dropdown-item-height: 40px;
.name {
font: var(--font-title-2);
margin-right: _.unit(1.5);
@include _.text-ellipsis;
}
.tag {
margin-right: _.unit(2);
.redDot {
width: 10px;
height: 10px;
border-radius: 50%;
background-color: var(--color-on-error-container);
}
.arrowIcon {

View file

@ -54,7 +54,8 @@ export default function TenantSelector() {
}}
>
<div className={styles.name}>{currentTenantInfo.name}</div>
<TenantEnvTag className={styles.tag} tag={currentTenantInfo.tag} />
<TenantEnvTag tag={currentTenantInfo.tag} />
{Boolean(pendingInvitations?.length) && <div className={styles.redDot} />}
<KeyboardArrowDown className={styles.arrowIcon} />
</div>
<Dropdown

View file

@ -5,7 +5,7 @@
flex-direction: column;
height: 100%;
min-height: 600px;
background: var(--color-surface-1);
background: var(--color-base);
align-items: center;
justify-content: center;
overflow-y: auto;
@ -17,7 +17,7 @@
width: 540px;
padding: _.unit(35) _.unit(17.5);
gap: _.unit(6);
background: var(--color-bg-float);
background: var(--color-layer-1);
border-radius: 16px;
box-shadow: var(--shadow-1);
text-align: center;

View file

@ -1,6 +1,7 @@
import { useTranslation } from 'react-i18next';
import Logo from '@/assets/images/logo.svg';
import AppLoading from '@/components/AppLoading';
import Button from '@/ds-components/Button';
import useCurrentUser from '@/hooks/use-current-user';
@ -12,9 +13,13 @@ type Props = {
function SwitchAccount({ onClickSwitch }: Props) {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { user } = useCurrentUser();
const { user, isLoading } = useCurrentUser();
const { id, primaryEmail, username } = user ?? {};
if (isLoading) {
return <AppLoading />;
}
return (
<div className={styles.container}>
<div className={styles.wrapper}>

View file

@ -47,10 +47,10 @@ function AcceptInvitation() {
resetTenants(data);
navigateTenant(getTenantIdFromOrganizationId(organizationId));
})();
}, [cloudApi, error, invitation, navigateTenant, t]);
}, [cloudApi, error, invitation, navigateTenant, resetTenants, t]);
// No invitation returned, indicating the current signed-in user is not the invitee.
if (error?.status === 404) {
if (error?.status === 403) {
return (
<SwitchAccount
onClickSwitch={() => {
@ -63,6 +63,10 @@ function AcceptInvitation() {
);
}
if (error?.status === 404) {
return <AppError errorMessage={t('invitation.invitation_not_found')} />;
}
if (invitation && invitation.status !== OrganizationInvitationStatus.Pending) {
return <AppError errorMessage={t('invitation.invalid_invitation_status')} />;
}

View file

@ -1,5 +1,5 @@
import { ReservedPlanId, TenantRole } from '@logto/schemas';
import { useContext, useMemo, useState } from 'react';
import { useContext, useEffect, useMemo, useState } from 'react';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
@ -50,9 +50,16 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
control,
handleSubmit,
setError,
reset,
formState: { errors },
} = formMethods;
useEffect(() => {
return () => {
reset();
};
}, [isOpen, reset]);
const roleOptions: Array<Option<TenantRole>> = useMemo(
() => [
{ value: TenantRole.Admin, title: t('admin') },

View file

@ -26,16 +26,16 @@ function TenantSettings() {
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Settings}`}>
<DynamicT forKey="tenants.tabs.settings" />
</TabNavItem>
{isDevFeaturesEnabled && (
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Members}`}>
<DynamicT forKey="tenants.tabs.members" />
</TabNavItem>
)}
{canManageTenant && (
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Domains}`}>
<DynamicT forKey="tenants.tabs.domains" />
</TabNavItem>
)}
{isDevFeaturesEnabled && (
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Members}`}>
<DynamicT forKey="tenants.tabs.members" />
</TabNavItem>
)}
{!isDevTenant && canManageTenant && (
<>
<TabNavItem href={`/tenant-settings/${TenantSettingsTabs.Subscription}`}>

View file

@ -13,7 +13,7 @@ import {
goToAdminConsole,
waitForToast,
} from '#src/ui-helpers/index.js';
import { expectNavigation, appendPathname, dcls, waitFor } from '#src/utils.js';
import { expectNavigation, appendPathname, dcls, waitFor, cls } from '#src/utils.js';
import {
type ApplicationMetadata,
@ -85,7 +85,7 @@ describe('applications', () => {
*/
await page.reload();
await expect(page).toMatchElement('table div[class$=item] a[class$=title]', {
await expect(page).toMatchElement(`table div[class$=item] a${cls('title')}`, {
text: initialApp.name,
});
});
@ -345,7 +345,7 @@ describe('applications', () => {
});
it('delete the initial application', async () => {
await expect(page).toClick('table tbody tr td div[class$=item] a[class$=title]', {
await expect(page).toClick(`table tbody tr td div[class$=item] a${cls('title')}`, {
text: initialApp.name,
});

View file

@ -14,6 +14,7 @@ import {
generateScopeName,
generateRoleName,
dcls,
cls,
} from '#src/utils.js';
import {
@ -183,7 +184,7 @@ describe('M2M RBAC', () => {
await expect(page).toFill('div[class$=filter] input', roleName);
await expect(page).toClick('button', { text: 'Search' });
await expect(page).toClick('table tbody tr td div[class$=meta]:has(a[class$=title])', {
await expect(page).toClick(`table tbody tr td div[class$=meta]:has(a${cls('title')})`, {
text: roleName,
});
});
@ -272,7 +273,7 @@ describe('M2M RBAC', () => {
});
await expect(page).toMatchElement(
'div[class$=applicationsTable] td div[class$=item] a[class$=title]',
[dcls('applicationsTable'), 'td', dcls('item'), `a${cls('title')}`].join(' '),
{
text: rbacTestAppname,
}
@ -302,7 +303,7 @@ describe('M2M RBAC', () => {
page.goto(appendPathname('/console/applications', logtoConsoleUrl).href)
);
await expect(page).toClick('table tbody tr td a[class$=title]', {
await expect(page).toClick(['table', 'tbody', 'tr', 'td', `a${cls('title')}`].join(' '), {
text: rbacTestAppname,
});
});
@ -341,7 +342,7 @@ describe('M2M RBAC', () => {
}
);
const roleRow = await expect(page).toMatchElement('table tbody tr:has(td a[class$=title])', {
const roleRow = await expect(page).toMatchElement(`table tbody tr:has(td a${cls('title')})`, {
text: roleName,
});

View file

@ -15,6 +15,7 @@ import {
generateResourceIndicator,
generateScopeName,
generateRoleName,
cls,
} from '#src/utils.js';
import { expectToSelectPermissionAction } from './helper.js';
@ -265,7 +266,7 @@ describe('User RBAC', () => {
});
await expect(page).toMatchElement(
'div[class$=usersTable] td div[class$=item] a[class$=title]',
`div[class$=usersTable] td div[class$=item] a${cls('title')}`,
{
text: rbacTestUsername,
}
@ -274,7 +275,7 @@ describe('User RBAC', () => {
it('remove a role form a user on the user details page', async () => {
// Navigate to user details page
await expect(page).toClick('table tbody tr td a[class$=title]', {
await expect(page).toClick(`table tbody tr td a${cls('title')}`, {
text: rbacTestUsername,
});
@ -287,7 +288,7 @@ describe('User RBAC', () => {
text: 'Roles',
});
const roleRow = await expect(page).toMatchElement('table tbody tr:has(td a[class$=title])', {
const roleRow = await expect(page).toMatchElement(`table tbody tr:has(td a${cls('title')})`, {
text: roleName,
});
@ -347,7 +348,7 @@ describe('User RBAC', () => {
}
);
await expect(page).toClick('table tbody tr td a[class$=title]', {
await expect(page).toClick(['table', 'tbody', 'tr', 'td', `a${cls('title')}`].join(' '), {
text: roleName,
});
@ -380,7 +381,7 @@ describe('User RBAC', () => {
}
);
await expect(page).toClick('table tbody tr td a[class$=title]', {
await expect(page).toClick(['table', 'tbody', 'tr', 'td', `a${cls('title')}`].join(' '), {
text: apiResourceName,
});

View file

@ -3,7 +3,7 @@ import { type Page } from 'puppeteer';
import { logtoConsoleUrl as logtoConsoleUrlString } from '#src/constants.js';
import { expectToClickDetailsPageOption, waitForToast } from '#src/ui-helpers/index.js';
import { expectNavigation, appendPathname } from '#src/utils.js';
import { expectNavigation, appendPathname, cls } from '#src/utils.js';
import {
expectToConfirmConnectorDeletion,
@ -129,7 +129,7 @@ export const expectToDeletePasswordlessConnector = async (page: Page, { name }:
page.goto(appendPathname('/console/connectors/passwordless', logtoConsoleUrl).href)
);
await expect(page).toClick('table tbody tr td div[class$=item] a[class$=title] span', {
await expect(page).toClick(`table tbody tr td div[class$=item] a${cls('title')} span`, {
text: name,
});
@ -150,7 +150,7 @@ export const expectToDeleteSocialConnector = async (page: Page, { name }: TestCo
page.goto(appendPathname('/console/connectors/social', logtoConsoleUrl).href)
);
await expect(page).toClick('table tbody tr td div[class$=item] a[class$=title] span', {
await expect(page).toClick(`table tbody tr td div[class$=item] a${cls('title')} span`, {
text: name,
});

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -3,11 +3,12 @@ const invitation = {
find_tenants_description:
'Your email address may already be registered with multiple tenants. You can choose to join the existing ones or continue create a new one.',
create_new_tenant: 'Create a new tenant',
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
switch_account: 'Sign in to another account',
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);

View file

@ -7,7 +7,7 @@ const invitation = {
/** UNTRANSLATED */
create_new_tenant: 'Create a new tenant',
/** UNTRANSLATED */
email_not_match_title: 'You are currently signed in as\n{{email}}.',
email_not_match_title: 'You are currently signed in as\n{{email}}',
/** UNTRANSLATED */
email_not_match_description:
'You do not currently have access to this organization.\nPlease sign in with the correct account to accept the invitation and become a member of the organization.',
@ -15,6 +15,8 @@ const invitation = {
switch_account: 'Sign in to another account',
/** UNTRANSLATED */
invalid_invitation_status: 'Invalid invitation. Please contact the administrator and try again.',
/** UNTRANSLATED */
invitation_not_found: 'Invitation not found. Please contact the administrator.',
};
export default Object.freeze(invitation);