Skip to content

Commit daf224e

Browse files
committed
Merge remote-tracking branch 'origin/production' into issue-922
2 parents 51e4f26 + 87e7371 commit daf224e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+4019
-3439
lines changed

CHANGELOG.md

+84
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,90 @@ All notable changes to this project will be documented in this file.
99

1010
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111

12+
## [7.9.5](https://github.com/specify/specify7/compare/v7.9.4...v7.9.5) (20 May 2024)
13+
14+
This release has for objective to migrated Workbench to React to align it with the rest of the application to ensure consistency and modernising the codebase.
15+
Workbench functionalities remain unchanged but this release helps improve internal development and maintenance of the workbench going forward.
16+
[Workbench Conversion](https://github.com/specify/specify7/pull/4637)
17+
18+
### Added
19+
20+
- **Live Search feature in Workbench**
21+
22+
## [7.9.4](https://github.com/specify/specify7/compare/v7.9.3.1...v7.9.4) (13 May 2024)
23+
24+
### Added
25+
26+
- **Added a visual editor for some app resources** ([#2796](https://github.com/specify/specify7/pull/2796))
27+
- The initial release supports
28+
- [Form Definitions](https://discourse.specifysoftware.org/t/editing-forms-in-specify-7/1557)
29+
- [Table Formats](https://discourse.specifysoftware.org/t/editing-table-formats-and-aggregations-in-specify-7/1558)
30+
- [Table Aggregation](https://discourse.specifysoftware.org/t/editing-table-formats-and-aggregations-in-specify-7/1558)
31+
- Visual editors for additional app resources will be added in the future.
32+
- Enforce uniqueness requirements for name ([#4164](https://github.com/specify/specify7/pull/4164))
33+
- Added query combo box for Specify Users in Export Feed ([#4345](https://github.com/specify/specify7/pull/4345))
34+
- Added support for [conditional forms](https://discourse.specifysoftware.org/t/editing-forms-in-specify-7/1557#conditional-rendering-22)
35+
- Added a preview for web links, table formats, and table aggregations ([#4343](https://github.com/specify/specify7/pull/4343))
36+
- Added numerous improvements to distinct queries ([#4596](https://github.com/specify/specify7/pull/4596)*Requested by University of Kansas, University of Michigan, Commonwealth Scientific and Industrial Research Organisation*)
37+
- Added links to records in distinct queries where all columns returned are the same
38+
- Introduced the option to view groups of grouped records in distinct query results
39+
- Distinct queries can now be exported to CSV
40+
- Added the ability to display only nodes with associated records in the tree viewer ([#4023](https://github.com/specify/specify7/pull/4023) – Commonwealth Scientific and Industrial Research Organisation)
41+
- Added the ability to set default values for boolean/checkbox fields in the form definition (#4585*Requested by University of Michigan, Commonwealth Scientific and Industrial Research Organisation*
42+
- Added the ability to import and export WorkBench data set upload plans ([#1363](https://github.com/specify/specify7/issues/1363)*Requested by Commonwealth Scientific and Industrial Research Organisation and others*)
43+
- Subforms can now be collapsed ([#3642](https://github.com/specify/specify7/pull/3642)*Requested by Commonwealth Scientific and Industrial Research Organisation and Agriculture and Agri-Food Canada*)
44+
- Added a new form element to show a view button next to a query combo box ([#4199](https://github.com/specify/specify7/pull/4199)*Requested by South African Institute for Aquatic Biodiversity*)
45+
- Fields in the Schema Config can now be sorted by their visibility status ([#3516](https://github.com/specify/specify7/pull/3516))
46+
- Added the ability to switch to 'Basic View' and 'Hide Field Mapper' in embedded query dialogs ([#2863](https://github.com/specify/specify7/pull/2863))
47+
- Added pagination when viewing large lists of resources (record sets, queries, etc.) to improve performance ([#3195](https://github.com/specify/specify7/pull/3195))
48+
- Added a preference to have records in read-only mode by default requiring the user to press an edit button before changes can be made ([#3553](https://github.com/specify/specify7/pull/3553))
49+
- Added the ability to hide the plus button in forms ([#3669](https://github.com/specify/specify7/pull/3669)*Requested by Commonwealth Scientific and Industrial Research Organisation*)
50+
- Added bulk resolve and bulk return when returning loans ([#4224](https://github.com/specify/specify7/pull/4224)*Requested by Commonwealth Scientific and Industrial Research Organisation*)
51+
- Kept the search panel open when modifying XML form ([#4260](https://github.com/specify/specify7/pull/4260))
52+
- A warning is now displayed if there are no available preparations associated with a catalog number when making an interaction ([#4195](https://github.com/specify/specify7/pull/4195))
53+
- Added table icons to the WorkBench data sets dialog based on base table in the upload plan ([#4475](https://github.com/specify/specify7/pull/4475))
54+
- Added frontend business rules for Address `isPrimary` so that it is set by default when adding a new address ([#4443](https://github.com/specify/specify7/pull/4443))
55+
56+
57+
### Changed
58+
- Differentiated list of tables for interactions and data entry ([#4198](https://github.com/specify/specify7/pull/4198))
59+
- Removed table name before app resource titles ([#4132](https://github.com/specify/specify7/pull/4132))
60+
- Numeric inputs no longer change on scroll ([#4249](https://github.com/specify/specify7/pull/4249))
61+
- Disabled gallery icon when there are no attachments on forms ([#4220](https://github.com/specify/specify7/pull/4220))
62+
- Search preview dialogs no longer display subviews ([#4254](https://github.com/specify/specify7/pull/4254))
63+
- Improved logic for selecting main tables fields when creating new records from query combo boxes ([#4293](https://github.com/specify/specify7/pull/4293))
64+
- Correctly detected main table fields in formatters ([#4516](https://github.com/specify/specify7/pull/4516))
65+
- Sidebar color preference has been moved and renamed ([#4355](https://github.com/specify/specify7/pull/4355))
66+
- Displayed disable icon add button instead of link when lowest tree rank ([#4351](https://github.com/specify/specify7/pull/4351))
67+
- "Use Localized Field Labels" checkbox is now a button ([#4344](https://github.com/specify/specify7/pull/4344))
68+
- Renamed record merging policy to `/record/merge` ([#4329](https://github.com/specify/specify7/pull/4329))
69+
- Switched to muted colors for taxon tiles ([#4476](https://github.com/specify/specify7/pull/4476)*Requested by Virginia Institute of Marine Science*)
70+
- Miscellaneous Reports dialog improvements ([#4396](https://github.com/specify/specify7/pull/4396))
71+
- Backend query exports now have user-friendly names ([#3590](https://github.com/specify/specify7/pull/3590))
72+
73+
### Fixed
74+
- Fixed an issue where the WorkBench did not always check for custom uniqueness rules ([#4593](https://github.com/specify/specify7/pull/4593)*Reported by Commonwealth Scientific and Industrial Research Organisation*)
75+
- Fixed bug causing incorrect disambiguation behavior in the WorkBench ([#4777](https://github.com/specify/specify7/pull/4777))
76+
- Made behavior consistent for Reports/Labels across forms and reports dialog, enhanced Report preferences. ([#4299](https://github.com/specify/specify7/pull/4299)*Reported by Florida Fish and Wildlife Research Institute and Commonwealth Scientific and Industrial Research Organisation*)
77+
- Fixed an issue that prevented new reports or labels from being created when there was a formatted table in the query ([#4427](https://github.com/specify/specify7/pull/4427)*Reported by The Hebrew University of Jerusalem, Florida Fish and Wildlife Research Institute, Gothenburg Museum of Natural History, and Oranim College of Education*)
78+
- Make taxonomic rank properly recompute when the parent changes ([#4462](https://github.com/specify/specify7/pull/4462)*Reported by Agriculture and Agri-Food Canada*)
79+
- Added a prompt for a user to define a record set name when creating one ([#4346](https://github.com/specify/specify7/pull/4346))
80+
- Improved home page load performance ([#4240](https://github.com/specify/specify7/pull/4240))
81+
- Makes 'Save' button style consistent in Schema Config and Mapper ([#3527](https://github.com/specify/specify7/pull/3527))
82+
- Make preferences visually read-only for users without proper permissions ([#3551](https://github.com/specify/specify7/pull/3551))
83+
- Fixed an issue preventing preparations from being added on the Loan form when displayed it was displayed in "form view" ([#3659](https://github.com/specify/specify7/pull/3659))
84+
- Fixed an issue where a cell or row could be selected multiple times in the WorkBench ([#3675](https://github.com/specify/specify7/pull/3675))
85+
- Fixed an issue where the WorkBench could not import certain spreadsheets ([#4223](https://github.com/specify/specify7/pull/4223)*Reported by Royal Botanic Garden Edinburgh*)
86+
- Refactored date picker and added tests ([#4276](https://github.com/specify/specify7/pull/4276))
87+
- Fixed spelling mistake in new record set text ([#4317](https://github.com/specify/specify7/pull/4317))
88+
- The cache is cleared when form edits are made, allowing you to see the latest version ([#4290](https://github.com/specify/specify7/pull/4290))
89+
- Fixed issues when parsing remote preferences ([#4251](https://github.com/specify/specify7/pull/4251)*Reported by Museu de Ciències Naturals de Barcelona*)
90+
- Fix inconsistency with hidden tables in schema and new query lists ([#4357](https://github.com/specify/specify7/pull/4357)*Reported by Commonwealth Scientific and Industrial Research Organisation*)
91+
- Made `usertype` get ignored when searching for Common directory app resources to ensure global app resources are applied appropriately ([#4332](https://github.com/specify/specify7/pull/4332))
92+
- Made minor accessibility improvements ([#4449](https://github.com/specify/specify7/pull/4449))
93+
- Scoped all front-end requests where needed to prevent resources from returning records from other collections ([#3304](https://github.com/specify/specify7/pull/3304))
94+
- Fixed WorkBench dialog heading so it displays "Timestamp Uploaded" instead of "Timestamp Modified" ([#4472](https://github.com/specify/specify7/pull/4472))
95+
1296
## [7.9.3.1](https://github.com/specify/specify7/compare/v7.9.3...v7.9.3.1) (29 January 2024)
1397

1498
This release fixes an issue that could cause an error when viewing an Accession or Repository Agreement form with interaction agents present.

specifyweb/frontend/js_src/css/workbench.css

+10
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,16 @@
7777
--accent-color: var(--search-result);
7878
}
7979

80+
/*
81+
* Override default font properties: required for handsontable 10 and above
82+
* See: https://github.com/handsontable/handsontable/pull/8681
83+
*/
84+
.handsontable {
85+
@apply text-inherit;
86+
font-family: inherit;
87+
font-size: inherit;
88+
}
89+
8090
/* Handsontable dark mode */
8191
.handsontable td,
8292
.htContextMenu table tbody tr td {

specifyweb/frontend/js_src/lib/components/DataModel/__tests__/businessRules.test.ts

+69
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { renderHook } from '@testing-library/react';
33
import { overrideAjax } from '../../../tests/ajax';
44
import { mockTime, requireContext } from '../../../tests/helpers';
55
import { overwriteReadOnly } from '../../../utils/types';
6+
import { getPref } from '../../InitialContext/remotePrefs';
67
import type { SerializedResource } from '../helperTypes';
78
import { getResourceApiUrl } from '../resource';
89
import { useSaveBlockers } from '../saveBlockers';
@@ -197,6 +198,18 @@ describe('treeBusinessRules', () => {
197198
_tableName: 'Taxon',
198199
id: 3,
199200
name: 'Acipenser',
201+
isAccepted: true,
202+
rankId: 180,
203+
definition: '/api/specify/taxontreedef/1/',
204+
definitionItem: '/api/specify/taxontreedefitem/9/',
205+
parent: '/api/specify/taxon/2/',
206+
};
207+
208+
const husoResponse: Partial<SerializedResource<Taxon>> = {
209+
_tableName: 'Taxon',
210+
id: 6,
211+
name: 'Huso',
212+
isAccepted: false,
200213
rankId: 180,
201214
definition: '/api/specify/taxontreedef/1/',
202215
definitionItem: '/api/specify/taxontreedefitem/9/',
@@ -207,6 +220,7 @@ describe('treeBusinessRules', () => {
207220
_tableName: 'Taxon',
208221
id: 4,
209222
name: 'oxyrinchus',
223+
isAccepted: true,
210224
rankId: 220,
211225
definition: '/api/specify/taxontreedef/1/',
212226
definitionItem: '/api/specify/taxontreedefitem/2/',
@@ -218,6 +232,7 @@ describe('treeBusinessRules', () => {
218232
id: 5,
219233
rankId: 230,
220234
name: 'oxyrinchus',
235+
isAccepted: true,
221236
definition: '/api/specify/taxontreedef/1/',
222237
definitionItem: '/api/specify/taxontreedefitem/22/',
223238
};
@@ -265,9 +280,11 @@ describe('treeBusinessRules', () => {
265280
};
266281

267282
const oxyrinchusFullNameResponse = 'Acipenser oxyrinchus';
283+
const dauricusFullNameResponse = 'Huso dauricus';
268284

269285
overrideAjax('/api/specify/taxon/2/', animaliaResponse);
270286
overrideAjax('/api/specify/taxon/3/', acipenserResponse);
287+
overrideAjax('/api/specify/taxon/6/', husoResponse);
271288
overrideAjax('/api/specify/taxon/4/', oxyrinchusSpeciesResponse);
272289
overrideAjax('/api/specify/taxon/5/', oxyrinchusSubSpeciesResponse);
273290
overrideAjax('/api/specify/taxontreedefitem/9/', genusResponse);
@@ -277,6 +294,10 @@ describe('treeBusinessRules', () => {
277294
'/api/specify_tree/taxon/3/predict_fullname/?name=oxyrinchus&treedefitemid=2',
278295
oxyrinchusFullNameResponse
279296
);
297+
overrideAjax(
298+
'/api/specify_tree/taxon/6/predict_fullname/?name=dauricus&treedefitemid=2',
299+
dauricusFullNameResponse
300+
);
280301
overrideAjax('/api/specify/taxon/?limit=1&parent=4&orderby=rankid', {
281302
objects: [oxyrinchusSubSpeciesResponse],
282303
meta: {
@@ -329,4 +350,52 @@ describe('treeBusinessRules', () => {
329350
);
330351
expect(result.current[0]).toStrictEqual(['Bad tree structure.']);
331352
});
353+
test('saveBlocker on synonymized parent', async () => {
354+
const taxon = new tables.Taxon.Resource({
355+
name: 'dauricus',
356+
parent: '/api/specify/taxon/6/',
357+
rankId: 220,
358+
definition: '/api/specify/taxontreedef/1/',
359+
definitionItem: '/api/specify/taxontreedefitem/2/',
360+
});
361+
362+
await taxon.businessRuleManager?.checkField('parent');
363+
364+
const { result } = renderHook(() =>
365+
useSaveBlockers(taxon, tables.Taxon.getField('parent'))
366+
);
367+
expect(result.current[0]).toStrictEqual(['Bad tree structure.']);
368+
369+
await taxon.businessRuleManager?.checkField('integer1');
370+
371+
const { result: fieldChangeResult } = renderHook(() =>
372+
useSaveBlockers(taxon, tables.Taxon.getField('parent'))
373+
);
374+
expect(fieldChangeResult.current[0]).toStrictEqual(['Bad tree structure.']);
375+
});
376+
test('saveBlocker not on synonymized parent w/preference', async () => {
377+
const remotePrefs = await import('../../InitialContext/remotePrefs');
378+
jest
379+
.spyOn(remotePrefs, 'getPref')
380+
.mockImplementation((key) =>
381+
key === 'sp7.allow_adding_child_to_synonymized_parent.Taxon'
382+
? true
383+
: getPref(key)
384+
);
385+
386+
const taxon = new tables.Taxon.Resource({
387+
name: 'dauricus',
388+
parent: '/api/specify/taxon/6/',
389+
rankId: 220,
390+
definition: '/api/specify/taxontreedef/1/',
391+
definitionItem: '/api/specify/taxontreedefitem/2/',
392+
});
393+
394+
await taxon.businessRuleManager?.checkField('parent');
395+
396+
const { result } = renderHook(() =>
397+
useSaveBlockers(taxon, tables.Taxon.getField('parent'))
398+
);
399+
expect(result.current[0]).toStrictEqual([]);
400+
});
332401
});

specifyweb/frontend/js_src/lib/components/DataModel/treeBusinessRules.ts

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { treeText } from '../../localization/tree';
22
import { ajax } from '../../utils/ajax';
33
import { f } from '../../utils/functools';
4+
import { getPref } from '../InitialContext/remotePrefs';
45
import { fetchPossibleRanks } from '../PickLists/TreeLevelPickList';
56
import { formatUrl } from '../Router/queryString';
67
import type { BusinessRuleResult } from './businessRules';
@@ -37,9 +38,15 @@ export const treeBusinessRules = async (
3738
? undefined
3839
: await fetchPossibleRanks(resource, parentDefItem.get('rankId'));
3940

41+
const doExpandSynonymActionsPref = getPref(
42+
`sp7.allow_adding_child_to_synonymized_parent.${resource.specifyTable.name}`
43+
);
44+
const isParentSynonym = !parent.get('isAccepted');
45+
4046
const hasBadTreeStrcuture =
4147
parent.id === resource.id ||
4248
definitionItem === undefined ||
49+
(isParentSynonym && !doExpandSynonymActionsPref) ||
4350
parent.get('rankId') >= definitionItem.get('rankId') ||
4451
(possibleRanks !== undefined &&
4552
!possibleRanks
@@ -60,6 +67,7 @@ export const treeBusinessRules = async (
6067
};
6168

6269
if (
70+
hasBadTreeStrcuture ||
6371
(resource.get('name')?.length ?? 0) === 0 ||
6472
definitionItem === undefined
6573
)

specifyweb/frontend/js_src/lib/components/FormParse/__tests__/index.test.ts

+103
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const {
3030
parseFormTableColumns,
3131
getColumnDefinitions,
3232
getColumnDefinition,
33+
parseRows,
3334
} = exportsForTests;
3435

3536
requireContext();
@@ -529,3 +530,105 @@ theories(getColumnDefinition, [
529530
out: 'B',
530531
},
531532
]);
533+
534+
const testRows = `
535+
<viewdef>
536+
<rows>
537+
<row>
538+
<cell type="label" labelFor="tt" label="test" />
539+
</row>
540+
<row>
541+
<cell type="field" name=" stationFieldNumber " uiType="text" colSpan="4" align="right" id="tt" />
542+
<cell type="field" name="collectingTrip.text1" uiType="checkbox" label="2" colSpan="1" align="right" />
543+
</row>
544+
<row>
545+
</row>
546+
<row>
547+
<cell type="subview" id="dt" viewname="Collectors" name="collectors"/>
548+
</row>
549+
</rows>
550+
</viewdef>`;
551+
552+
test('parseRows', async () => {
553+
const viewDef = xml(testRows);
554+
const rowsContainer = viewDef.children.rows[0];
555+
const rawRows = rowsContainer?.children?.row ?? [];
556+
557+
await expect(parseRows(rawRows, tables.CollectingEvent)).resolves.toEqual([
558+
[
559+
{
560+
align: 'right',
561+
ariaLabel: undefined,
562+
colSpan: 1,
563+
fieldNames: undefined,
564+
id: undefined,
565+
labelForCellId: 'tt',
566+
text: 'test',
567+
title: undefined,
568+
type: 'Label',
569+
verticalAlign: 'center',
570+
visible: true,
571+
},
572+
],
573+
[
574+
{
575+
align: 'left',
576+
ariaLabel: undefined,
577+
colSpan: 2,
578+
fieldDefinition: {
579+
defaultValue: undefined,
580+
isReadOnly: false,
581+
max: undefined,
582+
maxLength: undefined,
583+
min: undefined,
584+
minLength: undefined,
585+
step: undefined,
586+
type: 'Text',
587+
},
588+
fieldNames: ['stationFieldNumber'],
589+
id: 'tt',
590+
isRequired: false,
591+
type: 'Field',
592+
verticalAlign: 'center',
593+
visible: true,
594+
},
595+
{
596+
align: 'left',
597+
ariaLabel: undefined,
598+
colSpan: 1,
599+
fieldDefinition: {
600+
defaultValue: undefined,
601+
isReadOnly: false,
602+
label: '2',
603+
printOnSave: false,
604+
type: 'Checkbox',
605+
},
606+
fieldNames: ['collectingTrip', 'text1'],
607+
id: undefined,
608+
isRequired: false,
609+
type: 'Field',
610+
verticalAlign: 'center',
611+
visible: true,
612+
},
613+
],
614+
[],
615+
[
616+
{
617+
align: 'left',
618+
ariaLabel: undefined,
619+
colSpan: 1,
620+
fieldNames: ['collectors'],
621+
formType: 'formTable',
622+
icon: undefined,
623+
id: 'dt',
624+
isButton: false,
625+
isCollapsed: false,
626+
sortField: undefined,
627+
type: 'SubView',
628+
verticalAlign: 'stretch',
629+
viewName: 'Collectors',
630+
visible: true,
631+
},
632+
],
633+
]);
634+
});

specifyweb/frontend/js_src/lib/components/FormParse/fields.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,11 @@ const processFieldType: {
223223
hasNewButton: getProperty('newBtn')?.toLowerCase() !== 'false',
224224
hasSearchButton: getProperty('searchBtn')?.toLowerCase() !== 'false',
225225
hasEditButton: getProperty('editBtn')?.toLowerCase() !== 'false',
226-
hasViewButton: getProperty('viewBtn')?.toLowerCase() === 'true',
226+
hasViewButton:
227+
getProperty('viewBtn') === undefined &&
228+
getProperty('editBtn')?.toLowerCase() === 'false'
229+
? true
230+
: getProperty('viewBtn')?.toLowerCase() === 'true',
227231
typeSearch: getProperty('name'),
228232
searchView: getProperty('searchView'),
229233
};

0 commit comments

Comments
 (0)