mirror of
https://github.com/logto-io/logto.git
synced 2025-03-24 22:41:28 -05:00
Merge pull request #4845 from logto-io/yemq-log-7186-sso-connector-creation-modal
feat(console,phrases): add SSO connector creation modal
This commit is contained in:
commit
ee62015f42
24 changed files with 515 additions and 3 deletions
|
@ -5,10 +5,14 @@ import * as radioGroupStyles from '../ConnectorRadioGroup/index.module.scss';
|
|||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
function Skeleton() {
|
||||
type Props = {
|
||||
numberOfLoadingConnectors?: number;
|
||||
};
|
||||
|
||||
function Skeleton({ numberOfLoadingConnectors = 8 }: Props) {
|
||||
return (
|
||||
<div className={radioGroupStyles.connectorGroup}>
|
||||
{Array.from({ length: 8 }).map((_, index) => (
|
||||
{Array.from({ length: numberOfLoadingConnectors }).map((_, index) => (
|
||||
// eslint-disable-next-line react/no-array-index-key
|
||||
<div key={index} className={classNames(radioStyles.connector, styles.connector)}>
|
||||
<div className={styles.logo} />
|
||||
|
|
|
@ -116,7 +116,10 @@ function ConsoleContent() {
|
|||
<Route path=":tab/:connectorId" element={<ConnectorDetails />} />
|
||||
</Route>
|
||||
{isDevFeaturesEnabled && (
|
||||
<Route path="enterprise-sso" element={<EnterpriseSsoConnectors />} />
|
||||
<Route path="enterprise-sso">
|
||||
<Route index element={<EnterpriseSsoConnectors />} />
|
||||
<Route path="create" element={<EnterpriseSsoConnectors />} />
|
||||
</Route>
|
||||
)}
|
||||
<Route path="webhooks">
|
||||
<Route index element={<Webhooks />} />
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.ssoConnector {
|
||||
font: var(--font-body-2);
|
||||
display: flex;
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
margin-left: _.unit(3);
|
||||
|
||||
.name {
|
||||
font: var(--font-label-2);
|
||||
@include _.multi-line-ellipsis(1);
|
||||
padding-right: _.unit(3);
|
||||
}
|
||||
|
||||
.description {
|
||||
font: var(--font-body-3);
|
||||
color: var(--color-text-secondary);
|
||||
margin-top: _.unit(1);
|
||||
@include _.multi-line-ellipsis(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--color-hover);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
|
||||
> img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
flex-shrink: 0;
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { type SsoConnectorFactoryDetail } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import ImageWithErrorFallback from '@/ds-components/ImageWithErrorFallback';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
data: SsoConnectorFactoryDetail;
|
||||
};
|
||||
|
||||
function SsoConnectorRadio({ data: { providerName, logo, description } }: Props) {
|
||||
return (
|
||||
<div className={styles.ssoConnector}>
|
||||
<ImageWithErrorFallback
|
||||
containerClassName={styles.container}
|
||||
className={styles.logo}
|
||||
alt="logo"
|
||||
src={logo}
|
||||
/>
|
||||
<div className={styles.content}>
|
||||
<div className={classNames(styles.name)}>
|
||||
<span>{providerName}</span>
|
||||
</div>
|
||||
<div className={styles.description}>
|
||||
<span>{description}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SsoConnectorRadio;
|
|
@ -0,0 +1,40 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
@use '@/scss/dimensions' as dim;
|
||||
|
||||
.ssoConnectorGroup {
|
||||
gap: _.unit(4);
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-large) {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
|
||||
&.medium {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-medium) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
@media screen and (max-width: dim.$modal-layout-grid-small) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
import { type SsoConnectorFactoryDetail } from '@logto/schemas';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { type ConnectorRadioGroupSize } from '@/components/CreateConnectorForm/ConnectorRadioGroup';
|
||||
import RadioGroup, { Radio } from '@/ds-components/RadioGroup';
|
||||
|
||||
import SsoConnectorRadio from './SsoConnectorRadio';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
name: string;
|
||||
value?: string;
|
||||
className?: string;
|
||||
size: ConnectorRadioGroupSize;
|
||||
connectors: SsoConnectorFactoryDetail[];
|
||||
onChange: (providerName: string) => void;
|
||||
};
|
||||
|
||||
function SsoConnectorRadioGroup({ name, value, className, size, connectors, onChange }: Props) {
|
||||
return (
|
||||
<RadioGroup
|
||||
name={name}
|
||||
value={value}
|
||||
type="card"
|
||||
className={classNames(className, styles.ssoConnectorGroup, styles[size])}
|
||||
onChange={onChange}
|
||||
>
|
||||
{connectors.map((data) => (
|
||||
<Radio key={data.providerName} value={data.providerName}>
|
||||
<SsoConnectorRadio data={data} />
|
||||
</Radio>
|
||||
))}
|
||||
</RadioGroup>
|
||||
);
|
||||
}
|
||||
|
||||
export default SsoConnectorRadioGroup;
|
|
@ -0,0 +1,7 @@
|
|||
@use '@/scss/underscore' as _;
|
||||
|
||||
.textDivider {
|
||||
font: var(--font-body-2);
|
||||
color: var(--color-text-secondary);
|
||||
margin: _.unit(6) 0 _.unit(4);
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
import { type SsoConnectorFactoriesResponse, type SsoConnector } from '@logto/schemas';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import Modal from 'react-modal';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import Skeleton from '@/components/CreateConnectorForm/Skeleton';
|
||||
import { getConnectorRadioGroupSize } from '@/components/CreateConnectorForm/utils';
|
||||
import Button from '@/ds-components/Button';
|
||||
import DynamicT from '@/ds-components/DynamicT';
|
||||
import FormField from '@/ds-components/FormField';
|
||||
import ModalLayout from '@/ds-components/ModalLayout';
|
||||
import TextInput from '@/ds-components/TextInput';
|
||||
import { type RequestError } from '@/hooks/use-api';
|
||||
import useApi from '@/hooks/use-api';
|
||||
import * as modalStyles from '@/scss/modal.module.scss';
|
||||
import { trySubmitSafe } from '@/utils/form';
|
||||
|
||||
import SsoConnectorRadioGroup from './SsoConnectorRadioGroup';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
onClose: (ssoConnectorId?: string) => void;
|
||||
};
|
||||
|
||||
type FormType = {
|
||||
connectorName: string;
|
||||
};
|
||||
|
||||
function SsoCreationModal({ isOpen, onClose: rawOnClose }: Props) {
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const [selectedProviderName, setSelectedProviderName] = useState<string>();
|
||||
const { data, error } = useSWR<SsoConnectorFactoriesResponse, RequestError>(
|
||||
'api/sso-connector-factories'
|
||||
);
|
||||
const {
|
||||
reset,
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting, errors },
|
||||
} = useForm<FormType>();
|
||||
const api = useApi();
|
||||
|
||||
const isLoading = !data && !error;
|
||||
|
||||
const { standardConnectors = [], providerConnectors = [] } = data ?? {};
|
||||
|
||||
const radioGroupSize = useMemo(
|
||||
() => getConnectorRadioGroupSize(standardConnectors.length + providerConnectors.length),
|
||||
[standardConnectors, providerConnectors]
|
||||
);
|
||||
|
||||
const isCreateButtonDisabled = useMemo(
|
||||
() =>
|
||||
![...standardConnectors, ...providerConnectors].some(
|
||||
({ providerName }) => selectedProviderName === providerName
|
||||
),
|
||||
[selectedProviderName, standardConnectors, providerConnectors]
|
||||
);
|
||||
|
||||
// `rawOnClose` does not clean the state of the modal.
|
||||
const onClose = (ssoConnectorId?: string) => {
|
||||
setSelectedProviderName(undefined);
|
||||
reset();
|
||||
rawOnClose(ssoConnectorId);
|
||||
};
|
||||
|
||||
const handleSsoSelection = (providerName: string) => {
|
||||
setSelectedProviderName(providerName);
|
||||
};
|
||||
|
||||
const onSubmit = handleSubmit(
|
||||
trySubmitSafe(async (formData) => {
|
||||
if (isSubmitting) {
|
||||
return;
|
||||
}
|
||||
|
||||
const createdSsoConnector = await api
|
||||
.post(`api/sso-connectors`, { json: { ...formData, providerName: selectedProviderName } })
|
||||
.json<SsoConnector>();
|
||||
|
||||
onClose(createdSsoConnector.id);
|
||||
})
|
||||
);
|
||||
|
||||
if (!isOpen) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
shouldCloseOnEsc
|
||||
isOpen={isOpen}
|
||||
className={modalStyles.content}
|
||||
overlayClassName={modalStyles.overlay}
|
||||
onRequestClose={() => {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
<ModalLayout
|
||||
title="enterprise_sso.create_modal.title"
|
||||
footer={
|
||||
<Button
|
||||
title="enterprise_sso.create_modal.create_button_text"
|
||||
type="primary"
|
||||
disabled={isCreateButtonDisabled}
|
||||
onClick={onSubmit}
|
||||
/>
|
||||
}
|
||||
size={radioGroupSize}
|
||||
onClose={onClose}
|
||||
>
|
||||
{isLoading && <Skeleton numberOfLoadingConnectors={2} />}
|
||||
{error?.message}
|
||||
{providerConnectors.length > 0 && (
|
||||
<>
|
||||
<SsoConnectorRadioGroup
|
||||
name="providerConnectors"
|
||||
value={selectedProviderName}
|
||||
connectors={providerConnectors}
|
||||
size={radioGroupSize}
|
||||
onChange={handleSsoSelection}
|
||||
/>
|
||||
<div className={styles.textDivider}>
|
||||
<DynamicT forKey="enterprise_sso.create_modal.text_divider" />
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<SsoConnectorRadioGroup
|
||||
name="standardConnectors"
|
||||
value={selectedProviderName}
|
||||
connectors={standardConnectors}
|
||||
size={radioGroupSize}
|
||||
onChange={handleSsoSelection}
|
||||
/>
|
||||
<FormField isRequired title="enterprise_sso.create_modal.connector_name_field_title">
|
||||
<TextInput
|
||||
{...register('connectorName', { required: true })}
|
||||
placeholder={t('enterprise_sso.create_modal.connector_name_field_placeholder')}
|
||||
error={Boolean(errors.connectorName)}
|
||||
/>
|
||||
</FormField>
|
||||
</ModalLayout>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default SsoCreationModal;
|
|
@ -2,6 +2,7 @@ import { withAppInsights } from '@logto/app-insights/react';
|
|||
import { type SsoConnectorWithProviderConfig, Theme } from '@logto/schemas';
|
||||
import { conditional } from '@silverhand/essentials';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import useSWR from 'swr';
|
||||
|
||||
import Plus from '@/assets/icons/plus.svg';
|
||||
|
@ -20,16 +21,19 @@ import useTenantPathname from '@/hooks/use-tenant-pathname';
|
|||
import useTheme from '@/hooks/use-theme';
|
||||
import { buildUrl } from '@/utils/url';
|
||||
|
||||
import SsoCreationModal from './SsoCreationModal';
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
const pageSize = defaultPageSize;
|
||||
const enterpriseSsoPathname = '/enterprise-sso';
|
||||
const createEnterpriseSsoPathname = `${enterpriseSsoPathname}/create`;
|
||||
const buildGuidePathname = (id: string) => `${enterpriseSsoPathname}/${id}/guide`;
|
||||
const buildDetailsPathname = (id: string) => `${enterpriseSsoPathname}/${id}`;
|
||||
|
||||
function EnterpriseSsoConnectors() {
|
||||
const theme = useTheme();
|
||||
|
||||
const { pathname } = useLocation();
|
||||
const { navigate } = useTenantPathname();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const [{ page }, updateSearchParameters] = useSearchParametersWatcher({
|
||||
|
@ -163,6 +167,19 @@ function EnterpriseSsoConnectors() {
|
|||
),
|
||||
onRetry: async () => mutate(undefined, true),
|
||||
}}
|
||||
widgets={
|
||||
<SsoCreationModal
|
||||
isOpen={pathname.endsWith(createEnterpriseSsoPathname)}
|
||||
onClose={async (id) => {
|
||||
if (id) {
|
||||
navigate(buildGuidePathname(id), { replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
navigate(enterpriseSsoPathname);
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -12,6 +12,13 @@ const enterprise_sso = {
|
|||
placeholder_title: 'Enterprise connector',
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
title: 'Add enterprise connector',
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
connector_name_field_title: 'Connector name',
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
|
@ -24,6 +24,18 @@ const enterprise_sso = {
|
|||
/** UNTRANSLATED */
|
||||
placeholder_description:
|
||||
'Logto has provided many built-in enterprise identity providers to connect, meantime you can create your own with standard protocols.',
|
||||
create_modal: {
|
||||
/** UNTRANSLATED */
|
||||
title: 'Add enterprise connector',
|
||||
/** UNTRANSLATED */
|
||||
text_divider: 'Or you can customize your connector by a standard protocol.',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_title: 'Connector name',
|
||||
/** UNTRANSLATED */
|
||||
connector_name_field_placeholder: 'Name for the enterprise identity provider',
|
||||
/** UNTRANSLATED */
|
||||
create_button_text: 'Create connector',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(enterprise_sso);
|
||||
|
|
Loading…
Add table
Reference in a new issue