Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

MM-230 Use common panel to display search results and include # of co-ops filtered + further fixes #251

Merged
merged 15 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ mykomap's repository:
Install the prerequisites

apt install php php-curl rsync # On Debian
npm run install
npm install

Run the development web server in the background (do this in a separate console):

Expand Down
88 changes: 53 additions & 35 deletions src/map-app/app/map-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EventBus } from "../eventbus";
import "./map"; // Seems to be needed to prod the leaflet CSS into loading.
import { SidebarPresenter } from "./presenter/sidebar";
import { PhraseBook } from "../localisations";
import { toString as _toString } from '../utils';
import { toString as _toString, canDisplayExpandedSidebar } from '../utils';
import { Action, AppState, PropEquality, StateManager, TextSearch } from "./state-manager";
import { StateChange } from "../undo-stack";
import { Dictionary } from "../common-types";
Expand Down Expand Up @@ -48,7 +48,8 @@ export class MapUI {
});
};

EventBus.Directory.initiativeClicked.sub(initiative => this.onInitiativeClickedInSidebar(initiative));
EventBus.Map.initiativeClicked.sub(initiative => this.onInitiativeClicked(initiative));
EventBus.Map.clearFiltersAndSearch.sub(() => this.clearFiltersAndSearch());
}

// This inspects the config and constructs an appropriate set of
Expand Down Expand Up @@ -99,6 +100,7 @@ export class MapUI {
onNewInitiatives() {
const loadedInitiatives = this.dataServices.getAggregatedData().loadedInitiatives;
this.stateManager.reset(loadedInitiatives);
this.refreshSidebar();
}

createPresenter(): MapPresenter {
Expand All @@ -113,8 +115,8 @@ export class MapUI {
this.stateManager.clearPropFilter(filterName);
}

resetSearch(): void {
this.stateManager.reset();
clearFiltersAndSearch(): void {
this.stateManager.clearFiltersAndSearch();
}

/// Returns a list of property values matching the given filter
Expand All @@ -131,36 +133,38 @@ export class MapUI {
throw new Error(`an attempt to add a filter on an unknown propery name '${propName}'`);

const isMulti = propDef.type === 'multi';
if (value === undefined)
if (value === undefined) {
this.stateManager.clearPropFilter(propName);
else
} else {
this.stateManager.propFilter(new PropEquality(propName, value, isMulti));
}

if (canDisplayExpandedSidebar()) // on smaller screens, wait until user clicks Show Results
EventBus.Sidebar.showInitiativeList.pub();
}

isSelected(initiative: Initiative): boolean {
// Currently unimplemented - I can see an sea-initiative-active class
// being applied if a test was true, but it makes no sense in the current
// context AFAICT. The test was:
// initiative === this.contextStack.current()?.initiatives[0]

// The main thing is seemed to do is highlight an initiative (or
// initiatives) in the directory pop-out list of initiatives in a
// category.

// For now, just return false always. We may re-implement this later.
return false;
const selectedInitiatives = this.mapPresenter?.getSelectedInitiatives() ?? [];
return selectedInitiatives.includes(initiative);
}

toggleSelectInitiative(initiative: Initiative) {
// Currently unimplemented.
const selectedInitiatives = this.mapPresenter?.getSelectedInitiatives() ?? [];

// EventBus.Markers.needToShowLatestSelection.pub(lastContent.initiatives);
if (selectedInitiatives.includes(initiative)) {
EventBus.Markers.needToShowLatestSelection.pub(selectedInitiatives.filter(i => i !== initiative));
} else {
EventBus.Markers.needToShowLatestSelection.pub([...selectedInitiatives, initiative]);
}
}


performSearch(text: string) {
console.log("Search submitted: [" + text + "]");
this.stateManager.textSearch(new TextSearch(text));

if (canDisplayExpandedSidebar()) {// on smaller screens, wait until user clicks Show Results
EventBus.Sidebar.showInitiativeList.pub();
}
}

// Text to show in the search box
Expand All @@ -182,26 +186,40 @@ export class MapUI {
}

private refreshSidebar() {
this.getSidebarPresenter(this).then((presenter) => presenter.changeSidebar());
this.getSidebarPresenter(this).then((presenter) => {
presenter.refreshSidebar();
});
}



private notifyMapNeedsToNeedsToBeZoomedAndPannedOneInitiative(initiative: Initiative) {
const data = EventBus.Map.mkSelectAndZoomData([initiative]);
EventBus.Map.needsToBeZoomedAndPanned.pub(data);
private notifyMapNeedsToNeedsToSelectAndZoomOnInitiative(initiative: Initiative) {
const maxZoom = this.config.getMaxZoomOnOne();
const defaultPos = this.config.getDefaultLatLng();

const data = EventBus.Map.mkSelectAndZoomData([initiative], { maxZoom, defaultPos });
EventBus.Map.selectAndZoomOnInitiative.pub(data);
}

private onInitiativeClickedInSidebar(initiative?: Initiative) {
if (!initiative)
return;
private onInitiativeClicked(initiative?: Initiative) {
console.log('Clicked', initiative);

//this.parent.mapui.stateManager.append(new SearchResults([initiative]));
//console.log(this.parent.mapui.stateManager.current());

this.notifyMapNeedsToNeedsToBeZoomedAndPannedOneInitiative(initiative);
this.refreshSidebar();
EventBus.Initiative.searchedInitiativeClicked.pub(initiative);
if (initiative) {
// Move the window to the right position first
this.notifyMapNeedsToNeedsToSelectAndZoomOnInitiative(initiative);
// Populate the sidebar and highlight the intiative in the directory
this.getSidebarPresenter(this).then((presenter) => {
presenter.populateInitiativeSidebar(
initiative,
this.markers.getInitiativeContent(initiative) ?? ''
);
});
}
else {
// User has deselected
EventBus.Markers.needToShowLatestSelection.pub([]);
this.getSidebarPresenter(this).then((presenter) => {
presenter.hideInitiativeSidebar();
});
}
}

currentItem() {
Expand Down
15 changes: 9 additions & 6 deletions src/map-app/app/presenter/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { MapUI } from '../map-ui';

export class MapPresenter extends BasePresenter {
readonly view: MapView;
private previouslySelected: Initiative[] = [];
private currentlySelected: Initiative[] = [];

constructor(readonly mapUI: MapUI) {
super();
Expand All @@ -35,7 +35,7 @@ export class MapPresenter extends BasePresenter {
EventBus.Initiatives.loadStarted.sub(() => this.onInitiativeLoadMessage());
EventBus.Initiatives.loadFailed.sub(error => this.onInitiativeLoadMessage(error));

EventBus.Markers.needToShowLatestSelection.sub(initiative => this.onMarkersNeedToShowLatestSelection(initiative));
EventBus.Markers.needToShowLatestSelection.sub(initiatives => this.onMarkersNeedToShowLatestSelection(initiatives));
EventBus.Map.needsToBeZoomedAndPanned.sub(data => this.onMapNeedsToBeZoomedAndPanned(data));
EventBus.Map.needToShowInitiativeTooltip.sub(initiative => this.onNeedToShowInitiativeTooltip(initiative));
EventBus.Map.needToHideInitiativeTooltip.sub(initiative => this.onNeedToHideInitiativeTooltip(initiative));
Expand All @@ -49,7 +49,7 @@ export class MapPresenter extends BasePresenter {
}

onInitiativeClicked() {
EventBus.Directory.initiativeClicked.pub(undefined);
EventBus.Map.initiativeClicked.pub(undefined);
}

onLoad() {
Expand Down Expand Up @@ -88,19 +88,19 @@ export class MapPresenter extends BasePresenter {
console.log("onInitiativeComplete");

// Call this last so map will have bounds set (else error!)
this.mapUI.onNewInitiatives();
this.mapUI.onNewInitiatives();
}

private onInitiativeLoadMessage(error?: EventBus.Initiatives.DatasetError) {
this.view.startLoading(error);
}

onMarkersNeedToShowLatestSelection(selected: Initiative[]) {
this.previouslySelected.forEach((initiative) => {
this.currentlySelected.forEach((initiative) => {
this.mapUI.markers.setUnselected(initiative);
});

this.previouslySelected = selected;
this.currentlySelected = selected;

//zoom in and then select
selected.forEach((initiative) => {
Expand Down Expand Up @@ -144,4 +144,7 @@ export class MapPresenter extends BasePresenter {
this.view.selectAndZoomOnInitiative(data);
}

getSelectedInitiatives(): Initiative[] {
return this.currentlySelected;
}
}
65 changes: 53 additions & 12 deletions src/map-app/app/presenter/sidebar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EventBus } from '../../eventbus';
import { MapUI } from '../map-ui';
import { Initiative } from '../model/initiative';
import { SidebarView } from '../view/sidebar';
import { BasePresenter } from './base';
import { AboutSidebarPresenter } from './sidebar/about';
Expand Down Expand Up @@ -58,28 +59,30 @@ export class SidebarPresenter extends BasePresenter {

this.changeSidebar(defaultPanel);
}

// Changes or refreshes the sidebar
//
// @param name - the sidebar to change

/**
* Changes the sidebar
* @param name the sidebar to change (needs to be one of the keys of this.sidebar)
*/
changeSidebar(name?: SidebarId): void {
if (!name) {
if (this.sidebarName) {
// Just refresh the currently showing sidebar.
this.children[this.sidebarName]?.refreshView();
this.children[this.sidebarName]?.refreshView(false);
}
else {
// If nothing is showing, refresh the first in the list. Or nothing, if none.
// If no sidebar is set, pick the first one
let key: SidebarId;
for(key in this.children) {
const child = this.children[key];
if (!child)
continue;

this.sidebarName = key;
child.refreshView();
child.refreshView(true);
break;
}
console.warn('No sidebars to show');
}
return;
}
Expand All @@ -89,7 +92,7 @@ export class SidebarPresenter extends BasePresenter {
const child = this.children[name];
if (child !== undefined) {
this.sidebarName = name;
child.refreshView();
child.refreshView(true);
}
return;
}
Expand All @@ -101,6 +104,34 @@ export class SidebarPresenter extends BasePresenter {
);
}

/**
* Fully refresh the sidebar
*/
refreshSidebar() {
if (this.sidebarName) {
this.children[this.sidebarName]?.refreshView(true);
} else {
// If no sidebar is set, pick the first one
let key: SidebarId;
for(key in this.children) {
const child = this.children[key];
if (!child)
continue;

this.sidebarName = key;
child.refreshView(true);
break;
}
console.warn('No sidebars to show');
}

// If we get here it's not a valid sidebar (possibly it wasn't configured)
console.warn(
"Attempting to call SidebarPresenter.changeSidebar() with a "+
`non-existant sidebar '${name}' - ignoring.`
);
}

showSidebar() {
this.view.showSidebar();
}
Expand All @@ -118,6 +149,14 @@ export class SidebarPresenter extends BasePresenter {
this.view.hideInitiativeSidebar();
}

populateInitiativeSidebar(initiative: Initiative, initiativeContent: string) {
this.view.populateInitiativeSidebar(initiative, initiativeContent);
}

showInitiativeList() {
this.view.showInitiativeList();
}

hideInitiativeList() {
this.view.hideInitiativeList();
}
Expand All @@ -133,18 +172,20 @@ export class SidebarPresenter extends BasePresenter {
});
EventBus.Sidebar.showDirectory.sub(() => {
this.changeSidebar("directory");
this.view.showInitiativeList();
this.showSidebar();
});
EventBus.Sidebar.showDatasets.sub(() => {
this.changeSidebar("datasets");
this.showSidebar();
});
EventBus.Sidebar.showSidebar.sub(() => this.showSidebar());
EventBus.Sidebar.hideSidebar.sub(() => this.hideSidebar());
EventBus.Sidebar.hideInitiativeSidebar.sub(() => this.hideInitiativeSidebar());
EventBus.Sidebar.showInitiativeList.sub(() => this.showInitiativeList());
EventBus.Sidebar.hideInitiativeList.sub(() => this.hideInitiativeList());
EventBus.Initiatives.reset.sub(() => this.changeSidebar());
EventBus.Initiatives.loadComplete.sub(() => this.changeSidebar());
EventBus.Initiatives.reset.sub(() => {
this.changeSidebar();
this.hideInitiativeList();
});
}

}
Expand Down
Loading
Loading