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

Feature/open chart as map [DHIS2-5987] #213

Merged
merged 37 commits into from
Feb 27, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9c09c3b
Api module for interacting with user data store
neeilya Feb 6, 2019
27019e0
Api methods for saving/retrieving analytical object in/from user data…
neeilya Feb 6, 2019
58cfe61
MapMenu component
neeilya Feb 6, 2019
4958517
Remove map dropdown menu, use chart type selection section instead
neeilya Feb 7, 2019
81d3b16
Globe icon asset
neeilya Feb 7, 2019
6b550f1
Define "Open as map" visualization type
neeilya Feb 7, 2019
fcf08bb
Move managing-AO-in-user-data-store requests to api/userDataStore.js
neeilya Feb 7, 2019
589d001
Move visualization type menu item into dedicated component
neeilya Feb 7, 2019
0aeec59
Enable support for "Open as: Geo Map" visualization type
neeilya Feb 7, 2019
c5f7847
Prevent url from changing on "update" button click if path = "/curren…
neeilya Feb 11, 2019
60af8b9
Remove id, name & displayName attributes from AO before putting it in…
neeilya Feb 11, 2019
ef91042
Enable support for retrieving and applying chart config from user dat…
neeilya Feb 11, 2019
aa86d6d
Correct name for create/update method in user data store api
neeilya Feb 11, 2019
5d4f8b5
prettier
neeilya Feb 11, 2019
0a33f5c
Move api related "prepareCurrentAnalyticalObject" function into api/u…
neeilya Feb 11, 2019
2f10200
Tests
neeilya Feb 12, 2019
8af839b
Tests
neeilya Feb 12, 2019
81c2a17
Tests
neeilya Feb 13, 2019
3491344
Merge branch 'master' into feature/open-chart-as-map
neeilya Feb 13, 2019
99c45b3
Append dimension items names to currentAnalyticalObject
neeilya Feb 18, 2019
c82bc6a
Set column as default chart type
neeilya Feb 19, 2019
d2c44e5
Get parent graph map from visualization function
neeilya Feb 19, 2019
ab71050
Open as map confirmation dialog component
neeilya Feb 19, 2019
c196e27
Show confirmation dialog if user opens chart as map and chart has mul…
neeilya Feb 19, 2019
6ca131d
Generate parent graph map from current analytical object
neeilya Feb 19, 2019
12c0a48
Remove open as map confirmation dialog
neeilya Feb 20, 2019
b84a907
Rename "Open as: Geo Map" chart type to "Open as: Map"
neeilya Feb 20, 2019
f7d3a49
Append names only for dimensions which have name property in metadata
neeilya Feb 20, 2019
93f5e05
Move current analytical object specifc functions to separate module
neeilya Feb 20, 2019
ba35ec8
Tests
neeilya Feb 20, 2019
35b6572
Prettier
neeilya Feb 20, 2019
38a28f2
Handle edge case when no org units are selected
neeilya Feb 22, 2019
e8b3f2a
Move styles to dedicated styles file
neeilya Feb 22, 2019
8ad9cd2
Prettier
neeilya Feb 22, 2019
7ccffce
Use procedural style in prepare current analytical object function
neeilya Feb 25, 2019
3f71e0d
Fix appendDimensionItemNamesToAnalyticalObject function, include item…
neeilya Feb 27, 2019
dd4c65b
Merge branch 'master' into feature/open-chart-as-map
neeilya Feb 27, 2019
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
14 changes: 10 additions & 4 deletions packages/app/i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2019-01-21T11:22:11.007Z\n"
"PO-Revision-Date: 2019-01-21T11:22:11.007Z\n"
"POT-Creation-Date: 2019-02-06T12:52:28.419Z\n"
"PO-Revision-Date: 2019-02-06T12:52:28.419Z\n"

msgid "Rename successful"
msgstr ""
Expand Down Expand Up @@ -44,10 +44,10 @@ msgstr ""
msgid "Select All"
msgstr ""

msgid "Remove"
msgid "Search dimensions"
msgstr ""

msgid "Search dimensions"
msgid "Remove"
msgstr ""

msgid "Dimension recommended with selected data"
Expand Down Expand Up @@ -122,6 +122,12 @@ msgstr ""
msgid "None selected"
msgstr ""

msgid "Map"
msgstr ""

msgid "Open chart as map"
msgstr ""

msgid "Unsaved chart"
msgstr ""

Expand Down
9 changes: 9 additions & 0 deletions packages/app/src/api/analytics.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { getInstance } from 'd2';
import { FIXED_DIMENSIONS } from '../modules/fixedDimensions';
import * as userDataStore from './userDataStore';

const peId = FIXED_DIMENSIONS.pe.id;

export const CURRENT_AO_KEY = 'currentAnalyticalObject';

export const apiDownloadImage = async (type, formData) => {
const d2 = await getInstance();
const api = d2.Api.getApi();
Expand Down Expand Up @@ -100,3 +103,9 @@ export const apiFetchAnalyticsForYearOverYear = async (current, options) => {
yearlySeriesLabels,
}));
};

export const apiSaveAOInUserDataStore = (current, key = CURRENT_AO_KEY) =>
neeilya marked this conversation as resolved.
Show resolved Hide resolved
userDataStore.apiCreate(current, key);

export const apiFetchAOFromUserDataStore = (key = CURRENT_AO_KEY) =>
userDataStore.apiFetch(key);
36 changes: 36 additions & 0 deletions packages/app/src/api/userDataStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getInstance } from 'd2';
import { onError } from './index';

export const NAMESPACE = 'analytics';

export const hasNamespace = async d2 =>
await d2.currentUser.dataStore.has(NAMESPACE);

export const getNamespace = async (d2, hasNamespace) =>
hasNamespace
? await d2.currentUser.dataStore.get(NAMESPACE)
: await d2.currentUser.dataStore.create(NAMESPACE);

export const apiCreate = async (data, key, namespace) => {
try {
const d2 = await getInstance();
const ns =
namespace || (await getNamespace(d2, await hasNamespace(d2)));

return ns.set(key, data);
} catch (error) {
return onError(error);
}
};

export const apiFetch = async (key, namespace) => {
try {
const d2 = await getInstance();
const ns =
namespace || (await getNamespace(d2, await hasNamespace(d2)));

return ns.get(key);
} catch (error) {
return onError(error);
}
};
87 changes: 87 additions & 0 deletions packages/app/src/components/MapMenu/MapMenu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import React, { Component, Fragment } from 'react';
import Button from '@material-ui/core/Button';
import Menu from '@material-ui/core/Menu';
import i18n from '@dhis2/d2-i18n';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';

import { sGetCurrent } from '../../reducers/current';
import { apiSaveAOInUserDataStore } from '../../api/analytics';

export const MAPS_APP_URL = 'dhis-web-maps';

export const defaultState = {
anchorEl: null,
};

export class MapMenu extends Component {
constructor(props, context) {
super(props);

this.state = defaultState;
this.d2 = context.d2;
this.baseUrl = context.baseUrl;
}

toggleMenu = target => this.setState({ anchorEl: target || null });

onOpenChartAsMapClick = async () => {
await apiSaveAOInUserDataStore(this.props.current);

window.location.href = `${
this.baseUrl
}/${MAPS_APP_URL}?currentAnalyticalObject=true`;
};

render() {
return (
<Fragment>
<Button
className={this.props.className}
onClick={event => this.toggleMenu(event.currentTarget)}
disableFocusRipple
disableRipple
>
{i18n.t('Map')}
</Button>
<Menu
open={Boolean(this.state.anchorEl)}
anchorEl={this.state.anchorEl}
onClose={() => this.toggleMenu()}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
getContentAnchorEl={null}
disableAutoFocusItem
>
<Button
disabled={!this.props.current}
onClick={this.onOpenChartAsMapClick}
className={this.props.className}
>
{i18n.t('Open chart as map')}
</Button>
</Menu>
</Fragment>
);
}
}

MapMenu.propTypes = {
className: PropTypes.string,
};

MapMenu.contextTypes = {
d2: PropTypes.object,
baseUrl: PropTypes.string,
};

const mapStateToProps = state => ({
current: sGetCurrent(state),
});

export default connect(
mapStateToProps,
{}
)(MapMenu);
2 changes: 2 additions & 0 deletions packages/app/src/components/MenuBar/MenuBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import FileMenu from '@dhis2/d2-ui-file-menu';
import MapMenu from '../MapMenu/MapMenu';
import { withStyles } from '@material-ui/core/styles';

import UpdateButton from '../UpdateButton/UpdateButton';
Expand Down Expand Up @@ -49,6 +50,7 @@ export const MenuBar = ({ classes, ...props }, context) => (
<VisualizationOptionsManager className={classes.label} />
<DownloadMenu className={classes.label} />
<div className={classes.grow} />
<MapMenu className={classes.label} />
<InterpretationsButton className={classes.label} />
</div>
);
Expand Down