# Work required for Data Preview and Accessibility compliance
This is tested with the `webassets` branch of the [ckanext-dataexplorer-react extension](https://github.com/datopian/ckanext-dataexplorer-react/tree/webassets)
## Task List
* [ ] [Fix xloader push issue](#Xloader-Push-Issue)
* [ ] [Add views and datastore to UI](#Datastore-and-views-tab)
* [ ] [Fix UI issues to get the data preview working](#UI-Issues-to-get-data-preview-working) - (A fix has been added for this in this note)
* [ ] [Work on accessibility compliance](#Accessibility-Compliance)
* [ ] Write any required tests
## Accessibility Compliance
For a quick test for accessibility compliance, these chrome extensions can be installed:
* **[Axe Devtools - Web accessibility testing](https://chrome.google.com/webstore/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd)**
* **[WCAG color contrast checker](https://chrome.google.com/webstore/detail/wcag-color-contrast-check/plnahcmalebffmaghcpcmpaciebdhgdf)**
Using the Axe Devtools, **13** issues were uncovered:

By using the tool, full details on this can be seen and how to fix them
The [WCAG Checklist](https://webaim.org/standards/wcag/checklist) can also be used for a more detailed list of the requirements.
Here's a link to a meeting recording with more details: https://drive.google.com/file/d/1Jc39eSC8H-MnKBJqkT9Xd1DLqaOoQe2v/view?usp=drive_web
## Xloader Push Issue
When trying to use xloader to push to datastore, it gets stuck in pending, this issue also affects the testing instance: https://us-ed-testing.ckan.io/dataset/new-profile-2-9-1/resource_data/7154f2c8-15c3-4675-bbbf-edeafc8bc165. This would need to be fixed to get the data preview working.
Using datapusher works fine and xloader also works with a base ckan instance so the issue is probably from the xloader setup or the ed extension.
## Datastore and views tab
The [datastore](https://us-ed-testing.ckan.io/dataset/new-profile-2-9-1/resource_data/7154f2c8-15c3-4675-bbbf-edeafc8bc165) and the [views](https://us-ed-testing.ckan.io/dataset/new-profile-2-9-1/resource/7154f2c8-15c3-4675-bbbf-edeafc8bc165/views) tab would need to be added back to the resource UI. Currently, we have to enter their urls directly to be able to get to those pages.
## UI Issues to get data preview working
There are some errors preventing the data preview from being rendered, probably leftovers from the ckan 2.9 upgrade.
The issues were in 3 files:
- ckanext-ed/ckanext/ed/templates/package/snippets/resource_read.html - [Fix](#resource_readhtml)
- ckanext-ed/ckanext/ed/templates/package/snippets/resource_view.html - [Fix](#resource_viewhtml)
- ckanext-ed/ckanext/ed/templates/package/snippets/resource_views_list.html - [Fix](#resource_views_listhtml)
Replacing the files with these fixes the errors:
### resource_views_list.html
```html=
{% set views_created = views or resource_preview %}
{% if views_created %}
<ul class="nav {{ extra_class }}" {{ extra_attributes }}>
{% if resource_preview %}
<li{% if not view_id %} class="active"{% endif %}>
<a href="{{ h.url_for(controller='package', action='resource_read', id=pkg.name, resource_id=resource.id) }}" >
<i class="fa icon fa-eye-open"></i>
{{ _("Resource Preview") }}
</a>
</li>
{% endif %}
{% if request.args %}
{% set current_filters = request.args.get('filters') %}
{% else %}
{% set current_filters = request.str_GET.get('filters') %}
{% endif %}
{% for view in views %}
{% set is_selected = true if view_id == view.id else false %}
{% snippet "package/snippets/resource_views_list_item.html",
view=view,
pkg=pkg,
is_edit=is_edit,
is_selected=is_selected,
current_filters=current_filters
%}
{% endfor %}
</ul>
{% endif %}
```
### resource_view.html
```html=
{% import 'macros/form.html' as form %}
{% block resource_view %}
<div id="view-{{ resource_view['id'] }}" class="resource-view" data-id="{{ resource_view['id'] }}" data-title="{{ resource_view['title'] }}" data-description="{{ resource_view['descripion'] }}">
<div class="actions">
<a class="btn btn-default"
target="_blank"
href="{{ h.url_for('resource_view', id=package['name'], resource_id=resource['id'], view_id=resource_view['id'], qualified=True) }}">
<i class="fa fa-arrows-alt"></i>
{{ _("Fullscreen") }}
</a>
<a class="btn btn-default"
href="#embed-{{ resource_view['id'] }}"
data-module="resource-view-embed"
data-module-id="{{ resource_view['id'] }}"
data-module-url="{{ h.url_for('resource_view', id=package['name'], resource_id=resource['id'], view_id=resource_view['id'], qualified=True) }}">
<i class="fa fa-code"></i>
{{ _("Embed") }}
</a>
</div>
<p class="desc">{{ h.render_markdown(resource_view['description']) }}</p>
<div class="m-top ckanext-datapreview">
{% if not to_preview and h.resource_view_is_filterable(resource_view) %}
{% snippet 'package/snippets/resource_view_filters.html', resource=resource %}
{% endif %}
{% if not h.resource_view_is_iframed(resource_view) %}
{{ h.rendered_resource_view(resource_view, resource, package) }}
{% else %}
<div class="data-viewer-error js-hide">
<p class="text-danger">
<i class="fa fa-info-circle"></i>
{{ _('This resource view is not available at the moment.') }}
<a href="#" data-toggle="collapse" data-target="#data-view-error">
{{ _('Click here for more information.') }}
</a>
</p>
<p id="data-view-error" class="collapse"></p>
<p>
<a href="{{ resource.url }}" class="btn btn-default btn-lg resource-url-analytics" target="_blank">
<i class="fa fa-lg fa-arrow-circle-o-down"></i>
{{ _('Download resource') }}
</a>
</p>
</div>
{% if not to_preview %}
{% if request.args %}
{% set current_filters = request.args.get('filters') %}
{% else %}
{% set current_filters = request.str_GET.get('filters') %}
{% endif %}
{% if current_filters %}
{% set src = h.url_for(package['type'] ~ '_resource.view', id=package['name'],
resource_id=resource['id'],
view_id=resource_view['id'],
filters=current_filters, qualified=true) %}
{% else %}
{% set src = h.url_for(package['type'] ~ '_resource.view', id=package['name'],
resource_id=resource['id'],
view_id=resource_view['id'], qualified=true) %}
{% endif %}
{% else %}
{# When previewing we need to stick the whole resource_view as a param as there is no other way to pass to information on to the iframe #}
{% set src = h.url_for(package['type'] ~ '_resource.view', id=package['name'], resource_id=resource['id'], qualified=true) + '?' + h.urlencode({'resource_view': h.dump_json(resource_view)}) %}
{% endif %}
<iframe src="{{ src }}" frameborder="0" width="100%" data-module="data-viewer">
<p>{{ _('Your browser does not support iframes.') }}</p>
</iframe>
{% endif %}
</div>
<div id="embed-{{ resource_view['id'] }}" class="modal fade resource-view-embed">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h3 class="modal-title">{{ _("Embed resource view") }}</h3>
</div>
<div class="modal-body">
<p class="embed-content">{{ _("You can copy and paste the embed code into a CMS or blog software that supports raw HTML") }}</p>
<div class="row">
<div class="col-md-6">
{{ form.input("width", label=_("Width"), value=700, classes=["control-full"]) }}
</div>
<div class="col-md-6">
{{ form.input("height", label=_("Height"), value=400, classes=["control-full"]) }}
</div>
</div>
{{ form.textarea("code", label=_("Code"), value="", classes=["pre"], rows=3) }}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
```
### resource_read.html
```html=
{% set res = c.resource %}
{% block pre_primary %}
{% block resource %}
<section class="module module-resource">
{% block resource_inner %}
<div class="module-content">
{% set max_chars = 330 %}
{% set description_rendered = h.render_markdown(res.description) %}
{% if res.description|length < max_chars %}
<div class="text-justify">
{{ description_rendered | safe }}
</div>
{% else %}
<div class="text-justify collapse multi-collapse in" id="allDescription">
{{ description_rendered }}
<a data-toggle="collapse" href=".multi-collapse"
aria-controls="smallDescription allDescription">Hide</a>
</div>
<div class="text-justify collapse multi-collapse" id="smallDescription">
{{ description_rendered | safe | truncate(max_chars) }}
<a data-toggle="collapse" href=".multi-collapse"
aria-controls="smallDescription allDescription">Show more</a>
</div>
{% endif %}
{% block data_preview %}
{% block resource_view %}
{% block resource_view_nav %}
{% set resource_preview = h.resource_preview(c.resource, c.package) %}
{% snippet "package/snippets/resource_views_list.html",
views=resource_views,
pkg=pkg,
is_edit=false,
view_id=current_resource_view['id'],
resource_preview=resource_preview,
resource=c.resource,
extra_class="nav-tabs nav-tabs-plain"
%}
{% endblock %}
{% block resource_view_content %}
<div class="resource-view">
{% set resource_preview = h.resource_preview(c.resource, c.package) %}
{% set views_created = res.has_views or resource_preview %}
{% if views_created %}
{% if resource_preview and not current_resource_view %}
{{ h.resource_preview(c.resource, c.package) }}
{% else %}
{% for resource_view in resource_views %}
{% if resource_view == current_resource_view %}
{% snippet 'package/snippets/resource_view.html',
resource_view=resource_view,
resource=c.resource,
package=c.package
%}
{% endif %}
{% endfor %}
{% endif %}
{% else %}
{# Views not created #}
<div class="data-viewer-info">
<p>{{ _("There are no views created for this resource yet.") }}</p>
{% if h.check_access('resource_view_create', {'resource_id': c.resource.id}) %}
<p class="text-muted">
<i class="fa fa-info-circle"></i>
{{ _("Not seeing the views you were expecting?")}}
<a href="javascript:void(0);" data-toggle="collapse" data-target="#data-view-info">
{{ _('Click here for more information.') }}</a>
</p>
<div id="data-view-info" class="collapse">
<p>{{ _('Here are some reasons you may not be seeing expected views:') }}</p>
<ul>
<li>{{ _("No view has been created that is suitable for this resource")}}</li>
<li>{{ _("The site administrators may not have enabled the relevant view plugins")}}</li>
<li>{{ _("If a view requires the DataStore, the DataStore plugin may not be enabled, or the data may not have been pushed to the DataStore, or the DataStore hasn't finished processing the data yet")}}</li>
</ul>
</div>
{% endif %}
</div>
{% endif %}
</div>
{% endblock %}
</div>
{% endblock %}
{% endblock %}
{% endblock %}
</section>
{% endblock %}
{% endblock %}
{% block primary_content %}
{% block resource_additional_information %}
{% if res %}
<section class="module">
{% block resource_additional_information_inner %}
<div class="module-content">
<h2>{{ _('Additional Information') }}</h2>
<table class="usa-table usa-table--borderless" data-module="table-toggle-more">
<thead>
<tr>
<th scope="col">{{ _('Field') }}</th>
<th scope="col">{{ _('Value') }}</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ _('Data last updated') }}</th>
<td>{{ h.render_datetime(res.last_modified) or h.render_datetime(res.created) or _('unknown') }}</td>
</tr>
<tr>
<th scope="row">{{ _('Metadata last updated') }}</th>
<td>{{ h.render_datetime(res.revision_timestamp) or h.render_datetime(res.created) or _('unknown') }}</td>
</tr>
<tr>
<th scope="row">{{ _('Created') }}</th>
<td>{{ h.render_datetime(res.created) or _('unknown') }}</td>
</tr>
<tr>
<th scope="row">{{ _('Format') }}</th>
<td>{{ res.mimetype_inner or res.mimetype or res.format or _('unknown') }}</td>
</tr>
{% set source = h.get_resource_source(res.id) %}
{% if source and h.get_config_value('ckanext.ed.enable_ed_sources') %}
<tr><th scope="row">{{ _('Source') }}</th><td>
<a href="/ed_source/{{source[0]}}">{{ h.get_source_by_name(source[0]).title }}</a>
</td></tr>
{% endif %}
<tr>
<th scope="row">{{ _('License') }}</th>
<td>{% snippet "snippets/license.html", pkg_dict=pkg, text_only=True %}</td>
</tr>
{% if res.resource_set == "indirect" %}
<tr>
{% if res.access_url%}
<th scope="row">{{ _('Access URL') }}</th>
<td><p><a href="{{ res.access_url }}">{{ res.access_url }}</a></p>
</td>
{% else %}
<th scope="row">{{ _('API URL') }}</th>
<td><p><a href="{{ res.api_url }}">{{ res.api_url }}</a></p>
</td>
{% endif %}
</tr>
{% endif %}
{% set data_dictionary_url = res.data_dictionary_res %}
{% set data_dictionary_mimetype = '' %}
{% if data_dictionary_url %}
{% if 'http' not in data_dictionary_url %}
{% set file_url = '/uploads/data_dictionary/' + data_dictionary_url %}
{% else %}
{% set file_url = data_dictionary_url %}
{% endif %}
<tr><th scope="row">{{ _('Data Dictionary') }}</th><td><a href="{{ file_url }}">{{ res.data_dictionary_res }}</a></td></tr>
{% if res.data_dictionary_res_mimetype %}
<tr><th scope="row">{{ _('Data Dictionary Type') }}</th><td>{{ res.data_dictionary_res_mimetype }}</td></tr>
{% endif%}
{% if res.data_dictionary_res_format %}
<tr><th scope="row">{{ _('Data Dictionary Format') }}</th><td>{{ res.data_dictionary_res_format }}</td></tr>
{% endif%}
{% endif %}
{% set translated_from = h.get_translated_from(res) %}
{% if translated_from %}
<tr>
<th scope="row">{{ _('Translated From') }}</th>
<td>
<p><a href="{{ translated_from[1] }}"> {{ translated_from[0] }}</a></p>
</td>
</tr>
{% endif %}
{% set approval_status = res.approval_status %}
{% if approval_status %}
{% if h.ed_is_admin(c.user) or h.ed_is_editor(c.user) %}
<tr>
<th scope="row">{{ _('Status') }}</th>
<td>{{ approval_status }}</td>
</tr>
{% endif %}
{% endif %}
</tbody>
</table>
</div>
{% endblock %}
</section>
{% endif %}
{% endblock %}
{% endblock %}
```