Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2ef5c6e
Added Keep Current checkbox only when right side is unbounded
w-b-d Jul 18, 2025
7ff4d7c
Made temporary hardcoded changes in ChartLinkComponent.
anntreasajojo Jul 28, 2025
a6c1069
Refactored Chart Link Options UI
anntreasajojo Jul 31, 2025
79f02c5
Disabled Keep Current when the right side is bounded
anntreasajojo Aug 5, 2025
a8b2782
Updated appStateSlice and graphSlice and added parameter in url
w-b-d Aug 5, 2025
de1a067
Upated keep current checkbox to not appear when graph is unbounded on…
w-b-d Aug 5, 2025
7e3d0e6
Pulled in changes from Will's branch about when Keep Current checkbox…
anntreasajojo Aug 5, 2025
09005f6
Added functionality to shift slider range based on keep current check…
w-b-d Aug 8, 2025
6ac0799
Merge pull request #1 from nickhitos/ann_will_branch
nickhitos Aug 11, 2025
89b9884
Added keep chart current checkbox to be grey when conditions are not …
Aug 14, 2025
01fb5e1
The link in the tool-tip for keep chart current is now functioning.
anntreasajojo Aug 14, 2025
d985ffe
updated variable names
w-b-d Aug 19, 2025
94a1e64
cleaned up files
w-b-d Aug 19, 2025
f68f589
Merge pull request #2 from nickhitos/ann-rian-ui
nickhitos Aug 19, 2025
e4864eb
Merge branch 'development' into w/dev
w-b-d Aug 22, 2025
135b53f
Merge branch 'OpenEnergyDashboard:development' into development
w-b-d Aug 22, 2025
8ffc441
Merge branch 'test-backend-with-ui' into w/dev
w-b-d Aug 22, 2025
84bb65b
Merge pull request #4 from nickhitos/w/dev
w-b-d Aug 22, 2025
4c2c367
connected backend to frontend
w-b-d Aug 22, 2025
d4e5b61
Merge pull request #5 from nickhitos/test-backend-with-ui
w-b-d Aug 22, 2025
e79ee5b
Fixed eslint errors
w-b-d Aug 25, 2025
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ nohup.out

# Visual Studio Code settings file
.vscode/settings.json

.vscode/launch.json
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is used by OED to define the debugging setup, etc. I'm not sure it should be in .gitignore.

# tmp file
src/server/tmp/*

Expand Down
3 changes: 3 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"version": "0.2.0",
"configurations": [

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file only has new blank lines so please revert changes so none in file.

{

"name": "Attach to Node in Docker",
"type": "node",
"request": "attach",
Expand Down Expand Up @@ -44,6 +46,7 @@
"Attach to Node in Docker",
"Launch Firefox against localhost"
]

}
]
}
7 changes: 7 additions & 0 deletions as
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
origin/HEAD -> origin/development
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure what this file is for. Should it be removed?

origin/ann_branch
origin/ann_branch_2
origin/ann_will_branch
origin/codebase-testing
origin/development
origin/w/dev
7 changes: 7 additions & 0 deletions d
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
origin/HEAD -> origin/development
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm unsure what this file is for. Should it be removed?

origin/ann_branch
origin/ann_branch_2
origin/ann_will_branch
origin/codebase-testing
origin/development
origin/w/dev
162 changes: 125 additions & 37 deletions src/client/app/components/ChartLinkComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,28 @@
import * as React from 'react';
import { toast } from 'react-toastify';
import ReactTooltip from 'react-tooltip';
import { Button, ButtonGroup, Input } from 'reactstrap';
import { Button, ButtonGroup,Input} from 'reactstrap';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after comma.

import { useAppDispatch, useAppSelector } from '../redux/reduxHooks';
import { selectChartLink } from '../redux/selectors/uiSelectors';
import { selectChartLinkHideOptions, setChartLinkOptionsVisibility } from '../redux/slices/appStateSlice';
import { selectSelectedGroups, selectSelectedMeters } from '../redux/slices/graphSlice';
import { showErrorNotification, showInfoNotification } from '../utils/notifications';
import {
selectChartLinkHideOptions, selectIsKeepCurrent, setChartLinkOptionsVisibility,
setIsKeepCurrent
} from '../redux/slices/appStateSlice';
import {
selectSelectedGroups,
selectSelectedMeters,
selectQueryTimeInterval
} from '../redux/slices/graphSlice';
import {
showErrorNotification,
showInfoNotification
} from '../utils/notifications';
import { useTranslate } from '../redux/componentHooks';
import TooltipMarkerComponent from './TooltipMarkerComponent';
import { wellStyle, rowFlexStart } from '../styles/modalStyle';
import { wellStyle, rowFlexStart, labelStyle } from '../styles/modalStyle';
import { checkboxStyle } from '../styles/modalStyle';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove new blank lines so only one.



/**
* @returns chartLinkComponent
Expand All @@ -26,59 +39,134 @@ export default function ChartLinkComponent() {
const linkHideOptions = useAppSelector(selectChartLinkHideOptions);
const selectedMeters = useAppSelector(selectSelectedMeters);
const selectedGroups = useAppSelector(selectSelectedGroups);
const queryTimeInterval = useAppSelector(selectQueryTimeInterval);
const isKeepCurrent = useAppSelector(selectIsKeepCurrent);
const ref = React.useRef<HTMLDivElement>(null);

// THIS react.UseMemo ONLY RETURNS TRUE WHEN THE CONDITIONS ARE MET FOR USING KEEP CURRENT (left is is bounded and right is unbounded)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the uppercase needed? I think you are trying to emphasize the point but a regular comment seems fine as there are lots of comments on the code throughout OED. Some people find uppercase to be shouting so I try to avoid.

const shouldShowKeepCurrentCheckbox = React.useMemo(() => {
if (!queryTimeInterval) return false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if the logic could be made simpler and clearer since you only want to return true in one case. What if you set a variable to false. Then check if the left is bounded and right unbounded (protecting against undefined which is also false) and set variable to true. (A trinary as a single statement to do this is also fine.) Then return the variable value. I note this might avoid Multiple returns that, I believe, research has shown can lead to errors.

It may not matter after the changes but OED wants braces around all if/else statements, even if a single one for clarity.

if (queryTimeInterval.getIsBounded()) return false;
if (
queryTimeInterval.getStartTimestamp() == null &&
!queryTimeInterval.getIsBounded()
)
return false;
return true;
}, [queryTimeInterval]);

const handleButtonClick = () => {
// First attempt to write directly to user's clipboard.
navigator.clipboard.writeText(linkText)
navigator.clipboard
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I preferred the old formatting without the extra lines to shorten the code.

.writeText(linkText)
.then(() => {
showInfoNotification(translate('clipboard.copied'), toast.POSITION.TOP_RIGHT, 1000);
showInfoNotification(
translate('clipboard.copied'),
toast.POSITION.TOP_RIGHT,
1000
);
})
.catch(() => {
// if operation fails, open copyable text for manual copy.
showErrorNotification(translate('clipboard.not.copied'), toast.POSITION.TOP_RIGHT, 1000);
showErrorNotification(
translate('clipboard.not.copied'),
toast.POSITION.TOP_RIGHT,
1000
);
setLinkTextVisible(true);
});
};
if (selectedMeters.length > 0 || selectedGroups.length > 0) {
return (
<div>
{/* inputting new "keep chart current" feature */}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment should just say what the code does or be removed if you think it is not necessary.

<div style={labelStyle}>{translate('chart.link.options.title')}</div>
{/* hide options checkbox */}
<div className="checkbox">
<Input
type="checkbox"
style={checkboxStyle}
defaultChecked={linkHideOptions}
onClickCapture={e => {
e.stopPropagation();
dispatch(setChartLinkOptionsVisibility(!linkHideOptions));
}}
onMouseOver={() => {
ref.current && ReactTooltip.show(ref.current);
}}
onMouseLeave={() => {
ref.current && ReactTooltip.hide(ref.current);
}}
/>
<label>{translate('hide.options.when.using.this.label')}</label>
<TooltipMarkerComponent
page="home"
helpTextId="help.home.toggle.chart.link"
/>
</div>
{/* keep current checkbox ----> */}
{/* USE shouldShowKeepCurrentCheckbox AS THE CONDITIONAL BOOLEAN */}
<div className="checkbox">
<Input
type="checkbox"
style={checkboxStyle}
onMouseOver={() => {
ref.current && ReactTooltip.show(ref.current);
}}
onMouseLeave={() => {
ref.current && ReactTooltip.hide(ref.current);
}}
checked={isKeepCurrent}
onChange={e => dispatch(setIsKeepCurrent(e.target.checked))}
disabled={!shouldShowKeepCurrentCheckbox}
// shouldShow is the value we use to tell if it should be disabled or not
//when disabled = true, you CANNOT click the checkbox
/>

<label
// uses the default value when shouldShowKeepCurrentCheckbox is true, and the greyed out color when it's false
style={{
color: shouldShowKeepCurrentCheckbox
? undefined
: 'hsl(0, 0%, 70%)'
}}
>
{translate('keep.chart.current.label')}
</label>
{/* we need to create a tool tip for "keep chart current" checkbox */}
<TooltipMarkerComponent page="home" helpTextId="help.home.toggle.chart.link.keep.current" />
</div>

<div style={rowFlexStart}>
<ButtonGroup >
<Button outline onClick={handleButtonClick} >
<div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-evenly', gap: '1em', alignItems: 'center' }}>

<ButtonGroup>
<Button outline onClick={handleButtonClick}>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
gap: '1em',
alignItems: 'center'
}}
>
{translate('chart.link')}
<div ref={ref} data-for={'home'} data-tip={'help.home.toggle.chart.link'} >
<Input type='checkbox' defaultChecked={linkHideOptions}
onClickCapture={e => {
e.stopPropagation();
dispatch(setChartLinkOptionsVisibility(!linkHideOptions));
}}
onMouseOver={() => {
ref.current && ReactTooltip.show(ref.current);
}}
onMouseLeave={() => {
ref.current && ReactTooltip.hide(ref.current);
}}
/>
</div>

</div>
</Button>
<Button outline onClick={() => setLinkTextVisible(visible => !visible)}>
<Button
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the original formatting please be put back since shorter and will remove these lines as having changes.

outline
onClick={() => setLinkTextVisible(visible => !visible)}
>
{linkTextVisible ? 'x' : 'v'}
</Button>

</ButtonGroup>
<TooltipMarkerComponent page='home' helpTextId='help.home.toggle.chart.link' />
</div>
{
linkTextVisible &&
<div style={wellStyle}>
{linkText}
</div>
}
</div >
{linkTextVisible && <div style={wellStyle}>{linkText}</div>}
</div>
);
}
else {
} else {
return null;
}
}
}
3 changes: 2 additions & 1 deletion src/client/app/components/PlotNavComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
changeSliderRange, selectChartToRender, selectHistoryIsDirty,
selectSelectedGroups, selectSelectedMeters,
selectSliderRangeInterval, selectInitialXAxisRange,
selectQueryTimeInterval, updateTimeIntervalAndSliderRange
selectQueryTimeInterval, updateTimeIntervalAndSliderRange,updateTimeCreated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after comma.

} from '../redux/slices/graphSlice';
import HistoryComponent from './HistoryComponent';
import { ChartTypes } from '../types/redux/graph';
Expand Down Expand Up @@ -110,6 +110,7 @@ export const RefreshGraphComponent = () => {
const maxX = initialXAxisRange?.getEndTimestamp?.();
const nextInterval = getNextQueryTimeInterval(queryTimeInterval, sliderInterval, minX, maxX);
dispatch(updateTimeIntervalAndSliderRange(nextInterval));
dispatch(updateTimeCreated());
}
}}
/>
Expand Down
1 change: 1 addition & 0 deletions src/client/app/components/TooltipHelpComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default function TooltipHelpComponent(props: TooltipHelpProps) {
'help.home.select.units': { link: `${helpUrl}/graphingUnits/` },
'help.home.readings.per.day': { link: `${helpUrl}/readingsPerDay/` },
'help.home.toggle.chart.link': { link: `${helpUrl}/chartLink/` },
'help.home.toggle.chart.link.keep.current': { link: `${helpUrl}/chartLink/` },
'help.groups.groupdetails': { link: `${helpUrl}/groupViewing/#groupDetails` },
'help.groups.groupview': { link: `${helpUrl}/groupViewing/` },
'help.meters.meterview': { link: `${helpUrl}/meterViewing/` },
Expand Down
11 changes: 9 additions & 2 deletions src/client/app/redux/selectors/uiSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LanguageTypes } from 'types/redux/i18n';
import { selectGroupDataById } from '../../redux/api/groupsApi';
import { selectMeterDataById } from '../../redux/api/metersApi';
import { selectUnitDataById } from '../../redux/api/unitsApi';
import { selectChartLinkHideOptions, selectSelectedLanguage } from '../../redux/slices/appStateSlice';
import { selectChartLinkHideOptions, selectIsKeepCurrent, selectSelectedLanguage } from '../../redux/slices/appStateSlice';
import { DataType } from '../../types/Datasources';
import { GroupedOption, SelectOption } from '../../types/items';
import { ChartTypes, ShiftAmount } from '../../types/redux/graph';
Expand Down Expand Up @@ -453,9 +453,10 @@ export const selectChartLink = createAppSelector(
selectGraphState,
selectChartLinkHideOptions,
selectSliderRangeInterval,
selectIsKeepCurrent,
state => state.maps.selectedMap
],
(current, chartLinkHideOptions, rangeSliderInterval, selectedMap) => {
(current, chartLinkHideOptions, rangeSliderInterval, isKeepCurrent,selectedMap) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing off - see other comment.

// Determine the beginning of the URL to add arguments to.
// This is the current URL.
const winLocHref = window.location.href;
Expand Down Expand Up @@ -514,6 +515,12 @@ export const selectChartLink = createAppSelector(
if (chartLinkHideOptions) {
linkText += '&optionsVisibility=false';
}
if (isKeepCurrent) {
const timeCreatedEnd = current.timeCreated.getEndTimestamp();
const sliderStart = current.rangeSliderInterval.getStartTimestamp();
const diffDays = timeCreatedEnd.diff(sliderStart, 'days', true);
linkText += `&timeSpan=${diffDays.toFixed(2)}`;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about the toFix(2). Was it to limit the size of the link? My quick calculation indicates this would be accurate to about 15 minutes. If it was 5 decimal places then it would be about 1 second. I don't think it will matter too often but if the user set a precise time I'm wondering if there is a reason to reduce the accuracy this much. Thoughts?

}
return linkText;
}
);
Expand Down
17 changes: 13 additions & 4 deletions src/client/app/redux/slices/appStateSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface AppState {
selectedLanguage: LanguageTypes;
languageManuallySet: boolean;
refreshingReadings: boolean;
isKeepCurrent: boolean;
}

const defaultState: AppState = {
Expand All @@ -33,7 +34,8 @@ const defaultState: AppState = {
selectedLanguage: LanguageTypes.en,
chartLinkHideOptions: false,
languageManuallySet: false,
refreshingReadings: false
refreshingReadings: false,
isKeepCurrent: false
};

export const appStateSlice = createThunkSlice({
Expand Down Expand Up @@ -63,6 +65,9 @@ export const appStateSlice = createThunkSlice({
setRefresingReadings: create.reducer<boolean>((state, action) => {
state.refreshingReadings = action.payload;
}),
setIsKeepCurrent: create.reducer<boolean>((state, action) => {
state.isKeepCurrent = action.payload;
}),
initApp: create.asyncThunk(
// Thunk initiates many data fetching calls on startup before react begins to render
async (_: void, { dispatch }) => {
Expand Down Expand Up @@ -132,7 +137,9 @@ export const appStateSlice = createThunkSlice({
selectOptionsVisibility: state => state.optionsVisibility,
selectSelectedLanguage: state => state.selectedLanguage,
selectChartLinkHideOptions: state => state.chartLinkHideOptions,
selectRefreshingReadings: state => state.refreshingReadings
selectRefreshingReadings: state => state.refreshingReadings,
selectIsKeepCurrent: state => state.isKeepCurrent

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove extra blank line.

}
});

Expand All @@ -143,13 +150,15 @@ export const {
setOptionsVisibility,
updateSelectedLanguage,
setChartLinkOptionsVisibility,
setRefresingReadings
setRefresingReadings,
setIsKeepCurrent
} = appStateSlice.actions;

export const {
selectInitComplete,
selectOptionsVisibility,
selectSelectedLanguage,
selectChartLinkHideOptions,
selectRefreshingReadings
selectRefreshingReadings,
selectIsKeepCurrent
} = appStateSlice.selectors;
Loading