Skip to content

Commit 7a24f5d

Browse files
authored
Merge pull request #1112 from joshunrau/dev
v1.9.3
2 parents 0426937 + 1afd02b commit 7a24f5d

File tree

17 files changed

+255
-294
lines changed

17 files changed

+255
-294
lines changed

apps/api/package.json

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
"test": "env-cmd -f ../../.env vitest"
1616
},
1717
"dependencies": {
18-
"@casl/ability": "catalog:",
19-
"@casl/prisma": "catalog:",
2018
"@douglasneuroinformatics/libcrypto": "catalog:",
2119
"@douglasneuroinformatics/libjs": "^2.4.0",
2220
"@douglasneuroinformatics/libnest": "^3.0.1",
@@ -25,10 +23,7 @@
2523
"@faker-js/faker": "^9.4.0",
2624
"@nestjs/axios": "^4.0.0",
2725
"@nestjs/common": "^11.0.11",
28-
"@nestjs/config": "^4.0.0",
2926
"@nestjs/core": "^11.0.11",
30-
"@nestjs/mapped-types": "^2.1.0",
31-
"@nestjs/passport": "^11.0.5",
3227
"@nestjs/platform-express": "^11.0.11",
3328
"@nestjs/swagger": "^11.0.6",
3429
"@opendatacapture/demo": "workspace:*",
@@ -45,27 +40,16 @@
4540
"lodash-es": "workspace:lodash-es__4.x@*",
4641
"mongodb": "^6.15.0",
4742
"neverthrow": "^8.2.0",
48-
"passport": "^0.7.0",
49-
"passport-jwt": "4.0.1",
5043
"reflect-metadata": "^0.1.14",
5144
"rxjs": "^7.8.2",
5245
"ts-pattern": "workspace:ts-pattern__5.x@*",
5346
"zod": "workspace:zod__3.23.x@*"
5447
},
5548
"devDependencies": {
56-
"@douglasneuroinformatics/esbuild-plugin-prisma": "catalog:",
5749
"@nestjs/testing": "^11.0.11",
58-
"@opendatacapture/instrument-stubs": "workspace:*",
5950
"@types/express": "^5.0.0",
60-
"@types/supertest": "^6.0.2",
61-
"concurrently": "^9.1.2",
62-
"esbuild": "catalog:",
63-
"esbuild-plugin-tsc": "^0.4.0",
64-
"nodemon": "catalog:",
6551
"prisma": "catalog:",
66-
"prisma-json-types-generator": "^3.2.2",
67-
"supertest": "^7.0.0",
68-
"type-fest": "workspace:type-fest__4.x@*"
52+
"prisma-json-types-generator": "^3.2.2"
6953
},
7054
"imports": {
7155
"#runtime/v1/*": {

apps/api/src/core/env.schema.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { $BooleanLike, $NumberLike, $UrlLike } from '@douglasneuroinformatics/li
22
import { $BaseEnv } from '@douglasneuroinformatics/libnest';
33
import { z } from 'zod';
44

5-
export type Env = z.infer<typeof $Env>;
65
export const $Env = $BaseEnv
76
.omit({ API_PORT: true })
87
.extend({

apps/api/src/groups/__tests__/groups.service.spec.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import { ConflictException, NotFoundException } from '@nestjs/common';
66
import { Test } from '@nestjs/testing';
77
import { beforeEach, describe, expect, it } from 'vitest';
88

9-
import { InstrumentsService } from '@/instruments/instruments.service';
10-
9+
import { InstrumentsService } from '../../instruments/instruments.service';
1110
import { GroupsService } from '../groups.service';
1211

1312
describe('GroupsService', () => {

apps/api/src/instruments/instruments.service.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import type {
2828
InstrumentInfo,
2929
ScalarInstrumentBundleContainer
3030
} from '@opendatacapture/schemas/instrument';
31+
import { pick } from 'lodash-es';
3132

3233
import type { EntityOperationOptions } from '@/core/types';
3334

@@ -46,6 +47,7 @@ type InstrumentQuery<TKind extends InstrumentKind> = {
4647
@Injectable()
4748
export class InstrumentsService {
4849
constructor(
50+
@InjectModel('Group') private readonly groupModel: Model<'Group'>,
4951
@InjectModel('Instrument') private readonly instrumentModel: Model<'Instrument'>,
5052
private readonly cryptoService: CryptoService,
5153
private readonly loggingService: LoggingService,
@@ -87,6 +89,21 @@ export class InstrumentsService {
8789
if (!result.success) {
8890
throw new UnprocessableEntityException(result.message);
8991
}
92+
} else if (instance.internal.edition > 1) {
93+
await this.groupModel.updateMany({
94+
data: {
95+
accessibleInstrumentIds: {
96+
push: [id]
97+
}
98+
},
99+
where: {
100+
accessibleInstrumentIds: {
101+
has: this.generateScalarInstrumentId({
102+
internal: { edition: instance.internal.edition - 1, name: instance.internal.name }
103+
})
104+
}
105+
}
106+
});
90107
}
91108

92109
await this.instrumentModel.create({ data: { bundle, id } });
@@ -163,15 +180,28 @@ export class InstrumentsService {
163180
options: EntityOperationOptions = {}
164181
): Promise<InstrumentInfo[]> {
165182
const instances = await this.find(query, options);
166-
return instances.map(({ __runtimeVersion, clientDetails, details, id, kind, language, tags }) => ({
167-
__runtimeVersion,
168-
clientDetails,
169-
details,
170-
id,
171-
kind,
172-
language,
173-
tags
174-
}));
183+
const results = new Map<string, InstrumentInfo>();
184+
for (const instance of instances) {
185+
const info = pick(instance, [
186+
'__runtimeVersion',
187+
'clientDetails',
188+
'details',
189+
'id',
190+
'internal',
191+
'kind',
192+
'language',
193+
'tags'
194+
]);
195+
if (!info.internal) {
196+
results.set(info.id, info);
197+
continue;
198+
}
199+
const currentEntry = results.get(info.internal.name);
200+
if (!currentEntry || info.internal.edition > currentEntry.internal!.edition) {
201+
results.set(info.internal.name, info);
202+
}
203+
}
204+
return Array.from(results.values());
175205
}
176206

177207
generateInstrumentId(instrument: AnyInstrument) {

apps/api/src/typings/express.d.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

apps/api/tsconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66
"experimentalDecorators": true,
77
"paths": {
88
"@/*": ["src/*"],
9-
"/runtime/v1/*": ["../../runtime/v1/dist/*"],
109
"#runtime/v1/*": ["../../runtime/v1/dist/*"]
1110
},
1211
"strictPropertyInitialization": false
1312
},
14-
"include": ["scripts/*", "src/**/*", "libnest.config.ts", "vitest.config.ts"]
13+
"include": ["src/**/*", "libnest.config.ts", "vitest.config.ts"]
1514
}

apps/web/src/features/datahub/pages/SubjectAssignmentsPage.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const SubjectAssignmentsPage = () => {
3737

3838
const instrumentOptions = Object.fromEntries(
3939
(instrumentInfoQuery.data ?? [])
40+
.sort((a, b) => a.details.title.localeCompare(b.details.title))
4041
.filter((instrument) => {
4142
return currentGroup?.accessibleInstrumentIds.includes(instrument.id) ?? true;
4243
})

apps/web/src/features/instruments/components/InstrumentCard/InstrumentCard.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ export const InstrumentCard = ({ instrument, onClick }: InstrumentCardProps) =>
4040
}),
4141
text: instrument.details.description
4242
},
43+
{
44+
kind: 'text',
45+
label: t({
46+
en: 'Edition',
47+
fr: 'Édition'
48+
}),
49+
text: instrument.internal?.edition.toString()
50+
},
4351
{
4452
kind: 'text',
4553
label: t({

apps/web/src/features/instruments/components/InstrumentShowcase/InstrumentShowcase.tsx

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,34 +18,40 @@ export const InstrumentShowcase: React.FC<{
1818
onSelect: (instrument: TranslatedInstrumentInfo) => void;
1919
}> = ({ data: availableInstruments, onSelect }) => {
2020
const { t } = useTranslation();
21-
const [filteredInstruments, setFilteredInstruments] = useState<TranslatedInstrumentInfo[]>(availableInstruments);
21+
const [filteredInstruments, setFilteredInstruments] = useState<TranslatedInstrumentInfo[]>(
22+
availableInstruments.toSorted((a, b) => a.details.title.localeCompare(b.details.title))
23+
);
2224
const [tagOptions, setTagOptions] = useState<ListboxDropdownOption[]>([]);
2325
const [selectedKinds, setSelectedKinds] = useState<InstrumentShowcaseKindOption[]>([]);
2426
const [selectedLanguages, setSelectedLanguages] = useState<InstrumentShowcaseLanguageOption[]>([]);
2527
const [selectedTags, setSelectedTags] = useState<ListboxDropdownOption[]>([]);
2628
const [searchTerm, setSearchTerm] = useState('');
2729

2830
useEffect(() => {
29-
setFilteredInstruments(
30-
availableInstruments.filter(({ details, kind, supportedLanguages, tags }) => {
31-
if (selectedKinds.length && !selectedKinds.some(({ key }) => key === kind)) {
32-
return false;
33-
} else if (selectedLanguages.length && !selectedLanguages.some(({ key }) => supportedLanguages.includes(key))) {
34-
return false;
35-
} else if (selectedTags.length && !selectedTags.some(({ key }) => tags.includes(key))) {
36-
return false;
37-
}
38-
return details.title.toUpperCase().includes(searchTerm.toUpperCase());
39-
})
40-
);
31+
const updatedFilteredInstruments = availableInstruments.filter(({ details, kind, supportedLanguages, tags }) => {
32+
if (selectedKinds.length && !selectedKinds.some(({ key }) => key === kind)) {
33+
return false;
34+
} else if (selectedLanguages.length && !selectedLanguages.some(({ key }) => supportedLanguages.includes(key))) {
35+
return false;
36+
} else if (selectedTags.length && !selectedTags.some(({ key }) => tags.includes(key))) {
37+
return false;
38+
}
39+
return details.title.toUpperCase().includes(searchTerm.toUpperCase());
40+
});
41+
updatedFilteredInstruments.sort((a, b) => {
42+
return a.details.title.localeCompare(b.details.title);
43+
});
44+
setFilteredInstruments(updatedFilteredInstruments);
4145
}, [availableInstruments, selectedKinds, selectedLanguages, selectedTags, searchTerm]);
4246

4347
useEffect(() => {
4448
setTagOptions(
45-
Array.from(new Set(filteredInstruments.flatMap((item) => item.tags))).map((item) => ({
46-
key: item,
47-
label: item
48-
}))
49+
Array.from(new Set(filteredInstruments.flatMap((item) => item.tags)))
50+
.map((item) => ({
51+
key: item,
52+
label: item
53+
}))
54+
.sort((a, b) => a.label.localeCompare(b.label))
4955
);
5056
}, [availableInstruments]);
5157

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export default config(
2323
'apps/playground/src/instruments/examples/interactive/Interactive-With-Legacy-Script/legacy.js',
2424
'runtime/v1/src/**/*.d.ts',
2525
'vendor/**/*',
26+
'knip.ts',
2627
'vitest.config.ts',
2728
'vitest.workspace.ts'
2829
]

0 commit comments

Comments
 (0)