[Workplace Search] Fix doc link, remove shadows on panels and fix source id bug (#97482)

* Fix private source docs link

* Add a whole bunch of missed shadow/background changes to panels

* Add success messages to Role mappings

* Fix bug where sourceId still in memory

If you were on an org source and then clicked to view your Personal dashboard, the subnav was visible because the source Id was still in the logic file. This resets it on unmount.

As a part of this fix, dataLoading was set to true on reset. Because of this, some places that were resettings state, but not fetching new data, were left in a loading state. This commit also removes the redundant `resetSourceState` calls around the components that don’t fetch a fresh copy of the source data
This commit is contained in:
Scotty Bollinger 2021-04-19 12:27:37 -05:00 committed by GitHub
parent 77fe59d58f
commit 08b5f0db2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 67 additions and 29 deletions

View file

@ -19,9 +19,10 @@ export const LEAVE_FEEDBACK_EMAIL = 'support@elastic.co';
export const LEAVE_FEEDBACK_URL = `mailto:${LEAVE_FEEDBACK_EMAIL}?Subject=Elastic%20Workplace%20Search%20Feedback`;
export const DOCS_PREFIX = docLinks.workplaceSearchBase;
export const PERMISSIONS_DOCS_URL = `${DOCS_PREFIX}/workplace-search-permissions.html`;
export const DOCUMENT_PERMISSIONS_DOCS_URL = `${DOCS_PREFIX}/workplace-search-sources-document-permissions.html`;
export const DOCUMENT_PERMISSIONS_SYNC_DOCS_URL = `${DOCUMENT_PERMISSIONS_DOCS_URL}#sources-permissions-synchronizing`;
export const PRIVATE_SOURCES_DOCS_URL = `${DOCUMENT_PERMISSIONS_DOCS_URL}#sources-permissions-org-private`;
export const PRIVATE_SOURCES_DOCS_URL = `${PERMISSIONS_DOCS_URL}#organizational-sources-private-sources`;
export const EXTERNAL_IDENTITIES_DOCS_URL = `${DOCS_PREFIX}/workplace-search-external-identities-api.html`;
export const SECURITY_DOCS_URL = `${DOCS_PREFIX}/workplace-search-security.html`;
export const SMTP_DOCS_URL = `${DOCS_PREFIX}/workplace-search-smtp-mailer.html`;

View file

@ -126,7 +126,7 @@ export const AddSourceList: React.FC = () => {
<EuiFlexGroup justifyContent="center" alignItems="stretch">
<EuiFlexItem>
<EuiSpacer size="xl" />
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiSpacer size="s" />
<EuiSpacer size="xxl" />
<EuiEmptyPrompt

View file

@ -113,7 +113,7 @@ export const DisplaySettings: React.FC<DisplaySettingsProps> = ({ tabId }) => {
onTabClick={onSelectedTabChanged}
/>
) : (
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiEmptyPrompt
iconType="indexRollupApp"
title={<h2>{DISPLAY_SETTINGS_EMPTY_TITLE}</h2>}

View file

@ -116,7 +116,12 @@ export const Overview: React.FC = () => {
const emptyState = (
<>
<EuiSpacer size="s" />
<EuiPanel paddingSize="l" data-test-subj="EmptyDocumentSummary">
<EuiPanel
hasShadow={false}
color="subdued"
paddingSize="l"
data-test-subj="EmptyDocumentSummary"
>
<EuiEmptyPrompt
title={<h2>{SOURCES_NO_CONTENT_TITLE}</h2>}
iconType="documents"
@ -163,7 +168,12 @@ export const Overview: React.FC = () => {
const emptyState = (
<>
<EuiSpacer size="s" />
<EuiPanel paddingSize="l" data-test-subj="EmptyActivitySummary">
<EuiPanel
paddingSize="l"
hasShadow={false}
color="subdued"
data-test-subj="EmptyActivitySummary"
>
<EuiEmptyPrompt
title={<h2>{EMPTY_ACTIVITY_TITLE}</h2>}
iconType="clock"

View file

@ -140,7 +140,7 @@ export const Schema: React.FC = () => {
<SchemaFieldsTable />
</>
) : (
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiEmptyPrompt
iconType="managementApp"
title={<h2>{SCHEMA_EMPTY_SCHEMA_TITLE}</h2>}

View file

@ -34,7 +34,6 @@ import { SourceContent } from './source_content';
describe('SourceContent', () => {
const setActivePage = jest.fn();
const searchContentSourceDocuments = jest.fn();
const resetSourceState = jest.fn();
const setContentFilterValue = jest.fn();
const mockValues = {
@ -51,7 +50,6 @@ describe('SourceContent', () => {
setMockActions({
setActivePage,
searchContentSourceDocuments,
resetSourceState,
setContentFilterValue,
});
setMockValues({ ...mockValues });

View file

@ -56,12 +56,9 @@ const MAX_LENGTH = 28;
export const SourceContent: React.FC = () => {
const [searchTerm, setSearchTerm] = useState('');
const {
setActivePage,
searchContentSourceDocuments,
resetSourceState,
setContentFilterValue,
} = useActions(SourceLogic);
const { setActivePage, searchContentSourceDocuments, setContentFilterValue } = useActions(
SourceLogic
);
const {
contentSource: { id, serviceType, urlField, titleField, urlFieldIsLinkable, isFederatedSource },
@ -74,10 +71,6 @@ export const SourceContent: React.FC = () => {
sectionLoading,
} = useValues(SourceLogic);
useEffect(() => {
return resetSourceState;
}, []);
useEffect(() => {
searchContentSourceDocuments(id);
}, [contentFilterValue, activePage]);
@ -106,7 +99,7 @@ export const SourceContent: React.FC = () => {
const isCustomSource = serviceType === CUSTOM_SERVICE_TYPE;
const emptyState = (
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiEmptyPrompt
title={<h2>{emptyMessage}</h2>}
iconType="documents"

View file

@ -23,7 +23,6 @@ import { SourceSettings } from './source_settings';
describe('SourceSettings', () => {
const updateContentSource = jest.fn();
const removeContentSource = jest.fn();
const resetSourceState = jest.fn();
const getSourceConfigData = jest.fn();
const contentSource = fullContentSources[0];
const buttonLoading = false;
@ -41,7 +40,6 @@ describe('SourceSettings', () => {
setMockActions({
updateContentSource,
removeContentSource,
resetSourceState,
getSourceConfigData,
});
});

View file

@ -52,7 +52,7 @@ import { staticSourceData } from '../source_data';
import { SourceLogic } from '../source_logic';
export const SourceSettings: React.FC = () => {
const { updateContentSource, removeContentSource, resetSourceState } = useActions(SourceLogic);
const { updateContentSource, removeContentSource } = useActions(SourceLogic);
const { getSourceConfigData } = useActions(AddSourceLogic);
const {
@ -68,7 +68,6 @@ export const SourceSettings: React.FC = () => {
useEffect(() => {
getSourceConfigData(serviceType);
return resetSourceState;
}, []);
const {

View file

@ -81,7 +81,7 @@ export const PrivateSources: React.FC = () => {
);
const privateSourcesEmptyState = (
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiSpacer size="xxl" />
<EuiEmptyPrompt iconType="lock" title={<h2>{PRIVATE_EMPTY_TITLE}</h2>} />
<EuiSpacer size="xxl" />
@ -107,7 +107,7 @@ export const PrivateSources: React.FC = () => {
);
const sharedSourcesEmptyState = (
<EuiPanel>
<EuiPanel hasShadow={false} color="subdued">
<EuiSpacer size="xxl" />
<EuiEmptyPrompt
iconType={noSharedSourcesIcon}

View file

@ -88,13 +88,14 @@ export const SourceLogic = kea<MakeLogicType<SourceValues, SourceActions>>({
...contentSource,
summary,
}),
resetSourceState: () => ({} as ContentSourceFullData),
},
],
dataLoading: [
true,
{
onInitializeSource: () => false,
resetSourceState: () => false,
resetSourceState: () => true,
},
],
buttonLoading: [

View file

@ -47,12 +47,13 @@ import { SourceLogic } from './source_logic';
export const SourceRouter: React.FC = () => {
const { sourceId } = useParams() as { sourceId: string };
const { initializeSource } = useActions(SourceLogic);
const { initializeSource, resetSourceState } = useActions(SourceLogic);
const { contentSource, dataLoading } = useValues(SourceLogic);
const { isOrganization } = useValues(AppLogic);
useEffect(() => {
initializeSource(sourceId);
return resetSourceState;
}, []);
if (dataLoading) return <Loading />;

View file

@ -15,6 +15,27 @@ export const DELETE_ROLE_MAPPING_MESSAGE = i18n.translate(
}
);
export const ROLE_MAPPING_DELETED_MESSAGE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.roleMappingDeletedMessage',
{
defaultMessage: 'Successfully deleted role mapping',
}
);
export const ROLE_MAPPING_CREATED_MESSAGE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.roleMappingCreatedMessage',
{
defaultMessage: 'Role mapping successfully created.',
}
);
export const ROLE_MAPPING_UPDATED_MESSAGE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.roleMappingUpdatedMessage',
{
defaultMessage: 'Role mapping successfully updated.',
}
);
export const DEFAULT_GROUP_NAME = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.roleMapping.defaultGroupName',
{

View file

@ -7,7 +7,11 @@
import { kea, MakeLogicType } from 'kea';
import { clearFlashMessages, flashAPIErrors } from '../../../shared/flash_messages';
import {
clearFlashMessages,
flashAPIErrors,
setSuccessMessage,
} from '../../../shared/flash_messages';
import { HttpLogic } from '../../../shared/http';
import { KibanaLogic } from '../../../shared/kibana';
import { ANY_AUTH_PROVIDER } from '../../../shared/role_mapping/constants';
@ -15,7 +19,13 @@ import { AttributeName } from '../../../shared/types';
import { ROLE_MAPPINGS_PATH } from '../../routes';
import { RoleGroup, WSRoleMapping, Role } from '../../types';
import { DELETE_ROLE_MAPPING_MESSAGE, DEFAULT_GROUP_NAME } from './constants';
import {
DELETE_ROLE_MAPPING_MESSAGE,
ROLE_MAPPING_DELETED_MESSAGE,
ROLE_MAPPING_CREATED_MESSAGE,
ROLE_MAPPING_UPDATED_MESSAGE,
DEFAULT_GROUP_NAME,
} from './constants';
interface RoleMappingsServerDetails {
multipleAuthProvidersConfig: boolean;
@ -265,6 +275,7 @@ export const RoleMappingsLogic = kea<MakeLogicType<RoleMappingsValues, RoleMappi
try {
await http.delete(route);
navigateToUrl(ROLE_MAPPINGS_PATH);
setSuccessMessage(ROLE_MAPPING_DELETED_MESSAGE);
} catch (e) {
flashAPIErrors(e);
}
@ -297,9 +308,14 @@ export const RoleMappingsLogic = kea<MakeLogicType<RoleMappingsValues, RoleMappi
? http.post('/api/workplace_search/org/role_mappings', { body })
: http.put(`/api/workplace_search/org/role_mappings/${roleMapping.id}`, { body });
const SUCCESS_MESSAGE = !roleMapping
? ROLE_MAPPING_CREATED_MESSAGE
: ROLE_MAPPING_UPDATED_MESSAGE;
try {
await request;
navigateToUrl(ROLE_MAPPINGS_PATH);
setSuccessMessage(SUCCESS_MESSAGE);
} catch (e) {
flashAPIErrors(e);
}