mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Streams] Partitioning page toasts UX improvement (#206571)
## Summary Just a UX improvement to implement this: https://github.com/elastic/kibana/pull/206116#issuecomment-2587744663 (https://github.com/elastic/kibana/pull/206116 was merged already).
This commit is contained in:
parent
0c4c8aa163
commit
a4c1c2066a
1 changed files with 50 additions and 19 deletions
|
@ -45,6 +45,7 @@ import {
|
|||
import { useUnsavedChangesPrompt } from '@kbn/unsaved-changes-prompt';
|
||||
import { AbortableAsyncState } from '@kbn/observability-utils-browser/hooks/use_abortable_async';
|
||||
import { DraggableProvided } from '@hello-pangea/dnd';
|
||||
import { IToasts, Toast } from '@kbn/core/public';
|
||||
import { toMountPoint } from '@kbn/react-kibana-mount';
|
||||
import { useKibana } from '../../hooks/use_kibana';
|
||||
import { useStreamsAppFetch } from '../../hooks/use_streams_app_fetch';
|
||||
|
@ -57,10 +58,31 @@ import { PreviewTable } from '../preview_table';
|
|||
import { StreamDeleteModal } from '../stream_delete_modal';
|
||||
import { AssetImage } from '../asset_image';
|
||||
|
||||
function useRoutingState({ definition }: { definition?: ReadStreamDefinition }) {
|
||||
const [childUnderEdit, setChildUnderEdit] = React.useState<
|
||||
{ isNew: boolean; child: StreamChild } | undefined
|
||||
>();
|
||||
interface ChildUnderEdit {
|
||||
isNew: boolean;
|
||||
child: StreamChild;
|
||||
}
|
||||
|
||||
function useRoutingState({
|
||||
definition,
|
||||
toasts,
|
||||
}: {
|
||||
definition?: ReadStreamDefinition;
|
||||
toasts: IToasts;
|
||||
}) {
|
||||
const [lastDisplayedToast, setLastDisplayedToast] = React.useState<Toast | undefined>();
|
||||
|
||||
const [childUnderEdit, setChildUnderEdit] = React.useState<ChildUnderEdit | undefined>();
|
||||
|
||||
const selectChildUnderEdit = useCallback(
|
||||
(child: ChildUnderEdit | undefined) => {
|
||||
if (lastDisplayedToast) {
|
||||
toasts.remove(lastDisplayedToast.id);
|
||||
}
|
||||
setChildUnderEdit(child);
|
||||
},
|
||||
[lastDisplayedToast, toasts]
|
||||
);
|
||||
|
||||
// Child streams: either represents the child streams as they are, or the new order from drag and drop.
|
||||
const [childStreams, setChildStreams] = React.useState<
|
||||
|
@ -83,6 +105,9 @@ function useRoutingState({ definition }: { definition?: ReadStreamDefinition })
|
|||
|
||||
const onChildStreamDragEnd = useCallback(
|
||||
(event: DropResult) => {
|
||||
if (lastDisplayedToast) {
|
||||
toasts.remove(lastDisplayedToast.id);
|
||||
}
|
||||
setDraggingChildStream(undefined);
|
||||
if (typeof event.source.index === 'number' && typeof event.destination?.index === 'number') {
|
||||
setChildStreams([
|
||||
|
@ -90,7 +115,7 @@ function useRoutingState({ definition }: { definition?: ReadStreamDefinition })
|
|||
]);
|
||||
}
|
||||
},
|
||||
[childStreams]
|
||||
[childStreams, lastDisplayedToast, toasts]
|
||||
);
|
||||
|
||||
const cancelChanges = useCallback(() => {
|
||||
|
@ -104,9 +129,10 @@ function useRoutingState({ definition }: { definition?: ReadStreamDefinition })
|
|||
const [showDeleteModal, setShowDeleteModal] = React.useState(false);
|
||||
|
||||
return {
|
||||
setLastDisplayedToast,
|
||||
debouncedChildUnderEdit,
|
||||
childUnderEdit,
|
||||
setChildUnderEdit,
|
||||
selectChildUnderEdit,
|
||||
saveInProgress,
|
||||
setSaveInProgress,
|
||||
showDeleteModal,
|
||||
|
@ -129,7 +155,7 @@ export function StreamDetailRouting({
|
|||
}) {
|
||||
const { appParams, core } = useKibana();
|
||||
const theme = useEuiTheme().euiTheme;
|
||||
const routingAppState = useRoutingState({ definition });
|
||||
const routingAppState = useRoutingState({ definition, toasts: core.notifications.toasts });
|
||||
|
||||
const {
|
||||
dependencies: {
|
||||
|
@ -174,7 +200,7 @@ export function StreamDetailRouting({
|
|||
{routingAppState.showDeleteModal && routingAppState.childUnderEdit && (
|
||||
<StreamDeleteModal
|
||||
closeModal={closeModal}
|
||||
clearChildUnderEdit={() => routingAppState.setChildUnderEdit(undefined)}
|
||||
clearChildUnderEdit={() => routingAppState.selectChildUnderEdit(undefined)}
|
||||
refreshDefinition={refreshDefinition}
|
||||
id={routingAppState.childUnderEdit.child.name}
|
||||
availableStreams={availableStreams}
|
||||
|
@ -349,7 +375,7 @@ function ControlBar({
|
|||
}
|
||||
|
||||
routingAppState.setSaveInProgress(false);
|
||||
notifications.toasts.addSuccess({
|
||||
const toast = notifications.toasts.addSuccess({
|
||||
title: i18n.translate('xpack.streams.streamDetailRouting.saved', {
|
||||
defaultMessage: 'Stream saved',
|
||||
}),
|
||||
|
@ -376,16 +402,18 @@ function ControlBar({
|
|||
core
|
||||
),
|
||||
});
|
||||
routingAppState.setChildUnderEdit(undefined);
|
||||
routingAppState.setLastDisplayedToast(toast);
|
||||
routingAppState.selectChildUnderEdit(undefined);
|
||||
refreshDefinition();
|
||||
} catch (error) {
|
||||
routingAppState.setSaveInProgress(false);
|
||||
notifications.toasts.addError(error, {
|
||||
const toast = notifications.toasts.addError(error, {
|
||||
title: i18n.translate('xpack.streams.failedToSave', {
|
||||
defaultMessage: 'Failed to save',
|
||||
}),
|
||||
toastMessage: 'body' in error ? error.body.message : error.message,
|
||||
});
|
||||
routingAppState.setLastDisplayedToast(toast);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -640,7 +668,7 @@ function ChildStreamList({
|
|||
availableStreams,
|
||||
routingAppState: {
|
||||
childUnderEdit,
|
||||
setChildUnderEdit,
|
||||
selectChildUnderEdit,
|
||||
childStreams,
|
||||
onChildStreamDragEnd,
|
||||
onChildStreamDragStart,
|
||||
|
@ -706,13 +734,13 @@ function ChildStreamList({
|
|||
edit={!childUnderEdit?.isNew && child.name === childUnderEdit?.child.name}
|
||||
onEditStateChange={() => {
|
||||
if (child.name === childUnderEdit?.child.name) {
|
||||
setChildUnderEdit(undefined);
|
||||
selectChildUnderEdit(undefined);
|
||||
} else {
|
||||
setChildUnderEdit({ isNew: false, child });
|
||||
selectChildUnderEdit({ isNew: false, child });
|
||||
}
|
||||
}}
|
||||
onChildChange={(newChild) => {
|
||||
setChildUnderEdit({
|
||||
selectChildUnderEdit({
|
||||
isNew: false,
|
||||
child: newChild,
|
||||
});
|
||||
|
@ -733,10 +761,10 @@ function ChildStreamList({
|
|||
child={childUnderEdit.child}
|
||||
onChildChange={(newChild) => {
|
||||
if (!newChild) {
|
||||
setChildUnderEdit(undefined);
|
||||
selectChildUnderEdit(undefined);
|
||||
return;
|
||||
}
|
||||
setChildUnderEdit({
|
||||
selectChildUnderEdit({
|
||||
isNew: true,
|
||||
child: newChild,
|
||||
});
|
||||
|
@ -750,7 +778,7 @@ function ChildStreamList({
|
|||
iconType="plus"
|
||||
data-test-subj="streamsAppStreamDetailRoutingAddRuleButton"
|
||||
onClick={() => {
|
||||
setChildUnderEdit({
|
||||
selectChildUnderEdit({
|
||||
isNew: true,
|
||||
child: {
|
||||
name: `${definition.name}.child`,
|
||||
|
@ -839,7 +867,10 @@ function RoutingStreamEntry({
|
|||
color="transparent"
|
||||
paddingSize="s"
|
||||
{...draggableProvided.dragHandleProps}
|
||||
aria-label="Drag Handle"
|
||||
aria-label={i18n.translate(
|
||||
'xpack.streams.routingStreamEntry.euiPanel.dragHandleLabel',
|
||||
{ defaultMessage: 'Drag Handle' }
|
||||
)}
|
||||
>
|
||||
<EuiIcon type="grab" />
|
||||
</EuiPanel>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue