Jelajahi Sumber

Dynamic questions engine (wip)

Vijayakrishnan 3 tahun lalu
induk
melakukan
e95b663720

+ 63 - 0
public/js/dq.js

@@ -15,7 +15,70 @@
                     dataMap: current
                 };
                 $(this).closest('form').find('input[name="data"]').val(JSON.stringify(fullData));
+
+                runDQConditions($(this).closest('.dq-edit-container'));
             });
     };
+
+    function resolveAtomicCondition(_condition, _dataMap) {
+        if(!_condition.hasOwnProperty('key') || !_condition.hasOwnProperty('value')) {
+            _condition.resolution = false;
+            return;
+        }
+        let key = _condition.key, op = _condition.hasOwnProperty('op') ? _condition.op : 'eq';
+        let lhs = _dataMap[key], rhs = _condition.value;
+        switch(op) {
+            case 'eq':
+                _condition.resolution = (lhs == rhs); // NOTE: using == instead of === on purpose
+                break;
+            case 'lt':
+                _condition.resolution = (+lhs < +rhs);
+                break;
+            case 'lte':
+                _condition.resolution = (+lhs <= +rhs);
+                break;
+            case 'gt':
+                _condition.resolution = (+lhs > +rhs);
+                break;
+            case 'gte':
+                _condition.resolution = (+lhs >= +rhs);
+                break;
+            default:
+                _condition.resolution = false;
+        }
+    }
+
+    function resolveAllAtomicConditions(_conditions, _dataMap) {
+        if(Array.isArray(_conditions)) {
+
+        }
+        else {
+            resolveAtomicCondition(_conditions, _dataMap);
+        }
+    }
+
+    window.runDQConditions = function(_parent) {
+
+        _parent.find('.dq-line.has-pre-condition').each(function() {
+            let conditions = JSON.parse($(this).find('>.dq-pre-condition').first().text()),
+                dataMap = JSON.parse($(this).closest('.dq-edit-container').find('>.dq-data-map').first().text());
+
+            resolveAllAtomicConditions(conditions, dataMap);
+
+            // if object, single condition with key, op and value
+            if(!Array.isArray(conditions)) {
+                if(conditions.resolution) {
+                    $(this).removeClass('d-none');
+                }
+                else {
+                    $(this).addClass('d-none');
+                }
+            }
+
+            // else if array - means list of conditions with 'and' or 'or' separators - array size MUST be an odd number
+
+        });
+
+    }
     addMCInitializer('dq-edit', initDQ, '.dq-edit-container');
 }).call(window);

+ 1 - 1
resources/views/app/dq-engine/edit.blade.php

@@ -8,7 +8,7 @@ if(!$loadedData || !@$loadedData->lines || !@$loadedData->dataMap) {
 <div class="dq-edit-container">
     <div class="dq-definition d-none"><?= htmlentities(json_encode($loadedData->lines)) ?></div>
     <div class="dq-data-map d-none"><?= json_encode($loadedData->dataMap) ?></div>
-    @foreach ($template->lines as $line)
+    @foreach ($loadedData->lines as $line)
         @include('app.dq-engine.line', compact('line'))
     @endforeach
 </div>

+ 1 - 1
resources/views/app/dq-engine/field/radios.blade.php

@@ -1,7 +1,7 @@
 <div class="d-flex align-items-center">
     @foreach(@$line->options as $option)
         <label class="d-inline-flex align-items-center my-0 mr-3">
-            <input type="radio" value="{{$option}}" class="my-0 mr-1" {{ @$loadedData->dataMap->{$line->key} == $option ? 'checked' : '' }}>
+            <input type="radio" name="{{$line->key}}" value="{{$option}}" class="my-0 mr-1" {{ @$loadedData->dataMap->{$line->key} == $option ? 'checked' : '' }}>
             <span>{{$option}}</span>
         </label>
     @endforeach

+ 4 - 1
resources/views/app/dq-engine/line.blade.php

@@ -1,4 +1,7 @@
-<div class="mb-2 dq-line" dq-key="{{$line->key}}">
+<div class="mb-2 dq-line {{@$line->preConditions ? 'has-pre-condition d-none' : ''}}" dq-key="{{$line->key}}">
+    @if(@$line->preConditions)
+    <div class="dq-pre-condition d-none">{!! json_encode($line->preConditions) !!}</div>
+    @endif
     <label for="" class="mb-1 text-secondary">{{$line->helpText}}</label>
     @include('app.dq-engine.field.' . $line->fieldType)
     @if(@($line->lines) && count($line->lines))

+ 26 - 0
resources/views/app/dq-templates/tech.json

@@ -0,0 +1,26 @@
+{
+  "lines": [
+    {
+      "key": "fe_or_be",
+      "helpText": "Front end or Back end?",
+      "resultSummary": "<b>Tech</b>: {value}",
+      "fieldType": "radios",
+      "options": ["Front End", "Back End"]
+    },
+    {
+      "key": "fav_fe_tech",
+      "helpText": "Favorite Front End Framework?",
+      "resultSummary": "<b>Framework</b>: {value}",
+      "fieldType": "radios",
+      "options": ["Angular", "React", "Ember", "NextJS"],
+      "preConditions": {
+        "key": "fe_or_be",
+        "value": "Front End"
+      }
+    }
+  ],
+  "dataMap": {
+    "fe_or_be" : null,
+    "location" : null
+  }
+}

+ 1 - 1
resources/views/app/patient/note/edit-hpi.blade.php

@@ -69,7 +69,7 @@
 
     <?php
     if(!@$template) {
-        $template = 'test.json';
+        $template = 'tech.json';
     }
     $patient = $note->client;
     $data = $currentReview ? $currentReview : null;