From 438c667422d9ba12e6f8d97acf8a45ddbf476263 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Wed, 4 May 2022 09:59:01 -0700
Subject: [PATCH 01/18] large-scale refactor of subject control buttons for
uniformity.
---
src/GpsFormatToggle/index.js | 9 +-
src/HeatmapToggleButton/index.js | 24 ++---
src/HeatmapToggleButton/styles.module.scss | 94 ++-----------------
src/SubjectControls/_mixins.scss | 61 ++++++++++++
src/SubjectControls/button.js | 33 +++++++
src/SubjectControls/index.js | 24 ++++-
src/SubjectControls/index.test.js | 24 +++++
src/SubjectControls/styles.module.scss | 3 +-
src/SubjectGroupList/SubjectListItem.js | 2 +-
src/SubjectHistoricalDataModal/index.js | 29 ++++--
src/SubjectHistoricalDataModal/index.test.js | 3 +-
.../PatrolAwareTrackToggleButton.js | 69 ++++++++++++++
src/SubjectHistoryButton/index.js | 29 ++++++
src/SubjectHistoryButton/index.test.js | 32 +++++++
src/SubjectHistoryButton/styles.module.scss | 61 ++++++++++++
src/SubjectPopup/index.js | 46 ++++-----
src/SubjectPopup/index.test.js | 15 ---
src/SubjectPopup/styles.module.scss | 6 ++
src/TrackToggleButton/index.js | 32 +++++--
src/TrackToggleButton/styles.module.scss | 70 ++------------
src/common/images/icons/historical-data.svg | 3 +
src/common/images/icons/marker-feed.svg | 2 +-
src/common/styles/vars/_colors.scss | 2 +
23 files changed, 442 insertions(+), 231 deletions(-)
create mode 100644 src/SubjectControls/_mixins.scss
create mode 100644 src/SubjectControls/button.js
create mode 100644 src/SubjectControls/index.test.js
create mode 100644 src/SubjectHistoryButton/PatrolAwareTrackToggleButton.js
create mode 100644 src/SubjectHistoryButton/index.js
create mode 100644 src/SubjectHistoryButton/index.test.js
create mode 100644 src/SubjectHistoryButton/styles.module.scss
create mode 100644 src/common/images/icons/historical-data.svg
diff --git a/src/GpsFormatToggle/index.js b/src/GpsFormatToggle/index.js
index 9935174b9..0f116626f 100644
--- a/src/GpsFormatToggle/index.js
+++ b/src/GpsFormatToggle/index.js
@@ -23,8 +23,7 @@ const GpsFormatToggle = (props) => {
});
};
- const gpsString = showGpsString && calcGpsDisplayString(lat, lng, currentFormat);
- const displayGpsString = gpsString || null;
+ const gpsString = showGpsString ? calcGpsDisplayString(lat, lng, currentFormat) : null;
return (
@@ -34,9 +33,9 @@ const GpsFormatToggle = (props) => {
onClick={() => onGpsFormatClick(gpsFormat)}>{gpsFormat}
)}
- {displayGpsString &&
-
{displayGpsString}
- {showCopyControl &&
}
+ {gpsString &&
+ {gpsString}
+ {showCopyControl && }
}
diff --git a/src/HeatmapToggleButton/index.js b/src/HeatmapToggleButton/index.js
index 0b044fecf..c61e4fc40 100644
--- a/src/HeatmapToggleButton/index.js
+++ b/src/HeatmapToggleButton/index.js
@@ -1,19 +1,21 @@
-import React, { memo } from 'react';
+import React, { memo, useMemo } from 'react';
import noop from 'lodash/noop';
import PropTypes from 'prop-types';
import styles from './styles.module.scss';
-import LoadingOverlay from '../LoadingOverlay';
+
+import SubjectControlButton from '../SubjectControls/button';
const HeatmapToggleButton = (props) => {
- const { className: externalClass, heatmapVisible, heatmapPartiallyVisible, onButtonClick, showLabel, loading } = props;
- const className = heatmapVisible ? 'visible' : heatmapPartiallyVisible ? 'partial' : '';
- const labelText = className ? 'Heatmap on' : 'Heatmap off';
-
- return
- {loading && }
-
- {showLabel && {labelText}}
-
;
+ const { className: externalClass, heatmapVisible, heatmapPartiallyVisible, onButtonClick, ...rest } = props;
+
+ const stateClassName = heatmapVisible ? 'visible' : heatmapPartiallyVisible ? 'partial' : '';
+
+ const containerClassName = `${styles.container} ${stateClassName}`;
+ const buttonClassName = `${styles.button} ${styles[stateClassName]} ${externalClass || ''}`;
+
+ const labelText = stateClassName ? 'Heatmap on' : 'Heatmap off';
+
+ return
;
};
export default memo(HeatmapToggleButton);
diff --git a/src/HeatmapToggleButton/styles.module.scss b/src/HeatmapToggleButton/styles.module.scss
index 0613adcb9..df4354d5f 100644
--- a/src/HeatmapToggleButton/styles.module.scss
+++ b/src/HeatmapToggleButton/styles.module.scss
@@ -1,92 +1,16 @@
@import '../common/styles/buttons';
-
-$background_image_url: '../common/images/icons/';
-
-@mixin button($image: 'heatmap') {
- background: url('#{$background-image_url+$image}.svg');
- background-size: cover;
- border: none;
- display: block;
- filter: saturate(50%) grayscale(100%);
- height: $square-button-dimension;
- outline: none;
- width: $square-button-dimension;
-
- &:focus {
- outline: none;
- }
-}
-
-.button {
- @include button;
- &.visible {
- filter: unset;
- }
-}
+@import '../SubjectControls/mixins';
.container {
- align-items: center;
- display: flex;
- flex-flow: row;
- position: relative;
-
- &.hasLabel {
- background-color: rgba($secondary-light-gray, .25);
- border: 0.06rem solid $secondary-medium-light-gray;
- border-radius: .12rem;
- max-width: 5.75rem;
- max-height: 1.85rem;
- border-radius: 0.2rem;
- cursor: pointer;
-
- [class*=spinner] {
- position: relative;
- top: -16%;
+ @include control;
+ .button {
+ @include buttonBackground('heatmap');
+ filter: saturate(50%) grayscale(100%);
+ &.visible {
+ filter: unset;
}
-
- button {
- min-height: 1.80rem;
- height: 1.80rem;
- min-width: 1.80rem;
- width: 1.80rem;
- }
-
- span {
- font-size: 0.68rem;
- line-height: normal;
- padding: .1rem .7rem;
- margin: 0 -.2rem;
- }
-
- &[class*=visible] {
- border: 0.06px solid $bright-blue;
- background-color: rgba($bright-blue, 0.1);
- }
-
- &[class*=pinned] {
- border: 0.06px solid $green;
- background-color: rgba($green, 0.1);
+ &.partial {
+ filter: opacity(50%);
}
}
-
-}
-
-.visible {
- @include button;
}
-
-.partial {
- filter: opacity(50%);
-}
-
-div.loadingOverlay {
- background: none;
- z-index: 10;
- [class*=spinner] {
- height: 1rem;
- width: 1rem;
- &::after {
- background: none;
- }
- }
-}
\ No newline at end of file
diff --git a/src/SubjectControls/_mixins.scss b/src/SubjectControls/_mixins.scss
new file mode 100644
index 000000000..e0ea85a1b
--- /dev/null
+++ b/src/SubjectControls/_mixins.scss
@@ -0,0 +1,61 @@
+@mixin buttonBackground($image: 'tracks_off') {
+ $background_image_url: '../common/images/icons/';
+ background: url('#{$background_image_url+$image}.svg');
+ background-size: cover;
+}
+
+@mixin control {
+ align-items: center;
+ display: flex;
+ flex-flow: row;
+ position: relative;
+
+ &.hasLabel {
+ background-color: rgba($secondary-light-gray, .25);
+ border: 0.06rem solid $secondary-medium-light-gray;
+ border-radius: .12rem;
+ max-width: 5.75rem;
+ max-height: 1.85rem;
+ border-radius: 0.2rem;
+ cursor: pointer;
+
+ [class*=spinner] {
+ position: relative;
+ top: -16%;
+ }
+
+ button {
+ min-height: 1.80rem;
+ height: 1.80rem;
+ min-width: 1.80rem;
+ width: 1.80rem;
+ }
+
+ span {
+ font-size: 0.68rem;
+ line-height: normal;
+ padding: .1rem .7rem;
+ margin: 0 -.2rem;
+ }
+
+ }
+
+ .button {
+ @include buttonBackground();
+ background-color: $subject-control-btn-bg;
+ border: none;
+ display: block;
+ filter: saturate(50%) grayscale(100%);
+ height: $square-button-dimension;
+ outline: none;
+ width: $square-button-dimension;
+
+ &:focus {
+ outline: none;
+ }
+
+ &.visible {
+ filter: unset;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/SubjectControls/button.js b/src/SubjectControls/button.js
new file mode 100644
index 000000000..3e70245af
--- /dev/null
+++ b/src/SubjectControls/button.js
@@ -0,0 +1,33 @@
+import React, { forwardRef, memo } from 'react';
+import noop from 'lodash/noop';
+import PropTypes from 'prop-types';
+import LoadingOverlay from '../LoadingOverlay';
+import styles from './styles.module.scss';
+
+const SubjectControlButton = (props, ref) => {
+ const { buttonClassName = '', containerClassName = '', disabled = false, labelText, onClick, showLabel, loading, ...rest } = props;
+
+ return
+ {loading && }
+
+ {showLabel && labelText && {labelText}}
+
;
+};
+
+export default memo(forwardRef(SubjectControlButton));
+
+SubjectControlButton.defaultProps = {
+ onClick: noop,
+ showLabel: true,
+ loading: false,
+};
+
+SubjectControlButton.propTypes = {
+ buttonClassName: PropTypes.string,
+ containerClassName: PropTypes.string,
+ disabled: PropTypes.bool,
+ labelText: PropTypes.string,
+ onClick: PropTypes.func.isRequired,
+ showLabel: PropTypes.bool,
+ loading: PropTypes.bool,
+};
\ No newline at end of file
diff --git a/src/SubjectControls/index.js b/src/SubjectControls/index.js
index ab2c51408..acb628b05 100644
--- a/src/SubjectControls/index.js
+++ b/src/SubjectControls/index.js
@@ -1,8 +1,9 @@
-import React, { memo, useState } from 'react';
+import React, { lazy, memo, useCallback, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { usePermissions } from '../hooks';
+import { addModal } from '../ducks/modals';
import { PERMISSION_KEYS, PERMISSIONS } from '../constants';
@@ -11,24 +12,32 @@ import { addHeatmapSubjects, removeHeatmapSubjects, toggleTrackState } from '../
import TrackToggleButton from '../TrackToggleButton';
import HeatmapToggleButton from '../HeatmapToggleButton';
import SubjectMessagesPopover from '../SubjectMessagesPopover';
+import SubjectHistoryButton from '../SubjectHistoryButton';
import LocationJumpButton from '../LocationJumpButton';
import { trackEventFactory, MAP_LAYERS_CATEGORY } from '../utils/analytics';
+import { subjectIsStatic } from '../utils/subjects';
+
+
import { getSubjectControlState } from './selectors';
import { fetchTracksIfNecessary } from '../utils/tracks';
import styles from './styles.module.scss';
+const SubjectHistoricalDataModal = lazy(() => import('../SubjectHistoricalDataModal'));
+
const mapLayerTracker = trackEventFactory(MAP_LAYERS_CATEGORY);
const SubjectControls = (props) => {
const { subject,
+ addModal,
children,
showHeatmapButton,
showTrackButton,
showJumpButton,
showMessageButton,
+ showHistoryButton,
showTitles,
showLabels,
className,
@@ -49,8 +58,11 @@ const SubjectControls = (props) => {
const isMessageable = !!canViewMessages && !!showMessageButton && !!subject?.messaging?.length;
+ const hasAdditionalDeviceProps = !!subject?.device_status_properties?.length;
const canShowTrack = canShowTrackForSubject(subject);
+ const canShowHistoryButton = showHistoryButton && (subjectIsStatic(subject) ? !!hasAdditionalDeviceProps : true);
+
const fetchSubjectTracks = () => {
if (tracksLoaded) return new Promise(resolve => resolve());
return fetchTracksIfNecessary([id]);
@@ -89,6 +101,10 @@ const SubjectControls = (props) => {
}
};
+ const onHistoricalDataClick = useCallback(() => {
+ addModal({ content: SubjectHistoricalDataModal, subjectId: subject.id, subjectIsStatic: subjectIsStatic(subject), title: `Historical Data: ${subject.name}` });
+ }, [addModal, subject]);
+
if (!showHeatmapButton && !showTrackButton && !showJumpButton) return null;
return
{
heatmapVisible={subjectIsInHeatmap}
/>}
+ {canShowHistoryButton &&
}
+
{showJumpButton && coordinates &&
getSubjectControlState(state, props);
-export default connect(mapStateToProps, { toggleTrackState, addHeatmapSubjects, removeHeatmapSubjects })(memo(SubjectControls));
+export default connect(mapStateToProps, { addModal, toggleTrackState, addHeatmapSubjects, removeHeatmapSubjects })(memo(SubjectControls));
diff --git a/src/SubjectControls/index.test.js b/src/SubjectControls/index.test.js
new file mode 100644
index 000000000..01ed9fe16
--- /dev/null
+++ b/src/SubjectControls/index.test.js
@@ -0,0 +1,24 @@
+import React from 'react';
+import { render, screen, userEvent, waitFor } from '@testing-library/react';
+
+import SubjectControls from './';
+
+test('rendering without crashing', () => {
+ render();
+});
+
+describe('the track button', () => {
+
+});
+
+describe('the heatmap button', () => {
+
+});
+
+describe('the "jump to location" button', () => {
+
+});
+
+describe('the "historical data" button', () => {
+
+});
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index b9db19ae6..ea1ba4889 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -1,4 +1,5 @@
@import '../common/styles/layout';
+@import '../common/styles/vars/colors';
.controls {
display: flex;
@@ -19,4 +20,4 @@
stroke: black;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/SubjectGroupList/SubjectListItem.js b/src/SubjectGroupList/SubjectListItem.js
index f1e79ce8d..3809411f9 100644
--- a/src/SubjectGroupList/SubjectListItem.js
+++ b/src/SubjectGroupList/SubjectListItem.js
@@ -19,7 +19,7 @@ const SubjectListItem = (props) => {
{subject.name}
{!isEmpty(defaultProperty) && {`${defaultProperty.label}: ${defaultProperty.value} ${defaultProperty.units}`}}
-
+
;
};
diff --git a/src/SubjectHistoricalDataModal/index.js b/src/SubjectHistoricalDataModal/index.js
index 516a70d7c..ffc5ba444 100644
--- a/src/SubjectHistoricalDataModal/index.js
+++ b/src/SubjectHistoricalDataModal/index.js
@@ -10,7 +10,13 @@ import startCase from 'lodash/startCase';
import { fetchObservationsForSubject } from '../ducks/observations';
import { removeModal } from '../ducks/modals';
+
+import { calcGpsDisplayString } from '../utils/location';
+
+/* calcGpsDisplayString(lat, lng, currentFormat) */
+
import LoadingOverlay from '../LoadingOverlay';
+import TextCopyBtn from '../TextCopyBtn';
import DateTime from '../DateTime';
import styles from './styles.module.scss';
@@ -26,7 +32,7 @@ export const getObservationUniqProperties = (observations) => {
return uniqPropertiesByLabel.map(property => property.label);
};
-const SubjectHistoricalDataModal = ({ title, subjectId, fetchObservationsForSubject }) => {
+const SubjectHistoricalDataModal = ({ gpsFormat, title, subjectId, subjectIsStatic, fetchObservationsForSubject }) => {
const [loading, setLoadState] = useState(true);
const [subjectObservations, setSubjectObservations] = useState([]);
const [observationsCount, setObservationsCount] = useState(1);
@@ -44,10 +50,6 @@ const SubjectHistoricalDataModal = ({ title, subjectId, fetchObservationsForSubj
});
}, [fetchObservationsForSubject, subjectId]);
- useEffect(() => {
- if (activePage === 1) fetchObservations();
- }, [activePage, fetchObservations]);
-
useEffect(() => {
fetchObservations(activePage);
}, [activePage, fetchObservations]);
@@ -75,15 +77,20 @@ const SubjectHistoricalDataModal = ({ title, subjectId, fetchObservationsForSubj
Date |
{observationProperties.map(property => {startCase(property)} | )}
+ {!subjectIsStatic && Location | }
- {subjectObservations.map(({ id, recorded_at, device_status_properties }) =>
-
+ {subjectObservations.map(({ id, recorded_at, location, device_status_properties }) => {
+ const locationString = !subjectIsStatic && calcGpsDisplayString(location.latitude, location.longitude, gpsFormat);
+
+ return
|
{observationProperties.map(property => {getMatchedProperty(property, device_status_properties)} | )}
-
- )}
+ {!!locationString && {locationString}
+ | }
+ ;
+ })}
{observationsCount > ITEMS_PER_PAGE && ({ gpsFormat });
-export default connect(null, { fetchObservationsForSubject, removeModal })(memo(SubjectHistoricalDataModal));
\ No newline at end of file
+export default connect(mapStateToProps, { fetchObservationsForSubject, removeModal })(memo(SubjectHistoricalDataModal));
\ No newline at end of file
diff --git a/src/SubjectHistoricalDataModal/index.test.js b/src/SubjectHistoricalDataModal/index.test.js
index 40f05f313..873fbb2c0 100644
--- a/src/SubjectHistoricalDataModal/index.test.js
+++ b/src/SubjectHistoricalDataModal/index.test.js
@@ -7,6 +7,7 @@ import userEvent from '@testing-library/user-event';
import { fetchObservationsForSubject } from '../ducks/observations';
import { mockStore } from '../__test-helpers/MockStore';
+import { GPS_FORMATS } from '../utils/location';
import mockedObservationsData from '../__test-helpers/fixtures/observations';
import SubjectHistoricalDataModal, { ITEMS_PER_PAGE, getObservationUniqProperties } from './';
@@ -16,7 +17,7 @@ jest.mock('../ducks/observations', () => ({
fetchObservationsForSubject: jest.fn(),
}));
-const store = mockStore({ data: {}, view: {} });
+const store = mockStore({ data: {}, view: { userPreferences: { gpsFormat: GPS_FORMATS.DEG } } });
describe('SubjectHistoricalDataModal', () => {
let fetchObservationsForSubjectMock;
diff --git a/src/SubjectHistoryButton/PatrolAwareTrackToggleButton.js b/src/SubjectHistoryButton/PatrolAwareTrackToggleButton.js
new file mode 100644
index 000000000..ef1176f16
--- /dev/null
+++ b/src/SubjectHistoryButton/PatrolAwareTrackToggleButton.js
@@ -0,0 +1,69 @@
+import React, { memo, useCallback, useMemo } from 'react';
+import { connect } from 'react-redux';
+import isEqual from 'react-fast-compare';
+
+import { togglePatrolTrackState } from '../ducks/patrols';
+import { toggleTrackState } from '../ducks/map-ui';
+
+import { trackEventFactory, PATROL_LIST_ITEM_CATEGORY } from '../utils/analytics';
+
+import TrackToggleButton from './';
+
+const patrolListItemTracker = trackEventFactory(PATROL_LIST_ITEM_CATEGORY);
+
+const PatrolAwareTrackToggleButton = ({ buttonRef, dispatch: _dispatch, patrolData, patrolTrackState, subjectTrackState, togglePatrolTrackState, toggleTrackState, ...rest }) => {
+ const { patrol, leader } = patrolData;
+
+ const patrolTrackPinned = useMemo(() => patrolTrackState.pinned.includes(patrol.id), [patrol.id, patrolTrackState.pinned]);
+ const patrolTrackVisible = useMemo(() => !patrolTrackPinned && patrolTrackState.visible.includes(patrol.id), [patrol.id, patrolTrackPinned, patrolTrackState.visible]);
+ const patrolTrackHidden = useMemo(() => !patrolTrackPinned && !patrolTrackVisible, [patrolTrackPinned, patrolTrackVisible]);
+
+ const subjectTrackPinned = useMemo(() => !!leader && subjectTrackState.pinned.includes(leader.id), [leader, subjectTrackState.pinned]);
+ const subjectTrackVisible = useMemo(() => !!leader && !subjectTrackPinned && subjectTrackState.visible.includes(leader.id), [leader, subjectTrackPinned, subjectTrackState.visible]);
+ const subjectTrackHidden = useMemo(() => !subjectTrackPinned && !subjectTrackVisible, [subjectTrackPinned, subjectTrackVisible]);
+ // trackVisible={patrolTrackVisible} trackPinned={patrolTrackPinned} onClick={onTrackButtonClick}
+
+ const patrolToggleStates = useMemo(() => [patrolTrackPinned, patrolTrackVisible, patrolTrackHidden], [patrolTrackHidden, patrolTrackPinned, patrolTrackVisible]);
+ const subjectToggleStates = useMemo(() => [subjectTrackPinned, subjectTrackVisible, subjectTrackHidden], [subjectTrackHidden, subjectTrackPinned, subjectTrackVisible]);
+
+ const onTrackButtonClick = useCallback(() => {
+ const nextPatrolTrackStateIfToggled = patrolTrackPinned
+ ? 'hidden'
+ : patrolTrackHidden
+ ? 'visible'
+ : 'pinned';
+
+ if (!leader) return;
+ const actionToTrack = `Toggle patrol track state to ${nextPatrolTrackStateIfToggled} from patrol card popover`;
+
+ if (isEqual(patrolToggleStates, subjectToggleStates)) {
+ toggleTrackState(leader.id);
+ togglePatrolTrackState(patrol.id);
+ patrolListItemTracker.track(actionToTrack);
+ return;
+ }
+ if (!patrolTrackHidden && subjectTrackHidden) {
+ togglePatrolTrackState(patrol.id);
+ patrolListItemTracker.track(actionToTrack);
+ return;
+ }
+ if (subjectTrackPinned && patrolTrackVisible) {
+ togglePatrolTrackState(patrol.id);
+ patrolListItemTracker.track(actionToTrack);
+ }
+ if (patrolTrackPinned && subjectTrackVisible) {
+ toggleTrackState(leader.id);
+ }
+ if (patrolTrackHidden && !subjectTrackHidden) {
+ toggleTrackState(leader.id);
+ return;
+ }
+ }, [leader, patrol.id, patrolToggleStates, patrolTrackHidden, patrolTrackPinned, patrolTrackVisible, subjectToggleStates, subjectTrackHidden, subjectTrackPinned, subjectTrackVisible, togglePatrolTrackState, toggleTrackState]);
+
+ return ;
+};
+
+
+const mapStateToProps = ({ view: { patrolTrackState, subjectTrackState } }) => ({ patrolTrackState, subjectTrackState });
+
+export default connect(mapStateToProps, { togglePatrolTrackState, toggleTrackState })(memo(PatrolAwareTrackToggleButton));
\ No newline at end of file
diff --git a/src/SubjectHistoryButton/index.js b/src/SubjectHistoryButton/index.js
new file mode 100644
index 000000000..9caad1385
--- /dev/null
+++ b/src/SubjectHistoryButton/index.js
@@ -0,0 +1,29 @@
+import React, { forwardRef, memo } from 'react';
+import noop from 'lodash/noop';
+import PropTypes from 'prop-types';
+import styles from './styles.module.scss';
+
+const SubjectHistoryButton = (props, ref) => {
+ const { className: externalClassName, disabled, onClick, showLabel, ...rest } = props;
+
+
+ return
+
+ {showLabel && Historical Data}
+
;
+};
+
+export default memo(forwardRef(SubjectHistoryButton));
+
+SubjectHistoryButton.defaultProps = {
+ onClick: noop,
+ showLabel: true,
+};
+
+SubjectHistoryButton.propTypes = {
+ trackVisible: PropTypes.bool.isRequired,
+ trackPinned: PropTypes.bool.isRequired,
+ onClick: PropTypes.func,
+ showLabel: PropTypes.bool,
+ loading: PropTypes.bool,
+};
\ No newline at end of file
diff --git a/src/SubjectHistoryButton/index.test.js b/src/SubjectHistoryButton/index.test.js
new file mode 100644
index 000000000..7958da5e8
--- /dev/null
+++ b/src/SubjectHistoryButton/index.test.js
@@ -0,0 +1,32 @@
+import React from 'react';
+import { render, screen, userEvent, waitFor } from '@testing-library/react';
+
+import SubjectHistoryButton from './';
+
+const onClick = jest.fn();
+
+test('rendering without crashing', () => {
+ render();
+});
+
+test('call onClick', () => {
+ render();
+ waitFor(async () => {
+ const toggleButton = await screen.getByRole('button');
+ userEvent.click(toggleButton);
+ expect(onClick).toHaveBeenCalled();
+ });
+});
+
+describe('show different titles depending on showLabel prop', () => {
+ test('show the label showLabel is true', () => {
+ render();
+ expect(screen.getByText('Historical Data')).toBeTruthy();
+ });
+
+
+ test('Do not show any label if showLabel is false', () => {
+ render();
+ expect(() => screen.getByText('Historical Data')).toThrow();
+ });
+});
\ No newline at end of file
diff --git a/src/SubjectHistoryButton/styles.module.scss b/src/SubjectHistoryButton/styles.module.scss
new file mode 100644
index 000000000..29b51f833
--- /dev/null
+++ b/src/SubjectHistoryButton/styles.module.scss
@@ -0,0 +1,61 @@
+@import '../common/styles/buttons';
+@import '../common/styles/vars/colors';
+
+$background_image_url: '../common/images/icons/';
+
+@mixin button($image: 'tracks_off') {
+ background: url('#{$background-image_url+$image}.svg');
+ background-size: 85%;
+ background-position: 0.15rem 0.1rem;
+ background-repeat: no-repeat;
+ border: none;
+ display: block;
+ height: $square-button-dimension;
+ outline: none;
+ width: $square-button-dimension;
+
+ &:focus {
+ outline: none;
+ }
+}
+
+.button {
+ @include button('historical-data');
+ margin-top: 0.25rem;
+}
+
+.container {
+ display: flex;
+ align-items: center;
+ flex-flow: row;
+ position: relative;
+
+ &.hasLabel {
+ background-color: $subject-control-btn-bg;
+ border: 0.06px solid $secondary-medium-light-gray;
+ max-width: 5.75rem;
+ max-height: 1.85rem;
+ border-radius: 0.25rem;
+ cursor: pointer;
+
+ [class*=spinner] {
+ position: relative;
+ top: -16%;
+ }
+
+ button {
+ min-height: 1.80rem;
+ height: 1.80rem;
+ min-width: 1.80rem;
+ width: 1.80rem;
+ }
+
+ span {
+ font-size: 0.68rem;
+ line-height: normal;
+ padding: .1rem .7rem;
+ margin: 0 -.2rem;
+ }
+ }
+
+}
diff --git a/src/SubjectPopup/index.js b/src/SubjectPopup/index.js
index 2b792b5bd..cfc1d8ed5 100644
--- a/src/SubjectPopup/index.js
+++ b/src/SubjectPopup/index.js
@@ -1,4 +1,4 @@
-import React, { lazy, memo, Fragment, useCallback, useMemo, useState } from 'react';
+import React, { memo, Fragment, useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import format from 'date-fns/format';
@@ -12,7 +12,6 @@ import SubjectControls from '../SubjectControls';
import { ReactComponent as ChatIcon } from '../common/images/icons/chat-icon.svg';
import AddReport from '../AddReport';
-import { addModal } from '../ducks/modals';
import { showPopup } from '../ducks/popup';
import { DEVELOPMENT_FEATURE_FLAGS } from '../constants';
@@ -24,11 +23,9 @@ import styles from './styles.module.scss';
const { ENABLE_UFA_NAVIGATION_UI } = DEVELOPMENT_FEATURE_FLAGS;
-const SubjectHistoricalDataModal = lazy(() => import('../SubjectHistoricalDataModal'));
-
const STORAGE_KEY = 'showSubjectDetailsByDefault';
-const SubjectPopup = ({ data, popoverPlacement, timeSliderState, addModal, showPopup }) => {
+const SubjectPopup = ({ data, popoverPlacement, timeSliderState, showPopup }) => {
const { geometry, properties } = data;
const { active: isTimeSliderActive } = timeSliderState;
@@ -40,8 +37,10 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, addModal, showP
const { tracks_available } = properties;
const coordProps = typeof properties.coordinateProperties === 'string' ? JSON.parse(properties.coordinateProperties) : properties.coordinateProperties;
+ const isStatic = subjectIsStatic(data);
+
const hasAdditionalDeviceProps = !!device_status_properties?.length;
- const additionalPropsShouldBeToggleable = hasAdditionalDeviceProps && device_status_properties.length > 2 && !subjectIsStatic(data);
+ const additionalPropsShouldBeToggleable = hasAdditionalDeviceProps && device_status_properties.length > 2 && !isStatic;
const [additionalPropsToggledOn, toggleAdditionalPropsVisibility] = useState(window.localStorage.getItem(STORAGE_KEY) === 'true' ? true : false);
const showAdditionalProps = hasAdditionalDeviceProps &&
@@ -62,10 +61,6 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, addModal, showP
showPopup('subject-messages', { geometry, properties: properties, coordinates: geometry.coordinates });
}, [geometry, properties, showPopup]);
- const onHistoricalDataClick = useCallback(() => {
- addModal({ title: 'Historical Data', content: SubjectHistoricalDataModal, subjectId: properties.id });
- }, [addModal, properties]);
-
const locationObject = {
longitude: geometry.coordinates[0],
latitude: geometry.coordinates[1],
@@ -79,7 +74,7 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, addModal, showP
{properties.default_status_value && <>
{properties.image &&
}
-
{!isTimeSliderActive ? properties.default_status_value : 'No historical data'}
+
{properties.default_status_value}
>}
{properties.name}
@@ -111,33 +106,32 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, addModal, showP
}
{tracks_available && }
- {hasAdditionalDeviceProps && showAdditionalProps &&
-
+
;
};
diff --git a/src/SubjectHistoricalDataModal/index.js b/src/SubjectHistoricalDataModal/index.js
index ffc5ba444..4a6e74a74 100644
--- a/src/SubjectHistoricalDataModal/index.js
+++ b/src/SubjectHistoricalDataModal/index.js
@@ -16,7 +16,6 @@ import { calcGpsDisplayString } from '../utils/location';
/* calcGpsDisplayString(lat, lng, currentFormat) */
import LoadingOverlay from '../LoadingOverlay';
-import TextCopyBtn from '../TextCopyBtn';
import DateTime from '../DateTime';
import styles from './styles.module.scss';
@@ -87,7 +86,7 @@ const SubjectHistoricalDataModal = ({ gpsFormat, title, subjectId, subjectIsStat
return
|
{observationProperties.map(property => {getMatchedProperty(property, device_status_properties)} | )}
- {!!locationString && {locationString}
+ {!!locationString && | {locationString}
| }
;
})}
diff --git a/src/SubjectMessagesPopover/index.js b/src/SubjectMessagesPopover/index.js
index 9c0ed4aa1..8229b395c 100644
--- a/src/SubjectMessagesPopover/index.js
+++ b/src/SubjectMessagesPopover/index.js
@@ -1,6 +1,7 @@
import React, { memo, useMemo } from 'react';
import Popover from 'react-bootstrap/Popover';
import OverlayTrigger from 'react-bootstrap/OverlayTrigger';
+import SubjectControlButton from '../SubjectControls/button';
import { usePermissions } from '../hooks';
import { PERMISSION_KEYS, PERMISSIONS } from '../constants';
@@ -14,10 +15,12 @@ import { ReactComponent as ChatIcon } from '../common/images/icons/chat-icon.svg
import styles from './styles.module.scss';
const SubjectMessagesPopover = (props) => {
- const { className = '', subject } = props;
+ const { className = '', subject, ...rest } = props;
const hasMessagingWritePermissions = usePermissions(PERMISSION_KEYS.MESSAGING, PERMISSIONS.CREATE);
+ const buttonClassName = `${className} ${styles.button}`;
+
const params = useMemo(() => {
return { subject_id: subject?.id };
}, [subject]);
@@ -29,15 +32,15 @@ const SubjectMessagesPopover = (props) => {
{subject.name}
-
+
{!!hasMessagingWritePermissions && }
;
return
-
+
+
+
;
};
diff --git a/src/SubjectMessagesPopover/styles.module.scss b/src/SubjectMessagesPopover/styles.module.scss
index 60b11bad3..eca960d51 100644
--- a/src/SubjectMessagesPopover/styles.module.scss
+++ b/src/SubjectMessagesPopover/styles.module.scss
@@ -1,3 +1,5 @@
+@import '../SubjectControls/mixins';
+
.popover {
height: 22rem;
max-width: unset;
@@ -6,4 +8,12 @@
[class*=popover-body] {
height: 15.5rem;
}
+}
+
+.container {
+ @include control;
+}
+
+.button {
+ @include buttonBackground('chat-icon');
}
\ No newline at end of file
diff --git a/src/TrackToggleButton/styles.module.scss b/src/TrackToggleButton/styles.module.scss
index 9b24548cd..2493aabda 100644
--- a/src/TrackToggleButton/styles.module.scss
+++ b/src/TrackToggleButton/styles.module.scss
@@ -16,9 +16,12 @@
.button {
@include buttonBackground('tracks_off');
- &.visible, &.pinned {
+ &.visible {
@include buttonBackground('tracks_on');
}
+ &.pinned {
+ @include buttonBackground('tracks_pinned');
+ }
}
div.loadingOverlay {
From 722ce0dfed925ff32ea380647d6e8325e95f5de1 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Wed, 4 May 2022 15:44:51 -0700
Subject: [PATCH 03/18] better layout, wrapping, and label plumbing
---
src/SubjectControls/_mixins.scss | 1 +
src/SubjectControls/index.js | 10 +++--
src/SubjectControls/styles.module.scss | 2 +
src/SubjectMessagesPopover/index.js | 4 +-
src/SubjectMessagesPopover/styles.module.scss | 7 ++-
src/SubjectPopup/index.js | 2 +-
src/SubjectPopup/styles.module.scss | 44 +++----------------
7 files changed, 19 insertions(+), 51 deletions(-)
diff --git a/src/SubjectControls/_mixins.scss b/src/SubjectControls/_mixins.scss
index eca566693..5e47be1c0 100644
--- a/src/SubjectControls/_mixins.scss
+++ b/src/SubjectControls/_mixins.scss
@@ -10,6 +10,7 @@
@mixin control {
align-items: center;
+ cursor: pointer;
display: flex;
flex-flow: row;
position: relative;
diff --git a/src/SubjectControls/index.js b/src/SubjectControls/index.js
index 0dbf1d6bc..5d5b6a8aa 100644
--- a/src/SubjectControls/index.js
+++ b/src/SubjectControls/index.js
@@ -111,10 +111,6 @@ const SubjectControls = (props) => {
return
- {isMessageable &&
}
{showTrackButton && canShowTrack &&
{
heatmapVisible={subjectIsInHeatmap}
/>}
+ {isMessageable && }
+
{canShowHistoryButton && }
{showJumpButton && coordinates && {
;
return
-
-
-
+
;
};
diff --git a/src/SubjectMessagesPopover/styles.module.scss b/src/SubjectMessagesPopover/styles.module.scss
index eca960d51..a09e96d83 100644
--- a/src/SubjectMessagesPopover/styles.module.scss
+++ b/src/SubjectMessagesPopover/styles.module.scss
@@ -12,8 +12,7 @@
.container {
@include control;
+ .button {
+ @include buttonBackground('chat-icon');
+ }
}
-
-.button {
- @include buttonBackground('chat-icon');
-}
\ No newline at end of file
diff --git a/src/SubjectPopup/index.js b/src/SubjectPopup/index.js
index f01196d4c..8c81e11a4 100644
--- a/src/SubjectPopup/index.js
+++ b/src/SubjectPopup/index.js
@@ -119,7 +119,7 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, showPopup }) =>
{additionalPropsShouldBeToggleable && }
>}
-
+
>;
};
diff --git a/src/SubjectPopup/styles.module.scss b/src/SubjectPopup/styles.module.scss
index dc8e2bc31..ed4ca77dc 100644
--- a/src/SubjectPopup/styles.module.scss
+++ b/src/SubjectPopup/styles.module.scss
@@ -177,46 +177,12 @@ $background_image_url: '../common/images/icons/';
}
}
-.trackControls {
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
-}
-
.controls {
- display: flex;
-
- .messageButton {
- align-items: center;
- display: flex;
- flex-flow: row;
- position: relative;
- background-color: rgba($secondary-light-gray, 0.25);
- border: 0.06rem solid $secondary-medium-light-gray;
- border-radius: 0.2rem;
- cursor: pointer;
- margin-top: 0.31rem;
-
- button {
- height: 1.8rem;
- width: 1.8rem;
- background: url('#{$background-image_url}chat-icon.svg');
- background-size: cover;
- border: none;
- display: block;
- outline: none;
-
- &:focus {
- outline: none;
- }
- }
-
- span {
- font-size: 0.68rem;
- line-height: normal;
- padding: .1rem .7rem;
- margin: 0 -.2rem;
- }
+ flex-wrap: wrap;
+ > * {
+ flex: 1;
+ width: 49%;
+ margin: 0 0.25rem 0.25rem;
}
}
From 1e2e2577f8d7ae8fc43fa4e1cdc95d1c7272d9fa Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 5 May 2022 10:23:23 -0700
Subject: [PATCH 04/18] styling
---
src/HeatmapToggleButton/styles.module.scss | 1 -
src/SubjectControls/_mixins.scss | 36 ++--------------
src/SubjectControls/styles.module.scss | 42 +++++++++++++++----
src/SubjectMessagesPopover/styles.module.scss | 1 -
src/SubjectPopup/styles.module.scss | 2 +-
src/TrackToggleButton/styles.module.scss | 32 +++++++-------
6 files changed, 53 insertions(+), 61 deletions(-)
diff --git a/src/HeatmapToggleButton/styles.module.scss b/src/HeatmapToggleButton/styles.module.scss
index df4354d5f..c2ee9177b 100644
--- a/src/HeatmapToggleButton/styles.module.scss
+++ b/src/HeatmapToggleButton/styles.module.scss
@@ -2,7 +2,6 @@
@import '../SubjectControls/mixins';
.container {
- @include control;
.button {
@include buttonBackground('heatmap');
filter: saturate(50%) grayscale(100%);
diff --git a/src/SubjectControls/_mixins.scss b/src/SubjectControls/_mixins.scss
index 5e47be1c0..4dd43a643 100644
--- a/src/SubjectControls/_mixins.scss
+++ b/src/SubjectControls/_mixins.scss
@@ -4,49 +4,21 @@
@mixin buttonBackground($image: 'tracks_off') {
$background_image_url: '../common/images/icons/';
- background: url('#{$background_image_url+$image}.svg');
- background-size: cover;
+ background-image: url('#{$background_image_url+$image}.svg');
}
@mixin control {
align-items: center;
+ background-size: cover;
cursor: pointer;
display: flex;
flex-flow: row;
+ line-height: normal;
position: relative;
-
- &.hasLabel {
- background-color: rgba($secondary-light-gray, .25);
- border: 0.06rem solid $secondary-medium-light-gray;
- border-radius: .12rem;
- max-width: 5.75rem;
- max-height: 1.85rem;
- border-radius: 0.2rem;
- cursor: pointer;
-
- [class*=spinner] {
- position: relative;
- top: -16%;
- }
-
- button {
- min-height: 1.80rem;
- height: 1.80rem;
- min-width: 1.80rem;
- width: 1.80rem;
- }
-
- span {
- font-size: 0.68rem;
- line-height: normal;
- padding: .1rem .7rem;
- margin: 0 -.2rem;
- }
-
- }
.button {
@include buttonBackground();
+ background-size: cover;
background-color: $subject-control-btn-bg;
border: none;
display: block;
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index 90a5fe2aa..3b705f228 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -1,8 +1,11 @@
+@import '../common/styles/vars/colors';
+@import './mixins';
+
.controls {
align-items: center;
display: flex;
- justify-content: space-around;
+ justify-content: flex-start;
&.noTitles {
span {
display: none;
@@ -11,20 +14,41 @@
}
.container {
- height: 2.25rem;
position: relative;
+ @include control;
}
.loadingOverlay {
z-index: 1000;
}
-.messagingButton {
- border: none;
- padding: 0rem;
- svg {
- height: 2.2rem;
- width: 2.2rem;
+.hasLabel {
+ background-color: rgba($secondary-light-gray, .25);
+ border: 0.06rem solid $secondary-medium-light-gray;
+ border-radius: .12rem;
+ max-width: 5.75rem;
+ max-height: 1.85rem;
+ border-radius: 0.2rem;
+ cursor: pointer;
+
+ [class*=spinner] {
+ position: relative;
+ top: -16%;
}
-}
+
+ .button {
+ min-height: 1.80rem;
+ height: 1.80rem;
+ min-width: 1.80rem;
+ width: 1.80rem;
+ }
+
+ span {
+ font-size: 0.68rem;
+ line-height: normal;
+ padding: .1rem .7rem;
+ margin: 0 -.2rem;
+ }
+
+}
\ No newline at end of file
diff --git a/src/SubjectMessagesPopover/styles.module.scss b/src/SubjectMessagesPopover/styles.module.scss
index a09e96d83..2ebcd0ca4 100644
--- a/src/SubjectMessagesPopover/styles.module.scss
+++ b/src/SubjectMessagesPopover/styles.module.scss
@@ -11,7 +11,6 @@
}
.container {
- @include control;
.button {
@include buttonBackground('chat-icon');
}
diff --git a/src/SubjectPopup/styles.module.scss b/src/SubjectPopup/styles.module.scss
index ed4ca77dc..b8bd39f6f 100644
--- a/src/SubjectPopup/styles.module.scss
+++ b/src/SubjectPopup/styles.module.scss
@@ -181,7 +181,7 @@ $background_image_url: '../common/images/icons/';
flex-wrap: wrap;
> * {
flex: 1;
- width: 49%;
+ width: 45%;
margin: 0 0.25rem 0.25rem;
}
}
diff --git a/src/TrackToggleButton/styles.module.scss b/src/TrackToggleButton/styles.module.scss
index 2493aabda..effdd6226 100644
--- a/src/TrackToggleButton/styles.module.scss
+++ b/src/TrackToggleButton/styles.module.scss
@@ -2,25 +2,23 @@
@import '../SubjectControls/mixins';
.container {
- @include control;
- &[class*=visible] {
- border: 0.06px solid $bright-blue;
- background-color: rgba($bright-blue, 0.1);
- }
-
- &[class*=pinned] {
- border: 0.06px solid $green;
- background-color: rgba($green, 0.1);
- }
+ &[class*=visible] {
+ border: 0.06px solid $bright-blue;
+ background-color: rgba($bright-blue, 0.1);
}
-
-.button {
- @include buttonBackground('tracks_off');
- &.visible {
- @include buttonBackground('tracks_on');
+
+ &[class*=pinned] {
+ border: 0.06px solid $green;
+ background-color: rgba($green, 0.1);
}
- &.pinned {
- @include buttonBackground('tracks_pinned');
+ .button {
+ @include buttonBackground('tracks_off');
+ &.visible {
+ @include buttonBackground('tracks_on');
+ }
+ &.pinned {
+ @include buttonBackground('tracks_pinned');
+ }
}
}
From 6d760f71b5e66ca8aa34eb3d0102fbac81c55277 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 09:08:35 -0700
Subject: [PATCH 05/18] not showing historical data controls in map layer list
items. fixing interval issues with 'pingSocket'
---
src/SubjectControls/index.test.js | 53 +++++++++++++++++--------
src/SubjectGroupList/SubjectListItem.js | 4 +-
src/socket/index.js | 28 ++++++++-----
3 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/src/SubjectControls/index.test.js b/src/SubjectControls/index.test.js
index 01ed9fe16..f5648e33b 100644
--- a/src/SubjectControls/index.test.js
+++ b/src/SubjectControls/index.test.js
@@ -1,24 +1,45 @@
import React from 'react';
import { render, screen, userEvent, waitFor } from '@testing-library/react';
-import SubjectControls from './';
-
-test('rendering without crashing', () => {
- render();
-});
-
-describe('the track button', () => {
+import mockSubjectData from '../__test-helpers/fixtures/subjects';
-});
+import { Provider } from 'react-redux';
+import { mockStore } from '../__test-helpers/MockStore';
-describe('the heatmap button', () => {
-
-});
-
-describe('the "jump to location" button', () => {
+import SubjectControls from './';
-});
-describe('the "historical data" button', () => {
-});
+describe('SubjectControls', () => {
+ let store;
+ const [subject] = mockSubjectData;
+ const { properties } = subject;
+
+ beforeEach(() => {
+ store = mockStore({
+ data: {
+ tracks: {},
+ },
+ view: {
+ subjectTrackState: { pinned: [], visible: [] },
+ heatmapSubjectIDs: [],
+ },
+ });
+ });
+
+ test('rendering without crashing', () => {
+ render(
+
+
+ );
+ });
+
+ test('showing the historical data button', () => {
+ render(
+
+
+
+ );
+
+ });
+});
\ No newline at end of file
diff --git a/src/SubjectGroupList/SubjectListItem.js b/src/SubjectGroupList/SubjectListItem.js
index 2552049cb..f1e79ce8d 100644
--- a/src/SubjectGroupList/SubjectListItem.js
+++ b/src/SubjectGroupList/SubjectListItem.js
@@ -9,8 +9,6 @@ import listStyles from '../SideBar/styles.module.scss';
const SubjectListItem = (props) => {
const { map, ...subject } = props;
- const hasAdditionalDeviceProps = !!subject?.device_status_properties?.length;
-
const subjectRadioImage = useMemo(() => isRadioWithImage(props), [props]);
const isStaticTypeObject = subjectIsStatic(subject);
const defaultProperty = getSubjectDefaultDeviceProperty(subject);
@@ -21,7 +19,7 @@ const SubjectListItem = (props) => {
{subject.name}
{!isEmpty(defaultProperty) && {`${defaultProperty.label}: ${defaultProperty.value} ${defaultProperty.units}`}}
-
+
;
};
diff --git a/src/socket/index.js b/src/socket/index.js
index e4861327e..82f53ffdf 100644
--- a/src/socket/index.js
+++ b/src/socket/index.js
@@ -47,21 +47,27 @@ const pingSocket = (socket) => {
socket.on('echo_resp', () => {
pinged = true;
});
- socket.emit('echo', { data: 'ping' });
- return window.setInterval(() => {
- if (pinged) {
- pinged = false;
- socket.emit('echo', { data: 'ping' });
- } else {
- resetSocketStateTracking();
- }
+ let interval, timeout;
+
+ interval = window.setInterval(() => {
+ socket.emit('echo', { data: 'ping' });
+
+ timeout = window.setTimeout(() => {
+ if (pinged) {
+ pinged = false;
+ } else {
+ resetSocketStateTracking();
+ }
+ }, [15000]);
}, 30000);
+
+ return [interval, timeout];
};
export const bindSocketEvents = (socket, store) => {
let eventsBound = false;
- let pingInterval;
+ let pingInterval, pingTimeout;
socket.on('connect', () => {
store.dispatch({ type: SOCKET_HEALTHY_STATUS });
@@ -82,7 +88,9 @@ export const bindSocketEvents = (socket, store) => {
}
window.clearInterval(pingInterval);
- pingInterval = pingSocket(socket);
+ window.clearTimeout(pingTimeout);
+
+ [pingInterval, pingTimeout] = pingSocket(socket);
if (!eventsBound) {
Object.entries(events).forEach(([event_name, actionTypes]) => {
From 95c32d018fe68c59f82ad88cae1727d1215bdd5c Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 10:47:44 -0700
Subject: [PATCH 06/18] fixing tests, tweaking styles
---
src/SubjectControls/index.js | 2 +-
src/SubjectControls/index.test.js | 39 +++++++++++++++++----
src/SubjectHistoryButton/styles.module.scss | 1 +
3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/src/SubjectControls/index.js b/src/SubjectControls/index.js
index 5d5b6a8aa..1a7b87e36 100644
--- a/src/SubjectControls/index.js
+++ b/src/SubjectControls/index.js
@@ -133,7 +133,7 @@ const SubjectControls = (props) => {
subject={subject}
/>}
- {canShowHistoryButton && }
+ {canShowHistoryButton && }
{showJumpButton && coordinates && {
+ const real = jest.requireActual('../ducks/modals');
+ return {
+ ...real,
+ addModal: jest.fn(),
+ };
+});
describe('SubjectControls', () => {
let store;
const [subject] = mockSubjectData;
- const { properties } = subject;
+ const buttonTestId = `history-button-${subject.id}`;
beforeEach(() => {
store = mockStore({
@@ -30,16 +40,33 @@ describe('SubjectControls', () => {
test('rendering without crashing', () => {
render(
-
+
);
});
- test('showing the historical data button', () => {
+ test('showing the historical data button', async () => {
+ render(
+
+
+
+ );
+
+ await screen.findByTestId(buttonTestId);
+
+ });
+
+ test('showing the history modal on button click', async () => {
+
render(
-
+
);
+ const button = await screen.findByTestId(buttonTestId);
+ userEvent.click(button);
+
+ expect(addModal).toHaveBeenCalled();
+
});
});
\ No newline at end of file
diff --git a/src/SubjectHistoryButton/styles.module.scss b/src/SubjectHistoryButton/styles.module.scss
index 29b51f833..290472c91 100644
--- a/src/SubjectHistoryButton/styles.module.scss
+++ b/src/SubjectHistoryButton/styles.module.scss
@@ -21,6 +21,7 @@ $background_image_url: '../common/images/icons/';
.button {
@include button('historical-data');
+ pointer-events: none;
margin-top: 0.25rem;
}
From 4b0bca1b094b8ed01b47bc0c35b206ee8684acc1 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 10:54:38 -0700
Subject: [PATCH 07/18] fixing table text
---
src/SubjectHistoricalDataModal/index.test.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/SubjectHistoricalDataModal/index.test.js b/src/SubjectHistoricalDataModal/index.test.js
index 873fbb2c0..38d79b4e8 100644
--- a/src/SubjectHistoricalDataModal/index.test.js
+++ b/src/SubjectHistoricalDataModal/index.test.js
@@ -57,7 +57,8 @@ describe('SubjectHistoricalDataModal', () => {
expect(tableHeaders[2].childNodes[0]).toHaveTextContent('Temperature');
expect(tableCells[2].childNodes[0]).toHaveTextContent('1000 c');
- expect(tableHeaders[3]).toBe(undefined);
+ expect(tableHeaders[3].childNodes[0]).toHaveTextContent('Location');
+ expect(tableCells[3].childNodes[0]).toHaveTextContent('20.701133°, -103.572941°');
});
});
describe('pagination', () => {
From 965bf477ca981db687d60a2487633463a6a6ad18 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 11:09:20 -0700
Subject: [PATCH 08/18] fixing subject control tests
---
src/SubjectControls/index.test.js | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/SubjectControls/index.test.js b/src/SubjectControls/index.test.js
index 2cab6130b..f8a391f2e 100644
--- a/src/SubjectControls/index.test.js
+++ b/src/SubjectControls/index.test.js
@@ -2,6 +2,7 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
+import { subjectIsStatic } from '../utils/subjects';
import mockSubjectData from '../__test-helpers/fixtures/subjects';
@@ -21,11 +22,13 @@ jest.mock('../ducks/modals', () => {
});
describe('SubjectControls', () => {
- let store;
+ let store, addModalMock;
const [subject] = mockSubjectData;
const buttonTestId = `history-button-${subject.id}`;
beforeEach(() => {
+ addModalMock = jest.fn(() => () => {});
+ addModal.mockImplementation(addModalMock);
store = mockStore({
data: {
tracks: {},
@@ -66,7 +69,6 @@ describe('SubjectControls', () => {
const button = await screen.findByTestId(buttonTestId);
userEvent.click(button);
- expect(addModal).toHaveBeenCalled();
-
+ expect(addModal).toHaveBeenCalledWith(expect.objectContaining({ subjectId: subject.id, subjectIsStatic: subjectIsStatic(subject), title: `Historical Data: ${subject.name}` }));
});
});
\ No newline at end of file
From f07d7eb88adf8d66b451dbe4632e5ed537941673 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 11:25:26 -0700
Subject: [PATCH 09/18] layout tweak for label overlap
---
src/SubjectControls/styles.module.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index 3b705f228..ded71be58 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -47,7 +47,7 @@
span {
font-size: 0.68rem;
line-height: normal;
- padding: .1rem .7rem;
+ padding: .1rem .3rem;
margin: 0 -.2rem;
}
From 41842116f594b840055647a1d03a3e8316060799 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 12 May 2022 11:29:25 -0700
Subject: [PATCH 10/18] test refactor for better describe block
---
src/SubjectControls/index.test.js | 38 +++++++++++++++++--------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/src/SubjectControls/index.test.js b/src/SubjectControls/index.test.js
index f8a391f2e..d58899667 100644
--- a/src/SubjectControls/index.test.js
+++ b/src/SubjectControls/index.test.js
@@ -47,28 +47,32 @@ describe('SubjectControls', () => {
);
});
- test('showing the historical data button', async () => {
- render(
-
-
-
- );
+ describe('the histrical data button', () => {
- await screen.findByTestId(buttonTestId);
- });
+ test('showing the historical data button', async () => {
+ render(
+
+
+
+ );
- test('showing the history modal on button click', async () => {
+ await screen.findByTestId(buttonTestId);
- render(
-
-
-
- );
+ });
+
+ test('showing the history modal on button click', async () => {
- const button = await screen.findByTestId(buttonTestId);
- userEvent.click(button);
+ render(
+
+
+
+ );
- expect(addModal).toHaveBeenCalledWith(expect.objectContaining({ subjectId: subject.id, subjectIsStatic: subjectIsStatic(subject), title: `Historical Data: ${subject.name}` }));
+ const button = await screen.findByTestId(buttonTestId);
+ userEvent.click(button);
+
+ expect(addModal).toHaveBeenCalledWith(expect.objectContaining({ subjectId: subject.id, subjectIsStatic: subjectIsStatic(subject), title: `Historical Data: ${subject.name}` }));
+ });
});
});
\ No newline at end of file
From f627a4bea60f309072f3fae3505d507fd6afe7f3 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Wed, 18 May 2022 12:08:04 -0700
Subject: [PATCH 11/18] replacing pre-rendered popup content with the standard
state-managed popup renderer. code and test refactors to accommodate.
---
src/StaticSensorsLayer/index.js | 50 +++++++++++++++------
src/SubjectControls/_mixins.scss | 1 +
src/SubjectControls/index.test.js | 13 ++++--
src/SubjectControls/styles.module.scss | 4 +-
src/SubjectHistoricalDataModal/index.js | 2 -
src/SubjectHistoryButton/index.js | 10 ++---
src/SubjectHistoryButton/index.test.js | 6 +--
src/SubjectHistoryButton/styles.module.scss | 1 -
src/SubjectPopup/styles.module.scss | 1 -
9 files changed, 57 insertions(+), 31 deletions(-)
diff --git a/src/StaticSensorsLayer/index.js b/src/StaticSensorsLayer/index.js
index 7b61654b7..52a8c9412 100644
--- a/src/StaticSensorsLayer/index.js
+++ b/src/StaticSensorsLayer/index.js
@@ -1,20 +1,20 @@
import React, { useContext, memo, useCallback, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
-import { Provider, connect } from 'react-redux';
-import ReactDOM from 'react-dom';
+import { connect } from 'react-redux';
import mapboxgl from 'mapbox-gl';
import set from 'lodash/set';
import isEmpty from 'lodash/isEmpty';
-import store from '../store';
import { MapContext } from '../App';
import { DEVELOPMENT_FEATURE_FLAGS, LAYER_IDS, SUBJECT_FEATURE_CONTENT_TYPE } from '../constants';
import { addFeatureCollectionImagesToMap } from '../utils/map';
import { getSubjectDefaultDeviceProperty } from '../utils/subjects';
+
+import { showPopup } from '../ducks/popup';
+
import { BACKGROUND_LAYER, LABELS_LAYER } from './layerStyles';
import LayerBackground from '../common/images/sprites/layer-background-sprite.png';
-import SubjectPopup from '../SubjectPopup';
const { ENABLE_NEW_CLUSTERING } = DEVELOPMENT_FEATURE_FLAGS;
@@ -38,7 +38,7 @@ const IMAGE_DATA = {
const popup = new mapboxgl.Popup({ offset: [0, 0], anchor: 'bottom', closeButton: false });
-const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNames, simplifyMapDataOnZoom: { enabled: isDataInMapSimplified } }) => {
+const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNames, simplifyMapDataOnZoom: { enabled: isDataInMapSimplified }, showPopup }) => {
const map = useContext(MapContext);
const showMapStaticSubjectsNames = showMapNames[STATIC_SENSOR]?.enabled ?? false;
const [clickedLayerID, setClickedLayerID] = useState('');
@@ -94,13 +94,31 @@ const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNam
}
}, [map]);
- const createPopup = useCallback((layer) => {
+ const showPopupForStationarySubject = useCallback((layer) => {
+ const { geometry, properties } = layer;
+
+ const handleMapClick = () => {
+ setClickedLayerID('');
+ setLayerVisibility(layer.layer.id);
+ };
+
+ showPopup('subject', { geometry, properties, coordinates: geometry.coordinates });
+ setTimeout(() => map.once('click', handleMapClick));
+
+ }, [map, setLayerVisibility, showPopup]);
+
+ /* const createPopup = useCallback((layer) => {
const { geometry } = layer;
const elementContainer = document.createElement('div');
- ReactDOM.render(
-
- , elementContainer);
+ ReactDOM.render(
+
+
+
+
+
+
+ , elementContainer);
popup.setLngLat(geometry.coordinates)
.setDOMContent(elementContainer)
@@ -110,15 +128,21 @@ const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNam
setClickedLayerID('');
setLayerVisibility(layer.layer.id);
});
- }, [map, setLayerVisibility]);
+ }, [map, setLayerVisibility]); */
const onLayerClick = useCallback((event) => {
+ if (event?.originalEvent?.cancelBubble) return;
+
+ event?.preventDefault();
+ event?.originalEvent?.stopPropagation();
+
const clickedLayer = getStaticSensorLayer(event);
+
const clickedLayerID = clickedLayer.layer.id;
setClickedLayerID(clickedLayerID.replace(PREFIX_ID, ''));
- createPopup(clickedLayer);
+ showPopupForStationarySubject(clickedLayer);
setLayerVisibility(clickedLayerID, false);
- }, [getStaticSensorLayer, setClickedLayerID, createPopup, setLayerVisibility]);
+ }, [getStaticSensorLayer, showPopupForStationarySubject, setClickedLayerID, setLayerVisibility]);
const createLayer = useCallback((layerID, sourceId, layout, paint) => {
if (!map.getLayer(layerID)) {
@@ -198,7 +222,7 @@ const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNam
const mapStatetoProps = ({ view: { showMapNames, simplifyMapDataOnZoom } }) => ({ showMapNames, simplifyMapDataOnZoom });
-export default connect(mapStatetoProps, null)(memo(StaticSensorsLayer));
+export default connect(mapStatetoProps, { showPopup })(memo(StaticSensorsLayer));
StaticSensorsLayer.propTypes = {
staticSensors: PropTypes.object.isRequired,
diff --git a/src/SubjectControls/_mixins.scss b/src/SubjectControls/_mixins.scss
index 4dd43a643..d2c1e6e38 100644
--- a/src/SubjectControls/_mixins.scss
+++ b/src/SubjectControls/_mixins.scss
@@ -14,6 +14,7 @@
display: flex;
flex-flow: row;
line-height: normal;
+ overflow: hidden;
position: relative;
.button {
diff --git a/src/SubjectControls/index.test.js b/src/SubjectControls/index.test.js
index d58899667..368ef7e0a 100644
--- a/src/SubjectControls/index.test.js
+++ b/src/SubjectControls/index.test.js
@@ -8,6 +8,7 @@ import mockSubjectData from '../__test-helpers/fixtures/subjects';
import { Provider } from 'react-redux';
import { mockStore } from '../__test-helpers/MockStore';
+import NavigationWrapper from '../__test-helpers/navigationWrapper';
import { addModal } from '../ducks/modals';
@@ -43,7 +44,9 @@ describe('SubjectControls', () => {
test('rendering without crashing', () => {
render(
-
+
+
+
);
});
@@ -53,7 +56,9 @@ describe('SubjectControls', () => {
test('showing the historical data button', async () => {
render(
-
+
+
+
);
@@ -65,7 +70,9 @@ describe('SubjectControls', () => {
render(
-
+
+
+
);
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index ded71be58..6e9ccc4ff 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -26,7 +26,7 @@
.hasLabel {
background-color: rgba($secondary-light-gray, .25);
border: 0.06rem solid $secondary-medium-light-gray;
- border-radius: .12rem;
+ border-radius: 0.12rem;
max-width: 5.75rem;
max-height: 1.85rem;
border-radius: 0.2rem;
@@ -47,7 +47,7 @@
span {
font-size: 0.68rem;
line-height: normal;
- padding: .1rem .3rem;
+ padding: 0.1rem 0.3rem;
margin: 0 -.2rem;
}
diff --git a/src/SubjectHistoricalDataModal/index.js b/src/SubjectHistoricalDataModal/index.js
index 4a6e74a74..49548a749 100644
--- a/src/SubjectHistoricalDataModal/index.js
+++ b/src/SubjectHistoricalDataModal/index.js
@@ -13,8 +13,6 @@ import { removeModal } from '../ducks/modals';
import { calcGpsDisplayString } from '../utils/location';
-/* calcGpsDisplayString(lat, lng, currentFormat) */
-
import LoadingOverlay from '../LoadingOverlay';
import DateTime from '../DateTime';
diff --git a/src/SubjectHistoryButton/index.js b/src/SubjectHistoryButton/index.js
index 9caad1385..3eee7ba9e 100644
--- a/src/SubjectHistoryButton/index.js
+++ b/src/SubjectHistoryButton/index.js
@@ -3,14 +3,12 @@ import noop from 'lodash/noop';
import PropTypes from 'prop-types';
import styles from './styles.module.scss';
-const SubjectHistoryButton = (props, ref) => {
- const { className: externalClassName, disabled, onClick, showLabel, ...rest } = props;
+import SubjectControlButton from '../SubjectControls/button';
+const SubjectHistoryButton = (props, ref) => {
+ const { disabled, onClick, showLabel, ...rest } = props;
- return
-
- {showLabel && Historical Data}
-
;
+ return ;
};
export default memo(forwardRef(SubjectHistoryButton));
diff --git a/src/SubjectHistoryButton/index.test.js b/src/SubjectHistoryButton/index.test.js
index 7958da5e8..83efb4792 100644
--- a/src/SubjectHistoryButton/index.test.js
+++ b/src/SubjectHistoryButton/index.test.js
@@ -18,14 +18,14 @@ test('call onClick', () => {
});
});
-describe('show different titles depending on showLabel prop', () => {
- test('show the label showLabel is true', () => {
+describe('setting label visibility', () => {
+ test('showing the label showLabel is true', () => {
render();
expect(screen.getByText('Historical Data')).toBeTruthy();
});
- test('Do not show any label if showLabel is false', () => {
+ test('not showing any label if showLabel is false', () => {
render();
expect(() => screen.getByText('Historical Data')).toThrow();
});
diff --git a/src/SubjectHistoryButton/styles.module.scss b/src/SubjectHistoryButton/styles.module.scss
index 290472c91..b04f79eb7 100644
--- a/src/SubjectHistoryButton/styles.module.scss
+++ b/src/SubjectHistoryButton/styles.module.scss
@@ -22,7 +22,6 @@ $background_image_url: '../common/images/icons/';
.button {
@include button('historical-data');
pointer-events: none;
- margin-top: 0.25rem;
}
.container {
diff --git a/src/SubjectPopup/styles.module.scss b/src/SubjectPopup/styles.module.scss
index b8bd39f6f..0ce6691aa 100644
--- a/src/SubjectPopup/styles.module.scss
+++ b/src/SubjectPopup/styles.module.scss
@@ -180,7 +180,6 @@ $background_image_url: '../common/images/icons/';
.controls {
flex-wrap: wrap;
> * {
- flex: 1;
width: 45%;
margin: 0 0.25rem 0.25rem;
}
From ee7cc06ec179af83cf301d2fb101f313234a7d55 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Wed, 18 May 2022 12:26:40 -0700
Subject: [PATCH 12/18] PR feedback tweaks
---
src/SubjectControls/button.js | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/SubjectControls/button.js b/src/SubjectControls/button.js
index 3e70245af..163fbb6da 100644
--- a/src/SubjectControls/button.js
+++ b/src/SubjectControls/button.js
@@ -14,20 +14,22 @@ const SubjectControlButton = (props, ref) => {
;
};
-export default memo(forwardRef(SubjectControlButton));
+const memoizedSubjectControlButton = memo(forwardRef(SubjectControlButton));
-SubjectControlButton.defaultProps = {
+export default memoizedSubjectControlButton;
+
+memoizedSubjectControlButton.defaultProps = {
onClick: noop,
showLabel: true,
loading: false,
};
-SubjectControlButton.propTypes = {
+memoizedSubjectControlButton.propTypes = {
buttonClassName: PropTypes.string,
containerClassName: PropTypes.string,
disabled: PropTypes.bool,
labelText: PropTypes.string,
- onClick: PropTypes.func.isRequired,
+ onClick: PropTypes.func,
showLabel: PropTypes.bool,
loading: PropTypes.bool,
};
\ No newline at end of file
From f1f3ecf1e9e3773ac89672ac30cc4d8bea531267 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 19 May 2022 10:22:57 -0700
Subject: [PATCH 13/18] removing commented code
---
src/StaticSensorsLayer/index.js | 23 -----------------------
1 file changed, 23 deletions(-)
diff --git a/src/StaticSensorsLayer/index.js b/src/StaticSensorsLayer/index.js
index 52a8c9412..fd06480d7 100644
--- a/src/StaticSensorsLayer/index.js
+++ b/src/StaticSensorsLayer/index.js
@@ -107,29 +107,6 @@ const StaticSensorsLayer = ({ staticSensors = {}, isTimeSliderActive, showMapNam
}, [map, setLayerVisibility, showPopup]);
- /* const createPopup = useCallback((layer) => {
- const { geometry } = layer;
-
- const elementContainer = document.createElement('div');
- ReactDOM.render(
-
-
-
-
-
-
- , elementContainer);
-
- popup.setLngLat(geometry.coordinates)
- .setDOMContent(elementContainer)
- .addTo(map);
-
- popup.on('close', () => {
- setClickedLayerID('');
- setLayerVisibility(layer.layer.id);
- });
- }, [map, setLayerVisibility]); */
-
const onLayerClick = useCallback((event) => {
if (event?.originalEvent?.cancelBubble) return;
From 56d1efadaba3817d4758b14f081db4e89df443d8 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 19 May 2022 10:42:02 -0700
Subject: [PATCH 14/18] de-destructuring as per PR feedback
---
src/SubjectHistoryButton/index.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/SubjectHistoryButton/index.js b/src/SubjectHistoryButton/index.js
index 3eee7ba9e..ff9aefaf0 100644
--- a/src/SubjectHistoryButton/index.js
+++ b/src/SubjectHistoryButton/index.js
@@ -6,9 +6,8 @@ import styles from './styles.module.scss';
import SubjectControlButton from '../SubjectControls/button';
const SubjectHistoryButton = (props, ref) => {
- const { disabled, onClick, showLabel, ...rest } = props;
- return ;
+ return ;
};
export default memo(forwardRef(SubjectHistoryButton));
From 0e8d6c5bb32fa7afe97d58552366e2524bcabfd2 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 19 May 2022 10:45:47 -0700
Subject: [PATCH 15/18] adding back missing timeslider-based functionality as
per PR feedback
---
src/SubjectPopup/index.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/SubjectPopup/index.js b/src/SubjectPopup/index.js
index 8c81e11a4..142f93b1a 100644
--- a/src/SubjectPopup/index.js
+++ b/src/SubjectPopup/index.js
@@ -109,9 +109,9 @@ const SubjectPopup = ({ data, popoverPlacement, timeSliderState, showPopup }) =>
{device_status_properties.map(({ label, units, value }, index) =>
{label}
-
+ {isTimeSliderActive ? No historical data :
{value.toString()} {units}
-
+ }
)}
}
From ea09a75ac52f38b1f5ac96f7e08a72d0ae82f301 Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 19 May 2022 14:19:25 -0700
Subject: [PATCH 16/18] css tweaks for overflow issue
---
src/SubjectControls/_mixins.scss | 1 -
src/SubjectControls/styles.module.scss | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/SubjectControls/_mixins.scss b/src/SubjectControls/_mixins.scss
index d2c1e6e38..4dd43a643 100644
--- a/src/SubjectControls/_mixins.scss
+++ b/src/SubjectControls/_mixins.scss
@@ -14,7 +14,6 @@
display: flex;
flex-flow: row;
line-height: normal;
- overflow: hidden;
position: relative;
.button {
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index 6e9ccc4ff..ef2485185 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -30,6 +30,7 @@
max-width: 5.75rem;
max-height: 1.85rem;
border-radius: 0.2rem;
+ overflow: hidden;
cursor: pointer;
[class*=spinner] {
From 6a761dfcbb2fcf18b27aa7d72ba6db160127a3fe Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Thu, 19 May 2022 14:50:28 -0700
Subject: [PATCH 17/18] font size tweak
---
src/SubjectControls/styles.module.scss | 2 +-
src/SubjectHistoryButton/styles.module.scss | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/SubjectControls/styles.module.scss b/src/SubjectControls/styles.module.scss
index ef2485185..e977c79ab 100644
--- a/src/SubjectControls/styles.module.scss
+++ b/src/SubjectControls/styles.module.scss
@@ -46,7 +46,7 @@
}
span {
- font-size: 0.68rem;
+ font-size: 0.65rem;
line-height: normal;
padding: 0.1rem 0.3rem;
margin: 0 -.2rem;
diff --git a/src/SubjectHistoryButton/styles.module.scss b/src/SubjectHistoryButton/styles.module.scss
index b04f79eb7..154b3a49f 100644
--- a/src/SubjectHistoryButton/styles.module.scss
+++ b/src/SubjectHistoryButton/styles.module.scss
@@ -51,7 +51,7 @@ $background_image_url: '../common/images/icons/';
}
span {
- font-size: 0.68rem;
+ font-size: 0.65rem;
line-height: normal;
padding: .1rem .7rem;
margin: 0 -.2rem;
From aa8fc97bc72e39175f123ca0f9e564e3ee8eb2af Mon Sep 17 00:00:00 2001
From: Joshua Krautwurst
Date: Fri, 20 May 2022 14:19:31 -0700
Subject: [PATCH 18/18] style tweaks as per QA feedback
---
src/SubjectHistoryButton/styles.module.scss | 30 ++++++---------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/SubjectHistoryButton/styles.module.scss b/src/SubjectHistoryButton/styles.module.scss
index 154b3a49f..b22539f3b 100644
--- a/src/SubjectHistoryButton/styles.module.scss
+++ b/src/SubjectHistoryButton/styles.module.scss
@@ -1,34 +1,20 @@
@import '../common/styles/buttons';
@import '../common/styles/vars/colors';
+@import '../SubjectControls/mixins';
-$background_image_url: '../common/images/icons/';
-
-@mixin button($image: 'tracks_off') {
- background: url('#{$background-image_url+$image}.svg');
- background-size: 85%;
- background-position: 0.15rem 0.1rem;
- background-repeat: no-repeat;
- border: none;
- display: block;
- height: $square-button-dimension;
- outline: none;
- width: $square-button-dimension;
-
- &:focus {
- outline: none;
- }
-}
-
-.button {
- @include button('historical-data');
- pointer-events: none;
-}
.container {
display: flex;
align-items: center;
flex-flow: row;
position: relative;
+ .button {
+ @include buttonBackground('historical-data');
+ pointer-events: none;
+ background-size: 90%;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
&.hasLabel {
background-color: $subject-control-btn-bg;