-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Workplace Search] Add Account Settings page imported from Security plugin #99791
Changes from 14 commits
4d7bb8a
c416ab9
f994ba5
e09f42a
897615a
3080c1c
cfc1386
efa7d68
62aab12
4f8f832
9f18ea9
706ac2e
ebc2753
140cd91
e152365
8ec9379
9b932dc
2425821
1880755
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,6 @@ export const SETUP_GUIDE_PATH = '/setup_guide'; | |
|
||
export const NOT_FOUND_PATH = '/404'; | ||
export const LOGOUT_ROUTE = '/logout'; | ||
export const KIBANA_ACCOUNT_ROUTE = '/security/account'; | ||
|
||
export const LEAVE_FEEDBACK_EMAIL = '[email protected]'; | ||
export const LEAVE_FEEDBACK_URL = `mailto:${LEAVE_FEEDBACK_EMAIL}?Subject=Elastic%20Workplace%20Search%20Feedback`; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React, { useState, useEffect, useMemo } from 'react'; | ||
|
||
import { useValues } from 'kea'; | ||
|
||
import type { AuthenticatedUser } from '../../../../../../security/public'; | ||
import { KibanaLogic } from '../../../shared/kibana/kibana_logic'; | ||
|
||
export const AccountSettings: React.FC = () => { | ||
const { security } = useValues(KibanaLogic); | ||
|
||
const [currentUser, setCurrentUser] = useState<AuthenticatedUser | null>(null); | ||
|
||
useEffect(() => { | ||
security!.authc!.getCurrentUser().then(setCurrentUser); | ||
}, [security.authc]); | ||
|
||
const PersonalInfo = useMemo(() => security!.uiApi!.components.getPersonalInfo, [security.uiApi]); | ||
const ChangePassword = useMemo(() => security!.uiApi!.components.getChangePassword, [ | ||
security.uiApi, | ||
]); | ||
|
||
if (!currentUser) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<> | ||
<PersonalInfo user={currentUser} /> | ||
<ChangePassword user={currentUser} /> | ||
</> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
export { AccountSettings } from './account_settings'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
|
||
import type { CoreStart } from 'src/core/public'; | ||
|
||
import { UserAPIClient } from '../../management/users'; | ||
import type { ChangePasswordProps } from './change_password'; | ||
|
||
export const getChangePasswordComponent = async ( | ||
core: CoreStart | ||
): Promise<React.FC<Pick<ChangePasswordProps, 'user'>>> => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I learnt yesterday that export interface ChangePasswordProps {
user: AuthenticatedUser;
}
export interface ChangePasswordPropsInternal extends ChangePasswordProps {
userAPIClient: PublicMethodsOf<UserAPIClient>;
notifications: NotificationsSetup;
} (and you also need to merge the latest master and likely to update latest version of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good to know, and thanks for the link! I replaced it here: 2425821 |
||
const { ChangePassword } = await import('./change_password'); | ||
|
||
return (props: Pick<ChangePasswordProps, 'user'>) => { | ||
return ( | ||
<ChangePassword | ||
notifications={core.notifications} | ||
userAPIClient={new UserAPIClient(core.http)} | ||
{...props} | ||
/> | ||
); | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -6,3 +6,6 @@ | |||||||||
*/ | ||||||||||
|
||||||||||
export { accountManagementApp } from './account_management_app'; | ||||||||||
|
||||||||||
export type { ChangePasswordProps } from './change_password/change_password'; | ||||||||||
export type { PersonalInfoProps } from './personal_info/personal_info'; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: please export these types from
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, thanks! Updated here: 9b932dc |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import React from 'react'; | ||
|
||
import type { PersonalInfoProps } from './personal_info'; | ||
|
||
export const getPersonalInfoComponent = async (): Promise<React.FC<PersonalInfoProps>> => { | ||
const { PersonalInfo } = await import('./personal_info'); | ||
return (props: PersonalInfoProps) => { | ||
return <PersonalInfo {...props} />; | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
export { SuspenseErrorBoundary } from './suspense_error_boundary'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { EuiLoadingSpinner } from '@elastic/eui'; | ||
import type { PropsWithChildren } from 'react'; | ||
import React, { Component, Suspense } from 'react'; | ||
|
||
import { i18n } from '@kbn/i18n'; | ||
import type { NotificationsStart } from 'src/core/public'; | ||
|
||
interface Props { | ||
notifications: NotificationsStart; | ||
} | ||
|
||
interface State { | ||
error: Error | null; | ||
} | ||
|
||
export class SuspenseErrorBoundary extends Component<PropsWithChildren<Props>, State> { | ||
state: State = { | ||
error: null, | ||
}; | ||
|
||
static getDerivedStateFromError(error: Error) { | ||
// Update state so next render shows fallback UI. | ||
return { error }; | ||
} | ||
|
||
public componentDidCatch(error: Error) { | ||
const { notifications } = this.props; | ||
if (notifications) { | ||
const title = i18n.translate('xpack.security.uiApi.errorBoundaryToastTitle', { | ||
defaultMessage: 'Failed to load Kibana asset', | ||
}); | ||
const toastMessage = i18n.translate('xpack.security.uiApi.errorBoundaryToastMessage', { | ||
defaultMessage: 'Reload page to continue.', | ||
}); | ||
notifications.toasts.addError(error, { title, toastMessage }); | ||
} | ||
} | ||
|
||
render() { | ||
const { children, notifications } = this.props; | ||
const { error } = this.state; | ||
if (!notifications || error) { | ||
return null; | ||
} | ||
return <Suspense fallback={<EuiLoadingSpinner />}>{children}</Suspense>; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: won't we have an unhandled exception here in case security plugin is disabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for checking our plugin code as well! Good question.
No, if this component loads, we are guaranteed to have the security plugin enabled.
One of the requirements for being able to run Workplace Search is to have security enabled (see Step 2 in our installation docs). If security is disabled, Workplace Search won't run and this page could not be opened.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, thanks for clarifying! Was just confused by these
!
and was wondering ifsecurity
and its properties can really beundefined
or not (by the way it seems!
isn't strictly needed forsecurity
itself and is only needed to access its properties).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right. I guess I overdid it here. 😄
I plan to do a follow-up PR with some cleanup in the enterprise_search plugin only.
I'll update this line there if you don't mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me 👍