Skip to content

Commit cd35b04

Browse files
committed
[WIP] remove assigned pages
1 parent 27741eb commit cd35b04

File tree

7 files changed

+14
-154
lines changed

7 files changed

+14
-154
lines changed

.env.example

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ GOOGLE_SHEETS_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\EXAMPLEExampleG9w0BAQEFAAS
1414

1515
# IDs of each Google Sheet used. To determine a sheet’s ID, see:
1616
# https://developers.google.com/sheets/api/guides/concepts#spreadsheet_id
17-
# Sheet that maps users to their assigned sites
18-
GOOGLE_TASK_SHEET_ID=example_sdf8Za7sdft39a_osnzhJBI2dsftasdf
1917
# Sheet where changes marked as “important” are saved
2018
GOOGLE_IMPORTANT_CHANGE_SHEET_ID=example_sdf8Za7sdft39a_osnzhJBI2dsftasdf
2119
# Sheet where changes in the “dictionary” (of insignificant changes) are saved

DEPLOYMENT.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ In our deployment, environment variables are named:
2020
6. `GOOGLE_IMPORTANT_CHANGE_SHEET_ID`
2121
7. `GOOGLE_DICTIONARY_SHEET_ID`
2222

23-
All are optional, but you will need to set the `GOOGLE_*` variables if you want to use the “assigned pages” feature (see the “Google Sheets” section of [README.md](./README.md) for more details).
24-
2523
## Shell script
2624

2725
The script takes 2 arguments that are optional.

README.md

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ It’s a React.js-based browser application with a Node.js backend with the foll
3434
npm start
3535
```
3636

37-
5. (Optional) Set up Google Sheets for user tasking, saving important changes and repeated, “dictionary” changes. If you skip this step, everything will work fine, but your UI will show all pages when logged in, not just your assigned pages. See the section below on [Google Sheets](#google-sheets-tasking-and-significant-changes).
37+
5. (Optional) Set up Google Sheets for user tasking, saving important changes and repeated, “dictionary” changes. See the section below on [Google Sheets](#google-sheets-tasking-and-significant-changes).
3838

3939
[nodenv]: https://github.com/nodenv/nodenv
4040
[nvm-alternatives]: https://github.com/nodenv/nodenv/wiki/Alternatives
@@ -74,28 +74,7 @@ GOOGLE_SERVICE_CLIENT_EMAIL=73874number-example@developer.gserviceaccount.com
7474
GOOGLE_SHEETS_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\EXAMPLEExampleG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCsBjS7qpN+vUhz\nXRhcL3pwKZtewjZ478rs7FylT+YAJMmy1wOS3ze2FVYaBHelloFromXm9gL82OCSJn1ZThePastuwGA0\npe9oZSAtiB4ujaHhcWCO7ZYZzBvsPRJZR2eo4UokDpmgAS9ExTU7zN+eKTBTFGB4\nKDc7FAxqhk9dBcYFpLU34wuQsS/SZY1j3I/pmqQ7CHnGG+KLhyRiZ6UvlT8KjWejWTFdfMoredksjfGibberishkljfkls+\nkerGibberishll7\n7oU0VVs3xY5nhkjd#r34jkd7vxjknfy3jsdhf5zjkGYfyXFNhVjsl/bJ3AHA/C9Fd5z9JmOCsZE\nyD9Yjy72C50CjOgCp568pse85A==\n-----END PRIVATE KEY-----\n
7575
```
7676

77-
In the next two sections, you’ll create the 3 sheets.
78-
79-
80-
### Creating Tasking Sheets
81-
82-
User tasking data (analysis timeframes, who is assigned what domains and pages, etc.) is currently kept in a Google Docs spreadsheet for easy manipulation by project admins. To enable tasking in your local build, you’ll need to create your own copy of this spreadsheet.
83-
84-
You can start off by making a copy of [this example tasking sheet](https://docs.google.com/spreadsheets/d/1l5TAoJBbX6xV7ZYF9g5TnryJ4-SsatXvb-6cWuTMW5A/). Otherwise, you can create one from scratch: create a spreadsheet in Google Docs. It should have two worksheets or tabs, named:
85-
86-
1. `Tasks` (this should be the first tab)
87-
2. `Timeframes`
88-
89-
**The `Tasks` sheet** should be formatted such that the first column is a list of usernames/e-mail addresses. The rest of the columns in that row are the names of domains that the user in the first column is assigned (one domain per column). Domains are the `site` attribute of a page in [the API](https://api.monitoring.envirodatagov.org). The first row is reserved for column headers. The sheet might look like:
90-
91-
| A | B | C |
92-
| - | - | - |
93-
| User/e-mail | Site | Site | Etc. |
94-
| someone@example.com | DOT - fhwa.dot.gov | EPA - epa.gov | |
95-
| someone.else@example.com | EPA - epa.gov/arc-x | GAO - Climate Change | DOI - fws.gov |
96-
| learner@example.com | DOI - blm.gov | | |
97-
98-
In this case, someone@example.com is assigned two domains, while learner@example.com is assigned only one. There can be any number of columns on each row.
77+
In the next two sections, you’ll create the 2 sheets.
9978

10079
**The `Timeframes` sheet** holds information about analysis timeframes. The analysis team currently works on changes in 3-day chunks and this sheet lets you define when those chunks start and end. It should have exactly two columns. The first is a date (in ISO 8601 format) that a timeframe starts on. The second is the duration of that timeframe in seconds (e.g. `259200` for 3 days). Timeframes are assumed to repeat until a new timeframe is started. Like `tasks`, the first row is reserved for column headers. This sheet might look like:
10180

src/components/nav-bar.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export default ({children = null, title = 'EDGI Web Monitoring', user = null, sh
2020
<Link to="/" className="navbar-brand">{title}</Link>
2121
</div>
2222
<ul className="nav navbar-nav">
23-
<li>{renderNavLink('Assigned Pages', 'assignedPages', pageFilter, setPageFilter)}</li>
2423
<li>{renderNavLink('All Pages', 'pages', pageFilter, setPageFilter)}</li>
2524
<li>{renderUserInfo(user, showLogin, logOut)}</li>
2625
</ul>

src/components/web-monitoring-ui.jsx

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
22
import React from 'react';
33
import AriaModal from 'react-aria-modal';
44
import {BrowserRouter as Router, Redirect, Route} from 'react-router-dom';
5-
import WebMonitoringApi from '../services/web-monitoring-api';
65
import WebMonitoringDb from '../services/web-monitoring-db';
76
import EnvironmentBanner from './environment-banner';
87
import Loading from './loading';
@@ -18,8 +17,6 @@ const api = new WebMonitoringDb({
1817
url: configuration.WEB_MONITORING_DB_URL
1918
});
2019

21-
const localApi = new WebMonitoringApi(api);
22-
2320
/**
2421
* WebMonitoringUi represents the root container for the app. It also maintains
2522
* a top-level lsit of pages to share across the app. We do this here instead
@@ -34,7 +31,6 @@ export default class WebMonitoringUi extends React.Component {
3431
constructor (props) {
3532
super(props);
3633
this.state = {
37-
assignedPages: null,
3834
isLoading: true,
3935
pageFilter: '', // keeps track of which set of pages we are looking at
4036
pages: null,
@@ -65,7 +61,7 @@ export default class WebMonitoringUi extends React.Component {
6561

6662
afterLogin (user) {
6763
// Clear page lists (they could have held not-logged-in errors)
68-
this.setState({pages: null, assignedPages: null});
64+
this.setState({pages: null});
6965
this.hideLogin();
7066
this.loadPages(this.state.pageFilter);
7167
}
@@ -82,12 +78,11 @@ export default class WebMonitoringUi extends React.Component {
8278
}
8379

8480
/**
85-
* Load pages depending on whether we want all pages or assigned pages.
81+
* Load all pages
8682
* @private
87-
* @param {string} pageFilter Must be either 'assignedPages' or 'pages'
83+
* @param {string} pageFilter Must be 'pages'
8884
*
89-
* Sends a requests out to either db-api or localApi for pages and sets
90-
* corresponding `assignedPages` or `pages` property of state and `pageFilter`.
85+
* Sends a requests out to ocalApi for pages and sets `pages` property of state and `pageFilter`.
9186
* These are passed as props to various child components.
9287
*/
9388
loadPages (pageFilter) {
@@ -98,23 +93,19 @@ export default class WebMonitoringUi extends React.Component {
9893
}
9994

10095
const query = Object.assign({include_latest: true}, this.state.search);
101-
if (pageFilter === 'assignedPages') {
102-
return localApi.getPagesForUser(api.userData.email, null, query);
103-
}
104-
else {
105-
return api.getPages(query);
106-
}
96+
97+
return api.getPages(query);
10798
})
108-
// Set state.pages = error; downstream code should check `pages` type.
109-
.catch(error => error)
11099
.then(pages => {
111100
// TODO: differentiate between having no assignments (pages == null)
112101
// and having no changes to your assigned pages (pages == [])
113102
this.setState({
114103
[pageFilter]: pages || [],
115104
pageFilter
116105
});
117-
});
106+
})
107+
// Set state.pages = error; downstream code should check `pages` type.
108+
.catch(error => error);
118109
}
119110

120111
loadUser () {
@@ -170,15 +161,8 @@ export default class WebMonitoringUi extends React.Component {
170161
>
171162
<EnvironmentBanner apiUrl={api.url}/>
172163
</NavBar>
173-
<Route exact path="/" render={() => {
174-
if (this.state.user) {
175-
return <Redirect to="/assignedPages" />;
176-
} else {
177-
return <Redirect to="/pages" />;
178-
}
179-
}}/>
164+
<Route exact path="/" render={() => <Redirect to="/pages" />}/>
180165
<Route path="/pages" render={withData(PageList, 'pages')} />
181-
<Route path="/assignedPages" render={withData(PageList, 'assignedPages')} />
182166
<Route path="/page/:pageId/:change?" render={(routeProps) =>
183167
<PageDetails
184168
{...routeProps}
@@ -210,11 +194,10 @@ export default class WebMonitoringUi extends React.Component {
210194
}
211195

212196
getChildContext () {
213-
return {api, localApi};
197+
return { api };
214198
}
215199
}
216200

217201
WebMonitoringUi.childContextTypes = {
218-
api: PropTypes.instanceOf(WebMonitoringDb),
219-
localApi: PropTypes.instanceOf(WebMonitoringApi)
202+
api: PropTypes.instanceOf(WebMonitoringDb)
220203
};

src/services/__tests__/web-monitoring-api.test.js

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -37,51 +37,4 @@ describe('WebMonitoringApi', () => {
3737
start: new Date('2017-01-01')
3838
});
3939
});
40-
41-
test('getDomainsForUser() returns parsed data', () => {
42-
fetch.mock('begin:/api/domains/', {domains: ['first', 'second']});
43-
return expect(api.getDomainsForUser('x'))
44-
.resolves
45-
.toEqual(['first', 'second']);
46-
});
47-
48-
test('getDomainsForUser() rejects for users without assignments', () => {
49-
fetch.mock('begin:/api/domains/', {error: 'NOT_FOUND'});
50-
return expect(api.getDomainsForUser('x')).rejects.toBeTruthy();
51-
});
52-
53-
test('getDomainsForUser() rejects for bad input', () => {
54-
return expect(api.getDomainsForUser()).rejects.toBeTruthy();
55-
});
56-
57-
test('getPagesForUser() calls through to WebMonitoringDb', () => {
58-
fetch
59-
.mock('begin:/api/timeframe', {
60-
duration: 259200,
61-
end: '2017-01-04',
62-
start: '2017-01-01'
63-
})
64-
.mock('begin:/api/domains/', {domains: ['first', 'second']});
65-
66-
expect(api.getPagesForUser('x')).resolves.toEqual([
67-
{url: 'a', tags: [{name: 'site:first'}]},
68-
{url: 'b', tags: [{name: 'site:second'}]},
69-
{url: 'c', tags: [{name: 'site:second'}]}
70-
]);
71-
});
72-
73-
test.skip('getPagesForUser() does not have duplicate entries', () => {
74-
fetch
75-
.mock('begin:/api/timeframe', {
76-
duration: 259200,
77-
end: '2017-01-04',
78-
start: '2017-01-01'
79-
})
80-
.mock('begin:/api/domains/', {domains: ['first', 'first']});
81-
82-
expect(api.getPagesForUser('x')).resolves.toEqual([
83-
{url: 'a', site: 'first'}
84-
]);
85-
});
86-
8740
});

src/services/web-monitoring-api.js

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -36,56 +36,6 @@ export default class WebMonitoringApi {
3636
});
3737
}
3838

39-
/**
40-
* Get a list of domains assigned to a given user.
41-
* @param {string} username
42-
* @returns {Promise<string[]>}
43-
*/
44-
getDomainsForUser (username) {
45-
if (!username) {
46-
return Promise.reject(new TypeError('The first argument to getDomainsForUser() must be a string.'));
47-
}
48-
49-
const url = `/api/domains/${username}`;
50-
return fetch(url)
51-
.then(response => response.json())
52-
.then(data => {
53-
if (data.error) {
54-
throw new Error(data.error);
55-
}
56-
57-
return data.domains;
58-
});
59-
}
60-
61-
/**
62-
* Get a list of pages a user should analyze based on their assigned
63-
* domains and the analysis timeframe.
64-
*
65-
* This promise can resolve to an array of pages OR to `null`, which
66-
* indicates the user has no assigned pages to monitor (an empty array of
67-
* pages means none of their pages were updated in the given timeframe).
68-
*
69-
* @param {string} username
70-
* @param {AnalysisTimeframe} [timeframe] If omitted, defaults to current
71-
* @param {object} [query] Additional query options for getting pages
72-
* @returns {Promise<Page[]>}
73-
*/
74-
getPagesForUser (username, timeframe, query = {}) {
75-
const domainsRequest = this.getDomainsForUser(username);
76-
const timeframeRequest = Promise.resolve(timeframe || this.getCurrentTimeframe());
77-
78-
return Promise.all([domainsRequest, timeframeRequest])
79-
.then(([domains, timeframe]) => {
80-
if (domains.length === 0) return null;
81-
return this._getPagesByDomains(
82-
domains,
83-
this._dateRangeString(timeframe),
84-
query
85-
);
86-
});
87-
}
88-
8939
/**
9040
* Add change information to the dictionary of insignificant changes in
9141
* Google sheets.

0 commit comments

Comments
 (0)