From a401a116a008d6ca8e338d7a7800fba02b57b42a Mon Sep 17 00:00:00 2001 From: Ben Furber Date: Fri, 10 Nov 2023 13:31:07 +0000 Subject: [PATCH 1/4] fix: checking for pp for production builds --- src/stores/Maps/maps.store.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/stores/Maps/maps.store.ts b/src/stores/Maps/maps.store.ts index dc08636f3a..1a80e97a74 100644 --- a/src/stores/Maps/maps.store.ts +++ b/src/stores/Maps/maps.store.ts @@ -50,7 +50,9 @@ export class MapsStore extends ModuleStore { // HACK - ARH - 2019/12/09 filter unaccepted pins, should be done serverside const activeUser = this.activeUser const isAdmin = hasAdminRights(activeUser) - const isPP = localStorage.getItem('platformTheme') === 'precious-plastic' + const isPP = + (process.env.REACT_APP_PLATFORM_THEME || + localStorage.getItem('platformTheme')) === 'precious-plastic' pins = pins .filter((p) => { From 72cdfcd721c810da43649147ccf85445e882d3c4 Mon Sep 17 00:00:00 2001 From: Ben Furber Date: Fri, 10 Nov 2023 13:59:02 +0000 Subject: [PATCH 2/4] feat: move is precious plastic logic to util --- src/stores/Maps/maps.store.ts | 6 ++---- src/utils/isPreciousPlastic.test.ts | 15 +++++++++++++++ src/utils/isPreciousPlastic.ts | 6 ++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 src/utils/isPreciousPlastic.test.ts create mode 100644 src/utils/isPreciousPlastic.ts diff --git a/src/stores/Maps/maps.store.ts b/src/stores/Maps/maps.store.ts index 1a80e97a74..ae07cdeebb 100644 --- a/src/stores/Maps/maps.store.ts +++ b/src/stores/Maps/maps.store.ts @@ -21,6 +21,7 @@ import { } from 'src/utils/helpers' import { logger } from 'src/logger' import { filterMapPinsByType } from './filter' +import { isPreciousPlastic } from 'src/utils/isPreciousPlastic' const COLLECTION_NAME: IDBEndpoint = 'mappins' export class MapsStore extends ModuleStore { @@ -50,9 +51,6 @@ export class MapsStore extends ModuleStore { // HACK - ARH - 2019/12/09 filter unaccepted pins, should be done serverside const activeUser = this.activeUser const isAdmin = hasAdminRights(activeUser) - const isPP = - (process.env.REACT_APP_PLATFORM_THEME || - localStorage.getItem('platformTheme')) === 'precious-plastic' pins = pins .filter((p) => { @@ -60,7 +58,7 @@ export class MapsStore extends ModuleStore { const isPinAccepted = p.moderation === 'accepted' const wasCreatedByUser = activeUser && p._id === activeUser.userName const isAdminAndAccepted = isAdmin && p.moderation !== 'rejected' - const isPPMember = isPP && p.type === 'member' + const isPPMember = isPreciousPlastic() && p.type === 'member' return ( p.type && !isDeleted && diff --git a/src/utils/isPreciousPlastic.test.ts b/src/utils/isPreciousPlastic.test.ts new file mode 100644 index 0000000000..18cfd4e263 --- /dev/null +++ b/src/utils/isPreciousPlastic.test.ts @@ -0,0 +1,15 @@ +import { isPreciousPlastic } from './isPreciousPlastic' + +describe('isPreciousPlastic', () => { + it('is true when PP is the platform theme ', () => { + localStorage.setItem('platformTheme', 'precious-plastic') + const isPP = isPreciousPlastic() + expect(isPP).toBe(true) + }) + + it('is false when anything else is the platform theme ', () => { + localStorage.setItem('platformTheme', 'anything') + const isPP = isPreciousPlastic() + expect(isPP).toBe(false) + }) +}) diff --git a/src/utils/isPreciousPlastic.ts b/src/utils/isPreciousPlastic.ts new file mode 100644 index 0000000000..f902c6fd8d --- /dev/null +++ b/src/utils/isPreciousPlastic.ts @@ -0,0 +1,6 @@ +export const isPreciousPlastic = (): boolean => { + return ( + (process.env.REACT_APP_PLATFORM_THEME || + localStorage.getItem('platformTheme')) === 'precious-plastic' + ) +} From a1c9ae7b322c1c9ebf9e2c574ad0c9e6f6af6f6d Mon Sep 17 00:00:00 2001 From: Ben Furber Date: Fri, 10 Nov 2023 14:26:35 +0000 Subject: [PATCH 3/4] feat: remove member pin setting for pp users --- packages/cypress/src/integration/settings.spec.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/cypress/src/integration/settings.spec.ts b/packages/cypress/src/integration/settings.spec.ts index 5fa4e7ef71..d395ed1a03 100644 --- a/packages/cypress/src/integration/settings.spec.ts +++ b/packages/cypress/src/integration/settings.spec.ts @@ -326,10 +326,17 @@ describe('[Settings]', () => { }, } cy.login('settings_member_new@test.com', 'test1234') - cy.step('Go to User Settings') + + cy.step('Go to User Settings for Precious Plastic') + localStorage.setItem('platformTheme', 'precious-plastic') cy.clickMenuItem(UserMenuItem.Settings) selectFocus(expected.profileType) + cy.get('[data-cy=pin-description]').should('not.exist') + cy.step('Go to User Settings for Project Kamp') + localStorage.setItem('platformTheme', 'project-kamp') + cy.clickMenuItem(UserMenuItem.Settings) + selectFocus(expected.profileType) cy.get('[data-cy=location-dropdown]').should('exist') cy.get('[data-cy="add-a-map-pin"]').click() From eaffb5b7c2cd501e9e2efceb67880e4b6ce29fda Mon Sep 17 00:00:00 2001 From: Ben Furber Date: Mon, 13 Nov 2023 09:56:07 +0000 Subject: [PATCH 4/4] feat: allow member pins to still be selected on pp --- src/config/config.ts | 11 ++++++ src/pages/Maps/Content/Controls/Controls.tsx | 23 +++++-------- .../Controls/GroupingFilterDesktop.tsx | 8 ++--- .../Content/Controls/GroupingFilterMobile.tsx | 6 ++-- src/pages/Maps/Maps.tsx | 34 ++++++++++--------- src/stores/Maps/maps.store.ts | 22 ++++++++---- src/utils/isPreciousPlastic.test.ts | 15 -------- src/utils/isPreciousPlastic.ts | 6 ---- 8 files changed, 58 insertions(+), 67 deletions(-) delete mode 100644 src/utils/isPreciousPlastic.test.ts delete mode 100644 src/utils/isPreciousPlastic.ts diff --git a/src/config/config.ts b/src/config/config.ts index e90e420f24..e7f7ee7d00 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -157,3 +157,14 @@ export const SENTRY_CONFIG: ISentryConfig = { export const CDN_URL = _c('REACT_APP_CDN_URL', '') export const VERSION = _c('REACT_APP_PROJECT_VERSION', '') export const GA_TRACKING_ID = _c('REACT_APP_GA_TRACKING_ID') + +const isPreciousPlastic = (): boolean => { + return ( + (_c('REACT_APP_PLATFORM_THEME') || + localStorage.getItem('platformTheme')) === 'precious-plastic' + ) +} + +export const MAP_PROFILE_TYPE_HIDDEN_BY_DEFAULT = isPreciousPlastic() + ? 'member' + : undefined diff --git a/src/pages/Maps/Content/Controls/Controls.tsx b/src/pages/Maps/Content/Controls/Controls.tsx index 6589f96682..fe27c2fa60 100644 --- a/src/pages/Maps/Content/Controls/Controls.tsx +++ b/src/pages/Maps/Content/Controls/Controls.tsx @@ -8,7 +8,6 @@ import filterIcon from 'src/assets/icons/icon-filters-mobile.png' import { GroupingFilterDesktop } from './GroupingFilterDesktop' import { GroupingFilterMobile } from './GroupingFilterMobile' -import type { IMapPinType } from 'src/models/maps.models' import { HashLink as Link } from 'react-router-hash-link' import type { Map } from 'react-leaflet' import { inject } from 'mobx-react' @@ -21,7 +20,6 @@ import type { FilterGroup } from './transformAvailableFiltersToGroups' interface IProps extends RouteComponentProps { mapRef: React.RefObject availableFilters: FilterGroup[] - onFilterChange: (selected: Array) => void onLocationChange: (latlng: { lat: number; lng: number }) => void } interface IState { @@ -58,10 +56,14 @@ class Controls extends React.Component { return this.props as IInjectedProps } + onChange(selected) { + this.injected.mapsStore.setActivePinFilters(selected) + this.setState({ filtersSelected: selected }) + } + public render() { const { availableFilters } = this.props const { showFiltersMobile, filtersSelected } = this.state - const groupedFilters = availableFilters return ( { { - this.props.onFilterChange(selected as IMapPinType[]) - this.setState({ filtersSelected: selected }) - }} + availableFilters={availableFilters} + onChange={(selected) => this.onChange(selected)} /> { isOpen={showFiltersMobile} > { - this.props.onFilterChange(selected as IMapPinType[]) - this.setState({ filtersSelected: selected }) - }} + onChange={(selected) => this.onChange(selected)} onClose={this.toggleFilterMobileModal} /> diff --git a/src/pages/Maps/Content/Controls/GroupingFilterDesktop.tsx b/src/pages/Maps/Content/Controls/GroupingFilterDesktop.tsx index 40be33f894..23625d7216 100644 --- a/src/pages/Maps/Content/Controls/GroupingFilterDesktop.tsx +++ b/src/pages/Maps/Content/Controls/GroupingFilterDesktop.tsx @@ -5,9 +5,8 @@ import { Select } from 'oa-components' import type { FilterGroup } from './transformAvailableFiltersToGroups' interface IProps { - items: FilterGroup[] + availableFilters: FilterGroup[] onChange: (selectedItems: string[]) => void - selectedItems: Array } interface IInjectedProps extends IProps { mapsStore: MapsStore @@ -22,9 +21,6 @@ class GroupingFilterDesktop extends Component { } render() { - const { items } = this.props - const groupedOptions = items - const onSelectChange = (selectedOptions) => { const arr = selectedOptions.map((option) => option.value) this.props.onChange(arr) @@ -43,7 +39,7 @@ class GroupingFilterDesktop extends Component { variant="icons" isMulti isClearable - options={groupedOptions} + options={this.props.availableFilters} onChange={onSelectChange} placeholder="Select filters" /> diff --git a/src/pages/Maps/Content/Controls/GroupingFilterMobile.tsx b/src/pages/Maps/Content/Controls/GroupingFilterMobile.tsx index 9c728289ad..f47cd351c6 100644 --- a/src/pages/Maps/Content/Controls/GroupingFilterMobile.tsx +++ b/src/pages/Maps/Content/Controls/GroupingFilterMobile.tsx @@ -9,7 +9,7 @@ import type { MapsStore } from 'src/stores/Maps/maps.store' import type { FilterGroup } from './transformAvailableFiltersToGroups' interface IProps { - items: FilterGroup[] + availableFilters: FilterGroup[] selectedItems: Array onChange?: (selectedItems: string[]) => void onClose: () => void @@ -47,7 +47,7 @@ class GroupingFilterMobile extends Component { } render() { - const { items, selectedItems } = this.props + const { availableFilters, selectedItems } = this.props return ( @@ -61,7 +61,7 @@ class GroupingFilterMobile extends Component { /> - {items.map((item, idx) => { + {availableFilters.map((item, idx) => { return (
{ mapsStore: MapsStore @@ -37,12 +38,11 @@ class MapsPage extends React.Component { zoom: 3, firstLoad: true, } - this.mapRef = React.createRef() } public async componentDidMount() { - this.props.mapsStore.retrieveMapPins() + this.retrieveMapPins() this.props.mapsStore.retrievePinFilters() await this.showPinFromURL() if (!this.props.mapsStore.activePin) { @@ -61,6 +61,17 @@ class MapsPage extends React.Component { this.props.mapsStore.setActivePin(undefined) } + availableFilters() { + return transformAvailableFiltersToGroups(this.props.mapsStore, [ + { + grouping: 'verified-filter', + displayName: 'Verified', + type: 'verified', + }, + ...MAP_GROUPINGS, + ]) + } + private async promptUserLocation() { try { const position = await GetLocation() @@ -74,6 +85,10 @@ class MapsPage extends React.Component { } } + async retrieveMapPins() { + this.props.mapsStore.retrieveMapPins(MAP_PROFILE_TYPE_HIDDEN_BY_DEFAULT) + } + private setCenter(latlng: ILatLng) { this.setState({ center: latlng as ILatLng, @@ -112,20 +127,7 @@ class MapsPage extends React.Component { <> { - this.props.mapsStore.setActivePinFilters(selected) - }} + availableFilters={this.availableFilters()} onLocationChange={(latlng) => this.setCenter(latlng)} {...props} /> diff --git a/src/stores/Maps/maps.store.ts b/src/stores/Maps/maps.store.ts index ae07cdeebb..5b7867edad 100644 --- a/src/stores/Maps/maps.store.ts +++ b/src/stores/Maps/maps.store.ts @@ -5,6 +5,7 @@ import type { IMapPinWithDetail, IMapPinDetail, IBoundingBox, + IMapPinType, } from 'src/models/maps.models' import type { IDBEndpoint, IModerationStatus } from 'src/models/common.models' import type { RootStore } from '../index' @@ -21,7 +22,8 @@ import { } from 'src/utils/helpers' import { logger } from 'src/logger' import { filterMapPinsByType } from './filter' -import { isPreciousPlastic } from 'src/utils/isPreciousPlastic' + +type IFilterToRemove = IMapPinType | undefined const COLLECTION_NAME: IDBEndpoint = 'mappins' export class MapsStore extends ModuleStore { @@ -41,7 +43,10 @@ export class MapsStore extends ModuleStore { } @action - private processDBMapPins(pins: IMapPin[]) { + private processDBMapPins( + pins: IMapPin[], + filterToRemove: IFilterToRemove = undefined, + ) { if (pins.length === 0) { this.mapPins = [] return @@ -58,11 +63,10 @@ export class MapsStore extends ModuleStore { const isPinAccepted = p.moderation === 'accepted' const wasCreatedByUser = activeUser && p._id === activeUser.userName const isAdminAndAccepted = isAdmin && p.moderation !== 'rejected' - const isPPMember = isPreciousPlastic() && p.type === 'member' + return ( p.type && !isDeleted && - !isPPMember && (isPinAccepted || wasCreatedByUser || isAdminAndAccepted) ) }) @@ -70,7 +74,11 @@ export class MapsStore extends ModuleStore { return { ...p, verified: this.userStore.verifiedUsers[p._id] === true } }) this.mapPins = pins - this.filteredPins = this.mapPins + + const filters = this.activePinFilters + .filter(({ type }) => type !== filterToRemove) + .map(({ subType, type }) => (subType ? subType : type)) + this.setActivePinFilters(filters) } /* eslint-disable @typescript-eslint/no-unused-vars */ @@ -80,7 +88,7 @@ export class MapsStore extends ModuleStore { // this.recalculatePinCounts(boundingBox) } @action - public async retrieveMapPins() { + public async retrieveMapPins(filterToRemove: IFilterToRemove = undefined) { // TODO: make the function accept a bounding box to reduce load from DB /* TODO: unaccepted pins should be filtered in DB, before reaching the client @@ -94,7 +102,7 @@ export class MapsStore extends ModuleStore { .stream((pins) => { // TODO - make more efficient by tracking only new pins received and updating if (pins.length !== this.mapPins.length) { - this.processDBMapPins(pins) + this.processDBMapPins(pins, filterToRemove) } }) } diff --git a/src/utils/isPreciousPlastic.test.ts b/src/utils/isPreciousPlastic.test.ts deleted file mode 100644 index 18cfd4e263..0000000000 --- a/src/utils/isPreciousPlastic.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { isPreciousPlastic } from './isPreciousPlastic' - -describe('isPreciousPlastic', () => { - it('is true when PP is the platform theme ', () => { - localStorage.setItem('platformTheme', 'precious-plastic') - const isPP = isPreciousPlastic() - expect(isPP).toBe(true) - }) - - it('is false when anything else is the platform theme ', () => { - localStorage.setItem('platformTheme', 'anything') - const isPP = isPreciousPlastic() - expect(isPP).toBe(false) - }) -}) diff --git a/src/utils/isPreciousPlastic.ts b/src/utils/isPreciousPlastic.ts deleted file mode 100644 index f902c6fd8d..0000000000 --- a/src/utils/isPreciousPlastic.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const isPreciousPlastic = (): boolean => { - return ( - (process.env.REACT_APP_PLATFORM_THEME || - localStorage.getItem('platformTheme')) === 'precious-plastic' - ) -}