diff --git a/backend/packages/Upgrade/.env.example b/backend/packages/Upgrade/.env.example index 6afc4f49f7..3b7b441d07 100644 --- a/backend/packages/Upgrade/.env.example +++ b/backend/packages/Upgrade/.env.example @@ -78,4 +78,4 @@ CLIENT_API_SECRET=secret CLIENT_API_KEY=key CONTEXT_METADATA={"context_identifier_1":{"CONDITIONS":["potential-condition-1","potential-condition-1"],"GROUP_TYPES":["client_group_identifier_1","client_group_identifier_2","client_group_identifier_3"],"EXP_IDS":["decision_point_target_identifier_1","decision_point_target_identifier_2"],"EXP_POINTS":["decision_point_site_identifier_1","decision_point_site_identifier_2"]}} -METRICS=[{"metric":"totalTimeSeconds","datatype":"continuous"},{"groupClass":"masteryWorkspace","allowedKeys":["calculating_area_various_figures","Compare_functions_diff_reps_quadratic"],"attributes":[{"metric":"timeSeconds","datatype":"continuous"}]}] \ No newline at end of file +METRICS=[{"metrics":[{"metric":"totalTimeSeconds","datatype":"continuous"},{"groupClass":"masteryWorkspace","allowedKeys":["calculating_area_various_figures","Compare_functions_diff_reps_quadratic"],"attributes":[{"metric":"timeSeconds","datatype":"continuous"}]}],"contexts":["context_identifier_1"]}] diff --git a/backend/packages/Upgrade/.env.test b/backend/packages/Upgrade/.env.test index f2b99e12f2..d04135e853 100644 --- a/backend/packages/Upgrade/.env.test +++ b/backend/packages/Upgrade/.env.test @@ -89,4 +89,4 @@ CLIENT_API_SECRET = secret CLIENT_API_KEY = key CONTEXT_METADATA = {"add":{"EXP_IDS":["add-id1","add-id2"],"EXP_POINTS":["add-point1","add-point2"],"GROUP_TYPES":["add-group1","add-group2"],"CONDITIONS":["add-con1","add-con2","add-con3"]},"sub":{"EXP_IDS":["sub-id1","sub-id2"],"EXP_POINTS":["sub-point1","sub-point2"],"GROUP_TYPES":["sub-group1","sub-group2"],"CONDITIONS":["sub-con1","sub-con2","sub-con3"]},"mul":{"EXP_IDS":["mul-id1","mul-id2"],"EXP_POINTS":["mul-point1","mul-point2"],"GROUP_TYPES":["mul-group1","mul-group2"],"CONDITIONS":["mul-con1","mul-con2","mul-con3"]},"div":{"EXP_IDS":["div-id1","div-id2"],"EXP_POINTS":["div-point1","div-point2"],"GROUP_TYPES":["div-group1","div-group2"],"CONDITIONS":["div-con1","div-con2","div-con3"]}} -METRICS = [{"metric": "totalTimeSeconds","datatype": "continuous"}, {"metric": "workspaceCompletionStatus","datatype": "categorical", "allowedValues": ["GRADUATED", "PROMOTED"]}, { "groupClass": "addWorkspace", "allowedKeys": [ "level1", "level2" ], "attributes": [{"metric": "workspaceCompletionStatus","datatype": "categorical", "allowedValues": ["GRADUATED", "PROMOTED"]},{"metric": "timeSpent","datatype": "continuous"}]}] +METRICS = [{"metrics":[{"metric":"totalTimeSeconds","datatype":"continuous"},{"metric":"workspaceCompletionStatus","datatype":"categorical","allowedValues":["GRADUATED","PROMOTED"]}],"contexts":["test-context1","test-context2"]},{"metrics":[{"groupClass":"addWorkspace","allowedKeys":["level1","level2"],"attributes":[{"metric":"workspaceCompletionStatus","datatype":"categorical","allowedValues":["GRADUATED","PROMOTED"]},{"metric":"timeSpent","datatype":"continuous"}]}],"contexts":["test-context3"]}] diff --git a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.ts b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.ts index 7a8cea3d65..54f94a91db 100644 --- a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.ts +++ b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.ts @@ -876,7 +876,7 @@ export class ExperimentClientController { @Body({ validate: false }) metric: MetricValidator ): Promise { - return await this.metricService.saveAllMetrics(metric.metricUnit, request.logger); + return await this.metricService.saveAllMetrics(metric.metricUnit, metric.context, request.logger); } /** diff --git a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v1.ts b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v1.ts index f1416e1640..3e4ab4eab3 100644 --- a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v1.ts +++ b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v1.ts @@ -843,7 +843,7 @@ export class ExperimentClientController { @Body({ validate: false }) metric: MetricValidator ): Promise { - return await this.metricService.saveAllMetrics(metric.metricUnit, request.logger); + return await this.metricService.saveAllMetrics(metric.metricUnit, metric.context, request.logger); } /** diff --git a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v4.ts b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v4.ts index e3aef7a3e2..e78b9e5146 100644 --- a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v4.ts +++ b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v4.ts @@ -805,7 +805,7 @@ export class ExperimentClientController { @Body({ validate: false }) metric: MetricValidator ): Promise { - return await this.metricService.saveAllMetrics(metric.metricUnit, request.logger); + return await this.metricService.saveAllMetrics(metric.metricUnit, metric.context, request.logger); } /** diff --git a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v5.ts b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v5.ts index bee9f555d9..60adabb6d7 100644 --- a/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v5.ts +++ b/backend/packages/Upgrade/src/api/controllers/ExperimentClientController.v5.ts @@ -762,7 +762,7 @@ export class ExperimentClientController { @Body({ validate: true }) metric: MetricValidator ): Promise { - return await this.metricService.saveAllMetrics(metric.metricUnit, request.logger); + return await this.metricService.saveAllMetrics(metric.metricUnit, metric.context, request.logger); } /** diff --git a/backend/packages/Upgrade/src/api/controllers/MetricController.ts b/backend/packages/Upgrade/src/api/controllers/MetricController.ts index 6638b35249..0fe22e59d1 100644 --- a/backend/packages/Upgrade/src/api/controllers/MetricController.ts +++ b/backend/packages/Upgrade/src/api/controllers/MetricController.ts @@ -1,6 +1,6 @@ import { Authorized, JsonController, Get, Delete, Param, Post, Req, Body } from 'routing-controllers'; import { MetricService } from '../services/MetricService'; -import { IMetricUnit, SERVER_ERROR, } from 'upgrade_types'; +import { IMetricUnit, SERVER_ERROR } from 'upgrade_types'; import { AppRequest } from '../../types'; import { MetricValidator } from './validators/MetricValidator'; @@ -33,6 +33,33 @@ export class MetricController { return this.metricService.getAllMetrics(request.logger); } + /** + * @swagger + * /metric/{context}: + * get: + * description: Get all metrics with context + * parameters: + * - in: path + * name: context + * required: true + * schema: + * type: string + * description: context + * tags: + * - Metrics + * produces: + * - application/json + * responses: + * '200': + * description: Get all metrics with context + * '404': + * description: Context not found + */ + @Get('/:context') + public getMetricsByContext(@Param('context') context: string, @Req() request: AppRequest): Promise { + return this.metricService.getMetricsByContext(context, request.logger); + } + /** * @swagger * /metric/save: @@ -75,7 +102,7 @@ export class MetricController { @Body({ validate: true }) metric: MetricValidator, @Req() request: AppRequest ): Promise { - return this.metricService.upsertAllMetrics(metric.metricUnit, request.logger); + return this.metricService.upsertAllMetrics(metric.metricUnit, metric.context, request.logger); } /** diff --git a/backend/packages/Upgrade/src/api/controllers/validators/MetricValidator.ts b/backend/packages/Upgrade/src/api/controllers/validators/MetricValidator.ts index da3fca338a..93fa670962 100644 --- a/backend/packages/Upgrade/src/api/controllers/validators/MetricValidator.ts +++ b/backend/packages/Upgrade/src/api/controllers/validators/MetricValidator.ts @@ -1,4 +1,13 @@ -import { IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, ValidateNested, ValidationOptions, registerDecorator } from 'class-validator'; +import { + IsArray, + IsEnum, + IsNotEmpty, + IsOptional, + IsString, + ValidateNested, + ValidationOptions, + registerDecorator, +} from 'class-validator'; import { IMetricMetaData } from 'upgrade_types'; const IsMetricUnit = (validationOptions?: ValidationOptions) => { @@ -14,7 +23,7 @@ const IsMetricUnit = (validationOptions?: ValidationOptions) => { }, validator: { validate(value: any) { - return validateMetricUnit(value) + return validateMetricUnit(value); }, }, }); @@ -23,11 +32,11 @@ const IsMetricUnit = (validationOptions?: ValidationOptions) => { function validateMetricUnit(data: unknown) { if (Array.isArray(data) && data.every(isValidMetric)) { - return true + return true; } else { - return false + return false; } -}; +} function isValidMetric(value: any): value is IGroupMetric | ISingleMetric { if ('groupClass' in value) { @@ -49,9 +58,7 @@ function isValidMetric(value: any): value is IGroupMetric | ISingleMetric { (value.allowedValues === undefined || (Array.isArray(value.allowedValues) && value.allowedValues.every( - (allowedValue) => - typeof allowedValue === 'string' || - typeof allowedValue === 'number' + (allowedValue) => typeof allowedValue === 'string' || typeof allowedValue === 'number' ))) ); } @@ -68,7 +75,7 @@ class ISingleMetric { datatype: IMetricMetaData; @IsOptional() - @IsArray({each: true}) + @IsArray({ each: true }) allowedValues?: (string | number)[]; } @@ -77,7 +84,7 @@ class IGroupMetric { groupClass: string; @IsArray() - @IsString({each: true}) + @IsString({ each: true }) allowedKeys: string[]; @IsArray() @@ -91,4 +98,9 @@ export class MetricValidator { @IsNotEmpty() @IsMetricUnit() metricUnit: (ISingleMetric | IGroupMetric)[]; + + @IsArray() + @IsNotEmpty() + @IsString({ each: true }) + context: string[]; } diff --git a/backend/packages/Upgrade/src/api/models/Metric.ts b/backend/packages/Upgrade/src/api/models/Metric.ts index 36ebb53664..ada36f5bb3 100644 --- a/backend/packages/Upgrade/src/api/models/Metric.ts +++ b/backend/packages/Upgrade/src/api/models/Metric.ts @@ -19,6 +19,9 @@ export class Metric extends BaseModel { @Column({ type: 'simple-array', nullable: true }) public allowedData: string[]; + @Column('text', { array: true }) + public context: string[]; + @ManyToMany(() => Log, (log) => log.metrics, { cascade: true, }) diff --git a/backend/packages/Upgrade/src/api/repositories/MetricRepository.ts b/backend/packages/Upgrade/src/api/repositories/MetricRepository.ts index 794963e74f..43944e9524 100644 --- a/backend/packages/Upgrade/src/api/repositories/MetricRepository.ts +++ b/backend/packages/Upgrade/src/api/repositories/MetricRepository.ts @@ -30,6 +30,16 @@ export class MetricRepository extends Repository { }); } + public async getMetricsByContext(context: string): Promise { + return this.createQueryBuilder('metrics') + .where('context @> :searchContext', { searchContext: [context] }) + .getMany() + .catch((errorMsg: any) => { + const errorMsgString = repositoryError(this.constructor.name, 'getMetricsByContext', { context }, errorMsg); + throw errorMsgString; + }); + } + public async findMetricsWithQueries(ids: string[]): Promise { return this.createQueryBuilder('metrics') .innerJoin('metrics.queries', 'queries') diff --git a/backend/packages/Upgrade/src/api/services/MetricService.ts b/backend/packages/Upgrade/src/api/services/MetricService.ts index 4d70d1d41c..15a671b3ad 100644 --- a/backend/packages/Upgrade/src/api/services/MetricService.ts +++ b/backend/packages/Upgrade/src/api/services/MetricService.ts @@ -19,17 +19,28 @@ export class MetricService { return this.metricDocumentToJson(metricData); } - public async saveAllMetrics(metrics: Array, logger: UpgradeLogger): Promise { + public async getMetricsByContext(context: string, logger: UpgradeLogger): Promise { + logger.info({ message: `Get metrics by context ${context}` }); + const metricData = await this.metricRepository.getMetricsByContext(context); + return this.metricDocumentToJson(metricData); + } + + public async saveAllMetrics( + metrics: Array, + contexts: string[], + logger: UpgradeLogger + ): Promise { logger.info({ message: 'Save all metrics' }); - return await this.addAllMetrics(metrics, logger); + return await this.addAllMetrics(metrics, contexts, logger); } public async upsertAllMetrics( metrics: Array, + contexts: string[], logger: UpgradeLogger ): Promise { logger.info({ message: 'Upsert all metrics' }); - const upsertedMetrics = await this.addAllMetrics(metrics, logger); + const upsertedMetrics = await this.addAllMetrics(metrics, contexts, logger); return this.metricDocumentToJson(upsertedMetrics); } @@ -41,7 +52,11 @@ export class MetricService { return this.metricDocumentToJson(updatedMetric); } - private async addAllMetrics(metrics: Array, logger: UpgradeLogger): Promise { + private async addAllMetrics( + metrics: Array, + contexts: string[], + logger: UpgradeLogger + ): Promise { // check permission for metrics const isAllowed = await this.checkMetricsPermission(logger); if (!isAllowed) { @@ -57,6 +72,7 @@ export class MetricService { key: metric.key, type: metric.type, allowedData: metric.allowedData, + context: contexts, })); return this.metricRepository.save(metricDoc); } @@ -138,6 +154,7 @@ export class MetricService { children: [], metadata: { type: metric.type as any }, allowedData: metric.allowedData, + context: metric.context, }; metricPointer.push(newMetric); diff --git a/backend/packages/Upgrade/src/database/migrations/1712553037665-contextInMetric.ts b/backend/packages/Upgrade/src/database/migrations/1712553037665-contextInMetric.ts new file mode 100644 index 0000000000..41fbd37b9c --- /dev/null +++ b/backend/packages/Upgrade/src/database/migrations/1712553037665-contextInMetric.ts @@ -0,0 +1,13 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class contextInMetric1712553037665 implements MigrationInterface { + name = 'contextInMetric1712553037665'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "metric" ADD "context" text array NOT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "metric" DROP COLUMN "context"`); + } +} diff --git a/backend/packages/Upgrade/src/env.ts b/backend/packages/Upgrade/src/env.ts index 2dbe91fd1c..8bb7d2f66d 100644 --- a/backend/packages/Upgrade/src/env.ts +++ b/backend/packages/Upgrade/src/env.ts @@ -90,7 +90,7 @@ export const env = { initialization: { contextMetadata: JSON.parse(getOsEnv('CONTEXT_METADATA')), adminUsers: parseAdminUsers(getOsEnv('ADMIN_USERS')), - metrics: getOsEnvOptional('METRICS'), + metrics: getOsEnvOptional('PRE_DEFINED_METRICS'), }, hostUrl: getOsEnv('HOST_URL'), tokenSecretKey: getOsEnv('TOKEN_SECRET_KEY'), diff --git a/backend/packages/Upgrade/src/init/seed/initMetrics.ts b/backend/packages/Upgrade/src/init/seed/initMetrics.ts index ca1569e496..314afbe8c3 100644 --- a/backend/packages/Upgrade/src/init/seed/initMetrics.ts +++ b/backend/packages/Upgrade/src/init/seed/initMetrics.ts @@ -8,7 +8,10 @@ export function InitMetrics(logger: UpgradeLogger): Promise { // Init default metrics in system if (env.initialization.metrics) { try { - return metricService.saveAllMetrics(JSON.parse(env.initialization.metrics), logger); + const metrics = JSON.parse(env.initialization.metrics).map((metricData) => { + return metricService.saveAllMetrics(metricData.metrics, metricData.contexts, logger); + }); + Promise.all(metrics); } catch (err) { const error = new Error('Error while initializing metrics'); logger.error(error); diff --git a/backend/packages/Upgrade/test/integration/Experiment/dataLog/CreateLog.ts b/backend/packages/Upgrade/test/integration/Experiment/dataLog/CreateLog.ts index 438cd51820..f76c31078e 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/dataLog/CreateLog.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/dataLog/CreateLog.ts @@ -45,7 +45,7 @@ export default async function CreateLog(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, experimentObject.context, new UpgradeLogger()); const findMetric = await metricRepository.find(); expect(findMetric.length).toEqual(36); diff --git a/backend/packages/Upgrade/test/integration/Experiment/dataLog/LogOperations.ts b/backend/packages/Upgrade/test/integration/Experiment/dataLog/LogOperations.ts index 0a9f1018a6..51c3d0daaf 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/dataLog/LogOperations.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/dataLog/LogOperations.ts @@ -50,7 +50,7 @@ export default async function LogOperations(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, experimentObject.context, new UpgradeLogger()); const findMetric = await metricRepository.find(); expect(findMetric.length).toEqual(36); diff --git a/backend/packages/Upgrade/test/integration/Experiment/dataLog/RepeatedMeasure.ts b/backend/packages/Upgrade/test/integration/Experiment/dataLog/RepeatedMeasure.ts index 858077b027..eb5186833c 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/dataLog/RepeatedMeasure.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/dataLog/RepeatedMeasure.ts @@ -52,7 +52,7 @@ export default async function RepeatedMeasure(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, experimentObject.context, new UpgradeLogger()); // change experiment status to Enrolling const experimentId = experiments[0].id; diff --git a/backend/packages/Upgrade/test/integration/Experiment/metric/MetricCRUD.ts b/backend/packages/Upgrade/test/integration/Experiment/metric/MetricCRUD.ts index 931bae6187..0903242214 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/metric/MetricCRUD.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/metric/MetricCRUD.ts @@ -14,7 +14,7 @@ export default async function MetricCRUD(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); // create metrics service - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, ['home'], new UpgradeLogger()); let findMetric = await metricRepository.find(); expect(findMetric.length).toEqual(36); diff --git a/backend/packages/Upgrade/test/integration/Experiment/query/QueryCRUD.ts b/backend/packages/Upgrade/test/integration/Experiment/query/QueryCRUD.ts index 4bdb0aa5d1..84ae29efd3 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/query/QueryCRUD.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/query/QueryCRUD.ts @@ -45,7 +45,7 @@ export default async function QueryCRUD(): Promise { ); // create metrics service - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, experimentObject.context, new UpgradeLogger()); const findMetric = await metricRepository.find(); expect(findMetric.length).toEqual(36); diff --git a/backend/packages/Upgrade/test/integration/Experiment/stratification/MetricQueriesCheck.ts b/backend/packages/Upgrade/test/integration/Experiment/stratification/MetricQueriesCheck.ts index 5f708ef01e..74940ab0c2 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/stratification/MetricQueriesCheck.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/stratification/MetricQueriesCheck.ts @@ -26,7 +26,11 @@ export default async function MetricQueriesCheck(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); // create metrics service - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics( + metrics as any, + stratificationRandomExperimentAssignmentExperiment2.context, + new UpgradeLogger() + ); // creating new user const user = await userService.upsertUser(systemUser as any, new UpgradeLogger()); diff --git a/backend/packages/Upgrade/test/integration/Experiment/withinSubject/MetricQueriesCheck.ts b/backend/packages/Upgrade/test/integration/Experiment/withinSubject/MetricQueriesCheck.ts index 40bcb0fb3f..5e056936b5 100644 --- a/backend/packages/Upgrade/test/integration/Experiment/withinSubject/MetricQueriesCheck.ts +++ b/backend/packages/Upgrade/test/integration/Experiment/withinSubject/MetricQueriesCheck.ts @@ -26,7 +26,7 @@ export default async function MetricQueriesCheck(): Promise { await settingService.setClientCheck(false, true, new UpgradeLogger()); // create metrics service - await metricService.saveAllMetrics(metrics as any, new UpgradeLogger()); + await metricService.saveAllMetrics(metrics as any, withinSubjectExperiment.context, new UpgradeLogger()); // creating new user const user = await userService.upsertUser(systemUser as any, new UpgradeLogger()); diff --git a/backend/packages/Upgrade/test/unit/controllers/MetricController.test.ts b/backend/packages/Upgrade/test/unit/controllers/MetricController.test.ts index a514333202..451639562e 100644 --- a/backend/packages/Upgrade/test/unit/controllers/MetricController.test.ts +++ b/backend/packages/Upgrade/test/unit/controllers/MetricController.test.ts @@ -32,6 +32,7 @@ describe('Metric Controller Testing', () => { .post('/api/metric/save') .send({ metricUnit: [], + context: [], }) .set('Accept', 'application/json') .expect('Content-Type', /json/) diff --git a/backend/packages/Upgrade/test/unit/services/MetricService.test.ts b/backend/packages/Upgrade/test/unit/services/MetricService.test.ts index 6f9ad43507..97e4bce29f 100644 --- a/backend/packages/Upgrade/test/unit/services/MetricService.test.ts +++ b/backend/packages/Upgrade/test/unit/services/MetricService.test.ts @@ -14,6 +14,8 @@ describe('Audit Service Testing', () => { let module: TestingModule; const settingRes = [{ id: 'id', toCheckAuth: false, toFilterMetric: true }]; + const contexts = ['home']; + const simpleMetric: Array = [ { metric: 'totalProblemsCompleted', @@ -39,6 +41,7 @@ describe('Audit Service Testing', () => { key: 'totalProblemsCompleted', type: IMetricMetaData.CONTINUOUS, allowedData: [], + context: ['home'], logs: [], queries: [], createdAt: new Date('2020-1-1'), @@ -52,6 +55,7 @@ describe('Audit Service Testing', () => { key: 'totalProblemsCompleted', allowedData: [], children: [], + context: ['home'], metadata: { type: IMetricMetaData.CONTINUOUS, }, @@ -102,17 +106,17 @@ describe('Audit Service Testing', () => { }); it('should save all simple metrics', async () => { - const res = await service.saveAllMetrics(simpleMetric, new UpgradeLogger()); + const res = await service.saveAllMetrics(simpleMetric, contexts, new UpgradeLogger()); expect(res).toEqual(metric); }); it('should save all group metrics', async () => { - const res = await service.saveAllMetrics(groupMetric, new UpgradeLogger()); + const res = await service.saveAllMetrics(groupMetric, contexts, new UpgradeLogger()); expect(res).toEqual(metric); }); it('should upsert all metrics', async () => { - const res = await service.upsertAllMetrics(simpleMetric, new UpgradeLogger()); + const res = await service.upsertAllMetrics(simpleMetric, contexts, new UpgradeLogger()); expect(res).toEqual(metricResult); }); @@ -125,7 +129,7 @@ describe('Audit Service Testing', () => { settingRes[0].toFilterMetric = false; expect(async () => { - await service.saveAllMetrics(groupMetric, new UpgradeLogger()); + await service.saveAllMetrics(groupMetric, contexts, new UpgradeLogger()); }).rejects.toThrow('Metrics filter not enabled'); }); }); diff --git a/frontend/projects/upgrade/src/app/core/analysis/store/analysis.models.ts b/frontend/projects/upgrade/src/app/core/analysis/store/analysis.models.ts index de6d0e32c6..ec878e2d43 100644 --- a/frontend/projects/upgrade/src/app/core/analysis/store/analysis.models.ts +++ b/frontend/projects/upgrade/src/app/core/analysis/store/analysis.models.ts @@ -8,6 +8,7 @@ export const METRICS_JOIN_TEXT = '@__@'; export interface MetricUnit { key: string; children: MetricUnit[]; + context?: string[]; } export interface UpsertMetrics { diff --git a/frontend/projects/upgrade/src/app/features/dashboard/home/components/metrics/metrics.component.ts b/frontend/projects/upgrade/src/app/features/dashboard/home/components/metrics/metrics.component.ts index fd087be9a0..882ecb82cf 100644 --- a/frontend/projects/upgrade/src/app/features/dashboard/home/components/metrics/metrics.component.ts +++ b/frontend/projects/upgrade/src/app/features/dashboard/home/components/metrics/metrics.component.ts @@ -91,7 +91,9 @@ export class MonitoredMetricsComponent implements OnInit, OnChanges, OnDestroy { this.options = this.currentAssignmentUnit === ASSIGNMENT_UNIT.WITHIN_SUBJECTS ? this.allMetrics.filter((metric) => metric.children.length > 0) - : this.allMetrics; + : this.allMetrics.filter((metric) => + metric.context.includes(this.currentContext || this.experimentInfo?.context) + ); }); } @@ -711,7 +713,7 @@ export class MonitoredMetricsComponent implements OnInit, OnChanges, OnDestroy { ngOnChanges() { if (this.isContextChanged || this.isExperimentTypeChanged) { - this.isContextChanged = false; + this.optionsSub(); this.isExperimentTypeChanged = false; this.queries.clear(); this.metricsDataSource.next(this.queries.controls); diff --git a/types/src/Experiment/interfaces.ts b/types/src/Experiment/interfaces.ts index 24a657eab8..a8b2833dc6 100644 --- a/types/src/Experiment/interfaces.ts +++ b/types/src/Experiment/interfaces.ts @@ -112,6 +112,7 @@ export interface IExperimentSortParams { export interface IMetricUnit { key: string | string[]; + context?: string[]; children?: IMetricUnit[]; metadata?: { type: IMetricMetaData }; allowedData?: string[];