Skip to content

Commit 8cb6726

Browse files
Merge pull request #522 from zhuje/ou671-pf-theme-pr
OU-671: Add Patternfly Theming to Perses
2 parents c83cc49 + 7bb95b3 commit 8cb6726

File tree

2 files changed

+184
-24
lines changed

2 files changed

+184
-24
lines changed

README.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,26 @@ $ npm run build
171171
$ ./scripts/api_backend_dev.sh
172172
173173
# Lastly navigate to http://localhost:8080/ to see Perses app running
174-
```
174+
```
175+
176+
##### Install COO && Perses Datasource && Perses Sample Dashboard
177+
1. Install COO through the OpenShift UI > OperatorHub > Cluster Observability Operator
178+
2. Install UIPlugin > monitoring
179+
3. oc apply -f <PERSES_DATASOURCE_YAML>
180+
- See sample yaml [here](https://github.com/observability-ui/development-tools/blob/main/monitoring-plugin/monitoring-console-plugin/perses/thanos-querier-datasource.yaml)
181+
4. oc apply -f <PERSES_DASHBOARD_YAML>
182+
- See sample yaml [here](https://github.com/observability-ui/development-tools/blob/main/monitoring-plugin/monitoring-console-plugin/perses/perses-dashboard.yaml)
183+
184+
##### Port forward Perses Datasource
185+
To use the PERSES_DATASOURCE you deployed above, you'll need to forward it to your local machine then proxy it using the local Perses Instance.
186+
187+
```
188+
# Forward cluster Prometheus Instance to localhost:9090
189+
oc port-forward -n openshift-monitoring service/prometheus-operated 9090:9090
190+
191+
# Test is port-forward returns Prometheus data from query 'up'
192+
curl "http://localhost:9090/api/v1/query?query=up"
193+
```
194+
195+
Adjust Perses local instance http://localhost:8080/ to use the a proxy to http://localhost:9090/ instead of http://demo.prometheus.io.
196+

web/src/components/dashboards/perses/PersesWrapper.tsx

Lines changed: 161 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { useMemo } from 'react';
2-
import * as React from 'react';
1+
import { ThemeOptions, ThemeProvider } from '@mui/material';
2+
import { ChartThemeColor, getThemeColors } from '@patternfly/react-charts/victory';
33
import {
44
ChartsProvider,
55
generateChartsTheme,
@@ -8,37 +8,42 @@ import {
88
SnackbarProvider,
99
typography,
1010
} from '@perses-dev/components';
11-
import { ThemeProvider } from '@mui/material';
12-
import {
13-
DataQueriesProvider,
14-
dynamicImportPluginLoader,
15-
PluginModuleResource,
16-
PluginRegistry,
17-
TimeRangeProviderWithQueryParams,
18-
useInitialRefreshInterval,
19-
useInitialTimeRange,
20-
usePluginBuiltinVariableDefinitions,
21-
} from '@perses-dev/plugin-system';
2211
import {
2312
BuiltinVariableDefinition,
13+
DashboardResource,
2414
Definition,
2515
DurationString,
26-
DashboardResource,
2716
UnknownSpec,
2817
} from '@perses-dev/core';
29-
import panelsResource from '@perses-dev/panels-plugin/plugin.json';
30-
import prometheusResource from '@perses-dev/prometheus-plugin/plugin.json';
3118
import {
3219
DashboardProvider,
3320
DatasourceStoreProvider,
3421
VariableProviderWithQueryParams,
3522
} from '@perses-dev/dashboards';
36-
import { ChartThemeColor, getThemeColors } from '@patternfly/react-charts/victory';
23+
import panelsResource from '@perses-dev/panels-plugin/plugin.json';
24+
import {
25+
DataQueriesProvider,
26+
dynamicImportPluginLoader,
27+
PluginModuleResource,
28+
PluginRegistry,
29+
TimeRangeProviderWithQueryParams,
30+
useInitialRefreshInterval,
31+
useInitialTimeRange,
32+
usePluginBuiltinVariableDefinitions,
33+
} from '@perses-dev/plugin-system';
34+
import prometheusResource from '@perses-dev/prometheus-plugin/plugin.json';
35+
import React, { useMemo } from 'react';
3736
import { usePatternFlyTheme } from '../../hooks/usePatternflyTheme';
38-
import { CachedDatasourceAPI } from './perses/datasource-api';
3937
import { OcpDatasourceApi } from './datasource-api';
4038
import { PERSES_PROXY_BASE_PATH, useFetchPersesDashboard } from './perses-client';
41-
39+
import { CachedDatasourceAPI } from './perses/datasource-api';
40+
import {
41+
chart_color_blue_100,
42+
chart_color_blue_200,
43+
chart_color_blue_300,
44+
t_color_gray_95,
45+
t_color_white,
46+
} from '@patternfly/react-tokens';
4247
import { QueryParams } from '../../query-params';
4348
import { StringParam, useQueryParam } from 'use-query-params';
4449
import { useTranslation } from 'react-i18next';
@@ -80,18 +85,151 @@ interface PersesWrapperProps {
8085
project: string;
8186
}
8287

83-
export function PersesWrapper({ children, project }: PersesWrapperProps) {
84-
const { theme } = usePatternFlyTheme();
85-
const [dashboardName] = useQueryParam(QueryParams.Dashboard, StringParam);
88+
const mapPatterflyThemeToMUI = (theme: 'light' | 'dark'): ThemeOptions => {
89+
const isDark = theme === 'dark';
90+
const primaryTextColor = isDark ? t_color_white.value : t_color_gray_95.value;
91+
const primaryBackgroundColor = 'var(--pf-t--global--background--color--primary--default)';
8692

87-
const muiTheme = getTheme(theme, {
93+
return {
8894
typography: {
8995
...typography,
9096
fontFamily: 'var(--pf-t--global--font--family--body)',
97+
subtitle1: {
98+
// Card Heading
99+
fontFamily: 'var(--pf-t--global--font--family--heading)',
100+
fontWeight: 'var(--pf-t--global--font--weight--heading--default)',
101+
lineHeight: 'var(--pf-v6-c-card__title-text--LineHeight)',
102+
fontSize: 'var(--pf-t--global--font--size--heading--sm)',
103+
},
104+
h2: {
105+
// Panel Group Heading
106+
color: 'var(--pf-t--global--text--color--brand--default)',
107+
fontWeight: 'var(--pf-t--global--font--weight--body--default)',
108+
fontSize: 'var(--pf-t--global--font--size--600)',
109+
},
91110
},
111+
palette: {
112+
primary: {
113+
light: chart_color_blue_100.value,
114+
main: chart_color_blue_200.value,
115+
dark: chart_color_blue_300.value,
116+
contrastText: primaryTextColor,
117+
},
118+
secondary: {
119+
main: primaryTextColor,
120+
light: primaryTextColor,
121+
dark: primaryTextColor,
122+
},
123+
background: {
124+
default: primaryBackgroundColor,
125+
paper: primaryBackgroundColor,
126+
navigation: primaryBackgroundColor,
127+
code: primaryBackgroundColor,
128+
tooltip: primaryBackgroundColor,
129+
lighter: primaryBackgroundColor,
130+
border: primaryBackgroundColor,
131+
},
132+
text: {
133+
primary: primaryTextColor,
134+
secondary: primaryTextColor,
135+
disabled: primaryTextColor,
136+
navigation: primaryTextColor,
137+
accent: primaryTextColor,
138+
link: primaryTextColor,
139+
linkHover: primaryTextColor,
140+
},
141+
},
142+
components: {
143+
MuiTypography: {
144+
styleOverrides: {
145+
root: {
146+
// Custom Time Range Selector
147+
'&.MuiClock-meridiemText': {
148+
color: primaryTextColor,
149+
},
150+
},
151+
},
152+
},
153+
MuiSvgIcon: {
154+
styleOverrides: {
155+
root: {
156+
color: theme === 'dark' ? t_color_white.value : t_color_gray_95.value,
157+
},
158+
},
159+
},
160+
MuiCard: {
161+
styleOverrides: {
162+
root: {
163+
borderRadius: 'var(--pf-t--global--border--radius--medium)',
164+
borderColor: 'var(--pf-t--global--border--color--default)',
165+
},
166+
},
167+
},
168+
MuiCardHeader: {
169+
styleOverrides: {
170+
root: {
171+
'&.MuiCardHeader-root': {
172+
borderBottom: 'none',
173+
paddingBlockEnd: 'var(--pf-t--global--spacer--md)',
174+
paddingBlockStart: 'var(--pf-t--global--spacer--lg)',
175+
paddingLeft: 'var(--pf-t--global--spacer--lg)',
176+
paddingRight: 'var(--pf-t--global--spacer--lg)',
177+
},
178+
},
179+
},
180+
},
181+
MuiCardContent: {
182+
styleOverrides: {
183+
root: {
184+
'&.MuiCardContent-root': {
185+
borderTop: 'none',
186+
'&:last-child': {
187+
paddingBottom: 'var(--pf-t--global--spacer--lg)',
188+
paddingLeft: 'var(--pf-t--global--spacer--lg)',
189+
paddingRight: 'var(--pf-t--global--spacer--lg)',
190+
},
191+
},
192+
},
193+
},
194+
},
195+
MuiOutlinedInput: {
196+
styleOverrides: {
197+
notchedOutline: {
198+
borderColor: 'var(--pf-t--global--border--color--default)',
199+
},
200+
root: {
201+
'&:hover .MuiOutlinedInput-notchedOutline': {
202+
borderColor: 'var(--pf-t--global--border--color--default)',
203+
},
204+
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
205+
borderColor: 'var(--pf-t--global--border--color--default)',
206+
},
207+
},
208+
input: {
209+
// Dashboard Variables >> Text Variable
210+
padding: '8.5px 14px',
211+
},
212+
},
213+
},
214+
MuiSelect: {
215+
styleOverrides: {
216+
icon: {
217+
color: primaryTextColor,
218+
},
219+
},
220+
},
221+
},
222+
};
223+
};
224+
225+
export function PersesWrapper({ children, project }: PersesWrapperProps) {
226+
const { theme } = usePatternFlyTheme();
227+
const [dashboardName] = useQueryParam(QueryParams.Dashboard, StringParam);
228+
const muiTheme = getTheme(theme, {
92229
shape: {
93230
borderRadius: 6,
94231
},
232+
...mapPatterflyThemeToMUI(theme),
95233
});
96234

97235
const chartsTheme: PersesChartsTheme = generateChartsTheme(muiTheme, {

0 commit comments

Comments
 (0)