Closed agbeltran closed 4 years ago
The browse datagateway user story which shows some examples of card/grid views posted by @agbeltran.
So initial plan is to create a single card component and move onto creating multiple.
This will involve:
[x] figuring out how to use CSS3 Flexbox (or make use of Grids?); the current approach is to try flexbox (this will be a single EntityCard component - maybe needs a better name?),
[x] be able to control the sizing of these elements and see if it is possible to mix in the use of Grid (or maybe best not to use it with flexbox for styling a single Card) - flexbox and general CSS was used for controlling layout in the card,
[x] improve styling and layout of the card via CSS or Material UI components (look at the PaNOSC cards as an example).
An initial mockup of a single card is the following:
The whole card is in a flexbox but we only control the specifics of the layout for the items that are to the right of the image in the card. This is because we need to achieve two things with the flexbox:
This is the initial Balsamiq mockup that I am working of for the whole datagateway-dataview
and will be changed when required.
Some specific resources to learning flexbox's:
This can be updated when needed but other components of the CardView component include:
We will also need to make this component generic, similar to how the Table component works and just provide data to it and customise how it can be displayed for different entities (investigation/datasets).
At the moment I can start working with the investigation data. Similar to the Table component, the CardView should be able to accept props such as data, onClick, sort/onSort and check/onCheck in order to be customisable for different entities (i.e. investigations/datasets).
This CardView can then be used in custom card components e.g. InvestigationCardView/DatasetCardView but this will require more customisable in terms of layout.
The current priority is to:
Ignore https://github.com/ral-facilities/datagateway/commit/6fef79a233fc93da79e6d4df9d52ad0a09e882f0 as it is only related with #162 (this commit has been renamed for that branch).
Ongoing items to fix:
[x] toggling between views fetches the same data again from the API and adds to the data already present in the state, as a result, data in the state is duplicated,
[x] ~after toggling the view, the card information fails to load on /datasets or /datafiles but only works fine when toggled between table/card views on /investigations (work out why this occurs)~ This is due to duplicate data in the state (see above),
[x] query parameters need to be stored within the redux state,
[x] add space at end of the CardView page so the pagination component stands out,
[x] check: fix width of the information (start date, end date etc.) column when there is no information and only the Add to Cart/Remove from Cart button,
[x] ~fix the image sizing when there are thumbnails and have a consistent width on the card with and without an image (some cards may not have an image)~ *This is now tracked on #343,
[x] (question - ArrowTooltip will now be present in datagateway-common) the arrow tooltip needs to be generalised into separate wrapping components and not have features such as percentageWidth
/maxEnabledHeight
in the normal component (move to a separate component e.g. CardTooltip
),
[x] the collapsible component and "Show more"/"Show less" should not be present if the description does not exceed the default maximum content width (100px - this can be changed if needed),
[x] ~"No description available" should be centred on the card (?) if there is no summary available (maybe use a lighter font with Typography
component)~ This could be a future improvement but not necessary,
[x] ~ensure the width of the card with and without an image is the same (as some investigations/datasets may not contain an image - if there was a thumbnail - or have a default image)~ This is now tracked on #343,
[x] ~should we have an animation on the title or have the collapsible around the title and description (without this when the title expands the collapsing animation jumps)~ This could be a future improvement but not necessary,
[x] (question) description is not large enough to be collapsible but the title is long, should we show the "Show more"/"Show less"?
[x] disable "Max results" dropdown select list if the number of results is lower than the smallest results option in the list,
[x] ~no "&view=card" when toggling between views~ (moving to redux),
[x] ~added items to cart are not kept when moving between pages using pagination (requires add/remove to/from cart to be implemented)~; this is not an issue since we check the cartItems IDs match to the data IDs in the currently loaded data for a page (cartItems already track the items in the cart, we just read from the state),
[x] pagination should put the user at the top of the page when they select a new page (this automatically happens now as we request more new data on each page),
[x] toggle cards Switch should not appear on routes other than that of /browse/investigation and /browse/investigation/[investigationId]/dataset,
[x] view query parameter should not automatically trigger on routes other than ones with the toggle (linked to above issue),
[x] (question) ~throw an error if the attribute is not found as at the moment the whole cardview fails to load if an incorrect dataKey
is passed~ (this most likely is not needed - data will not load anyway - maybe show a generic error message when something fails to fetch?),
[x] after clicking on the investigation breadcrumb link, from within a dataset, the dataset information lingers within the state resulting in the investigation data showing dataset data and not rendering the cards properly (data needs to be loaded again for various variables such as data count, max results and queries, so correct pagination and data is requested with the right start/stop index),
[x] ~usage of dataKey and link when only one is required to show the title; have a plain title with no link or a title with a link (title with link is used at the moment but review use of CardViewDetails
- label, dataKey and content/link)~ This can be changed in the future if needed,
[x] important: width of the cards fluctuate when browsing between pages (with varying contents),
[x] clearTable
needs to work to temporarily fix duplicate data between views (we use clearData to specifically update the data with an empty array in Redux),
[x] pagination component holds the same page when moving between InvestigationCardView and DatasetCardView (a workaround for this issue was to check for the query parameter and page change),
[x] how should the other options for fetching data i.e. getInvestigation/getDatasetCount be provided? (we use loadData - maybe load initial data with options in customised card view and then just provide function to load more data?); we can just provide this when setting the mapDispatchToProps
,
[x] clicking on the same max results dropdown item results in the data loading again (preventing this issues' incorrect behaviour of loading data),
[x] clicking on the current page number on the pagination component results in the data being fetched again if the CardView
component is using pagination to fetch data from API (prevent this by ~disabling the current pagination number by using PaginationItem
~ not executing any of the onChange
actions if we are on the same page as being selected - additionally keeps the selected colour as opposed to disabling using the PaginationItem
),
[x] navigating by pressing the back button in the browser removes the queries due to the push event instead of going straight to the previous page (so requires two back button presses); this is due to the automatic push view we add if the query was not already present),
[x] due to the investigation/card view not unmounting correctly, props are carried over between the two different card views (one to tackle this is to have default values in the state e.g. -1 for a number and set it to the correct value in a useEffect),
[x] important: sizing issues; a lot of the sizing issues with the Grid and the Card/CardView is due to the fact I have hardcoded the sizes in px
- use more generic percentages or other sizing options to fix this,
[x] important: routes defined in the supportedPaths
in PageCard
that have a trailing /
are not matched (when we receive a route with a trailing '/', trim it),
[x] ~align circular progress bar when loading the page data~ (changed to a LinearProgess
on top of the CardView
),
[x] ~important: max results dropdown default value should not be -1 (should be "" ?)~,
[x] changing the max results on a page with less results than any of the options means that the data no longer renders (do not display max results selections when data is lower),
[x] ISIS instruments table does not fetch instrument data upon loading directly but only when toggled (due to fetchCount
not being called and the totalDataCount
not being updated to trigger a load of the data),
[x] displayName
issue when defining content anonymous function in information object (disable with // eslint-disable-next-line react/display-name
); this can be changed if needed,
[x] ~check: imports for CardViews not being found (an exporting issue?)~; this will be moved to datagateway-common
,
[x] evaluate the look and design of the Card when optional information is not provided i.e. buttons, further information, description or tags,
[x] ~check: evaluate use of React.useMemo vs React.useEffect in CardViews~ any difference in performance?,
[x] ~currently since we support both providing the whole data and disabling fetching via pagination (in https://github.com/ral-facilities/datagateway/commit/c89ee8ed3edc9ae92a6f0aebba3d5e4732ce070a), you have to manually use clearData
in the custom card view if you are fetching data as it will not be called in the CardView
component to prevent clearing data before/after it is loaded so when the state is updated the data may not show (the option to use pagination optionally can be removed once ISIS API calls supports just fetching the specific information we need and not all the data)~ the paginatedFetch option is now fully removed,
[x] provide a more concrete solution to the re-loading of data when totalDataCount
has changed and loadData needs to be set to false again (make a totalDataCount
part of the state as it used by the Pagination
component); reloading only occurs when there is more than one page of items and you click on the same number however does not request data again if there is only 1 page (why is this?),
[x] totalDataCount
update forces data to be fetched twice as CardView uses previous prop; use loading
in state to wait for any requests which are being fetched before loading the data in the CardView
component,
[x] ~question: location changes with filtering parameters does not apply filters when using the backward/forward browser buttons (how to fix this?)~ This has been fixed,
[x] clear savedView data in state if the location has changed since the information stored in savedView will no longer apply,
[x] important: manually providing a maxResults query parameter prevents the CardView
from loading data,
[x] important/check: prevent any manually provided, incorrect query parameters from preventing incorrect data to be loaded,
[x] ~important: Hide filtering/sort/pagination/max results (disable search too?) until data is fetched from the API~ All of these are hidden except for advanced filters,
[x] important: Adding/removing an item to and from the cart causes the page to scroll back to the top (maybe due to state update?).
Additional features for the Card and CardView (arising from sprint planning and remaining tasks):
[x] the toggled view should be saved to localStorage (retained for later use) so the user can continue using the same view as before,
[x] query parameters should be used for view type (table/card) (done), pagination (done), max results (done), filtering (done), sorting (done),
[x] toggling to card view with page query parameter does not work due to the internal page number set to the value it was beforehand (URL only works on page load/refresh),
[x] toggle (Switch component) button requires names for table/card,
[x] instruments could possibly used as tags (Chip components),
[x] search box (with dropdown advanced search - provide as a dialog or collapsible to search box - chosen collapsible),
[x] ~add in lucene search (datagateway-search
data-search branch implements this with code in datagateway-common
) to search box~ Moved to separate issue: #342,
[x] important: sort/filter box should be optional and should be able to be hidden in the CardView if no data,
[x] pagination needs to use the skip
and limit
when requesting information from the API (so we only get the information we need, this may pose a problem when calculating the maximum pages needed for pagination; solved by /count request)
[x] filter box; include faceted search with instruments (related to the Chips in each card tags) - this may require understanding the metadata we have to work with,
[x] look at example search functionality e.g. HEPData and advanced search on FAIRsharing,
[x] show investigation/dataset count/size in the cards for InvestigationCardView and DatasetCardView; this will need the getSize, getInvestigationCount/getDatasetCount options to be flagged when fetching investigation and dataset information,
[x] (question) add label and content renderer for further information to provide formatted data; added label and content to title links,
[x] link in investigation and dataset card views; support CardView detail to render Link component,
[x] ~question: tooltip needs at least a basic label in order to be shown otherwise it must be disabled via disableHoverListener
(handled by the label passed through the title prop in CardView)~,
[x] add/remove investigation/dataset from cart,
[x] link/content rendering for further information data,
[x] important: provide custom user-defined options for the max results aside from the default 10, 20 and 30,
[x] provide optional for retrievable information in further information (so only fetched when clicked - done with ExpansionPanel
); allow for a custom react node to be rendered with data (we can make use of existing details panels used in tables for this),
[x] provide support for multiple buttons in further information (pass array of ReactNode which can then be rendered),
[x] important: add ArrowTooltip support for large information which cannot be rendered in the information on the card,
[x] important: add ArrowTooltip support for filter by options (does this display?),
[x] support for deep nested object dataKey rendering,
[x] add support to save view information between both views including queries, filters and sort (when implemented),
[x] automatically expand a filtering panel if any of its options are selected (we keep a selectedCount
in filtersInfo
for each filter item); the defaultExpanded
prop for ExpansionPanel
is changed on the render so it is not expanded,
[x] ~important: add support to filter nested properties when this is available in the API (e.g. get distinct values for INVESTIGATIONINSTRUMENT[0].INSTRUMENT.NAME
); filtering for nested objects use dots as delimiters and do not include arrays, so INVESTIGATIONINSTRUMENT[0].INSTRUMENT.NAME
as a filter in the code corresponds to INVESTIGATIONINSTRUMENT.INSTRUMENT.NAME
in API call, adapt the code to handle this change in the filter object within the state~ (this has been addressed in https://github.com/ral-facilities/datagateway/commit/dc0f206e8d5cd2c78e79a5f776174bd2ad26a833),
[x] add ability specify custom (text/calendar) filter for any further information provided and render appropriate under "Filter By" section,
[x] important: make use of supportedPaths
in PageContainer
for both table and cards,
[x] ~add in support for images in Card
and CardView
when there is a field for it in ICAT (image code has been commented out for now)~ This now has a separate issue and code has been added back in: #343,
[x] important: correct UI layout issues (filters/sort boxes) and card data (we need to stretch the filter/sort box to stretch across screen and in a single column when browser width is decreased),
[x] important: show a "no data available" (or similar) if there is no data to display.
The updated mockup for the whole CardView includes the add/remove from cart buttons and search box:
To accommodate different data and to show less information for certain entities, we may need to check that the card layout works well when you have less information provided i.e. when there are no tags, no further information.
Also the card needs to support for entities which may not be items to add to cart but more links to further information, so the add/remove to/from cart may not be present. These varying layouts may be required for a variety of entities for ISIS and DIAMOND.
A feature that needs to be implemented is filtering. At the moment querying for ISIS means that we cannot use the distinct option to get only the data we need, meaning all data is fetched when we need we need to know all the values possible for filtering options.
To get around this we can provide the option to not use a paginated fetch of the data (so not using the offsetParams
to fetch data) and then just assume the view has passed in all the data available. As a result we do not fetch all the data again. This means we would just have to provide the option to slice data or query the API again to fetch data based on offsetParams. A check maybe required before doing the slice (so the stopIndex
is not assumed to be greater than the actual data length) and make sure the count we use is depending on if fetching data via pagination has been flagged so we can choose whether to use totalDataCount
or the data.length
.
As @louise-davies mentioned this is a bug and once this issue has been fixed in the future we can provide the option to just provide this via pagination only. The custom view at the moment will need to pass in an array of all the data returned for the specific property (from the whole data and not just the paginated data on the page) otherwise the filtering for that property cannot be done.
A feature that needs to be implemented is filtering. At the moment querying for ISIS means that we cannot use the distinct option to get only the data we need, meaning all data is fetched when we need we need to know all the values possible for filtering options.
To get around this we can provide the option to not use a paginated fetch of the data (so not using the
offsetParams
to fetch data) and then just assume the view has passed in all the data available. As a result we do not fetch all the data again. This means we would just have to provide the option to slice data or query the API again to fetch data based on offsetParams. A check maybe required before doing the slice (so thestopIndex
is not assumed to be greater than the actual data length) and make sure the count we use is depending on if fetching data via pagination has been flagged so we can choose whether to usetotalDataCount
or thedata.length
.As @louise-davies mentioned this is a bug and once this issue has been fixed in the future we can provide the option to just provide this via pagination only. The custom view at the moment will need to pass in an array of all the data returned for the specific property (from the whole data and not just the paginated data on the page) otherwise the filtering for that property cannot be done.
Allowed both options in https://github.com/ral-facilities/datagateway/commit/c89ee8ed3edc9ae92a6f0aebba3d5e4732ce070a. We now need to provide filtering methods to put data in the state to get filtering information.
Once the card view has been implemented, the main components need to be moved into datagateway-common
.
card
and cardView
into datagateway-common
.I have removed the counting of the filtering options in https://github.com/ral-facilities/datagateway/commit/b212c35fa8683634c51c4f0c73c464763c471801. This is due to the fact that the API currently does not support fetching a single property for all data. Without this, we will have to fetch all data and then we would not require pagination. If this is added then we can add back in the count which is similar to what is mocked up by PanOSC.
An issue has been created to track this feature (#265) so it can be added in the future.
Mentioned by @louise-davies, there are already actions which allow for filtering i.e. filterTable
which adds a value to the existing Filter
object in state. We will need to add support for string and number arrays so that multiple items can be added to support filtering (using in
for where
in the API query).
The following needs to be done in order to adjust filtering to work using the existing state:
[x] add string/number array handling for Filter
and handle that in getApiFilter
,
[x] adjust loadURLQuery
and getURLQuery
to parse and create queries based on the filter
in state instead of the query.filters
,
[x] ~rename filterTable
to filterData
as it will support card view as well as the table~,
[x] all card view components need to fetch count whenever the filter is updated (fetching count triggers the data to be loaded again - we need to prevent this from fetching data/count twice).
A feature that needs to be implemented is filtering. At the moment querying for ISIS means that we cannot use the distinct option to get only the data we need, meaning all data is fetched when we need we need to know all the values possible for filtering options.
To get around this we can provide the option to not use a paginated fetch of the data (so not using the
offsetParams
to fetch data) and then just assume the view has passed in all the data available. As a result we do not fetch all the data again. This means we would just have to provide the option to slice data or query the API again to fetch data based on offsetParams. A check maybe required before doing the slice (so thestopIndex
is not assumed to be greater than the actual data length) and make sure the count we use is depending on if fetching data via pagination has been flagged so we can choose whether to usetotalDataCount
or thedata.length
.As @louise-davies mentioned this is a bug and once this issue has been fixed in the future we can provide the option to just provide this via pagination only. The custom view at the moment will need to pass in an array of all the data returned for the specific property (from the whole data and not just the paginated data on the page) otherwise the filtering for that property cannot be done.
As an update to this whilst discussing with @louise-davies, in the future, the distinct
filter will be working for ISIS endpoints and also the issue relating to fetching data with a nested properties this means we can use the distinct filter for getting filters like INVESTIGATIONINSTRUMENT.INSTRUMENT.NAME
and then pagination will work for fetching data with nested properties with where
.
At the moment the code to do fetching without pagination will be removed and there will be no filtering on the ISIS tables.
There is an active issue regarding having a feature for showing the count of the specific filter options. Previously this was demonstrated by fetching the distinct filters and then counting via client-side (for a lot of data this may not be feasible).
Add the following filters to DLS (DIAMOND) pages:
We need to ensure that filters and sorts queries are supported by all the table components:
[x] ensure that the filters query works with table,
[x] ensure that sorts query parameter is supported by table.
Tables now support filters and sorts, although switching between views keeps the same data and does not clear the data appropriately.
There is now a requirement for an advanced search which allows the user to specifically filter the information on the cards (similar to the table view) e.g. TITLE
, DESCRIPTION
, any of the further information (including dates). This can be provided through smaller text boxes which allows for date selection as well.
dataKey
provided on the cards (allow these to be added to the filter object in state when contents of these search boxes are altered - similar to table text/date filters),Following a code review of this branch, a couple of features and issues were noted:
[x] make the navigation bar (breadcrumbs and results) sticky, so that scrolling down on the card view will still show it (mentioned by @tswinb),
[x] important: cards per page randomly disappeared after clearing a filter (possibly related to issue where pagination is not up to date - this issue should not occur now since the maximum number of pages for pagination is set on an update of totalDataCount
),
[x] ~investigate whether having an independent cards scroll from the page scroll is desirable (mentioned by @tswinb) (cards are already in a List
- maybe this can be made scrollable?)~ This can be added later if needed, currently has sticky navbar,
[x] extract out components of CardView
to decouple it from the state e.g. advanced search, filters panel to simplify it (mentioned by @louise-davies).
We also need to add in forward support for search and sort queries (for when they are implemented):
CardViewDetails
(disableSort
),Add tests for the following:
[x] Entity card tests (needs description collapsed test),
[x] Card view tests,
[x] Generic card view tests,
[x] ISIS card view tests,
[x] DLS card view tests.
An issue found is that after applying a custom filter the pagination component does not re-render with new values. This leads to the possibility that you can click on a page number which is incorrect and the card view would not show any data.
Add icons support in line with the suggested UI improvements. Icons won't be added to title and description but will be added to the information area:
An issue that is still persistent is that data is fetched twice from the API (due to the count updating later on?). So for all count requests we get the data being fetched twice:
Looking at Redux we can see that clearData
gets called twice and fetch data is called again. Most likely due to a state update meaning useEffects are run again and the parameters still allow for another request to be made (check loadedData
?).
Add icons support in line with the suggested UI improvements. Icons won't be added to title and description but will be added to the information area:
- [x] important: icons are supported on information in card via the card view.
Icons can be changed, if required, after a sprint review.
An initial data fetch with a max results query parameter results in the limit being calculated as -1 and therefore the data request fails.
An issue that is still persistent is that data is fetched twice from the API (due to the count updating later on?). So for all count requests we get the data being fetched twice:
- [ ] important: data gets fetched twice after a count request; we only want one count and one data request (with all changes in sort/filters/custom filters/max results).
Looking at Redux we can see that
clearData
gets called twice and fetch data is called again. Most likely due to a state update meaning useEffects are run again and the parameters still allow for another request to be made (checkloadedData
?).
Furthermore if we are navigating from a card view which already had a loaded count, then the previously used count is also fetched twice:
An initial data fetch with a max results query parameter results in the limit being calculated as -1 and therefore the data request fails.
- [x] important: Initial data fetch does not occur with a limit of -1.
The num pages and start/stop index was strictly checking for -1, this has been changed to only fetch data for greater values.
An issue that is still persistent is that data is fetched twice from the API (due to the count updating later on?). So for all count requests we get the data being fetched twice:
- [ ] important: data gets fetched twice after a count request; we only want one count and one data request (with all changes in sort/filters/custom filters/max results).
Looking at Redux we can see that
clearData
gets called twice and fetch data is called again. Most likely due to a state update meaning useEffects are run again and the parameters still allow for another request to be made (checkloadedData
?).
This seems like it is still an issue within the CardView component. This should be investigated and we need to ensure that the CardView component does not produce duplicate requests.
An issue that is still persistent is that data is fetched twice from the API (due to the count updating later on?). So for all count requests we get the data being fetched twice:
- [ ] important: data gets fetched twice after a count request; we only want one count and one data request (with all changes in sort/filters/custom filters/max results).
Looking at Redux we can see that
clearData
gets called twice and fetch data is called again. Most likely due to a state update meaning useEffects are run again and the parameters still allow for another request to be made (checkloadedData
?).Furthermore if we are navigating from a card view which already had a loaded count, then the previously used count is also fetched twice:
- [x] important: navigating between card views does not re-issue a count request from the previous card view (this is because it is still in state?)
This no longer seems to be an issue and I do not see duplicate count requests.
An issue that is still persistent is that data is fetched twice from the API (due to the count updating later on?). So for all count requests we get the data being fetched twice:
- [ ] important: data gets fetched twice after a count request; we only want one count and one data request (with all changes in sort/filters/custom filters/max results).
Looking at Redux we can see that
clearData
gets called twice and fetch data is called again. Most likely due to a state update meaning useEffects are run again and the parameters still allow for another request to be made (checkloadedData
?).This seems like it is still an issue within the CardView component. This should be investigated and we need to ensure that the CardView component does not produce duplicate requests.
If this issue still exists, then it should hopefully be fixed through the refactor of using react-query for table and card views in #701.
Create a component to visualise different entities in a grid/card view. This component will be in the
datagateway-dataview
package.This card view needs to be paginated.
We will customise it for specific entities such as investigations and datasets (and there will be separate issues for those).
This relates to https://github.com/ral-facilities/datagateway-userstories/issues/110
Acceptance criteria