CB-4335 identify providers forms uses useForm

This commit is contained in:
s.teleshev
2023-12-06 17:49:07 +01:00
parent 87961b3252
commit e6a4e64acd
6 changed files with 168 additions and 160 deletions
@@ -79,7 +79,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
if (controlType === 'file' && state) {
return (
<InputFileTextContent
required={property.required}
required={!property.required}
tooltip={property.description}
labelTooltip={property.displayName || property.description}
name={property.id!}
@@ -119,7 +119,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
if (state !== undefined) {
return (
<FieldCheckbox
required={property.required}
required={!property.required}
id={property.id}
name={property.id!}
state={state}
@@ -151,7 +151,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
if (state !== undefined) {
return (
<Combobox
required={property.required}
required={!property.required}
name={property.id!}
state={state}
items={property.validValues!}
@@ -171,7 +171,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
return (
<Combobox
required={property.required}
required={!property.required}
name={property.id!}
items={property.validValues!}
keySelector={value => value}
@@ -192,7 +192,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
if (state !== undefined) {
return (
<Textarea
required={property.required}
required={!property.required}
title={state[property.id!]}
labelTooltip={property.description || property.displayName}
description={description}
@@ -209,7 +209,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
return (
<Textarea
required={property.required}
required={!property.required}
title={value}
labelTooltip={property.description || property.displayName}
description={description}
@@ -227,7 +227,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
if (state !== undefined) {
return (
<InputField
required={property.required}
required={!property.required}
type={password ? 'password' : 'text'}
title={password ? property.description || property.displayName : state[property.id!]}
labelTooltip={property.description || property.displayName}
@@ -250,7 +250,7 @@ export const RenderField = observer<RenderFieldProps>(function RenderField({
return (
<InputField
required={property.required}
required={!property.required}
type={password ? 'password' : 'text'}
title={password ? property.description || property.displayName : value}
labelTooltip={property.description || property.displayName}
@@ -9,14 +9,14 @@ import { observer } from 'mobx-react-lite';
import { useEffect } from 'react';
import styled, { css } from 'reshadow';
import { IconOrImage, Loader, Placeholder, useExecutor, useObjectRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { Form, IconOrImage, Loader, Placeholder, useExecutor, useForm, useObjectRef, useStyles, useTranslate } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import type { AdminAuthProviderConfiguration } from '@cloudbeaver/core-sdk';
import { BASE_TAB_STYLES, TabList, TabPanelList, TabsState, UNDERLINE_TAB_BIG_STYLES, UNDERLINE_TAB_STYLES } from '@cloudbeaver/core-ui';
import { AuthConfigurationFormService } from './AuthConfigurationFormService';
import { authConfigurationContext } from './Contexts/authConfigurationContext';
import type { IAuthConfigurationFormState } from './IAuthConfigurationFormProps';
import type { IAuthConfigurationFormActions, IAuthConfigurationFormState } from './IAuthConfigurationFormProps';
const tabsStyles = css`
TabList {
@@ -100,6 +100,12 @@ export const AuthConfigurationForm = observer<Props>(function AuthConfigurationF
const style = useStyles(BASE_TAB_STYLES, tabsStyles, UNDERLINE_TAB_STYLES, UNDERLINE_TAB_BIG_STYLES);
const styles = useStyles(style, topBarStyles, formStyles);
const service = useService(AuthConfigurationFormService);
const form = useForm({
onSubmit: async () => {
await state.save();
},
});
const actions = useObjectRef<IAuthConfigurationFormActions>({ save: form.submit });
useExecutor({
executor: state.submittingTask,
@@ -121,30 +127,33 @@ export const AuthConfigurationForm = observer<Props>(function AuthConfigurationF
}, []);
return styled(styles)(
<TabsState container={service.tabsContainer} state={state} onCancel={onCancel}>
<box className={className}>
<configuration-top-bar>
<configuration-top-bar-tabs>
<configuration-status-message>
{state.statusMessage && (
<>
<IconOrImage icon="/icons/info_icon.svg" />
{translate(state.statusMessage)}
</>
)}
</configuration-status-message>
<TabList style={style} disabled={false} />
</configuration-top-bar-tabs>
<configuration-top-bar-actions>
<Loader suspense inline hideMessage hideException>
<Placeholder container={service.actionsContainer} state={state} onCancel={onCancel} />
</Loader>
</configuration-top-bar-actions>
</configuration-top-bar>
<content-box>
<TabPanelList style={style} />
</content-box>
</box>
</TabsState>,
<Form context={form}>
<TabsState actions={actions} container={service.tabsContainer} state={state} onCancel={onCancel}>
<box className={className}>
<configuration-top-bar>
<configuration-top-bar-tabs>
<configuration-status-message>
{state.statusMessage && (
<>
<IconOrImage icon="/icons/info_icon.svg" />
{translate(state.statusMessage)}
</>
)}
</configuration-status-message>
<TabList style={style} disabled={false} />
</configuration-top-bar-tabs>
<configuration-top-bar-actions>
<Loader suspense inline hideMessage hideException>
<Placeholder actions={actions} container={service.actionsContainer} state={state} onCancel={onCancel} />
</Loader>
</configuration-top-bar-actions>
</configuration-top-bar>
<content-box>
<TabPanelList style={style} />
</content-box>
</box>
</TabsState>
</Form>
,
);
});
@@ -12,7 +12,7 @@ import { Button, PlaceholderComponent, useTranslate } from '@cloudbeaver/core-bl
import type { IAuthConfigurationFormProps } from './IAuthConfigurationFormProps';
export const AuthConfigurationFormBaseActions: PlaceholderComponent<IAuthConfigurationFormProps> = observer(
function AuthConfigurationFormBaseActions({ state, onCancel }) {
function AuthConfigurationFormBaseActions({ state, onCancel, actions }) {
const translate = useTranslate();
return (
@@ -22,7 +22,7 @@ export const AuthConfigurationFormBaseActions: PlaceholderComponent<IAuthConfigu
{translate('ui_processing_cancel')}
</Button>
)}
<Button type="button" disabled={state.disabled || state.readonly} mod={['unelevated']} loader onClick={state.save}>
<Button type="button" disabled={state.disabled || state.readonly} mod={['unelevated']} loader onClick={actions.save}>
{translate(state.mode === 'edit' ? 'ui_processing_save' : 'ui_processing_create')}
</Button>
</>
@@ -30,8 +30,13 @@ export interface IAuthConfigurationFormState {
readonly setOptions: (mode: AuthConfigurationFormMode) => this;
}
export interface IAuthConfigurationFormActions {
save: () => void;
}
export interface IAuthConfigurationFormProps {
state: IAuthConfigurationFormState;
actions: IAuthConfigurationFormActions;
onCancel?: () => void;
}
@@ -14,7 +14,6 @@ import {
ColoredContainer,
Combobox,
FieldCheckbox,
Form,
Group,
GroupTitle,
InputField,
@@ -45,8 +44,6 @@ const emptyArray: AuthProviderConfigurationParametersFragment[] = [];
export const AuthConfigurationOptions: TabContainerPanelComponent<IAuthConfigurationFormProps> = observer(function AuthConfigurationOptions({
state,
}) {
const formRef = useRef<HTMLFormElement>(null);
const translate = useTranslate();
const copy = useClipboard();
const style = useStyles(styles);
@@ -63,133 +60,131 @@ export const AuthConfigurationOptions: TabContainerPanelComponent<IAuthConfigura
}, [state]);
return styled(style)(
<Form ref={formRef}>
<ColoredContainer parent gap overflow>
<ColoredContainer parent gap overflow>
<Group small gap>
<Combobox
name="providerId"
state={state.config}
items={providers.resource.configurable}
keySelector={provider => provider.id}
valueSelector={provider => provider.label}
iconSelector={provider => provider.icon}
titleSelector={provider => provider.description}
placeholder={translate('administration_identity_providers_choose_provider_placeholder')}
readOnly={state.readonly || edit}
disabled={state.disabled}
required
tiny
fill
onSelect={handleProviderSelect}
>
{translate('administration_identity_providers_provider')}
</Combobox>
<InputField name="id" state={state.config} readOnly={state.readonly || edit} disabled={state.disabled} required tiny fill>
{translate('administration_identity_providers_provider_id')}
</InputField>
<InputField name="displayName" state={state.config} minLength={1} disabled={state.disabled} readOnly={state.readonly} required tiny fill>
{translate('administration_identity_providers_provider_configuration_name')}
</InputField>
<Textarea name="description" state={state.config} disabled={state.disabled} readOnly={state.readonly}>
{translate('administration_identity_providers_provider_configuration_description')}
</Textarea>
<InputField name="iconURL" state={state.config} disabled={state.disabled} readOnly={state.readonly}>
{translate('administration_identity_providers_provider_configuration_icon_url')}
</InputField>
<FieldCheckbox
id={edit ? state.config.id : 'AuthConfigurationDisabled'}
name="disabled"
state={state.config}
disabled={state.disabled}
readOnly={state.readonly}
>
{translate('administration_identity_providers_provider_configuration_disabled')}
</FieldCheckbox>
</Group>
{parameters.isLoaded() && parameters.data && (
<>
{isUncategorizedExists && (
<Group small gap vertical>
<GroupTitle>{translate('administration_identity_providers_provider_configuration_parameters')}</GroupTitle>
<ObjectPropertyInfoForm
state={state.config.parameters}
properties={parameters.data}
category={null}
disabled={state.disabled}
readOnly={state.readonly}
/>
</Group>
)}
{categories.map(category => (
<Group key={category} small gap vertical>
<GroupTitle keepSize>{category}</GroupTitle>
<ObjectPropertyInfoForm
state={state.config.parameters}
properties={parameters.data!}
category={category}
disabled={state.disabled}
readOnly={state.readonly}
keepSize
/>
</Group>
))}
</>
)}
{(state.config.metadataLink || state.config.signInLink || state.config.signOutLink || state.config.acsLink) && (
<Group small gap>
<Combobox
name="providerId"
<GroupTitle>{translate('administration_identity_providers_provider_configuration_links')}</GroupTitle>
<InputField
name="signInLink"
state={state.config}
items={providers.resource.configurable}
keySelector={provider => provider.id}
valueSelector={provider => provider.label}
iconSelector={provider => provider.icon}
titleSelector={provider => provider.description}
placeholder={translate('administration_identity_providers_choose_provider_placeholder')}
readOnly={state.readonly || edit}
title={state.config.signInLink}
disabled={state.disabled}
required
tiny
fill
onSelect={handleProviderSelect}
autoHide
readOnly
onCustomCopy={() => copy(state.config.signInLink!, true)}
>
{translate('administration_identity_providers_provider')}
</Combobox>
<InputField name="id" state={state.config} readOnly={state.readonly || edit} disabled={state.disabled} required tiny fill>
{translate('administration_identity_providers_provider_id')}
Sign in
</InputField>
<InputField name="displayName" state={state.config} minLength={1} disabled={state.disabled} readOnly={state.readonly} required tiny fill>
{translate('administration_identity_providers_provider_configuration_name')}
</InputField>
<Textarea name="description" state={state.config} disabled={state.disabled} readOnly={state.readonly}>
{translate('administration_identity_providers_provider_configuration_description')}
</Textarea>
<InputField name="iconURL" state={state.config} disabled={state.disabled} readOnly={state.readonly}>
{translate('administration_identity_providers_provider_configuration_icon_url')}
</InputField>
<FieldCheckbox
id={edit ? state.config.id : 'AuthConfigurationDisabled'}
name="disabled"
<InputField
name="signOutLink"
state={state.config}
title={state.config.signOutLink}
disabled={state.disabled}
readOnly={state.readonly}
autoHide
readOnly
onCustomCopy={() => copy(state.config.signOutLink!, true)}
>
{translate('administration_identity_providers_provider_configuration_disabled')}
</FieldCheckbox>
Sign out
</InputField>
<InputField
name="redirectLink"
state={state.config}
title={state.config.redirectLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.redirectLink!, true)}
>
Redirect
</InputField>
<InputField
name="acsLink"
state={state.config}
title={state.config.acsLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.acsLink!, true)}
>
ACS
</InputField>
{state.config.metadataLink && (
<Link href={state.config.metadataLink} target="_blank" rel="noopener noreferrer">
{translate('administration_identity_providers_provider_configuration_links_metadata')}
</Link>
)}
</Group>
{parameters.isLoaded() && parameters.data && (
<>
{isUncategorizedExists && (
<Group small gap vertical>
<GroupTitle>{translate('administration_identity_providers_provider_configuration_parameters')}</GroupTitle>
<ObjectPropertyInfoForm
state={state.config.parameters}
properties={parameters.data}
category={null}
disabled={state.disabled}
readOnly={state.readonly}
/>
</Group>
)}
{categories.map(category => (
<Group key={category} small gap vertical>
<GroupTitle keepSize>{category}</GroupTitle>
<ObjectPropertyInfoForm
state={state.config.parameters}
properties={parameters.data!}
category={category}
disabled={state.disabled}
readOnly={state.readonly}
keepSize
/>
</Group>
))}
</>
)}
{(state.config.metadataLink || state.config.signInLink || state.config.signOutLink || state.config.acsLink) && (
<Group small gap>
<GroupTitle>{translate('administration_identity_providers_provider_configuration_links')}</GroupTitle>
<InputField
name="signInLink"
state={state.config}
title={state.config.signInLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.signInLink!, true)}
>
Sign in
</InputField>
<InputField
name="signOutLink"
state={state.config}
title={state.config.signOutLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.signOutLink!, true)}
>
Sign out
</InputField>
<InputField
name="redirectLink"
state={state.config}
title={state.config.redirectLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.redirectLink!, true)}
>
Redirect
</InputField>
<InputField
name="acsLink"
state={state.config}
title={state.config.acsLink}
disabled={state.disabled}
autoHide
readOnly
onCustomCopy={() => copy(state.config.acsLink!, true)}
>
ACS
</InputField>
{state.config.metadataLink && (
<Link href={state.config.metadataLink} target="_blank" rel="noopener noreferrer">
{translate('administration_identity_providers_provider_configuration_links_metadata')}
</Link>
)}
</Group>
)}
</ColoredContainer>
</Form>,
)}
</ColoredContainer>
);
});
@@ -110,7 +110,6 @@ export const ConnectionForm = observer<ConnectionFormProps>(function ConnectionF
const form = useForm({
onSubmit: event => {
if (event?.type === 'test') {
console.info('test');
state.test();
} else {
state.save();