Skip to content

Commit

Permalink
Merge branch 'issue-5223' of https://github.com/specify/specify7 into…
Browse files Browse the repository at this point in the history
… issue-5223
  • Loading branch information
melton-jason committed Oct 12, 2024
2 parents 1f4b985 + d7078b9 commit 619f84b
Show file tree
Hide file tree
Showing 60 changed files with 2,618 additions and 438 deletions.
14 changes: 7 additions & 7 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ DATABASE_PORT=3306
MYSQL_ROOT_PASSWORD=password
DATABASE_NAME=specify

# When running Specify 7 for the first time or during updates that
# require migrations, ensure that the MASTER_NAME and MASTER_PASSWORD
# are set to the root username and password. This will ensure proper
# execution of Django migrations during the initial setup.
# After launching Specify and verifying the update is complete, you can
# When running Specify 7 for the first time or during updates that
# require migrations, ensure that the MASTER_NAME and MASTER_PASSWORD
# are set to the root username and password. This will ensure proper
# execution of Django migrations during the ixnitial setup.
# After launching Specify and verifying the update is complete, you can
# safely replace these credentials with the master SQL user name and password.
MASTER_NAME=root
MASTER_PASSWORD=password
Expand Down Expand Up @@ -36,7 +36,7 @@ CELERY_RESULT_BACKEND=redis://redis/1
LOG_LEVEL=WARNING

# Set this variable to `true` to run Specify 7 in debug mode. This
# should only be used during development and troubleshooting and not
# during general use. Django applications leak memory when operated
# should only be used during development and troubleshooting and not
# during general use. Django applications leak memory when operated
# continuously in debug mode.
SP7_DEBUG=true
10 changes: 5 additions & 5 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
# See https://github.com/specify/specify7-test-panel/issues/110#issuecomment-1943045253
VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g')
if [ "${{ github.event.repository.default_branch }}" = "$VERSION" ]; then
VERSION=edge
VERSION=production
fi
elif [[ $GITHUB_REF == refs/pull/* ]]; then
VERSION=pr-${{ github.event.number }}
Expand Down Expand Up @@ -82,9 +82,9 @@ jobs:
uses: docker/build-push-action@v6
with:
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
tags: ${{ steps.prep.outputs.tags }}
push: true

- name: Export digest
run: |
mkdir -p /tmp/digests
Expand Down Expand Up @@ -134,4 +134,4 @@ jobs:
- name: Inspect image
run: |
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,26 @@ All notable changes to this project will be documented in this file.

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

## [7.9.7](https://github.com/specify/specify7/compare/v7.9.6.2...v7.9.7) (1 October 2024)

### Added
* Added an all-new **Bulk Carry Forward** feature to enable series data entry in Specify 7 ([#4804](https://github.com/specify/specify7/pull/4804), [#5120](https://github.com/specify/specify7/pull/5120)_Requested by University of Minnesota Entomology, Bulgarian Academy of Sciences, KU Entomology, and many others_)
* Added support for Geography Code at any rank when building a query ([#5094](https://github.com/specify/specify7/pull/5094)_Requested by Museu de Ciències Naturals de Barcelona, KU Ichthyology, and many others_)
* Added a preference (enabled by default) to insert a [UTF-8 BOM](https://en.wikipedia.org/wiki/Byte_order_mark#:~:text=%5B3%5D-,UTF%2D8,-%5Bedit%5D) to CSV exports ([#5204](https://github.com/specify/specify7/pull/5204))
* When enabled, you should be able to open exported CSV files in Excel without using the import utility.

### Changed
* Removed the limit on the number of results returned when searching a tree in the tree viewer ([#5125](https://github.com/specify/specify7/pull/5125))
* Descriptions for User Preferences have been improved ([#5064](https://github.com/specify/specify7/pull/5064))
* Specify in Docker is now built for both `x64_86` and `arm64` architectures, enabling native deployment on ARM-based servers ([#5235](https://github.com/specify/specify7/pull/5235))
* Collection, Discipline, Division, and the Audit Log are now visible in the list of query tables by default ([#5133](https://github.com/specify/specify7/pull/5133))

### Fixed
* Fixed an issue that caused table aggregation separators to be cleared when set to the default separator (`; `) ([#5240](https://github.com/specify/specify7/pull/5240))
* Fixed an issue that allowed users to carry forward preparations in an interaction when cloning or using carry forward ([#4905](https://github.com/specify/specify7/pull/4905))
* Fixed an issue that would cause a crash if an `ExportFeed` was configured with an invalid Specify user ID ([#5042](https://github.com/specify/specify7/pull/5042))
* Fixed an issue where a border would not appear for query items in the report query dialog ([#5159](https://github.com/specify/specify7/pull/5159))

## [7.9.6.2](https://github.com/specify/specify7/compare/v7.9.6.1...v7.9.6.2) (22 July 2024)

- Fixed an issue that prevented `TimestampModified` from being captured upon saving a record since the `v7.9.6` release ([#5108](https://github.com/specify/specify7/issues/5108)*Reported by the University of Kansas and Ohio State University*)
Expand Down
27 changes: 12 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# [Specify 7](https://www.specifysoftware.org/products/specify-7/)

The [Specify Collections Consortium](https://www.specifysoftware.org) is pleased
to offer Specify 7, a web implementation of our biological collections data
to offer Specify 7, the web implementation of our biological collections data
management platform.

We encourage members to use
Expand All @@ -15,30 +15,27 @@ access to this repository.

The new generation of Specify combines the interface design components and data
management foundation of Specify 6 with the efficiency and ease-of-use of
web-based data access and cloud computing. The Specify 7 web application uses
web-based data access and cloud computing. Specify 7 uses
the same interface layout language as Specify 6, so any user interface
customization made in one product is mirrored in the other. Also Specify 6 and
Specify 7 use the same data model and can work from the same Specify MySQL
database, which means they can be run simultaneously with any Specify
collection. By providing an easy migration path to the web, Specify 7 helps
customization made in one platform is mirrored in the other. Also Specify 6 and
Specify 7 use the same data model and can work from the same Specify MySQL or MariaDB
database, which means 6 and 7 can be run simultaneously with any Specify
collection. Specify 7 helps
transition Specify 6 collections to cloud computing. It is also a great starting
platform for collections which prefer zero workstation software installation and
platform for institutions that prefer zero workstation software installation and
ubiquitous web browser access.

Specify 7’s server/browser architecture open the door for computing support of
collaborative digitization projects and for remote hosting of institutional or
project specimen databases. Without the need for a local area or campus network
Specify 7’s architecture supports collaborative digitization projects and remote hosting of specimen databases. Without the need for a local area or campus network
to connect to the MySQL data server, Specify 7 gives you and your collaborators
access to a shared specimen database through any web browser. Without adequate
IT support to maintain a secure database server? With the Specify 7 server
access to a shared specimen database through any web browser. Finding it challenging to obtain IT support to maintain a local secure database server? With the Specify 7 server
software supported on generic Linux servers, museums can utilize a server
hosting service to provide support for the technical complexities of systems
administration, security management, and backing-up. Want to create a joint
database with remote collaborators for a collaborative digitizing effort? No
database for a collaborative digitizing effort? No
problem! Host, hire a hosting service or use
our [Specify Cloud](https://www.specifysoftware.org/products/cloud/) service for
your Specify database, set up accounts and go. We provide the same efficient
user interface and printed reports and labels customization, and help desk
user interface, report and labels customization and help desk
support for Specify 7 as we do for Specify 6.

**Secure.**
Expand Down Expand Up @@ -69,7 +66,7 @@ The Specify Collections Consortium is funded by its member
institutions. The Consortium web site is:
https://specifysoftware.org

Specify 7 Copyright © 2023 Specify Collections Consortium. Specify
Specify 7 Copyright © 2024 Specify Collections Consortium. Specify
comes with ABSOLUTELY NO WARRANTY. This is free software licensed
under GNU General Public License 2 (GPL2).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`fields are loaded 1`] = `
[
"[literalField CollectionObject.actualTotalCountAmt]",
"[literalField CollectionObject.age]",
"[literalField CollectionObject.availability]",
"[literalField CollectionObject.catalogNumber]",
"[literalField CollectionObject.catalogedDate]",
Expand Down Expand Up @@ -104,6 +105,7 @@ exports[`fields are loaded 1`] = `
exports[`literal fields are loaded 1`] = `
[
"[literalField CollectionObject.actualTotalCountAmt]",
"[literalField CollectionObject.age]",
"[literalField CollectionObject.availability]",
"[literalField CollectionObject.catalogNumber]",
"[literalField CollectionObject.catalogedDate]",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,25 +119,6 @@ describe('Collection Object business rules', () => {
expect(collectionObject.get('collectionObjectType')).toBeDefined();
});

test('Save blocked when CollectionObjectType of a CollectionObject does not have same tree definition as its associated Determination -> taxon', async () => {
const collectionObject = getBaseCollectionObject();

const determination =
collectionObject.getDependentResource('determinations')?.models[0];

const { result } = renderHook(() =>
useSaveBlockers(determination, tables.Determination.getField('taxon'))
);

await act(async () => {
await determination?.businessRuleManager?.checkField('taxon');
});

expect(result.current[0]).toStrictEqual([
'Taxon does not belong to the same tree as this Object Type',
]);
});

const otherCollectionObjectTypeUrl = getResourceApiUrl(
'CollectionObjectType',
2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ test('getFieldsToNotClone', () => {
});
expect(getFieldsToNotClone(tables.CollectionObject, true, false)).toEqual([
'actualTotalCountAmt',
'age',
'catalogNumber',
'timestampModified',
'guid',
Expand All @@ -304,6 +305,7 @@ test('getFieldsToNotClone', () => {
]);
expect(getFieldsToNotClone(tables.CollectionObject, false, false)).toEqual([
'actualTotalCountAmt',
'age',
'catalogNumber',
'timestampModified',
'guid',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ test('domain data is fetched and parsed correctly', async () =>
],
paleoContextChildTable: 'collectionobject',
referenceSymbol: '#',
treeSymbol: '$',
treeRankSymbol: '$',
treeDefinitionSymbol: '%',
}));
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ test('indexed fields are loaded', () =>
{
"accession": "[relationship CollectionObject.accession]",
"actualTotalCountAmt": "[literalField CollectionObject.actualTotalCountAmt]",
"age": "[literalField CollectionObject.age]",
"agent1": "[relationship CollectionObject.agent1]",
"altCatalogNumber": "[literalField CollectionObject.altCatalogNumber]",
"appraisal": "[relationship CollectionObject.appraisal]",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { formsText } from '../../localization/forms';
import { resourcesText } from '../../localization/resources';
import { f } from '../../utils/functools';
import type { BusinessRuleResult } from './businessRules';
Expand Down Expand Up @@ -51,7 +50,6 @@ type MappedBusinessRuleDefs = {
};

const CURRENT_DETERMINATION_KEY = 'determination-isCurrent';
const DETERMINATION_TAXON_KEY = 'determination-taxon';

const hasNoCurrentDetermination = (collection: Collection<Determination>) =>
collection.models.length > 0 &&
Expand Down Expand Up @@ -199,14 +197,8 @@ export const businessRuleDefs: MappedBusinessRuleDefs = {
const taxonTreeDefinition = fetchedTaxon.definition;
const COTypeTreeDefinition = fetchedCOType.taxonTreeDef;

return taxonTreeDefinition === COTypeTreeDefinition
? void setSaveBlockers(
currentDetermination as SpecifyResource<AnySchema>,
currentDetermination.specifyTable.field.taxon,
[],
DETERMINATION_TAXON_KEY
)
: resource.set('determinations', []);
if (taxonTreeDefinition !== COTypeTreeDefinition)
resource.set('determinations', []);
})
.catch((error) => {
console.error('Error fetching resources:', error);
Expand All @@ -233,57 +225,6 @@ export const businessRuleDefs: MappedBusinessRuleDefs = {
accepted === null ? taxon : getLastAccepted(accepted)
);

const related = determination.collection?.related;
if (
related !== undefined &&
related.specifyTable.name === 'CollectionObject'
) {
const collectionObject =
related as SpecifyResource<CollectionObject>;
void f
.all({
defaultType:
collectionObject.get('collectionObjectType') === undefined
? collectionObject
.rgetPromise('collection')
.then(async (collection) =>
collection.rgetPromise('collectionObjectType')
)
.then((coType) => coType ?? undefined)
: undefined,
coType: collectionObject.rgetPromise(
'collectionObjectType',
true
),
})
.then(({ defaultType, coType }) => {
const resolvedCoType = coType ?? defaultType;
/*
* Have to set save blockers directly here to get this working.
* Since following code has to wait for above rgetPromise to resolve, returning a Promise<BusinessRuleResult> for validation here is too slow and
* does not get captured by business rules.
*/
if (
resolvedCoType?.get('taxonTreeDef') ===
(taxon?.get('definition') ?? '')
) {
setSaveBlockers(
determination as SpecifyResource<AnySchema>,
determination.specifyTable.field.taxon,
[],
DETERMINATION_TAXON_KEY
);
} else {
setSaveBlockers(
determination as SpecifyResource<AnySchema>,
determination.specifyTable.field.taxon,
[formsText.invalidTree()],
DETERMINATION_TAXON_KEY
);
}
});
}

return taxon === null
? {
isValid: true,
Expand Down
7 changes: 5 additions & 2 deletions specifyweb/frontend/js_src/lib/components/DataModel/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ type Schema = {
'Institution'
];
readonly referenceSymbol: string;
readonly treeSymbol: string;
readonly treeDefinitionSymbol: string;
readonly treeRankSymbol: string;
readonly fieldPartSeparator: string;
};

Expand Down Expand Up @@ -64,8 +65,10 @@ const schemaBase: Writable<Schema> = {

// Prefix for -to-many indexes
referenceSymbol: '#',
// Prefix for Tree Definitions
treeDefinitionSymbol: '%',
// Prefix for tree ranks
treeSymbol: '$',
treeRankSymbol: '$',
// Separator for partial fields (date parts in Query Builder)
fieldPartSeparator: '-',
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ export const schemaExtras: {
indexed: false,
unique: false,
}),
new LiteralField(table, {
// TODO: LiteralField or Relationship?
name: 'age',
required: false,
readOnly: true,
type: 'java.lang.Integer',
indexed: false,
unique: false,
}),
],
(): void => {
const collection = getField(table, 'collection');
Expand Down
Loading

0 comments on commit 619f84b

Please sign in to comment.