Skip to content

Commit

Permalink
minor bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
isaozler committed Sep 10, 2023
1 parent 35cad7a commit 22b21be
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 47 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## 0.1.2

- Fixes for [issue #16](https://github.com/isaozler/grafana-shift-selector/issues/16)
- Fixed groupUUID field. Gets auto-selected if not provided.
- Breaking refresh rate fixed. Added custom refresh rate input to force dashboard refresh at preferred rate.
- Added progressbar to visualise the refresh rate
- Deprecated location service replaced

## 0.1.1

- Fixed review bugs
Expand Down
55 changes: 53 additions & 2 deletions src/ShiftSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,31 @@ import './styles/core.css';
import 'react-datepicker/dist/react-datepicker.min.css';

import { PanelProps } from '@grafana/data';
import { TPropOptions } from './types';
import { TPropOptions, vars } from './types';
import { setTypeChangeHandler, shiftSelectHandler } from './utils';
import { ShiftSelectorWrapper, ShiftSelectorContainer } from './styles/components';
import { ShiftOptions } from './components/options';
import { InputWrappers } from './components/inputWrappers';
import { Alerts } from './components/alerts';
import { useShiftSelectorHook } from './hooks/core';
import { locationService } from '@grafana/runtime';
import { ProgressBar } from './components/progressBar';

let refreshT: NodeJS.Timer | null = null;

const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
const [renderCount, setRenderCount] = useState(0);
const [isBlockedRender, setIsBlockedRender] = useState(false);
const [shiftSelectorPluginPanel, setShiftSelectorPluginPanel] = useState<NodeListOf<HTMLDivElement> | null>(null);
const [autoSelectShiftGroup, setAutoSelectShiftGroup] = useState(
locationService.getSearch().get(vars.queryShiftsGroup) ?? props.options.autoSelectShiftGroup
);
const { data: _data, width, height, timeRange } = props;

const {
isShowDayLabel,
isShowTimeLabel,
isAutoSelectShift,
autoSelectShiftGroup,
dayLabel,
rangeLabelType,
shiftOptionsLabelType,
Expand All @@ -30,7 +38,9 @@ const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
var_label_mapping,
isShowRangeButtons,
isShowProductionDateSelector,
isProgressbarVisible,
} = props.options;

const {
resetAlert,

Expand All @@ -50,6 +60,10 @@ const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
setProductionDate,
} = useShiftSelectorHook({
...props,
options: {
...props.options,
autoSelectShiftGroup,
},
shiftSelectorPluginPanel,
} as PanelProps<TPropOptions>);

Expand Down Expand Up @@ -86,12 +100,46 @@ const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
}
}, [shiftSelectorRef, setAlerts]);

useEffect(() => {
if (
!!props.options.autoSelectShiftGroup &&
!!autoSelectShiftGroup &&
props.options.autoSelectShiftGroup !== autoSelectShiftGroup
) {
locationService.partial(
{
[vars.queryShiftsGroup]: props.options.autoSelectShiftGroup,
[vars.queryShiftsOptions]: null,
},
true
);
setAutoSelectShiftGroup(props.options.autoSelectShiftGroup);
}
}, [props.options.autoSelectShiftGroup, autoSelectShiftGroup]);

useEffect(() => {
if (refreshT) {
clearInterval(refreshT);
refreshT = null;
}

if (props.options._refreshInterval) {
refreshT = setInterval(() => {
props.eventBus.publish({ type: 'refresh', payload: undefined, origin: undefined });
setRenderCount((d) => d + 1);
}, props.options._refreshInterval as unknown as number);
}
}, [props.eventBus, props.options._refreshInterval]);

if (isBlockedRender) {
return <Alerts alerts={alerts} resetAlert={resetAlert} setClosedAlerts={setClosedAlerts} />;
}

return (
<ShiftSelectorWrapper ref={shiftSelectorRef} id="shift-selector-plugin">
{isProgressbarVisible && isAutoSelectShift && (
<ProgressBar renderCount={renderCount} refresh={props.options._refreshInterval} />
)}
<Alerts alerts={alerts} resetAlert={resetAlert} setClosedAlerts={setClosedAlerts} />
{shiftOptions?.options?.length ? (
<ShiftSelectorContainer
Expand All @@ -103,6 +151,8 @@ const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
>
{!isAutoSelectShift ? (
<InputWrappers
refreshInterval={props.options.refreshInterval}
_refreshInterval={props.options._refreshInterval}
timeRange={timeRange}
isShowDayLabel={isShowDayLabel}
dayLabel={dayLabel}
Expand All @@ -118,6 +168,7 @@ const ShiftSelector: React.FC<PanelProps<TPropOptions>> = (props) => {
setProductionDate={setProductionDate}
isShowProductionDateSelector={isShowProductionDateSelector}
isShowRangeButtons={isShowRangeButtons}
isProgressbarVisible={isProgressbarVisible}
/>
) : (
<></>
Expand Down
1 change: 0 additions & 1 deletion src/components/inputWrappers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ type TPropInputWrapperOptions = Omit<
| 'autoSelectShiftGroup'
| 'isShowTimeLabel'
| 'shiftOptionsLabelType'
| 'refreshInterval'
| 'var_query_map_dynamic'
| 'var_query_map_static'
| 'var_label_mapping'
Expand Down
18 changes: 11 additions & 7 deletions src/components/options.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import { config } from '@grafana/runtime';
import { config, locationService } from '@grafana/runtime';
import {
ShiftOptionsWrapper,
ShiftsWrapper,
Expand Down Expand Up @@ -68,9 +68,9 @@ export const ShiftOptions = ({
const { sunny, sunset, night } = mappingsParsed;

const allMappings = {
sunny: ['morning', 'morgen', 'day', ...(sunny ? sunny : [])],
'sunset-down': ['afternoon', 'middag', ...(sunset ? sunset : [])],
night: ['night', 'nacht', ...(night ? night : [])],
sunny: ['morning', 'morgen', 'day', ...(sunny || [])],
'sunset-down': ['afternoon', 'middag', ...(sunset || [])],
night: ['night', 'nacht', ...(night || [])],
};

return (
Expand Down Expand Up @@ -99,8 +99,8 @@ export const ShiftOptions = ({
const start = `${sh}:${sm}`;
const end = `${eh}:${em}`;
const isActive =
new URLSearchParams(window.location.search).get(vars.queryShiftsOptions) === uuid ||
new URLSearchParams(window.location.search).get(vars.queryShiftsOptions) === 'All';
locationService.getSearch().get(vars.queryShiftsOptions) === uuid ||
locationService.getSearch().get(vars.queryShiftsOptions) === 'All';
const fromTimeLabel = setType === 'from' ? `${start}` : `${end}`;
const timeLabel = setType === 'both' ? `${start} - ${end}` : fromTimeLabel;

Expand All @@ -114,7 +114,11 @@ export const ShiftOptions = ({
? `mdi mdi-weather-${buttonTypes(label, allMappings)}`
: ''
}`}
onClick={() => shiftSelectHandler(item, setShiftParams, productionDate)}
onClick={() => {
if (!isRealtimeActive) {
shiftSelectHandler(item, setShiftParams, productionDate);
}
}}
isRealtime={isRealtimeActive}
>
<ShiftLabelSpan>
Expand Down
36 changes: 36 additions & 0 deletions src/components/progressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';

import { config } from '@grafana/runtime';
import { keyframes, styled } from '@stitches/react';

const colors: any = config.theme.colors;

const load = keyframes({
'0%': { width: '0%' },
'100%': { width: '100%' },
});

export const Bar = styled('div', {
width: '100%',
height: 4,
marginTop: -16,
marginBottom: 12,
position: 'relative',
'&:after': {
content: '',
position: 'absolute',
top: 0,
left: 0,
background: colors.border1,
width: 10,
height: '100%',
animationName: load,
animationDuration: 'inherit',
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
},
});

export const ProgressBar = ({ refresh, renderCount }: { refresh: string; renderCount: number }) => {
return <Bar data-count={renderCount} style={{ animationDuration: `${refresh}ms` }} />;
};
71 changes: 44 additions & 27 deletions src/hooks/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
getDataSourceSrv,
toDataQueryResponse,
RefreshEvent,
getLocationSrv,
getTemplateSrv,
TemplateSrv,
locationService,
} from '@grafana/runtime';

import {
Expand All @@ -25,21 +25,21 @@ import {
TStaticShift,
vars,
} from '../types';
import { dateTimeFormat, getRelativeDates, startHourIsGreater, transformShiftData, updateActiveShift } from '../utils';
import { dateTimeFormat, getInitGroupUUID, getRelativeDates, startHourIsGreater, transformShiftData, updateActiveShift } from '../utils';

let isInitiated = false;

export const useShiftSelectorHook = (props: PanelProps<TPropOptions>) => {
const { data: _data, width, height, timeRange, eventBus } = props;
const {
isAutoSelectShift,
autoSelectShiftGroup,
refreshInterval,
isDataSourceShifts,
var_query_map_dynamic,
var_query_map_static,
shiftSelectorPluginPanel,
} = props.options;

const locationSrv = getLocationSrv();
const locationSrv = locationService;
const templateSrv = getTemplateSrv() as TemplateSrv & { timeRange: TimeRange };
const dateRange = templateSrv.timeRange;

Expand All @@ -55,6 +55,7 @@ export const useShiftSelectorHook = (props: PanelProps<TPropOptions>) => {
const [siteUUID, setSiteUUID] = useState<any>();
const [isStatic, setIsStatic] = useState<boolean>(false);
const [sqlConfig, setSqlConfig] = useState<TSqlConfig | null>(null);
const [autoSelectShiftGroup, setAutoSelectShiftGroup] = useState<string>(new URLSearchParams(window.location.search).get(vars.queryShiftsGroup) ?? props.options.autoSelectShiftGroup);

const processShifts = useCallback(({ rowsCount, responseFields }) => {
return Array.from({ length: rowsCount })
Expand Down Expand Up @@ -120,14 +121,13 @@ export const useShiftSelectorHook = (props: PanelProps<TPropOptions>) => {
},
[alerts]
);

const getRefreshRate = useCallback(() => {
const refreshValue = new URLSearchParams(window.location.search).get('refresh');
const refresh = {
...(refreshValue ? { refresh: refreshValue } : isAutoSelectShift ? { refresh: refreshInterval } : {}),
};
return {
refresh: locationService.getSearch().get('refresh'),
}
}, []);

return refresh;
}, [isAutoSelectShift, refreshInterval]);
const setShiftParams = useCallback(
(shift: TExtendedShift, isManualUpdate = false) => {
const { startDate, endDate } = shift || {};
Expand Down Expand Up @@ -340,16 +340,14 @@ ORDER by ??, ??
const query = {
from: isSwapDates ? to : from,
to: isSwapDates ? from : to,
[vars.queryShiftsGroup]: autoSelectShiftGroup,
[vars.queryShiftsOptions]: uuid,
...getRefreshRate(),
};

locationSrv.update({
partial: true,
query,
});
locationSrv.partial(query, false);
}
}, [locationSrv, customTimeRange, timeRange.to, timeRange.from, getRefreshRate, setInitDateRange]);
}, [locationSrv, customTimeRange, timeRange.to, timeRange.from, getRefreshRate, setInitDateRange, autoSelectShiftGroup, isAutoSelectShift]);

useEffect(() => {
if (width < 400) {
Expand Down Expand Up @@ -419,15 +417,6 @@ ORDER by ??, ??
}
}, [siteUUID, sqlConfig, getValues]);

useEffect(() => {
locationSrv.update({
partial: true,
query: {
...getRefreshRate(),
},
});
}, [locationSrv, getRefreshRate]);

useEffect(() => {
if (isStatic && sqlConfig?.static?.shifts) {
setShiftOptions(() => processStaticOptions(sqlConfig.static?.shifts));
Expand All @@ -439,9 +428,35 @@ ORDER by ??, ??
}, [isStatic, sqlConfig, setShiftOptions, processStaticOptions, templateSrv]);

useEffect(() => {
const subscriber = eventBus.getStream(RefreshEvent).subscribe((event) => {
const isRealtimeActive = !!(isAutoSelectShift && autoSelectShiftGroup);
const isRealtimeActive = !!(isAutoSelectShift && autoSelectShiftGroup);

if (isAutoSelectShift && !autoSelectShiftGroup && shiftOptions?.options?.length && shiftValues?.length) {
const initGroup = getInitGroupUUID(shiftOptions.options, shiftValues)

locationSrv.partial({
[vars.queryShiftsGroup]: initGroup,
...getRefreshRate(),
}, false);
setAutoSelectShiftGroup(initGroup)
}

if (!isInitiated && isRealtimeActive && autoSelectShiftGroup && shiftOptions?.options?.length && shiftValues?.length && productionDate) {
isInitiated = true;

updateActiveShift({
setShiftParams,
autoSelectShiftGroup,
isAutoSelectShift,
shifts: {
options: shiftOptions.options,
values: shiftValues,
},
setProductionDate,
productionDate,
});
}

const subscriber = eventBus.getStream(RefreshEvent).subscribe((event) => {
if (isRealtimeActive) {
updateActiveShift({
setShiftParams,
Expand All @@ -461,6 +476,7 @@ ORDER by ??, ??
subscriber.unsubscribe();
};
}, [
locationSrv,
productionDate,
eventBus,
setShiftParams,
Expand All @@ -471,6 +487,7 @@ ORDER by ??, ??
props.timeRange.from,
props.timeRange.to,
shiftSelectorPluginPanel,
getRefreshRate,
]);

useEffect(() => {
Expand Down
Loading

0 comments on commit 22b21be

Please sign in to comment.