From f655b6ac19ed9e0f780e9f81050d0493bf269c3d Mon Sep 17 00:00:00 2001 From: Michael Ritter Date: Fri, 18 Oct 2024 14:41:56 -0600 Subject: [PATCH 1/3] Change package version to 10.0.0-rc.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57c2a574..db1297c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cspace-ui", - "version": "10.0.0-dev", + "version": "10.0.0-rc.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cspace-ui", - "version": "10.0.0-dev", + "version": "10.0.0-rc.1", "license": "ECL-2.0", "dependencies": { "classnames": "^2.2.5", diff --git a/package.json b/package.json index 4c9d436e..dd406d31 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cspace-ui", - "version": "10.0.0-dev", + "version": "10.0.0-rc.1", "description": "CollectionSpace user interface for browsers", "author": "Ray Lee ", "license": "ECL-2.0", From fc96c85a3669c2d54219f2c0ef724b15f1bc7fe4 Mon Sep 17 00:00:00 2001 From: Michael Ritter Date: Fri, 25 Oct 2024 20:39:02 -0600 Subject: [PATCH 2/3] Set row aria-label for search results (#241) --- src/components/search/SearchResultTable.jsx | 95 ++++++++++++++----- .../search/SearchResultTable.spec.jsx | 29 +++++- 2 files changed, 99 insertions(+), 25 deletions(-) diff --git a/src/components/search/SearchResultTable.jsx b/src/components/search/SearchResultTable.jsx index de8fdc72..6f840cfc 100644 --- a/src/components/search/SearchResultTable.jsx +++ b/src/components/search/SearchResultTable.jsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Immutable from 'immutable'; -import { defineMessages, FormattedMessage } from 'react-intl'; +import { defineMessages, intlShape, FormattedMessage } from 'react-intl'; import { Link } from 'react-router-dom'; import get from 'lodash/get'; import { Table } from 'cspace-layout'; @@ -16,6 +16,11 @@ const messages = defineMessages({ id: 'searchResultTable.searchPending', defaultMessage: '⋯', }, + rowLabel: { + id: 'searchResultTable.rowLabel', + description: 'The aria-label for a row', + defaultMessage: '{primary} selected row {index} of {total}', + }, }); /** @@ -31,7 +36,7 @@ const isSortable = (column, searchDescriptor) => { return (sortBy && (!searchDescriptor.getIn(['searchQuery', 'rel']) || sortBy.indexOf('/0/') === -1)); }; -const rowRenderer = (params, location) => { +const rowRenderer = (params, location, ariaLabel) => { // This is a fork of react-virtualized's default row renderer: // https://github.com/bvaughn/react-virtualized/blob/master/source/Table/defaultRowRenderer.js @@ -58,7 +63,7 @@ const rowRenderer = (params, location) => { // onRowMouseOver || // onRowRightClick ) { - a11yProps['aria-label'] = 'row'; + a11yProps['aria-label'] = ariaLabel; a11yProps.tabIndex = 0; if (onRowClick) { @@ -122,6 +127,7 @@ const propTypes = { }).isRequired, formatCellData: PropTypes.func, formatColumnLabel: PropTypes.func, + intl: intlShape, isSearchPending: PropTypes.bool, linkItems: PropTypes.bool, // eslint-disable-next-line react/forbid-prop-types @@ -156,11 +162,13 @@ export default class SearchResultTable extends Component { constructor() { super(); + this.getColumnConfig = this.getColumnConfig.bind(this); this.getItemLocation = this.getItemLocation.bind(this); this.handleKeyDown = this.handleKeyDown.bind(this); this.handleRowClick = this.handleRowClick.bind(this); this.renderNoItems = this.renderNoItems.bind(this); this.renderRow = this.renderRow.bind(this); + this.renderRowLabel = this.renderRowLabel.bind(this); this.sort = this.sort.bind(this); } @@ -193,6 +201,35 @@ export default class SearchResultTable extends Component { } } + getColumnConfig() { + const { + columnSetName, + config, + searchDescriptor, + } = this.props; + + const recordType = searchDescriptor.get('recordType'); + const subresource = searchDescriptor.get('subresource'); + + const columnConfigurer = subresource + ? config.subresources[subresource] + : config.recordTypes[recordType]; + + let columnConfig = get(columnConfigurer, ['columns', columnSetName]); + + if (!columnConfig && columnSetName !== defaultProps.columnSetName) { + // Fall back to the default column set if the named one doesn't exist. + + columnConfig = get(columnConfigurer, ['columns', defaultProps.columnSetName]); + } + + if (!columnConfig) { + columnConfig = []; + } + + return columnConfig; + } + getItemLocation(item) { const { config, @@ -253,7 +290,31 @@ export default class SearchResultTable extends Component { return
{message}
; } - renderRow(params) { + renderRowLabel(params, totalItems) { + const { + intl, + } = this.props; + + const { + index, + rowData, + } = params; + + const columnConfig = this.getColumnConfig(); + const primaryCol = Object.keys(columnConfig) + .filter((col) => col !== 'workflowState') + .at(0); + + const primaryData = rowData.get(primaryCol); + const label = primaryData + ? intl.formatMessage(messages.rowLabel, + { primary: primaryData, index: index + 1, total: totalItems }) + : 'row'; + + return label; + } + + renderRow(params, totalItems) { const { getItemLocation, linkItems, @@ -271,12 +332,13 @@ export default class SearchResultTable extends Component { location = locationGetter(rowData); } - return rowRenderer(params, location); + const ariaLabel = this.renderRowLabel(params, totalItems); + + return rowRenderer(params, location, ariaLabel); } renderTable() { const { - columnSetName, config, formatCellData, formatColumnLabel, @@ -288,8 +350,6 @@ export default class SearchResultTable extends Component { } = this.props; if (searchResult) { - const recordType = searchDescriptor.get('recordType'); - const subresource = searchDescriptor.get('subresource'); const searchQuery = searchDescriptor.get('searchQuery'); const listTypeConfig = config.listTypes[listType]; @@ -320,21 +380,7 @@ export default class SearchResultTable extends Component { items = Immutable.List.of(items); } - const columnConfigurer = subresource - ? config.subresources[subresource] - : config.recordTypes[recordType]; - - let columnConfig = get(columnConfigurer, ['columns', columnSetName]); - - if (!columnConfig && columnSetName !== defaultProps.columnSetName) { - // Fall back to the default column set if the named one doesn't exist. - - columnConfig = get(columnConfigurer, ['columns', defaultProps.columnSetName]); - } - - if (!columnConfig) { - columnConfig = []; - } + const columnConfig = this.getColumnConfig(); const columns = Object.keys(columnConfig) .filter((name) => !columnConfig[name].disabled) @@ -402,6 +448,7 @@ export default class SearchResultTable extends Component { } const height = (heightBasis * rowHeight) + rowHeight; + const renderRowWithTotal = (params) => this.renderRow(params, totalItems); return (
@@ -416,7 +463,7 @@ export default class SearchResultTable extends Component { sortBy={sortColumnName} sortDirection={sortDir === 'desc' ? Table.SortDirection.DESC : Table.SortDirection.ASC} noRowsRenderer={this.renderNoItems} - rowRenderer={this.renderRow} + rowRenderer={renderRowWithTotal} />
); diff --git a/test/specs/components/search/SearchResultTable.spec.jsx b/test/specs/components/search/SearchResultTable.spec.jsx index 7f375361..693df9d1 100644 --- a/test/specs/components/search/SearchResultTable.spec.jsx +++ b/test/specs/components/search/SearchResultTable.spec.jsx @@ -145,6 +145,10 @@ const searchResult = Immutable.fromJS({ }, }); +const intl = { + formatMessage: (message) => `formatted ${message.id}`, +}; + describe('SearchResultTable', () => { beforeEach(function before() { this.container = createTestContainer(this); @@ -153,7 +157,10 @@ describe('SearchResultTable', () => { it('should render as a div', function test() { render( - + , this.container, ); @@ -166,6 +173,7 @@ describe('SearchResultTable', () => { @@ -183,6 +191,7 @@ describe('SearchResultTable', () => { @@ -200,6 +209,7 @@ describe('SearchResultTable', () => { @@ -216,6 +226,7 @@ describe('SearchResultTable', () => { @@ -230,6 +241,7 @@ describe('SearchResultTable', () => { @@ -244,6 +256,7 @@ describe('SearchResultTable', () => { { { { @@ -322,6 +338,7 @@ describe('SearchResultTable', () => { { render( { render( { render( { render( { render( { render( { render( { render( { render( { Date: Tue, 29 Oct 2024 12:38:31 -0600 Subject: [PATCH 3/3] Change package version to 10.0.0-rc.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index db1297c8..a375bf6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cspace-ui", - "version": "10.0.0-rc.1", + "version": "10.0.0-rc.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cspace-ui", - "version": "10.0.0-rc.1", + "version": "10.0.0-rc.2", "license": "ECL-2.0", "dependencies": { "classnames": "^2.2.5", diff --git a/package.json b/package.json index dd406d31..73f4aa4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cspace-ui", - "version": "10.0.0-rc.1", + "version": "10.0.0-rc.2", "description": "CollectionSpace user interface for browsers", "author": "Ray Lee ", "license": "ECL-2.0",