Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpacker migration #3320

Merged
merged 24 commits into from
Feb 26, 2024
Merged

Webpacker migration #3320

merged 24 commits into from
Feb 26, 2024

Conversation

murny
Copy link
Contributor

@murny murny commented Dec 25, 2023

Context

Webpacker is deprecated/end of life now and has been a source of many CVEs for this project. This PR will migrate our JS assets to Esbuild (via jsbundling) and css/image assets back to sprockets (+ cssbundling).

This is more aligned with the recommended approach from Rails. (e.g if you generate a new Rails 7 application most likely you would use esbuild or importmaps)

Did a bunch of testing on various screens and trying all our custom JS etc and no issues.

This diff is very large, but most of it is deletion of files and package/gem lock diffs.

@murny murny changed the base branch from master to Rails-7-upgrade December 25, 2023 07:52
Copy link

github-actions bot commented Dec 25, 2023

1 Warning
⚠️ This PR is too big! Consider breaking it down into smaller PRs.

Generated by 🚫 Danger

Base automatically changed from Rails-7-upgrade to master January 17, 2024 22:23
@murny murny marked this pull request as ready for review January 26, 2024 23:11
app/javascript/application.js Outdated Show resolved Hide resolved
package.json Show resolved Hide resolved
Copy link
Contributor

@ConnorSheremeta ConnorSheremeta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a couple comments and questions.

Can/should these be removed? (references in nginx.conf and .gitignore)

location ^~ /packs/ {
,
/public/packs
,
/public/packs-test

@@ -4,36 +4,32 @@
"private": true,
"scripts": {
"lint": "eslint --ext .js app/javascript",
"lint-css": "stylelint \"app/javascript/**/*.scss\""
"lint-css": "stylelint \"app/assets/stylesheets/**/*.scss\"",
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=/assets",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am getting these warnings:

WARN -- : Removed sourceMappingURL comment for missing asset '/assets/admin.js.map' from /app/app/assets/builds/admin.js
WARN -- : Removed sourceMappingURL comment for missing asset '/assets/application.js.map' from /app/app/assets/builds/application.js

Which go away when omitting the --public-path=/assets flag. I believe this is an issue upstream however which should be resolved here: rails/sprockets-rails#515

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. From reading those issues, sounds like we want --public-path=/asset as this allows static assets like images to be loaded from JS (see here rails/jsbundling-rails#58)

So I rather break sourcemaps (which is for debugging) a bit over breaking this serving static assets from JS? Looks like it got fixed in propshaft, so hopefully theirs a fix for this in the future.

Gemfile Show resolved Hide resolved
.github/workflows/push.yml Show resolved Hide resolved
Copy link

@accesslint accesslint bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are accessibility issues in these changes.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

Copy link

@accesslint accesslint bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are accessibility issues in these changes.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

proxy_pass http://jupiter;

# limit_req zone=one;
access_log /var/log/nginx.access.log;
error_log /var/log/nginx.error.log;
}

location ^~ /packs/ {
location ~ ^/assets/ {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@murny
Copy link
Contributor Author

murny commented Feb 10, 2024

K think I updated and answered everything from feedback. Thanks for the through review, Connor 🙏.

Copy link

@accesslint accesslint bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are accessibility issues in these changes.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

Copy link
Contributor

@ConnorSheremeta ConnorSheremeta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link

@accesslint accesslint bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are accessibility issues in these changes.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

{
"version": 3,
"sources": ["../../javascript/src/admin/ajax_table.js", "../../javascript/src/admin/new_batch_ingest.js"],
"sourcesContent": ["document.addEventListener('turbolinks:load', () => {\n function renderNewTable() {\n const $form = $(this).closest('form');\n let action = $form.attr('action');\n if (!action) {\n action = window.location.href;\n }\n $.get(action, $form.serialize(), null, 'script');\n return false;\n }\n\n function ajaxLink() {\n $.getScript(this.href);\n return false;\n }\n // Fetch new table for autocomplete and filter widgets\n $('.js-autocomplete select').change(renderNewTable);\n\n // TODO: Could be improved. Should maybe bring in a `debounce` function for this search\n $('.js-autocomplete input').keyup(renderNewTable);\n\n // Sorting and pagination links\n $('#js-ajax-table').on('click', ' th a.sort_link, .pagination a', ajaxLink);\n});\n", "/* eslint-disable no-undef */\n\nfunction addFileInput(id, name) {\n if (\n $('.js-batch-ingest-files-list').find(`input[value='${id}']`).length === 0\n ) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[batch_ingest_files_attributes][][google_file_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-files-list').append(input);\n }\n}\n\nfunction addSpreadsheetInput(id, name) {\n const input = `<li class=\"list-group-item d-flex justify-content-between\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_name]\" value=\"${name}\">\n <input type=\"hidden\" name=\"batch_ingest[google_spreadsheet_id]\" value=\"${id}\">\n ${name}\n <button type=\"button\" class=\"btn btn-danger btn-sm js-btn-delete-file\">\n <i class=\"fa fa-trash-alt\" aria-hidden=\"true\"></i> Delete\n </button>\n </li>`;\n\n $('.js-batch-ingest-spreadsheet').append(input);\n $('.js-btn-spreadsheet').addClass('d-none');\n}\n\nfunction deleteFileFromFilesList() {\n $(this).closest('li').remove();\n}\n\nfunction deleteSpreadsheet() {\n $(this).closest('li').remove();\n $('.js-btn-spreadsheet').removeClass('d-none');\n}\n\nfunction pickerFilesCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n data.docs.forEach((doc) => {\n addFileInput(doc.id, doc.name);\n });\n }\n}\n\nfunction pickerSpreadsheetCallback(data) {\n if (data.action === google.picker.Action.PICKED) {\n addSpreadsheetInput(data.docs[0].id, data.docs[0].name);\n }\n}\n\nfunction createFilesPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.DocsView(google.picker.ViewId.DOCS);\n view.setMimeTypes(\n 'application/epub+zip,'\n + 'application/excel,'\n + 'application/gzip,'\n + 'application/json,'\n + 'application/mp4,'\n + 'application/msword,'\n + 'application/octet-stream,'\n + 'application/pdf,'\n + 'application/postscript,'\n + 'application/rtf,'\n + 'application/sql,'\n + 'application/vnd.android.package-archive,'\n + 'application/vnd.ms-access,'\n + 'application/vnd.ms-asf,'\n + 'application/vnd.ms-excel,'\n + 'application/vnd.ms-excel.sheet.binary.macroenabled.12,'\n + 'application/vnd.ms-excel.sheet.macroenabled.12,'\n + 'application/vnd.ms-powerpoint,'\n + 'application/vnd.oasis.opendocument.text,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.presentation,'\n + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow,'\n + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document,'\n + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template,'\n + 'application/x-7z-compressed,'\n + 'application/x-bibtex,'\n + 'application/x-bibtex-text-file,'\n + 'application/x-ole-storage,'\n + 'application/x-rar,'\n + 'application/x-rar-compressed,'\n + 'application/x-spss-sav,'\n + 'application/x-tar,'\n + 'application/x-xz,'\n + 'application/x-zip-compressed,'\n + 'application/xml,'\n + 'application/zip,'\n + 'audio/mp4,'\n + 'audio/mpeg,'\n + 'audio/vnd.wave,'\n + 'audio/wav,'\n + 'audio/x-m4a,'\n + 'audio/x-mpegurl,'\n + 'audio/x-ms-asx,'\n + 'audio/x-ms-wma,'\n + 'audio/x-ms-wmv,'\n + 'audio/x-wav,'\n + 'audio/x-wave,'\n + 'image/gif,'\n + 'image/jpeg,'\n + 'image/png,'\n + 'image/svg+xml,'\n + 'image/tiff,'\n + 'inode/x-empty,'\n + 'message/rfc822,'\n + 'text/comma-separated-values,'\n + 'text/csv,'\n + 'text/html,'\n + 'text/plain,'\n + 'text/rtf,'\n + 'text/x-bibtex,'\n + 'text/x-csrc,'\n + 'text/x-matlab,'\n + 'text/x-objcsrc,'\n + 'text/x-r-source,'\n + 'text/x-r-sweave,'\n + 'video/mp4,'\n + 'video/mpeg,'\n + 'video/quicktime,'\n + 'video/x-flv,'\n + 'video/x-m4v,'\n + 'video/x-ms-wmv,'\n + 'video/x-msvideo',\n );\n view.setIncludeFolders(true);\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a file(s)')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .enableFeature(google.picker.Feature.MULTISELECT_ENABLED)\n .enableFeature(google.picker.Feature.SUPPORT_DRIVES)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerFilesCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction createSpreadsheetPicker() {\n const { developerKey, accessToken } = this.dataset;\n\n if (accessToken && developerKey) {\n const view = new google.picker.View(google.picker.ViewId.SPREADSHEETS);\n view.setMimeTypes('application/vnd.google-apps.spreadsheet');\n view.setParent('root');\n\n const picker = new google.picker.PickerBuilder()\n .setTitle('Select a spreadsheet')\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setOAuthToken(accessToken)\n .addView(view)\n .setDeveloperKey(developerKey)\n .setCallback(pickerSpreadsheetCallback)\n .build();\n picker.setVisible(true);\n }\n}\n\nfunction registerClickEvents() {\n document\n .querySelector('.js-btn-spreadsheet')\n .addEventListener('click', createSpreadsheetPicker);\n document\n .querySelector('.js-btn-files')\n .addEventListener('click', createFilesPicker);\n}\n\nfunction loadAndInitGAPI() {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.src = 'https://apis.google.com/js/api.js';\n script.onload = (e) => {\n window.gapi.load('picker', { callback: registerClickEvents });\n };\n document.getElementsByTagName('head')[0].appendChild(script);\n });\n}\n\ndocument.addEventListener('turbolinks:load', () => {\n if (document.querySelector('.js-batch-ingest-spreadsheet')) {\n loadAndInitGAPI();\n $('.js-batch-ingest-spreadsheet').on(\n 'click',\n '.js-btn-delete-file',\n deleteSpreadsheet,\n );\n $('.js-batch-ingest-files-list').on(\n 'click',\n '.js-btn-delete-file',\n deleteFileFromFilesList,\n );\n }\n});\n"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this element is missing an accessible name or label. That makes it hard for people using screen readers or voice control to use the control.

Copy link
Contributor

@ConnorSheremeta ConnorSheremeta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@murny
Copy link
Contributor Author

murny commented Feb 24, 2024

Manually tested this some more today, precompile the assets as if it was production as well, and think this is ready to go now. Just need a re-approval.

@murny murny merged commit 4535b6e into master Feb 26, 2024
4 checks passed
@murny murny deleted the webpacker-migration branch February 26, 2024 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants