From a2e8bc2977caa0d2a7b7c686a8a8f293a9c68c01 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 11:14:07 -0600 Subject: [PATCH 01/10] GitHub Issue 503: Field editor URL option to set target window (i.e. _blank) --- .../components/releaseNotes/components.md | 4 ++ .../NameAndLinkingOptions.tsx | 40 ++++++++++++++----- .../components/domainproperties/constants.ts | 1 + .../components/domainproperties/models.tsx | 12 ++++++ .../src/theme/domainproperties.scss | 2 +- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/packages/components/releaseNotes/components.md b/packages/components/releaseNotes/components.md index 65fdbe2874..6a42cae7c2 100644 --- a/packages/components/releaseNotes/components.md +++ b/packages/components/releaseNotes/components.md @@ -1,6 +1,10 @@ # @labkey/components Components, models, actions, and utility functions for LabKey applications and pages +### version TBD +*Released*: TBD +- GitHub Issue 503: Field editor URL option to set target window (i.e. _blank) + ### version 7.7.1 *Released*: 29 December 2025 - [GitHub Issue 734](https://github.com/LabKey/internal-issues/issues/734) Update sizing of comment input box for better display in narrow screens diff --git a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx index 292762ecfb..5faeea8aa8 100644 --- a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx +++ b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx @@ -16,6 +16,7 @@ import { DOMAIN_FIELD_LABEL, DOMAIN_FIELD_ONTOLOGY_PRINCIPAL_CONCEPT, DOMAIN_FIELD_URL, + DOMAIN_FIELD_URL_TARGET_WINDOW, } from './constants'; import { DomainField, IDomainFormDisplayOptions } from './models'; import { SectionHeading } from './SectionHeading'; @@ -39,6 +40,12 @@ export class NameAndLinkingOptions extends PureComponent { this.props?.onChange(id, value); }; + handleURLTargetWindowChange = (evt: any): void => { + const id = evt.target.id; + const isChecked = evt.target.checked; + this.onChange(id, isChecked ? '_blank' : null); + }; + getImportAliasHelpText = (): ReactNode => { return ( <> @@ -120,6 +127,16 @@ export class NameAndLinkingOptions extends PureComponent { )}
+ {!appPropertiesOnly && + hasModule(ONTOLOGY_MODULE_NAME) && + !field.isUniqueIdField() && + !field.isCalculatedField() && ( + + )}
@@ -132,16 +149,19 @@ export class NameAndLinkingOptions extends PureComponent { onChange={this.handleChange} disabled={isFieldFullyLocked(field.lockType)} /> - {!appPropertiesOnly && - hasModule(ONTOLOGY_MODULE_NAME) && - !field.isUniqueIdField() && - !field.isCalculatedField() && ( - - )} + {/*GitHub Issue 503: Field editor URL option to set target window (i.e. _blank)*/} +
+ + Open links in a new tab +
diff --git a/packages/components/src/internal/components/domainproperties/constants.ts b/packages/components/src/internal/components/domainproperties/constants.ts index 7525f0dce1..7d1511ebf3 100644 --- a/packages/components/src/internal/components/domainproperties/constants.ts +++ b/packages/components/src/internal/components/domainproperties/constants.ts @@ -27,6 +27,7 @@ export const DOMAIN_FIELD_DESCRIPTION = 'description'; export const DOMAIN_FIELD_LABEL = 'label'; export const DOMAIN_FIELD_IMPORTALIASES = 'importAliases'; export const DOMAIN_FIELD_URL = 'URL'; +export const DOMAIN_FIELD_URL_TARGET_WINDOW = 'URLTargetWindow'; export const DOMAIN_FIELD_LOOKUP_CONTAINER = 'lookupContainer'; export const DOMAIN_FIELD_LOOKUP_QUERY = 'lookupQueryValue'; export const DOMAIN_FIELD_LOOKUP_SCHEMA = 'lookupSchema'; diff --git a/packages/components/src/internal/components/domainproperties/models.tsx b/packages/components/src/internal/components/domainproperties/models.tsx index 50326689f3..28766ccafb 100644 --- a/packages/components/src/internal/components/domainproperties/models.tsx +++ b/packages/components/src/internal/components/domainproperties/models.tsx @@ -914,6 +914,7 @@ export interface IDomainField { uniqueConstraint?: boolean; updatedField: boolean; URL?: string; + URLTargetWindow?: string; visible: boolean; } @@ -985,6 +986,7 @@ export class DomainField required: false, scale: MAX_TEXT_LENGTH, URL: undefined, + URLTargetWindow: undefined, shownInDetailsView: true, shownInInsertView: true, shownInUpdateView: true, @@ -1047,6 +1049,7 @@ export class DomainField declare scale?: number; declare scannable?: boolean; declare URL?: string; + declare URLTargetWindow?: string; declare shownInDetailsView?: boolean; declare shownInInsertView?: boolean; declare shownInUpdateView?: boolean; @@ -1190,6 +1193,11 @@ export class DomainField field.rangeURI = raw.rangeURI; } + // handle URLTargetWindow prop casing mismatch + if (raw['urltargetWindow']) { + field.URLTargetWindow = raw['urltargetWindow']; + } + return field; } @@ -1215,6 +1223,10 @@ export class DomainField json.url = json.URL; delete json.URL; } + if (json.URLTargetWindow !== undefined) { + json.urlTargetWindow = json.URLTargetWindow; + delete json.URLTargetWindow; + } if (json.PHI !== undefined) { json.phi = json.PHI; delete json.PHI; diff --git a/packages/components/src/theme/domainproperties.scss b/packages/components/src/theme/domainproperties.scss index 17bf43d2c0..ab4e697cd3 100644 --- a/packages/components/src/theme/domainproperties.scss +++ b/packages/components/src/theme/domainproperties.scss @@ -359,7 +359,7 @@ margin: 6px 20px 0 0 !important; } -.domain-text-option-scannable { +.domain-text-option-scannable, .domain-text-option-urltargetwindow { display: inline; } From 0e1f744c2374cd498e6bf318693f1940a8c0e374 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 11:14:48 -0600 Subject: [PATCH 02/10] 7.7.1-fb-urlTargetWindow503.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 313278a3a9..a90913831f 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.7.1", + "version": "7.7.1-fb-urlTargetWindow503.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.7.1", + "version": "7.7.1-fb-urlTargetWindow503.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 86bfb757f7..5acb839011 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.7.1", + "version": "7.7.1-fb-urlTargetWindow503.0", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From df04608526dc43f4e29a21d40226a4225370ec2b Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 13:36:46 -0600 Subject: [PATCH 03/10] Fix casing issue with urltargetWindow --- .../src/internal/components/domainproperties/models.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/internal/components/domainproperties/models.tsx b/packages/components/src/internal/components/domainproperties/models.tsx index 28766ccafb..c01053c58a 100644 --- a/packages/components/src/internal/components/domainproperties/models.tsx +++ b/packages/components/src/internal/components/domainproperties/models.tsx @@ -1224,7 +1224,7 @@ export class DomainField delete json.URL; } if (json.URLTargetWindow !== undefined) { - json.urlTargetWindow = json.URLTargetWindow; + json.urltargetWindow = json.URLTargetWindow; // note casing because of GWTPropertyDescriptor behavior on server side delete json.URLTargetWindow; } if (json.PHI !== undefined) { From 1eeee975dc2a3d1b905cafb5edee1ac26a9fd919 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 13:37:40 -0600 Subject: [PATCH 04/10] 7.7.1-fb-urlTargetWindow503.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 a90913831f..7d95edb0ac 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.0", + "version": "7.7.1-fb-urlTargetWindow503.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.0", + "version": "7.7.1-fb-urlTargetWindow503.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 5acb839011..0c03453298 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.0", + "version": "7.7.1-fb-urlTargetWindow503.1", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 284d8b380fc02ac25cebdfb9b4e6936feacf0b3b Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 14:08:16 -0600 Subject: [PATCH 05/10] urlTargetWindow -> urlTarget --- .../domainproperties/NameAndLinkingOptions.tsx | 14 +++++++------- .../components/domainproperties/constants.ts | 2 +- .../components/domainproperties/models.tsx | 18 +++++++++--------- .../components/src/theme/domainproperties.scss | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx index 5faeea8aa8..5d5c64eb16 100644 --- a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx +++ b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.tsx @@ -16,7 +16,7 @@ import { DOMAIN_FIELD_LABEL, DOMAIN_FIELD_ONTOLOGY_PRINCIPAL_CONCEPT, DOMAIN_FIELD_URL, - DOMAIN_FIELD_URL_TARGET_WINDOW, + DOMAIN_FIELD_URL_TARGET, } from './constants'; import { DomainField, IDomainFormDisplayOptions } from './models'; import { SectionHeading } from './SectionHeading'; @@ -40,7 +40,7 @@ export class NameAndLinkingOptions extends PureComponent { this.props?.onChange(id, value); }; - handleURLTargetWindowChange = (evt: any): void => { + handleURLTargetChange = (evt: any): void => { const id = evt.target.id; const isChecked = evt.target.checked; this.onChange(id, isChecked ? '_blank' : null); @@ -153,11 +153,11 @@ export class NameAndLinkingOptions extends PureComponent {
Open links in a new tab diff --git a/packages/components/src/internal/components/domainproperties/constants.ts b/packages/components/src/internal/components/domainproperties/constants.ts index 7d1511ebf3..80aba4c72c 100644 --- a/packages/components/src/internal/components/domainproperties/constants.ts +++ b/packages/components/src/internal/components/domainproperties/constants.ts @@ -27,7 +27,7 @@ export const DOMAIN_FIELD_DESCRIPTION = 'description'; export const DOMAIN_FIELD_LABEL = 'label'; export const DOMAIN_FIELD_IMPORTALIASES = 'importAliases'; export const DOMAIN_FIELD_URL = 'URL'; -export const DOMAIN_FIELD_URL_TARGET_WINDOW = 'URLTargetWindow'; +export const DOMAIN_FIELD_URL_TARGET = 'URLTarget'; export const DOMAIN_FIELD_LOOKUP_CONTAINER = 'lookupContainer'; export const DOMAIN_FIELD_LOOKUP_QUERY = 'lookupQueryValue'; export const DOMAIN_FIELD_LOOKUP_SCHEMA = 'lookupSchema'; diff --git a/packages/components/src/internal/components/domainproperties/models.tsx b/packages/components/src/internal/components/domainproperties/models.tsx index c01053c58a..9e4c20b49f 100644 --- a/packages/components/src/internal/components/domainproperties/models.tsx +++ b/packages/components/src/internal/components/domainproperties/models.tsx @@ -914,7 +914,7 @@ export interface IDomainField { uniqueConstraint?: boolean; updatedField: boolean; URL?: string; - URLTargetWindow?: string; + URLTarget?: string; visible: boolean; } @@ -986,7 +986,7 @@ export class DomainField required: false, scale: MAX_TEXT_LENGTH, URL: undefined, - URLTargetWindow: undefined, + URLTarget: undefined, shownInDetailsView: true, shownInInsertView: true, shownInUpdateView: true, @@ -1049,7 +1049,7 @@ export class DomainField declare scale?: number; declare scannable?: boolean; declare URL?: string; - declare URLTargetWindow?: string; + declare URLTarget?: string; declare shownInDetailsView?: boolean; declare shownInInsertView?: boolean; declare shownInUpdateView?: boolean; @@ -1193,9 +1193,9 @@ export class DomainField field.rangeURI = raw.rangeURI; } - // handle URLTargetWindow prop casing mismatch - if (raw['urltargetWindow']) { - field.URLTargetWindow = raw['urltargetWindow']; + // handle URLTarget prop casing mismatch + if (raw['urltarget']) { + field.URLTarget = raw['urltarget']; } return field; @@ -1223,9 +1223,9 @@ export class DomainField json.url = json.URL; delete json.URL; } - if (json.URLTargetWindow !== undefined) { - json.urltargetWindow = json.URLTargetWindow; // note casing because of GWTPropertyDescriptor behavior on server side - delete json.URLTargetWindow; + if (json.URLTarget !== undefined) { + json.urltarget = json.URLTarget; // note casing because of GWTPropertyDescriptor behavior on server side + delete json.URLTarget; } if (json.PHI !== undefined) { json.phi = json.PHI; diff --git a/packages/components/src/theme/domainproperties.scss b/packages/components/src/theme/domainproperties.scss index ab4e697cd3..d3633a010e 100644 --- a/packages/components/src/theme/domainproperties.scss +++ b/packages/components/src/theme/domainproperties.scss @@ -359,7 +359,7 @@ margin: 6px 20px 0 0 !important; } -.domain-text-option-scannable, .domain-text-option-urltargetwindow { +.domain-text-option-scannable, .domain-text-option-urltarget { display: inline; } From 17b258bb76b6227a29e1ffa61b6e3b2f88e70aad Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 14:08:56 -0600 Subject: [PATCH 06/10] 7.7.1-fb-urlTargetWindow503.2 --- 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 7d95edb0ac..ffa9614847 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.1", + "version": "7.7.1-fb-urlTargetWindow503.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.1", + "version": "7.7.1-fb-urlTargetWindow503.2", "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 0c03453298..8dfb895c10 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.1", + "version": "7.7.1-fb-urlTargetWindow503.2", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 33b04e192536853004984c674fc67792b35f19a7 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 14:47:37 -0600 Subject: [PATCH 07/10] add URLTarget to domain field summary grid --- .../src/internal/components/domainproperties/models.tsx | 9 ++++++++- .../components/domainproperties/propertiesUtil.ts | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/components/src/internal/components/domainproperties/models.tsx b/packages/components/src/internal/components/domainproperties/models.tsx index 9e4c20b49f..c199713296 100644 --- a/packages/components/src/internal/components/domainproperties/models.tsx +++ b/packages/components/src/internal/components/domainproperties/models.tsx @@ -549,7 +549,14 @@ export class DomainDesign if (!showFilterCriteria) delete columns.filterCriteria; const unsortedColumns = List( - Object.keys(columns).map(key => ({ index: key, caption: camelCaseToTitleCase(key), sortable: true })) + Object.keys(columns).map(key => { + let caption = camelCaseToTitleCase(key); + // special case for url and urltarget + if (key.toLowerCase() === 'url') caption = 'URL'; + if (key.toLowerCase() === 'urltarget') caption = 'URL Target'; + + return { index: key, caption, sortable: true }; + }) ); return specialCols.concat(unsortedColumns.sort(reorderSummaryColumns)).toList(); } diff --git a/packages/components/src/internal/components/domainproperties/propertiesUtil.ts b/packages/components/src/internal/components/domainproperties/propertiesUtil.ts index 1858fb1dda..9efbce3b2a 100644 --- a/packages/components/src/internal/components/domainproperties/propertiesUtil.ts +++ b/packages/components/src/internal/components/domainproperties/propertiesUtil.ts @@ -147,6 +147,7 @@ export function reorderSummaryColumns(a: DomainPropertiesGridColumn, b: DomainPr 'label', 'importAliases', 'url', + 'urltarget', 'conditionalFormats', 'propertyValidators', 'valueExpression', From 9b7ede1105061ddf78a81e925e364270792eb244 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 14:48:10 -0600 Subject: [PATCH 08/10] 7.7.1-fb-urlTargetWindow503.3 --- 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 ffa9614847..ca46566fff 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.2", + "version": "7.7.1-fb-urlTargetWindow503.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.2", + "version": "7.7.1-fb-urlTargetWindow503.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 8dfb895c10..437ccf70d8 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.7.1-fb-urlTargetWindow503.2", + "version": "7.7.1-fb-urlTargetWindow503.3", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [ From 103b1d396f9455acfcae8b0bed172df563d72e98 Mon Sep 17 00:00:00 2001 From: cnathe Date: Tue, 30 Dec 2025 15:56:44 -0600 Subject: [PATCH 09/10] jest test updates --- .../NameAndLinkingOptions.test.tsx | 34 +++++++++++++++++++ .../NameAndLinkingOptions.test.tsx.snap | 14 ++++++++ .../domainproperties/models.test.ts | 9 +++++ 3 files changed, 57 insertions(+) diff --git a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.test.tsx b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.test.tsx index beaafddf61..4511cec5cd 100644 --- a/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.test.tsx +++ b/packages/components/src/internal/components/domainproperties/NameAndLinkingOptions.test.tsx @@ -5,10 +5,12 @@ import { createFormInputId } from './utils'; import { CALCULATED_CONCEPT_URI, DOMAIN_FIELD_DESCRIPTION, + DOMAIN_FIELD_FULLY_LOCKED, DOMAIN_FIELD_IMPORTALIASES, DOMAIN_FIELD_LABEL, DOMAIN_FIELD_ONTOLOGY_PRINCIPAL_CONCEPT, DOMAIN_FIELD_URL, + DOMAIN_FIELD_URL_TARGET, STORAGE_UNIQUE_ID_CONCEPT_URI, STRING_RANGE_URI, } from './constants'; @@ -29,6 +31,7 @@ const field = DomainField.create({ label: _label, importAliases: _importAliases, URL: _URL, + URLTarget: '_blank', propertyURI: 'test', }); @@ -50,6 +53,15 @@ const calculatedField = DomainField.create({ conceptURI: CALCULATED_CONCEPT_URI, }); +const lockedField = DomainField.create({ + name: 'lockedField', + rangeURI: STRING_RANGE_URI, + propertyId: 3, + description: 'locked field desc', + label: 'Locked Field', + lockType: DOMAIN_FIELD_FULLY_LOCKED, +}); + const DEFAULT_PROPS = { index: 1, domainIndex: 1, @@ -73,21 +85,31 @@ describe('NameAndLinkingOptions', () => { let formField = document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_DESCRIPTION, 1, 1)); expect(formField.length).toEqual(1); expect(formField[0].textContent).toEqual(_description); + expect(formField[0].hasAttribute('disabled')).toEqual(false); // Label formField = document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_LABEL, 1, 1)); expect(formField.length).toEqual(1); expect(formField[0].getAttribute('value')).toEqual(_label); + expect(formField[0].hasAttribute('disabled')).toEqual(false); // Aliases formField = document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_IMPORTALIASES, 1, 1)); expect(formField.length).toEqual(1); expect(formField[0].getAttribute('value')).toEqual(_importAliases); + expect(formField[0].hasAttribute('disabled')).toEqual(false); // URL formField = document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_URL, 1, 1)); expect(formField.length).toEqual(1); expect(formField[0].getAttribute('value')).toEqual(_URL); + expect(formField[0].hasAttribute('disabled')).toEqual(false); + + // URL Target + formField = document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_URL_TARGET, 1, 1)); + expect(formField.length).toEqual(1); + expect(formField[0].hasAttribute('checked')).toEqual(true); + expect(formField[0].hasAttribute('disabled')).toEqual(false); expect(container).toMatchSnapshot(); }); @@ -119,6 +141,9 @@ describe('NameAndLinkingOptions', () => { test('calculated field', () => { render(); expect(document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_IMPORTALIASES, 1, 1))).toHaveLength(0); + + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_URL, 1, 1)).getAttribute('value')).toEqual(''); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_URL_TARGET, 1, 1)).hasAttribute('checked')).toEqual(false); }); test('hideImportAliases', () => { @@ -132,4 +157,13 @@ describe('NameAndLinkingOptions', () => { ); expect(document.querySelectorAll('#' + createFormInputId(DOMAIN_FIELD_IMPORTALIASES, 1, 1))).toHaveLength(0); }); + + test('locked field', () => { + render(); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_LABEL, 1, 1)).hasAttribute('disabled')).toEqual(true); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_DESCRIPTION, 1, 1)).hasAttribute('disabled')).toEqual(true); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_IMPORTALIASES, 1, 1)).hasAttribute('disabled')).toEqual(true); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_URL, 1, 1)).hasAttribute('disabled')).toEqual(true); + expect(document.querySelector('#' + createFormInputId(DOMAIN_FIELD_URL_TARGET, 1, 1)).hasAttribute('disabled')).toEqual(true); + }); }); diff --git a/packages/components/src/internal/components/domainproperties/__snapshots__/NameAndLinkingOptions.test.tsx.snap b/packages/components/src/internal/components/domainproperties/__snapshots__/NameAndLinkingOptions.test.tsx.snap index 4ac4b5d759..6d6ea29fa3 100644 --- a/packages/components/src/internal/components/domainproperties/__snapshots__/NameAndLinkingOptions.test.tsx.snap +++ b/packages/components/src/internal/components/domainproperties/__snapshots__/NameAndLinkingOptions.test.tsx.snap @@ -110,6 +110,20 @@ exports[`NameAndLinkingOptions Name and Linking options 1`] = ` type="text" value="This is a URL" /> +
+ + + Open links in a new tab + +
diff --git a/packages/components/src/internal/components/domainproperties/models.test.ts b/packages/components/src/internal/components/domainproperties/models.test.ts index 1e4adbe6e1..1b5e02acdc 100644 --- a/packages/components/src/internal/components/domainproperties/models.test.ts +++ b/packages/components/src/internal/components/domainproperties/models.test.ts @@ -122,6 +122,7 @@ const gridDataAppPropsOnlyConst = [ scale: 4000, name: 'a', URL: '', + URLTarget: '', conceptURI: '', rangeURI: 'http://www.w3.org/2001/XMLSchema#int', PHI: '', @@ -188,6 +189,7 @@ const nameCol = new GridColumn({ const gridColumnsConst = [ selectionCol, nameCol, + { index: 'URLTarget', caption: 'URL Target', sortable: true }, { index: 'URL', caption: 'URL', sortable: true }, { index: 'PHI', caption: 'PHI', sortable: true }, { index: 'rangeURI', caption: 'Range URI', sortable: true }, @@ -1490,6 +1492,13 @@ describe('resolveBaseProperties', () => { DOMAIN_FIELD_PARTIALLY_LOCKED ); }); + + test('URLTarget', () => { + expect(DomainField.resolveBaseProperties({}).URLTarget).toBeUndefined(); + expect(DomainField.resolveBaseProperties({ URLTarget: '_self' }).URLTarget).toBeUndefined(); + expect(DomainField.resolveBaseProperties({ urltarget: '_self' }).URLTarget).toBe('_self'); + expect(DomainField.resolveBaseProperties({ urltarget: '_blank' }).URLTarget).toBe('_blank'); + }); }); describe('resolveLookupQueryValue', () => { From ec297a4394adbd8fda32f1b6f80da7fca7fbcbdd Mon Sep 17 00:00:00 2001 From: cnathe Date: Fri, 2 Jan 2026 10:39:09 -0600 Subject: [PATCH 10/10] 7.7.3-fb-urlTargetWindow503.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 08e20f7140..d4b8f1e16d 100644 --- a/packages/components/package-lock.json +++ b/packages/components/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/components", - "version": "7.7.3", + "version": "7.7.3-fb-urlTargetWindow503.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/components", - "version": "7.7.3", + "version": "7.7.3-fb-urlTargetWindow503.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 ae0ca2eba2..69cb3c3a95 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/components", - "version": "7.7.3", + "version": "7.7.3-fb-urlTargetWindow503.0", "description": "Components, models, actions, and utility functions for LabKey applications and pages", "sideEffects": false, "files": [