-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Id prefixes in filters (#1124)
Issue #1015 When filtering by an id, do not include the prefix in the url query params. Do include the prefix in the display chip for active filters. Note: Does this need to be behind a feature flag? ![id-prefixes](https://github.com/user-attachments/assets/e37da985-db75-432d-8068-42c15f3470fd)
- Loading branch information
Showing
13 changed files
with
243 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
export enum IdPrefix { | ||
Annotation = 'AN', | ||
Dataset = 'DS', | ||
Deposition = 'CZCDP', | ||
Run = 'RN', | ||
TiltSeries = 'TS', | ||
} |
111 changes: 111 additions & 0 deletions
111
frontend/packages/data-portal/app/utils/idPrefixes.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { QueryParams } from 'app/constants/query' | ||
|
||
import { | ||
getPrefixedId, | ||
isFilterPrefixValid, | ||
removeIdPrefix, | ||
} from './idPrefixes' | ||
|
||
describe('removeIdPrefix()', () => { | ||
it('should extract numeric id from string', () => { | ||
const testCases = [ | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
input: 'id1', | ||
output: '1', | ||
}, | ||
{ | ||
queryParam: QueryParams.DatasetId, | ||
input: 'id-123', | ||
output: '123', | ||
}, | ||
{ | ||
queryParam: QueryParams.AnnotationId, | ||
input: 'id-1234', | ||
output: '1234', | ||
}, | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
input: 'xyz-123', | ||
output: '123', | ||
}, | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
input: 'id-0008', | ||
output: '0008', | ||
}, | ||
] | ||
|
||
testCases.forEach((testCase) => | ||
expect(removeIdPrefix(testCase.input, testCase.queryParam)).toEqual( | ||
testCase.output, | ||
), | ||
) | ||
}) | ||
it('should return the same string if the queryParam does not have a prefix', () => { | ||
const testCases = [ | ||
{ | ||
queryParam: QueryParams.AuthorName, | ||
input: 'Jane Doe', | ||
output: 'Jane Doe', | ||
}, | ||
] | ||
|
||
testCases.forEach((testCase) => | ||
expect(removeIdPrefix(testCase.input, testCase.queryParam)).toEqual( | ||
testCase.output, | ||
), | ||
) | ||
}) | ||
}) | ||
|
||
describe('getPrefixedId()', () => { | ||
it('should add prefix to id', () => { | ||
const testCases = [ | ||
{ queryParam: QueryParams.DepositionId, id: '123', output: 'CZCDP-123' }, | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
id: 'deposition-123', | ||
output: 'CZCDP-123', | ||
}, | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
id: 'deposition-123-456', | ||
output: 'CZCDP-123456', | ||
}, | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
id: 'deposition-0008', | ||
output: 'CZCDP-0008', | ||
}, | ||
] | ||
|
||
testCases.forEach((testCase) => | ||
expect(getPrefixedId(testCase.id, testCase.queryParam)).toEqual( | ||
testCase.output, | ||
), | ||
) | ||
}) | ||
}) | ||
|
||
describe('isFilterPrefixValid()', () => { | ||
it('should validate filter prefix', () => { | ||
const testCases = [ | ||
{ | ||
queryParam: QueryParams.DepositionId, | ||
value: 'CZCDP-123', | ||
output: true, | ||
}, | ||
{ queryParam: QueryParams.DepositionId, value: '123', output: true }, | ||
{ queryParam: QueryParams.AnnotationId, value: 'AN123', output: true }, | ||
{ queryParam: QueryParams.AnnotationId, value: 'NAN-123', output: false }, | ||
{ queryParam: QueryParams.DatasetId, value: '1-23', output: false }, | ||
] | ||
|
||
testCases.forEach((testCase) => | ||
expect(isFilterPrefixValid(testCase.value, testCase.queryParam)).toEqual( | ||
testCase.output, | ||
), | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { | ||
GO_PREFIX, | ||
UNIPROTKB_PREFIX, | ||
} from 'app/constants/annotationObjectIdLinks' | ||
import { IdPrefix } from 'app/constants/idPrefixes' | ||
import { QueryParams } from 'app/constants/query' | ||
|
||
// TODO: as we add more prefixes, we need to update this map | ||
export const QueryParamToIdPrefixMap: Partial<Record<QueryParams, IdPrefix>> = { | ||
[QueryParams.AnnotationId]: IdPrefix.Annotation, | ||
[QueryParams.DatasetId]: IdPrefix.Dataset, | ||
[QueryParams.DepositionId]: IdPrefix.Deposition, | ||
// Currently we cannot filter by Run or Tiltseries ID, so they are not here | ||
} | ||
|
||
// This function takes a value string and returns the all non-prefix portions. | ||
// Inputs can be in the form of "id-123", "123", "id123", or "id-123-456" | ||
// Inputs can also be strings like "Author Name" | ||
// NOTE: If we need prefixes for string values, like "PREFIX-Author Name", we will need to update this function | ||
export function removeIdPrefix(value: string, queryParam?: QueryParams) { | ||
if (!queryParam) return value | ||
const prefix = QueryParamToIdPrefixMap[queryParam] | ||
if (!prefix) return value | ||
|
||
// Use a regular expression to match the numeric portion of the ID | ||
const matches = value.match(/\d+/g) | ||
|
||
// If a match is found, return it, otherwise return null | ||
return matches ? matches.join('') : null | ||
} | ||
|
||
export function getPrefixedId(id: string, queryParam?: QueryParams) { | ||
if (!queryParam) return id | ||
// ID may or may not already be prefixed, so take it off just in case | ||
const cleanId = removeIdPrefix(id, queryParam) | ||
const prefix = QueryParamToIdPrefixMap[queryParam] ?? '' | ||
return prefix ? `${prefix}-${cleanId}` : id | ||
} | ||
|
||
export const getEntityIdPrefixRegex = (prefix: string) => | ||
RegExp(`^(${prefix})?(-)?\\d+$`, 'i') | ||
|
||
export const ALL_DIGITS_REGEX = /^\d+$/ | ||
export const OBJECT_ID_REGEX = RegExp( | ||
`^(?:${GO_PREFIX}|${UNIPROTKB_PREFIX}).+$`, | ||
) | ||
|
||
export function isFilterPrefixValid(value: string, queryParam?: QueryParams) { | ||
if (!queryParam || value === '') return true | ||
const prefix = QueryParamToIdPrefixMap[queryParam] | ||
if (!prefix) return true | ||
|
||
const validationRegex = prefix ? getEntityIdPrefixRegex(prefix) : /^\d+$/ | ||
return validationRegex.test(value) | ||
} |
Oops, something went wrong.