Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Max min values #1396

Open
wants to merge 26 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
92afc55
create unit changes
Nov 26, 2024
8953030
edit unit changes
Nov 26, 2024
4edc46d
Merge pull request #32 from oss-slu/create_unit_1307
Rakesh-Ranga-Buram Nov 27, 2024
c29b70c
Merge pull request #33 from oss-slu/edit_unit_1307
Rakesh-Ranga-Buram Nov 27, 2024
a9380c9
adding coulumns to the units table
Rakesh-Ranga-Buram Nov 27, 2024
e72f18e
Disable changes
Rakesh-Ranga-Buram Dec 5, 2024
fb0b593
Merge pull request #34 from oss-slu/Rakesh_disable_changes
Rakesh-Ranga-Buram Dec 7, 2024
99f5de5
Requested Changes
Rakesh-Ranga-Buram Dec 27, 2024
55a44d8
Merge pull request #35 from oss-slu/MinMax_RequestedChanges
Rakesh-Ranga-Buram Dec 27, 2024
500c00e
preference table changes
Rakesh-Ranga-Buram Dec 28, 2024
d162834
Merge pull request #36 from oss-slu/MinMax_Preference
Rakesh-Ranga-Buram Dec 28, 2024
1b3a182
Merge branch 'development' into MaxMinValues
Rakesh-Ranga-Buram Dec 29, 2024
b4f9431
Update PreferencesComponent.tsx
Rakesh-Ranga-Buram Dec 29, 2024
ca4f316
Update data.ts
Rakesh-Ranga-Buram Dec 29, 2024
788a59e
Adding DisableChecksType enum tests
Rakesh-Ranga-Buram Dec 29, 2024
057b53f
Merge pull request #37 from oss-slu/MinMax_EnumTests
Rakesh-Ranga-Buram Dec 29, 2024
00870ec
Pipeline changes
Rakesh-Ranga-Buram Jan 10, 2025
1851023
Merge pull request #38 from oss-slu/MinMaxValues_pipeline
Rakesh-Ranga-Buram Jan 10, 2025
8523554
Merge branch 'development' into MaxMinValues
Rakesh-Ranga-Buram Jan 13, 2025
996bb4d
resolving merge conflicts
Rakesh-Ranga-Buram Jan 13, 2025
587ab18
Merge pull request #42 from oss-slu/MinMaxValues_conflicts
Rakesh-Ranga-Buram Jan 13, 2025
5ae6979
unrelated translation fix
huss Jan 30, 2025
66781a4
resolving comments
Rakesh-Ranga-Buram Feb 13, 2025
3d31689
Merge pull request #43 from oss-slu/MinMaxValues_comment
Rakesh-Ranga-Buram Feb 13, 2025
9ffcc01
Removing min/max from site settings
Rakesh-Ranga-Buram Feb 20, 2025
81d3655
Merge pull request #44 from oss-slu/MinMaxValues_SiteSettings
Rakesh-Ranga-Buram Feb 20, 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
29 changes: 22 additions & 7 deletions src/client/app/components/meters/CreateMeterModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { useTranslate } from '../../redux/componentHooks';
import TimeZoneSelect from '../TimeZoneSelect';
import TooltipHelpComponent from '../TooltipHelpComponent';
import TooltipMarkerComponent from '../TooltipMarkerComponent';
import { selectUnitDataById } from '../../redux/api/unitsApi';

interface CreateMeterModalProps {
onCreateMeter?: (meterIdentifier: string) => void; // Define the type of the callback function
Expand All @@ -55,6 +56,7 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps):
const [meterDetails, setMeterDetails] = useState(defaultValues);
const unitIsSelected = meterDetails.unitId !== -999;
const defaultGaphicUnitIsSelected = meterDetails.defaultGraphicUnit !== -999;
const unitsDataById = useAppSelector(selectUnitDataById);

const { compatibleGraphicUnits, incompatibleGraphicUnits, compatibleUnits } = useAppSelector(state =>
// Type assertion due to conflicting GPS Property
Expand Down Expand Up @@ -92,6 +94,21 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps):
const handleTimeZoneChange = (timeZone: string) => {
setMeterDetails({ ...meterDetails, ['timeZone']: timeZone });
};

const handleUnitChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selectedUnitId = Number(e.target.value);
const selectedUnit = unitsDataById[selectedUnitId];

if (selectedUnit) {
setMeterDetails(details => ({
...details,
unitId: selectedUnitId,
minVal: selectedUnit.minVal,
maxVal: selectedUnit.maxVal
}));
}
};

// Reset the state to default values
const resetState = () => {
setMeterDetails(defaultValues);
Expand Down Expand Up @@ -245,9 +262,7 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps):
</Label>
<Input id='unitId' name='unitId' type='select'
value={meterDetails.unitId}
onChange={e => {
handleNumberChange(e);
}}
onChange={handleUnitChange}
invalid={!unitIsSelected}>
<option value={-999} key={-999} hidden disabled>
{translate('select.unit')}
Expand Down Expand Up @@ -544,25 +559,25 @@ export default function CreateMeterModalComponent(props: CreateMeterModalProps):
<Row xs='1' lg='2'>
{/* minVal input */}
<Col><FormGroup>
<Label for='minVal'>{translate('meter.minVal')}</Label>
<Label for='minVal'>{translate('minVal')}</Label>
<Input id='minVal' name='minVal' type='number'
onChange={e => handleNumberChange(e)}
min={MIN_VAL}
max={meterDetails.maxVal}
defaultValue={meterDetails.minVal}
value={meterDetails.minVal}
invalid={meterDetails?.minVal < MIN_VAL || meterDetails?.minVal > meterDetails?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: MIN_VAL, max: meterDetails.maxVal }} />
</FormFeedback>
</FormGroup></Col>
{/* maxVal input */}
<Col><FormGroup>
<Label for='maxVal'>{translate('meter.maxVal')}</Label>
<Label for='maxVal'>{translate('maxVal')}</Label>
<Input id='maxVal' name='maxVal' type='number'
onChange={e => handleNumberChange(e)}
min={meterDetails.minVal}
max={MAX_VAL}
defaultValue={meterDetails.maxVal}
value={meterDetails.maxVal}
invalid={meterDetails?.maxVal > MAX_VAL || meterDetails?.minVal > meterDetails?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: meterDetails.minVal, max: MAX_VAL }} />
Expand Down
30 changes: 27 additions & 3 deletions src/client/app/components/meters/EditMeterModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr

const [validMeter, setValidMeter] = useState(isValidMeter(localMeterEdits));

useEffect(() => {
const selectedUnit = unitDataById[localMeterEdits.unitId];
if (selectedUnit) {
setLocalMeterEdits(edits => ({
...edits,
minVal: selectedUnit.minVal,
maxVal: selectedUnit.maxVal
}));
}
}, [localMeterEdits.unitId, unitDataById]);

useEffect(() => { setValidMeter(isValidMeter(localMeterEdits)); }, [localMeterEdits]);
/* End State */

Expand All @@ -76,6 +87,19 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr
}
}, [localMeterEdits.cumulative]);

const handleUnitChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const selectedUnitId = Number(e.target.value);
const selectedUnit = unitDataById[selectedUnitId];
if (selectedUnit) {
setLocalMeterEdits({
...localMeterEdits,
unitId: selectedUnitId,
minVal: selectedUnit.minVal,
maxVal: selectedUnit.maxVal
});
}
};

// Save changes
// Currently using the old functionality which is to compare inherited prop values to state values
// If there is a difference between props and state, then a change was made
Expand Down Expand Up @@ -279,7 +303,7 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr
name='unitId'
type='select'
value={localMeterEdits.unitId}
onChange={e => handleNumberChange(e)}>
onChange={handleUnitChange}>
{Array.from(compatibleUnits).map(unit => {
return (<option value={unit.id} key={unit.id}>{unit.identifier}</option>);
})}
Expand Down Expand Up @@ -599,7 +623,7 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr
<Row xs='1' lg='2'>
{/* minVal input */}
<Col><FormGroup>
<Label for='minVal'>{translate('meter.minVal')}</Label>
<Label for='minVal'>{translate('minVal')}</Label>
<Input
id='minVal'
name='minVal'
Expand All @@ -615,7 +639,7 @@ export default function EditMeterModalComponent(props: EditMeterModalComponentPr
</FormGroup></Col>
{/* maxVal input */}
<Col><FormGroup>
<Label for='maxVal'>{translate('meter.maxVal')}</Label>
<Label for='maxVal'>{translate('maxVal')}</Label>
<Input
id='maxVal'
name='maxVal'
Expand Down
33 changes: 32 additions & 1 deletion src/client/app/components/unit/CreateUnitModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { tooltipBaseStyle } from '../../styles/modalStyle';
import { unitsApi } from '../../redux/api/unitsApi';
import { useTranslate } from '../../redux/componentHooks';
import { showSuccessNotification, showErrorNotification } from '../../utils/notifications';
import { MAX_VAL, MIN_VAL } from '../../redux/selectors/adminSelectors';

/**
* Defines the create unit modal form
Expand All @@ -38,7 +39,9 @@ export default function CreateUnitModalComponent() {
// The client code makes the id for the selected unit and default graphic unit be -99
// so it can tell it is not yet assigned and do the correct logic for that case.
// The units API expects these values to be undefined on call so that the database can assign their values.
id: -99
id: -99,
minVal: MIN_VAL,
maxVal: MAX_VAL
};

/* State */
Expand Down Expand Up @@ -267,6 +270,34 @@ export default function CreateUnitModalComponent() {
</FormFeedback>
</FormGroup></Col>
</Row>
<Row xs='1' lg='2'>
{/* minVal input */}
<Col><FormGroup>
<Label for='minVal'>{translate('minVal')}</Label>
<Input id='minVal' name='minVal' type='number'
onChange={e => handleNumberChange(e)}
min={MIN_VAL}
max={state.maxVal}
defaultValue={state.minVal}
invalid={state?.minVal < MIN_VAL || state?.minVal > state?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: MIN_VAL, max: state.maxVal }} />
</FormFeedback>
</FormGroup></Col>
{/* maxVal input */}
<Col><FormGroup>
<Label for='maxVal'>{translate('maxVal')}</Label>
<Input id='maxVal' name='maxVal' type='number'
onChange={e => handleNumberChange(e)}
min={state.minVal}
max={MAX_VAL}
defaultValue={state.maxVal}
invalid={state?.maxVal > MAX_VAL || state?.minVal > state?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: state.minVal, max: MAX_VAL }} />
</FormFeedback>
</FormGroup></Col>
</Row>
{/* Note input */}
<FormGroup>
<Label for='note'>{translate('note')}</Label>
Expand Down
35 changes: 34 additions & 1 deletion src/client/app/components/unit/EditUnitModalComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { conversionArrow } from '../../utils/conversionArrow';
import { showErrorNotification, showSuccessNotification } from '../../utils/notifications';
import ConfirmActionModalComponent from '../ConfirmActionModalComponent';
import TooltipMarkerComponent from '../TooltipMarkerComponent';
import { MAX_VAL, MIN_VAL } from '../../redux/selectors/adminSelectors';

interface EditUnitModalComponentProps {
show: boolean;
Expand Down Expand Up @@ -193,7 +194,9 @@ export default function EditUnitModalComponent(props: EditUnitModalComponentProp
|| props.unit.preferredDisplay != state.preferredDisplay
|| props.unit.secInRate != state.secInRate
|| props.unit.suffix != state.suffix
|| props.unit.note != state.note;
|| props.unit.note != state.note
|| props.unit.minVal != state.minVal
|| props.unit.maxVal != state.maxVal;
} else {
// Tell user that not going to update due to input issues.
showErrorNotification(`${translate('unit.input.error')}`);
Expand Down Expand Up @@ -418,6 +421,36 @@ export default function EditUnitModalComponent(props: EditUnitModalComponentProp
</FormFeedback>
</FormGroup></Col>
</Row>
<Row xs='1' lg='2'>
{/* minVal input */}
<Col><FormGroup>
<Label for='minVal'>{translate('minVal')}</Label>
<Input id='minVal' name='minVal' type='number'
onChange={e => handleNumberChange(e)}
min={MIN_VAL}
max={state.maxVal}
defaultValue={state.minVal}
required value={state.minVal}
invalid={state?.minVal < MIN_VAL || state?.minVal > state?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: MIN_VAL, max: state.maxVal }} />
</FormFeedback>
</FormGroup></Col>
{/* maxVal input */}
<Col><FormGroup>
<Label for='maxVal'>{translate('maxVal')}</Label>
<Input id='maxVal' name='maxVal' type='number'
onChange={e => handleNumberChange(e)}
min={state.minVal}
max={MAX_VAL}
defaultValue={state.maxVal}
required value={state.maxVal}
invalid={state?.maxVal > MAX_VAL || state?.minVal > state?.maxVal} />
<FormFeedback>
<FormattedMessage id="error.bounds" values={{ min: state.minVal, max: MAX_VAL }} />
</FormFeedback>
</FormGroup></Col>
</Row>
{/* Note input */}
<FormGroup>
<Label for='note'>{translate('unit')}</Label>
Expand Down
12 changes: 6 additions & 6 deletions src/client/app/translations/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ const LocaleTranslationData = {
"meter.enabled": "Updates:",
"meter.endOnlyTime": "Only End Times:",
"meter.endTimeStamp": "End Time Stamp:",
"meter.minVal": "Minimum Reading Value Check",
"meter.maxVal": "Maximum Reading Value Check",
"minVal": "Minimum Reading Value Check",
"maxVal": "Maximum Reading Value Check",
"meter.minDate": "Minimum Reading Date Check",
"meter.maxDate": "Maximum Reading Date Check",
"meter.maxError": "Maximum Number of Errors Check",
Expand Down Expand Up @@ -860,8 +860,8 @@ const LocaleTranslationData = {
"meter.enabled": "Mises à Jour du Mèters",
"meter.endOnlyTime": "End Only Time:\u{26A1}",
"meter.endTimeStamp": "End Time Stamp:\u{26A1}",
"meter.minVal": "Minimum Reading Value Check\u{26A1}",
"meter.maxVal": "Maximum Reading Value Check\u{26A1}",
"minVal": "Minimum Reading Value Check\u{26A1}",
"maxVal": "Maximum Reading Value Check\u{26A1}",
"meter.minDate": "Minimum Reading Date Check\u{26A1}",
"meter.maxDate": "Maximum Reading Date Check\u{26A1}",
"meter.maxError": "Maximum Number of Errors Check\u{26A1}",
Expand Down Expand Up @@ -1382,8 +1382,8 @@ const LocaleTranslationData = {
"meter.enabled": "Medidor activado",
"meter.endOnlyTime": "Solo tiempos finales.",
"meter.endTimeStamp": "Marca de tiempo al final:",
"meter.minVal": "Revisión del valor mínimo de lectura",
"meter.maxVal": "Revisión del valor máximo de lectura",
"minVal": "Revisión del valor mínimo de lectura",
"maxVal": "Revisión del valor máximo de lectura",
"meter.minDate": "Revisión de la fecha mínima de lectura",
"meter.maxDate": "Revisión de la fecha máxima de lectura",
"meter.maxError": "Revisión del número máximo de errores",
Expand Down
26 changes: 14 additions & 12 deletions src/client/app/types/redux/units.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,22 @@ export interface UnitData {
displayable: DisplayableType;
preferredDisplay: boolean;
note: string;
maxVal: number;
minVal: number;
}

export interface UnitEditData {
id: number;
name: string;
identifier: string;
unitRepresent: string;
secInRate: number;
typeOfUnit: UnitType;
suffix: string;
displayable: DisplayableType;
preferredDisplay: boolean;
note: string;
}
// export interface UnitEditData {
// id: number;
// name: string;
// identifier: string;
// unitRepresent: string;
// secInRate: number;
// typeOfUnit: UnitType;
// suffix: string;
// displayable: DisplayableType;
// preferredDisplay: boolean;
// note: string;
// }

export interface UnitDataById extends Record<number, UnitData> { }

Expand Down
4 changes: 3 additions & 1 deletion src/client/app/utils/input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ export const NoUnit: UnitData = {
suffix: '',
displayable: DisplayableType.none,
preferredDisplay: false,
note: ''
note: '',
minVal: -Infinity,
maxVal: Infinity
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/server/migrations/1.0.0-2.0.0/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ module.exports = {
// It should not matter but first rename cik and then do units.
await db.none(sqlFile('../migrations/1.0.0-2.0.0/sql/cik/alter_cik_table.sql'));
await db.none(sqlFile('../migrations/1.0.0-2.0.0/sql/units/alter_units_table.sql'));
await db.none(sqlFile('../migrations/1.0.0-2.0.0/sql/units/alter_units_table_add_columns.sql'));
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */

ALTER TABLE units
ADD COLUMN IF NOT EXISTS min_val FLOAT NOT NULL DEFAULT -9007199254740991 CHECK (min_val::FLOAT >= -9007199254740991),
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 unclear on the value of these checks as it seems to verify it is not out of bounds of allowed min/max float. Would it make sense to remove these checks and check that max_val >= min_val? This also applies to meters (and preferences but those seem likely to go away).

ADD COLUMN IF NOT EXISTS max_val FLOAT NOT NULL DEFAULT 9007199254740991 CHECK (max_val::FLOAT <= 9007199254740991)
;
6 changes: 4 additions & 2 deletions src/server/models/Unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Unit {
* @param {*} preferredDisplay True if this unit is always displayed. If not, the user needs to ask to see (for future enhancement).
* @param {*} note Note about this unit.
*/
constructor(id, name, identifier = name, unitRepresent, secInRate = 3600, typeOfUnit, suffix = '', displayable, preferredDisplay, note) {
constructor(id, name, identifier = name, unitRepresent, secInRate = 3600, typeOfUnit, suffix = '', displayable, preferredDisplay, note, minVal, maxVal) {
this.id = id;
this.name = name;
this.identifier = identifier;
Expand All @@ -30,6 +30,8 @@ class Unit {
this.displayable = displayable;
this.preferredDisplay = preferredDisplay;
this.note = note;
this.minVal = minVal;
this.maxVal = maxVal;
}

/**
Expand All @@ -39,7 +41,7 @@ class Unit {
*/
static mapRow(row) {
return new Unit(row.id, row.name, row.identifier, row.unit_represent, row.sec_in_rate,
row.type_of_unit, row.suffix, row.displayable, row.preferred_display, row.note);
row.type_of_unit, row.suffix, row.displayable, row.preferred_display, row.note, row.min_val, row.max_val);
}

/**
Expand Down
Loading
Loading