LibraryPanels: Separates name from panel title (#38707)

* LibraryPanels: Separates name from panel title

* WIP

* Chore: fixes update for duplicate lib panels

* Chore: reverts implementation

* Chore: show library options only for library panels

* Chore: ui fixes after PR comments

* Chore: fixes issue when creating library panels
This commit is contained in:
Hugo Häggmark
2021-09-01 13:27:43 +02:00
committed by GitHub
parent 6cfb640a0b
commit 55e20bbf04
11 changed files with 115 additions and 64 deletions
@@ -14,35 +14,35 @@ interface AddLibraryPanelContentsProps {
export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: AddLibraryPanelContentsProps) => {
const [folderId, setFolderId] = useState(initialFolderId);
const [panelTitle, setPanelTitle] = useState(panel.title);
const [debouncedPanelTitle, setDebouncedPanelTitle] = useState(panel.title);
const [panelName, setPanelName] = useState(panel.title);
const [debouncedPanelName, setDebouncedPanelName] = useState(panel.title);
const [waiting, setWaiting] = useState(false);
useEffect(() => setWaiting(true), [panelTitle]);
useDebounce(() => setDebouncedPanelTitle(panelTitle), 350, [panelTitle]);
useEffect(() => setWaiting(true), [panelName]);
useDebounce(() => setDebouncedPanelName(panelName), 350, [panelName]);
const { saveLibraryPanel } = usePanelSave();
const onCreate = useCallback(() => {
panel.title = panelTitle;
panel.libraryPanel = { uid: undefined, name: panelName };
saveLibraryPanel(panel, folderId!).then((res) => {
if (!(res instanceof Error)) {
onDismiss();
}
});
}, [panel, panelTitle, folderId, onDismiss, saveLibraryPanel]);
const isValidTitle = useAsync(async () => {
}, [panel, panelName, folderId, onDismiss, saveLibraryPanel]);
const isValidName = useAsync(async () => {
try {
return !(await getLibraryPanelByName(panelTitle)).some((lp) => lp.folderId === folderId);
return !(await getLibraryPanelByName(panelName)).some((lp) => lp.folderId === folderId);
} catch (err) {
err.isHandled = true;
return true;
} finally {
setWaiting(false);
}
}, [debouncedPanelTitle, folderId]);
}, [debouncedPanelName, folderId]);
const invalidInput =
!isValidTitle?.value && isValidTitle.value !== undefined && panelTitle === debouncedPanelTitle && !waiting;
!isValidName?.value && isValidName.value !== undefined && panelName === debouncedPanelName && !waiting;
return (
<>
@@ -51,7 +51,7 @@ export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: A
invalid={invalidInput}
error={invalidInput ? 'Library panel with this name already exists' : ''}
>
<Input name="name" value={panelTitle} onChange={(e) => setPanelTitle(e.currentTarget.value)} />
<Input name="name" value={panelName} onChange={(e) => setPanelName(e.currentTarget.value)} />
</Field>
<Field label="Save in folder" description="Library panel permissions are derived from the folder permissions">
<FolderPicker onChange={({ id }) => setFolderId(id)} initialFolderId={initialFolderId} />
@@ -18,11 +18,12 @@ export const LibraryPanelInformation: React.FC<Props> = ({ panel, formatDate })
}
return (
<>
<p className={styles.libraryPanelInfo}>
<div className={styles.info}>
<div className={styles.libraryPanelInfo}>
{`Used on ${panel.libraryPanel.meta.connectedDashboards} `}
{panel.libraryPanel.meta.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}
<br />
</div>
<div className={styles.libraryPanelInfo}>
Last edited on {formatDate?.(panel.libraryPanel.meta.updated, 'L') ?? panel.libraryPanel.meta.updated} by
{panel.libraryPanel.meta.updatedBy.avatarUrl && (
<img
@@ -34,17 +35,19 @@ export const LibraryPanelInformation: React.FC<Props> = ({ panel, formatDate })
/>
)}
{panel.libraryPanel.meta.updatedBy.name}
</p>
</>
</div>
</div>
);
};
const getStyles = (theme: GrafanaTheme) => {
return {
info: css`
line-height: 1;
`,
libraryPanelInfo: css`
color: ${theme.colors.textSemiWeak};
font-size: ${theme.typography.size.sm};
margin-left: ${theme.spacing.xxs};
`,
userAvatar: css`
border-radius: 50%;
@@ -59,7 +59,7 @@ export async function addLibraryPanel(
): Promise<LibraryElementDTO> {
const { result } = await getBackendSrv().post(`/api/library-elements`, {
folderId,
name: panelSaveModel.title,
name: panelSaveModel.libraryPanel.name,
model: panelSaveModel,
kind: LibraryElementKind.Panel,
});
@@ -70,12 +70,15 @@ export async function updateLibraryPanel(
panelSaveModel: PanelModelWithLibraryPanel,
folderId: number
): Promise<LibraryElementDTO> {
const { result } = await getBackendSrv().patch(`/api/library-elements/${panelSaveModel.libraryPanel.uid}`, {
const { uid, name, version } = panelSaveModel.libraryPanel;
const kind = LibraryElementKind.Panel;
const model = panelSaveModel;
const { result } = await getBackendSrv().patch(`/api/library-elements/${uid}`, {
folderId,
name: panelSaveModel.title,
model: panelSaveModel,
version: panelSaveModel.libraryPanel.version,
kind: LibraryElementKind.Panel,
name,
model,
version,
kind,
});
return result;
}
+1 -1
View File
@@ -42,6 +42,7 @@ function updatePanelModelWithUpdate(panel: PanelModel, updated: LibraryElementDT
...updated.model,
configRev: 0, // reset config rev, since changes have been saved
libraryPanel: toPanelModelLibraryPanel(updated),
title: panel.title,
});
panel.refresh();
}
@@ -52,7 +53,6 @@ function saveOrUpdateLibraryPanel(panel: any, folderId: number): Promise<Library
}
if (panel.libraryPanel && panel.libraryPanel.uid === undefined) {
panel.libraryPanel.name = panel.title;
return addLibraryPanel(panel, folderId!);
}