diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index 2a10b0a9bf..a87e81efc6 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.55.2", + "version": "7.55.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.55.2", + "version": "7.55.3", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@hello-pangea/dnd": "18.0.1", diff --git a/packages/components/package.json b/packages/components/package.json index df3b7f07d5..f86f597e7a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.55.2", + "version": "7.55.3", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ diff --git a/packages/components/src/internal/components/container/FolderAPIWrapper.ts b/packages/components/src/internal/components/container/FolderAPIWrapper.ts index 963f0921a8..63f93503e5 100644 --- a/packages/components/src/internal/components/container/FolderAPIWrapper.ts +++ b/packages/components/src/internal/components/container/FolderAPIWrapper.ts @@ -5,7 +5,7 @@ import { ActionURL, Ajax, Utils } from '@labkey/api'; import { Container } from '../base/models/Container'; -import { handleRequestFailure } from '../../request'; +import { handleRequestFailure, request } from '../../request'; import { SAMPLE_MANAGER_APP_PROPERTIES } from '../../app/constants'; import { FolderConfigurableDataType } from '../entities/models'; import { getFolderDataTypeExclusions } from '../entities/actions'; @@ -54,7 +54,7 @@ export interface FolderAPIWrapper { excludeArchived?: boolean ) => Promise; getDataTypeExcludedContainers: (dataType: FolderConfigurableDataType, dataTypeRowId: number) => Promise; - getFolderDataTypeExclusions: (excludedContainer?: string, reload?: boolean) => Promise<{ [key: string]: number[] }>; + getFolderDataTypeExclusions: (excludedContainer?: string, reload?: boolean) => Promise>; getMultipleDataTypeExcludedContainers: ( dataType: FolderConfigurableDataType, dataTypeRowIds: number[] @@ -87,7 +87,7 @@ export class ServerFolderAPIWrapper implements FolderAPIWrapper { }); }; - archiveFolder = (archive: boolean = true, containerPath?: string): Promise => { + archiveFolder = (archive = true, containerPath?: string): Promise => { return new Promise((resolve, reject) => { Ajax.request({ url: ActionURL.buildURL( @@ -126,22 +126,16 @@ export class ServerFolderAPIWrapper implements FolderAPIWrapper { }; getAuditSettings = (containerPath?: string): Promise => { - return new Promise((resolve, reject) => { - Ajax.request({ - url: ActionURL.buildURL('audit', 'getAuditSettings', containerPath), - method: 'POST', - success: Utils.getCallbackWrapper(response => { - resolve(response); - }), - failure: handleRequestFailure(reject, 'Failed to retrieve audit settings.'), - }); + return request({ + url: ActionURL.buildURL('audit', 'getAuditSettings.api', containerPath), + errorLogMsg: 'Failed to retrieve audit settings.', }); }; setAuditCommentsRequired = (requireUserComments: boolean, containerPath?: string): Promise => { return new Promise((resolve, reject) => { Ajax.request({ - url: ActionURL.buildURL('audit', 'saveAuditSettings', containerPath), + url: ActionURL.buildURL('audit', 'saveAuditSettings.api', containerPath), method: 'POST', jsonData: { requireUserComments }, success: Utils.getCallbackWrapper(() => { @@ -197,7 +191,6 @@ export class ServerFolderAPIWrapper implements FolderAPIWrapper { return new Promise((resolve, reject) => { Ajax.request({ url: ActionURL.buildURL(SAMPLE_MANAGER_APP_PROPERTIES.controllerName, 'getDataTypeExclusion.api'), - method: 'GET', params: { dataType, dataTypeRowId, @@ -230,7 +223,7 @@ export class ServerFolderAPIWrapper implements FolderAPIWrapper { } return new Promise((resolve, reject) => { - const promises: Array>> = []; + const promises: Promise>[] = []; dataTypeRowIds.forEach(id => { promises.push(this.getDataTypeExcludedContainersAsRecord(dataType, id)); diff --git a/packages/components/src/internal/components/forms/formsy/Formsy.test.tsx b/packages/components/src/internal/components/forms/formsy/Formsy.test.tsx index 3a1ce27a63..d35cbd94e9 100644 --- a/packages/components/src/internal/components/forms/formsy/Formsy.test.tsx +++ b/packages/components/src/internal/components/forms/formsy/Formsy.test.tsx @@ -1,7 +1,7 @@ // This file was originally derived from the "formsy-react" package, specifically, v2.3.2. // Credit: Christian Alfoni and the Formsy Authors // Repository: https://github.com/formsy/formsy-react/tree/0226fab133a25 -import React, { act, FC, memo, PropsWithChildren, useCallback, useRef, useState } from 'react'; +import React, { act, FC, memo, PropsWithChildren, useCallback, useMemo, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { createEvent, fireEvent, render } from '@testing-library/react'; import { userEvent } from '@testing-library/user-event'; @@ -448,6 +448,55 @@ describe('Formsy', () => { }); }); + describe('validation messages', () => { + // Mirrors an input whose error message is enriched by data that only starts loading once the validation + // failure is known, so the message changes while the rules and the value stay put. + const AsyncMessageForm: FC = () => { + const [isRegistered, setIsRegistered] = useState(false); + const [canAssociate, setCanAssociate] = useState(false); + const validations = useMemo(() => ({ isNotRegistered: isRegistered }), [isRegistered]); + const validationErrors = useMemo( + () => ({ isNotRegistered: canAssociate ? 'Already registered. Associate?' : 'Already registered.' }), + [canAssociate] + ); + const onRegister = useCallback(() => setIsRegistered(true), []); + const onAssociate = useCallback(() => setCanAssociate(true), []); + + return ( + <> + + + +