mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
Folder: Replace folderId with folderUid (#58393)
* support folderuid in FolderPicker * support folderuid in unified alerting * support folderuid when returning to view mode after editing a panel * support folderuid when preselecting the folderpicker in dashboard general settings * support folderuid when saving dashboard * support folderuid when pre-selecting folderpicker in dashboard form * support folderuid in routes when loading a dashboard * support folderuid when saving dashboard json * support folderuid when validating new dashboard name * support folderuid when moving dashboard to another folder * support folderuid on dashboard action buttons * support folderuid when creating a new dashboard on an empty folder * support folderuid when showing library panel modal * support folderuid when saving library panel * support folderuid when importing dashboard * fixed broken tests * use folderuid when importing dashboards * remove commented line * fix typo when comparing uid values
This commit is contained in:
+11
-11
@@ -13,11 +13,11 @@ import { usePanelSave } from '../../utils/usePanelSave';
|
||||
interface AddLibraryPanelContentsProps {
|
||||
onDismiss: () => void;
|
||||
panel: PanelModel;
|
||||
initialFolderId?: number;
|
||||
initialFolderUid?: string;
|
||||
}
|
||||
|
||||
export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: AddLibraryPanelContentsProps) => {
|
||||
const [folderId, setFolderId] = useState(initialFolderId);
|
||||
export const AddLibraryPanelContents = ({ panel, initialFolderUid, onDismiss }: AddLibraryPanelContentsProps) => {
|
||||
const [folderUid, setFolderUid] = useState(initialFolderUid);
|
||||
const [panelName, setPanelName] = useState(panel.title);
|
||||
const [debouncedPanelName, setDebouncedPanelName] = useState(panel.title);
|
||||
const [waiting, setWaiting] = useState(false);
|
||||
@@ -28,15 +28,15 @@ export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: A
|
||||
const { saveLibraryPanel } = usePanelSave();
|
||||
const onCreate = useCallback(() => {
|
||||
panel.libraryPanel = { uid: '', name: panelName };
|
||||
saveLibraryPanel(panel, folderId!).then((res) => {
|
||||
saveLibraryPanel(panel, folderUid!).then((res) => {
|
||||
if (!(res instanceof Error)) {
|
||||
onDismiss();
|
||||
}
|
||||
});
|
||||
}, [panel, panelName, folderId, onDismiss, saveLibraryPanel]);
|
||||
}, [panel, panelName, folderUid, onDismiss, saveLibraryPanel]);
|
||||
const isValidName = useAsync(async () => {
|
||||
try {
|
||||
return !(await getLibraryPanelByName(panelName)).some((lp) => lp.folderId === folderId);
|
||||
return !(await getLibraryPanelByName(panelName)).some((lp) => lp.folderUid === folderUid);
|
||||
} catch (err) {
|
||||
if (isFetchError(err)) {
|
||||
err.isHandled = true;
|
||||
@@ -45,7 +45,7 @@ export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: A
|
||||
} finally {
|
||||
setWaiting(false);
|
||||
}
|
||||
}, [debouncedPanelName, folderId]);
|
||||
}, [debouncedPanelName, folderUid]);
|
||||
|
||||
const invalidInput =
|
||||
!isValidName?.value && isValidName.value !== undefined && panelName === debouncedPanelName && !waiting;
|
||||
@@ -72,8 +72,8 @@ export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: A
|
||||
)}
|
||||
>
|
||||
<FolderPicker
|
||||
onChange={({ id }) => setFolderId(id)}
|
||||
initialFolderId={initialFolderId}
|
||||
onChange={({ uid }) => setFolderUid(uid)}
|
||||
initialFolderUid={initialFolderUid}
|
||||
inputId="share-panel-library-panel-folder-picker"
|
||||
/>
|
||||
</Field>
|
||||
@@ -94,10 +94,10 @@ interface Props extends AddLibraryPanelContentsProps {
|
||||
isOpen?: boolean;
|
||||
}
|
||||
|
||||
export const AddLibraryPanelModal = ({ isOpen = false, panel, initialFolderId, ...props }: Props) => {
|
||||
export const AddLibraryPanelModal = ({ isOpen = false, panel, initialFolderUid, ...props }: Props) => {
|
||||
return (
|
||||
<Modal title="Create library panel" isOpen={isOpen} onDismiss={props.onDismiss}>
|
||||
<AddLibraryPanelContents panel={panel} initialFolderId={initialFolderId} onDismiss={props.onDismiss} />
|
||||
<AddLibraryPanelContents panel={panel} initialFolderUid={initialFolderUid} onDismiss={props.onDismiss} />
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
+6
-6
@@ -28,9 +28,9 @@ jest.mock('debounce-promise', () => {
|
||||
const debounce = (fn: any) => {
|
||||
const debounced = () =>
|
||||
Promise.resolve([
|
||||
{ label: 'General', value: { id: 0, title: 'General' } },
|
||||
{ label: 'Folder1', value: { id: 1, title: 'Folder1' } },
|
||||
{ label: 'Folder2', value: { id: 2, title: 'Folder2' } },
|
||||
{ label: 'General', value: { uid: '', title: 'General' } },
|
||||
{ label: 'Folder1', value: { id: 'xMsQdBfWz', title: 'Folder1' } },
|
||||
{ label: 'Folder2', value: { id: 'wfTJJL5Wz', title: 'Folder2' } },
|
||||
]);
|
||||
return debounced;
|
||||
};
|
||||
@@ -187,7 +187,7 @@ describe('LibraryPanelsSearch', () => {
|
||||
kind: LibraryElementKind.Panel,
|
||||
uid: 'uid',
|
||||
description: 'Library Panel Description',
|
||||
folderId: 0,
|
||||
folderUid: '',
|
||||
model: { type: 'timeseries', title: 'A title' },
|
||||
type: 'timeseries',
|
||||
orgId: 1,
|
||||
@@ -242,7 +242,7 @@ describe('LibraryPanelsSearch', () => {
|
||||
kind: LibraryElementKind.Panel,
|
||||
uid: 'uid',
|
||||
description: 'Library Panel Description',
|
||||
folderId: 0,
|
||||
folderUid: '',
|
||||
model: { type: 'timeseries', title: 'A title' },
|
||||
type: 'timeseries',
|
||||
orgId: 1,
|
||||
@@ -286,7 +286,7 @@ describe('LibraryPanelsSearch', () => {
|
||||
kind: LibraryElementKind.Panel,
|
||||
uid: 'uid',
|
||||
description: 'Library Panel Description',
|
||||
folderId: 0,
|
||||
folderUid: '',
|
||||
model: { type: 'timeseries', title: 'A title' },
|
||||
type: 'timeseries',
|
||||
orgId: 1,
|
||||
|
||||
@@ -106,7 +106,7 @@ function mockLibraryPanel({
|
||||
uid = '1',
|
||||
id = 1,
|
||||
orgId = 1,
|
||||
folderId = 0,
|
||||
folderUid = '',
|
||||
name = 'Test Panel',
|
||||
model = { type: 'text', title: 'Test Panel' },
|
||||
meta = {
|
||||
@@ -126,7 +126,7 @@ function mockLibraryPanel({
|
||||
uid,
|
||||
id,
|
||||
orgId,
|
||||
folderId,
|
||||
folderUid,
|
||||
name,
|
||||
kind: LibraryElementKind.Panel,
|
||||
model,
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ export const PanelLibraryOptionsGroup: FC<Props> = ({ panel, searchQuery }) => {
|
||||
<AddLibraryPanelModal
|
||||
panel={panel}
|
||||
onDismiss={() => setShowingAddPanelModal(false)}
|
||||
initialFolderId={dashboard?.meta.folderId}
|
||||
initialFolderUid={dashboard?.meta.folderUid}
|
||||
isOpen={showingAddPanelModal}
|
||||
/>
|
||||
)}
|
||||
|
||||
+10
-3
@@ -10,14 +10,21 @@ import { usePanelSave } from '../../utils/usePanelSave';
|
||||
|
||||
interface Props {
|
||||
panel: PanelModelWithLibraryPanel;
|
||||
folderId: number;
|
||||
folderUid: string;
|
||||
isUnsavedPrompt?: boolean;
|
||||
onConfirm: () => void;
|
||||
onDismiss: () => void;
|
||||
onDiscard: () => void;
|
||||
}
|
||||
|
||||
export const SaveLibraryPanelModal = ({ panel, folderId, isUnsavedPrompt, onDismiss, onConfirm, onDiscard }: Props) => {
|
||||
export const SaveLibraryPanelModal = ({
|
||||
panel,
|
||||
folderUid,
|
||||
isUnsavedPrompt,
|
||||
onDismiss,
|
||||
onConfirm,
|
||||
onDiscard,
|
||||
}: Props) => {
|
||||
const [searchString, setSearchString] = useState('');
|
||||
const dashState = useAsync(async () => {
|
||||
const searchHits = await getConnectedDashboards(panel.libraryPanel.uid);
|
||||
@@ -98,7 +105,7 @@ export const SaveLibraryPanelModal = ({ panel, folderId, isUnsavedPrompt, onDism
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
saveLibraryPanel(panel, folderId).then(() => {
|
||||
saveLibraryPanel(panel, folderUid).then(() => {
|
||||
onConfirm();
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -77,10 +77,10 @@ export async function getLibraryPanelByName(name: string): Promise<LibraryElemen
|
||||
|
||||
export async function addLibraryPanel(
|
||||
panelSaveModel: PanelModelWithLibraryPanel,
|
||||
folderId: number
|
||||
folderUid: string
|
||||
): Promise<LibraryElementDTO> {
|
||||
const { result } = await getBackendSrv().post(`/api/library-elements`, {
|
||||
folderId,
|
||||
folderUid,
|
||||
name: panelSaveModel.libraryPanel.name,
|
||||
model: panelSaveModel,
|
||||
kind: LibraryElementKind.Panel,
|
||||
|
||||
@@ -32,7 +32,7 @@ export interface LibraryElementsSearchResult {
|
||||
export interface LibraryElementDTO {
|
||||
id: number;
|
||||
orgId: number;
|
||||
folderId: number;
|
||||
folderUid: string;
|
||||
uid: string;
|
||||
name: string;
|
||||
kind: LibraryElementKind;
|
||||
|
||||
@@ -13,9 +13,9 @@ export function createPanelLibrarySuccessNotification(message: string): AppNotif
|
||||
return createSuccessNotification(message);
|
||||
}
|
||||
|
||||
export async function saveAndRefreshLibraryPanel(panel: PanelModel, folderId: number): Promise<LibraryElementDTO> {
|
||||
export async function saveAndRefreshLibraryPanel(panel: PanelModel, folderUid: string): Promise<LibraryElementDTO> {
|
||||
const panelSaveModel = toPanelSaveModel(panel);
|
||||
const savedPanel = await saveOrUpdateLibraryPanel(panelSaveModel, folderId);
|
||||
const savedPanel = await saveOrUpdateLibraryPanel(panelSaveModel, folderUid);
|
||||
updatePanelModelWithUpdate(panel, savedPanel);
|
||||
return savedPanel;
|
||||
}
|
||||
@@ -44,13 +44,13 @@ function updatePanelModelWithUpdate(panel: PanelModel, updated: LibraryElementDT
|
||||
panel.refresh();
|
||||
}
|
||||
|
||||
function saveOrUpdateLibraryPanel(panel: any, folderId: number): Promise<LibraryElementDTO> {
|
||||
function saveOrUpdateLibraryPanel(panel: any, folderUid: string): Promise<LibraryElementDTO> {
|
||||
if (!panel.libraryPanel) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
if (panel.libraryPanel && panel.libraryPanel.uid === '') {
|
||||
return addLibraryPanel(panel, folderId!);
|
||||
return addLibraryPanel(panel, folderUid!);
|
||||
}
|
||||
|
||||
return updateLibraryPanel(panel);
|
||||
|
||||
@@ -15,9 +15,9 @@ import {
|
||||
|
||||
export const usePanelSave = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [state, saveLibraryPanel] = useAsyncFn(async (panel: PanelModel, folderId: number) => {
|
||||
const [state, saveLibraryPanel] = useAsyncFn(async (panel: PanelModel, folderUid: string) => {
|
||||
try {
|
||||
return await saveAndRefreshLibraryPanel(panel, folderId);
|
||||
return await saveAndRefreshLibraryPanel(panel, folderUid);
|
||||
} catch (err) {
|
||||
if (isFetchError(err)) {
|
||||
err.isHandled = true;
|
||||
|
||||
Reference in New Issue
Block a user