From 2ef5c6e0fb39cf9e1aa11453be3e155a18378b95 Mon Sep 17 00:00:00 2001 From: William Brady-Diaz <161429870+w-b-d@users.noreply.github.com> Date: Fri, 18 Jul 2025 12:32:53 -0700 Subject: [PATCH 01/14] Added Keep Current checkbox only when right side is unbounded --- .../app/components/ChartLinkComponent.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 0cfacbfcbf..368eeaca63 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -9,7 +9,7 @@ import { Button, ButtonGroup, Input } from 'reactstrap'; 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 {selectQueryTimeInterval, selectSelectedGroups, selectSelectedMeters } from '../redux/slices/graphSlice'; import { showErrorNotification, showInfoNotification } from '../utils/notifications'; import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; @@ -26,7 +26,18 @@ export default function ChartLinkComponent() { const linkHideOptions = useAppSelector(selectChartLinkHideOptions); const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); + const queryTimeInterval = useAppSelector(selectQueryTimeInterval) const ref = React.useRef(null); + + const shouldShowKeepCurrentCheckbox = React.useMemo(() => { + if (!queryTimeInterval) return false + const end = queryTimeInterval.getEndTimestamp?.() + const isRightUnBounded = !end + return isRightUnBounded + }, [queryTimeInterval]) + + + const handleButtonClick = () => { // First attempt to write directly to user's clipboard. navigator.clipboard.writeText(linkText) @@ -66,6 +77,12 @@ export default function ChartLinkComponent() { + {shouldShowKeepCurrentCheckbox && ( + + )} + From 7ff4d7c16dba3ddc0806dd90f767b767fd181650 Mon Sep 17 00:00:00 2001 From: anntreasajojo Date: Mon, 28 Jul 2025 14:57:02 -0700 Subject: [PATCH 02/14] Made temporary hardcoded changes in ChartLinkComponent. --- src/client/app/components/ChartLinkComponent.tsx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 0cfacbfcbf..07a7290811 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -19,6 +19,7 @@ import { wellStyle, rowFlexStart } from '../styles/modalStyle'; * @returns chartLinkComponent */ export default function ChartLinkComponent() { + const translate = useTranslate(); const dispatch = useAppDispatch(); const [linkTextVisible, setLinkTextVisible] = React.useState(false); @@ -42,6 +43,15 @@ export default function ChartLinkComponent() { if (selectedMeters.length > 0 || selectedGroups.length > 0) { return (
+
+ Chart Link Options: +
+ Hide Options When Using This Link +
+
+ Keep Chart Current +
+
-
{ linkTextVisible && diff --git a/src/client/app/translations/data.ts b/src/client/app/translations/data.ts index 60490fb536..795bd19a9e 100644 --- a/src/client/app/translations/data.ts +++ b/src/client/app/translations/data.ts @@ -49,6 +49,7 @@ const LocaleTranslationData = { "calibration.submit.button": "Submit", "cancel": "Cancel", "chart.link": "Chart Link", + "chart.link.options.title": "Chart Link Options:", "child.groups": "Child Groups", "child.meters": "Child Meters", "clear.date.range": "Clear Date Range", @@ -291,6 +292,7 @@ const LocaleTranslationData = { "hide": "Hide", "hide.options": "Hide options", "hide.options.in.link": "Hide options in link", + "hide.options.when.using.this.label": "Hide options when using this link", "home": "Home", "hour": "Hour", "identifier": "Identifier:", @@ -309,6 +311,7 @@ const LocaleTranslationData = { "invalid.number": "Please submit a valid number (between 0 and 2.0)", "invalid.token.login": "Token has expired. Please log in again.", "invalid.token.login.admin": "Token has expired. Please log in again to view this page.", + "keep.chart.current.label": "Keep chart current", "language": "Language", "last.four.weeks": "Last four weeks", "last.week": "Last week", @@ -619,6 +622,7 @@ const LocaleTranslationData = { "calibration.submit.button": "Soumettre", "cancel": "Annuler", "chart.link": "Chart Link\u{26A1}", + "chart.link.options.title": "Chart Link Options:\u{26A1}", "child.groups": "Groupes Enfants", "child.meters": "Mètres Enfants", "clear.date.range": "Clear Date Range\u{26A1}", @@ -861,6 +865,7 @@ const LocaleTranslationData = { "hide": "Cacher", "hide.options": "Options de quai", "hide.options.in.link": "Hide options in link\u{26A1}", + "hide.options.when.using.this.label": "Hide options when using this link\u{26A1}", "home": "Accueil", "hour": "Hour\u{26A1}", "identifier": "Identifier:\u{26A1}", @@ -879,6 +884,7 @@ const LocaleTranslationData = { "invalid.number": "Please submit a valid number (between 0 and 2.0)\u{26A1}", "invalid.token.login": "Le jeton a expiré. Connectez-vous à nouveau.", "invalid.token.login.admin": "Le jeton a expiré. Please log in again to view this page.\u{26A1}", + "keep.chart.current.label": "Keep chart current\u{26A1}", "language": "Langue", "last.four.weeks": "Quatre dernières semaines", "last.week": "La semaine dernière", @@ -1189,6 +1195,7 @@ const LocaleTranslationData = { "calibration.submit.button": "Enviar", "cancel": "Cancelar", "chart.link": "Enlace de la tabla", + "chart.link.options.title": "Opciones de enlace de gráfico:", "child.groups": "Grupos secundarios", "child.meters": "Medidores secundarios", "clear.date.range": "Clear Date Range\u{26A1}", @@ -1431,6 +1438,7 @@ const LocaleTranslationData = { "hide": "Esconder", "hide.options": "Esconder las opciones", "hide.options.in.link": "Esconder las opciones en el enlace", + "hide.options.when.using.this.label": "Ocultar opciones al usar este enlace", "home": "Inicio", "hour": "Hora", "identifier": "Identificador:", @@ -1449,6 +1457,7 @@ const LocaleTranslationData = { "invalid.number": "Por favor indique un número válido (entre 0 a 2.0)", "invalid.token.login": "El token se ha vencido. Inicie la sesión nuevamente", "invalid.token.login.admin": "El token se ha vencido. Inicie la sesión nuevamente para ver esta página.", + "keep.chart.current.label": "Mantener el gráfico actualizado", "language": "Idioma", "last.four.weeks": "Últimas cuatro semanas", "last.week": "La semana pasada", From 79f02c5dcd6ff602d2cffa2f89af90bb1403dfa5 Mon Sep 17 00:00:00 2001 From: anntreasajojo Date: Tue, 5 Aug 2025 12:34:22 -0700 Subject: [PATCH 04/14] Disabled Keep Current when the right side is bounded --- src/client/app/components/ChartLinkComponent.tsx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 8e9c8791d3..5874fd1cb9 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -5,11 +5,11 @@ import * as React from 'react'; import { toast } from 'react-toastify'; import ReactTooltip from 'react-tooltip'; -import { Button, ButtonGroup, Input } from 'reactstrap'; +import { Button, ButtonGroup} from 'reactstrap'; 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 { selectSelectedGroups, selectSelectedMeters, selectQueryTimeInterval} from '../redux/slices/graphSlice'; import { showErrorNotification, showInfoNotification } from '../utils/notifications'; import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; @@ -28,7 +28,15 @@ export default function ChartLinkComponent() { const linkHideOptions = useAppSelector(selectChartLinkHideOptions); const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); + const queryTimeInterval = useAppSelector(selectQueryTimeInterval) const ref = React.useRef(null); + + const shouldShowKeepCurrentCheckbox = React.useMemo(() => { + if (!queryTimeInterval) return false + const end = queryTimeInterval.getEndTimestamp?.() + const isRightUnBounded = !end + return isRightUnBounded + }, [queryTimeInterval]) const handleButtonClick = () => { // First attempt to write directly to user's clipboard. navigator.clipboard.writeText(linkText) @@ -71,6 +79,7 @@ export default function ChartLinkComponent() {
{/* keep current checkbox */} + {shouldShowKeepCurrentCheckbox && (
+ )}
- {shouldShowKeepCurrentCheckbox && ( - diff --git a/src/client/app/components/PlotNavComponent.tsx b/src/client/app/components/PlotNavComponent.tsx index 62dcd445a8..569e59d74d 100644 --- a/src/client/app/components/PlotNavComponent.tsx +++ b/src/client/app/components/PlotNavComponent.tsx @@ -12,7 +12,7 @@ import { changeSliderRange, selectChartToRender, selectHistoryIsDirty, selectSelectedGroups, selectSelectedMeters, selectSliderRangeInterval, selectInitialXAxisRange, - selectQueryTimeInterval, updateTimeIntervalAndSliderRange + selectQueryTimeInterval, updateTimeIntervalAndSliderRange,updateTimeCreated } from '../redux/slices/graphSlice'; import HistoryComponent from './HistoryComponent'; import { ChartTypes } from '../types/redux/graph'; @@ -110,6 +110,7 @@ export const RefreshGraphComponent = () => { const maxX = initialXAxisRange?.getEndTimestamp?.(); const nextInterval = getNextQueryTimeInterval(queryTimeInterval, sliderInterval, minX, maxX); dispatch(updateTimeIntervalAndSliderRange(nextInterval)); + dispatch(updateTimeCreated()) } }} /> diff --git a/src/client/app/redux/selectors/uiSelectors.ts b/src/client/app/redux/selectors/uiSelectors.ts index b43445045d..6d6516fc9d 100644 --- a/src/client/app/redux/selectors/uiSelectors.ts +++ b/src/client/app/redux/selectors/uiSelectors.ts @@ -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, selectCurrentTime, selectSelectedLanguage } from '../../redux/slices/appStateSlice'; import { DataType } from '../../types/Datasources'; import { GroupedOption, SelectOption } from '../../types/items'; import { ChartTypes, ShiftAmount } from '../../types/redux/graph'; @@ -453,9 +453,11 @@ export const selectChartLink = createAppSelector( selectGraphState, selectChartLinkHideOptions, selectSliderRangeInterval, + selectCurrentTime, + state => state.maps.selectedMap ], - (current, chartLinkHideOptions, rangeSliderInterval, selectedMap) => { + (current, chartLinkHideOptions, rangeSliderInterval, currentTime,selectedMap) => { // Determine the beginning of the URL to add arguments to. // This is the current URL. const winLocHref = window.location.href; @@ -514,7 +516,13 @@ export const selectChartLink = createAppSelector( if (chartLinkHideOptions) { linkText += '&optionsVisibility=false'; } + + if(currentTime){ + linkText += `&timeCreated=${current.timeCreated.getEndTimestamp().format('YYYY-MM-DDTHH:00:00[Z]')}`; + } + return linkText; + } ); diff --git a/src/client/app/redux/slices/appStateSlice.ts b/src/client/app/redux/slices/appStateSlice.ts index a356bd4619..c08bad6a48 100644 --- a/src/client/app/redux/slices/appStateSlice.ts +++ b/src/client/app/redux/slices/appStateSlice.ts @@ -25,6 +25,7 @@ export interface AppState { selectedLanguage: LanguageTypes; languageManuallySet: boolean; refreshingReadings: boolean; + currentTime: boolean; } const defaultState: AppState = { @@ -33,7 +34,8 @@ const defaultState: AppState = { selectedLanguage: LanguageTypes.en, chartLinkHideOptions: false, languageManuallySet: false, - refreshingReadings: false + refreshingReadings: false, + currentTime: false, }; export const appStateSlice = createThunkSlice({ @@ -63,6 +65,9 @@ export const appStateSlice = createThunkSlice({ setRefresingReadings: create.reducer((state, action) => { state.refreshingReadings = action.payload; }), + setCurrentTime: create.reducer((state, action) => { + state.currentTime = action.payload; + }), initApp: create.asyncThunk( // Thunk initiates many data fetching calls on startup before react begins to render async (_: void, { dispatch }) => { @@ -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, + selectCurrentTime: state => state.currentTime, + } }); @@ -143,7 +150,8 @@ export const { setOptionsVisibility, updateSelectedLanguage, setChartLinkOptionsVisibility, - setRefresingReadings + setRefresingReadings, + setCurrentTime } = appStateSlice.actions; export const { @@ -151,5 +159,6 @@ export const { selectOptionsVisibility, selectSelectedLanguage, selectChartLinkHideOptions, - selectRefreshingReadings + selectRefreshingReadings, + selectCurrentTime } = appStateSlice.selectors; diff --git a/src/client/app/redux/slices/graphSlice.ts b/src/client/app/redux/slices/graphSlice.ts index 1c8ee41f04..4db56d0105 100644 --- a/src/client/app/redux/slices/graphSlice.ts +++ b/src/client/app/redux/slices/graphSlice.ts @@ -26,6 +26,7 @@ const defaultState: GraphState = { initialXAxisRange: TimeInterval.unbounded(), queryTimeInterval: TimeInterval.unbounded(), rangeSliderInterval: TimeInterval.unbounded(), + timeCreated: new TimeInterval(moment(),moment()), duration: moment.duration(4, 'weeks'), comparePeriod: ComparePeriod.Week, compareTimeInterval: calculateCompareTimeInterval(ComparePeriod.Week, moment()), @@ -142,6 +143,9 @@ export const graphSlice = createSlice({ state.current.threeD.meterOrGroupID = action.payload; } }, + updateTimeCreated: (state) => { + state.current.timeCreated = new TimeInterval(moment(), moment()); + }, updateThreeDMeterOrGroup: (state, action: PayloadAction) => { if (state.current.threeD.meterOrGroup !== action.payload) { state.current.threeD.meterOrGroup = action.payload; @@ -362,6 +366,11 @@ export const graphSlice = createSlice({ case 'shiftTimeInterval': current.shiftTimeInterval = TimeInterval.fromString(value); break; + case 'timeCreated': + const now = moment() + const timeCreated = current.timeCreated.getEndTimestamp() + const diffDays = now.diff(timeCreated,'days', true) + } }); } @@ -405,7 +414,8 @@ export const graphSlice = createSlice({ selectPlotlySliderMin: state => state.current.rangeSliderInterval.getStartTimestamp()?.utc().toDate().toISOString(), selectPlotlySliderMax: state => state.current.rangeSliderInterval.getEndTimestamp()?.utc().toDate().toISOString(), selectShiftAmount: state => state.current.shiftAmount, - selectShiftTimeInterval: state => state.current.shiftTimeInterval + selectShiftTimeInterval: state => state.current.shiftTimeInterval, + selectTimeCreated : state => state.current.timeCreated } }); @@ -425,7 +435,7 @@ export const { selectDefaultGraphState, selectHistoryIsDirty, selectPlotlySliderMax, selectPlotlySliderMin, selectShiftAmount, selectShiftTimeInterval, - selectInitialXAxisRange + selectInitialXAxisRange,selectTimeCreated } = graphSlice.selectors; // actionCreators exports @@ -444,6 +454,6 @@ export const { updateThreeDReadingInterval, updateThreeDMeterOrGroupInfo, updateSelectedMetersOrGroups, updateShiftAmount, setInitialXAxisRange, updateTimeIntervalAndSliderRange, - updateShiftTimeInterval + updateShiftTimeInterval,updateTimeCreated } = graphSlice.actions; diff --git a/src/client/app/types/redux/graph.ts b/src/client/app/types/redux/graph.ts index 906dbfa403..b53ca85060 100644 --- a/src/client/app/types/redux/graph.ts +++ b/src/client/app/types/redux/graph.ts @@ -86,4 +86,5 @@ export interface GraphState { hotlinked: boolean; shiftAmount: ShiftAmount; shiftTimeInterval: TimeInterval; + timeCreated: TimeInterval; } From de1a067dfd01edff635aec1938681451acaa4dac Mon Sep 17 00:00:00 2001 From: William Brady-Diaz <161429870+w-b-d@users.noreply.github.com> Date: Tue, 5 Aug 2025 13:21:07 -0700 Subject: [PATCH 06/14] Upated keep current checkbox to not appear when graph is unbounded on both sides --- src/client/app/components/ChartLinkComponent.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index d297a02779..00d6fb3437 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -15,6 +15,7 @@ import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; import { wellStyle, rowFlexStart } from '../styles/modalStyle'; + /** * @returns chartLinkComponent */ @@ -33,11 +34,11 @@ export default function ChartLinkComponent() { const ref = React.useRef(null); const shouldShowcurrentTimeCheckbox = React.useMemo(() => { if (!queryTimeInterval) return false - const end = queryTimeInterval.getEndTimestamp?.() - const isRightUnBounded = !end - return isRightUnBounded + 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) @@ -71,6 +72,7 @@ export default function ChartLinkComponent() { ref.current && ReactTooltip.hide(ref.current); }} /> +
From 7e3d0e68fbfc894080d0752e4dec0ec0e8f3aa75 Mon Sep 17 00:00:00 2001 From: anntreasajojo Date: Tue, 5 Aug 2025 13:54:21 -0700 Subject: [PATCH 07/14] Pulled in changes from Will's branch about when Keep Current checkbox should appear --- .../app/components/ChartLinkComponent.tsx | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 5874fd1cb9..9d324481ec 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -30,12 +30,11 @@ export default function ChartLinkComponent() { const selectedGroups = useAppSelector(selectSelectedGroups); const queryTimeInterval = useAppSelector(selectQueryTimeInterval) const ref = React.useRef(null); - const shouldShowKeepCurrentCheckbox = React.useMemo(() => { if (!queryTimeInterval) return false - const end = queryTimeInterval.getEndTimestamp?.() - const isRightUnBounded = !end - return isRightUnBounded + 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. @@ -80,23 +79,23 @@ export default function ChartLinkComponent() { {/* keep current checkbox */} {shouldShowKeepCurrentCheckbox && ( -
- { - ref.current && ReactTooltip.show(ref.current); - }} - onMouseLeave={() => { - ref.current && ReactTooltip.hide(ref.current); - }} - /> - - {/* we need to create a tool tip for "keep chart current" checkbox */} - -
+
+ { + ref.current && ReactTooltip.show(ref.current); + }} + onMouseLeave={() => { + ref.current && ReactTooltip.hide(ref.current); + }} + /> + + {/* we need to create a tool tip for "keep chart current" checkbox */} + +
)}
From 09005f6cd454fff2b6174df86708df703d531788 Mon Sep 17 00:00:00 2001 From: William Brady-Diaz <161429870+w-b-d@users.noreply.github.com> Date: Fri, 8 Aug 2025 11:34:14 -0700 Subject: [PATCH 08/14] Added functionality to shift slider range based on keep current checkbox and timespan parameter --- src/client/app/components/ChartLinkComponent.tsx | 3 +-- src/client/app/redux/selectors/uiSelectors.ts | 5 ++++- src/client/app/redux/slices/graphSlice.ts | 8 ++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 00d6fb3437..8f193b4bad 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -9,7 +9,7 @@ import { Button, ButtonGroup, Input } from 'reactstrap'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { selectChartLink } from '../redux/selectors/uiSelectors'; import { selectChartLinkHideOptions, selectCurrentTime, setChartLinkOptionsVisibility, setCurrentTime } from '../redux/slices/appStateSlice'; -import {selectQueryTimeInterval, selectSelectedGroups, selectSelectedMeters, selectSliderRangeInterval } from '../redux/slices/graphSlice'; +import {selectQueryTimeInterval, selectSelectedGroups, selectSelectedMeters } from '../redux/slices/graphSlice'; import { showErrorNotification, showInfoNotification } from '../utils/notifications'; import { useTranslate } from '../redux/componentHooks'; import TooltipMarkerComponent from './TooltipMarkerComponent'; @@ -29,7 +29,6 @@ export default function ChartLinkComponent() { const selectedGroups = useAppSelector(selectSelectedGroups); const queryTimeInterval = useAppSelector(selectQueryTimeInterval) const currentTime = useAppSelector(selectCurrentTime) - const range = useAppSelector(selectSliderRangeInterval) const ref = React.useRef(null); const shouldShowcurrentTimeCheckbox = React.useMemo(() => { diff --git a/src/client/app/redux/selectors/uiSelectors.ts b/src/client/app/redux/selectors/uiSelectors.ts index 6d6516fc9d..2e6573e8af 100644 --- a/src/client/app/redux/selectors/uiSelectors.ts +++ b/src/client/app/redux/selectors/uiSelectors.ts @@ -518,7 +518,10 @@ export const selectChartLink = createAppSelector( } if(currentTime){ - linkText += `&timeCreated=${current.timeCreated.getEndTimestamp().format('YYYY-MM-DDTHH:00:00[Z]')}`; + const timeCreatedEnd = current.timeCreated.getEndTimestamp() + const sliderStart = current.rangeSliderInterval.getStartTimestamp() + const diffDays = timeCreatedEnd.diff(sliderStart,'days',true) + linkText += `&timeSpan=${diffDays.toFixed(2)}`; } return linkText; diff --git a/src/client/app/redux/slices/graphSlice.ts b/src/client/app/redux/slices/graphSlice.ts index 4db56d0105..7f7c39fdf0 100644 --- a/src/client/app/redux/slices/graphSlice.ts +++ b/src/client/app/redux/slices/graphSlice.ts @@ -366,11 +366,11 @@ export const graphSlice = createSlice({ case 'shiftTimeInterval': current.shiftTimeInterval = TimeInterval.fromString(value); break; - case 'timeCreated': + case 'timeSpan': + const days = parseFloat(value) const now = moment() - const timeCreated = current.timeCreated.getEndTimestamp() - const diffDays = now.diff(timeCreated,'days', true) - + const leftBound = now.clone().subtract(days, 'days') + current.rangeSliderInterval = new TimeInterval(leftBound,undefined) } }); } From 89b98848418acf4b254ea935367ca0e906c46e31 Mon Sep 17 00:00:00 2001 From: rhassettcoding Date: Thu, 14 Aug 2025 11:55:16 -0700 Subject: [PATCH 09/14] Added keep chart current checkbox to be grey when conditions are not met, aswell as the checkbox being disabled under the same conditions. --- as | 7 + d | 7 + .../app/components/ChartLinkComponent.tsx | 176 +++++++++++------- src/client/app/translations/data.ts | 3 + 4 files changed, 125 insertions(+), 68 deletions(-) create mode 100644 as create mode 100644 d diff --git a/as b/as new file mode 100644 index 0000000000..e13c0ed59e --- /dev/null +++ b/as @@ -0,0 +1,7 @@ + origin/HEAD -> origin/development + origin/ann_branch + origin/ann_branch_2 + origin/ann_will_branch + origin/codebase-testing + origin/development + origin/w/dev diff --git a/d b/d new file mode 100644 index 0000000000..e13c0ed59e --- /dev/null +++ b/d @@ -0,0 +1,7 @@ + origin/HEAD -> origin/development + origin/ann_branch + origin/ann_branch_2 + origin/ann_will_branch + origin/codebase-testing + origin/development + origin/w/dev diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 9d324481ec..d0a20e4fea 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -2,25 +2,35 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import * as React from 'react'; -import { toast } from 'react-toastify'; -import ReactTooltip from 'react-tooltip'; -import { Button, ButtonGroup} from 'reactstrap'; -import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; -import { selectChartLink } from '../redux/selectors/uiSelectors'; -import { selectChartLinkHideOptions, setChartLinkOptionsVisibility } 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, labelStyle } from '../styles/modalStyle'; -import { checkboxStyle } from '../styles/modalStyle'; +import * as React from "react"; +import { toast } from "react-toastify"; +import ReactTooltip from "react-tooltip"; +import { Button, ButtonGroup } from "reactstrap"; +import { useAppDispatch, useAppSelector } from "../redux/reduxHooks"; +import { selectChartLink } from "../redux/selectors/uiSelectors"; +import { + selectChartLinkHideOptions, + setChartLinkOptionsVisibility, +} 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, labelStyle } from "../styles/modalStyle"; +import { checkboxStyle } from "../styles/modalStyle"; +import { color } from "d3"; /** * @returns chartLinkComponent */ export default function ChartLinkComponent() { - const translate = useTranslate(); const dispatch = useAppDispatch(); const [linkTextVisible, setLinkTextVisible] = React.useState(false); @@ -28,23 +38,38 @@ export default function ChartLinkComponent() { const linkHideOptions = useAppSelector(selectChartLinkHideOptions); const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); - const queryTimeInterval = useAppSelector(selectQueryTimeInterval) + const queryTimeInterval = useAppSelector(selectQueryTimeInterval); const ref = React.useRef(null); + + // THIS react.UseMemo ONLY RETURNS TRUE WHEN THE CONDITIONS ARE MET FOR USING KEEP CURRENT (left is is bounded and right is unbounded) const shouldShowKeepCurrentCheckbox = React.useMemo(() => { - if (!queryTimeInterval) return false - if(queryTimeInterval.getIsBounded()) return false - if(queryTimeInterval.getStartTimestamp() == null && !queryTimeInterval.getIsBounded()) return false - return true - }, [queryTimeInterval]) + if (!queryTimeInterval) return false; + 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 + .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); }); }; @@ -52,16 +77,14 @@ export default function ChartLinkComponent() { return (
{/* inputting new "keep chart current" feature */} -
- {translate('chart.link.options.title')} -
+
{translate("chart.link.options.title")}
{/* hide options checkbox */} -
+
{ + onClickCapture={(e) => { e.stopPropagation(); dispatch(setChartLinkOptionsVisibility(!linkHideOptions)); }} @@ -72,53 +95,70 @@ export default function ChartLinkComponent() { ref.current && ReactTooltip.hide(ref.current); }} /> -
+ {/* keep current checkbox ----> */} + {/* USE shouldShowKeepCurrentCheckbox AS THE CONDITIONAL BOOLEAN */} +
+ { + ref.current && ReactTooltip.show(ref.current); + }} + onMouseLeave={() => { + ref.current && ReactTooltip.hide(ref.current); + }} + 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 + /> + + - + {/* we need to create a tool tip for "keep chart current" checkbox */} +
- {/* keep current checkbox */} - {shouldShowKeepCurrentCheckbox && ( -
- { - ref.current && ReactTooltip.show(ref.current); - }} - onMouseLeave={() => { - ref.current && ReactTooltip.hide(ref.current); - }} - /> - - {/* we need to create a tool tip for "keep chart current" checkbox */} - -
- )} +
- - -
- { - linkTextVisible && -
- {linkText} -
- } -
+ {linkTextVisible &&
{linkText}
} +
); - } - else { + } else { return null; } -} \ No newline at end of file +} diff --git a/src/client/app/translations/data.ts b/src/client/app/translations/data.ts index 795bd19a9e..e68f753409 100644 --- a/src/client/app/translations/data.ts +++ b/src/client/app/translations/data.ts @@ -287,6 +287,7 @@ const LocaleTranslationData = { "help.home.select.rates": "Rates determine the time normalization for a line graph. Please visit {link} for further details and information", "help.home.select.units": "Units determine the values displayed in a graphic. Please visit {link} for further details and information", "help.home.toggle.chart.link": "With the \"Toggle chart link\" button a box appears that gives a URL that will recreate the current graphic. The link will recreate the graphic in the future, esp. for others to see. The person using this URL will be in a fully functional OED so they can make changes after the original graphic is displayed. You can help discourage changes by choosing the option to hide the option choice so they are not visible when using the URL. Please visit {link} for further details and information.", + "help.home.toggle.chart.link.keep.current": "With the \"Keep current\" option, the chart link will always show the same span of time as the original graphic, but shifted so it ends at the current time when the link is used. This is only available if the server data range goes up to the present (unbounded on the right). The link will work for any supported graphic type (line or bar) and ensures viewers always see the most recent data for that time span. Please visit {link} for further details and information.", "help.meters.meterview": "This page shows information on meters. Please visit {link} for further details and information.", "here": "here", "hide": "Hide", @@ -860,6 +861,7 @@ const LocaleTranslationData = { "help.home.select.rates": "Rates determine the time normalization for a line graph. Please visit {link} for further details and information\u{26A1}", "help.home.select.units": "Units determine the values displayed in a graphic. Please visit {link} for further details and information\u{26A1}", "help.home.toggle.chart.link": "With the \"Toggle chart link\" button a box appears that gives a URL that will recreate the current graphic. The link will recreate the graphic in the future, esp. for others to see. The person using this URL will be in a fully functional OED so they can make changes after the original graphic is displayed. You can help discourage changes by choosing the option to hide the option choice so they are not visible when using the URL. Please visit {link} for further details and information.\u{26A1}", + "help.home.toggle.chart.link.keep.current": "With the \"Keep current\" option, the chart link will always show the same span of time as the original graphic, but shifted so it ends at the current time when the link is used. This is only available if the server data range goes up to the present (unbounded on the right). The link will work for any supported graphic type (line or bar) and ensures viewers always see the most recent data for that time span. Please visit {link} for further details and information.\u{26A1}", "help.meters.meterview": "This page shows information on meters. Please visit {link} for further details and information.\u{26A1}", "here": "ici", "hide": "Cacher", @@ -1433,6 +1435,7 @@ const LocaleTranslationData = { "help.home.select.rates": "Las tasas determinan la normalización de tiempo para un gráfico de línea. Por favor visite {link} para obtener más detalles e información.", "help.home.select.units": "Las unidades determinan los valores mostrados en un gráfico. Por favor visite {link} para obtener más detalles e información.", "help.home.toggle.chart.link": "Con el botón \"Alternar enlace de gráfico\" aparece un cuadro que da un URL para recrear el gráfico actual. El enlace recreará el gráfico en el futuro, especialmente para que otros lo vean. La persona que usa este URL estará en un OED completamente funcional para que pueda realizar cambios después de mostrar el gráfico original. Puede desalentar los cambios eligiendo la opción de esconder las opciones del menú para que no sean visible al usar el URL. Por favor visite {link} para obtener más detalles e información.", + "help.home.toggle.chart.link.keep.current": "Con la opción \"Mantener actualizado\", el enlace del gráfico siempre mostrará el mismo lapso de tiempo que el gráfico original, pero desplazado para que finalice en el momento actual cuando se utiliza. Esto solo está disponible si el rango de datos del servidor llega hasta el presente (sin límite a la derecha). El enlace funciona con cualquier tipo de gráfico compatible (línea o barra) y garantiza que los usuarios siempre vean los datos más recientes para ese lapso. Visite {link} para obtener más detalles e información.", "help.meters.meterview": "Esta página muestra información sobre los medidores. Por favor visite {link} para obtener más detalles e información.", "here": "aquí", "hide": "Esconder", From 01fb5e13b65e42861389b553ae0a59340d3cd254 Mon Sep 17 00:00:00 2001 From: anntreasajojo Date: Thu, 14 Aug 2025 13:00:04 -0700 Subject: [PATCH 10/14] The link in the tool-tip for keep chart current is now functioning. --- src/client/app/components/TooltipHelpComponent.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/client/app/components/TooltipHelpComponent.tsx b/src/client/app/components/TooltipHelpComponent.tsx index f48de775ea..d13714ece9 100644 --- a/src/client/app/components/TooltipHelpComponent.tsx +++ b/src/client/app/components/TooltipHelpComponent.tsx @@ -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/` }, From d985ffec724effc71e7297779dae3bf822a7f52b Mon Sep 17 00:00:00 2001 From: w <161429870+w-b-d@users.noreply.github.com> Date: Tue, 19 Aug 2025 11:32:08 -0700 Subject: [PATCH 11/14] updated variable names --- src/client/app/components/ChartLinkComponent.tsx | 8 ++++---- src/client/app/redux/selectors/uiSelectors.ts | 8 ++++---- src/client/app/redux/slices/appStateSlice.ts | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 8f193b4bad..dd961df5b7 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -8,7 +8,7 @@ import ReactTooltip from 'react-tooltip'; import { Button, ButtonGroup, Input } from 'reactstrap'; import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; import { selectChartLink } from '../redux/selectors/uiSelectors'; -import { selectChartLinkHideOptions, selectCurrentTime, setChartLinkOptionsVisibility, setCurrentTime } from '../redux/slices/appStateSlice'; +import { selectChartLinkHideOptions, selectGraphCreationTime, setChartLinkOptionsVisibility, setGraphCreationTime } from '../redux/slices/appStateSlice'; import {selectQueryTimeInterval, selectSelectedGroups, selectSelectedMeters } from '../redux/slices/graphSlice'; import { showErrorNotification, showInfoNotification } from '../utils/notifications'; import { useTranslate } from '../redux/componentHooks'; @@ -28,7 +28,7 @@ export default function ChartLinkComponent() { const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); const queryTimeInterval = useAppSelector(selectQueryTimeInterval) - const currentTime = useAppSelector(selectCurrentTime) + const graphCreationTime = useAppSelector(selectGraphCreationTime) const ref = React.useRef(null); const shouldShowcurrentTimeCheckbox = React.useMemo(() => { @@ -85,8 +85,8 @@ export default function ChartLinkComponent() { dispatch(setCurrentTime(e.target.checked))} + checked={graphCreationTime} + onChange={e => dispatch(setGraphCreationTime(e.target.checked))} /> Keep Current diff --git a/src/client/app/redux/selectors/uiSelectors.ts b/src/client/app/redux/selectors/uiSelectors.ts index 2e6573e8af..2e4a917eb6 100644 --- a/src/client/app/redux/selectors/uiSelectors.ts +++ b/src/client/app/redux/selectors/uiSelectors.ts @@ -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, selectCurrentTime, selectSelectedLanguage } from '../../redux/slices/appStateSlice'; +import { selectChartLinkHideOptions, selectGraphCreationTime, selectSelectedLanguage } from '../../redux/slices/appStateSlice'; import { DataType } from '../../types/Datasources'; import { GroupedOption, SelectOption } from '../../types/items'; import { ChartTypes, ShiftAmount } from '../../types/redux/graph'; @@ -453,11 +453,11 @@ export const selectChartLink = createAppSelector( selectGraphState, selectChartLinkHideOptions, selectSliderRangeInterval, - selectCurrentTime, + selectGraphCreationTime, state => state.maps.selectedMap ], - (current, chartLinkHideOptions, rangeSliderInterval, currentTime,selectedMap) => { + (current, chartLinkHideOptions, rangeSliderInterval, graphCreationTime,selectedMap) => { // Determine the beginning of the URL to add arguments to. // This is the current URL. const winLocHref = window.location.href; @@ -517,7 +517,7 @@ export const selectChartLink = createAppSelector( linkText += '&optionsVisibility=false'; } - if(currentTime){ + if(graphCreationTime){ const timeCreatedEnd = current.timeCreated.getEndTimestamp() const sliderStart = current.rangeSliderInterval.getStartTimestamp() const diffDays = timeCreatedEnd.diff(sliderStart,'days',true) diff --git a/src/client/app/redux/slices/appStateSlice.ts b/src/client/app/redux/slices/appStateSlice.ts index c08bad6a48..fd45cd1011 100644 --- a/src/client/app/redux/slices/appStateSlice.ts +++ b/src/client/app/redux/slices/appStateSlice.ts @@ -25,7 +25,7 @@ export interface AppState { selectedLanguage: LanguageTypes; languageManuallySet: boolean; refreshingReadings: boolean; - currentTime: boolean; + graphCreationTime: boolean; } const defaultState: AppState = { @@ -35,7 +35,7 @@ const defaultState: AppState = { chartLinkHideOptions: false, languageManuallySet: false, refreshingReadings: false, - currentTime: false, + graphCreationTime: false, }; export const appStateSlice = createThunkSlice({ @@ -65,8 +65,8 @@ export const appStateSlice = createThunkSlice({ setRefresingReadings: create.reducer((state, action) => { state.refreshingReadings = action.payload; }), - setCurrentTime: create.reducer((state, action) => { - state.currentTime = action.payload; + setGraphCreationTime: create.reducer((state, action) => { + state.graphCreationTime = action.payload; }), initApp: create.asyncThunk( // Thunk initiates many data fetching calls on startup before react begins to render @@ -138,7 +138,7 @@ export const appStateSlice = createThunkSlice({ selectSelectedLanguage: state => state.selectedLanguage, selectChartLinkHideOptions: state => state.chartLinkHideOptions, selectRefreshingReadings: state => state.refreshingReadings, - selectCurrentTime: state => state.currentTime, + selectGraphCreationTime: state => state.graphCreationTime, } }); @@ -151,7 +151,7 @@ export const { updateSelectedLanguage, setChartLinkOptionsVisibility, setRefresingReadings, - setCurrentTime + setGraphCreationTime } = appStateSlice.actions; export const { @@ -160,5 +160,5 @@ export const { selectSelectedLanguage, selectChartLinkHideOptions, selectRefreshingReadings, - selectCurrentTime + selectGraphCreationTime } = appStateSlice.selectors; From 94a1e643ca2050b6b78674de959be8954893b86b Mon Sep 17 00:00:00 2001 From: w <161429870+w-b-d@users.noreply.github.com> Date: Tue, 19 Aug 2025 11:37:33 -0700 Subject: [PATCH 12/14] cleaned up files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0910e89c44..a74f392f7b 100644 --- a/.gitignore +++ b/.gitignore @@ -53,7 +53,7 @@ nohup.out # Visual Studio Code settings file .vscode/settings.json - +.vscode/launch.json # tmp file src/server/tmp/* From 4c2c367fa42b0620f3c2d97ade9fc07c453650a9 Mon Sep 17 00:00:00 2001 From: w <161429870+w-b-d@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:06:59 -0700 Subject: [PATCH 13/14] connected backend to frontend --- .../app/components/ChartLinkComponent.tsx | 28 ++++++------------- src/client/app/redux/selectors/uiSelectors.ts | 8 +++--- src/client/app/redux/slices/appStateSlice.ts | 14 +++++----- src/client/app/redux/slices/graphSlice.ts | 2 +- 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index 3379f97f9b..ea279a84ad 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -5,11 +5,12 @@ import * as React from "react"; import { toast } from "react-toastify"; import ReactTooltip from "react-tooltip"; -import { Button, ButtonGroup } from "reactstrap"; +import { Button, ButtonGroup,Input} from "reactstrap"; import { useAppDispatch, useAppSelector } from "../redux/reduxHooks"; import { selectChartLink } from "../redux/selectors/uiSelectors"; import { -selectChartLinkHideOptions, selectGraphCreationTime, setChartLinkOptionsVisibility, setGraphCreationTime +selectChartLinkHideOptions, selectIsKeepCurrent, setChartLinkOptionsVisibility, +setIsKeepCurrent } from "../redux/slices/appStateSlice"; import { selectSelectedGroups, @@ -24,7 +25,7 @@ import { useTranslate } from "../redux/componentHooks"; import TooltipMarkerComponent from "./TooltipMarkerComponent"; import { wellStyle, rowFlexStart, labelStyle } from "../styles/modalStyle"; import { checkboxStyle } from "../styles/modalStyle"; -import { color } from "d3"; + /** @@ -39,7 +40,7 @@ export default function ChartLinkComponent() { const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); const queryTimeInterval = useAppSelector(selectQueryTimeInterval); - const graphCreationTime = useAppSelector(selectGraphCreationTime) + const isKeepCurrent = useAppSelector(selectIsKeepCurrent) const ref = React.useRef(null); // THIS react.UseMemo ONLY RETURNS TRUE WHEN THE CONDITIONS ARE MET FOR USING KEEP CURRENT (left is is bounded and right is unbounded) @@ -82,7 +83,7 @@ export default function ChartLinkComponent() {
{translate("chart.link.options.title")}
{/* hide options checkbox */}
- */} {/* USE shouldShowKeepCurrentCheckbox AS THE CONDITIONAL BOOLEAN */}
- { @@ -115,6 +116,8 @@ export default function ChartLinkComponent() { 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 @@ -157,19 +160,6 @@ export default function ChartLinkComponent() { > {linkTextVisible ? "x" : "v"} - - {shouldShowcurrentTimeCheckbox && ( - - - - )}
diff --git a/src/client/app/redux/selectors/uiSelectors.ts b/src/client/app/redux/selectors/uiSelectors.ts index 2e4a917eb6..1f16de3118 100644 --- a/src/client/app/redux/selectors/uiSelectors.ts +++ b/src/client/app/redux/selectors/uiSelectors.ts @@ -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, selectGraphCreationTime, 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'; @@ -453,11 +453,11 @@ export const selectChartLink = createAppSelector( selectGraphState, selectChartLinkHideOptions, selectSliderRangeInterval, - selectGraphCreationTime, + selectIsKeepCurrent, state => state.maps.selectedMap ], - (current, chartLinkHideOptions, rangeSliderInterval, graphCreationTime,selectedMap) => { + (current, chartLinkHideOptions, rangeSliderInterval, isKeepCurrent,selectedMap) => { // Determine the beginning of the URL to add arguments to. // This is the current URL. const winLocHref = window.location.href; @@ -517,7 +517,7 @@ export const selectChartLink = createAppSelector( linkText += '&optionsVisibility=false'; } - if(graphCreationTime){ + if(isKeepCurrent){ const timeCreatedEnd = current.timeCreated.getEndTimestamp() const sliderStart = current.rangeSliderInterval.getStartTimestamp() const diffDays = timeCreatedEnd.diff(sliderStart,'days',true) diff --git a/src/client/app/redux/slices/appStateSlice.ts b/src/client/app/redux/slices/appStateSlice.ts index fd45cd1011..c15797b379 100644 --- a/src/client/app/redux/slices/appStateSlice.ts +++ b/src/client/app/redux/slices/appStateSlice.ts @@ -25,7 +25,7 @@ export interface AppState { selectedLanguage: LanguageTypes; languageManuallySet: boolean; refreshingReadings: boolean; - graphCreationTime: boolean; + isKeepCurrent: boolean; } const defaultState: AppState = { @@ -35,7 +35,7 @@ const defaultState: AppState = { chartLinkHideOptions: false, languageManuallySet: false, refreshingReadings: false, - graphCreationTime: false, + isKeepCurrent: false, }; export const appStateSlice = createThunkSlice({ @@ -65,8 +65,8 @@ export const appStateSlice = createThunkSlice({ setRefresingReadings: create.reducer((state, action) => { state.refreshingReadings = action.payload; }), - setGraphCreationTime: create.reducer((state, action) => { - state.graphCreationTime = action.payload; + setIsKeepCurrent: create.reducer((state, action) => { + state.isKeepCurrent = action.payload; }), initApp: create.asyncThunk( // Thunk initiates many data fetching calls on startup before react begins to render @@ -138,7 +138,7 @@ export const appStateSlice = createThunkSlice({ selectSelectedLanguage: state => state.selectedLanguage, selectChartLinkHideOptions: state => state.chartLinkHideOptions, selectRefreshingReadings: state => state.refreshingReadings, - selectGraphCreationTime: state => state.graphCreationTime, + selectIsKeepCurrent: state => state.isKeepCurrent, } }); @@ -151,7 +151,7 @@ export const { updateSelectedLanguage, setChartLinkOptionsVisibility, setRefresingReadings, - setGraphCreationTime + setIsKeepCurrent } = appStateSlice.actions; export const { @@ -160,5 +160,5 @@ export const { selectSelectedLanguage, selectChartLinkHideOptions, selectRefreshingReadings, - selectGraphCreationTime + selectIsKeepCurrent } = appStateSlice.selectors; diff --git a/src/client/app/redux/slices/graphSlice.ts b/src/client/app/redux/slices/graphSlice.ts index 265aa7b654..41f18e9632 100644 --- a/src/client/app/redux/slices/graphSlice.ts +++ b/src/client/app/redux/slices/graphSlice.ts @@ -359,7 +359,7 @@ export const { selectSelectedGroups, selectQueryTimeInterval, selectThreeDMeterOrGroup, selectCompareTimeInterval, selectThreeDMeterOrGroupID, selectThreeDReadingInterval, - selectLastMeterOrGroup, selectGraphAreaNormalization, + selectLastMeterOrGroup, selectSliderRangeInterval, selectDefaultGraphState, selectHistoryIsDirty, selectPlotlySliderMax, selectPlotlySliderMin, selectShiftAmount, From e79ee5bd01cefd54a8e6b9a08840ab1500599c46 Mon Sep 17 00:00:00 2001 From: w <161429870+w-b-d@users.noreply.github.com> Date: Sun, 24 Aug 2025 20:22:24 -0700 Subject: [PATCH 14/14] Fixed eslint errors --- .../app/components/ChartLinkComponent.tsx | 68 +++++++++---------- .../app/components/PlotNavComponent.tsx | 2 +- src/client/app/redux/selectors/uiSelectors.ts | 14 ++-- src/client/app/redux/slices/appStateSlice.ts | 4 +- src/client/app/redux/slices/graphSlice.ts | 13 ++-- 5 files changed, 49 insertions(+), 52 deletions(-) diff --git a/src/client/app/components/ChartLinkComponent.tsx b/src/client/app/components/ChartLinkComponent.tsx index ea279a84ad..295a1ae707 100644 --- a/src/client/app/components/ChartLinkComponent.tsx +++ b/src/client/app/components/ChartLinkComponent.tsx @@ -2,29 +2,29 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import * as React from "react"; -import { toast } from "react-toastify"; -import ReactTooltip from "react-tooltip"; -import { Button, ButtonGroup,Input} from "reactstrap"; -import { useAppDispatch, useAppSelector } from "../redux/reduxHooks"; -import { selectChartLink } from "../redux/selectors/uiSelectors"; +import * as React from 'react'; +import { toast } from 'react-toastify'; +import ReactTooltip from 'react-tooltip'; +import { Button, ButtonGroup,Input} from 'reactstrap'; +import { useAppDispatch, useAppSelector } from '../redux/reduxHooks'; +import { selectChartLink } from '../redux/selectors/uiSelectors'; import { -selectChartLinkHideOptions, selectIsKeepCurrent, setChartLinkOptionsVisibility, -setIsKeepCurrent -} from "../redux/slices/appStateSlice"; + selectChartLinkHideOptions, selectIsKeepCurrent, setChartLinkOptionsVisibility, + setIsKeepCurrent +} from '../redux/slices/appStateSlice'; import { selectSelectedGroups, selectSelectedMeters, - selectQueryTimeInterval, -} from "../redux/slices/graphSlice"; + selectQueryTimeInterval +} from '../redux/slices/graphSlice'; import { showErrorNotification, - showInfoNotification, -} from "../utils/notifications"; -import { useTranslate } from "../redux/componentHooks"; -import TooltipMarkerComponent from "./TooltipMarkerComponent"; -import { wellStyle, rowFlexStart, labelStyle } from "../styles/modalStyle"; -import { checkboxStyle } from "../styles/modalStyle"; + showInfoNotification +} from '../utils/notifications'; +import { useTranslate } from '../redux/componentHooks'; +import TooltipMarkerComponent from './TooltipMarkerComponent'; +import { wellStyle, rowFlexStart, labelStyle } from '../styles/modalStyle'; +import { checkboxStyle } from '../styles/modalStyle'; @@ -40,7 +40,7 @@ export default function ChartLinkComponent() { const selectedMeters = useAppSelector(selectSelectedMeters); const selectedGroups = useAppSelector(selectSelectedGroups); const queryTimeInterval = useAppSelector(selectQueryTimeInterval); - const isKeepCurrent = useAppSelector(selectIsKeepCurrent) + const isKeepCurrent = useAppSelector(selectIsKeepCurrent); const ref = React.useRef(null); // THIS react.UseMemo ONLY RETURNS TRUE WHEN THE CONDITIONS ARE MET FOR USING KEEP CURRENT (left is is bounded and right is unbounded) @@ -61,7 +61,7 @@ export default function ChartLinkComponent() { .writeText(linkText) .then(() => { showInfoNotification( - translate("clipboard.copied"), + translate('clipboard.copied'), toast.POSITION.TOP_RIGHT, 1000 ); @@ -69,7 +69,7 @@ export default function ChartLinkComponent() { .catch(() => { // if operation fails, open copyable text for manual copy. showErrorNotification( - translate("clipboard.not.copied"), + translate('clipboard.not.copied'), toast.POSITION.TOP_RIGHT, 1000 ); @@ -80,14 +80,14 @@ export default function ChartLinkComponent() { return (
{/* inputting new "keep chart current" feature */} -
{translate("chart.link.options.title")}
+
{translate('chart.link.options.title')}
{/* hide options checkbox */}
{ + onClickCapture={e => { e.stopPropagation(); dispatch(setChartLinkOptionsVisibility(!linkHideOptions)); }} @@ -98,7 +98,7 @@ export default function ChartLinkComponent() { ref.current && ReactTooltip.hide(ref.current); }} /> - + - {translate("keep.chart.current.label")} + {translate('keep.chart.current.label')} {/* we need to create a tool tip for "keep chart current" checkbox */} @@ -143,24 +143,24 @@ export default function ChartLinkComponent() { - +
{linkTextVisible &&
{linkText}
} diff --git a/src/client/app/components/PlotNavComponent.tsx b/src/client/app/components/PlotNavComponent.tsx index 569e59d74d..347ecab15a 100644 --- a/src/client/app/components/PlotNavComponent.tsx +++ b/src/client/app/components/PlotNavComponent.tsx @@ -110,7 +110,7 @@ export const RefreshGraphComponent = () => { const maxX = initialXAxisRange?.getEndTimestamp?.(); const nextInterval = getNextQueryTimeInterval(queryTimeInterval, sliderInterval, minX, maxX); dispatch(updateTimeIntervalAndSliderRange(nextInterval)); - dispatch(updateTimeCreated()) + dispatch(updateTimeCreated()); } }} /> diff --git a/src/client/app/redux/selectors/uiSelectors.ts b/src/client/app/redux/selectors/uiSelectors.ts index 1f16de3118..fc77bb7e36 100644 --- a/src/client/app/redux/selectors/uiSelectors.ts +++ b/src/client/app/redux/selectors/uiSelectors.ts @@ -454,7 +454,6 @@ export const selectChartLink = createAppSelector( selectChartLinkHideOptions, selectSliderRangeInterval, selectIsKeepCurrent, - state => state.maps.selectedMap ], (current, chartLinkHideOptions, rangeSliderInterval, isKeepCurrent,selectedMap) => { @@ -516,16 +515,13 @@ 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)}`; + if (isKeepCurrent) { + const timeCreatedEnd = current.timeCreated.getEndTimestamp(); + const sliderStart = current.rangeSliderInterval.getStartTimestamp(); + const diffDays = timeCreatedEnd.diff(sliderStart, 'days', true); + linkText += `&timeSpan=${diffDays.toFixed(2)}`; } - return linkText; - } ); diff --git a/src/client/app/redux/slices/appStateSlice.ts b/src/client/app/redux/slices/appStateSlice.ts index c15797b379..7413752f03 100644 --- a/src/client/app/redux/slices/appStateSlice.ts +++ b/src/client/app/redux/slices/appStateSlice.ts @@ -35,7 +35,7 @@ const defaultState: AppState = { chartLinkHideOptions: false, languageManuallySet: false, refreshingReadings: false, - isKeepCurrent: false, + isKeepCurrent: false }; export const appStateSlice = createThunkSlice({ @@ -138,7 +138,7 @@ export const appStateSlice = createThunkSlice({ selectSelectedLanguage: state => state.selectedLanguage, selectChartLinkHideOptions: state => state.chartLinkHideOptions, selectRefreshingReadings: state => state.refreshingReadings, - selectIsKeepCurrent: state => state.isKeepCurrent, + selectIsKeepCurrent: state => state.isKeepCurrent } }); diff --git a/src/client/app/redux/slices/graphSlice.ts b/src/client/app/redux/slices/graphSlice.ts index 41f18e9632..fa2cc31ee4 100644 --- a/src/client/app/redux/slices/graphSlice.ts +++ b/src/client/app/redux/slices/graphSlice.ts @@ -141,7 +141,7 @@ export const graphSlice = createSlice({ if (state.current.threeD.meterOrGroupID !== action.payload) { state.current.threeD.meterOrGroupID = action.payload; } - },updateTimeCreated: (state) => { + },updateTimeCreated: state => { state.current.timeCreated = new TimeInterval(moment(), moment()); }, @@ -293,11 +293,12 @@ export const graphSlice = createSlice({ case 'shiftTimeInterval': current.shiftTimeInterval = TimeInterval.fromString(value); break; - case 'timeSpan': - const days = parseFloat(value) - const now = moment() - const leftBound = now.clone().subtract(days, 'days') - current.rangeSliderInterval = new TimeInterval(leftBound,undefined) + case 'timeSpan':{ + const days = parseFloat(value); + const now = moment(); + const leftBound = now.clone().subtract(days, 'days'); + current.rangeSliderInterval = new TimeInterval(leftBound,undefined); + break;} } }); }