diff --git a/CHANGELOG.md b/CHANGELOG.md index 655421c78..b04b608ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Layout of primary contributor flag. UIIN-503. * Settings pages for note types. UIIN-453. * Bug fixes: UIIN-568 +* Remove results display by default (no search queries or filters). UIIN-79 ## [1.8.0](https://github.com/folio-org/ui-inventory/tree/v1.8.0) (2019-05-10) [Full Changelog](https://github.com/folio-org/ui-inventory/compare/v1.7.0...v1.8.0) diff --git a/src/Instances.js b/src/Instances.js index 3721be6a0..8215cb94f 100644 --- a/src/Instances.js +++ b/src/Instances.js @@ -6,10 +6,13 @@ import { FormattedMessage } from 'react-intl'; import { stripesShape, IntlConsumer, + AppIcon, } from '@folio/stripes/core'; // eslint-disable-line import/no-unresolved -import { SearchAndSort } from '@folio/stripes/smart-components'; -import { filters2cql, onChangeFilter as commonChangeFilter } from '@folio/stripes/components'; -import { AppIcon } from '@folio/stripes-core'; +import { + SearchAndSort, + makeQueryFunction, +} from '@folio/stripes/smart-components'; +import { onChangeFilter as commonChangeFilter } from '@folio/stripes/components'; import packageInfo from '../package'; import InstanceForm from './edit/InstanceForm'; @@ -56,15 +59,15 @@ const filterConfig = [ ]; const searchableIndexes = [ - { label: 'All (title, contributor, identifier)', value: 'all', makeQuery: term => `(title="${term}" or contributors adj "\\"name\\": \\"${term}\\"" or identifiers adj "\\"value\\": \\"${term}\\"")` }, - { label: 'Barcode', value: 'item.barcode', makeQuery: term => `(item.barcode=="${term}")` }, - { label: 'Instance ID', value: 'id', makeQuery: term => `(id="${term}")` }, - { label: 'Title', value: 'title', makeQuery: term => `(title="${term}")` }, - { label: 'Identifier', value: 'identifier', makeQuery: term => `(identifiers adj "\\"value\\": \\"${term}\\"")` }, - { label: '- ISBN', value: 'isbn', makeQuery: (term, args) => `identifiers == "*\\"value\\": \\"${term}\\", \\"identifierTypeId\\": \\"${args.identifierTypeId}\\""` }, - { label: '- ISSN', value: 'issn', makeQuery: (term, args) => `identifiers == "*\\"value\\": \\"${term}\\", \\"identifierTypeId\\": \\"${args.identifierTypeId}\\""` }, - { label: 'Contributor', value: 'contributor', makeQuery: term => `(contributors adj "\\"name\\": \\"${term}\\"")` }, - { label: 'Subject', value: 'subject', makeQuery: term => `(subjects="${term}")` }, + { label: 'All (title, contributor, identifier)', value: 'all', queryTemplate: 'title="%{query.query}" or contributors adj "\\"name\\": \\"%{query.query}\\"" or identifiers adj "\\"value\\": \\"%{query.query}\\""' }, + { label: 'Barcode', value: 'item.barcode', queryTemplate: 'item.barcode=="%{query.query}"' }, + { label: 'Instance ID', value: 'id', queryTemplate: 'id="%{query.query}"' }, + { label: 'Title', value: 'title', queryTemplate: 'title="%{query.query}"' }, + { label: 'Identifier', value: 'identifier', queryTemplate: 'identifiers adj "\\"value\\": \\"%{query.query}\\""' }, + { label: '- ISBN', value: 'isbn', queryTemplate: 'identifiers == "*\\"value\\": \\"%{query.query}\\", \\"identifierTypeId\\": \\"<%= identifierTypeId %>\\""' }, + { label: '- ISSN', value: 'issn', queryTemplate: 'identifiers == "*\\"value\\": \\"%{query.query}\\", \\"identifierTypeId\\": \\"<%= identifierTypeId %>\\""' }, + { label: 'Contributor', value: 'contributor', queryTemplate: 'contributors adj "\\"name\\": \\"%{query.query}\\""' }, + { label: 'Subject', value: 'subject', queryTemplate: 'subjects="%{query.query}"' }, ]; class Instances extends React.Component { @@ -92,61 +95,39 @@ class Instances extends React.Component { GET: { params: { query: (...args) => { - /* - This code is not DRY as it is copied from makeQueryFunction in stripes-components. - This is necessary, as makeQueryFunction only references query parameters as a data source. - STRIPES-480 is intended to correct this and allow this query function to be replace with a call - to makeQueryFunction. - https://issues.folio.org/browse/STRIPES-480 - */ - const resourceData = args[2]; - const sortMap = { - Title: 'title', - publishers: 'publication', - Contributors: 'contributors', - }; - - const index = resourceData.query.qindex ? resourceData.query.qindex : 'all'; - const searchableIndex = searchableIndexes.find(idx => idx.value === index); - - let makeQueryArgs = {}; - if (index === 'isbn' || index === 'issn') { - const identifierType = resourceData.identifier_types.records.find(type => type.name.toLowerCase() === index); - makeQueryArgs = { identifierTypeId: (identifierType ? identifierType.id : 'identifier-type-not-found') }; - } - - let cql = searchableIndex.makeQuery(resourceData.query.query || '', makeQueryArgs); - - const filterCql = filters2cql(filterConfig, resourceData.query.filters); - if (filterCql) { - if (cql) { - cql = `(${cql}) and ${filterCql}`; - } else { - cql = filterCql; - } - } - - const { sort } = resourceData.query; - if (sort) { - const sortIndexes = sort.split(',').map((sort1) => { - let reverse = false; - if (sort1.startsWith('-')) { - // eslint-disable-next-line no-param-reassign - sort1 = sort1.substr(1); - reverse = true; - } - let sortIndex = sortMap[sort1] || sort1; - if (reverse) { - sortIndex = `${sortIndex.replace(' ', '/sort.descending ')}/sort.descending`; - } - return sortIndex; - }); - - cql += ` sortby ${sortIndexes.join(' ')}`; + const [ + queryParams, + pathComponents, + resourceData, + logger + ] = args; + const queryIndex = resourceData.query.qindex ? resourceData.query.qindex : 'all'; + const searchableIndex = searchableIndexes.find(idx => idx.value === queryIndex); + let queryTemplate = ''; + + if (queryIndex === 'isbn' || queryIndex === 'issn') { + const identifierType = resourceData.identifier_types.records.find(type => type.name.toLowerCase() === queryIndex); + const identifierTypeId = identifierType ? identifierType.id : 'identifier-type-not-found'; + + queryTemplate = _.template(searchableIndex.queryTemplate)({ identifierTypeId }); + } else { + queryTemplate = searchableIndex.queryTemplate; } - return cql; - }, + resourceData.query = { ...resourceData.query, qindex: '' }; + + return makeQueryFunction( + 'cql.allRecords=1', + queryTemplate, + { + Title: 'title', + publishers: 'publication', + Contributors: 'contributors', + }, + filterConfig, + 2 + )(queryParams, pathComponents, resourceData, logger); + } }, staticFallback: { params: {} }, }, diff --git a/test/bigtest/interactors/inventory.js b/test/bigtest/interactors/inventory.js index 475ff001f..3c1ad02ec 100644 --- a/test/bigtest/interactors/inventory.js +++ b/test/bigtest/interactors/inventory.js @@ -5,16 +5,18 @@ import { selectable, fillable, clickable, + isPresent, } from '@bigtest/interactor'; export default @interactor class InventoryInteractor { static defaultScope = '[data-test-inventory-instances]'; + isNoResultsMessageLabelPresent = isPresent('[class*=noResultsMessageLabel]'); instances = collection('[role=row] a'); instance = scoped('[data-test-instance-details]'); + chooseSearchOption= selectable('#input-inventory-search-qindex'); - chooseFilter = selectable('#input-inventory-search-qindex'); - fillFilter = fillable('#input-inventory-search'); + fillSearchField = fillable('#input-inventory-search'); clickSearch = clickable('[data-test-search-and-sort-submit]'); } diff --git a/test/bigtest/tests/instances-index-test.js b/test/bigtest/tests/instances-index-test.js index 4b426a4e8..24ef0fd05 100644 --- a/test/bigtest/tests/instances-index-test.js +++ b/test/bigtest/tests/instances-index-test.js @@ -11,38 +11,51 @@ describe('Instances', () => { const inventory = new InventoryInteractor(); beforeEach(async function () { - this.server.createList('instance', 25, 'withHoldingAndItem'); this.visit('/inventory'); }); - it('shows the list of inventory items', () => { - expect(inventory.isVisible).to.equal(true); + it('is no results message label present', () => { + expect(inventory.isNoResultsMessageLabelPresent).to.equal(true); }); - it('renders each instance', () => { - expect(inventory.instances().length).to.be.gte(5); - }); - - describe('clicking on the first item', function () { + describe('search by barcode', function () { beforeEach(async function () { - await inventory.instances(0).click(); + this.server.createList('instance', 25, 'withHoldingAndItem'); + const item = this.server.schema.instances.first().holdings.models[0].items.models[0]; + await inventory.chooseSearchOption('Barcode'); + await inventory.fillSearchField(item.barcode); + await inventory.clickSearch(); + }); + + it('should find instance with given barcode', () => { + expect(inventory.instances().length).to.be.equal(1); }); - it('loads the instance details', function () { - expect(inventory.instance.isVisible).to.equal(true); + describe('clicking on the first item', function () { + beforeEach(async function () { + await inventory.instances(0).click(); + }); + + it('loads the instance details', function () { + expect(inventory.instance.isVisible).to.equal(true); + }); }); }); - describe('search by barcode', function () { + describe('search by ISSN', function () { beforeEach(async function () { - const item = this.server.schema.instances.first().holdings.models[0].items.models[0]; - await inventory.chooseFilter('Barcode'); - await inventory.fillFilter(item.barcode); + this.server.createList('instance', 25, 'withHoldingAndItem'); + await inventory.chooseSearchOption('- ISSN'); + await inventory.fillSearchField('incorrect value'); await inventory.clickSearch(); }); - it('should find instance with given barcode', () => { - expect(inventory.instances().length).to.be.equal(1); + it('should not find instance with given ISSN', () => { + expect(inventory.instances().length).to.be.equal(0); + }); + + it('is no results message label present', () => { + expect(inventory.isNoResultsMessageLabelPresent).to.equal(true); }); }); });