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() 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 dc08636f3a..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' @@ -22,6 +23,8 @@ import { import { logger } from 'src/logger' import { filterMapPinsByType } from './filter' +type IFilterToRemove = IMapPinType | undefined + const COLLECTION_NAME: IDBEndpoint = 'mappins' export class MapsStore extends ModuleStore { mapPins$: Subscription @@ -40,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 @@ -50,7 +56,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 = localStorage.getItem('platformTheme') === 'precious-plastic' pins = pins .filter((p) => { @@ -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 = isPP && 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) } }) }