mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Command Palette: Display dashboard location (#63807)
* show folder for dashboard, adjust how ancestors are displayed, clamp to single line * fix keys * better responsiveness * use subtitle consistently * use span instead of div
This commit is contained in:
parent
b009ba6cd4
commit
27635e6f7b
@ -35,11 +35,12 @@ export const ResultItem = React.forwardRef(
|
||||
|
||||
let name = action.name;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const hasAction = Boolean(action.command?.perform || (action as ActionImpl & { url?: string }).url);
|
||||
const hasCommandOrLink = (action: ActionImpl) =>
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
Boolean(action.command?.perform || (action as ActionImpl & { url?: string }).url);
|
||||
|
||||
// TODO: does this needs adjusting for i18n?
|
||||
if (action.children.length && !hasAction && !name.endsWith('...')) {
|
||||
if (action.children.length && !hasCommandOrLink(action) && !name.endsWith('...')) {
|
||||
name += '...';
|
||||
}
|
||||
|
||||
@ -48,16 +49,17 @@ export const ResultItem = React.forwardRef(
|
||||
<div className={styles.actionContainer}>
|
||||
{action.icon}
|
||||
<div className={styles.textContainer}>
|
||||
<div>
|
||||
{ancestors.length > 0 &&
|
||||
ancestors.map((ancestor) => (
|
||||
<React.Fragment key={ancestor.id}>
|
||||
{ancestors.map((ancestor) => (
|
||||
<React.Fragment key={ancestor.id}>
|
||||
{!hasCommandOrLink(ancestor) && (
|
||||
<>
|
||||
<span className={styles.breadcrumbAncestor}>{ancestor.name}</span>
|
||||
<span className={styles.breadcrumbAncestor}>›</span>
|
||||
</React.Fragment>
|
||||
))}
|
||||
<span>{name}</span>
|
||||
</div>
|
||||
<span className={styles.breadcrumbSeparator}>›</span>
|
||||
</>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
<span>{name}</span>
|
||||
</div>
|
||||
{action.subtitle && <span className={styles.subtitleText}>{action.subtitle}</span>}
|
||||
</div>
|
||||
@ -98,30 +100,35 @@ const getResultItemStyles = (theme: GrafanaTheme2) => {
|
||||
actionContainer: css({
|
||||
display: 'flex',
|
||||
gap: theme.spacing(1),
|
||||
alignItems: 'center',
|
||||
alignItems: 'baseline',
|
||||
fontSize: theme.typography.fontSize,
|
||||
width: '100%',
|
||||
}),
|
||||
textContainer: css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}),
|
||||
shortcut: css({
|
||||
padding: theme.spacing(0, 1),
|
||||
background: theme.colors.background.secondary,
|
||||
borderRadius: theme.shape.borderRadius(),
|
||||
fontSize: theme.typography.fontSize,
|
||||
display: 'block',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
}),
|
||||
breadcrumbAncestor: css({
|
||||
marginRight: theme.spacing(1),
|
||||
color: theme.colors.text.secondary,
|
||||
}),
|
||||
subtitleText: css({
|
||||
fontSize: theme.typography.fontSize - 2,
|
||||
breadcrumbSeparator: css({
|
||||
color: theme.colors.text.secondary,
|
||||
marginLeft: theme.spacing(1),
|
||||
marginRight: theme.spacing(1),
|
||||
}),
|
||||
shortcutContainer: css({
|
||||
display: 'grid',
|
||||
gridAutoFlow: 'column',
|
||||
gap: theme.spacing(1),
|
||||
subtitleText: css({
|
||||
...theme.typography.bodySmall,
|
||||
color: theme.colors.text.secondary,
|
||||
display: 'block',
|
||||
flexBasis: '20%',
|
||||
flexGrow: 1,
|
||||
flexShrink: 0,
|
||||
maxWidth: 'fit-content',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
@ -57,7 +57,7 @@ export async function getSearchResultActions(searchQuery: string): Promise<Comma
|
||||
});
|
||||
|
||||
const goToSearchResultActions: CommandPaletteAction[] = data.view.map((item) => {
|
||||
const { url, name, kind } = item; // items are backed by DataFrameView, so must hold the url in a closure
|
||||
const { url, name, kind, location } = item; // items are backed by DataFrameView, so must hold the url in a closure
|
||||
return {
|
||||
id: `go/${kind}${url}`,
|
||||
name: `${name}`,
|
||||
@ -67,6 +67,7 @@ export async function getSearchResultActions(searchQuery: string): Promise<Comma
|
||||
: t('command-palette.section.folder-search-results', 'Folders'),
|
||||
priority: SEARCH_RESULTS_PRORITY,
|
||||
url: locationUtil.stripBaseFromUrl(url),
|
||||
subtitle: data.view.dataFrame.meta?.custom?.locationInfo[location]?.name,
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,7 @@ function idForNavItem(navItem: NavModelItem) {
|
||||
return 'navModel.' + navItem.id ?? navItem.url ?? navItem.text ?? navItem.subTitle;
|
||||
}
|
||||
|
||||
function navTreeToActions(navTree: NavModelItem[], parent?: NavModelItem): CommandPaletteAction[] {
|
||||
function navTreeToActions(navTree: NavModelItem[], parents: NavModelItem[] = []): CommandPaletteAction[] {
|
||||
const navActions: CommandPaletteAction[] = [];
|
||||
|
||||
for (const navItem of navTree) {
|
||||
@ -27,19 +27,21 @@ function navTreeToActions(navTree: NavModelItem[], parent?: NavModelItem): Comma
|
||||
|
||||
const priority = isCreateAction ? ACTIONS_PRIORITY : DEFAULT_PRIORITY;
|
||||
|
||||
const subtitle = parents.map((parent) => parent.text).join(' > ');
|
||||
const action = {
|
||||
id: idForNavItem(navItem),
|
||||
name: text, // TODO: translate
|
||||
name: text,
|
||||
section: section,
|
||||
url: url && locationUtil.stripBaseFromUrl(url),
|
||||
parent: parent && !isCreateAction && idForNavItem(parent),
|
||||
parent: parents.length > 0 && !isCreateAction ? idForNavItem(parents[parents.length - 1]) : undefined,
|
||||
priority: priority,
|
||||
subtitle: isCreateAction ? undefined : subtitle,
|
||||
};
|
||||
|
||||
navActions.push(action);
|
||||
|
||||
if (children?.length) {
|
||||
const childActions = navTreeToActions(children, navItem);
|
||||
const childActions = navTreeToActions(children, [...parents, navItem]);
|
||||
navActions.push(...childActions);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user