Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/v1.0.0' into development
Browse files Browse the repository at this point in the history
fix up some meter modal columns too
  • Loading branch information
huss committed Sep 30, 2023
2 parents 4eacc17 + 86af4a5 commit 0b326f3
Show file tree
Hide file tree
Showing 60 changed files with 941 additions and 798 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ private
!/src/server/test/**/*.csv
!/src/server/data/unit/*.csv

# CSV gz files (except ones needed for database tests)
*.csv.gz
!/src/server/test/**/*.csv.gz
!/src/server/data/unit/*.csv.gz

# Database
postgres-data

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "open-energy-dashboard",
"version": "0.8.0",
"version": "1.0.0",
"private": false,
"license": "MPL-2.0",
"repository": "https://github.com/OpenEnergyDashboard/OED",
Expand Down
7 changes: 5 additions & 2 deletions src/client/app/actions/admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ export function updateDefaultAreaUnit(defaultAreaUnit: AreaUnitType): t.UpdateDe
}

export function updateDefaultLanguage(defaultLanguage: LanguageTypes): t.UpdateDefaultLanguageAction {
moment.locale(defaultLanguage);
return { type: ActionType.UpdateDefaultLanguage, defaultLanguage };
}

Expand Down Expand Up @@ -113,7 +112,6 @@ function fetchPreferences(): Thunk {
dispatch(requestPreferences());
const preferences = await preferencesApi.getPreferences();
dispatch(receivePreferences(preferences));
moment.locale(getState().admin.defaultLanguage);
if (!getState().graph.hotlinked) {
dispatch((dispatch2: Dispatch) => {
const state = getState();
Expand All @@ -125,7 +123,12 @@ function fetchPreferences(): Thunk {
dispatch2(toggleAreaNormalization());
}
if (preferences.defaultLanguage !== state.options.selectedLanguage) {
// if the site default differs from the selected language, update the selected language and the locale
dispatch2(updateSelectedLanguage(preferences.defaultLanguage));
moment.locale(preferences.defaultLanguage);
} else {
// else set moment locale to site default
moment.locale(getState().admin.defaultLanguage);
}
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/client/app/actions/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
* 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 moment from 'moment';
import { ActionType } from '../types/redux/actions';
import { LanguageTypes } from '../types/redux/i18n';
import * as t from '../types/redux/options';

export function updateSelectedLanguage(selectedLanguage: LanguageTypes): t.UpdateSelectedLanguageAction {
moment.locale(selectedLanguage);
return {type: ActionType.UpdateSelectedLanguage, selectedLanguage };
}
6 changes: 3 additions & 3 deletions src/client/app/components/AreaUnitSelectComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ export default function AreaUnitSelectComponent() {
{graphState.areaNormalization &&
<div>
<p style={labelStyle}>
<FormattedMessage id='units.area' />:
<FormattedMessage id='area.unit' />:
</p>
<Select
options={unitOptions}
value={{ label: translate(`AreaUnitType.${graphState.selectedAreaUnit}`), value: graphState.selectedAreaUnit} as StringSelectOption}
value={{ label: translate(`AreaUnitType.${graphState.selectedAreaUnit}`), value: graphState.selectedAreaUnit } as StringSelectOption}
onChange={newSelectedUnit => {
if (newSelectedUnit) {
dispatch(updateSelectedAreaUnit(newSelectedUnit.value as AreaUnitType))
Expand All @@ -84,4 +84,4 @@ export default function AreaUnitSelectComponent() {
}
</div>
);
}
}
7 changes: 4 additions & 3 deletions src/client/app/components/ChartDataSelectComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { UnitsState } from '../types/redux/units';
import { MetersState } from 'types/redux/meters';
import { GroupsState } from 'types/redux/groups';
import { AreaUnitType } from '../utils/getAreaUnitConversion';
import translate from '../utils/translate';

/**
* A component which allows the user to select which data should be displayed on the chart.
Expand Down Expand Up @@ -187,7 +188,7 @@ export default function ChartDataSelectComponent() {
if (firstDisabledMeter != -1) {
sortedMeters.splice(firstDisabledMeter, 0, {
value: 0,
label: '----- Incompatible Meters -----',
label: '----- ' + translate('incompatible.meters') + ' -----',
isDisabled: true
} as SelectOption
);
Expand Down Expand Up @@ -230,7 +231,7 @@ export default function ChartDataSelectComponent() {
if (firstDisabledGroup != -1) {
sortedGroups.splice(firstDisabledGroup, 0, {
value: 0,
label: '----- Incompatible Groups -----',
label: '----- ' + translate('incompatible.groups') + ' -----',
isDisabled: true
} as SelectOption
);
Expand All @@ -257,7 +258,7 @@ export default function ChartDataSelectComponent() {
if (firstDisabledUnit != -1) {
sortedUnits.splice(firstDisabledUnit, 0, {
value: 0,
label: '----- Incompatible Units -----',
label: '----- ' + translate('incompatible.units') + ' -----',
isDisabled: true
} as SelectOption
);
Expand Down
43 changes: 23 additions & 20 deletions src/client/app/components/ExportComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { hasToken } from '../utils/token';
import { usersApi } from '../utils/api'
import { UserRole } from '../types/items';
import translate from '../utils/translate';
import { ChartTypes } from '../types/redux/graph';
import { ChartTypes, MeterOrGroup } from '../types/redux/graph';
import { lineUnitLabel, barUnitLabel } from '../utils/graphics';
import { ConversionData } from '../types/redux/conversions';
import { AreaUnitType, getAreaUnitConversion } from '../utils/getAreaUnitConversion';
Expand Down Expand Up @@ -57,20 +57,22 @@ export default function ExportComponent() {
// Get the full y-axis unit label for a line
const returned = lineUnitLabel(unitsState[unitId], graphState.lineGraphRate, graphState.areaNormalization, graphState.selectedAreaUnit);
const unitLabel = returned.unitLabel
// The rate will be 1 if it is per hour (since state readings are per hour) or no rate scaling so no change.
const rateScaling = returned.needsRateScaling ? graphState.lineGraphRate.rate : 1;
// Loop over the displayed meters and export one-by-one. Does nothing if no meters selected.
for (const meterId of graphState.selectedMeters) {
const meterArea = metersState[meterId].area;
// export if area normalization is off or the meter can be normalized
if (!graphState.areaNormalization || (metersState[meterId].area > 0 && metersState[meterId].areaUnit !== AreaUnitType.none)) {
if (!graphState.areaNormalization || (meterArea > 0 && metersState[meterId].areaUnit !== AreaUnitType.none)) {
// Line readings data for this meter.
const byMeterID = readingsState.line.byMeterID[meterId];
// Make sure it exists in case state is not there yet.
if (byMeterID !== undefined) {
// The selected rate for scaling
let scaling = graphState.lineGraphRate.rate;
if (graphState.areaNormalization) {
// convert the meter area into the proper unit, if needed
scaling *= getAreaUnitConversion(metersState[meterId].areaUnit, graphState.selectedAreaUnit);
}
// Convert the meter area into the proper unit if normalizing by area or use 1 if not so won't change reading values.
const areaScaling = graphState.areaNormalization ?
meterArea * getAreaUnitConversion(metersState[meterId].areaUnit, graphState.selectedAreaUnit) : 1;
// Divide areaScaling into the rate so have complete scaling factor for readings.
const scaling = rateScaling / areaScaling;
// Get the readings for the time range and unit graphed
const byTimeInterval = byMeterID[timeInterval.toString()];
if (byTimeInterval !== undefined) {
Expand All @@ -86,26 +88,27 @@ export default function ExportComponent() {
const sortedReadings = _.sortBy(readings, item => item.startTimestamp, 'asc');
// Identifier for current meter.
const meterIdentifier = metersState[meterId].identifier;
graphExport(sortedReadings, meterIdentifier, unitLabel, unitIdentifier, chartName, scaling, errorBarState);
graphExport(sortedReadings, meterIdentifier, unitLabel, unitIdentifier, chartName, scaling, MeterOrGroup.meter, errorBarState);
}
}
}
}
}
// Loop over the displayed groups and export one-by-one. Does nothing if no groups selected.
for (const groupId of graphState.selectedGroups) {
const groupArea = groupsState[groupId].area;
// export if area normalization is off or the group can be normalized
if (!graphState.areaNormalization || (groupsState[groupId].area > 0 && groupsState[groupId].areaUnit !== AreaUnitType.none)) {
if (!graphState.areaNormalization || (groupArea > 0 && groupsState[groupId].areaUnit !== AreaUnitType.none)) {
// Line readings data for this group.
const byGroupID = readingsState.line.byGroupID[groupId];
// Make sure it exists in case state is not there yet.
if (byGroupID !== undefined) {
// The selected rate for scaling
let scaling = graphState.lineGraphRate.rate;
if (graphState.areaNormalization) {
// convert the meter area into the proper unit, if needed
scaling *= getAreaUnitConversion(groupsState[groupId].areaUnit, graphState.selectedAreaUnit);
}
// Convert the group area into the proper unit if normalizing by area or use 1 if not so won't change reading values.
const areaScaling = graphState.areaNormalization ?
groupArea * getAreaUnitConversion(groupsState[groupId].areaUnit, graphState.selectedAreaUnit) : 1;
// Divide areaScaling into the rate so have complete scaling factor for readings.
const scaling = rateScaling / areaScaling;

// Get the readings for the time range and unit graphed
const byTimeInterval = byGroupID[timeInterval.toString()];
if (byTimeInterval !== undefined) {
Expand All @@ -121,7 +124,7 @@ export default function ExportComponent() {
const sortedReadings = _.sortBy(readings, item => item.startTimestamp, 'asc');
// Identifier for current group.
const groupName = groupsState[groupId].name;
graphExport(sortedReadings, groupName, unitLabel, unitIdentifier, chartName, scaling);
graphExport(sortedReadings, groupName, unitLabel, unitIdentifier, chartName, scaling, MeterOrGroup.group);
}
}
}
Expand Down Expand Up @@ -164,7 +167,7 @@ export default function ExportComponent() {
const sortedReadings = _.sortBy(readings, item => item.startTimestamp, 'asc');
// Identifier for current meter.
const meterIdentifier = metersState[meterId].identifier;
graphExport(sortedReadings, meterIdentifier, unitLabel, unitIdentifier, chartName, scaling);
graphExport(sortedReadings, meterIdentifier, unitLabel, unitIdentifier, chartName, scaling, MeterOrGroup.meter);
}
}
}
Expand Down Expand Up @@ -202,7 +205,7 @@ export default function ExportComponent() {
const sortedReadings = _.sortBy(readings, item => item.startTimestamp, 'asc');
// Identifier for current group.
const groupName = groupsState[groupId].name;
graphExport(sortedReadings, groupName, unitLabel, unitIdentifier, chartName, scaling);
graphExport(sortedReadings, groupName, unitLabel, unitIdentifier, chartName, scaling, MeterOrGroup.group);
}
}
}
Expand Down Expand Up @@ -326,4 +329,4 @@ export default function ExportComponent() {
</div> : ''}
</>
);
}
}
49 changes: 42 additions & 7 deletions src/client/app/components/HeaderButtonsComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import { Navbar, Nav, NavLink, UncontrolledDropdown, DropdownToggle, DropdownMen
import LanguageSelectorComponent from './LanguageSelectorComponent';
import { toggleOptionsVisibility } from '../actions/graph';
import { BASE_URL } from './TooltipHelpComponent';
import TooltipMarkerComponent from './TooltipMarkerComponent';
import TooltipHelpContainer from '../containers/TooltipHelpContainer';

/**
* React Component that defines the header buttons at the top of a page
Expand All @@ -30,6 +32,13 @@ export default function HeaderButtonsComponent() {
// Get the current page so know which one should not be shown in menu.
const currentPage = getPage();

// OED version is needed for help redirect
const version = useSelector((state: State) => state.version.version);
// Help URL location
let helpUrl = BASE_URL + version;
// options help
const optionsHelp = helpUrl + '/optionsMenu.html';

// This is the state model for rendering this page.
const defaultState = {
// All these values should update before user interacts with them so hide everything until the useEffects
Expand Down Expand Up @@ -60,7 +69,9 @@ export default function HeaderButtonsComponent() {
shouldUnitsButtonDisabled: true,
shouldConversionsButtonDisabled: true,
// Translated menu title that depend on whether logged in.
menuTitle: ''
menuTitle: '',
// link to help page for page choices. Should not see default but use general help URL.
pageChoicesHelp: helpUrl
};

// Local state for rendering.
Expand All @@ -71,9 +82,15 @@ export default function HeaderButtonsComponent() {
const unsavedChangesState = useSelector((state: State) => state.unsavedWarning.hasUnsavedChanges);
// whether to collapse options when on graphs page
const optionsVisibility = useSelector((state: State) => state.graph.optionsVisibility);
// OED version is needed for help redirect
const version = useSelector((state: State) => state.version.version);
const HELP_URL = BASE_URL + version;

// Must update in case the version was not set when the page was loaded.
useEffect(() => {
helpUrl = BASE_URL + version;
setState(prevState => ({
...prevState,
pageChoicesHelp: helpUrl
}));
}, [version]);

// This updates which page is disabled because it is the one you are on.
useEffect(() => {
Expand Down Expand Up @@ -133,16 +150,21 @@ export default function HeaderButtonsComponent() {
const currentShowOptionsStyle = {
display: currentPage === '' ? 'block' : 'none'
}
// Admin help or regular user page
const neededPage = loggedInAsAdmin ? '/adminPageChoices.html' : '/pageChoices.html';
const currentPageChoicesHelp = helpUrl + neededPage;

setState(prevState => ({
...prevState,
adminViewableLinkStyle: currentAdminViewableLinkStyle,
csvViewableLinkStyle: currentCsvViewableLinkStyle,
loginLinkStyle: currentLoginLinkStyle,
logoutLinkStyle: currentLogoutLinkStyle,
menuTitle: currentMenuTitle,
pageChoicesHelp: currentPageChoicesHelp,
showOptionsStyle: currentShowOptionsStyle
}));
}, [currentUser]);
}, [currentUser, helpUrl]);

// Handle actions on logout.
const handleLogOut = () => {
Expand All @@ -160,6 +182,8 @@ export default function HeaderButtonsComponent() {
return (
<div>
<Navbar expand>
<TooltipHelpContainer page={'all'} />
<TooltipMarkerComponent page='all' helpTextId='help.home.navigation' />
<Nav navbar>
<NavLink
disabled={state.shouldHomeButtonDisabled}
Expand Down Expand Up @@ -220,6 +244,11 @@ export default function HeaderButtonsComponent() {
to="/admin">
<FormattedMessage id='admin.panel' />
</DropdownItem>
<DropdownItem divider />
<DropdownItem
href={state.pageChoicesHelp}>
<FormattedMessage id="help" />
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<UncontrolledDropdown nav inNavbar>
Expand All @@ -230,6 +259,7 @@ export default function HeaderButtonsComponent() {
<LanguageSelectorComponent />
<DropdownItem
style={state.showOptionsStyle}
className='d-none d-lg-block'
onClick={() => dispatch(toggleOptionsVisibility())}>
<FormattedMessage id={optionsVisibility ? 'hide.options' : 'show.options'} />
</DropdownItem>
Expand All @@ -247,14 +277,19 @@ export default function HeaderButtonsComponent() {
onClick={handleLogOut}>
<FormattedMessage id='log.out' />
</DropdownItem>
<DropdownItem divider />
<DropdownItem
href={optionsHelp}>
<FormattedMessage id="help" />
</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
<NavLink
href={HELP_URL}>
href={helpUrl}>
<FormattedMessage id='help' />
</NavLink>
</Nav>
</Navbar>
</div>
);
}
}
Loading

0 comments on commit 0b326f3

Please sign in to comment.