TabItemEditor: Add tab title edit undo action (#110497)
* add undo action for tab title change * add i18n
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useMemo } from 'react';
|
import { useMemo, useRef } from 'react';
|
||||||
|
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { Trans, t } from '@grafana/i18n';
|
import { Trans, t } from '@grafana/i18n';
|
||||||
@@ -10,6 +10,7 @@ import { SHARED_DASHBOARD_QUERY } from 'app/plugins/datasource/dashboard/constan
|
|||||||
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
|
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
|
||||||
|
|
||||||
import { useConditionalRenderingEditor } from '../../conditional-rendering/ConditionalRenderingEditor';
|
import { useConditionalRenderingEditor } from '../../conditional-rendering/ConditionalRenderingEditor';
|
||||||
|
import { dashboardEditActions } from '../../edit-pane/shared';
|
||||||
import { getQueryRunnerFor, useDashboard } from '../../utils/utils';
|
import { getQueryRunnerFor, useDashboard } from '../../utils/utils';
|
||||||
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
||||||
import { useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
import { useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||||
@@ -69,6 +70,7 @@ export function useEditOptions(model: TabItem, isNewElement: boolean): OptionsPa
|
|||||||
|
|
||||||
function TabTitleInput({ tab, isNewElement, id }: { tab: TabItem; isNewElement: boolean; id?: string }) {
|
function TabTitleInput({ tab, isNewElement, id }: { tab: TabItem; isNewElement: boolean; id?: string }) {
|
||||||
const { title } = tab.useState();
|
const { title } = tab.useState();
|
||||||
|
const prevTitle = useRef('');
|
||||||
|
|
||||||
const ref = useEditPaneInputAutoFocus({ autoFocus: isNewElement });
|
const ref = useEditPaneInputAutoFocus({ autoFocus: isNewElement });
|
||||||
const hasUniqueTitle = tab.hasUniqueTitle();
|
const hasUniqueTitle = tab.hasUniqueTitle();
|
||||||
@@ -85,6 +87,8 @@ function TabTitleInput({ tab, isNewElement, id }: { tab: TabItem; isNewElement:
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
title={t('dashboard.tabs-layout.tab-options.title-option', 'Title')}
|
title={t('dashboard.tabs-layout.tab-options.title-option', 'Title')}
|
||||||
value={title}
|
value={title}
|
||||||
|
onFocus={() => (prevTitle.current = title || '')}
|
||||||
|
onBlur={() => editTabTitleAction(tab, title || '', prevTitle.current || '')}
|
||||||
onChange={(e) => tab.onChangeTitle(e.currentTarget.value)}
|
onChange={(e) => tab.onChangeTitle(e.currentTarget.value)}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
@@ -139,3 +143,16 @@ function TabRepeatSelect({ tab, id }: { tab: TabItem; id?: string }) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function editTabTitleAction(tab: TabItem, title: string, prevTitle: string) {
|
||||||
|
if (title === prevTitle) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dashboardEditActions.edit({
|
||||||
|
description: t('dashboard.edit-actions.tab-title', 'Change tab title'),
|
||||||
|
source: tab,
|
||||||
|
perform: () => tab.onChangeTitle(title),
|
||||||
|
undo: () => tab.onChangeTitle(prevTitle),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -4695,7 +4695,8 @@
|
|||||||
"paste-panel": "Paste panel",
|
"paste-panel": "Paste panel",
|
||||||
"remove": "Remove {{typeName}}",
|
"remove": "Remove {{typeName}}",
|
||||||
"row-title": "Change row title",
|
"row-title": "Change row title",
|
||||||
"switch-layout": "Switch layout"
|
"switch-layout": "Switch layout",
|
||||||
|
"tab-title": "Change tab title"
|
||||||
},
|
},
|
||||||
"edit-pane": {
|
"edit-pane": {
|
||||||
"elements": {
|
"elements": {
|
||||||
|
|||||||
Reference in New Issue
Block a user