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:
Leo
2022-11-17 09:22:57 +01:00
committed by GitHub
parent ab36252c86
commit 27b6b3b3bd
37 changed files with 194 additions and 173 deletions
@@ -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>
);
};
@@ -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,
@@ -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,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,
+1 -1
View File
@@ -32,7 +32,7 @@ export interface LibraryElementsSearchResult {
export interface LibraryElementDTO {
id: number;
orgId: number;
folderId: number;
folderUid: string;
uid: string;
name: string;
kind: LibraryElementKind;
+4 -4
View File
@@ -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;