mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Preferences: Support setting any dashboard as home, not just the starred ones (#54258)
This commit is contained in:
@@ -2900,9 +2900,6 @@ exports[`better eslint`] = {
|
|||||||
"public/app/core/components/Select/SortPicker.tsx:5381": [
|
"public/app/core/components/Select/SortPicker.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||||
],
|
],
|
||||||
"public/app/core/components/SharedPreferences/SharedPreferences.tsx:5381": [
|
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
|
||||||
],
|
|
||||||
"public/app/core/components/TagFilter/TagBadge.tsx:5381": [
|
"public/app/core/components/TagFilter/TagBadge.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||||
|
|||||||
@@ -31,12 +31,16 @@ func (hs *HTTPServer) SetHomeDashboard(c *models.ReqContext) response.Response {
|
|||||||
dashboardID := cmd.HomeDashboardID
|
dashboardID := cmd.HomeDashboardID
|
||||||
if cmd.HomeDashboardUID != nil {
|
if cmd.HomeDashboardUID != nil {
|
||||||
query := models.GetDashboardQuery{Uid: *cmd.HomeDashboardUID}
|
query := models.GetDashboardQuery{Uid: *cmd.HomeDashboardUID}
|
||||||
|
if query.Uid == "" {
|
||||||
|
dashboardID = 0 // clear the value
|
||||||
|
} else {
|
||||||
err := hs.DashboardService.GetDashboard(c.Req.Context(), &query)
|
err := hs.DashboardService.GetDashboard(c.Req.Context(), &query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(404, "Dashboard not found", err)
|
return response.Error(404, "Dashboard not found", err)
|
||||||
}
|
}
|
||||||
dashboardID = query.Result.Id
|
dashboardID = query.Result.Id
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cmd.HomeDashboardID = dashboardID
|
cmd.HomeDashboardID = dashboardID
|
||||||
|
|
||||||
@@ -122,12 +126,17 @@ func (hs *HTTPServer) updatePreferencesFor(ctx context.Context, orgID, userID, t
|
|||||||
dashboardID := dtoCmd.HomeDashboardID
|
dashboardID := dtoCmd.HomeDashboardID
|
||||||
if dtoCmd.HomeDashboardUID != nil {
|
if dtoCmd.HomeDashboardUID != nil {
|
||||||
query := models.GetDashboardQuery{Uid: *dtoCmd.HomeDashboardUID, OrgId: orgID}
|
query := models.GetDashboardQuery{Uid: *dtoCmd.HomeDashboardUID, OrgId: orgID}
|
||||||
|
if query.Uid == "" {
|
||||||
|
// clear the value
|
||||||
|
dashboardID = 0
|
||||||
|
} else {
|
||||||
err := hs.DashboardService.GetDashboard(ctx, &query)
|
err := hs.DashboardService.GetDashboard(ctx, &query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(404, "Dashboard not found", err)
|
return response.Error(404, "Dashboard not found", err)
|
||||||
}
|
}
|
||||||
dashboardID = query.Result.Id
|
dashboardID = query.Result.Id
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dtoCmd.HomeDashboardID = dashboardID
|
dtoCmd.HomeDashboardID = dashboardID
|
||||||
|
|
||||||
saveCmd := pref.SavePreferenceCommand{
|
saveCmd := pref.SavePreferenceCommand{
|
||||||
@@ -176,12 +185,18 @@ func (hs *HTTPServer) patchPreferencesFor(ctx context.Context, orgID, userID, te
|
|||||||
dashboardID := dtoCmd.HomeDashboardID
|
dashboardID := dtoCmd.HomeDashboardID
|
||||||
if dtoCmd.HomeDashboardUID != nil {
|
if dtoCmd.HomeDashboardUID != nil {
|
||||||
query := models.GetDashboardQuery{Uid: *dtoCmd.HomeDashboardUID, OrgId: orgID}
|
query := models.GetDashboardQuery{Uid: *dtoCmd.HomeDashboardUID, OrgId: orgID}
|
||||||
|
if query.Uid == "" {
|
||||||
|
// clear the value
|
||||||
|
defaultDash := int64(0)
|
||||||
|
dashboardID = &defaultDash
|
||||||
|
} else {
|
||||||
err := hs.DashboardService.GetDashboard(ctx, &query)
|
err := hs.DashboardService.GetDashboard(ctx, &query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return response.Error(404, "Dashboard not found", err)
|
return response.Error(404, "Dashboard not found", err)
|
||||||
}
|
}
|
||||||
dashboardID = &query.Result.Id
|
dashboardID = &query.Result.Id
|
||||||
}
|
}
|
||||||
|
}
|
||||||
dtoCmd.HomeDashboardID = dashboardID
|
dtoCmd.HomeDashboardID = dashboardID
|
||||||
|
|
||||||
patchCmd := pref.PatchPreferenceCommand{
|
patchCmd := pref.PatchPreferenceCommand{
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export const DashboardPicker = ({
|
|||||||
// value was manually changed from outside or we are rendering for the first time.
|
// value was manually changed from outside or we are rendering for the first time.
|
||||||
// We need to fetch dashboard information.
|
// We need to fetch dashboard information.
|
||||||
const res = await backendSrv.getDashboardByUid(value);
|
const res = await backendSrv.getDashboardByUid(value);
|
||||||
|
if (res.dashboard) {
|
||||||
setCurrent({
|
setCurrent({
|
||||||
value: {
|
value: {
|
||||||
uid: res.dashboard.uid,
|
uid: res.dashboard.uid,
|
||||||
@@ -62,6 +63,7 @@ export const DashboardPicker = ({
|
|||||||
},
|
},
|
||||||
label: formatLabel(res.meta?.folderTitle, res.dashboard.title),
|
label: formatLabel(res.meta?.folderTitle, res.dashboard.title),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
// we don't need to rerun this effect every time `current` changes
|
// we don't need to rerun this effect every time `current` changes
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
|||||||
@@ -161,7 +161,6 @@ describe('SharedPreferences', () => {
|
|||||||
const darkThemeRadio = assertInstanceOf(screen.getByLabelText('Dark'), HTMLInputElement);
|
const darkThemeRadio = assertInstanceOf(screen.getByLabelText('Dark'), HTMLInputElement);
|
||||||
await userEvent.click(darkThemeRadio);
|
await userEvent.click(darkThemeRadio);
|
||||||
|
|
||||||
await selectOptionInTest(screen.getByLabelText('Home Dashboard'), 'Another Dashboard');
|
|
||||||
await selectOptionInTest(screen.getByLabelText('Timezone'), 'Australia/Sydney');
|
await selectOptionInTest(screen.getByLabelText('Timezone'), 'Australia/Sydney');
|
||||||
await selectOptionInTest(screen.getByLabelText('Week start'), 'Saturday');
|
await selectOptionInTest(screen.getByLabelText('Week start'), 'Saturday');
|
||||||
await selectOptionInTest(screen.getByLabelText(/language/i), 'French');
|
await selectOptionInTest(screen.getByLabelText(/language/i), 'French');
|
||||||
@@ -171,7 +170,7 @@ describe('SharedPreferences', () => {
|
|||||||
timezone: 'Australia/Sydney',
|
timezone: 'Australia/Sydney',
|
||||||
weekStart: 'saturday',
|
weekStart: 'saturday',
|
||||||
theme: 'dark',
|
theme: 'dark',
|
||||||
homeDashboardUID: 'anotherDash',
|
homeDashboardUID: 'myDash',
|
||||||
queryHistory: {
|
queryHistory: {
|
||||||
homeTab: '',
|
homeTab: '',
|
||||||
},
|
},
|
||||||
@@ -193,7 +192,7 @@ describe('SharedPreferences', () => {
|
|||||||
timezone: 'browser',
|
timezone: 'browser',
|
||||||
weekStart: '',
|
weekStart: '',
|
||||||
theme: '',
|
theme: '',
|
||||||
homeDashboardUID: undefined,
|
homeDashboardUID: 'myDash',
|
||||||
queryHistory: {
|
queryHistory: {
|
||||||
homeTab: '',
|
homeTab: '',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,33 +10,25 @@ import {
|
|||||||
Field,
|
Field,
|
||||||
FieldSet,
|
FieldSet,
|
||||||
Form,
|
Form,
|
||||||
Icon,
|
|
||||||
Label,
|
Label,
|
||||||
RadioButtonGroup,
|
RadioButtonGroup,
|
||||||
Select,
|
Select,
|
||||||
stylesFactory,
|
stylesFactory,
|
||||||
TimeZonePicker,
|
TimeZonePicker,
|
||||||
Tooltip,
|
|
||||||
WeekStartPicker,
|
WeekStartPicker,
|
||||||
FeatureBadge,
|
FeatureBadge,
|
||||||
} from '@grafana/ui';
|
} from '@grafana/ui';
|
||||||
|
import { DashboardPicker } from 'app/core/components/Select/DashboardPicker';
|
||||||
import { ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN } from 'app/core/internationalization/constants';
|
import { ENGLISH_US, FRENCH_FRANCE, SPANISH_SPAIN } from 'app/core/internationalization/constants';
|
||||||
import { PreferencesService } from 'app/core/services/PreferencesService';
|
import { PreferencesService } from 'app/core/services/PreferencesService';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv';
|
import { UserPreferencesDTO } from 'app/types';
|
||||||
import { DashboardSearchItem, DashboardSearchItemType } from 'app/features/search/types';
|
|
||||||
|
|
||||||
import { UserPreferencesDTO } from '../../../types';
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
resourceUri: string;
|
resourceUri: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DefaultDashboardSearchItem = Omit<DashboardSearchItem, 'uid'> & { uid?: string };
|
export type State = UserPreferencesDTO;
|
||||||
|
|
||||||
export type State = UserPreferencesDTO & {
|
|
||||||
dashboards: DashboardSearchItem[] | DefaultDashboardSearchItem[];
|
|
||||||
};
|
|
||||||
|
|
||||||
const themes: SelectableValue[] = [
|
const themes: SelectableValue[] = [
|
||||||
{ value: '', label: t({ id: 'shared-preferences.theme.default-label', message: 'Default' }) },
|
{ value: '', label: t({ id: 'shared-preferences.theme.default-label', message: 'Default' }) },
|
||||||
@@ -77,21 +69,6 @@ const languages: Array<SelectableValue<string>> = [
|
|||||||
|
|
||||||
const i18nFlag = Boolean(config.featureToggles.internationalization);
|
const i18nFlag = Boolean(config.featureToggles.internationalization);
|
||||||
|
|
||||||
const DEFAULT_DASHBOARD_HOME: DefaultDashboardSearchItem = {
|
|
||||||
title: 'Default',
|
|
||||||
tags: [],
|
|
||||||
type: '' as DashboardSearchItemType,
|
|
||||||
uid: undefined,
|
|
||||||
uri: '',
|
|
||||||
url: '',
|
|
||||||
folderTitle: '',
|
|
||||||
folderUid: '',
|
|
||||||
folderUrl: '',
|
|
||||||
isStarred: false,
|
|
||||||
slug: '',
|
|
||||||
items: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
export class SharedPreferences extends PureComponent<Props, State> {
|
export class SharedPreferences extends PureComponent<Props, State> {
|
||||||
service: PreferencesService;
|
service: PreferencesService;
|
||||||
|
|
||||||
@@ -100,27 +77,16 @@ export class SharedPreferences extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
this.service = new PreferencesService(props.resourceUri);
|
this.service = new PreferencesService(props.resourceUri);
|
||||||
this.state = {
|
this.state = {
|
||||||
homeDashboardUID: DEFAULT_DASHBOARD_HOME.uid,
|
|
||||||
theme: '',
|
theme: '',
|
||||||
timezone: '',
|
timezone: '',
|
||||||
weekStart: '',
|
weekStart: '',
|
||||||
locale: '',
|
locale: '',
|
||||||
dashboards: [],
|
|
||||||
queryHistory: { homeTab: '' },
|
queryHistory: { homeTab: '' },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const prefs = await this.service.load();
|
const prefs = await this.service.load();
|
||||||
const dashboards = await backendSrv.search({ starred: true });
|
|
||||||
|
|
||||||
if (prefs.homeDashboardUID && !dashboards.find((d) => d.uid === prefs.homeDashboardUID)) {
|
|
||||||
const missingDash = await backendSrv.search({ dashboardUIDs: prefs.homeDashboardUID });
|
|
||||||
|
|
||||||
if (missingDash.length > 0) {
|
|
||||||
dashboards.push(missingDash[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
homeDashboardUID: prefs.homeDashboardUID,
|
homeDashboardUID: prefs.homeDashboardUID,
|
||||||
@@ -128,7 +94,6 @@ export class SharedPreferences extends PureComponent<Props, State> {
|
|||||||
timezone: prefs.timezone,
|
timezone: prefs.timezone,
|
||||||
weekStart: prefs.weekStart,
|
weekStart: prefs.weekStart,
|
||||||
locale: prefs.locale,
|
locale: prefs.locale,
|
||||||
dashboards: [DEFAULT_DASHBOARD_HOME, ...dashboards],
|
|
||||||
queryHistory: prefs.queryHistory,
|
queryHistory: prefs.queryHistory,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -162,30 +127,11 @@ export class SharedPreferences extends PureComponent<Props, State> {
|
|||||||
this.setState({ locale });
|
this.setState({ locale });
|
||||||
};
|
};
|
||||||
|
|
||||||
getFullDashName = (dashboard: SelectableValue<DashboardSearchItem>) => {
|
|
||||||
if (typeof dashboard.folderTitle === 'undefined' || dashboard.folderTitle === '') {
|
|
||||||
return dashboard.title;
|
|
||||||
}
|
|
||||||
return dashboard.folderTitle + ' / ' + dashboard.title;
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { theme, timezone, weekStart, homeDashboardUID, locale, dashboards } = this.state;
|
const { theme, timezone, weekStart, homeDashboardUID, locale } = this.state;
|
||||||
const { disabled } = this.props;
|
const { disabled } = this.props;
|
||||||
const styles = getStyles();
|
const styles = getStyles();
|
||||||
|
|
||||||
const homeDashboardTooltip = (
|
|
||||||
<Tooltip
|
|
||||||
content={
|
|
||||||
<Trans id="shared-preferences.fields.home-dashboard-tooltip">
|
|
||||||
Not finding the dashboard you want? Star it first, then it should appear in this select box.
|
|
||||||
</Trans>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Icon name="info-circle" />
|
|
||||||
</Tooltip>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={this.onSubmitForm}>
|
<Form onSubmit={this.onSubmitForm}>
|
||||||
{() => {
|
{() => {
|
||||||
@@ -205,23 +151,18 @@ export class SharedPreferences extends PureComponent<Props, State> {
|
|||||||
<span className={styles.labelText}>
|
<span className={styles.labelText}>
|
||||||
<Trans id="shared-preferences.fields.home-dashboard-label">Home Dashboard</Trans>
|
<Trans id="shared-preferences.fields.home-dashboard-label">Home Dashboard</Trans>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{homeDashboardTooltip}
|
|
||||||
</Label>
|
</Label>
|
||||||
}
|
}
|
||||||
data-testid="User preferences home dashboard drop down"
|
data-testid="User preferences home dashboard drop down"
|
||||||
>
|
>
|
||||||
<Select
|
<DashboardPicker
|
||||||
value={dashboards.find((dashboard) => dashboard.uid === homeDashboardUID)}
|
value={homeDashboardUID}
|
||||||
getOptionValue={(i) => i.uid}
|
onChange={(v) => this.onHomeDashboardChanged(v?.uid ?? '')}
|
||||||
getOptionLabel={this.getFullDashName}
|
defaultOptions={true}
|
||||||
onChange={(dashboard: SelectableValue<DashboardSearchItem>) =>
|
isClearable={true}
|
||||||
this.onHomeDashboardChanged(dashboard.uid)
|
|
||||||
}
|
|
||||||
options={dashboards}
|
|
||||||
placeholder={t({
|
placeholder={t({
|
||||||
id: 'shared-preferences.fields.home-dashboard-placeholder',
|
id: 'shared-preferences.fields.home-dashboard-placeholder',
|
||||||
message: 'Choose default dashboard',
|
message: 'Default dashboard',
|
||||||
})}
|
})}
|
||||||
inputId="home-dashboard-select"
|
inputId="home-dashboard-select"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -719,11 +719,7 @@ msgstr "Home Dashboard"
|
|||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
||||||
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
||||||
msgstr "Choose default dashboard"
|
msgstr "Default dashboard"
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
|
||||||
msgid "shared-preferences.fields.home-dashboard-tooltip"
|
|
||||||
msgstr "Not finding the dashboard you want? Star it first, then it should appear in this select box."
|
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
||||||
msgid "shared-preferences.fields.locale-label"
|
msgid "shared-preferences.fields.locale-label"
|
||||||
|
|||||||
@@ -724,10 +724,6 @@ msgstr ""
|
|||||||
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
|
||||||
msgid "shared-preferences.fields.home-dashboard-tooltip"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
||||||
msgid "shared-preferences.fields.locale-label"
|
msgid "shared-preferences.fields.locale-label"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -724,10 +724,6 @@ msgstr ""
|
|||||||
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
|
||||||
msgid "shared-preferences.fields.home-dashboard-tooltip"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
||||||
msgid "shared-preferences.fields.locale-label"
|
msgid "shared-preferences.fields.locale-label"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
@@ -718,10 +718,6 @@ msgstr ""
|
|||||||
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
msgid "shared-preferences.fields.home-dashboard-placeholder"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
|
||||||
msgid "shared-preferences.fields.home-dashboard-tooltip"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
#: public/app/core/components/SharedPreferences/SharedPreferences.tsx
|
||||||
msgid "shared-preferences.fields.locale-label"
|
msgid "shared-preferences.fields.locale-label"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
Reference in New Issue
Block a user