From cd3b09db950c7ef517cc42dbb359a9995ab88c61 Mon Sep 17 00:00:00 2001
From: Steve Reis <stevereis93@gmail.com>
Date: Fri, 22 Apr 2022 13:46:50 +0000
Subject: [PATCH] fix: Add datasets to groups and variables

---
 .../connectors/datashield/main.connector.ts   | 18 +++---
 .../connectors/datashield/transformations.ts  | 62 +++++++++++++++----
 api/src/engine/engine.interfaces.ts           |  6 +-
 api/src/engine/models/group.model.ts          |  6 ++
 api/src/engine/models/variable.model.ts       |  6 ++
 api/src/schema.gql                            |  6 ++
 6 files changed, 82 insertions(+), 22 deletions(-)

diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts
index ad0e132..03b4e80 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/main.connector.ts
@@ -17,12 +17,8 @@ import {
 } from 'src/engine/engine.interfaces';
 import { Domain } from 'src/engine/models/domain.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
-import {
-  Experiment,
-  PartialExperiment,
-} from 'src/engine/models/experiment/experiment.model';
+import { Experiment } from 'src/engine/models/experiment/experiment.model';
 import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
-import { ExperimentEditInput } from 'src/engine/models/experiment/input/experiment-edit.input';
 import { ListExperiments } from 'src/engine/models/experiment/list-experiments.model';
 import { RawResult } from 'src/engine/models/result/raw-result.model';
 import {
@@ -31,7 +27,9 @@ import {
 } from 'src/engine/models/result/table-result.model';
 import { User } from 'src/users/models/user.model';
 import {
-  transformToDomains,
+  dataToGroups,
+  dsGroup,
+  transformToDomain,
   transformToHisto,
   transformToTable,
 } from './transformations';
@@ -188,7 +186,7 @@ export default class DataShieldService implements IEngineService {
     return expResult;
   }
 
-  async listExperiments(page: number, name: string): Promise<ListExperiments> {
+  async listExperiments(): Promise<ListExperiments> {
     return {
       totalExperiments: 0,
       experiments: [],
@@ -247,7 +245,11 @@ export default class DataShieldService implements IEngineService {
       }),
     );
 
-    return [transformToDomains.evaluate(response.data)];
+    const dsDomain = transformToDomain.evaluate(response.data);
+    const groups = response.data['groups'] as dsGroup[];
+
+    dataToGroups(dsDomain, groups);
+    return [dsDomain];
   }
 
   async getActiveUser(req: Request): Promise<User> {
diff --git a/api/src/engine/connectors/datashield/transformations.ts b/api/src/engine/connectors/datashield/transformations.ts
index 065040b..7e2c215 100644
--- a/api/src/engine/connectors/datashield/transformations.ts
+++ b/api/src/engine/connectors/datashield/transformations.ts
@@ -2,29 +2,31 @@
 // see : https://docs.jsonata.org/
 
 import * as jsonata from 'jsonata';
+import { Domain } from 'src/engine/models/domain.model';
+import { Group } from 'src/engine/models/group.model';
 
-export const transformToDomains = jsonata(`
+export const transformToDomain = jsonata(`
 {
   "id": "sophia",
+  "label": "Sophia",
   "datasets": datasets.{
       "id": $.id[0],
       "label": $.label[0]
   },
   "rootGroup": {
-      "id": rootGroup.id[0],
-      "label": rootGroup.label[0],
-      "groups": rootGroup.groups
+      "id": "root",
+      "label": "Sophia",
+      "groups": $append(rootGroup.groups, $keys($.groups.variables))
   },
-  "groups": groups.{
+  "groups": datasets.{
       "id": $.id[0],
       "label": $.label[0],
-      "variables": $.variables,
-      "groups": $.groups
-  },
-  "variables": $distinct(groups.variables).{
+      "groups": [],
+      "datasets": $.id[0][]
+    }[],
+  "variables": $distinct(groups.variables.($type($) = 'object' ? $.* : $)).{
       "id": $,
-      "label": $trim($replace($ & '', '.', ' ')),
-      "type": "Number"
+      "label": $trim($replace($ & '', '.', ' '))
   }
 }
 `);
@@ -82,3 +84,41 @@ export const transformToTable = jsonata(`
 export const transformToUser = jsonata(`
 $ ~> |$|{'id': subjectId}, ['subjectId']|
 `);
+
+export type dsGroup = {
+  id: string[];
+  label: string[];
+  variables: Record<string, string[]> | string[];
+  groups?: string[];
+};
+
+export const dataToGroups = (dsDomain: Domain, groups: dsGroup[]) => {
+  groups.forEach((g) => {
+    if (Array.isArray(g.variables)) {
+      dsDomain.groups.push({
+        id: g.id[0],
+        label: g.label[0],
+        variables: g.variables,
+      });
+      return;
+    }
+
+    if (dsDomain.rootGroup.groups.includes(g.id[0])) {
+      dsDomain.rootGroup.groups = dsDomain.rootGroup.groups.filter(
+        (gId) => gId !== g.id[0],
+      );
+    }
+
+    return Object.entries(g.variables).map(([key, val]) => {
+      const id = `${g.id}-${key}`;
+      dsDomain.groups.find((g) => g.id === key).groups.push(id);
+      const group: Group = {
+        id,
+        variables: val,
+        groups: g['groups'] ? g['groups'].map((g) => `${g}-${key}`) : undefined,
+        label: `${g.label[0]} (${key})`,
+      };
+      dsDomain.groups.push(group);
+    });
+  });
+};
diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/engine.interfaces.ts
index c36cd48..3df6762 100644
--- a/api/src/engine/engine.interfaces.ts
+++ b/api/src/engine/engine.interfaces.ts
@@ -38,7 +38,7 @@ export interface IEngineService {
     req?: Request,
   ): Promise<Experiment>;
 
-  listExperiments(
+  listExperiments?(
     page: number,
     name: string,
     req?: Request,
@@ -46,9 +46,9 @@ export interface IEngineService {
 
   getExperiment(id: string, req?: Request): Promise<Experiment>;
 
-  removeExperiment(id: string, req?: Request): Promise<PartialExperiment>;
+  removeExperiment?(id: string, req?: Request): Promise<PartialExperiment>;
 
-  editExperient(
+  editExperient?(
     id: string,
     expriment: ExperimentEditInput,
     req?: Request,
diff --git a/api/src/engine/models/group.model.ts b/api/src/engine/models/group.model.ts
index 11be6a1..92a6c1d 100644
--- a/api/src/engine/models/group.model.ts
+++ b/api/src/engine/models/group.model.ts
@@ -15,4 +15,10 @@ export class Group extends BaseModel {
     nullable: true,
   })
   variables?: string[];
+
+  @Field(() => [String], {
+    description: 'List of datasets avalaible, set null if all datasets allowed',
+    nullable: true,
+  })
+  datasets?: string[];
 }
diff --git a/api/src/engine/models/variable.model.ts b/api/src/engine/models/variable.model.ts
index c48a32b..7d8aae7 100644
--- a/api/src/engine/models/variable.model.ts
+++ b/api/src/engine/models/variable.model.ts
@@ -16,4 +16,10 @@ export class Variable extends BaseModel {
 
   @Field(() => [Group], { nullable: true, defaultValue: [] })
   groups?: Group[];
+
+  @Field(() => [String], {
+    description: 'List of datasets avalaible, set null if all datasets allowed',
+    nullable: true,
+  })
+  datasets?: string[];
 }
diff --git a/api/src/schema.gql b/api/src/schema.gql
index 8f5b0fe..33142a2 100644
--- a/api/src/schema.gql
+++ b/api/src/schema.gql
@@ -45,6 +45,9 @@ type Group {
 
   """List of variable's ids"""
   variables: [String!]
+
+  """List of datasets avalaible, set null if all datasets allowed"""
+  datasets: [String!]
 }
 
 type Category {
@@ -59,6 +62,9 @@ type Variable {
   description: String
   enumerations: [Category!]
   groups: [Group!]
+
+  """List of datasets avalaible, set null if all datasets allowed"""
+  datasets: [String!]
 }
 
 type Domain {
-- 
GitLab