[Enterprise Search] Add License popover to the DLS switches (#159734)

## Summary

- Add license checks for DLS enable widget.
- Add license checks for Access Control Sync widget.



e7ca5c18-e2f6-4684-9a90-964774ccb100




### Checklist

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
This commit is contained in:
Efe Gürkan YALAMAN 2023-06-15 16:02:31 +02:00 committed by GitHub
parent 4573874fab
commit 1da01d14be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 146 additions and 26 deletions

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React from 'react';
import React, { useState } from 'react';
import { useActions, useValues } from 'kea';
@ -21,13 +21,19 @@ import {
EuiIcon,
EuiFlexGroup,
EuiFlexItem,
EuiButtonIcon,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { Status } from '../../../../../../common/types/api';
import { DisplayType } from '../../../../../../common/types/connectors';
import { LicensingLogic } from '../../../../shared/licensing';
import { ConnectorConfigurationApiLogic } from '../../../api/connector/update_connector_configuration_api_logic';
import { PlatinumLicensePopover } from '../../shared/platinum_license_popover/platinum_license_popover';
import {
ConnectorConfigurationLogic,
ConfigEntryView,
@ -64,6 +70,8 @@ export const ConnectorConfigurationFieldType: React.FC<ConnectorConfigurationFie
}) => {
const { status } = useValues(ConnectorConfigurationApiLogic);
const { setLocalConfigEntry } = useActions(ConnectorConfigurationLogic);
const { hasPlatinumLicense } = useValues(LicensingLogic);
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const {
key,
@ -145,10 +153,45 @@ export const ConnectorConfigurationFieldType: React.FC<ConnectorConfigurationFie
);
case DisplayType.TOGGLE:
const toggleSwitch = (
const toggleSwitch = !hasPlatinumLicense ? (
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiFlexItem grow={false}>
<EuiSwitch
checked={ensureBooleanType(value)}
disabled={status === Status.LOADING || !hasPlatinumLicense}
label={
<EuiToolTip content={tooltip}>
<p>{label}</p>
</EuiToolTip>
}
onChange={(event) => {
setLocalConfigEntry({ ...configEntry, value: event.target.checked });
}}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<PlatinumLicensePopover
button={
<EuiButtonIcon
aria-label={i18n.translate(
'xpack.enterpriseSearch.content.newIndex.selectConnector.openPopoverLabel',
{
defaultMessage: 'Open licensing popover',
}
)}
iconType="questionInCircle"
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
/>
}
closePopover={() => setIsPopoverOpen(false)}
isPopoverOpen={isPopoverOpen}
/>
</EuiFlexItem>
</EuiFlexGroup>
) : (
<EuiSwitch
checked={ensureBooleanType(value)}
disabled={status === Status.LOADING}
disabled={status === Status.LOADING || !hasPlatinumLicense}
label={
<EuiToolTip content={tooltip}>
<p>{label}</p>

View file

@ -27,6 +27,7 @@ import { ConnectorStatus, SyncJobType } from '../../../../../../common/types/con
import { generateEncodedPath } from '../../../../shared/encode_path_params';
import { KibanaLogic } from '../../../../shared/kibana';
import { LicensingLogic } from '../../../../shared/licensing';
import { EuiButtonTo } from '../../../../shared/react_router_helpers';
import { UnsavedChangesPrompt } from '../../../../shared/unsaved_changes_prompt';
import { SEARCH_INDEX_TAB_PATH } from '../../../routes';
@ -70,6 +71,7 @@ export const ConnectorSchedulingComponent: React.FC = () => {
useValues(IndexViewLogic);
const { index } = useValues(IndexViewLogic);
const { hasChanges } = useValues(ConnectorSchedulingLogic);
const { hasPlatinumLicense } = useValues(LicensingLogic);
const shouldShowIncrementalSync =
hasIncrementalSyncFeature && productFeatures.hasIncrementalSyncEnabled;
@ -211,7 +213,11 @@ export const ConnectorSchedulingComponent: React.FC = () => {
}
)}
>
<ConnectorContentScheduling type={SyncJobType.ACCESS_CONTROL} index={index} />
<ConnectorContentScheduling
type={SyncJobType.ACCESS_CONTROL}
index={index}
hasPlatinumLicense={hasPlatinumLicense}
/>
</SchedulePanel>
</EuiFlexItem>
)}

View file

@ -21,6 +21,7 @@ import { UpdateConnectorSchedulingApiLogic } from '../../../../api/connector/upd
import { ConnectorSchedulingLogic } from '../connector_scheduling_logic';
interface ConnectorCronEditorProps {
disabled?: boolean;
onReset?(): void;
onSave?(interval: ConnectorScheduling['interval']): void;
scheduling: ConnectorScheduling;
@ -28,6 +29,7 @@ interface ConnectorCronEditorProps {
}
export const ConnectorCronEditor: React.FC<ConnectorCronEditorProps> = ({
disabled = false,
scheduling,
onSave,
onReset,
@ -58,7 +60,7 @@ export const ConnectorCronEditor: React.FC<ConnectorCronEditorProps> = ({
<EuiFlexItem>
<CronEditor
data-telemetry-id="entSearchContent-connector-scheduling-editSchedule"
disabled={!scheduling.enabled}
disabled={!scheduling.enabled || disabled}
fieldToPreferredValueMap={fieldToPreferredValueMap}
cronExpression={simpleCron.expression}
frequency={simpleCron.frequency}
@ -83,7 +85,7 @@ export const ConnectorCronEditor: React.FC<ConnectorCronEditorProps> = ({
<EuiFlexItem grow={false}>
<EuiButtonEmpty
data-telemetry-id="entSearchContent-connector-scheduling-resetSchedule"
disabled={!hasChanges || status === Status.LOADING}
disabled={!hasChanges || status === Status.LOADING || disabled}
onClick={() => {
setNewInterval(scheduling.interval);
setSimpleCron({
@ -105,7 +107,7 @@ export const ConnectorCronEditor: React.FC<ConnectorCronEditorProps> = ({
<EuiFlexItem grow={false}>
<EuiButton
data-telemetry-id="entSearchContent-connector-scheduling-saveSchedule"
disabled={!hasChanges || status === Status.LOADING}
disabled={!hasChanges || status === Status.LOADING || disabled}
onClick={() => onSave && onSave(newInterval)}
>
{i18n.translate(

View file

@ -17,6 +17,8 @@ import {
EuiPanel,
EuiAccordion,
EuiTitle,
EuiButtonIcon,
EuiSwitchProps,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -25,11 +27,13 @@ import { SyncJobType } from '../../../../../../../common/types/connectors';
import { ConnectorViewIndex, CrawlerViewIndex } from '../../../../types';
import { PlatinumLicensePopover } from '../../../shared/platinum_license_popover/platinum_license_popover';
import { ConnectorSchedulingLogic } from '../connector_scheduling_logic';
import { ConnectorCronEditor } from './connector_cron_editor';
export interface ConnectorContentSchedulingProps {
hasPlatinumLicense?: boolean;
index: CrawlerViewIndex | ConnectorViewIndex;
type: SyncJobType;
}
@ -81,9 +85,26 @@ const getDescriptionText = (type: ConnectorContentSchedulingProps['type']) => {
}
};
const EnableSwitch: React.FC<{
checked: boolean;
disabled: boolean;
onChange: EuiSwitchProps['onChange'];
}> = ({ disabled, checked, onChange }) => (
<EuiSwitch
disabled={disabled}
checked={checked}
label={i18n.translate(
'xpack.enterpriseSearch.content.indices.connectorScheduling.switch.label',
{ defaultMessage: 'Enabled' }
)}
onChange={onChange}
/>
);
export const ConnectorContentScheduling: React.FC<ConnectorContentSchedulingProps> = ({
type,
index,
hasPlatinumLicense = false,
}) => {
const { setHasChanges, updateScheduling } = useActions(ConnectorSchedulingLogic);
const schedulingInput = index.connector.scheduling;
@ -91,6 +112,9 @@ export const ConnectorContentScheduling: React.FC<ConnectorContentSchedulingProp
const [isAccordionOpen, setIsAccordionOpen] = useState<'open' | 'closed'>(
scheduling[type].enabled ? 'open' : 'closed'
);
const [isPlatinumPopoverOpen, setIsPlatinumPopoverOpen] = useState(false);
const isGated = !hasPlatinumLicense && type === SyncJobType.ACCESS_CONTROL;
return (
<>
@ -117,30 +141,75 @@ export const ConnectorContentScheduling: React.FC<ConnectorContentSchedulingProp
setIsAccordionOpen(isOpen ? 'open' : 'closed');
}}
extraAction={
<EuiSwitch
checked={scheduling[type].enabled}
label={i18n.translate(
'xpack.enterpriseSearch.content.indices.connectorScheduling.switch.label',
{ defaultMessage: 'Enabled' }
)}
onChange={(e) => {
if (e.target.checked) {
setIsAccordionOpen('open');
}
setScheduling({
...scheduling,
...{
[type]: { enabled: e.target.checked, interval: scheduling[type].interval },
},
});
setHasChanges(type);
}}
/>
isGated ? (
<EuiFlexGroup responsive={false} gutterSize="s">
<EuiFlexItem>
<PlatinumLicensePopover
isPopoverOpen={isPlatinumPopoverOpen}
closePopover={() => setIsPlatinumPopoverOpen(!isPlatinumPopoverOpen)}
button={
<EuiButtonIcon
aria-label={i18n.translate(
'xpack.enterpriseSearch.content.newIndex.selectConnector.openPopoverLabel',
{
defaultMessage: 'Open licensing popover',
}
)}
iconType="questionInCircle"
onClick={() => setIsPlatinumPopoverOpen(!isPlatinumPopoverOpen)}
/>
}
/>
</EuiFlexItem>
<EuiFlexItem>
<EnableSwitch
disabled={isGated}
checked={scheduling[type].enabled}
onChange={(e) => {
if (e.target.checked) {
setIsAccordionOpen('open');
}
setScheduling({
...scheduling,
...{
[type]: {
enabled: e.target.checked,
interval: scheduling[type].interval,
},
},
});
setHasChanges(type);
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
) : (
<EnableSwitch
disabled={isGated}
checked={scheduling[type].enabled}
onChange={(e) => {
if (e.target.checked) {
setIsAccordionOpen('open');
}
setScheduling({
...scheduling,
...{
[type]: {
enabled: e.target.checked,
interval: scheduling[type].interval,
},
},
});
setHasChanges(type);
}}
/>
)
}
>
<EuiFlexGroup direction="column">
<EuiFlexItem>
<ConnectorCronEditor
disabled={isGated}
scheduling={scheduling[type]}
type={type}
onReset={() => {