diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
index 1d04504cdcbc..748dc6a7cbcf 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts
@@ -305,6 +305,10 @@ export const exampleResult = {
urlField: 'myLink',
color: '#e3e3e3',
descriptionField: 'about',
+ typeField: 'otherType',
+ mediaTypeField: 'otherMediaType',
+ createdByField: 'otherCreatedBy',
+ updatedByField: 'otherUpdatedBy',
detailFields: [
{ fieldName: 'cats', label: 'Felines' },
{ fieldName: 'dogs', label: 'Canines' },
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts
index bce778f90436..edc772b36955 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/types.ts
@@ -204,6 +204,10 @@ export interface SearchResultConfig {
titleField: string | null;
subtitleField: string | null;
descriptionField: string | null;
+ typeField: string | null;
+ mediaTypeField: string | null;
+ createdByField: string | null;
+ updatedByField: string | null;
urlField: string | null;
color: string;
detailFields: DetailField[];
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.test.ts
new file mode 100644
index 000000000000..6475df7f4c39
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.test.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getAsLocalDateTimeString } from './';
+
+describe('getAsLocalDateTimeString', () => {
+ it('returns localized date if string can be parsed as date', () => {
+ const date = '2021-06-28';
+
+ expect(getAsLocalDateTimeString(date)).toEqual(new Date(Date.parse(date)).toLocaleString());
+ });
+
+ it('returns null if string cannot be parsed as date', () => {
+ const date = 'foo';
+
+ expect(getAsLocalDateTimeString(date)).toEqual(null);
+ });
+});
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.ts
new file mode 100644
index 000000000000..d5ceb50d4c9a
--- /dev/null
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/get_as_local_datetime_string.ts
@@ -0,0 +1,11 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export const getAsLocalDateTimeString = (str: string) => {
+ const dateValue = Date.parse(str);
+ return dateValue ? new Date(dateValue).toLocaleString() : null;
+};
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/index.ts
index 37228cf9e702..2d15d6ce407b 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/index.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/utils/index.ts
@@ -6,3 +6,4 @@
*/
export { toSentenceSerial } from './to_sentence_serial';
+export { getAsLocalDateTimeString } from './get_as_local_datetime_string';
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.scss b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.scss
index 027f36a5c551..e5b680c5edec 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.scss
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings.scss
@@ -22,6 +22,23 @@
0 0 20px $euiColorLightestShade;
}
+@mixin searchResultTag {
+ height: 20px;
+ border-radius: 2px;
+ display: inline-flex;
+ align-items: center;
+ padding: 0 .25rem;
+ background: #E9EDF2;
+ color: #647487;
+ font-size: 10px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: .075em;
+ white-space: nowrap;
+ z-index: 1;
+ margin-right: 5px;
+}
+
// Wrapper
.custom-source-display-settings {
font-size: 16px;
@@ -73,6 +90,28 @@
color: $euiColorDarkShade;
}
}
+
+ &__tag {
+ @include searchResultTag;
+ }
+
+ &__tag-content {
+ display: inline-flex;
+ height: 20px;
+ flex-shrink: 0;
+ align-items: center;
+ }
+
+ &__meta {
+ position: relative;
+ z-index: 1;
+ display: flex;
+ flex-flow: row nowrap;
+ align-items: center;
+ margin-top: .5rem;
+ font-size: .8em;
+ overflow: hidden;
+ }
}
.example-result-content-placeholder {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
index 10c715c80b3d..3e409fb9f614 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.test.ts
@@ -52,6 +52,10 @@ describe('DisplaySettingsLogic', () => {
urlFieldHover: false,
subtitleFieldHover: false,
descriptionFieldHover: false,
+ typeFieldHover: false,
+ mediaTypeFieldHover: false,
+ createdByFieldHover: false,
+ updatedByFieldHover: false,
fieldOptions: [],
optionalFieldOptions: [
{
@@ -182,6 +186,50 @@ describe('DisplaySettingsLogic', () => {
});
});
+ it('setTypeField', () => {
+ const TYPE = 'new type';
+ DisplaySettingsLogic.actions.setServerResponseData(serverProps);
+ DisplaySettingsLogic.actions.setTypeField(TYPE);
+
+ expect(DisplaySettingsLogic.values.searchResultConfig).toEqual({
+ ...searchResultConfig,
+ typeField: TYPE,
+ });
+ });
+
+ it('setMediaTypeField', () => {
+ const MEDIA_TYPE = 'new media type';
+ DisplaySettingsLogic.actions.setServerResponseData(serverProps);
+ DisplaySettingsLogic.actions.setMediaTypeField(MEDIA_TYPE);
+
+ expect(DisplaySettingsLogic.values.searchResultConfig).toEqual({
+ ...searchResultConfig,
+ mediaTypeField: MEDIA_TYPE,
+ });
+ });
+
+ it('setCreatedByField', () => {
+ const CREATED_BY = 'new created by';
+ DisplaySettingsLogic.actions.setServerResponseData(serverProps);
+ DisplaySettingsLogic.actions.setCreatedByField(CREATED_BY);
+
+ expect(DisplaySettingsLogic.values.searchResultConfig).toEqual({
+ ...searchResultConfig,
+ createdByField: CREATED_BY,
+ });
+ });
+
+ it('setUpdatedByField', () => {
+ const UPDATED_BY = 'new updated by';
+ DisplaySettingsLogic.actions.setServerResponseData(serverProps);
+ DisplaySettingsLogic.actions.setUpdatedByField(UPDATED_BY);
+
+ expect(DisplaySettingsLogic.values.searchResultConfig).toEqual({
+ ...searchResultConfig,
+ updatedByField: UPDATED_BY,
+ });
+ });
+
it('setDetailFields', () => {
const result = {
destination: {
@@ -286,6 +334,36 @@ describe('DisplaySettingsLogic', () => {
expect(DisplaySettingsLogic.values.urlFieldHover).toEqual(!defaultValues.urlFieldHover);
});
+
+ it('toggleTypeFieldHover', () => {
+ DisplaySettingsLogic.actions.toggleTypeFieldHover();
+
+ expect(DisplaySettingsLogic.values.typeFieldHover).toEqual(!defaultValues.typeFieldHover);
+ });
+
+ it('toggleMediaTypeFieldHover', () => {
+ DisplaySettingsLogic.actions.toggleMediaTypeFieldHover();
+
+ expect(DisplaySettingsLogic.values.mediaTypeFieldHover).toEqual(
+ !defaultValues.mediaTypeFieldHover
+ );
+ });
+
+ it('toggleCreatedByFieldHover', () => {
+ DisplaySettingsLogic.actions.toggleCreatedByFieldHover();
+
+ expect(DisplaySettingsLogic.values.createdByFieldHover).toEqual(
+ !defaultValues.createdByFieldHover
+ );
+ });
+
+ it('toggleUpdatedByFieldHover', () => {
+ DisplaySettingsLogic.actions.toggleUpdatedByFieldHover();
+
+ expect(DisplaySettingsLogic.values.updatedByFieldHover).toEqual(
+ !defaultValues.updatedByFieldHover
+ );
+ });
});
describe('listeners', () => {
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
index 38424df724bd..556507d891dc 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/display_settings_logic.ts
@@ -55,6 +55,10 @@ interface DisplaySettingsActions {
setUrlField(urlField: string): string;
setSubtitleField(subtitleField: string | null): string | null;
setDescriptionField(descriptionField: string | null): string | null;
+ setTypeField(typeField: string | null): string | null;
+ setMediaTypeField(mediaTypeField: string | null): string | null;
+ setCreatedByField(createdByField: string | null): string | null;
+ setUpdatedByField(updatedByField: string | null): string | null;
setColorField(hex: string): string;
setDetailFields(result: DropResult): { result: DropResult };
openEditDetailField(editFieldIndex: number | null): number | null;
@@ -70,6 +74,10 @@ interface DisplaySettingsActions {
toggleTitleFieldHover(): void;
toggleSubtitleFieldHover(): void;
toggleDescriptionFieldHover(): void;
+ toggleTypeFieldHover(): void;
+ toggleMediaTypeFieldHover(): void;
+ toggleCreatedByFieldHover(): void;
+ toggleUpdatedByFieldHover(): void;
toggleUrlFieldHover(): void;
}
@@ -89,6 +97,10 @@ interface DisplaySettingsValues {
urlFieldHover: boolean;
subtitleFieldHover: boolean;
descriptionFieldHover: boolean;
+ typeFieldHover: boolean;
+ mediaTypeFieldHover: boolean;
+ createdByFieldHover: boolean;
+ updatedByFieldHover: boolean;
fieldOptions: OptionValue[];
optionalFieldOptions: OptionValue[];
availableFieldOptions: OptionValue[];
@@ -100,6 +112,10 @@ export const defaultSearchResultConfig = {
subtitleField: '',
descriptionField: '',
urlField: '',
+ typeField: '',
+ mediaTypeField: '',
+ createdByField: '',
+ updatedByField: '',
color: '#000000',
detailFields: [],
};
@@ -115,7 +131,11 @@ export const DisplaySettingsLogic = kea<
setTitleField: (titleField: string) => titleField,
setUrlField: (urlField: string) => urlField,
setSubtitleField: (subtitleField: string | null) => subtitleField,
- setDescriptionField: (descriptionField: string) => descriptionField,
+ setDescriptionField: (descriptionField: string | null) => descriptionField,
+ setTypeField: (typeField: string | null) => typeField,
+ setMediaTypeField: (mediaTypeField: string | null) => mediaTypeField,
+ setCreatedByField: (createdByField: string | null) => createdByField,
+ setUpdatedByField: (updatedByField: string | null) => updatedByField,
setColorField: (hex: string) => hex,
setDetailFields: (result: DropResult) => ({ result }),
openEditDetailField: (editFieldIndex: number | null) => editFieldIndex,
@@ -128,6 +148,10 @@ export const DisplaySettingsLogic = kea<
toggleTitleFieldHover: () => true,
toggleSubtitleFieldHover: () => true,
toggleDescriptionFieldHover: () => true,
+ toggleTypeFieldHover: () => true,
+ toggleMediaTypeFieldHover: () => true,
+ toggleCreatedByFieldHover: () => true,
+ toggleUpdatedByFieldHover: () => true,
toggleUrlFieldHover: () => true,
initializeDisplaySettings: () => true,
setServerData: () => true,
@@ -181,6 +205,19 @@ export const DisplaySettingsLogic = kea<
...searchResultConfig,
descriptionField,
}),
+ setTypeField: (searchResultConfig, typeField) => ({ ...searchResultConfig, typeField }),
+ setMediaTypeField: (searchResultConfig, mediaTypeField) => ({
+ ...searchResultConfig,
+ mediaTypeField,
+ }),
+ setCreatedByField: (searchResultConfig, createdByField) => ({
+ ...searchResultConfig,
+ createdByField,
+ }),
+ setUpdatedByField: (searchResultConfig, updatedByField) => ({
+ ...searchResultConfig,
+ updatedByField,
+ }),
setColorField: (searchResultConfig, color) => ({ ...searchResultConfig, color }),
setDetailFields: (searchResultConfig, { result: { destination, source } }) => {
const detailFields = cloneDeep(searchResultConfig.detailFields);
@@ -273,7 +310,31 @@ export const DisplaySettingsLogic = kea<
descriptionFieldHover: [
false,
{
- toggleDescriptionFieldHover: (addFieldModalVisible) => !addFieldModalVisible,
+ toggleDescriptionFieldHover: (descriptionFieldHover) => !descriptionFieldHover,
+ },
+ ],
+ typeFieldHover: [
+ false,
+ {
+ toggleTypeFieldHover: (typeFieldHover) => !typeFieldHover,
+ },
+ ],
+ mediaTypeFieldHover: [
+ false,
+ {
+ toggleMediaTypeFieldHover: (mediaTypeFieldHover) => !mediaTypeFieldHover,
+ },
+ ],
+ createdByFieldHover: [
+ false,
+ {
+ toggleCreatedByFieldHover: (createdByFieldHover) => !createdByFieldHover,
+ },
+ ],
+ updatedByFieldHover: [
+ false,
+ {
+ toggleUpdatedByFieldHover: (updatedByFieldHover) => !updatedByFieldHover,
},
],
},
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
index c3d56949d0fe..eef508b2e618 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx
@@ -13,16 +13,12 @@ import { useValues } from 'kea';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import { URL_LABEL } from '../../../../constants';
+import { getAsLocalDateTimeString } from '../../../../utils';
import { CustomSourceIcon } from './custom_source_icon';
import { DisplaySettingsLogic } from './display_settings_logic';
import { TitleField } from './title_field';
-const getAsLocalDateTimeString = (str: string) => {
- const dateValue = Date.parse(str);
- return dateValue ? new Date(dateValue).toLocaleString() : null;
-};
-
export const ExampleResultDetailCard: React.FC = () => {
const {
sourceName,
diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
index 7139ea30be13..1835d8485664 100644
--- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_search_result_group.test.tsx
@@ -41,4 +41,26 @@ describe('ExampleSearchResultGroup', () => {
expect(wrapper.find('[data-test-subj="DefaultDescriptionLabel"]')).toHaveLength(1);
});
+
+ it('renders optional fields if they exist in result', () => {
+ setMockValues({
+ ...exampleResult,
+ exampleDocuments: [
+ {
+ myLink: 'http://foo',
+ otherTitle: 'foo',
+ otherType: 'File',
+ otherMediaType: 'PDF',
+ otherCreatedBy: 'bar',
+ otherUpdatedBy: 'baz',
+ },
+ ],
+ });
+ const wrapper = shallow(