Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 58 additions & 5 deletions public/app/core/components/SharedPreferences/SharedPreferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as React from 'react';

import { FeatureState, getBuiltInThemes, ThemeRegistryItem } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { config, reportInteraction } from '@grafana/runtime';
import { config, reportInteraction, getAppEvents, ThemeChangedEvent } from '@grafana/runtime';
import { Preferences as UserPreferencesDTO } from '@grafana/schema/src/raw/preferences/x/preferences_types.gen';
import {
Button,
Expand All @@ -26,11 +26,14 @@ import { t, Trans } from 'app/core/internationalization';
import { LANGUAGES, PSEUDO_LOCALE } from 'app/core/internationalization/constants';
import { PreferencesService } from 'app/core/services/PreferencesService';
import { changeTheme } from 'app/core/services/theme';
import type { Unsubscribable } from 'rxjs';

export interface Props {
resourceUri: string;
disabled?: boolean;
preferenceType: 'org' | 'team' | 'user';
onConfirm?: () => Promise<boolean>;
eventBus?: { subscribe: Function };
}

export type State = UserPreferencesDTO & {
Expand Down Expand Up @@ -67,6 +70,7 @@ function getLanguageOptions(): ComboboxOption[] {
export class SharedPreferences extends PureComponent<Props, State> {
service: PreferencesService;
themeOptions: ComboboxOption[];
private themeChangedSub?: Unsubscribable;

constructor(props: Props) {
super(props);
Expand Down Expand Up @@ -110,6 +114,7 @@ export class SharedPreferences extends PureComponent<Props, State> {
isLoading: true,
});
const prefs = await this.service.load();
console.log('Loaded preferences:');

this.setState({
isLoading: false,
Expand All @@ -121,6 +126,32 @@ export class SharedPreferences extends PureComponent<Props, State> {
queryHistory: prefs.queryHistory,
navbar: prefs.navbar,
});

// Listen to Grafana theme changes and reflect them in the dropdown immediately
const eventBus = this.props.eventBus ?? getAppEvents();
if (eventBus && typeof eventBus.subscribe === 'function') {
this.themeChangedSub = eventBus.subscribe(ThemeChangedEvent, (evt: any) => {
try {
const payload = evt?.payload;
const isDark = typeof payload?.isDark === 'boolean' ? payload.isDark : payload?.colors?.mode === 'dark';
const mode: 'light' | 'dark' = isDark ? 'dark' : 'light';

if (this.state.theme !== mode) {
this.setState({ theme: mode });
}
} catch (err) {
console.warn('[SharedPreferences] Failed to sync theme from ThemeChangedEvent:', err);
}
});
}
}

componentWillUnmount() {
try {
this.themeChangedSub?.unsubscribe();
} catch (err) {
console.warn('[SharedPreferences] Failed to unsubscribe ThemeChangedEvent:', err);
}
}

onSubmitForm = async (event: React.FormEvent<HTMLFormElement>) => {
Expand All @@ -135,15 +166,37 @@ export class SharedPreferences extends PureComponent<Props, State> {
};

onThemeChanged = (value: ComboboxOption<string>) => {
this.setState({ theme: value.value });
const raw = value?.value ?? '';
const prev = this.state.theme;

if (prev !== raw) {
this.setState({ theme: raw });
}

reportInteraction('grafana_preferences_theme_changed', {
toTheme: value.value,
toTheme: raw,
preferenceType: this.props.preferenceType,
});

if (value.value) {
changeTheme(value.value, true);
if (raw) {
try {
changeTheme(raw, true);
} catch (err) {}
}

try {
const theme2 = config?.theme2;
if (!theme2) {
console.warn('[SharedPreferences] publish skipped: config.theme2 is not available');
} else {
const appEvents = getAppEvents();
if (typeof appEvents.publish === 'function') {
appEvents.publish(new ThemeChangedEvent(theme2));
} else {
console.warn('[SharedPreferences] publish ThemeChangedEvent skipped: publish is not a function');
}
}
} catch (err) {}
};

onTimeZoneChanged = (timezone?: string) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@ import { useAsync } from 'react-use';
import { GrafanaTheme2, ScopedVars } from '@grafana/data';
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
import { selectors } from '@grafana/e2e-selectors';
import { config } from '@grafana/runtime';
import { DashboardLink } from '@grafana/schema';
import { Dropdown, Icon, Button, Menu, ScrollContainer, useStyles2 } from '@grafana/ui';
import { ButtonLinkProps, LinkButton } from '@grafana/ui/src/components/Button';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItem } from 'app/features/search/types';
import { isPmmAdmin } from 'app/percona/shared/helpers/permissions';

import { getLinkSrv } from '../../../panel/panellinks/link_srv';

Expand All @@ -29,22 +27,7 @@ interface DashboardLinksMenuProps {

function DashboardLinksMenu({ dashboardUID, link }: DashboardLinksMenuProps) {
const styles = useStyles2(getStyles);
let resolvedLinks = useResolvedLinks({ dashboardUID, link });

// @PERCONA
// TODO: PMM-7736 remove it ASAP after migration transition period is finished
if (link.title === 'PMM') {
if (isPmmAdmin(config.bootData.user)) {
resolvedLinks = [
{ uid: '1000', url: '/graph/add-instance', title: 'PMM Add Instance' },
{ uid: '1001', url: '/graph/advisors/insights', title: 'PMM Advisors' },
{ uid: '1002', url: '/graph/inventory', title: 'PMM Inventory' },
{ uid: '1003', url: '/graph/settings', title: 'PMM Settings' },
];
} else {
return <></>;
}
}
const resolvedLinks = useResolvedLinks({ dashboardUID, link });

if (!resolvedLinks || resolveLinks.length === 0) {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,13 @@ const AddBackupPage: FC = () => {
);

return (
<Page navId="backup-add-edit" layout={PageLayoutType.Custom}>
<Page
navId="backup-add-edit"
pageNav={{
text: modalTitle,
}}
layout={PageLayoutType.Custom}
>
<Overlay isPending={pending}>
<Form
initialValues={initialValues}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { PerconaBootstrapperProps } from './PerconaBootstrapper.types';
import PerconaNavigation from './PerconaNavigation/PerconaNavigation';
import PerconaTourBootstrapper from './PerconaTour';
import PerconaUpdateVersion from './PerconaUpdateVersion/PerconaUpdateVersion';
import { isPmmNavEnabled } from '../../helpers/plugin';

// This component is only responsible for populating the store with Percona's settings initially
export const PerconaBootstrapper = ({ onReady }: PerconaBootstrapperProps) => {
Expand Down Expand Up @@ -117,10 +118,11 @@ export const PerconaBootstrapper = ({ onReady }: PerconaBootstrapperProps) => {
<>
{isSignedIn && <Telemetry />}
<PerconaNavigation />
<PerconaTourBootstrapper />
{!isPmmNavEnabled() && <PerconaTourBootstrapper />}
{updateAvailable && showUpdateModal && !isLoadingUpdates ? (
<PerconaUpdateVersion />
) : (
!isPmmNavEnabled() &&
isSignedIn &&
showTour && (
<Modal onDismiss={dismissModal} isOpen={modalIsOpen} title={Messages.title}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ export const WEIGHTS = {
config: -900,
};

export const PMM_BACKUP_ADD_EDIT: NavModelItem = {
id: 'backup-add-edit',
text: 'Create backup',
url: `${config.appSubUrl}/backup/new`,
hideFromBreadcrumbs: true,
isCreateAction: true,
};

export const PMM_BACKUP_PAGE: NavModelItem = {
id: 'backup',
icon: 'history',
Expand Down Expand Up @@ -36,6 +44,7 @@ export const PMM_BACKUP_PAGE: NavModelItem = {
text: 'Storage Locations',
url: `${config.appSubUrl}/backup/locations`,
},
PMM_BACKUP_ADD_EDIT,
],
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import {
} from 'app/percona/shared/core/reducers/updates';
import { setSnoozedVersion } from 'app/percona/shared/core/reducers/user/user';
import { getPerconaSettings, getPerconaUser, getUpdatesInfo } from 'app/percona/shared/core/selectors';
import { isPmmNavEnabled } from 'app/percona/shared/helpers/plugin';
import { useAppDispatch } from 'app/store/store';
import { useSelector } from 'app/types';

import { Messages } from './PerconaUpdateVersion.constants';
import { getStyles } from './PerconaUpdateVersion.styles';
import { locationService } from '@grafana/runtime';

const PerconaUpdateVersion = () => {
const { updateAvailable, installed, latest, changeLogs, showUpdateModal, latestNewsUrl } =
Expand Down Expand Up @@ -52,7 +54,12 @@ const PerconaUpdateVersion = () => {

const onUpdateClick = () => {
dispatch(setShowUpdateModal(false));
window.location.assign(PMM_UPDATES_LINK.url!);

if (isPmmNavEnabled()) {
locationService.push(PMM_UPDATES_LINK.url!);
} else {
window.location.assign(PMM_UPDATES_LINK.url!);
}
};

return (
Expand Down
3 changes: 3 additions & 0 deletions public/app/percona/shared/helpers/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { config } from '@grafana/runtime';

export const isPmmNavEnabled = () => !!config.apps['pmm-compat-app']?.preload;
8 changes: 7 additions & 1 deletion public/app/plugins/panel/pmm-update/UpdatePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import { Button, Spinner } from '@grafana/ui';
import { PMM_UPDATES_LINK } from 'app/percona/shared/components/PerconaBootstrapper/PerconaNavigation';
import { checkUpdatesAction } from 'app/percona/shared/core/reducers/updates';
import { getPerconaUser, getPerconaSettings, getUpdatesInfo } from 'app/percona/shared/core/selectors';
import { isPmmNavEnabled } from 'app/percona/shared/helpers/plugin';
import { useAppDispatch } from 'app/store/store';
import { useSelector } from 'app/types';

import { Messages } from './UpdatePanel.messages';
import { styles } from './UpdatePanel.styles';
import { formatDateWithTime } from './UpdatePanel.utils';
import { AvailableUpdate, CurrentVersion, InfoBox, LastCheck } from './components';
import { locationService } from '@grafana/runtime';

export const UpdatePanel: FC = () => {
const isOnline = navigator.onLine;
Expand Down Expand Up @@ -38,7 +40,11 @@ export const UpdatePanel: FC = () => {
};

const handleOpenUpdates = () => {
window.location.assign(PMM_UPDATES_LINK.url!);
if (isPmmNavEnabled()) {
locationService.push(PMM_UPDATES_LINK.url!);
} else {
window.location.assign(PMM_UPDATES_LINK.url!);
}
};

return (
Expand Down
Loading