[Enterprise Search] Tech debt/cleanup: remove I/E/T Typescript prefixes (#83027)

* [All] Remove prefixes on simple self-contained type defs

- Types should not be exported
- Types should not be used outside each affected file

* [All][kea] Remove ts prefixes and unnecessary exports

Kea now takes care of type checking for us, so there should virtually never be a need to export our values and actions interfaces going forward

* [shared] Remove createHref type prefixes

* [shared] Remove breadcrumb prefixes

* [shared] Remove telemetry prefixes

* [shared] remove types.ts

Opionionated change: it was only being used for IFlashMessage, and at this point I think it's more useful to go in one level deeper to grab the type you need

* [server] remove route dependencies prefixes

* [server] Various type cleanups

- plugin.ts - remove unnecessary export
- MockRouter - remove prefix for request type, change IMockRouter to match Kibana's IRouter
- check_access - remove prefixes
- callEnterpriseSearchConfigAPI - remove prefixes
- EnterpriseSearchRequestHandler - remove prefixes

* [common] Remove InitialAppData prefix

+ remove unnecessary export from public/plugin.ts

* [common] Remove Meta prefixes

* [common] Remove configured limits prefixes

* [AS] Remove Account and Role prefixes

* [AS] Remove Engine prefixes

* [AS] Remove credentials prefixes

* [AS] Remove log settings prefixes

* [WS] Remove account/organization/initial data prefixes

* [WS] Remove group(s), user, & content source prefixes

+ GroupLogic and GroupsLogic refactor - remove unnecessary defs in actions, it's already defined in the Actions interface above and in some cases (e.g. old History param) is causing out of date issues

* [WS] Misc type fixes

- TSpacerSize -> SpaceSizeTypes
- SourcePriority - remove prefixes
- IComponentLoader - this isn't used anywhere else and appears to be component props so it probably should live only within component_loader.tsx
- Remove recent feed activity prefix

* [WS][Opinionated] Move interfaces not used in server/ out of common/ and to public/
This commit is contained in:
Constance 2020-11-10 10:52:20 -08:00 committed by GitHub
parent 8842e9b7a9
commit c7f085ff0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
114 changed files with 598 additions and 626 deletions

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
export interface IAccount {
export interface Account {
accountId: string;
onboardingComplete: boolean;
role: {
@ -21,7 +21,7 @@ export interface IAccount {
};
}
export interface IConfiguredLimits {
export interface ConfiguredLimits {
engine: {
maxDocumentByteSize: number;
maxEnginesPerMetaEngine: number;

View file

@ -5,39 +5,39 @@
*/
import {
IAccount as IAppSearchAccount,
IConfiguredLimits as IAppSearchConfiguredLimits,
Account as AppSearchAccount,
ConfiguredLimits as AppSearchConfiguredLimits,
} from './app_search';
import {
IWorkplaceSearchInitialData,
IConfiguredLimits as IWorkplaceSearchConfiguredLimits,
WorkplaceSearchInitialData,
ConfiguredLimits as WorkplaceSearchConfiguredLimits,
} from './workplace_search';
export interface IInitialAppData {
export interface InitialAppData {
readOnlyMode?: boolean;
ilmEnabled?: boolean;
isFederatedAuth?: boolean;
configuredLimits?: IConfiguredLimits;
configuredLimits?: ConfiguredLimits;
access?: {
hasAppSearchAccess: boolean;
hasWorkplaceSearchAccess: boolean;
};
appSearch?: IAppSearchAccount;
workplaceSearch?: IWorkplaceSearchInitialData;
appSearch?: AppSearchAccount;
workplaceSearch?: WorkplaceSearchInitialData;
}
export interface IConfiguredLimits {
appSearch: IAppSearchConfiguredLimits;
workplaceSearch: IWorkplaceSearchConfiguredLimits;
export interface ConfiguredLimits {
appSearch: AppSearchConfiguredLimits;
workplaceSearch: WorkplaceSearchConfiguredLimits;
}
export interface IMetaPage {
export interface MetaPage {
current: number;
size: number;
total_pages: number;
total_results: number;
}
export interface IMeta {
page: IMetaPage;
export interface Meta {
page: MetaPage;
}

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
export interface IAccount {
export interface Account {
id: string;
groups: string[];
isAdmin: boolean;
@ -14,65 +14,19 @@ export interface IAccount {
viewedOnboardingPage: boolean;
}
export interface IOrganization {
export interface Organization {
name: string;
defaultOrgName: string;
}
export interface IWorkplaceSearchInitialData {
organization: IOrganization;
account: IAccount;
export interface WorkplaceSearchInitialData {
organization: Organization;
account: Account;
}
export interface IConfiguredLimits {
export interface ConfiguredLimits {
customApiSource: {
maxDocumentByteSize: number;
totalFields: number;
};
}
export interface IGroup {
id: string;
name: string;
createdAt: string;
updatedAt: string;
contentSources: IContentSource[];
users: IUser[];
usersCount: number;
color?: string;
}
export interface IGroupDetails extends IGroup {
contentSources: IContentSourceDetails[];
canEditGroup: boolean;
canDeleteGroup: boolean;
}
export interface IUser {
id: string;
name: string | null;
initials: string;
pictureUrl: string | null;
color: string;
email: string;
role?: string;
groupIds: string[];
}
export interface IContentSource {
id: string;
serviceType: string;
name: string;
}
export interface IContentSourceDetails extends IContentSource {
status: string;
statusMessage: string;
documentCount: string;
isFederatedSource: boolean;
searchable: boolean;
supportedByLicense: boolean;
errorReason: number;
allowsReauth: boolean;
boost: number;
}

View file

@ -20,13 +20,13 @@ import { mountWithIntl } from './';
* const wrapper = mountAsync(<Component />);
*/
interface IOptions {
interface Options {
i18n?: boolean;
}
export const mountAsync = async (
children: React.ReactElement,
options: IOptions
options: Options
): Promise<ReactWrapper> => {
let wrapper: ReactWrapper | undefined;

View file

@ -6,24 +6,24 @@
import { kea, MakeLogicType } from 'kea';
import { IInitialAppData } from '../../../common/types';
import { IConfiguredLimits, IAccount, IRole } from './types';
import { InitialAppData } from '../../../common/types';
import { ConfiguredLimits, Account, Role } from './types';
import { getRoleAbilities } from './utils/role';
export interface IAppValues {
interface AppValues {
hasInitialized: boolean;
ilmEnabled: boolean;
configuredLimits: Partial<IConfiguredLimits>;
account: Partial<IAccount>;
myRole: Partial<IRole>;
configuredLimits: Partial<ConfiguredLimits>;
account: Partial<Account>;
myRole: Partial<Role>;
}
export interface IAppActions {
initializeAppData(props: IInitialAppData): Required<IInitialAppData>;
interface AppActions {
initializeAppData(props: InitialAppData): Required<InitialAppData>;
setOnboardingComplete(): boolean;
}
export const AppLogic = kea<MakeLogicType<IAppValues, IAppActions>>({
export const AppLogic = kea<MakeLogicType<AppValues, AppActions>>({
path: ['enterprise_search', 'app_search', 'app_logic'],
actions: {
initializeAppData: (props) => props,

View file

@ -10,7 +10,7 @@ import { EuiCheckbox, EuiText, EuiTitle, EuiSpacer, EuiPanel } from '@elastic/eu
import { i18n } from '@kbn/i18n';
import { CredentialsLogic } from '../../credentials_logic';
import { ITokenReadWrite } from '../../types';
import { TokenReadWrite } from '../../types';
export const FormKeyReadWriteAccess: React.FC = () => {
const { setTokenReadWrite } = useActions(CredentialsLogic);
@ -37,7 +37,7 @@ export const FormKeyReadWriteAccess: React.FC = () => {
name="read"
id="read"
checked={activeApiToken.read}
onChange={(e) => setTokenReadWrite(e.target as ITokenReadWrite)}
onChange={(e) => setTokenReadWrite(e.target as TokenReadWrite)}
label={i18n.translate(
'xpack.enterpriseSearch.appSearch.credentials.formReadWrite.readLabel',
{ defaultMessage: 'Read Access' }
@ -47,7 +47,7 @@ export const FormKeyReadWriteAccess: React.FC = () => {
name="write"
id="write"
checked={activeApiToken.write}
onChange={(e) => setTokenReadWrite(e.target as ITokenReadWrite)}
onChange={(e) => setTokenReadWrite(e.target as TokenReadWrite)}
label={i18n.translate(
'xpack.enterpriseSearch.appSearch.credentials.formReadWrite.writeLabel',
{ defaultMessage: 'Write Access' }

View file

@ -11,12 +11,12 @@ import { shallow } from 'enzyme';
import { EuiFlyoutHeader } from '@elastic/eui';
import { ApiTokenTypes } from '../constants';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
import { CredentialsFlyoutHeader } from './header';
describe('CredentialsFlyoutHeader', () => {
const apiToken: IApiToken = {
const apiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,

View file

@ -10,7 +10,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { EuiBasicTable, EuiCopy, EuiEmptyPrompt } from '@elastic/eui';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
import { ApiTokenTypes } from '../constants';
import { HiddenText } from '../../../../shared/hidden_text';
@ -18,7 +18,7 @@ import { Key } from './key';
import { CredentialsList } from './credentials_list';
describe('Credentials', () => {
const apiToken: IApiToken = {
const apiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,
@ -77,7 +77,7 @@ describe('Credentials', () => {
});
const wrapper = shallow(<CredentialsList />);
const { items } = wrapper.find(EuiBasicTable).props();
expect(items.map((i: IApiToken) => i.id)).toEqual([undefined, 1, 2]);
expect(items.map((i: ApiToken) => i.id)).toEqual([undefined, 1, 2]);
});
});

View file

@ -14,7 +14,7 @@ import { i18n } from '@kbn/i18n';
import { CredentialsLogic } from '../credentials_logic';
import { Key } from './key';
import { HiddenText } from '../../../../shared/hidden_text';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
import { TOKEN_TYPE_DISPLAY_NAMES } from '../constants';
import { apiTokenSort } from '../utils/api_token_sort';
import { getModeDisplayText, getEnginesDisplayText } from '../utils';
@ -26,21 +26,21 @@ export const CredentialsList: React.FC = () => {
const items = useMemo(() => apiTokens.slice().sort(apiTokenSort), [apiTokens]);
const columns: Array<EuiBasicTableColumn<IApiToken>> = [
const columns: Array<EuiBasicTableColumn<ApiToken>> = [
{
name: 'Name',
width: '12%',
render: (token: IApiToken) => token.name,
render: (token: ApiToken) => token.name,
},
{
name: 'Type',
width: '15%',
render: (token: IApiToken) => TOKEN_TYPE_DISPLAY_NAMES[token.type],
render: (token: ApiToken) => TOKEN_TYPE_DISPLAY_NAMES[token.type],
},
{
name: 'Key',
width: '36%',
render: (token: IApiToken) => {
render: (token: ApiToken) => {
const { key } = token;
if (!key) return null;
return (
@ -64,12 +64,12 @@ export const CredentialsList: React.FC = () => {
{
name: 'Modes',
width: '10%',
render: (token: IApiToken) => getModeDisplayText(token),
render: (token: ApiToken) => getModeDisplayText(token),
},
{
name: 'Engines',
width: '18%',
render: (token: IApiToken) => getEnginesDisplayText(token),
render: (token: ApiToken) => getEnginesDisplayText(token),
},
{
actions: [
@ -83,7 +83,7 @@ export const CredentialsList: React.FC = () => {
type: 'icon',
icon: 'pencil',
color: 'primary',
onClick: (token: IApiToken) => showCredentialsForm(token),
onClick: (token: ApiToken) => showCredentialsForm(token),
},
{
name: i18n.translate('xpack.enterpriseSearch.actions.delete', {
@ -95,7 +95,7 @@ export const CredentialsList: React.FC = () => {
type: 'icon',
icon: 'trash',
color: 'danger',
onClick: (token: IApiToken) => deleteApiKey(token.name),
onClick: (token: ApiToken) => deleteApiKey(token.name),
},
],
},
@ -108,7 +108,7 @@ export const CredentialsList: React.FC = () => {
hidePerPageOptions: true,
};
const onTableChange = ({ page }: CriteriaWithPagination<IApiToken>) => {
const onTableChange = ({ page }: CriteriaWithPagination<ApiToken>) => {
const { index: current } = page;
fetchCredentials(current + 1);
};

View file

@ -8,14 +8,14 @@ import React from 'react';
import { EuiButtonIcon } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
interface IProps {
interface Props {
copy: () => void;
toggleIsHidden: () => void;
isHidden: boolean;
text: React.ReactNode;
}
export const Key: React.FC<IProps> = ({ copy, toggleIsHidden, isHidden, text }) => {
export const Key: React.FC<Props> = ({ copy, toggleIsHidden, isHidden, text }) => {
const hideIcon = isHidden ? 'eye' : 'eyeClosed';
const hideIconLabel = isHidden
? i18n.translate('xpack.enterpriseSearch.appSearch.credentials.showApiKey', {

View file

@ -17,11 +17,11 @@ import {
} from '../../../shared/flash_messages';
import { AppLogic } from '../../app_logic';
import { IMeta } from '../../../../../common/types';
import { IEngine } from '../../types';
import { IApiToken, ICredentialsDetails, ITokenReadWrite } from './types';
import { Meta } from '../../../../../common/types';
import { Engine } from '../../types';
import { ApiToken, CredentialsDetails, TokenReadWrite } from './types';
export const defaultApiToken: IApiToken = {
export const defaultApiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,
@ -29,21 +29,21 @@ export const defaultApiToken: IApiToken = {
access_all_engines: true,
};
interface ICredentialsLogicActions {
interface CredentialsLogicActions {
addEngineName(engineName: string): string;
onApiKeyDelete(tokenName: string): string;
onApiTokenCreateSuccess(apiToken: IApiToken): IApiToken;
onApiTokenCreateSuccess(apiToken: ApiToken): ApiToken;
onApiTokenError(formErrors: string[]): string[];
onApiTokenUpdateSuccess(apiToken: IApiToken): IApiToken;
onApiTokenUpdateSuccess(apiToken: ApiToken): ApiToken;
removeEngineName(engineName: string): string;
setAccessAllEngines(accessAll: boolean): boolean;
setCredentialsData(meta: IMeta, apiTokens: IApiToken[]): { meta: IMeta; apiTokens: IApiToken[] };
setCredentialsDetails(details: ICredentialsDetails): ICredentialsDetails;
setCredentialsData(meta: Meta, apiTokens: ApiToken[]): { meta: Meta; apiTokens: ApiToken[] };
setCredentialsDetails(details: CredentialsDetails): CredentialsDetails;
setNameInputBlurred(isBlurred: boolean): boolean;
setTokenReadWrite(tokenReadWrite: ITokenReadWrite): ITokenReadWrite;
setTokenReadWrite(tokenReadWrite: TokenReadWrite): TokenReadWrite;
setTokenName(name: string): string;
setTokenType(tokenType: string): string;
showCredentialsForm(apiToken?: IApiToken): IApiToken;
showCredentialsForm(apiToken?: ApiToken): ApiToken;
hideCredentialsForm(): { value: boolean };
resetCredentials(): { value: boolean };
initializeCredentialsData(): { value: boolean };
@ -54,25 +54,25 @@ interface ICredentialsLogicActions {
onEngineSelect(engineName: string): string;
}
interface ICredentialsLogicValues {
activeApiToken: IApiToken;
interface CredentialsLogicValues {
activeApiToken: ApiToken;
activeApiTokenExists: boolean;
activeApiTokenRawName: string;
apiTokens: IApiToken[];
apiTokens: ApiToken[];
dataLoading: boolean;
engines: IEngine[];
engines: Engine[];
formErrors: string[];
isCredentialsDataComplete: boolean;
isCredentialsDetailsComplete: boolean;
fullEngineAccessChecked: boolean;
meta: Partial<IMeta>;
meta: Partial<Meta>;
nameInputBlurred: boolean;
shouldShowCredentialsForm: boolean;
}
export const CredentialsLogic = kea<
MakeLogicType<ICredentialsLogicValues, ICredentialsLogicActions>
>({
type CredentialsLogicType = MakeLogicType<CredentialsLogicValues, CredentialsLogicActions>; // If we leave this inline, Prettier does some horrifying indenting nonsense :/
export const CredentialsLogic = kea<CredentialsLogicType>({
path: ['enterprise_search', 'app_search', 'credentials_logic'],
actions: () => ({
addEngineName: (engineName) => engineName,
@ -267,7 +267,7 @@ export const CredentialsLogic = kea<
onApiTokenChange: async () => {
const { id, name, engines, type, read, write } = values.activeApiToken;
const data: IApiToken = {
const data: ApiToken = {
name,
type,
};

View file

@ -4,14 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IEngine } from '../../types';
import { Engine } from '../../types';
import { ApiTokenTypes } from './constants';
export interface ICredentialsDetails {
engines: IEngine[];
export interface CredentialsDetails {
engines: Engine[];
}
export interface IApiToken {
export interface ApiToken {
access_all_engines?: boolean;
key?: string;
engines?: string[];
@ -22,7 +22,7 @@ export interface IApiToken {
write?: boolean;
}
export interface ITokenReadWrite {
export interface TokenReadWrite {
name: 'read' | 'write';
checked: boolean;
}

View file

@ -7,10 +7,10 @@
import { apiTokenSort } from '.';
import { ApiTokenTypes } from '../constants';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
describe('apiTokenSort', () => {
const apiToken: IApiToken = {
const apiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,

View file

@ -4,9 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IApiToken } from '../types';
import { ApiToken } from '../types';
export const apiTokenSort = (apiTokenA: IApiToken, apiTokenB: IApiToken): number => {
export const apiTokenSort = (apiTokenA: ApiToken, apiTokenB: ApiToken): number => {
if (!apiTokenA.id) {
return -1;
}

View file

@ -8,10 +8,10 @@ import React from 'react';
import { shallow } from 'enzyme';
import { getEnginesDisplayText } from './get_engines_display_text';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
import { ApiTokenTypes } from '../constants';
const apiToken: IApiToken = {
const apiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,

View file

@ -6,9 +6,9 @@
import React from 'react';
import { ApiTokenTypes, ALL } from '../constants';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
export const getEnginesDisplayText = (apiToken: IApiToken): JSX.Element | string => {
export const getEnginesDisplayText = (apiToken: ApiToken): JSX.Element | string => {
const { type, access_all_engines: accessAll, engines = [] } = apiToken;
if (type === ApiTokenTypes.Admin) {
return '--';

View file

@ -5,11 +5,11 @@
*/
import { ApiTokenTypes } from '../constants';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
import { getModeDisplayText } from './get_mode_display_text';
const apiToken: IApiToken = {
const apiToken: ApiToken = {
name: '',
type: ApiTokenTypes.Private,
read: true,

View file

@ -5,9 +5,9 @@
*/
import { ApiTokenTypes, READ_ONLY, READ_WRITE, SEARCH_DISPLAY, WRITE_ONLY } from '../constants';
import { IApiToken } from '../types';
import { ApiToken } from '../types';
export const getModeDisplayText = (apiToken: IApiToken): string => {
export const getModeDisplayText = (apiToken: ApiToken): string => {
const { read = false, write = false, type } = apiToken;
switch (type) {

View file

@ -28,11 +28,11 @@ import { EnginesTable } from './engines_table';
import './engines_overview.scss';
interface IGetEnginesParams {
interface GetEnginesParams {
type: string;
pageIndex: number;
}
interface ISetEnginesCallbacks {
interface SetEnginesCallbacks {
setResults: React.Dispatch<React.SetStateAction<never[]>>;
setResultsTotal: React.Dispatch<React.SetStateAction<number>>;
}
@ -49,12 +49,12 @@ export const EnginesOverview: React.FC = () => {
const [metaEnginesPage, setMetaEnginesPage] = useState(1);
const [metaEnginesTotal, setMetaEnginesTotal] = useState(0);
const getEnginesData = async ({ type, pageIndex }: IGetEnginesParams) => {
const getEnginesData = async ({ type, pageIndex }: GetEnginesParams) => {
return await http.get('/api/app_search/engines', {
query: { type, pageIndex },
});
};
const setEnginesData = async (params: IGetEnginesParams, callbacks: ISetEnginesCallbacks) => {
const setEnginesData = async (params: GetEnginesParams, callbacks: SetEnginesCallbacks) => {
const response = await getEnginesData(params);
callbacks.setResults(response.results);

View file

@ -16,28 +16,28 @@ import { getEngineRoute } from '../../routes';
import { ENGINES_PAGE_SIZE } from '../../../../../common/constants';
interface IEnginesTableData {
interface EnginesTableData {
name: string;
created_at: string;
document_count: number;
field_count: number;
}
interface IEnginesTablePagination {
interface EnginesTablePagination {
totalEngines: number;
pageIndex: number;
onPaginate(pageIndex: number): void;
}
interface IEnginesTableProps {
data: IEnginesTableData[];
pagination: IEnginesTablePagination;
interface EnginesTableProps {
data: EnginesTableData[];
pagination: EnginesTablePagination;
}
interface IOnChange {
interface OnChange {
page: {
index: number;
};
}
export const EnginesTable: React.FC<IEnginesTableProps> = ({
export const EnginesTable: React.FC<EnginesTableProps> = ({
data,
pagination: { totalEngines, pageIndex, onPaginate },
}) => {
@ -52,7 +52,7 @@ export const EnginesTable: React.FC<IEnginesTableProps> = ({
}),
});
const columns: Array<EuiBasicTableColumn<IEnginesTableData>> = [
const columns: Array<EuiBasicTableColumn<EnginesTableData>> = [
{
field: 'name',
name: i18n.translate('xpack.enterpriseSearch.appSearch.enginesOverview.table.column.name', {
@ -144,7 +144,7 @@ export const EnginesTable: React.FC<IEnginesTableProps> = ({
totalItemCount: totalEngines,
hidePerPageOptions: true,
}}
onChange={({ page }: IOnChange) => {
onChange={({ page }: OnChange) => {
const { index } = page;
onPaginate(index + 1); // Note on paging - App Search's API pages start at 1, EuiBasicTables' pages start at 0
}}

View file

@ -17,7 +17,7 @@ jest.mock('../../../../shared/flash_messages', () => ({
}));
import { flashAPIErrors } from '../../../../shared/flash_messages';
import { ELogRetentionOptions } from './types';
import { LogRetentionOptions } from './types';
import { LogRetentionLogic } from './log_retention_logic';
describe('LogRetentionLogic', () => {
@ -87,11 +87,11 @@ describe('LogRetentionLogic', () => {
it('should be set to the provided value', () => {
mount();
LogRetentionLogic.actions.setOpenedModal(ELogRetentionOptions.Analytics);
LogRetentionLogic.actions.setOpenedModal(LogRetentionOptions.Analytics);
expect(LogRetentionLogic.values).toEqual({
...DEFAULT_VALUES,
openedModal: ELogRetentionOptions.Analytics,
openedModal: LogRetentionOptions.Analytics,
});
});
});
@ -194,10 +194,10 @@ describe('LogRetentionLogic', () => {
describe('openedModal', () => {
it('should be reset to null', () => {
mount({
openedModal: ELogRetentionOptions.Analytics,
openedModal: LogRetentionOptions.Analytics,
});
LogRetentionLogic.actions.saveLogRetention(ELogRetentionOptions.Analytics, true);
LogRetentionLogic.actions.saveLogRetention(LogRetentionOptions.Analytics, true);
expect(LogRetentionLogic.values).toEqual({
...DEFAULT_VALUES,
@ -211,7 +211,7 @@ describe('LogRetentionLogic', () => {
const promise = Promise.resolve(TYPICAL_SERVER_LOG_RETENTION);
http.put.mockReturnValue(promise);
LogRetentionLogic.actions.saveLogRetention(ELogRetentionOptions.Analytics, true);
LogRetentionLogic.actions.saveLogRetention(LogRetentionOptions.Analytics, true);
expect(http.put).toHaveBeenCalledWith('/api/app_search/log_settings', {
body: JSON.stringify({
@ -233,7 +233,7 @@ describe('LogRetentionLogic', () => {
const promise = Promise.reject('An error occured');
http.put.mockReturnValue(promise);
LogRetentionLogic.actions.saveLogRetention(ELogRetentionOptions.Analytics, true);
LogRetentionLogic.actions.saveLogRetention(LogRetentionOptions.Analytics, true);
try {
await promise;
@ -252,7 +252,7 @@ describe('LogRetentionLogic', () => {
isLogRetentionUpdating: false,
});
LogRetentionLogic.actions.toggleLogRetention(ELogRetentionOptions.Analytics);
LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.Analytics);
expect(LogRetentionLogic.values).toEqual({
...DEFAULT_VALUES,
@ -264,17 +264,17 @@ describe('LogRetentionLogic', () => {
it('will call setOpenedModal if already enabled', () => {
mount({
logRetention: {
[ELogRetentionOptions.Analytics]: {
[LogRetentionOptions.Analytics]: {
enabled: true,
},
},
});
jest.spyOn(LogRetentionLogic.actions, 'setOpenedModal');
LogRetentionLogic.actions.toggleLogRetention(ELogRetentionOptions.Analytics);
LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.Analytics);
expect(LogRetentionLogic.actions.setOpenedModal).toHaveBeenCalledWith(
ELogRetentionOptions.Analytics
LogRetentionOptions.Analytics
);
});
});
@ -337,17 +337,17 @@ describe('LogRetentionLogic', () => {
it('will call saveLogRetention if NOT already enabled', () => {
mount({
logRetention: {
[ELogRetentionOptions.Analytics]: {
[LogRetentionOptions.Analytics]: {
enabled: false,
},
},
});
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');
LogRetentionLogic.actions.toggleLogRetention(ELogRetentionOptions.Analytics);
LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.Analytics);
expect(LogRetentionLogic.actions.saveLogRetention).toHaveBeenCalledWith(
ELogRetentionOptions.Analytics,
LogRetentionOptions.Analytics,
true
);
});
@ -359,7 +359,7 @@ describe('LogRetentionLogic', () => {
jest.spyOn(LogRetentionLogic.actions, 'saveLogRetention');
jest.spyOn(LogRetentionLogic.actions, 'setOpenedModal');
LogRetentionLogic.actions.toggleLogRetention(ELogRetentionOptions.API);
LogRetentionLogic.actions.toggleLogRetention(LogRetentionOptions.API);
expect(LogRetentionLogic.actions.saveLogRetention).not.toHaveBeenCalled();
expect(LogRetentionLogic.actions.setOpenedModal).not.toHaveBeenCalled();

View file

@ -6,31 +6,31 @@
import { kea, MakeLogicType } from 'kea';
import { ELogRetentionOptions, ILogRetention, ILogRetentionServer } from './types';
import { LogRetentionOptions, LogRetention, LogRetentionServer } from './types';
import { HttpLogic } from '../../../../shared/http';
import { flashAPIErrors } from '../../../../shared/flash_messages';
import { convertLogRetentionFromServerToClient } from './utils/convert_log_retention';
interface ILogRetentionActions {
interface LogRetentionActions {
clearLogRetentionUpdating(): { value: boolean };
closeModals(): { value: boolean };
fetchLogRetention(): { value: boolean };
saveLogRetention(
option: ELogRetentionOptions,
option: LogRetentionOptions,
enabled: boolean
): { option: ELogRetentionOptions; enabled: boolean };
setOpenedModal(option: ELogRetentionOptions): { option: ELogRetentionOptions };
toggleLogRetention(option: ELogRetentionOptions): { option: ELogRetentionOptions };
updateLogRetention(logRetention: ILogRetention): { logRetention: ILogRetention };
): { option: LogRetentionOptions; enabled: boolean };
setOpenedModal(option: LogRetentionOptions): { option: LogRetentionOptions };
toggleLogRetention(option: LogRetentionOptions): { option: LogRetentionOptions };
updateLogRetention(logRetention: LogRetention): { logRetention: LogRetention };
}
interface ILogRetentionValues {
logRetention: ILogRetention | null;
interface LogRetentionValues {
logRetention: LogRetention | null;
isLogRetentionUpdating: boolean;
openedModal: ELogRetentionOptions | null;
openedModal: LogRetentionOptions | null;
}
export const LogRetentionLogic = kea<MakeLogicType<ILogRetentionValues, ILogRetentionActions>>({
export const LogRetentionLogic = kea<MakeLogicType<LogRetentionValues, LogRetentionActions>>({
path: ['enterprise_search', 'app_search', 'log_retention_logic'],
actions: () => ({
clearLogRetentionUpdating: true,
@ -72,7 +72,7 @@ export const LogRetentionLogic = kea<MakeLogicType<ILogRetentionValues, ILogRete
const { http } = HttpLogic.values;
const response = await http.get('/api/app_search/log_settings');
actions.updateLogRetention(
convertLogRetentionFromServerToClient(response as ILogRetentionServer)
convertLogRetentionFromServerToClient(response as LogRetentionServer)
);
} catch (e) {
flashAPIErrors(e);
@ -89,7 +89,7 @@ export const LogRetentionLogic = kea<MakeLogicType<ILogRetentionValues, ILogRete
body: JSON.stringify(updateData),
});
actions.updateLogRetention(
convertLogRetentionFromServerToClient(response as ILogRetentionServer)
convertLogRetentionFromServerToClient(response as LogRetentionServer)
);
} catch (e) {
flashAPIErrors(e);

View file

@ -4,39 +4,39 @@
* you may not use this file except in compliance with the Elastic License.
*/
export enum ELogRetentionOptions {
export enum LogRetentionOptions {
Analytics = 'analytics',
API = 'api',
}
export interface ILogRetention {
[ELogRetentionOptions.Analytics]: ILogRetentionSettings;
[ELogRetentionOptions.API]: ILogRetentionSettings;
export interface LogRetention {
[LogRetentionOptions.Analytics]: LogRetentionSettings;
[LogRetentionOptions.API]: LogRetentionSettings;
}
export interface ILogRetentionPolicy {
export interface LogRetentionPolicy {
isDefault: boolean;
minAgeDays: number | null;
}
export interface ILogRetentionSettings {
export interface LogRetentionSettings {
disabledAt?: string | null;
enabled?: boolean;
retentionPolicy?: ILogRetentionPolicy | null;
retentionPolicy?: LogRetentionPolicy | null;
}
export interface ILogRetentionServer {
[ELogRetentionOptions.Analytics]: ILogRetentionServerSettings;
[ELogRetentionOptions.API]: ILogRetentionServerSettings;
export interface LogRetentionServer {
[LogRetentionOptions.Analytics]: LogRetentionServerSettings;
[LogRetentionOptions.API]: LogRetentionServerSettings;
}
export interface ILogRetentionServerPolicy {
export interface LogRetentionServerPolicy {
is_default: boolean;
min_age_days: number | null;
}
export interface ILogRetentionServerSettings {
export interface LogRetentionServerSettings {
disabled_at: string | null;
enabled: boolean;
retention_policy: ILogRetentionServerPolicy | null;
retention_policy: LogRetentionServerPolicy | null;
}

View file

@ -5,23 +5,23 @@
*/
import {
ELogRetentionOptions,
ILogRetention,
ILogRetentionPolicy,
ILogRetentionServer,
ILogRetentionServerPolicy,
ILogRetentionServerSettings,
ILogRetentionSettings,
LogRetentionOptions,
LogRetention,
LogRetentionPolicy,
LogRetentionServer,
LogRetentionServerPolicy,
LogRetentionServerSettings,
LogRetentionSettings,
} from '../types';
export const convertLogRetentionFromServerToClient = (
logRetention: ILogRetentionServer
): ILogRetention => ({
[ELogRetentionOptions.Analytics]: convertLogRetentionSettingsFromServerToClient(
logRetention[ELogRetentionOptions.Analytics]
logRetention: LogRetentionServer
): LogRetention => ({
[LogRetentionOptions.Analytics]: convertLogRetentionSettingsFromServerToClient(
logRetention[LogRetentionOptions.Analytics]
),
[ELogRetentionOptions.API]: convertLogRetentionSettingsFromServerToClient(
logRetention[ELogRetentionOptions.API]
[LogRetentionOptions.API]: convertLogRetentionSettingsFromServerToClient(
logRetention[LogRetentionOptions.API]
),
});
@ -29,7 +29,7 @@ const convertLogRetentionSettingsFromServerToClient = ({
disabled_at: disabledAt,
enabled,
retention_policy: retentionPolicy,
}: ILogRetentionServerSettings): ILogRetentionSettings => ({
}: LogRetentionServerSettings): LogRetentionSettings => ({
disabledAt,
enabled,
retentionPolicy:
@ -39,7 +39,7 @@ const convertLogRetentionSettingsFromServerToClient = ({
const convertLogRetentionPolicyFromServerToClient = ({
min_age_days: minAgeDays,
is_default: isDefault,
}: ILogRetentionServerPolicy): ILogRetentionPolicy => ({
}: LogRetentionServerPolicy): LogRetentionPolicy => ({
isDefault,
minAgeDays,
});

View file

@ -12,7 +12,7 @@ import { getAppSearchUrl } from '../shared/enterprise_search_url';
import { KibanaLogic } from '../shared/kibana';
import { HttpLogic } from '../shared/http';
import { AppLogic } from './app_logic';
import { IInitialAppData } from '../../../common/types';
import { InitialAppData } from '../../../common/types';
import { APP_SEARCH_PLUGIN } from '../../../common/constants';
import { Layout, SideNav, SideNavLink } from '../shared/layout';
@ -36,7 +36,7 @@ import { Settings, SETTINGS_TITLE } from './components/settings';
import { Credentials, CREDENTIALS_TITLE } from './components/credentials';
import { ROLE_MAPPINGS_TITLE } from './components/role_mappings';
export const AppSearch: React.FC<IInitialAppData> = (props) => {
export const AppSearch: React.FC<InitialAppData> = (props) => {
const { config } = useValues(KibanaLogic);
return !config.host ? <AppSearchUnconfigured /> : <AppSearchConfigured {...props} />;
};
@ -52,7 +52,7 @@ export const AppSearchUnconfigured: React.FC = () => (
</Switch>
);
export const AppSearchConfigured: React.FC<IInitialAppData> = (props) => {
export const AppSearchConfigured: React.FC<InitialAppData> = (props) => {
const { initializeAppData } = useActions(AppLogic);
const { hasInitialized } = useValues(AppLogic);
const { errorConnecting, readOnlyMode } = useValues(HttpLogic);
@ -100,11 +100,11 @@ export const AppSearchConfigured: React.FC<IInitialAppData> = (props) => {
);
};
interface IAppSearchNavProps {
interface AppSearchNavProps {
subNav?: React.ReactNode;
}
export const AppSearchNav: React.FC<IAppSearchNavProps> = ({ subNav }) => {
export const AppSearchNav: React.FC<AppSearchNavProps> = ({ subNav }) => {
const {
myRole: { canViewSettings, canViewAccountCredentials, canViewRoleMappings },
} = useValues(AppLogic);

View file

@ -5,9 +5,9 @@
*/
export * from '../../../common/types/app_search';
export { IRole, TRole, TAbility } from './utils/role';
export { Role, RoleTypes, AbilityTypes } from './utils/role';
export interface IEngine {
export interface Engine {
name: string;
type: string;
language: string;

View file

@ -4,18 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IAccount } from '../../types';
import { Account } from '../../types';
export type TRole = 'owner' | 'admin' | 'dev' | 'editor' | 'analyst';
export type TAbility = 'manage' | 'edit' | 'view';
export type RoleTypes = 'owner' | 'admin' | 'dev' | 'editor' | 'analyst';
export type AbilityTypes = 'manage' | 'edit' | 'view';
export interface IRole {
export interface Role {
id: string;
roleType: TRole;
availableRoleTypes: TRole[];
roleType: RoleTypes;
availableRoleTypes: RoleTypes[];
credentialTypes: string[];
canAccessAllEngines: boolean;
can(action: TAbility, subject: string): boolean;
can(action: AbilityTypes, subject: string): boolean;
canViewMetaEngines: boolean;
canViewAccountCredentials: boolean;
canViewEngineAnalytics: boolean;
@ -48,10 +48,10 @@ export interface IRole {
* Transforms the `role` data we receive from the Enterprise Search
* server into a more convenient format for front-end use
*/
export const getRoleAbilities = (role: IAccount['role']): IRole => {
export const getRoleAbilities = (role: Account['role']): Role => {
// Role ability function helpers
const myRole = {
can: (action: TAbility, subject: string): boolean => {
can: (action: AbilityTypes, subject: string): boolean => {
return (
role?.ability?.manage?.includes(subject) ||
(Array.isArray(role.ability[action]) && role.ability[action].includes(subject))
@ -63,8 +63,8 @@ export const getRoleAbilities = (role: IAccount['role']): IRole => {
// Clone top-level role props, and move some props out of `ability` and into the top-level for convenience
const topLevelProps = {
id: role.id,
roleType: role.roleType as TRole,
availableRoleTypes: role.ability.availableRoleTypes as TRole[],
roleType: role.roleType as RoleTypes,
availableRoleTypes: role.ability.availableRoleTypes as RoleTypes[],
credentialTypes: role.ability.credentialTypes,
};

View file

@ -16,7 +16,7 @@ import { KibanaLogic } from '../../../shared/kibana';
import './product_card.scss';
interface IProductCard {
interface ProductCardProps {
// Expects product plugin constants (@see common/constants.ts)
product: {
ID: string;
@ -27,7 +27,7 @@ interface IProductCard {
image: string;
}
export const ProductCard: React.FC<IProductCard> = ({ product, image }) => {
export const ProductCard: React.FC<ProductCardProps> = ({ product, image }) => {
const { sendEnterpriseSearchTelemetry } = useActions(TelemetryLogic);
const { config } = useValues(KibanaLogic);

View file

@ -30,14 +30,14 @@ import { SetupGuideCta } from '../setup_guide';
import AppSearchImage from '../../assets/app_search.png';
import WorkplaceSearchImage from '../../assets/workplace_search.png';
interface IProductSelectorProps {
interface ProductSelectorProps {
access: {
hasAppSearchAccess?: boolean;
hasWorkplaceSearchAccess?: boolean;
};
}
export const ProductSelector: React.FC<IProductSelectorProps> = ({ access }) => {
export const ProductSelector: React.FC<ProductSelectorProps> = ({ access }) => {
const { hasAppSearchAccess, hasWorkplaceSearchAccess } = access;
const { config } = useValues(KibanaLogic);

View file

@ -9,7 +9,7 @@ import { Route, Switch } from 'react-router-dom';
import { useValues } from 'kea';
import { KibanaLogic } from '../shared/kibana';
import { IInitialAppData } from '../../../common/types';
import { InitialAppData } from '../../../common/types';
import { HttpLogic } from '../shared/http';
@ -21,7 +21,7 @@ import { SetupGuide } from './components/setup_guide';
import './index.scss';
export const EnterpriseSearch: React.FC<IInitialAppData> = ({ access = {} }) => {
export const EnterpriseSearch: React.FC<InitialAppData> = ({ access = {} }) => {
const { errorConnecting } = useValues(HttpLogic);
const { config } = useValues(KibanaLogic);

View file

@ -14,7 +14,7 @@ import { I18nProvider } from '@kbn/i18n/react';
import { AppMountParameters, CoreStart } from 'src/core/public';
import { PluginsStart, ClientConfigType, ClientData } from '../plugin';
import { IInitialAppData } from '../../common/types';
import { InitialAppData } from '../../common/types';
import { mountKibanaLogic } from './shared/kibana';
import { mountLicensingLogic } from './shared/licensing';
@ -29,7 +29,7 @@ import { externalUrl } from './shared/enterprise_search_url';
*/
export const renderApp = (
App: React.FC<IInitialAppData>,
App: React.FC<InitialAppData>,
{ params, core, plugins }: { params: AppMountParameters; core: CoreStart; plugins: PluginsStart },
{ config, data }: { config: ClientConfigType; data: ClientData }
) => {

View file

@ -15,12 +15,12 @@ export interface IFlashMessage {
description?: ReactNode;
}
export interface IFlashMessagesValues {
interface FlashMessagesValues {
messages: IFlashMessage[];
queuedMessages: IFlashMessage[];
historyListener: Function | null;
}
export interface IFlashMessagesActions {
interface FlashMessagesActions {
setFlashMessages(messages: IFlashMessage | IFlashMessage[]): { messages: IFlashMessage[] };
clearFlashMessages(): void;
setQueuedMessages(messages: IFlashMessage | IFlashMessage[]): { messages: IFlashMessage[] };
@ -31,7 +31,7 @@ export interface IFlashMessagesActions {
const convertToArray = (messages: IFlashMessage | IFlashMessage[]) =>
!Array.isArray(messages) ? [messages] : messages;
export const FlashMessagesLogic = kea<MakeLogicType<IFlashMessagesValues, IFlashMessagesActions>>({
export const FlashMessagesLogic = kea<MakeLogicType<FlashMessagesValues, FlashMessagesActions>>({
path: ['enterprise_search', 'flash_messages_logic'],
actions: {
setFlashMessages: (messages) => ({ messages: convertToArray(messages) }),

View file

@ -17,7 +17,7 @@ import { FlashMessagesLogic, IFlashMessage } from './';
* `errors` property in the response's data, which will contain messages we can
* display to the user.
*/
interface IErrorResponse {
interface ErrorResponse {
statusCode: number;
error: string;
message: string;
@ -25,17 +25,14 @@ interface IErrorResponse {
errors: string[];
};
}
interface IOptions {
interface Options {
isQueued?: boolean;
}
/**
* Converts API/HTTP errors into user-facing Flash Messages
*/
export const flashAPIErrors = (
error: HttpResponse<IErrorResponse>,
{ isQueued }: IOptions = {}
) => {
export const flashAPIErrors = (error: HttpResponse<ErrorResponse>, { isQueued }: Options = {}) => {
const defaultErrorMessage = 'An unexpected error occurred';
const errorFlashMessages: IFlashMessage[] = Array.isArray(error?.body?.attributes?.errors)

View file

@ -5,12 +5,6 @@
*/
export { FlashMessages } from './flash_messages';
export {
FlashMessagesLogic,
IFlashMessage,
IFlashMessagesValues,
IFlashMessagesActions,
mountFlashMessagesLogic,
} from './flash_messages_logic';
export { FlashMessagesLogic, IFlashMessage, mountFlashMessagesLogic } from './flash_messages_logic';
export { flashAPIErrors } from './handle_api_errors';
export { setSuccessMessage, setErrorMessage, setQueuedSuccessMessage } from './set_message_helpers';

View file

@ -7,18 +7,18 @@
import React, { useState, ReactElement } from 'react';
import { i18n } from '@kbn/i18n';
interface IChildrenProps {
interface ChildrenProps {
toggle: () => void;
isHidden: boolean;
hiddenText: React.ReactNode;
}
interface IProps {
interface Props {
text: string;
children(props: IChildrenProps): ReactElement;
children(props: ChildrenProps): ReactElement;
}
export const HiddenText: React.FC<IProps> = ({ text, children }) => {
export const HiddenText: React.FC<Props> = ({ text, children }) => {
const [isHidden, toggleIsHidden] = useState(true);
const hiddenLabel = i18n.translate('xpack.enterpriseSearch.hiddenText', {

View file

@ -10,20 +10,20 @@ import { HttpSetup, HttpInterceptorResponseError, HttpResponse } from 'src/core/
import { READ_ONLY_MODE_HEADER } from '../../../../common/constants';
export interface IHttpValues {
interface HttpValues {
http: HttpSetup;
httpInterceptors: Function[];
errorConnecting: boolean;
readOnlyMode: boolean;
}
export interface IHttpActions {
interface HttpActions {
initializeHttpInterceptors(): void;
setHttpInterceptors(httpInterceptors: Function[]): { httpInterceptors: Function[] };
setErrorConnecting(errorConnecting: boolean): { errorConnecting: boolean };
setReadOnlyMode(readOnlyMode: boolean): { readOnlyMode: boolean };
}
export const HttpLogic = kea<MakeLogicType<IHttpValues, IHttpActions>>({
export const HttpLogic = kea<MakeLogicType<HttpValues, HttpActions>>({
path: ['enterprise_search', 'http_logic'],
actions: {
initializeHttpInterceptors: () => null,
@ -108,12 +108,12 @@ export const HttpLogic = kea<MakeLogicType<IHttpValues, IHttpActions>>({
/**
* Mount/props helper
*/
interface IHttpLogicProps {
interface HttpLogicProps {
http: HttpSetup;
errorConnecting?: boolean;
readOnlyMode?: boolean;
}
export const mountHttpLogic = (props: IHttpLogicProps) => {
export const mountHttpLogic = (props: HttpLogicProps) => {
HttpLogic(props);
const unmount = HttpLogic.mount();
return unmount;

View file

@ -4,4 +4,4 @@
* you may not use this file except in compliance with the Elastic License.
*/
export { HttpLogic, IHttpValues, IHttpActions, mountHttpLogic } from './http_logic';
export { HttpLogic, mountHttpLogic } from './http_logic';

View file

@ -11,9 +11,9 @@ import { History } from 'history';
import { ApplicationStart, ChromeBreadcrumb } from 'src/core/public';
import { HttpLogic } from '../http';
import { createHref, ICreateHrefOptions } from '../react_router_helpers';
import { createHref, CreateHrefOptions } from '../react_router_helpers';
interface IKibanaLogicProps {
interface KibanaLogicProps {
config: { host?: string };
history: History;
navigateToUrl: ApplicationStart['navigateToUrl'];
@ -21,17 +21,17 @@ interface IKibanaLogicProps {
setDocTitle(title: string): void;
renderHeaderActions(HeaderActions: FC): void;
}
export interface IKibanaValues extends IKibanaLogicProps {
navigateToUrl(path: string, options?: ICreateHrefOptions): Promise<void>;
export interface KibanaValues extends KibanaLogicProps {
navigateToUrl(path: string, options?: CreateHrefOptions): Promise<void>;
}
export const KibanaLogic = kea<MakeLogicType<IKibanaValues>>({
export const KibanaLogic = kea<MakeLogicType<KibanaValues>>({
path: ['enterprise_search', 'kibana_logic'],
reducers: ({ props }) => ({
config: [props.config || {}, {}],
history: [props.history, {}],
navigateToUrl: [
(url: string, options?: ICreateHrefOptions) => {
(url: string, options?: CreateHrefOptions) => {
const deps = { history: props.history, http: HttpLogic.values.http };
const href = createHref(url, deps, options);
return props.navigateToUrl(href);
@ -44,7 +44,7 @@ export const KibanaLogic = kea<MakeLogicType<IKibanaValues>>({
}),
});
export const mountKibanaLogic = (props: IKibanaLogicProps) => {
export const mountKibanaLogic = (props: KibanaLogicProps) => {
KibanaLogic(props);
const unmount = KibanaLogic.mount();
return unmount;

View file

@ -23,15 +23,15 @@ import { letBrowserHandleEvent, createHref } from '../react_router_helpers';
* Types
*/
interface IBreadcrumb {
interface Breadcrumb {
text: string;
path?: string;
// Used to navigate outside of the React Router basename,
// i.e. if we need to go from App Search to Enterprise Search
shouldNotCreateHref?: boolean;
}
export type TBreadcrumbs = IBreadcrumb[];
export type TBreadcrumbTrail = string[]; // A trail of breadcrumb text
export type Breadcrumbs = Breadcrumb[];
export type BreadcrumbTrail = string[]; // A trail of breadcrumb text
/**
* Generate an array of breadcrumbs based on:
@ -50,7 +50,7 @@ export type TBreadcrumbTrail = string[]; // A trail of breadcrumb text
* > Source Prioritization (linked to `/groups/{example-group-id}/source_prioritization`)
*/
export const useGenerateBreadcrumbs = (trail: TBreadcrumbTrail): TBreadcrumbs => {
export const useGenerateBreadcrumbs = (trail: BreadcrumbTrail): Breadcrumbs => {
const { history } = useValues(KibanaLogic);
const pathArray = stripLeadingSlash(history.location.pathname).split('/');
@ -65,7 +65,7 @@ export const useGenerateBreadcrumbs = (trail: TBreadcrumbTrail): TBreadcrumbs =>
* https://elastic.github.io/eui/#/navigation/breadcrumbs
*/
export const useEuiBreadcrumbs = (breadcrumbs: TBreadcrumbs): EuiBreadcrumb[] => {
export const useEuiBreadcrumbs = (breadcrumbs: Breadcrumbs): EuiBreadcrumb[] => {
const { navigateToUrl, history } = useValues(KibanaLogic);
const { http } = useValues(HttpLogic);
@ -89,7 +89,7 @@ export const useEuiBreadcrumbs = (breadcrumbs: TBreadcrumbs): EuiBreadcrumb[] =>
* Product-specific breadcrumb helpers
*/
export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) =>
export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useEuiBreadcrumbs([
{
text: ENTERPRISE_SEARCH_PLUGIN.NAME,
@ -99,10 +99,10 @@ export const useEnterpriseSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) =
...breadcrumbs,
]);
export const useAppSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) =>
export const useAppSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useEnterpriseSearchBreadcrumbs([{ text: APP_SEARCH_PLUGIN.NAME, path: '/' }, ...breadcrumbs]);
export const useWorkplaceSearchBreadcrumbs = (breadcrumbs: TBreadcrumbs = []) =>
export const useWorkplaceSearchBreadcrumbs = (breadcrumbs: Breadcrumbs = []) =>
useEnterpriseSearchBreadcrumbs([
{ text: WORKPLACE_SEARCH_PLUGIN.NAME, path: '/' },
...breadcrumbs,

View file

@ -15,24 +15,24 @@ import {
* https://github.com/elastic/kibana/blob/master/docs/development/core/public/kibana-plugin-core-public.chromedoctitle.md
*/
export type TTitle = string[];
type Title = string[];
/**
* Given an array of page titles, return a final formatted document title
* @param pages - e.g., ['Curations', 'some Engine', 'App Search']
* @returns - e.g., 'Curations - some Engine - App Search'
*/
export const generateTitle = (pages: TTitle) => pages.join(' - ');
export const generateTitle = (pages: Title) => pages.join(' - ');
/**
* Product-specific helpers
*/
export const enterpriseSearchTitle = (page: TTitle = []) =>
export const enterpriseSearchTitle = (page: Title = []) =>
generateTitle([...page, ENTERPRISE_SEARCH_PLUGIN.NAME]);
export const appSearchTitle = (page: TTitle = []) =>
export const appSearchTitle = (page: Title = []) =>
generateTitle([...page, APP_SEARCH_PLUGIN.NAME]);
export const workplaceSearchTitle = (page: TTitle = []) =>
export const workplaceSearchTitle = (page: Title = []) =>
generateTitle([...page, WORKPLACE_SEARCH_PLUGIN.NAME]);

View file

@ -14,7 +14,7 @@ import {
useEnterpriseSearchBreadcrumbs,
useAppSearchBreadcrumbs,
useWorkplaceSearchBreadcrumbs,
TBreadcrumbTrail,
BreadcrumbTrail,
} from './generate_breadcrumbs';
import { enterpriseSearchTitle, appSearchTitle, workplaceSearchTitle } from './generate_title';
@ -33,11 +33,11 @@ import { enterpriseSearchTitle, appSearchTitle, workplaceSearchTitle } from './g
* Title output: Workplace Search - Elastic
*/
interface ISetChromeProps {
trail?: TBreadcrumbTrail;
interface SetChromeProps {
trail?: BreadcrumbTrail;
}
export const SetEnterpriseSearchChrome: React.FC<ISetChromeProps> = ({ trail = [] }) => {
export const SetEnterpriseSearchChrome: React.FC<SetChromeProps> = ({ trail = [] }) => {
const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic);
const title = reverseArray(trail);
@ -54,7 +54,7 @@ export const SetEnterpriseSearchChrome: React.FC<ISetChromeProps> = ({ trail = [
return null;
};
export const SetAppSearchChrome: React.FC<ISetChromeProps> = ({ trail = [] }) => {
export const SetAppSearchChrome: React.FC<SetChromeProps> = ({ trail = [] }) => {
const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic);
const title = reverseArray(trail);
@ -71,7 +71,7 @@ export const SetAppSearchChrome: React.FC<ISetChromeProps> = ({ trail = [] }) =>
return null;
};
export const SetWorkplaceSearchChrome: React.FC<ISetChromeProps> = ({ trail = [] }) => {
export const SetWorkplaceSearchChrome: React.FC<SetChromeProps> = ({ trail = [] }) => {
const { setBreadcrumbs, setDocTitle } = useValues(KibanaLogic);
const title = reverseArray(trail);

View file

@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n';
import './layout.scss';
interface ILayoutProps {
interface LayoutProps {
navigation: React.ReactNode;
restrictWidth?: boolean;
readOnlyMode?: boolean;
@ -23,7 +23,7 @@ export interface INavContext {
}
export const NavContext = React.createContext({});
export const Layout: React.FC<ILayoutProps> = ({
export const Layout: React.FC<LayoutProps> = ({
children,
navigation,
restrictWidth,

View file

@ -23,7 +23,7 @@ import './side_nav.scss';
* Side navigation - product & icon + links wrapper
*/
interface ISideNavProps {
interface SideNavProps {
// Expects product plugin constants (@see common/constants.ts)
product: {
NAME: string;
@ -31,7 +31,7 @@ interface ISideNavProps {
};
}
export const SideNav: React.FC<ISideNavProps> = ({ product, children }) => {
export const SideNav: React.FC<SideNavProps> = ({ product, children }) => {
return (
<nav
id="enterpriseSearchNav"
@ -61,7 +61,7 @@ export const SideNav: React.FC<ISideNavProps> = ({ product, children }) => {
* Side navigation link item
*/
interface ISideNavLinkProps {
interface SideNavLinkProps {
to: string;
isExternal?: boolean;
className?: string;
@ -69,7 +69,7 @@ interface ISideNavLinkProps {
subNav?: React.ReactNode;
}
export const SideNavLink: React.FC<ISideNavLinkProps> = ({
export const SideNavLink: React.FC<SideNavLinkProps> = ({
isExternal,
to,
children,
@ -114,11 +114,11 @@ export const SideNavLink: React.FC<ISideNavLinkProps> = ({
* Side navigation non-link item
*/
interface ISideNavItemProps {
interface SideNavItemProps {
className?: string;
}
export const SideNavItem: React.FC<ISideNavItemProps> = ({ children, className, ...rest }) => {
export const SideNavItem: React.FC<SideNavItemProps> = ({ children, className, ...rest }) => {
const classes = classNames('enterpriseSearchNavLinks__item', className);
return (
<li {...rest} className={classes}>

View file

@ -9,18 +9,18 @@ import { Observable, Subscription } from 'rxjs';
import { ILicense } from '../../../../../licensing/public';
export interface ILicensingValues {
interface LicensingValues {
license: ILicense | null;
licenseSubscription: Subscription | null;
hasPlatinumLicense: boolean;
hasGoldLicense: boolean;
}
export interface ILicensingActions {
interface LicensingActions {
setLicense(license: ILicense): ILicense;
setLicenseSubscription(licenseSubscription: Subscription): Subscription;
}
export const LicensingLogic = kea<MakeLogicType<ILicensingValues, ILicensingActions>>({
export const LicensingLogic = kea<MakeLogicType<LicensingValues, LicensingActions>>({
path: ['enterprise_search', 'licensing_logic'],
actions: {
setLicense: (license) => license,
@ -72,10 +72,10 @@ export const LicensingLogic = kea<MakeLogicType<ILicensingValues, ILicensingActi
/**
* Mount/props helper
*/
interface ILicensingLogicProps {
interface LicensingLogicProps {
license$: Observable<ILicense>;
}
export const mountLicensingLogic = (props: ILicensingLogicProps) => {
export const mountLicensingLogic = (props: LicensingLogicProps) => {
LicensingLogic(props);
const unmount = LicensingLogic.mount();
return unmount;

View file

@ -22,18 +22,18 @@ import { HttpSetup } from 'src/core/public';
*
* Links completely outside of Kibana should not use our React Router helpers or navigateToUrl.
*/
interface ICreateHrefDeps {
interface CreateHrefDeps {
history: History;
http: HttpSetup;
}
export interface ICreateHrefOptions {
export interface CreateHrefOptions {
shouldNotCreateHref?: boolean;
}
export const createHref = (
path: string,
{ history, http }: ICreateHrefDeps,
{ shouldNotCreateHref }: ICreateHrefOptions = {}
{ history, http }: CreateHrefDeps,
{ shouldNotCreateHref }: CreateHrefOptions = {}
): string => {
return shouldNotCreateHref ? http.basePath.prepend(path) : history.createHref({ pathname: path });
};

View file

@ -20,7 +20,7 @@ import { letBrowserHandleEvent, createHref } from './';
* https://github.com/elastic/eui/blob/master/wiki/react-router.md#react-router-51
*/
interface IEuiReactRouterProps {
interface EuiReactRouterProps {
to: string;
onClick?(): void;
// Used to navigate outside of the React Router plugin basename but still within Kibana,
@ -28,7 +28,7 @@ interface IEuiReactRouterProps {
shouldNotCreateHref?: boolean;
}
export const EuiReactRouterHelper: React.FC<IEuiReactRouterProps> = ({
export const EuiReactRouterHelper: React.FC<EuiReactRouterProps> = ({
to,
onClick,
shouldNotCreateHref,
@ -59,8 +59,8 @@ export const EuiReactRouterHelper: React.FC<IEuiReactRouterProps> = ({
* Component helpers
*/
type TEuiReactRouterLinkProps = EuiLinkAnchorProps & IEuiReactRouterProps;
export const EuiReactRouterLink: React.FC<TEuiReactRouterLinkProps> = ({
type EuiReactRouterLinkProps = EuiLinkAnchorProps & EuiReactRouterProps;
export const EuiReactRouterLink: React.FC<EuiReactRouterLinkProps> = ({
to,
onClick,
shouldNotCreateHref,
@ -71,8 +71,8 @@ export const EuiReactRouterLink: React.FC<TEuiReactRouterLinkProps> = ({
</EuiReactRouterHelper>
);
type TEuiReactRouterButtonProps = EuiButtonProps & IEuiReactRouterProps;
export const EuiReactRouterButton: React.FC<TEuiReactRouterButtonProps> = ({
type EuiReactRouterButtonProps = EuiButtonProps & EuiReactRouterProps;
export const EuiReactRouterButton: React.FC<EuiReactRouterButtonProps> = ({
to,
onClick,
shouldNotCreateHref,
@ -83,8 +83,8 @@ export const EuiReactRouterButton: React.FC<TEuiReactRouterButtonProps> = ({
</EuiReactRouterHelper>
);
type TEuiReactRouterPanelProps = EuiPanelProps & IEuiReactRouterProps;
export const EuiReactRouterPanel: React.FC<TEuiReactRouterPanelProps> = ({
type EuiReactRouterPanelProps = EuiPanelProps & EuiReactRouterProps;
export const EuiReactRouterPanel: React.FC<EuiReactRouterPanelProps> = ({
to,
onClick,
shouldNotCreateHref,

View file

@ -5,7 +5,7 @@
*/
export { letBrowserHandleEvent } from './link_events';
export { createHref, ICreateHrefOptions } from './create_href';
export { createHref, CreateHrefOptions } from './create_href';
export {
EuiReactRouterLink as EuiLink,
EuiReactRouterButton as EuiButton,

View file

@ -11,20 +11,20 @@ import { MouseEvent } from 'react';
* let browsers handle natively, e.g. new tabs/windows
*/
type THandleEvent = (event: MouseEvent) => boolean;
type HandleEvent = (event: MouseEvent) => boolean;
export const letBrowserHandleEvent: THandleEvent = (event) =>
export const letBrowserHandleEvent: HandleEvent = (event) =>
event.defaultPrevented ||
isModifiedEvent(event) ||
!isLeftClickEvent(event) ||
isTargetBlank(event);
const isModifiedEvent: THandleEvent = (event) =>
const isModifiedEvent: HandleEvent = (event) =>
!!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
const isLeftClickEvent: THandleEvent = (event) => event.button === 0;
const isLeftClickEvent: HandleEvent = (event) => event.button === 0;
const isTargetBlank: THandleEvent = (event) => {
const isTargetBlank: HandleEvent = (event) => {
const element = event.target as HTMLElement;
const target = element.getAttribute('target');
return !!target && target !== '_self';

View file

@ -32,7 +32,7 @@ import './setup_guide.scss';
* customizable, but the basic layout and instruction steps are DRYed out
*/
interface ISetupGuideProps {
interface SetupGuideProps {
children: React.ReactNode;
productName: string;
productEuiIcon: 'logoAppSearch' | 'logoWorkplaceSearch' | 'logoEnterpriseSearch';
@ -40,7 +40,7 @@ interface ISetupGuideProps {
elasticsearchNativeAuthLink?: string;
}
export const SetupGuide: React.FC<ISetupGuideProps> = ({
export const SetupGuide: React.FC<SetupGuideProps> = ({
children,
productName,
productEuiIcon,

View file

@ -8,12 +8,12 @@ import React from 'react';
import { EuiTableHeader, EuiTableHeaderCell } from '@elastic/eui';
interface ITableHeaderProps {
interface TableHeaderProps {
headerItems: string[];
extraCell?: boolean;
}
export const TableHeader: React.FC<ITableHeaderProps> = ({ headerItems, extraCell }) => (
export const TableHeader: React.FC<TableHeaderProps> = ({ headerItems, extraCell }) => (
<EuiTableHeader>
{headerItems.map((item, i) => (
<EuiTableHeaderCell key={i}>{item}</EuiTableHeaderCell>

View file

@ -7,13 +7,16 @@
import React, { useEffect } from 'react';
import { useActions } from 'kea';
import { TelemetryLogic, TSendTelemetry } from './telemetry_logic';
import { TelemetryLogic, SendTelemetryHelper } from './telemetry_logic';
/**
* React component helpers - useful for on-page-load/views
*/
export const SendEnterpriseSearchTelemetry: React.FC<TSendTelemetry> = ({ action, metric }) => {
export const SendEnterpriseSearchTelemetry: React.FC<SendTelemetryHelper> = ({
action,
metric,
}) => {
const { sendTelemetry } = useActions(TelemetryLogic);
useEffect(() => {
@ -23,7 +26,7 @@ export const SendEnterpriseSearchTelemetry: React.FC<TSendTelemetry> = ({ action
return null;
};
export const SendAppSearchTelemetry: React.FC<TSendTelemetry> = ({ action, metric }) => {
export const SendAppSearchTelemetry: React.FC<SendTelemetryHelper> = ({ action, metric }) => {
const { sendTelemetry } = useActions(TelemetryLogic);
useEffect(() => {
@ -33,7 +36,7 @@ export const SendAppSearchTelemetry: React.FC<TSendTelemetry> = ({ action, metri
return null;
};
export const SendWorkplaceSearchTelemetry: React.FC<TSendTelemetry> = ({ action, metric }) => {
export const SendWorkplaceSearchTelemetry: React.FC<SendTelemetryHelper> = ({ action, metric }) => {
const { sendTelemetry } = useActions(TelemetryLogic);
useEffect(() => {

View file

@ -9,21 +9,21 @@ import { kea, MakeLogicType } from 'kea';
import { JSON_HEADER as headers } from '../../../../common/constants';
import { HttpLogic } from '../http';
export interface ISendTelemetry {
interface SendTelemetry {
action: 'viewed' | 'error' | 'clicked';
metric: string; // e.g., 'setup_guide'
product: 'enterprise_search' | 'app_search' | 'workplace_search';
}
export type TSendTelemetry = Omit<ISendTelemetry, 'product'>;
export type SendTelemetryHelper = Omit<SendTelemetry, 'product'>;
interface ITelemetryActions {
sendTelemetry(args: ISendTelemetry): ISendTelemetry;
sendEnterpriseSearchTelemetry(args: TSendTelemetry): TSendTelemetry;
sendAppSearchTelemetry(args: TSendTelemetry): TSendTelemetry;
sendWorkplaceSearchTelemetry(args: TSendTelemetry): TSendTelemetry;
interface TelemetryActions {
sendTelemetry(args: SendTelemetry): SendTelemetry;
sendEnterpriseSearchTelemetry(args: SendTelemetryHelper): SendTelemetryHelper;
sendAppSearchTelemetry(args: SendTelemetryHelper): SendTelemetryHelper;
sendWorkplaceSearchTelemetry(args: SendTelemetryHelper): SendTelemetryHelper;
}
export const TelemetryLogic = kea<MakeLogicType<ITelemetryActions>>({
export const TelemetryLogic = kea<MakeLogicType<TelemetryActions>>({
path: ['enterprise_search', 'telemetry_logic'],
actions: {
sendTelemetry: ({ action, metric, product }) => ({ action, metric, product }),
@ -32,7 +32,7 @@ export const TelemetryLogic = kea<MakeLogicType<ITelemetryActions>>({
sendWorkplaceSearchTelemetry: ({ action, metric }) => ({ action, metric }),
},
listeners: ({ actions }) => ({
sendTelemetry: async ({ action, metric, product }: ISendTelemetry) => {
sendTelemetry: async ({ action, metric, product }: SendTelemetry) => {
const { http } = HttpLogic.values;
try {
const body = JSON.stringify({ product, action, metric });
@ -41,11 +41,11 @@ export const TelemetryLogic = kea<MakeLogicType<ITelemetryActions>>({
throw new Error('Unable to send telemetry');
}
},
sendEnterpriseSearchTelemetry: ({ action, metric }: TSendTelemetry) =>
sendEnterpriseSearchTelemetry: ({ action, metric }: SendTelemetryHelper) =>
actions.sendTelemetry({ action, metric, product: 'enterprise_search' }),
sendAppSearchTelemetry: ({ action, metric }: TSendTelemetry) =>
sendAppSearchTelemetry: ({ action, metric }: SendTelemetryHelper) =>
actions.sendTelemetry({ action, metric, product: 'app_search' }),
sendWorkplaceSearchTelemetry: ({ action, metric }: TSendTelemetry) =>
sendWorkplaceSearchTelemetry: ({ action, metric }: SendTelemetryHelper) =>
actions.sendTelemetry({ action, metric, product: 'workplace_search' }),
}),
});

View file

@ -10,14 +10,14 @@ import { truncate, truncateBeginning } from './';
import './truncated_content.scss';
interface ITruncatedContentProps {
interface TruncatedContentProps {
content: string;
length: number;
beginning?: boolean;
tooltipType?: 'inline' | 'title';
}
export const TruncatedContent: React.FC<ITruncatedContentProps> = ({
export const TruncatedContent: React.FC<TruncatedContentProps> = ({
content,
length,
beginning = false,

View file

@ -1,7 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
export { IFlashMessage } from './flash_messages';

View file

@ -6,25 +6,25 @@
import { kea, MakeLogicType } from 'kea';
import { IInitialAppData } from '../../../common/types';
import { InitialAppData } from '../../../common/types';
import {
IOrganization,
IWorkplaceSearchInitialData,
IAccount,
Organization,
WorkplaceSearchInitialData,
Account,
} from '../../../common/types/workplace_search';
export interface IAppValues extends IWorkplaceSearchInitialData {
interface AppValues extends WorkplaceSearchInitialData {
hasInitialized: boolean;
isFederatedAuth: boolean;
}
export interface IAppActions {
initializeAppData(props: IInitialAppData): IInitialAppData;
interface AppActions {
initializeAppData(props: InitialAppData): InitialAppData;
}
const emptyOrg = {} as IOrganization;
const emptyAccount = {} as IAccount;
const emptyOrg = {} as Organization;
const emptyAccount = {} as Account;
export const AppLogic = kea<MakeLogicType<IAppValues, IAppActions>>({
export const AppLogic = kea<MakeLogicType<AppValues, AppActions>>({
path: ['enterprise_search', 'workplace_search', 'app_logic'],
actions: {
initializeAppData: ({ workplaceSearch, isFederatedAuth }) => ({

View file

@ -8,12 +8,12 @@ import React from 'react';
import { EuiCodeBlock, EuiFormLabel, EuiSpacer } from '@elastic/eui';
interface IApiKeyProps {
interface ApiKeyProps {
apiKey: string;
label?: string;
}
export const ApiKey: React.FC<IApiKeyProps> = ({ apiKey, label }) => (
export const ApiKey: React.FC<ApiKeyProps> = ({ apiKey, label }) => (
<>
{label && (
<>

View file

@ -8,11 +8,13 @@ import React from 'react';
import { EuiLoadingSpinner, EuiTextColor } from '@elastic/eui';
import { IComponentLoader } from '../../../types';
interface ComponentLoaderProps {
text?: string;
}
import './component_loader.scss';
export const ComponentLoader: React.FC<IComponentLoader> = ({ text = 'Loading...' }) => (
export const ComponentLoader: React.FC<ComponentLoaderProps> = ({ text = 'Loading...' }) => (
<div className="componentLoader">
<EuiLoadingSpinner size="l" />
<EuiTextColor className="componentLoaderText" color="subdued">

View file

@ -8,24 +8,24 @@ import React from 'react';
import { EuiSpacer } from '@elastic/eui';
import { TSpacerSize } from '../../../types';
import { SpacerSizeTypes } from '../../../types';
import { ViewContentHeader } from '../view_content_header';
import './content_section.scss';
interface IContentSectionProps {
interface ContentSectionProps {
children: React.ReactNode;
className?: string;
title?: React.ReactNode;
description?: React.ReactNode;
action?: React.ReactNode;
headerChildren?: React.ReactNode;
headerSpacer?: TSpacerSize;
headerSpacer?: SpacerSizeTypes;
testSubj?: string;
}
export const ContentSection: React.FC<IContentSectionProps> = ({
export const ContentSection: React.FC<ContentSectionProps> = ({
children,
className = '',
title,

View file

@ -19,7 +19,7 @@ import {
EuiToolTip,
} from '@elastic/eui';
interface ICredentialItemProps {
interface CredentialItemProps {
label: string;
value: string;
testSubj: string;
@ -28,7 +28,7 @@ interface ICredentialItemProps {
const inputSelectAll = (e: React.MouseEvent<HTMLInputElement>) => e.currentTarget.select();
export const CredentialItem: React.FC<ICredentialItemProps> = ({
export const CredentialItem: React.FC<CredentialItemProps> = ({
label,
value,
testSubj,

View file

@ -11,7 +11,7 @@ import { EuiSpacer } from '@elastic/eui';
import { ApiKey } from '../api_key';
import { CredentialItem } from '../credential_item';
interface ISourceConfigFieldsProps {
interface SourceConfigFieldsProps {
clientId?: string;
clientSecret?: string;
publicKey?: string;
@ -19,7 +19,7 @@ interface ISourceConfigFieldsProps {
baseUrl?: string;
}
export const SourceConfigFields: React.FC<ISourceConfigFieldsProps> = ({
export const SourceConfigFields: React.FC<SourceConfigFieldsProps> = ({
clientId,
clientSecret,
publicKey,

View file

@ -12,14 +12,14 @@ import _camelCase from 'lodash/camelCase';
import { images } from '../assets';
interface ISourceIconProps {
interface SourceIconProps {
serviceType: string;
name: string;
className?: string;
wrapped?: boolean;
}
export const SourceIcon: React.FC<ISourceIconProps> = ({
export const SourceIcon: React.FC<SourceIconProps> = ({
name,
serviceType,
className,

View file

@ -25,7 +25,7 @@ import {
import { EuiLink } from '../../../../shared/react_router_helpers';
import { SOURCE_STATUSES as statuses } from '../../../constants';
import { IContentSourceDetails } from '../../../types';
import { ContentSourceDetails } from '../../../types';
import { ADD_SOURCE_PATH, SOURCE_DETAILS_PATH, getContentSourcePath } from '../../../routes';
import { SourceIcon } from '../source_icon';
@ -40,11 +40,11 @@ export interface ISourceRow {
onSearchableToggle?(sourceId: string, isSearchable: boolean): void;
}
interface ISourceRowProps extends ISourceRow {
source: IContentSourceDetails;
interface SourceRowProps extends ISourceRow {
source: ContentSourceDetails;
}
export const SourceRow: React.FC<ISourceRowProps> = ({
export const SourceRow: React.FC<SourceRowProps> = ({
source: {
id,
serviceType,

View file

@ -10,13 +10,13 @@ import { EuiTable, EuiTableBody } from '@elastic/eui';
import { TableHeader } from '../../../../shared/table_header/table_header';
import { SourceRow, ISourceRow } from '../source_row';
import { IContentSourceDetails } from '../../../types';
import { ContentSourceDetails } from '../../../types';
interface ISourcesTableProps extends ISourceRow {
sources: IContentSourceDetails[];
interface SourcesTableProps extends ISourceRow {
sources: ContentSourceDetails[];
}
export const SourcesTable: React.FC<ISourcesTableProps> = ({
export const SourcesTable: React.FC<SourcesTableProps> = ({
sources,
showDetails,
isOrganization,

View file

@ -8,7 +8,7 @@ import React from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiTablePagination } from '@elastic/eui';
interface ITablePaginationBarProps {
interface TablePaginationBarProps {
itemLabel?: string;
itemsPerPage?: number;
totalPages: number;
@ -22,7 +22,7 @@ interface ITablePaginationBarProps {
const MAX_PAGES = 100;
export const TablePaginationBar: React.FC<ITablePaginationBarProps> = ({
export const TablePaginationBar: React.FC<TablePaginationBarProps> = ({
itemLabel = 'Items',
itemsPerPage = 10,
totalPages,

View file

@ -6,11 +6,11 @@
import React from 'react';
import { IUser } from '../../../types';
import { User } from '../../../types';
import './user_icon.scss';
export const UserIcon: React.FC<IUser> = ({ name, pictureUrl, color, initials, email }) => (
export const UserIcon: React.FC<User> = ({ name, pictureUrl, color, initials, email }) => (
<div className="user-icon user-icon--small" style={{ backgroundColor: color }}>
{pictureUrl ? (
<img src={pictureUrl} className="avatar__image" alt={name || email} />

View file

@ -8,14 +8,14 @@ import React from 'react';
import { EuiTableRow, EuiTableRowCell } from '@elastic/eui';
import { IUser } from '../../../types';
import { User } from '../../../types';
interface IUserRowProps {
user: IUser;
interface UserRowProps {
user: User;
showEmail?: boolean;
}
export const UserRow: React.FC<IUserRowProps> = ({ user: { name, email }, showEmail }) => (
export const UserRow: React.FC<UserRowProps> = ({ user: { name, email }, showEmail }) => (
<EuiTableRow>
<EuiTableRowCell>{name}</EuiTableRowCell>
<EuiTableRowCell>{showEmail && <span>{email}</span>}</EuiTableRowCell>

View file

@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiSpacer } from '@elasti
import { FlexGroupAlignItems } from '@elastic/eui/src/components/flex/flex_group';
interface IViewContentHeaderProps {
interface ViewContentHeaderProps {
title: React.ReactNode;
description?: React.ReactNode;
action?: React.ReactNode;
@ -18,7 +18,7 @@ interface IViewContentHeaderProps {
titleSize?: 's' | 'm' | 'l';
}
export const ViewContentHeader: React.FC<IViewContentHeaderProps> = ({
export const ViewContentHeader: React.FC<ViewContentHeaderProps> = ({
title,
titleSize = 'm',
description,

View file

@ -9,7 +9,7 @@ import { Route, Redirect, Switch } from 'react-router-dom';
import { useActions, useValues } from 'kea';
import { WORKPLACE_SEARCH_PLUGIN } from '../../../common/constants';
import { IInitialAppData } from '../../../common/types';
import { InitialAppData } from '../../../common/types';
import { KibanaLogic } from '../shared/kibana';
import { HttpLogic } from '../shared/http';
import { AppLogic } from './app_logic';
@ -24,12 +24,12 @@ import { NotFound } from '../shared/not_found';
import { Overview } from './views/overview';
import { GroupsRouter } from './views/groups';
export const WorkplaceSearch: React.FC<IInitialAppData> = (props) => {
export const WorkplaceSearch: React.FC<InitialAppData> = (props) => {
const { config } = useValues(KibanaLogic);
return !config.host ? <WorkplaceSearchUnconfigured /> : <WorkplaceSearchConfigured {...props} />;
};
export const WorkplaceSearchConfigured: React.FC<IInitialAppData> = (props) => {
export const WorkplaceSearchConfigured: React.FC<InitialAppData> = (props) => {
const { hasInitialized } = useValues(AppLogic);
const { initializeAppData } = useActions(AppLogic);
const { renderHeaderActions } = useValues(KibanaLogic);

View file

@ -6,12 +6,54 @@
export * from '../../../common/types/workplace_search';
export type TSpacerSize = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl';
export type SpacerSizeTypes = 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl';
export interface ISourcePriority {
export interface Group {
id: string;
name: string;
createdAt: string;
updatedAt: string;
contentSources: ContentSource[];
users: User[];
usersCount: number;
color?: string;
}
export interface GroupDetails extends Group {
contentSources: ContentSourceDetails[];
canEditGroup: boolean;
canDeleteGroup: boolean;
}
export interface User {
id: string;
name: string | null;
initials: string;
pictureUrl: string | null;
color: string;
email: string;
role?: string;
groupIds: string[];
}
export interface ContentSource {
id: string;
serviceType: string;
name: string;
}
export interface ContentSourceDetails extends ContentSource {
status: string;
statusMessage: string;
documentCount: string;
isFederatedSource: boolean;
searchable: boolean;
supportedByLicense: boolean;
errorReason: number;
allowsReauth: boolean;
boost: number;
}
export interface SourcePriority {
[id: string]: number;
}
export interface IComponentLoader {
text?: string;
}

View file

@ -4,12 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IGroupValues } from '../group_logic';
import { IGroupDetails, ISourcePriority } from '../../../types';
import { GroupDetails, SourcePriority } from '../../../types';
export const mockGroupValues = {
group: {} as IGroupDetails,
group: {} as GroupDetails,
dataLoading: true,
manageUsersModalVisible: false,
managerModalFormErrors: [],
@ -19,6 +17,6 @@ export const mockGroupValues = {
selectedGroupSources: [],
selectedGroupUsers: [],
groupPrioritiesUnchanged: true,
activeSourcePriorities: {} as ISourcePriority,
cachedSourcePriorities: {} as ISourcePriority,
} as IGroupValues;
activeSourcePriorities: {} as SourcePriority,
cachedSourcePriorities: {} as SourcePriority,
};

View file

@ -4,16 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IGroupsValues } from '../groups_logic';
import { IContentSource, IUser, IGroup } from '../../../types';
import { ContentSource, User, Group } from '../../../types';
import { DEFAULT_META } from '../../../../shared/constants';
export const mockGroupsValues = {
groups: [] as IGroup[],
contentSources: [] as IContentSource[],
users: [] as IUser[],
groups: [] as Group[],
contentSources: [] as ContentSource[],
users: [] as User[],
groupsDataLoading: true,
groupListLoading: true,
newGroupModalOpen: false,
@ -29,4 +27,4 @@ export const mockGroupsValues = {
allGroupUsers: [],
filterValue: '',
groupsMeta: DEFAULT_META,
} as IGroupsValues;
};

View file

@ -15,7 +15,7 @@ import { EuiFieldSearch, EuiFilterSelectItem, EuiCard, EuiPopoverTitle } from '@
import { FilterableUsersList } from './filterable_users_list';
import { IUser } from '../../../types';
import { User } from '../../../types';
const mockSetState = jest.fn();
const useStateMock: any = (initState: any) => [initState, mockSetState];
@ -96,7 +96,7 @@ describe('FilterableUsersList', () => {
});
it('handles hidden users when count is higher than 20', () => {
const _users = [] as IUser[];
const _users = [] as User[];
const NUM_TOTAL_USERS = 30;
const NUM_VISIBLE_USERS = 20;

View file

@ -17,7 +17,7 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { UserOptionItem } from './user_option_item';
@ -36,8 +36,8 @@ const NO_USERS_FOUND = i18n.translate(
}
);
interface IFilterableUsersListProps {
users: IUser[];
interface FilterableUsersListProps {
users: User[];
selectedOptions?: string[];
itemsClickable?: boolean;
isPopover?: boolean;
@ -46,7 +46,7 @@ interface IFilterableUsersListProps {
removeFilteredUser(userId: string): void;
}
export const FilterableUsersList: React.FC<IFilterableUsersListProps> = ({
export const FilterableUsersList: React.FC<FilterableUsersListProps> = ({
users,
selectedOptions = [],
itemsClickable,
@ -59,7 +59,7 @@ export const FilterableUsersList: React.FC<IFilterableUsersListProps> = ({
const filterUsers = (userId: string): boolean => {
if (!filterValue) return true;
const filterUser = users.find(({ id }) => id === userId) as IUser;
const filterUser = users.find(({ id }) => id === userId) as User;
const filteredName = filterUser.name || filterUser.email;
return filteredName.toLowerCase().indexOf(filterValue.toLowerCase()) > -1;
};

View file

@ -10,13 +10,13 @@ import { useActions } from 'kea';
import { EuiFilterGroup, EuiPopover } from '@elastic/eui';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { GroupsLogic } from '../groups_logic';
import { FilterableUsersList } from './filterable_users_list';
interface IIFilterableUsersPopoverProps {
users: IUser[];
interface FilterableUsersPopoverProps {
users: User[];
selectedOptions?: string[];
itemsClickable?: boolean;
isPopoverOpen: boolean;
@ -26,7 +26,7 @@ interface IIFilterableUsersPopoverProps {
closePopover(): void;
}
export const FilterableUsersPopover: React.FC<IIFilterableUsersPopoverProps> = ({
export const FilterableUsersPopover: React.FC<FilterableUsersPopoverProps> = ({
users,
selectedOptions = [],
itemsClickable,

View file

@ -28,7 +28,7 @@ import {
import { EuiButton as EuiLinkButton } from '../../../../shared/react_router_helpers';
import { IGroup } from '../../../types';
import { Group } from '../../../types';
import { ORG_SOURCES_PATH } from '../../../routes';
import noSharedSourcesIcon from '../../../assets/share_circle.svg';
@ -67,17 +67,17 @@ const EMPTY_STATE_BODY = i18n.translate(
}
);
interface IGroupManagerModalProps {
interface GroupManagerModalProps {
children: React.ReactElement;
label: string;
allItems: object[];
numSelected: number;
hideModal(group: IGroup): void;
hideModal(group: Group): void;
selectAll(allItems: object[]): void;
saveItems(): void;
}
export const GroupManagerModal: React.FC<IGroupManagerModalProps> = ({
export const GroupManagerModal: React.FC<GroupManagerModalProps> = ({
children,
label,
allItems,

View file

@ -15,7 +15,7 @@ import { EuiTableRow, EuiTableRowCell, EuiIcon } from '@elastic/eui';
import { TruncatedContent } from '../../../../shared/truncate';
import { EuiLink } from '../../../../shared/react_router_helpers';
import { IGroup } from '../../../types';
import { Group } from '../../../types';
import { AppLogic } from '../../../app_logic';
import { getGroupPath } from '../../../routes';
@ -42,7 +42,7 @@ const dateDisplay = (date: string) =>
? moment(date).fromNow()
: moment(date).format('MMMM D, YYYY');
export const GroupRow: React.FC<IGroup> = ({
export const GroupRow: React.FC<Group> = ({
id,
name,
updatedAt,

View file

@ -10,19 +10,19 @@ import { i18n } from '@kbn/i18n';
import { EuiFilterGroup, EuiPopover, EuiPopoverTitle, EuiButtonEmpty } from '@elastic/eui';
import { IContentSource } from '../../../types';
import { ContentSource } from '../../../types';
import { SourceOptionItem } from './source_option_item';
interface IGroupRowSourcesDropdownProps {
interface GroupRowSourcesDropdownProps {
isPopoverOpen: boolean;
numOptions: number;
groupSources: IContentSource[];
groupSources: ContentSource[];
onButtonClick(): void;
closePopover(): void;
}
export const GroupRowSourcesDropdown: React.FC<IGroupRowSourcesDropdownProps> = ({
export const GroupRowSourcesDropdown: React.FC<GroupRowSourcesDropdownProps> = ({
isPopoverOpen,
numOptions,
groupSources,

View file

@ -13,7 +13,7 @@ import { EuiLoadingContent, EuiButtonEmpty } from '@elastic/eui';
import { GroupsLogic } from '../groups_logic';
import { FilterableUsersPopover } from './filterable_users_popover';
interface IGroupRowUsersDropdownProps {
interface GroupRowUsersDropdownProps {
isPopoverOpen: boolean;
numOptions: number;
groupId: string;
@ -21,7 +21,7 @@ interface IGroupRowUsersDropdownProps {
closePopover(): void;
}
export const GroupRowUsersDropdown: React.FC<IGroupRowUsersDropdownProps> = ({
export const GroupRowUsersDropdown: React.FC<GroupRowUsersDropdownProps> = ({
isPopoverOpen,
numOptions,
groupId,

View file

@ -32,7 +32,7 @@ import { SourceIcon } from '../../../components/shared/source_icon';
import { GroupLogic } from '../group_logic';
import { IContentSource } from '../../../types';
import { ContentSource } from '../../../types';
const HEADER_TITLE = i18n.translate(
'xpack.enterpriseSearch.workplaceSearch.groups.sourceProioritization.headerTitle',
@ -140,7 +140,7 @@ export const GroupSourcePrioritization: React.FC = () => {
<EuiTableHeaderCell align="right">{PRIORITY_TABLE_HEADER}</EuiTableHeaderCell>
</EuiTableHeader>
<EuiTableBody>
{contentSources.map(({ id, name, serviceType }: IContentSource) => (
{contentSources.map(({ id, name, serviceType }: ContentSource) => (
<EuiTableRow key={id} data-test-subj="GroupsRow">
<EuiTableRowCell>
<EuiFlexGroup justifyContent="flexStart" alignItems="center" responsive={false}>

View file

@ -16,7 +16,7 @@ import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
import { SourceIcon } from '../../../components/shared/source_icon';
import { IContentSourceDetails } from '../../../types';
import { ContentSourceDetails } from '../../../types';
describe('GroupSources', () => {
it('renders', () => {
@ -26,7 +26,7 @@ describe('GroupSources', () => {
});
it('handles hidden sources when count is higer than 10', () => {
const sources = [] as IContentSourceDetails[];
const sources = [] as ContentSourceDetails[];
const NUM_TOTAL_SOURCES = 10;
[...Array(NUM_TOTAL_SOURCES)].forEach((_, i) => {

View file

@ -9,15 +9,15 @@ import React, { useState } from 'react';
import { SourceIcon } from '../../../components/shared/source_icon';
import { MAX_TABLE_ROW_ICONS } from '../../../constants';
import { IContentSource } from '../../../types';
import { ContentSource } from '../../../types';
import { GroupRowSourcesDropdown } from './group_row_sources_dropdown';
interface IGroupSourcesProps {
groupSources: IContentSource[];
interface GroupSourcesProps {
groupSources: ContentSource[];
}
export const GroupSources: React.FC<IGroupSourcesProps> = ({ groupSources }) => {
export const GroupSources: React.FC<GroupSourcesProps> = ({ groupSources }) => {
const [popoverOpen, setPopoverOpen] = useState(false);
const closePopover = () => setPopoverOpen(false);
const togglePopover = () => setPopoverOpen(!popoverOpen);

View file

@ -11,7 +11,7 @@ import { users } from '../../../__mocks__/users.mock';
import React from 'react';
import { shallow } from 'enzyme';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { GroupUsers } from './group_users';
import { GroupRowUsersDropdown } from './group_row_users_dropdown';
@ -32,7 +32,7 @@ describe('GroupUsers', () => {
});
it('handles hidden users when count is higher than 20', () => {
const _users = [] as IUser[];
const _users = [] as User[];
const NUM_TOTAL_USERS = 20;
[...Array(NUM_TOTAL_USERS)].forEach((_, i) => {

View file

@ -9,17 +9,17 @@ import React, { useState } from 'react';
import { UserIcon } from '../../../components/shared/user_icon';
import { MAX_TABLE_ROW_ICONS } from '../../../constants';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { GroupRowUsersDropdown } from './group_row_users_dropdown';
interface IGroupUsersProps {
groupUsers: IUser[];
interface GroupUsersProps {
groupUsers: User[];
usersCount: number;
groupId: string;
}
export const GroupUsers: React.FC<IGroupUsersProps> = ({ groupUsers, usersCount, groupId }) => {
export const GroupUsers: React.FC<GroupUsersProps> = ({ groupUsers, usersCount, groupId }) => {
const [popoverOpen, setPopoverOpen] = useState(false);
const closePopover = () => setPopoverOpen(false);
const togglePopover = () => setPopoverOpen(!popoverOpen);

View file

@ -12,7 +12,7 @@ import { groups } from '../../../__mocks__/groups.mock';
import React from 'react';
import { shallow } from 'enzyme';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { GroupUsersTable } from './group_users_table';
import { TableHeader } from '../../../../shared/table_header';
@ -38,7 +38,7 @@ describe('GroupUsersTable', () => {
});
it('renders pagination', () => {
const users = [] as IUser[];
const users = [] as User[];
const NUM_TOTAL_USERS = 20;
[...Array(NUM_TOTAL_USERS)].forEach((_, i) => {

View file

@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n';
import { EuiTable, EuiTableBody, EuiTablePagination } from '@elastic/eui';
import { Pager } from '@elastic/eui';
import { IUser } from '../../../types';
import { User } from '../../../types';
import { TableHeader } from '../../../../shared/table_header';
import { UserRow } from '../../../components/shared/user_row';
@ -74,7 +74,7 @@ export const GroupUsersTable: React.FC = () => {
<EuiTable className="table table--emphasized">
<TableHeader extraCell={isFederatedAuth} headerItems={headerItems} />
<EuiTableBody>
{users.slice(firstItem, lastItem + 1).map((user: IUser) => (
{users.slice(firstItem, lastItem + 1).map((user: User) => (
<UserRow key={user.id} showEmail={!isFederatedAuth} user={user} />
))}
</EuiTableBody>

View file

@ -11,15 +11,15 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { TruncatedContent } from '../../../../shared/truncate';
import { SourceIcon } from '../../../components/shared/source_icon';
import { IContentSource } from '../../../types';
import { ContentSource } from '../../../types';
const MAX_LENGTH = 28;
interface ISourceOptionItemProps {
source: IContentSource;
interface SourceOptionItemProps {
source: ContentSource;
}
export const SourceOptionItem: React.FC<ISourceOptionItemProps> = ({ source }) => (
export const SourceOptionItem: React.FC<SourceOptionItemProps> = ({ source }) => (
<EuiFlexGroup gutterSize="xs" justifyContent="flexStart" alignItems="center">
<EuiFlexItem grow={false}>
<SourceIcon wrapped {...source} />

View file

@ -8,18 +8,18 @@ import React from 'react';
import { EuiFilterSelectItem } from '@elastic/eui';
import { IContentSource } from '../../../types';
import { ContentSource } from '../../../types';
import { SourceOptionItem } from './source_option_item';
interface ISourcesListProps {
contentSources: IContentSource[];
interface SourcesListProps {
contentSources: ContentSource[];
filteredSources: string[];
addFilteredSource(sourceId: string): void;
removeFilteredSource(sourceId: string): void;
}
export const SourcesList: React.FC<ISourcesListProps> = ({
export const SourcesList: React.FC<SourcesListProps> = ({
contentSources,
filteredSources,
addFilteredSource,

View file

@ -9,13 +9,13 @@ import React from 'react';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { UserIcon } from '../../../components/shared/user_icon';
import { IUser } from '../../../types';
import { User } from '../../../types';
interface IUserOptionItemProps {
user: IUser;
interface UserOptionItemProps {
user: User;
}
export const UserOptionItem: React.FC<IUserOptionItemProps> = ({ user }) => (
export const UserOptionItem: React.FC<UserOptionItemProps> = ({ user }) => (
<EuiFlexGroup gutterSize="xs" justifyContent="flexStart" alignItems="center">
<EuiFlexItem grow={false}>
<UserIcon {...user} />

View file

@ -6,7 +6,6 @@
import { kea, MakeLogicType } from 'kea';
import { isEqual } from 'lodash';
import { History } from 'history';
import { i18n } from '@kbn/i18n';
import { HttpLogic } from '../../../shared/http';
@ -20,26 +19,26 @@ import {
} from '../../../shared/flash_messages';
import { GROUPS_PATH } from '../../routes';
import { IContentSourceDetails, IGroupDetails, IUser, ISourcePriority } from '../../types';
import { ContentSourceDetails, GroupDetails, User, SourcePriority } from '../../types';
export const MAX_NAME_LENGTH = 40;
export interface IGroupActions {
onInitializeGroup(group: IGroupDetails): IGroupDetails;
onGroupNameChanged(group: IGroupDetails): IGroupDetails;
onGroupPrioritiesChanged(group: IGroupDetails): IGroupDetails;
interface GroupActions {
onInitializeGroup(group: GroupDetails): GroupDetails;
onGroupNameChanged(group: GroupDetails): GroupDetails;
onGroupPrioritiesChanged(group: GroupDetails): GroupDetails;
onGroupNameInputChange(groupName: string): string;
addGroupSource(sourceId: string): string;
removeGroupSource(sourceId: string): string;
addGroupUser(userId: string): string;
removeGroupUser(userId: string): string;
onGroupSourcesSaved(group: IGroupDetails): IGroupDetails;
onGroupUsersSaved(group: IGroupDetails): IGroupDetails;
onGroupSourcesSaved(group: GroupDetails): GroupDetails;
onGroupUsersSaved(group: GroupDetails): GroupDetails;
setGroupModalErrors(errors: string[]): string[];
hideSharedSourcesModal(group: IGroupDetails): IGroupDetails;
hideManageUsersModal(group: IGroupDetails): IGroupDetails;
selectAllSources(contentSources: IContentSourceDetails[]): IContentSourceDetails[];
selectAllUsers(users: IUser[]): IUser[];
hideSharedSourcesModal(group: GroupDetails): GroupDetails;
hideManageUsersModal(group: GroupDetails): GroupDetails;
selectAllSources(contentSources: ContentSourceDetails[]): ContentSourceDetails[];
selectAllUsers(users: User[]): User[];
updatePriority(id: string, boost: number): { id: string; boost: number };
resetGroup(): void;
showConfirmDeleteModal(): void;
@ -55,8 +54,8 @@ export interface IGroupActions {
saveGroupSourcePrioritization(): void;
}
export interface IGroupValues {
group: IGroupDetails;
interface GroupValues {
group: GroupDetails;
dataLoading: boolean;
manageUsersModalVisible: boolean;
managerModalFormErrors: string[];
@ -66,36 +65,36 @@ export interface IGroupValues {
selectedGroupSources: string[];
selectedGroupUsers: string[];
groupPrioritiesUnchanged: boolean;
activeSourcePriorities: ISourcePriority;
cachedSourcePriorities: ISourcePriority;
activeSourcePriorities: SourcePriority;
cachedSourcePriorities: SourcePriority;
}
export const GroupLogic = kea<MakeLogicType<IGroupValues, IGroupActions>>({
export const GroupLogic = kea<MakeLogicType<GroupValues, GroupActions>>({
path: ['enterprise_search', 'workplace_search', 'group'],
actions: {
onInitializeGroup: (group: IGroupDetails) => group,
onGroupNameChanged: (group: IGroupDetails) => group,
onGroupPrioritiesChanged: (group: IGroupDetails) => group,
onGroupNameInputChange: (groupName: string) => groupName,
addGroupSource: (sourceId: string) => sourceId,
removeGroupSource: (sourceId: string) => sourceId,
addGroupUser: (userId: string) => userId,
removeGroupUser: (userId: string) => userId,
onGroupSourcesSaved: (group: IGroupDetails) => group,
onGroupUsersSaved: (group: IGroupDetails) => group,
setGroupModalErrors: (errors: string[]) => errors,
hideSharedSourcesModal: (group: IGroupDetails) => group,
hideManageUsersModal: (group: IGroupDetails) => group,
selectAllSources: (contentSources: IContentSourceDetails[]) => contentSources,
selectAllUsers: (users: IUser[]) => users,
updatePriority: (id: string, boost: number) => ({ id, boost }),
onInitializeGroup: (group) => group,
onGroupNameChanged: (group) => group,
onGroupPrioritiesChanged: (group) => group,
onGroupNameInputChange: (groupName) => groupName,
addGroupSource: (sourceId) => sourceId,
removeGroupSource: (sourceId) => sourceId,
addGroupUser: (userId) => userId,
removeGroupUser: (userId) => userId,
onGroupSourcesSaved: (group) => group,
onGroupUsersSaved: (group) => group,
setGroupModalErrors: (errors) => errors,
hideSharedSourcesModal: (group) => group,
hideManageUsersModal: (group) => group,
selectAllSources: (contentSources) => contentSources,
selectAllUsers: (users) => users,
updatePriority: (id, boost) => ({ id, boost }),
resetGroup: () => true,
showConfirmDeleteModal: () => true,
hideConfirmDeleteModal: () => true,
showSharedSourcesModal: () => true,
showManageUsersModal: () => true,
resetFlashMessages: () => true,
initializeGroup: (groupId: string, history: History) => ({ groupId, history }),
initializeGroup: (groupId) => ({ groupId }),
deleteGroup: () => true,
updateGroupName: () => true,
saveGroupSources: () => true,
@ -104,13 +103,13 @@ export const GroupLogic = kea<MakeLogicType<IGroupValues, IGroupActions>>({
},
reducers: {
group: [
{} as IGroupDetails,
{} as GroupDetails,
{
onInitializeGroup: (_, group) => group,
onGroupNameChanged: (_, group) => group,
onGroupSourcesSaved: (_, group) => group,
onGroupUsersSaved: (_, group) => group,
resetGroup: () => ({} as IGroupDetails),
resetGroup: () => ({} as GroupDetails),
},
],
dataLoading: [
@ -375,8 +374,8 @@ export const GroupLogic = kea<MakeLogicType<IGroupValues, IGroupActions>>({
}),
});
const mapPriorities = (contentSources: IContentSourceDetails[]): ISourcePriority => {
const prioritiesMap = {} as ISourcePriority;
const mapPriorities = (contentSources: ContentSourceDetails[]): SourcePriority => {
const prioritiesMap = {} as SourcePriority;
contentSources.forEach(({ id, boost }) => {
prioritiesMap[id] = boost;
});

View file

@ -15,37 +15,37 @@ import {
setSuccessMessage,
} from '../../../shared/flash_messages';
import { IContentSource, IGroup, IUser } from '../../types';
import { ContentSource, Group, User } from '../../types';
import { JSON_HEADER as headers } from '../../../../../common/constants';
import { DEFAULT_META } from '../../../shared/constants';
import { IMeta } from '../../../../../common/types';
import { Meta } from '../../../../../common/types';
export const MAX_NAME_LENGTH = 40;
interface IGroupsServerData {
contentSources: IContentSource[];
users: IUser[];
interface GroupsServerData {
contentSources: ContentSource[];
users: User[];
}
interface IGroupsSearchResponse {
results: IGroup[];
meta: IMeta;
interface GroupsSearchResponse {
results: Group[];
meta: Meta;
}
export interface IGroupsActions {
onInitializeGroups(data: IGroupsServerData): IGroupsServerData;
setSearchResults(data: IGroupsSearchResponse): IGroupsSearchResponse;
interface GroupsActions {
onInitializeGroups(data: GroupsServerData): GroupsServerData;
setSearchResults(data: GroupsSearchResponse): GroupsSearchResponse;
addFilteredSource(sourceId: string): string;
removeFilteredSource(sourceId: string): string;
addFilteredUser(userId: string): string;
removeFilteredUser(userId: string): string;
setGroupUsers(allGroupUsers: IUser[]): IUser[];
setGroupUsers(allGroupUsers: User[]): User[];
setAllGroupLoading(allGroupUsersLoading: boolean): boolean;
setFilterValue(filterValue: string): string;
setActivePage(activePage: number): number;
setNewGroupName(newGroupName: string): string;
setNewGroup(newGroup: IGroup): IGroup;
setNewGroup(newGroup: Group): Group;
setNewGroupFormErrors(errors: string[]): string[];
openNewGroupModal(): void;
closeNewGroupModal(): void;
@ -62,43 +62,43 @@ export interface IGroupsActions {
saveNewGroup(): void;
}
export interface IGroupsValues {
groups: IGroup[];
contentSources: IContentSource[];
users: IUser[];
interface GroupsValues {
groups: Group[];
contentSources: ContentSource[];
users: User[];
groupsDataLoading: boolean;
groupListLoading: boolean;
newGroupModalOpen: boolean;
newGroupName: string;
newGroup: IGroup | null;
newGroup: Group | null;
newGroupNameErrors: string[];
filterSourcesDropdownOpen: boolean;
filteredSources: string[];
filterUsersDropdownOpen: boolean;
filteredUsers: string[];
allGroupUsersLoading: boolean;
allGroupUsers: IUser[];
allGroupUsers: User[];
filterValue: string;
groupsMeta: IMeta;
groupsMeta: Meta;
hasFiltersSet: boolean;
}
export const GroupsLogic = kea<MakeLogicType<IGroupsValues, IGroupsActions>>({
export const GroupsLogic = kea<MakeLogicType<GroupsValues, GroupsActions>>({
path: ['enterprise_search', 'workplace_search', 'groups'],
actions: {
onInitializeGroups: (data: IGroupsServerData) => data,
setSearchResults: (data: IGroupsSearchResponse) => data,
addFilteredSource: (sourceId: string) => sourceId,
removeFilteredSource: (sourceId: string) => sourceId,
addFilteredUser: (userId: string) => userId,
removeFilteredUser: (userId: string) => userId,
setGroupUsers: (allGroupUsers: IUser[]) => allGroupUsers,
onInitializeGroups: (data) => data,
setSearchResults: (data) => data,
addFilteredSource: (sourceId) => sourceId,
removeFilteredSource: (sourceId) => sourceId,
addFilteredUser: (userId) => userId,
removeFilteredUser: (userId) => userId,
setGroupUsers: (allGroupUsers) => allGroupUsers,
setAllGroupLoading: (allGroupUsersLoading: boolean) => allGroupUsersLoading,
setFilterValue: (filterValue: string) => filterValue,
setActivePage: (activePage: number) => activePage,
setNewGroupName: (newGroupName: string) => newGroupName,
setNewGroup: (newGroup: IGroup) => newGroup,
setNewGroupFormErrors: (errors: string[]) => errors,
setFilterValue: (filterValue) => filterValue,
setActivePage: (activePage) => activePage,
setNewGroupName: (newGroupName) => newGroupName,
setNewGroup: (newGroup) => newGroup,
setNewGroupFormErrors: (errors) => errors,
openNewGroupModal: () => true,
closeNewGroupModal: () => true,
closeFilterSourcesDropdown: () => true,
@ -109,13 +109,13 @@ export const GroupsLogic = kea<MakeLogicType<IGroupsValues, IGroupsActions>>({
resetGroupsFilters: () => true,
resetGroups: () => true,
initializeGroups: () => true,
getSearchResults: (resetPagination?: boolean) => ({ resetPagination }),
fetchGroupUsers: (groupId: string) => ({ groupId }),
getSearchResults: (resetPagination) => ({ resetPagination }),
fetchGroupUsers: (groupId) => ({ groupId }),
saveNewGroup: () => true,
},
reducers: {
groups: [
[] as IGroup[],
[] as Group[],
{
setSearchResults: (_, { results }) => results,
},

View file

@ -4,8 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { IOverviewValues } from '../overview_logic';
import { setMockValues as setMockKeaValues, setMockActions } from '../../../../__mocks__/kea.mock';
import { DEFAULT_INITIAL_APP_DATA } from '../../../../../../common/__mocks__';
@ -22,7 +20,7 @@ export const mockOverviewValues = {
personalSourcesCount: 0,
sourcesCount: 0,
dataLoading: true,
} as IOverviewValues;
};
export const mockActions = {
initializeOverview: jest.fn(() => ({})),

View file

@ -22,7 +22,7 @@ import {
import { TelemetryLogic } from '../../../shared/telemetry';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
interface IOnboardingCardProps {
interface OnboardingCardProps {
title: React.ReactNode;
icon: React.ReactNode;
description: React.ReactNode;
@ -32,7 +32,7 @@ interface IOnboardingCardProps {
complete?: boolean;
}
export const OnboardingCard: React.FC<IOnboardingCardProps> = ({
export const OnboardingCard: React.FC<OnboardingCardProps> = ({
title,
icon,
description,

View file

@ -7,9 +7,9 @@
import { kea, MakeLogicType } from 'kea';
import { HttpLogic } from '../../../shared/http';
import { IFeedActivity } from './recent_activity';
import { FeedActivity } from './recent_activity';
export interface IOverviewServerData {
interface OverviewServerData {
hasUsers: boolean;
hasOrgSources: boolean;
canCreateContentSources: boolean;
@ -18,19 +18,19 @@ export interface IOverviewServerData {
pendingInvitationsCount: number;
accountsCount: number;
personalSourcesCount: number;
activityFeed: IFeedActivity[];
activityFeed: FeedActivity[];
}
export interface IOverviewActions {
setServerData(serverData: IOverviewServerData): IOverviewServerData;
interface OverviewActions {
setServerData(serverData: OverviewServerData): OverviewServerData;
initializeOverview(): void;
}
export interface IOverviewValues extends IOverviewServerData {
interface OverviewValues extends OverviewServerData {
dataLoading: boolean;
}
export const OverviewLogic = kea<MakeLogicType<IOverviewValues, IOverviewActions>>({
export const OverviewLogic = kea<MakeLogicType<OverviewValues, OverviewActions>>({
path: ['enterprise_search', 'workplace_search', 'overview_logic'],
actions: {
setServerData: (serverData) => serverData,

View file

@ -22,7 +22,7 @@ import { OverviewLogic } from './overview_logic';
import './recent_activity.scss';
export interface IFeedActivity {
export interface FeedActivity {
status?: string;
id: string;
message: string;
@ -50,7 +50,7 @@ export const RecentActivity: React.FC = () => {
<EuiPanel>
{activityFeed.length > 0 ? (
<>
{activityFeed.map((props: IFeedActivity, index) => (
{activityFeed.map((props: FeedActivity, index) => (
<RecentActivityItem {...props} key={index} />
))}
</>
@ -86,7 +86,7 @@ export const RecentActivity: React.FC = () => {
);
};
export const RecentActivityItem: React.FC<IFeedActivity> = ({
export const RecentActivityItem: React.FC<FeedActivity> = ({
id,
status,
message,

View file

@ -9,13 +9,13 @@ import { EuiCard, EuiFlexItem, EuiTitle, EuiTextColor } from '@elastic/eui';
import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url';
interface IStatisticCardProps {
interface StatisticCardProps {
title: string;
count?: number;
actionPath?: string;
}
export const StatisticCard: React.FC<IStatisticCardProps> = ({ title, count = 0, actionPath }) => {
export const StatisticCard: React.FC<StatisticCardProps> = ({ title, count = 0, actionPath }) => {
const linkProps = actionPath
? {
href: getWorkplaceSearchUrl(actionPath),

View file

@ -17,22 +17,23 @@ import {
HomePublicPluginSetup,
} from '../../../../src/plugins/home/public';
import { LicensingPluginStart } from '../../licensing/public';
import {
APP_SEARCH_PLUGIN,
ENTERPRISE_SEARCH_PLUGIN,
WORKPLACE_SEARCH_PLUGIN,
} from '../common/constants';
import { IInitialAppData } from '../common/types';
import { InitialAppData } from '../common/types';
export interface ClientConfigType {
host?: string;
}
export interface ClientData extends IInitialAppData {
export interface ClientData extends InitialAppData {
publicUrl?: string;
errorConnecting?: boolean;
}
export interface PluginsSetup {
interface PluginsSetup {
home?: HomePublicPluginSetup;
}
export interface PluginsStart {

View file

@ -19,7 +19,7 @@ import {
type MethodType = 'get' | 'post' | 'put' | 'patch' | 'delete';
type PayloadType = 'params' | 'query' | 'body';
interface IMockRouterProps {
interface IMockRouter {
method: MethodType;
path: string;
payload?: PayloadType;
@ -29,7 +29,7 @@ interface IMockRouterRequest {
query?: object;
params?: object;
}
type TMockRouterRequest = KibanaRequest | IMockRouterRequest;
type MockRouterRequest = KibanaRequest | IMockRouterRequest;
export class MockRouter {
public router!: jest.Mocked<IRouter>;
@ -38,7 +38,7 @@ export class MockRouter {
public payload?: PayloadType;
public response = httpServerMock.createResponseFactory();
constructor({ method, path, payload }: IMockRouterProps) {
constructor({ method, path, payload }: IMockRouter) {
this.createRouter();
this.method = method;
this.path = path;
@ -49,7 +49,7 @@ export class MockRouter {
this.router = httpServiceMock.createRouter();
};
public callRoute = async (request: TMockRouterRequest) => {
public callRoute = async (request: MockRouterRequest) => {
const routerCalls = this.router[this.method].mock.calls as any[];
if (!routerCalls.length) throw new Error('No routes registered.');
@ -65,7 +65,7 @@ export class MockRouter {
* Schema validation helpers
*/
public validateRoute = (request: TMockRouterRequest) => {
public validateRoute = (request: MockRouterRequest) => {
if (!this.payload) throw new Error('Cannot validate wihout a payload type specified.');
const [config] = this.router[this.method].mock.calls[0];
@ -77,11 +77,11 @@ export class MockRouter {
payloadValidation.validate(payloadRequest);
};
public shouldValidate = (request: TMockRouterRequest) => {
public shouldValidate = (request: MockRouterRequest) => {
expect(() => this.validateRoute(request)).not.toThrow();
};
public shouldThrow = (request: TMockRouterRequest) => {
public shouldThrow = (request: MockRouterRequest) => {
expect(() => this.validateRoute(request)).toThrow();
};
}

View file

@ -10,7 +10,7 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { getSavedObjectAttributesFromRepo } from '../lib/telemetry';
interface ITelemetry {
interface Telemetry {
ui_viewed: {
setup_guide: number;
engines_overview: number;
@ -37,7 +37,7 @@ export const registerTelemetryUsageCollector = (
savedObjects: SavedObjectsServiceStart,
log: Logger
) => {
const telemetryUsageCollector = usageCollection.makeUsageCollector<ITelemetry>({
const telemetryUsageCollector = usageCollection.makeUsageCollector<Telemetry>({
type: 'app_search',
fetch: async () => fetchTelemetryMetrics(savedObjects, log),
isReady: () => true,
@ -72,7 +72,7 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log
log
);
const defaultTelemetrySavedObject: ITelemetry = {
const defaultTelemetrySavedObject: Telemetry = {
ui_viewed: {
setup_guide: 0,
engines_overview: 0,
@ -111,5 +111,5 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log
header_launch_button: get(savedObjectAttributes, 'ui_clicked.header_launch_button', 0),
engine_table_link: get(savedObjectAttributes, 'ui_clicked.engine_table_link', 0),
},
} as ITelemetry;
} as Telemetry;
};

View file

@ -10,7 +10,7 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import { getSavedObjectAttributesFromRepo } from '../lib/telemetry';
interface ITelemetry {
interface Telemetry {
ui_viewed: {
overview: number;
setup_guide: number;
@ -35,7 +35,7 @@ export const registerTelemetryUsageCollector = (
savedObjects: SavedObjectsServiceStart,
log: Logger
) => {
const telemetryUsageCollector = usageCollection.makeUsageCollector<ITelemetry>({
const telemetryUsageCollector = usageCollection.makeUsageCollector<Telemetry>({
type: 'enterprise_search',
fetch: async () => fetchTelemetryMetrics(savedObjects, log),
isReady: () => true,
@ -68,7 +68,7 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log
log
);
const defaultTelemetrySavedObject: ITelemetry = {
const defaultTelemetrySavedObject: Telemetry = {
ui_viewed: {
overview: 0,
setup_guide: 0,
@ -99,5 +99,5 @@ const fetchTelemetryMetrics = async (savedObjects: SavedObjectsServiceStart, log
app_search: get(savedObjectAttributes, 'ui_clicked.app_search', 0),
workplace_search: get(savedObjectAttributes, 'ui_clicked.workplace_search', 0),
},
} as ITelemetry;
} as Telemetry;
};

View file

@ -37,7 +37,7 @@ export const getSavedObjectAttributesFromRepo = async (
* Set saved objection attributes - used by telemetry route
*/
interface IIncrementUICounter {
interface IncrementUICounter {
id: string; // Telemetry name
savedObjects: SavedObjectsServiceStart;
uiAction: string;
@ -49,7 +49,7 @@ export async function incrementUICounter({
savedObjects,
uiAction,
metric,
}: IIncrementUICounter) {
}: IncrementUICounter) {
const internalRepository = savedObjects.createInternalRepository();
await internalRepository.incrementCounter(

Some files were not shown because too many files have changed in this diff Show more