- 15 Sep, 2016 10 commits
-
-
Robert Knight authored
Use the <svg-icon> component to render a refresh icon in the top bar and adjust the styling to center the icon and pending update count vertically.
-
Robert Knight authored
Following the approach we have implemented for using <svg> icons on the website without all of the hassle that comes with icon fonts, implement an <svg-icon> component which renders icons as inline SVGs in the client and add the 'refresh' icon for use in the top bar.
-
Robert Knight authored
-
Robert Knight authored
-
Robert Knight authored
-
Robert Knight authored
Prevent the apply updates button from being squashed horizontally and thus wrapping onto multiple lines
-
Robert Knight authored
Implement support for tooltips that point up at the target element and use this facility for the 'Apply Updates' icon in the toolbar.
-
Robert Knight authored
To avoid having the contents of the sidebar shift in a distracting way while the user is reading or editing an annotation, do not apply real-time updates received via the WS immediately but instead alert the user to the updates via an icon in the top-bar and apply the updates when the user clicks the button. This commit implements support for caching updates in the streamer, showing an icon and applying updates when the user clicks the icon. Known issues: - The icon does not currently match the Refresh icon in the specs - The tooltip sits above the icon pointing down, instead of pointing up as per the mocks
-
Robert Knight authored
-
Nick Stenning authored
Refactor Redux store into smaller modules
-
- 14 Sep, 2016 5 commits
-
-
Robert Knight authored
-
Robert Knight authored
Use helper functions to take the set of action creator and selector functions exported by each module and expose them on annotationUI.
-
Robert Knight authored
Split the large switch statements in each reducer function into objects which map action types to state update functions. These functions are then composed together with a `createReducer` helper defined in `reducers/util`
-
Robert Knight authored
For the benefit of developers who are not familiar with Redux and Elm-style architectures, add documentation at the top of the annotationUI module which explains how state is managed in the app.
-
Robert Knight authored
The `annotationUI` module evolved from before we used Redux to manage app state and it was getting large and doing too much. This PR splits out most of the logic into smaller modules in the `reducers` folder. The `annotationUI` module continues to present the same exports as before to avoid needing to change too much in one commit. Each module in `reducers/` defines: - An `init` function which returns the initial state relating to some aspect of the application - A set of action types, relating to that aspect of the application - An `update` function which processes those actions - A set of action creators, which are helper functions that create these actions - A set of selector functions, which are helper functions that return derived data from this state There is a root module in reducers/index.js which combines the actions, init function and update functions from each module into a single init and update function which can be used to initialize the Redux store. Action creators which require access to the current app state or are asynchronous, such as `addAnnotations` return thunks. See https://github.com/gaearon/redux-thunk#motivation . Several selection-related action creators currently return thunks but can be refactored in future into plain actions. To avoid making this commit too large, annotationUI continues to export wrappers around the action creators so that code outside the Redux store and tests do not need to be changed.
-
- 13 Sep, 2016 8 commits
-
-
Robert Knight authored
-
Robert Knight authored
-
Robert Knight authored
Add temporary timestamps to new annotations (for sorting)
-
Nick Stenning authored
Brand new annotations (and page notes) are currently displayed as editor widgets in the sidebar alongside all the existing annotation cards. This means they need to be sortable. Sorting by location isn't a problem, because the annotation already carries the document location information by the time it gets to `addAnnotations`, but sorting by the updated date is, because currently the `created` and `updated` fields are only provided when the server sends back the saved annotation. This commit changes that by adding temporary `created` and `updated` timestamps to new annotations (those without an ID). These will be ignored entirely by the server, and overwritten when the annotation is saved. If for whatever reason `addAnnotations` is called with a new annotation that already has these fields, they will not be overwritten. Fixes (the rest of) #96.
-
Robert Knight authored
Don't reset the sortKey unless actually switching tabs
-
Nick Stenning authored
Creating a new annotation or page note would reset the sortKey for the sidebar to the default, because doing so can trigger a call to `selectTab`. This change ensures that we shortcut the state update if we're already on the correct tab, and don't update `sortKey` in that case.
-
Robert Knight authored
Sort notes tab by date
-
Nick Stenning authored
This commit prevents page notes from being sorted by "Location" (i.e. document location), a meaningless property for page notes, which would result in them being sorted unpredictably. Instead, we define a default sort key and a set of allowable sort keys for each sidebar tab. When switching between tabs, the sort key is updated to the default, and the set of allowable sort keys updated depending on the tab. This results in page notes being sorted (by default) in ascending order of their most recent update. Using "updated" rather than "created" is a bit dubious, but changing this requires a bit of care to avoid strange behaviour on the stream, so I've left that for another time. N.B. As implemented, the sort key on each tab will be reset to the default every time the tab changes. This is less surprising than preserving the sort key across tab switches, and doesn't involve any requirement to remember system state across tab switches. We can also revisit this in the future if it seems wrong. Fixes #96.
-
- 12 Sep, 2016 6 commits
-
-
Robert Knight authored
-
Robert Knight authored
-
Nick Stenning authored
Extract virtualized thread list into its own component
-
Robert Knight authored
Annotation quotes now have a default color of `$grey-7`, so there is no need to have an additional selector for when the annotation card is hovered.
-
Robert Knight authored
* Extract thread list into its own component for better encapsulation and easier testing * Rename `annotation-card` to `thread-list__card` and move it to the component styling file for `thread-list`. Unfortunately a couple of visual effects still require it to be referenced in annotation.scss * Remove ng-show hack in thread list Remove the "ng-show" attribute which was added as a hack for reasons which are no longer applicable. See https://github.com/hypothesis/h/issues/2642#issuecomment-150629305 for original context. * Remove unused js-hover class and the code that supports it It turns out that this class is no longer referenced in code or applicable styling.
-
Robert Knight authored
Fix missing initialization of $orphan flag for new annotations and properly account for annotations that do not have IDs in ADD_ANNOTATIONS and UPDATE_ANCHOR_STATUS actions. - Fix ADD_ANNOTATIONS action replacing the first existing unsaved annotation when a second unsaved annotation is added - Fix UPDATE_ANCHOR_STATUS action not matching annotations without IDs (ie. new annotations) correctly. - Fix $orphan flag not being initialized for new annotations Fixes #94
-
- 09 Sep, 2016 2 commits
-
-
Nick Stenning authored
-
Nick Stenning authored
-
- 08 Sep, 2016 1 commit
-
-
Sean Hammond authored
Remove "assertion" GET param from token requests
-
- 07 Sep, 2016 2 commits
-
-
Nick Stenning authored
When fetching a JWT from the server, the client needs to supply the session CSRF token in order to prevent third-party pages from being able to fetch and use tokens without the user's permission. Previously, we supplied the CSRF token in an "assertion" GET parameter (partially in an attempt to make this look a bit like an OAuth token issuance API) but in Pyramid 1.7 this isn't allowed. (This is good: allowing the CSRF to be passed as a GET parameter makes it easier to construct a cross-domain attack which retrieves a token for the user). This commit moves the CSRF token into a request header, which works because there are only two legitimate situations in which this request is made: - from an embed iframe, which is on the same origin as the service - from a Chrome extension iframe, which is permitted to make cross-origin XHR requests to URLs specified in the manifest (in our case, `<all_urls>`). Note that we cannot rely on Angular's built-in CSRF support here, because it does not operate for cross-domain requests.
-
Nick Stenning authored
This reverts commit e0e23bde. This needs more thought, as the X-CSRF-Token header won't currently be set for cross-domain requests (such as those made by the extension sidebar).
-
- 06 Sep, 2016 6 commits
-
-
Robert Knight authored
Remove "assertion" GET param from token requests
-
Nick Stenning authored
When fetching a JWT from the server, the client needs to supply the session CSRF token in order to prevent third-party pages from being able to fetch and use tokens without the user's permission. Previously, it was necessary to supply this token in the "assertion" GET parameter -- in an attempt to make this look a bit like an OAuth token issuance API -- but in Pyramid 1.7 this isn't allowed, and it turns out not to be necessary, because Angular's CSRF support retrieves the token from an XSRF-TOKEN cookie set in earlier requests and sets the X-CSRF-Token request header automatically.
-
Nick Stenning authored
-
Nick Stenning authored
-
Nick Stenning authored
-
Robert Knight authored
When receiving annotation updates via the WebSocket, merge the updated annotation with the existing local annotation, preserving the local tag and anchoring status flags. This fixes a problem where Annotations would be shown as Orphans after an update was received via the WebSocket * When an annotation update is received, merge the current/new versions rather than removing the current version and replacing it with the new one. * Remove mutation of existing annotation in `loadAnnotations()`, since the reducer function is now responsible for merging changes and triggering UI updates
-