Skip to content
4 changes: 2 additions & 2 deletions packages/components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@labkey/components",
"version": "6.39.0",
"version": "6.39.1",
"description": "Components, models, actions, and utility functions for LabKey applications and pages",
"sideEffects": false,
"files": [
Expand Down
6 changes: 6 additions & 0 deletions packages/components/releaseNotes/components.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# @labkey/components
Components, models, actions, and utility functions for LabKey applications and pages

### version 6.39.1
*Released*: 2 May 2025
- Issue 52979: App grid customize view doesn't expand lookup field with special char
- Issue 52472: Re-clicking the Source Types, Sample Types or Assay links in the mega menu removes the sort=Name parameter from the url
- Customize view available field data-fieldkey attribute to use encoded fieldKey values

### version 6.39.0
*Released*: 2 May 2025
- Export `getSourceDomainDefaultSystemFields`
Expand Down
4 changes: 4 additions & 0 deletions packages/components/src/internal/app/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ export function addSourcesSectionConfig(
emptyText: 'No source types have been defined',
filteredEmptyText: 'No source types available',
iconURL: imageURL('_images', 'source_type.svg'),
headerURLParams: { 'sourcetypegrid.sort': 'Name' }, // Issue 52472
});
if (user && userCanDesignSourceTypes(user)) {
sourcesMenuConfig = sourcesMenuConfig.merge({
Expand All @@ -596,6 +597,7 @@ export function getSamplesSectionConfig(user: User): MenuSectionConfig {
emptyText: 'No sample types have been defined',
filteredEmptyText: 'No sample types available',
iconURL: imageURL('_images', 'samples.svg'),
headerURLParams: { 'samplesetgrid.sort': 'Name' }, // Issue 52472
});
if (user && user.hasDesignSampleTypesPermission()) {
samplesMenuConfig = samplesMenuConfig.merge({
Expand All @@ -616,6 +618,7 @@ export function addAssaysSectionConfig(
emptyText: 'No assays have been defined',
filteredEmptyText: 'No assays available',
iconURL: imageURL('_images', 'assay.svg'),
headerURLParams: { 'allassaysgrid.sort': 'Name', 'activeassaysgrid.sort': 'Name' }, // Issue 52472
});
if (user && user.hasDesignAssaysPermission()) {
assaysMenuConfig = assaysMenuConfig.merge({
Expand Down Expand Up @@ -660,6 +663,7 @@ function getMediaSectionConfig(): MenuSectionConfig {
function getRegistrySectionConfig(): MenuSectionConfig {
return new MenuSectionConfig({
iconURL: imageURL('_images', 'molecule.svg'),
headerURLParams: { 'query.sort': 'Name' }, // Issue 52472
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export const ColumnChoice: FC<ColumnChoiceProps> = memo(props => {
false
);
const supportsExpand = !!onExpandColumn;
const colFieldKey = column.index;
const disabled = disabledMsg !== undefined;

// 46256: use encoded fieldKeyPath
Expand Down Expand Up @@ -136,12 +135,12 @@ export const ColumnChoice: FC<ColumnChoiceProps> = memo(props => {
);

return (
<div className="list-group-item flex" key={colFieldKey} data-fieldkey={colFieldKey}>
<div className="list-group-item flex" key={column.index} data-fieldkey={column.fieldKeyPath}>
Comment thread
cnathe marked this conversation as resolved.
{supportsExpand && (
<>
{parentFieldKeys.map((parent, index) => (
// eslint-disable-next-line react/no-array-index-key
<div className="field-expand-icon" key={`${colFieldKey}|${index}`} />
<div className="field-expand-icon" key={`${column.index}|${index}`} />
Comment thread
cnathe marked this conversation as resolved.
))}
<div className="field-expand-icon">
{column.isLookup() && !isExpanded && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,16 @@ export const ProductMenuSection: FC<MenuSectionProps> = memo(props => {
section.productId,
currentProductId,
containerPath,
undefined,
config.headerURLParams,
config.headerURLPart ?? section.key
);

if (headerURL instanceof AppURL) {
headerEl = <Link to={headerURL.toString()} className="menu-section-link">{label}</Link>;
headerEl = (
<Link to={headerURL.toString()} className="menu-section-link">
{label}
</Link>
);
} else {
headerEl = <a href={getHref(headerURL)}>{label}</a>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class ProductMenuModel extends Record({
});

return List<MenuSectionModel>(sections);
};
}

setLoadedSections(sections: List<MenuSectionModel>): ProductMenuModel {
return this.merge({
Expand Down Expand Up @@ -219,6 +219,7 @@ export class MenuSectionConfig extends Record({
filteredEmptyText: undefined,
emptyAppURL: undefined,
emptyURLText: 'Get started...',
headerURLParams: undefined,
headerURLPart: undefined,
headerText: undefined,
iconCls: undefined,
Expand All @@ -232,6 +233,7 @@ export class MenuSectionConfig extends Record({
declare filteredEmptyText?: string;
declare emptyAppURL?: AppURL;
declare emptyURLText: string;
declare headerURLParams: Record<string, any>;
declare headerURLPart: string;
declare headerText?: string;
declare iconCls?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { QueryColumn } from '../QueryColumn';

import { SCHEMAS } from '../../internal/schemas';

import { QueryModel } from './QueryModel';
import { QueryInfo } from '../QueryInfo';

import { QueryModel } from './QueryModel';

export const includedColumnsForCustomizationFilter = (column: QueryColumn, showAllColumns: boolean): boolean => {
const isAncestor = column.fieldKeyPath?.indexOf('/Ancestors') >= 0;
const isAncestorChild = column.fieldKeyPath?.indexOf('Ancestors/') >= 0;
Expand All @@ -34,12 +35,15 @@ export const includedColumnsForCustomizationFilter = (column: QueryColumn, showA

export const getExpandQueryInfo = async (queryInfo: QueryInfo, column: QueryColumn): Promise<QueryInfo> => {
const fkQueryInfo = await getQueryDetails({
fk: column.index,
fk: column.fieldKeyPath, // Issue 52979: use encoded fieldKeyPath
lookup: column.lookup,
schemaQuery: queryInfo.schemaQuery,
});
// For data classes, we want to limit the Ancestor filters to exclude 'Samples'
if (column.index === QueryColumn.ANCESTORS_PREFIX && queryInfo.schemaQuery.schemaName === SCHEMAS.DATA_CLASSES.SCHEMA) {
if (
column.fieldKey === QueryColumn.ANCESTORS_PREFIX &&
queryInfo.schemaQuery.schemaName === SCHEMAS.DATA_CLASSES.SCHEMA
) {
fkQueryInfo.columns = fkQueryInfo.columns.filter(
col => col.fieldKey !== 'Samples' && col.fieldKey !== 'MediaSamples'
);
Expand Down