Skip to content

Commit

Permalink
ui: fix: timezone handling
Browse files Browse the repository at this point in the history
  • Loading branch information
yohamta committed Nov 9, 2024
1 parent 0f35a5c commit 8ad03c8
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 38 deletions.
42 changes: 20 additions & 22 deletions ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,17 @@ import { SWRConfig } from 'swr';
import fetchJson from './lib/fetchJson';
import Search from './pages/search';
import { UserPreferencesProvider } from './contexts/UserPreference';

export type Config = {
apiURL: string;
title: string;
navbarColor: string;
tz: string;
version: string;
};
import { Config, ConfigContext } from './contexts/ConfigContext';
import moment from 'moment-timezone';

type Props = {
config: Config;
};

function App({ config }: Props) {
const [title, setTitle] = React.useState<string>('');
config.tz ||= moment.tz.guess();

return (
<SWRConfig
value={{
Expand All @@ -39,20 +35,22 @@ function App({ config }: Props) {
setTitle,
}}
>
<UserPreferencesProvider>
<BrowserRouter>
<Layout {...config}>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/dags/" element={<DAGs />} />
<Route path="/dags/:name/:tab" element={<DAGDetails />} />
<Route path="/dags/:name/" element={<DAGDetails />} />
<Route path="/search/" element={<Search />} />
</Routes>
</Layout>
</BrowserRouter>
</UserPreferencesProvider>
<ConfigContext.Provider value={config}>
<UserPreferencesProvider>
<BrowserRouter>
<Layout {...config}>
<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/dags/" element={<DAGs />} />
<Route path="/dags/:name/:tab" element={<DAGDetails />} />
<Route path="/dags/:name/" element={<DAGDetails />} />
<Route path="/search/" element={<Search />} />
</Routes>
</Layout>
</BrowserRouter>
</UserPreferencesProvider>
</ConfigContext.Provider>
</AppBarContext.Provider>
</SWRConfig>
);
Expand Down
6 changes: 2 additions & 4 deletions ui/src/components/molecules/DAGTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ import {
KeyboardArrowUp,
} from '@mui/icons-material';
import LiveSwitch from './LiveSwitch';
import moment from 'moment';
import 'moment-duration-format';
import Ticker from '../atoms/Ticker';
import VisuallyHidden from '../atoms/VisuallyHidden';
import moment from 'moment-timezone';

type Props = {
DAGs: DAGItem[];
Expand Down Expand Up @@ -251,9 +251,7 @@ const defaultColumns = [
}),
columnHelper.accessor('Type', {
id: 'Schedule',
header: getConfig().tz
? `Schedule in ${getConfig().tz}`
: 'Schedule',
header: `Schedule in ${getConfig().tz || moment.tz.guess()}`,
enableSorting: true,
cell: (props) => {
const data = props.row.original!;
Expand Down
15 changes: 6 additions & 9 deletions ui/src/components/molecules/DashboardTimechart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'vis-timeline/styles/vis-timeline-graph2d.css';
import { statusColorMapping } from '../../consts';
import { DAGStatus } from '../../models';
import { WorkflowListItem } from '../../models/api';
import { useConfig } from '../../contexts/ConfigContext';

type Props = { data: DAGStatus[] | WorkflowListItem[] };

Expand All @@ -21,15 +22,11 @@ type TimelineItem = {
function DashboardTimechart({ data: input }: Props) {
const timelineRef = useRef<HTMLDivElement>(null);
const timelineInstance = useRef<Timeline | null>(null);
const config = useConfig();

useEffect(() => {
if (!timelineRef.current) return;

let timezone = getConfig().tz;
if (!timezone) {
timezone = moment.tz.guess();
}

const items: TimelineItem[] = [];
const now = moment();
const startOfDay = moment().startOf('day');
Expand All @@ -47,8 +44,8 @@ function DashboardTimechart({ data: input }: Props) {
items.push({
id: status.Name + `_${status.RequestId}`,
content: status.Name,
start: startMoment.tz(timezone).toDate(),
end: end.tz(timezone).toDate(),
start: startMoment.tz(config.tz).toDate(),
end: end.tz(config.tz).toDate(),
group: 'main',
className: `status-${status.Status}`,
});
Expand All @@ -59,7 +56,7 @@ function DashboardTimechart({ data: input }: Props) {

if (!timelineInstance.current) {
timelineInstance.current = new Timeline(timelineRef.current, dataset, {
moment: (date: MomentInput) => moment(date).tz(timezone),
moment: (date: MomentInput) => moment(date).tz(config.tz),
start: startOfDay.toDate(),
end: now.endOf('day').toDate(),
orientation: 'top',
Expand All @@ -76,7 +73,7 @@ function DashboardTimechart({ data: input }: Props) {
hour: 'HH:mm',
},
majorLabels: {
hour: 'HH:mm',
hour: 'ddd D MMMM',
day: 'ddd D MMMM',
},
},
Expand Down
15 changes: 15 additions & 0 deletions ui/src/contexts/ConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext, useContext } from 'react';

export type Config = {
apiURL: string;
title: string;
navbarColor: string;
tz: string;
version: string;
};

export const ConfigContext = createContext<Config>(null!);

export function useConfig() {
return useContext(ConfigContext);
}
3 changes: 2 additions & 1 deletion ui/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { createRoot } from 'react-dom/client';

import App, { Config } from './App';
import App from './App';
import './styles/styles.css';
import './styles/prism.css';

Expand All @@ -14,6 +14,7 @@ import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
import { Config } from './contexts/ConfigContext';

declare global {
const getConfig: () => Config;
Expand Down
3 changes: 2 additions & 1 deletion ui/src/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import cronParser from 'cron-parser';
import moment from 'moment-timezone';
import { WorkflowListItem } from './api';

export enum SchedulerStatus {
Expand Down Expand Up @@ -150,7 +151,7 @@ export function getNextSchedule(data: WorkflowListItem): number {
if (!schedules || schedules.length == 0 || data.Suspended) {
return Number.MAX_SAFE_INTEGER;
}
const tz = getConfig().tz;
const tz = getConfig().tz || moment.tz.guess();
const datesToRun = schedules.map((s) => {
const expression = tz
? cronParser.parseExpression(s.Expression, {
Expand Down
4 changes: 3 additions & 1 deletion ui/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import DashboardTimechart from '../components/molecules/DashboardTimechart';
import Title from '../components/atoms/Title';
import { AppBarContext } from '../contexts/AppBarContext';
import useSWR from 'swr';
import { useConfig } from '../contexts/ConfigContext';

type metrics = Record<SchedulerStatus, number>;

Expand All @@ -25,6 +26,7 @@ function Dashboard() {
const { data } = useSWR<ListWorkflowsResponse>(`/dags`, null, {
refreshInterval: 10000,
});
const config = useConfig();

React.useEffect(() => {
if (!data) {
Expand Down Expand Up @@ -79,7 +81,7 @@ function Dashboard() {
height: '100%',
}}
>
<Title>{getConfig().tz ? `Timeline in ${getConfig().tz}` : "Timeline"}</Title>
<Title>{`Timeline in ${config.tz}`}</Title>
<DashboardTimechart data={data?.DAGs || []} />
</Box>
</Grid>
Expand Down

0 comments on commit 8ad03c8

Please sign in to comment.