Skip to content

Commit

Permalink
[Discover] Hide "Add a field", "Edit" and "Create a data view" button…
Browse files Browse the repository at this point in the history
…s in viewer mode (#134582)

* [Discover] Hide "Add a field" button for read only access

* [Discover] Hide "Create a data view" button for read only access on desktop

* [Discover] Hide "Create a data view" and "Add a field" button for read only access on mobile

* [Discover] Make sure that error message is shown when access rights were reduced for a user in meantime

* [Discover] Make checks safe

* [Discover] Update tests

* [Discover] Streamline the logic

* [Discover] Update tests

* [Discover] Add tests

* [Discover] Add tests

* [Discover] Update code style

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
jughosta and kibanamachine authored Jun 21, 2022
1 parent 9ec4d31 commit 7410fbf
Show file tree
Hide file tree
Showing 10 changed files with 272 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ export function DiscoverLayout({
resetSavedSearch={resetSavedSearch}
onChangeIndexPattern={onChangeIndexPattern}
onEditRuntimeField={onEditRuntimeField}
useNewFieldsApi={useNewFieldsApi}
/>
<EuiPageBody className="dscPageBody" aria-describedby="savedSearchTitle">
<SavedSearchURLConflictCallout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,13 @@ export interface DiscoverFieldProps {
multiFields?: Array<{ field: DataViewField; isSelected: boolean }>;

/**
* Callback to edit a runtime field from index pattern
* Callback to edit a field from data view
* @param fieldName name of the field to edit
*/
onEditField?: (fieldName: string) => void;

/**
* Callback to delete a runtime field from index pattern
* Callback to delete a runtime field from data view
* @param fieldName name of the field to delete
*/
onDeleteField?: (fieldName: string) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { cloneDeep, each } from 'lodash';
import { ReactWrapper } from 'enzyme';
import { findTestSubject } from '@elastic/eui/lib/test';
import { Action } from '@kbn/ui-actions-plugin/public';
// @ts-expect-error
import realHits from '../../../../__fixtures__/real_hits';

Expand All @@ -29,6 +30,16 @@ import { BehaviorSubject } from 'rxjs';
import { FetchStatus } from '../../../types';
import { AvailableFields$ } from '../../hooks/use_saved_search';

const mockGetActions = jest.fn<Promise<Array<Action<object>>>, [string, { fieldName: string }]>(
() => Promise.resolve([])
);

jest.mock('../../../../kibana_services', () => ({
getUiActions: () => ({
getTriggerCompatibleActions: mockGetActions,
}),
}));

function getCompProps(): DiscoverSidebarProps {
const indexPattern = stubLogstashIndexPattern;
const hits = each(cloneDeep(realHits), (hit) =>
Expand Down Expand Up @@ -73,6 +84,7 @@ function getCompProps(): DiscoverSidebarProps {
createNewDataView: jest.fn(),
onDataViewCreated: jest.fn(),
availableFields$,
useNewFieldsApi: true,
};
}

Expand Down Expand Up @@ -105,4 +117,80 @@ describe('discover sidebar', function () {
findTestSubject(comp, 'fieldToggle-extension').simulate('click');
expect(props.onRemoveField).toHaveBeenCalledWith('extension');
});

it('should render "Add a field" button', () => {
const addFieldButton = findTestSubject(comp, 'indexPattern-add-field_btn');
expect(addFieldButton.length).toBe(1);
addFieldButton.simulate('click');
expect(props.editField).toHaveBeenCalledWith();
});

it('should render "Edit field" button', () => {
findTestSubject(comp, 'field-bytes').simulate('click');
const editFieldButton = findTestSubject(comp, 'discoverFieldListPanelEdit-bytes');
expect(editFieldButton.length).toBe(1);
editFieldButton.simulate('click');
expect(props.editField).toHaveBeenCalledWith('bytes');
});

it('should not render Add/Edit field buttons in viewer mode', () => {
const compInViewerMode = mountWithIntl(
<KibanaContextProvider services={mockDiscoverServices}>
<DiscoverSidebar {...props} editField={undefined} />
</KibanaContextProvider>
);
const addFieldButton = findTestSubject(compInViewerMode, 'indexPattern-add-field_btn');
expect(addFieldButton.length).toBe(0);
findTestSubject(comp, 'field-bytes').simulate('click');
const editFieldButton = findTestSubject(compInViewerMode, 'discoverFieldListPanelEdit-bytes');
expect(editFieldButton.length).toBe(0);
});

it('should render buttons in data view picker correctly', async () => {
const compWithPicker = mountWithIntl(
<KibanaContextProvider services={mockDiscoverServices}>
<DiscoverSidebar {...props} showDataViewPicker />
</KibanaContextProvider>
);
// open data view picker
findTestSubject(compWithPicker, 'indexPattern-switch-link').simulate('click');
expect(findTestSubject(compWithPicker, 'changeDataViewPopover').length).toBe(1);
// click "Add a field"
const addFieldButtonInDataViewPicker = findTestSubject(
compWithPicker,
'indexPattern-add-field'
);
expect(addFieldButtonInDataViewPicker.length).toBe(1);
addFieldButtonInDataViewPicker.simulate('click');
expect(props.editField).toHaveBeenCalledWith();
// click "Create a data view"
const createDataViewButton = findTestSubject(compWithPicker, 'dataview-create-new');
expect(createDataViewButton.length).toBe(1);
createDataViewButton.simulate('click');
expect(props.createNewDataView).toHaveBeenCalled();
});

it('should not render buttons in data view picker when in viewer mode', async () => {
const compWithPickerInViewerMode = mountWithIntl(
<KibanaContextProvider services={mockDiscoverServices}>
<DiscoverSidebar
{...props}
showDataViewPicker
editField={undefined}
createNewDataView={undefined}
/>
</KibanaContextProvider>
);
// open data view picker
findTestSubject(compWithPickerInViewerMode, 'indexPattern-switch-link').simulate('click');
expect(findTestSubject(compWithPickerInViewerMode, 'changeDataViewPopover').length).toBe(1);
// check that buttons are not present
const addFieldButtonInDataViewPicker = findTestSubject(
compWithPickerInViewerMode,
'indexPattern-add-field'
);
expect(addFieldButtonInDataViewPicker.length).toBe(0);
const createDataViewButton = findTestSubject(compWithPickerInViewerMode, 'dataview-create-new');
expect(createDataViewButton.length).toBe(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,18 @@ export interface DiscoverSidebarProps extends Omit<DiscoverSidebarResponsiveProp
*/
setFieldEditorRef?: (ref: () => void | undefined) => void;

editField: (fieldName?: string) => void;
/**
* Handles "Edit field" action
* Buttons will be hidden if not provided
* @param fieldName
*/
editField?: (fieldName?: string) => void;

createNewDataView: () => void;
/**
* Handles "Create a data view action" action
* Buttons will be hidden if not provided
*/
createNewDataView?: () => void;

/**
* a statistics of the distribution of fields in the given hits
Expand Down Expand Up @@ -113,9 +122,6 @@ export function DiscoverSidebarComponent({
}: DiscoverSidebarProps) {
const { uiSettings, dataViewFieldEditor } = useDiscoverServices();
const [fields, setFields] = useState<DataViewField[] | null>(null);

const dataViewFieldEditPermission = dataViewFieldEditor?.userPermissions.editIndexPattern();
const canEditDataViewField = !!dataViewFieldEditPermission && useNewFieldsApi;
const [scrollContainer, setScrollContainer] = useState<Element | null>(null);
const [fieldsToRender, setFieldsToRender] = useState(FIELDS_PER_PAGE);
const [fieldsPerPage, setFieldsPerPage] = useState(FIELDS_PER_PAGE);
Expand Down Expand Up @@ -258,7 +264,7 @@ export function DiscoverSidebarComponent({

const deleteField = useMemo(
() =>
canEditDataViewField && selectedIndexPattern
editField && selectedIndexPattern
? async (fieldName: string) => {
const ref = dataViewFieldEditor.openDeleteModal({
ctx: {
Expand All @@ -279,7 +285,7 @@ export function DiscoverSidebarComponent({
: undefined,
[
selectedIndexPattern,
canEditDataViewField,
editField,
setFieldEditorRef,
closeFlyout,
onEditRuntimeField,
Expand Down Expand Up @@ -396,8 +402,8 @@ export function DiscoverSidebarComponent({
selected={true}
trackUiMetric={trackUiMetric}
multiFields={multiFields?.get(field.name)}
onEditField={canEditDataViewField ? editField : undefined}
onDeleteField={canEditDataViewField ? deleteField : undefined}
onEditField={editField}
onDeleteField={deleteField}
showFieldStats={showFieldStats}
/>
</li>
Expand Down Expand Up @@ -456,8 +462,8 @@ export function DiscoverSidebarComponent({
getDetails={getDetailsByField}
trackUiMetric={trackUiMetric}
multiFields={multiFields?.get(field.name)}
onEditField={canEditDataViewField ? editField : undefined}
onDeleteField={canEditDataViewField ? deleteField : undefined}
onEditField={editField}
onDeleteField={deleteField}
showFieldStats={showFieldStats}
/>
</li>
Expand Down Expand Up @@ -485,8 +491,8 @@ export function DiscoverSidebarComponent({
getDetails={getDetailsByField}
trackUiMetric={trackUiMetric}
multiFields={multiFields?.get(field.name)}
onEditField={canEditDataViewField ? editField : undefined}
onDeleteField={canEditDataViewField ? deleteField : undefined}
onEditField={editField}
onDeleteField={deleteField}
showFieldStats={showFieldStats}
/>
</li>
Expand All @@ -498,18 +504,20 @@ export function DiscoverSidebarComponent({
)}
</div>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton
iconType="indexOpen"
data-test-subj="indexPattern-add-field_btn"
onClick={() => editField()}
size="s"
>
{i18n.translate('discover.fieldChooser.addField.label', {
defaultMessage: 'Add a field',
})}
</EuiButton>
</EuiFlexItem>
{!!editField && (
<EuiFlexItem grow={false}>
<EuiButton
iconType="indexOpen"
data-test-subj="indexPattern-add-field_btn"
onClick={() => editField()}
size="s"
>
{i18n.translate('discover.fieldChooser.addField.label', {
defaultMessage: 'Add a field',
})}
</EuiButton>
</EuiFlexItem>
)}
</EuiFlexGroup>
</EuiPageSideBar>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ const mockServices = {
},
},
docLinks: { links: { discover: { fieldTypeHelp: '' } } },
dataViewEditor: {
userPermissions: {
editDataView: jest.fn(() => true),
},
},
} as unknown as DiscoverServices;

const mockfieldCounts: Record<string, number> = {};
Expand Down Expand Up @@ -111,6 +116,7 @@ function getCompProps(): DiscoverSidebarResponsiveProps {
onEditRuntimeField: jest.fn(),
viewMode: VIEW_MODE.DOCUMENT_LEVEL,
onDataViewCreated: jest.fn(),
useNewFieldsApi: true,
};
}

Expand Down Expand Up @@ -160,4 +166,31 @@ describe('discover responsive sidebar', function () {
expect(findTestSubject(comp, 'fieldList-unpopular').children().length).toBe(4);
expect(mockCalcFieldCounts.mock.calls.length).toBe(1);
});

it('should show "Add a field" button to create a runtime field', () => {
expect(mockServices.dataViewEditor.userPermissions.editDataView).toHaveBeenCalled();
expect(findTestSubject(comp, 'indexPattern-add-field_btn').length).toBe(1);
});

it('should not show "Add a field" button in viewer mode', () => {
const mockedServicesInViewerMode = {
...mockServices,
dataViewEditor: {
...mockServices.dataViewEditor,
userPermissions: {
...mockServices.dataViewEditor.userPermissions,
editDataView: jest.fn(() => false),
},
},
};
const compInViewerMode = mountWithIntl(
<KibanaContextProvider services={mockedServicesInViewerMode}>
<DiscoverSidebarResponsive {...props} />
</KibanaContextProvider>
);
expect(
mockedServicesInViewerMode.dataViewEditor.userPermissions.editDataView
).toHaveBeenCalled();
expect(findTestSubject(compInViewerMode, 'indexPattern-add-field_btn').length).toBe(0);
});
});
Loading

0 comments on commit 7410fbf

Please sign in to comment.