From 78cc0a97ecbb8fe3163f15c4529d6c9427eee0a6 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 17 Feb 2026 08:49:43 -0600 Subject: [PATCH 1/9] GitHub Issue 830: Assay design add transform script webdav path doesn't resolve from subfolder - AssayProtocolModel.container to compare domain id to the container.parentId to get parentPath when applicable --- packages/components/jest.config.js | 3 ++ .../components/releaseNotes/components.md | 5 +++ .../domainproperties/assay/models.test.ts | 38 +++++++++++++++++++ .../domainproperties/assay/models.ts | 14 ++++--- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/packages/components/jest.config.js b/packages/components/jest.config.js index 01ac6e87bd..39fbf01ba8 100644 --- a/packages/components/jest.config.js +++ b/packages/components/jest.config.js @@ -7,7 +7,10 @@ module.exports = { LABKEY: { contextPath: '/labkey', container: { + id: 'e28ed3a3-4d74-103b-9678-6554da263543', path: '/DefaultTestContainer', + parentId: '01b94403-4179-1039-a799-ea54f212702c', + parentPath: '/ParentTestContainer', formats: { dateFormat: "yyyy-MM-dd", dateTimeFormat: "yyyy-MM-dd HH:mm", diff --git a/packages/components/releaseNotes/components.md b/packages/components/releaseNotes/components.md index 8358be645f..b153473dc6 100644 --- a/packages/components/releaseNotes/components.md +++ b/packages/components/releaseNotes/components.md @@ -1,6 +1,11 @@ # @labkey/components Components, models, actions, and utility functions for LabKey applications and pages +### version TBD +*Released*: TBD February 2026 +- GitHub Issue 830: Assay design add transform script webdav path doesn't resolve from subfolder + - AssayProtocolModel.container to compare domain id to the container.parentId to get parentPath when applicable + ### version 7.18.0 *Released*: 17 February 2026 - Update `FilterStatus` to optionally include an "Add Filter" button diff --git a/packages/components/src/internal/components/domainproperties/assay/models.test.ts b/packages/components/src/internal/components/domainproperties/assay/models.test.ts index 632bf625a3..79344ff38f 100644 --- a/packages/components/src/internal/components/domainproperties/assay/models.test.ts +++ b/packages/components/src/internal/components/domainproperties/assay/models.test.ts @@ -289,6 +289,44 @@ describe('AssayProtocolModel', () => { expect(existingModel.container).toBe('Test Container'); }); + test('by container id', () => { + let existingModel = AssayProtocolModel.create({ + protocolId: 1, + name: 'Test Assay Protocol', + domains: [ + { + name: 'Sample Fields', + container: 'e28ed3a3-4d74-103b-9678-6554da263543', // see jest.config.js + }, + ], + }); + expect(existingModel.container).toBe('/DefaultTestContainer'); + + existingModel = AssayProtocolModel.create({ + protocolId: 1, + name: 'Test Assay Protocol', + domains: [ + { + name: 'Sample Fields', + container: '01b94403-4179-1039-a799-ea54f212702c', // see jest.config.js + }, + ], + }); + expect(existingModel.container).toBe('/ParentTestContainer'); + + existingModel = AssayProtocolModel.create({ + protocolId: 1, + name: 'Test Assay Protocol', + domains: [ + { + name: 'Sample Fields', + container: '01b94403-bogus-ea54f212702c', + }, + ], + }); + expect(existingModel.container).toBe('01b94403-bogus-ea54f212702c'); + }); + test('domainContainerId', () => { const newModel = AssayProtocolModel.create({ name: 'Test Assay Protocol', diff --git a/packages/components/src/internal/components/domainproperties/assay/models.ts b/packages/components/src/internal/components/domainproperties/assay/models.ts index 3a9ed1cc6e..b66ead8a45 100644 --- a/packages/components/src/internal/components/domainproperties/assay/models.ts +++ b/packages/components/src/internal/components/domainproperties/assay/models.ts @@ -167,12 +167,14 @@ export class AssayProtocolModel extends ImmutableRecord({ get container(): string { const container = new Container(getServerContext().container); const domainContainerId = this.domainContainerId; - - return this.isNew() - ? getAppHomeFolderPath(container) - : domainContainerId === container.id - ? container.path - : domainContainerId; + const domainContainerPath = + domainContainerId === container.id + ? container.path + : domainContainerId === container.parentId + ? container.parentPath + : domainContainerId; + + return this.isNew() ? getAppHomeFolderPath(container) : domainContainerPath; } get domainContainerId(): string { From c21f811b57784ec9a2b4eedb8dcf470c7bd043ca Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 17 Feb 2026 08:50:24 -0600 Subject: [PATCH 2/9] 7.18.0-fb-transormSubfolder.0 --- packages/components/package-lock.json | 4 ++-- packages/components/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index ce7a24c328..afa32c14e2 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.18.0", + "version": "7.18.0-fb-transormSubfolder.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.18.0", + "version": "7.18.0-fb-transormSubfolder.0", "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 85a658ba0d..9918805921 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.18.0", + "version": "7.18.0-fb-transormSubfolder.0", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 36c21eae0d3d6b2c14deac58834fe0c45610a3fc Mon Sep 17 00:00:00 2001 From: cnathe Date: Thu, 19 Feb 2026 08:16:44 -0600 Subject: [PATCH 3/9] 7.20.0-fb-transformSubfolder.0 --- packages/components/package-lock.json | 4 ++-- packages/components/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index bf2c0adf3a..6511f6045d 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.20.0", + "version": "7.20.0-fb-transformSubfolder.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.20.0", + "version": "7.20.0-fb-transformSubfolder.0", "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 53b3e1755a..28a3e22ea8 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.20.0", + "version": "7.20.0-fb-transformSubfolder.0", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 29a6501d1ba60d0c1550196b635ca2efc0809435 Mon Sep 17 00:00:00 2001 From: cnathe Date: Thu, 19 Feb 2026 08:54:48 -0600 Subject: [PATCH 4/9] TransformScriptsInput to resolve the domain containerId to the containerPath to use for webdav operations --- .../components/releaseNotes/components.md | 1 + .../assay/AssayPropertiesInput.tsx | 39 ++++++++++++++----- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/packages/components/releaseNotes/components.md b/packages/components/releaseNotes/components.md index e48060899d..59e7befd84 100644 --- a/packages/components/releaseNotes/components.md +++ b/packages/components/releaseNotes/components.md @@ -5,6 +5,7 @@ Components, models, actions, and utility functions for LabKey applications and p *Released*: TBD February 2026 - GitHub Issue 830: Assay design add transform script webdav path doesn't resolve from subfolder - AssayProtocolModel.container to compare domain id to the container.parentId to get parentPath when applicable + - TransformScriptsInput to resolve the domain containerId to the containerPath to use for webdav operations ### version 7.20.0 *Released*: 18 February 2026 diff --git a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx index 2c3f515419..f165eae41a 100644 --- a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx +++ b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx @@ -33,6 +33,7 @@ import { AssayProtocolModel, ProtocolTransformScript } from './models'; import { FORM_IDS, SCRIPTS_DIR } from './constants'; import { getScriptEngineForExtension, getValidPublishTargets } from './actions'; import { useFilterCriteriaContext } from './FilterCriteriaContext'; +import { fetchContainers } from '../../permissions/actions'; interface AssayPropertiesInputProps extends DomainFieldLabelProps, PropsWithChildren { colSize?: number; @@ -426,11 +427,30 @@ interface TransformScriptsInputProps { interface TransformScriptsInputState { addingScript: AddingScriptType; addingScriptPath: string; + assayContainerPath: string; error: string; } export class TransformScriptsInput extends React.PureComponent { - readonly state = { error: undefined, addingScript: undefined, addingScriptPath: '' }; + readonly state = { error: undefined, addingScript: undefined, addingScriptPath: '', assayContainerPath: undefined }; + + async componentDidMount() { + const { model } = this.props; + + try { + // GitHub Issue 830: resolve the domain containerId to the containerPath to use for webdav operations + const assayContainerId = model.container; + const assayContainer = await fetchContainers({ + container: assayContainerId, + includeEffectivePermissions: false, + includeSubfolders: false, + includeStandardProperties: false, + }); + this.setState({ assayContainerPath: assayContainer?.[0]?.path ?? assayContainerId }); + } catch (error) { + console.error(error); + } + } toggleAddingScript = (): void => { this.setState(state => ({ @@ -464,13 +484,13 @@ export class TransformScriptsInput extends React.PureComponent => { if (this.state.addingScript !== AddingScriptType.path) return; - const { model } = this.props; + const { assayContainerPath } = this.state; this.setState({ error: undefined }); try { const value = this.state.addingScriptPath?.trim() ?? ''; if (value.length > 0) { - await getScriptEngineForExtension(getFileExtension(value), model.container); + await getScriptEngineForExtension(getFileExtension(value), assayContainerPath); this.addScript(value); } } catch (e) { @@ -481,15 +501,14 @@ export class TransformScriptsInput extends React.PureComponent): Promise => { if (this.state.addingScript !== AddingScriptType.file) return; - const { model } = this.props; + const { assayContainerPath } = this.state; this.setState({ error: undefined }); try { - await getScriptEngineForExtension(getFileExtension(files.first()?.name), model.container); - - const url = getWebDavUrl(model.container, SCRIPTS_DIR, false, true); + await getScriptEngineForExtension(getFileExtension(files.first()?.name), assayContainerPath); + const url = getWebDavUrl(assayContainerPath, SCRIPTS_DIR, false, true); const fileName = await uploadWebDavFileToUrl(files.first(), url, false); - const scriptFiles = await getWebDavFiles(model.container, SCRIPTS_DIR, false, true); + const scriptFiles = await getWebDavFiles(assayContainerPath, SCRIPTS_DIR, false, true); const filePath = scriptFiles.get('files')?.get(fileName)?.dataFileUrl; // dataFileUrl comes back encoded and with a "file://" prefix @@ -570,7 +589,7 @@ export class TransformScriptsInput extends React.PureComponent(); const protocolTransformAttachments = protocolTransformScripts .map(config => ({ @@ -709,7 +728,7 @@ export class TransformScriptsInput extends React.PureComponent
Date: Thu, 19 Feb 2026 09:02:17 -0600 Subject: [PATCH 5/9] TransformScriptsInput init state for assayContainerPath to model.container --- .../assay/AssayPropertiesInput.tsx | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx index f165eae41a..16e1b3bb96 100644 --- a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx +++ b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx @@ -432,23 +432,32 @@ interface TransformScriptsInputState { } export class TransformScriptsInput extends React.PureComponent { - readonly state = { error: undefined, addingScript: undefined, addingScriptPath: '', assayContainerPath: undefined }; + readonly state = { + error: undefined, + addingScript: undefined, + addingScriptPath: '', + assayContainerPath: this.props.model.container, + }; async componentDidMount() { const { model } = this.props; + // GitHub Issue 830: resolve the domain containerId to the containerPath to use for webdav operations + let assayContainerPath = model.container; try { - // GitHub Issue 830: resolve the domain containerId to the containerPath to use for webdav operations - const assayContainerId = model.container; const assayContainer = await fetchContainers({ - container: assayContainerId, + container: assayContainerPath, includeEffectivePermissions: false, includeSubfolders: false, includeStandardProperties: false, }); - this.setState({ assayContainerPath: assayContainer?.[0]?.path ?? assayContainerId }); + if (assayContainer?.length === 1) { + assayContainerPath = assayContainer[0].path; + } } catch (error) { console.error(error); + } finally { + this.setState({ assayContainerPath }); } } From 9484e60dc0c7c3c9e35b545fc781e429c74fc8e6 Mon Sep 17 00:00:00 2001 From: cnathe Date: Thu, 19 Feb 2026 09:02:44 -0600 Subject: [PATCH 6/9] 7.20.0-fb-transformSubfolder.1 --- packages/components/package-lock.json | 4 ++-- packages/components/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/package-lock.json b/packages/components/package-lock.json index 6511f6045d..a58ab9d724 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.20.0-fb-transformSubfolder.0", + "version": "7.20.0-fb-transformSubfolder.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.20.0-fb-transformSubfolder.0", + "version": "7.20.0-fb-transformSubfolder.1", "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 28a3e22ea8..de5d034d5f 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.20.0-fb-transformSubfolder.0", + "version": "7.20.0-fb-transformSubfolder.1", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 3801c46c4a5c84de3e71259da0eb1a9cda76e9b4 Mon Sep 17 00:00:00 2001 From: cnathe Date: Fri, 20 Feb 2026 13:47:25 -0600 Subject: [PATCH 7/9] npm run lint-branch-fix --- .../assay/AssayPropertiesInput.tsx | 136 +++++++++--------- .../domainproperties/assay/models.ts | 2 +- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx index 16e1b3bb96..245e68a69f 100644 --- a/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx +++ b/packages/components/src/internal/components/domainproperties/assay/AssayPropertiesInput.tsx @@ -76,32 +76,32 @@ interface InputProps { } export const NameInput: FC = memo(props => ( - + - + )); NameInput.displayName = 'NameInput'; export const DescriptionInput: FC = memo(props => ( A short description for this assay design.

} + hideAdvancedProperties={props.hideAdvancedProperties} + label="Description" >