Skip to content

Commit 548a8ee

Browse files
authored
Merge pull request #395 from SYU15/rm-assigned-pages
Phase 1 of remove assigned pages
2 parents fdf2e54 + 311fd27 commit 548a8ee

File tree

3 files changed

+20
-84
lines changed

3 files changed

+20
-84
lines changed

README.md

Lines changed: 3 additions & 24 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 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
@@ -63,7 +63,7 @@ Screenshot:
6363
![screenshot](screenshot.png)
6464

6565

66-
## Google Sheets (Tasking and Significant Changes)
66+
## Google Sheets (Significant Changes)
6767

6868
The analysis UI keeps some data and runtime configuration separate from the public web monitoring database ([`web-monitoring-db`](http://github.com/edgi-govdata-archiving/web-monitoring-db)). This data is kept in 3 Google Docs spreadsheets. You can use the UI without configuring them, but you will be missing some functionality.
6969

@@ -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: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,14 @@ import {Link, NavLink} from 'react-router-dom';
1313
* The NavBar component renders an app title, user info, links, etc.
1414
* @param {NavBarProps} props
1515
*/
16-
export default ({children = null, title = 'EDGI Web Monitoring', user = null, showLogin, logOut, pageFilter, setPageFilter}) => (
16+
export default ({children = null, title = 'EDGI Web Monitoring', user = null, showLogin, logOut }) => (
1717
<nav className="navbar navbar-inverse">
1818
<div className="container-fluid">
1919
<div className="navbar-header">
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>
24-
<li>{renderNavLink('All Pages', 'pages', pageFilter, setPageFilter)}</li>
23+
<li><NavLink to="/pages" exact>All Pages</NavLink></li>
2524
<li>{renderUserInfo(user, showLogin, logOut)}</li>
2625
</ul>
2726
</div>
@@ -43,18 +42,3 @@ function renderUserInfo (user, showLogin, logOut) {
4342
return <button className="auth-status btn btn-link" onClick={showLogin}>Log In</button>;
4443
}
4544
}
46-
47-
function renderNavLink (linkText, filterToMatch, pageFilter, setPageFilter) {
48-
const matchesFilter = match => match ? match.url === `/${filterToMatch}` : pageFilter === filterToMatch;
49-
const setFilter = () => setPageFilter(filterToMatch);
50-
51-
return (
52-
<NavLink
53-
to={`/${filterToMatch}`}
54-
isActive={matchesFilter}
55-
onClick={setFilter}
56-
>
57-
{linkText}
58-
</NavLink>
59-
);
60-
}

src/components/web-monitoring-ui.jsx

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ const api = new WebMonitoringDb({
1919
});
2020

2121
const localApi = new WebMonitoringApi(api);
22-
2322
/**
2423
* WebMonitoringUi represents the root container for the app. It also maintains
2524
* a top-level lsit of pages to share across the app. We do this here instead
@@ -34,9 +33,7 @@ export default class WebMonitoringUi extends React.Component {
3433
constructor (props) {
3534
super(props);
3635
this.state = {
37-
assignedPages: null,
3836
isLoading: true,
39-
pageFilter: '', // keeps track of which set of pages we are looking at
4037
pages: null,
4138
search: null,
4239
showLogin: false,
@@ -47,14 +44,9 @@ export default class WebMonitoringUi extends React.Component {
4744
this.afterLogin = this.afterLogin.bind(this);
4845
this.logOut = this.logOut.bind(this);
4946
this.loadPages = this.loadPages.bind(this);
50-
this.setPageFilter = this.setPageFilter.bind(this);
5147
this.search = this.search.bind(this);
5248
}
5349

54-
setPageFilter (filter) {
55-
this.setState({pageFilter: filter});
56-
}
57-
5850
showLogin () {
5951
this.setState({showLogin: true});
6052
}
@@ -65,9 +57,9 @@ export default class WebMonitoringUi extends React.Component {
6557

6658
afterLogin (user) {
6759
// Clear page lists (they could have held not-logged-in errors)
68-
this.setState({pages: null, assignedPages: null});
60+
this.setState({pages: null});
6961
this.hideLogin();
70-
this.loadPages(this.state.pageFilter);
62+
this.loadPages();
7163
}
7264

7365
logOut () {
@@ -78,41 +70,32 @@ export default class WebMonitoringUi extends React.Component {
7870

7971
search (query) {
8072
this.setState({search: query});
81-
this.loadPages(this.state.pageFilter);
73+
this.loadPages();
8274
}
8375

8476
/**
85-
* Load pages depending on whether we want all pages or assigned pages.
77+
* Load all pages.
8678
* @private
87-
* @param {string} pageFilter Must be either 'assignedPages' or 'pages'
8879
*
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`.
80+
* Sends a requests out to localApi for pages and sets `pages` property of state.
9181
* These are passed as props to various child components.
9282
*/
93-
loadPages (pageFilter) {
83+
loadPages () {
9484
api.isLoggedIn()
9585
.then(loggedIn => {
9686
if (!loggedIn) {
9787
return Promise.reject(new Error('You must be logged in to view pages'));
9888
}
9989

10090
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-
}
91+
92+
return api.getPages(query);
10793
})
10894
// Set state.pages = error; downstream code should check `pages` type.
10995
.catch(error => error)
11096
.then(pages => {
111-
// TODO: differentiate between having no assignments (pages == null)
112-
// and having no changes to your assigned pages (pages == [])
11397
this.setState({
114-
[pageFilter]: pages || [],
115-
pageFilter
98+
pages: pages || []
11699
});
117100
});
118101
}
@@ -141,11 +124,11 @@ export default class WebMonitoringUi extends React.Component {
141124
return this.renderLoginDialog();
142125
}
143126

144-
const withData = (ComponentType, pageType) => {
127+
const withData = (ComponentType) => {
145128
return (routeProps) => {
146-
const pages = this.state[pageType];
129+
const pages = this.state.pages;
147130
if (!pages) {
148-
this.loadPages(pageType);
131+
this.loadPages();
149132
}
150133
return <ComponentType
151134
{...routeProps}
@@ -165,26 +148,16 @@ export default class WebMonitoringUi extends React.Component {
165148
user={this.state.user}
166149
showLogin={this.showLogin}
167150
logOut={this.logOut}
168-
pageFilter={this.state.pageFilter}
169-
setPageFilter={this.setPageFilter}
170151
>
171152
<EnvironmentBanner apiUrl={api.url}/>
172153
</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-
}}/>
180-
<Route path="/pages" render={withData(PageList, 'pages')} />
181-
<Route path="/assignedPages" render={withData(PageList, 'assignedPages')} />
154+
<Route exact path="/" render={() => <Redirect to="/pages" />}/>
155+
<Route path="/pages" render={withData(PageList)} />
182156
<Route path="/page/:pageId/:change?" render={(routeProps) =>
183157
<PageDetails
184158
{...routeProps}
185159
user={this.state.user}
186-
pageFilter={this.state.pageFilter}
187-
pages={this.state[this.state.pageFilter]}
160+
pages={this.state.pages}
188161
/>
189162
}/>
190163
<Route path="/version/:versionId" component={VersionRedirect} />

0 commit comments

Comments
 (0)