Bladeren bron

Omega - all hx segments + ros

Vijayakrishnan 3 jaren geleden
bovenliggende
commit
10d6ac57b8

+ 8 - 3
resources/views/app/patient/note/dashboard_script.blade.php

@@ -200,11 +200,16 @@
                         }
 
                         <?php
-                        $rosSegment = $note->getSegmentByInternalName('ros');
+                        $rosName = 'ros';
+                        $rosSegment = $note->getSegmentByInternalName($rosName);
+                        if(!$rosSegment) {
+                            $rosName = 'omega_ros';
+                            $rosSegment = $note->getSegmentByInternalName($rosName);
+                        }
                         ?>
                         @if($rosSegment)
-                        if(editParent.is('[data-segment-template-name="ros"]')) {
-                            openDynamicStagPopup('/note-segment-view/{{$note->client->uid}}/{{$note->uid}}/{{$rosSegment->uid}}/ros/edit',
+                        if(editParent.is('[data-segment-template-name="{{$rosName}}"]')) {
+                            openDynamicStagPopup('/note-segment-view/{{$note->client->uid}}/{{$note->uid}}/{{$rosSegment->uid}}/{{$rosName}}/edit',
                                 'init-ros-{{$note->id}}',
                                 'Review of Systems',
                                 false,

+ 7 - 7
resources/views/app/patient/note/segment-slim.blade.php

@@ -17,20 +17,20 @@
                 <div class="d-none if-not-edit inset-comment summary-container">
                     @if($note->is_signed_by_hcp && $segment->accepted_suggestion_summary_html)
                         {!! $segment->accepted_suggestion_summary_html !!}
-                    @else 
+                    @else
                         {!! $segment->summary_html !!}
-                    @endif 
+                    @endif
                 </div>
 
-                <?php if($iName !== 'ros') { ?>
+                <?php if($iName !== 'ros' && $iName !== 'omega_ros') { ?>
                 <div class="d-none if-edit edit-container">
                     {!! $segment->edit_html !!}
                 </div>
                 <?php } ?>
-   
+
             </div>
-        
-        
+
+
             @if(!$note->is_signed_by_hcp)
                 <a class="edit-trigger d-none if-edit c-pointer ml-3">
                     <i class="fas fa-caret-up font-size-16"></i>
@@ -60,6 +60,6 @@
     </div>
 
 
-    
+
 
 </div>

+ 426 - 1
resources/views/app/patient/segment-templates/omega_history_family/edit.blade.php

@@ -1 +1,426 @@
-<h1>omega_history_family</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+if(!@$segment) $segment = null;
+
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'FAMILY_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "count" => 1,
+        "unknown" => false,
+        "items" => [
+            [
+                "relationship" => '',
+                "status" => '',
+                "general_no_health_concern" => null,
+                "general_arthritis" => null,
+                "general_asthma" => null,
+                "general_bleeding_disorder" => null,
+                "general_cad_lt_age_55" => null,
+                "general_copd" => null,
+                "general_diabetes" => null,
+                "general_heart_attack" => null,
+                "general_heart_disease" => null,
+                "general_high_cholesterol" => null,
+                "general_hypertension" => null,
+                "general_mental_illness" => null,
+                "general_osteoporosis" => null,
+                "general_stroke" => null,
+                "cancer_breast_ca" => null,
+                "cancer_colon_ca" => null,
+                "cancer_other_ca" => null,
+                "cancer_ovarian_ca" => null,
+                "cancer_uterine_ca" => null,
+                "comments" => '',
+            ]
+        ]
+    ];
+}
+
+?>
+
+<hr class="hide-outside-popup mt-3 mb-0">
+<div class="p-3 mcp-theme-1">
+    <div {{!!$segment ? 'visit-moe' : 'moe'}} close-on-save close-on-cancel class="d-block">
+        <form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1"
+                    {{!$segment ? 'hook=onHxPopupClosure' : ''}}>
+            @if(!!@$segment)
+                <input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
+            @else
+                <input type="hidden" name="segmentUid" value="<?= $note->coreSegment->uid ?>">
+            @endif
+            <input type="hidden" name="uid" value="<?= $point->uid ?>">
+            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+            <input type="hidden" name="data">
+
+            <div id="edit-univ_history_family-container">
+
+                <div class="border border-secondary rounded mb-2 p-2">
+                    <label class="my-0 d-flex align-items-center">
+                        <input type="checkbox" class="my-0 mr-2" v-model="unknown" name="unknown">
+                        <span>Family history is unknown/unavailable</span>
+                    </label>
+                </div>
+
+                <div v-if="!unknown" v-for="(item, index) in items" class="note-section-item-row">
+                    <hr v-if="index > 0" class="row">
+                    <div class="row mb-3">
+                        <div class="col-md-3">
+                            <label class="text-secondary text-sm mb-1 d-block">Relationship</label>
+                            <select class="form-control form-control-sm min-width-unset" v-model="item.relationship" required>
+                                <option value="">-- select --</option>
+                                <option value="Mother">Mother</option>
+                                <option value="Father">Father</option>
+                                <option value="Sister (First)">Sister (First)</option>
+                                <option value="Sister (Second)">Sister (Second)</option>
+                                <option value="Sister (Third)">Sister (Third)</option>
+                                <option value="Sister (Fourth)">Sister (Fourth)</option>
+                                <option value="Brother (First)">Brother (First)</option>
+                                <option value="Brother (Second)">Brother (Second)</option>
+                                <option value="Brother (Third)">Brother (Third)</option>
+                                <option value="Brother (Fourth)">Brother (Fourth)</option>
+                                <option value="Daughter (First)">Daughter (First)</option>
+                                <option value="Daughter (Second)">Daughter (Second)</option>
+                                <option value="Daughter (Third)">Daughter (Third)</option>
+                                <option value="Daughter (Fourth)">Daughter (Fourth)</option>
+                                <option value="Son (First)">Son (First)</option>
+                                <option value="Son (Second)">Son (Second)</option>
+                                <option value="Son (Third)">Son (Third)</option>
+                                <option value="Son (Fourth)">Son (Fourth)</option>
+                                <option value="Half-sister">Half-sister</option>
+                                <option value="Half-brother">Half-brother</option>
+                                <option value="Maternal Aunt">Maternal Aunt</option>
+                                <option value="Paternal Aunt">Paternal Aunt</option>
+                                <option value="Maternal Uncle">Maternal Uncle</option>
+                                <option value="Paternal Uncle">Paternal Uncle</option>
+                                <option value="Niece">Niece</option>
+                                <option value="Nephew">Nephew</option>
+                                <option value="Maternal Cousin">Maternal Cousin</option>
+                                <option value="Paternal Cousin">Paternal Cousin</option>
+                                <option value="Maternal Grandmother">Maternal Grandmother</option>
+                                <option value="Maternal Grandfather">Maternal Grandfather</option>
+                                <option value="Paternal Grandmother">Paternal Grandmother</option>
+                                <option value="Paternal Grandfather">Paternal Grandfather</option>
+                                <option value="Granddaughter">Granddaughter</option>
+                                <option value="Grandson">Grandson</option>
+                            </select>
+                        </div>
+                        <div class="col-md-6">
+                            <label class="text-secondary text-sm mb-1 d-block">Health Status</label>
+                            <label class="my-0 mr-3 d-inline-flex align-items-center">
+                                <input type="radio" :name="'item_' + index + '_status'" v-model="item.status" value="Alive" class="mr-1">
+                                Alive
+                            </label>
+                            <label class="my-0 mr-3 d-inline-flex align-items-center">
+                                <input type="radio" :name="'item_' + index + '_status'" v-model="item.status" value="Deceased" class="mr-1">
+                                Deceased
+                            </label>
+                            <label class="my-0 mr-3 d-inline-flex align-items-center">
+                                <input type="radio" :name="'item_' + index + '_status'" v-model="item.status" value="Unknown" class="mr-1">
+                                Unknown
+                            </label>
+                        </div>
+                        <div class="col-md-2">
+                            <label class="text-secondary text-sm mb-1 d-block">&nbsp;</label>
+                            <div moe relative v-if="items.length > 1">
+                                <a href="#" start show><i class="fa fa-trash-alt text-danger on-hover-opaque"></i></a>
+                                <div url="/nop" right>
+                                    <p>Are you sure?</p>
+                                    <div class="">
+                                        <a class="btn btn-sm btn-danger text-white" v-on:click.prevent="removeItem(index)">Yes</a>
+                                        <button type="button" class="btn btn-sm btn-default border" cancel>No</button>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div class="row mb-1 font-weight-bold">
+                        <div class="col-8">
+                            General
+                        </div>
+                        <div class="col-4">
+                            Cancer
+                        </div>
+                    </div>
+                    <div class="row mb-1 font-weight-bold">
+                        <div class="col-4">
+                            <div class="rspace">+</div>
+                            <div class="rspace">-</div>
+                        </div>
+                        <div class="col-4">
+                            <div class="rspace">+</div>
+                            <div class="rspace">-</div>
+                        </div>
+                        <div class="col-4">
+                            <div class="rspace">+</div>
+                            <div class="rspace">-</div>
+                        </div>
+                    </div>
+                    <div class="row mb-3">
+                        <div class="col-4">
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_no_health_concern'" v-model="item.general_no_health_concern"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_no_health_concern'" v-model="item.general_no_health_concern"></div>
+                                <span class="ml-2">No Health Concern</span>
+                                <a href="#" v-show="item.general_no_health_concern" v-on:click.prevent="clearValue(item, 'general_no_health_concern')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_arthritis'" v-model="item.general_arthritis"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_arthritis'" v-model="item.general_arthritis"></div>
+                                <span class="ml-2">Arthritis</span>
+                                <a href="#" v-show="item.general_arthritis" v-on:click.prevent="clearValue(item, 'general_arthritis')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_asthma'" v-model="item.general_asthma"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_asthma'" v-model="item.general_asthma"></div>
+                                <span class="ml-2">Asthma</span>
+                                <a href="#" v-show="item.general_asthma" v-on:click.prevent="clearValue(item, 'general_asthma')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_bleeding_disorder'" v-model="item.general_bleeding_disorder"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_bleeding_disorder'" v-model="item.general_bleeding_disorder"></div>
+                                <span class="ml-2">Bleeding Disorder</span>
+                                <a href="#" v-show="item.general_bleeding_disorder" v-on:click.prevent="clearValue(item, 'general_bleeding_disorder')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_cad_lt_age_55'" v-model="item.general_cad_lt_age_55"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_cad_lt_age_55'" v-model="item.general_cad_lt_age_55"></div>
+                                <span class="ml-2">CAD < age 55</span>
+                                <a href="#" v-show="item.general_cad_lt_age_55" v-on:click.prevent="clearValue(item, 'general_cad_lt_age_55')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_copd'" v-model="item.general_copd"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_copd'" v-model="item.general_copd"></div>
+                                <span class="ml-2">COPD</span>
+                                <a href="#" v-show="item.general_copd" v-on:click.prevent="clearValue(item, 'general_copd')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_diabetes'" v-model="item.general_diabetes"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_diabetes'" v-model="item.general_diabetes"></div>
+                                <span class="ml-2">Diabetes</span>
+                                <a href="#" v-show="item.general_diabetes" v-on:click.prevent="clearValue(item, 'general_diabetes')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_heart_attack'" v-model="item.general_heart_attack"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_heart_attack'" v-model="item.general_heart_attack"></div>
+                                <span class="ml-2">Heart Attack</span>
+                                <a href="#" v-show="item.general_heart_attack" v-on:click.prevent="clearValue(item, 'general_heart_attack')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_heart_disease'" v-model="item.general_heart_disease"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_heart_disease'" v-model="item.general_heart_disease"></div>
+                                <span class="ml-2">Heart Disease</span>
+                                <a href="#" v-show="item.general_heart_disease" v-on:click.prevent="clearValue(item, 'general_heart_disease')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_high_cholesterol'" v-model="item.general_high_cholesterol"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_high_cholesterol'" v-model="item.general_high_cholesterol"></div>
+                                <span class="ml-2">High Cholesterol</span>
+                                <a href="#" v-show="item.general_high_cholesterol" v-on:click.prevent="clearValue(item, 'general_high_cholesterol')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_hypertension'" v-model="item.general_hypertension"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_hypertension'" v-model="item.general_hypertension"></div>
+                                <span class="ml-2">Hypertension</span>
+                                <a href="#" v-show="item.general_hypertension" v-on:click.prevent="clearValue(item, 'general_hypertension')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_mental_illness'" v-model="item.general_mental_illness"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_mental_illness'" v-model="item.general_mental_illness"></div>
+                                <span class="ml-2">Mental Illness</span>
+                                <a href="#" v-show="item.general_mental_illness" v-on:click.prevent="clearValue(item, 'general_mental_illness')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_osteoporosis'" v-model="item.general_osteoporosis"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_osteoporosis'" v-model="item.general_osteoporosis"></div>
+                                <span class="ml-2">Osteoporosis</span>
+                                <a href="#" v-show="item.general_osteoporosis" v-on:click.prevent="clearValue(item, 'general_osteoporosis')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_general_stroke'" v-model="item.general_stroke"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_general_stroke'" v-model="item.general_stroke"></div>
+                                <span class="ml-2">Stroke</span>
+                                <a href="#" v-show="item.general_stroke" v-on:click.prevent="clearValue(item, 'general_stroke')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                        </div>
+                        <div class="col-4">
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_cancer_breast_ca'" v-model="item.cancer_breast_ca"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_cancer_breast_ca'" v-model="item.cancer_breast_ca"></div>
+                                <span class="ml-2">Breast CA</span>
+                                <a href="#" v-show="item.cancer_breast_ca" v-on:click.prevent="clearValue(item, 'cancer_breast_ca')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_cancer_colon_ca'" v-model="item.cancer_colon_ca"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_cancer_colon_ca'" v-model="item.cancer_colon_ca"></div>
+                                <span class="ml-2">Colon CA</span>
+                                <a href="#" v-show="item.cancer_colon_ca" v-on:click.prevent="clearValue(item, 'cancer_colon_ca')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_cancer_other_ca'" v-model="item.cancer_other_ca"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_cancer_other_ca'" v-model="item.cancer_other_ca"></div>
+                                <span class="ml-2">Other CA</span>
+                                <a href="#" v-show="item.cancer_other_ca" v-on:click.prevent="clearValue(item, 'cancer_other_ca')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_cancer_ovarian_ca'" v-model="item.cancer_ovarian_ca"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_cancer_ovarian_ca'" v-model="item.cancer_ovarian_ca"></div>
+                                <span class="ml-2">Ovarian CA</span>
+                                <a href="#" v-show="item.cancer_ovarian_ca" v-on:click.prevent="clearValue(item, 'cancer_ovarian_ca')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                            <div class="d-flex align-items-center">
+                                <div class="rspace"><input type="radio" value="yes" :name="'item_' + index + '_cancer_uterine_ca'" v-model="item.cancer_uterine_ca"></div>
+                                <div class="rspace"><input type="radio" value="no" :name="'item_' + index + '_cancer_uterine_ca'" v-model="item.cancer_uterine_ca"></div>
+                                <span class="ml-2">Uterine CA</span>
+                                <a href="#" v-show="item.cancer_uterine_ca" v-on:click.prevent="clearValue(item, 'cancer_uterine_ca')"><i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i></a>
+                            </div>
+                        </div>
+                    </div>
+
+                    <div class="row mb-2">
+                        <div class="col-md-12">
+                        <textarea class="form-control form-control-sm" type="text" v-model="item.comments" :model-index="index" placeholder="Additional details (optional)">
+                        </textarea>
+                        </div>
+                    </div>
+
+                </div>
+
+                <div class="form-group my-2">
+                    <button v-if="!unknown" class="btn btn-sm btn-default text-primary border border-primary mr-2"
+                            v-on:click.prevent="addItem()"
+                    >Add Family Member</button>
+                </div>
+
+            </div>
+
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
+
+        </form>
+    </div>
+</div>
+<script>
+    (function() {
+
+        window.segmentInitializers.<?= !!@$segment ? $segment->segmentTemplate->internal_name : $segmentInternalName ?> = function() {
+
+            new Vue({
+                el: '#edit-univ_history_family-container',
+                data: {
+                    count: {{ $contentData['count'] }},
+                    unknown: {{ $contentData['unknown'] ? 'true' : 'false' }},
+                    items: <?= json_encode($contentData['items']) ?>
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            let parent = $('#edit-univ_history_family-container').closest('form');
+                            parent.find('[name="data"]').val(JSON.stringify(this.$data));
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+
+                    clearValue: function(_item, _key) {
+                        _item[_key] = null;
+                        Vue.nextTick(function() {
+                            $('#edit-univ_history_family-container').find('textarea').first().trigger('input');
+                        });
+                    },
+
+                    addItem: function() {
+                        this.items.push({
+                            relationship: '',
+                            status: '',
+
+                            general_no_health_concern: null,
+                            general_arthritis: null,
+                            general_asthma: null,
+                            general_bleeding_disorder: null,
+                            general_cad_lt_age_55: null,
+                            general_copd: null,
+                            general_diabetes: null,
+                            general_heart_attack: null,
+                            general_heart_disease: null,
+                            general_high_cholesterol: null,
+                            general_hypertension: null,
+                            general_mental_illness: null,
+                            general_osteoporosis: null,
+                            general_stroke: null,
+
+                            cancer_breast_ca: null,
+                            cancer_colon_ca: null,
+                            cancer_other_ca: null,
+                            cancer_ovarian_ca: null,
+                            cancer_uterine_ca: null,
+
+                            comments: '',
+                        });
+                        this.count = this.items.length;
+
+                        // trigger autosave!
+                        Vue.nextTick(() => {
+                            let parent = $('#edit-univ_history_family-container').closest('form');
+                            parent.find('[name="unknown"]').trigger('change');
+                            $('#edit-univ_history_family-container').find('[moe][initialized]').removeAttr('initialized');
+                            initMoes();
+                        });
+                    },
+                    removeItem: function(_index) {
+                        this.items.splice(_index, 1);
+                        this.count = this.items.length;
+
+                        // trigger autosave!
+                        Vue.nextTick(() => {
+                            let parent = $('#edit-univ_history_family-container').closest('form');
+                            parent.find('[name="unknown"]').trigger('change');
+                            hideMoeFormMask();
+                        });
+                    }
+                },
+                mounted: function() {
+                    $('#edit-univ_history_family-container').find('[moe][initialized]').removeAttr('initialized');
+                    initMoes();
+                }
+            });
+
+        };
+
+    }).call(window);
+</script>

+ 92 - 0
resources/views/app/patient/segment-templates/omega_history_family/log.blade.php

@@ -0,0 +1,92 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+$labels = [
+    'general_no_health_concern' => 'No health concern',
+    'general_arthritis' => 'Arthritis',
+    'general_asthma' => 'Asthma',
+    'general_bleeding_disorder' => 'Bleeding disorder',
+    'general_cad_lt_age_55' => 'CAD &gt; age 55',
+    'general_copd' => 'COPD',
+    'general_diabetes' => 'Diabetes',
+    'general_heart_attack' => 'Heart attack',
+    'general_heart_disease' => 'Heart disease',
+    'general_high_cholesterol' => 'High cholesterol',
+    'general_hypertension' => 'Hypertension',
+    'general_mental_illness' => 'Mental illness',
+    'general_osteoporosis' => 'Osteoporosis',
+    'general_stroke' => 'Stroke',
+    'cancer_breast_ca' => 'Breast cancer',
+    'cancer_colon_ca' => 'Colon cancer',
+    'cancer_other_ca' => 'Other cancer',
+    'cancer_ovarian_ca' => 'Ovarian cancer',
+    'cancer_uterine_ca' => 'Uterine cancer',
+];
+
+$point = Point::getOnlyTopLevelPointOfCategory($note, 'FAMILY_HISTORY', true);
+
+if($point) {
+    ?> <div class="popup-content-container px-3"> <?php
+    foreach ($point->childReviews as $childReview) {
+        $contentData = $parsed = false;
+        if ($childReview->data) {
+            $childReview->data = json_decode($childReview->data, true);
+            $contentData = $parsed = $childReview->data;
+
+            if($contentData && !$contentData['unknown'] && !!$contentData['count']) {
+                ?>
+                <div class="mb-1 font-weight-bold">{{$childReview->creatorPro->displayName()}} - {{friendly_date($childReview->note->effective_dateest)}}</div>
+                <div class="pl-3 bg-light border p-3 mb-3">
+                <?php
+                for ($i = 0; $i < $contentData['count']; $i++) {
+                    ?>
+                    <div class="<?= $i > 0 ? 'mt-2' : '' ?>">
+                        <div class="">
+                            <b><?= isset($contentData['items'][$i]['relationship']) ? $contentData['items'][$i]['relationship'] : '--' ?></b>
+                            <?php if(isset($contentData['items'][$i]['status']) && !empty($contentData['items'][$i]['status'])): ?>
+                            <span class="ml-1 text-secondary">(<?= $contentData['items'][$i]['status'] ?>)</span>
+                            <?php endif; ?>
+                        </div>
+                        <div class="ml-3">
+                            <?php
+                            $positives = [];
+                            $negatives = [];
+                            foreach ($labels as $k => $v) {
+                                if(isset($contentData['items'][$i][$k])) {
+                                    if(strtolower($contentData['items'][$i][$k]) === 'yes') {
+                                        $positives[] = $v;
+                                    }
+                                    else {
+                                        $negatives[] = $v;
+                                    }
+                                }
+                            }
+                            ?>
+                            @if(count($positives))
+                                <div class="pt-1"><b>Positive for</b>: {!!  implode(', ', $positives) !!}</div>
+                            @endif
+                            @if(count($negatives))
+                                <div class="pt-1"><b>Negative for</b>: {!!  implode(', ', $negatives) !!}</div>
+                            @endif
+                        </div>
+                        <?php if(isset($contentData['items'][$i]['comments']) && !empty($contentData['items'][$i]['comments'])): ?>
+                        <div class="ml-3 pt-1 client-rs-contents">
+                            <b>Comments: </b><?= $contentData['items'][$i]['comments'] ?>
+                        </div>
+                        <?php endif; ?>
+                    </div>
+                    <?php
+                }
+                ?>
+                </div>
+                <?php
+            }
+        }
+    }
+    ?> </div> <?php
+}

+ 93 - 1
resources/views/app/patient/segment-templates/omega_history_family/summary.blade.php

@@ -1 +1,93 @@
-<h1>omega_history_family</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+if(!@$note) {
+    $note = $patient->coreNote;
+}
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'FAMILY_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+$labels = [
+    'general_no_health_concern' => 'No health concern',
+    'general_arthritis' => 'Arthritis',
+    'general_asthma' => 'Asthma',
+    'general_bleeding_disorder' => 'Bleeding disorder',
+    'general_cad_lt_age_55' => 'CAD &gt; age 55',
+    'general_copd' => 'COPD',
+    'general_diabetes' => 'Diabetes',
+    'general_heart_attack' => 'Heart attack',
+    'general_heart_disease' => 'Heart disease',
+    'general_high_cholesterol' => 'High cholesterol',
+    'general_hypertension' => 'Hypertension',
+    'general_mental_illness' => 'Mental illness',
+    'general_osteoporosis' => 'Osteoporosis',
+    'general_stroke' => 'Stroke',
+    'cancer_breast_ca' => 'Breast cancer',
+    'cancer_colon_ca' => 'Colon cancer',
+    'cancer_other_ca' => 'Other cancer',
+    'cancer_ovarian_ca' => 'Ovarian cancer',
+    'cancer_uterine_ca' => 'Uterine cancer',
+];
+
+if($contentData && !$contentData['unknown'] && !!$contentData['count']) {
+    for ($i = 0; $i < $contentData['count']; $i++) {
+?>
+<div class="<?= $i > 0 ? 'mt-2' : '' ?>">
+    <div class="">
+        <b><?= isset($contentData['items'][$i]['relationship']) ? $contentData['items'][$i]['relationship'] : '--' ?></b>
+        <?php if(isset($contentData['items'][$i]['status']) && !empty($contentData['items'][$i]['status'])): ?>
+        <span class="ml-1 text-secondary">(<?= $contentData['items'][$i]['status'] ?>)</span>
+        <?php endif; ?>
+    </div>
+    <div class="ml-3">
+        <?php
+        $positives = [];
+        $negatives = [];
+        foreach ($labels as $k => $v) {
+            if(isset($contentData['items'][$i][$k])) {
+                if(strtolower($contentData['items'][$i][$k]) === 'yes') {
+                    $positives[] = $v;
+                }
+                else {
+                    $negatives[] = $v;
+                }
+            }
+        }
+        ?>
+        @if(count($positives))
+            <div class="pt-1"><b>Positive for</b>: {!!  implode(', ', $positives) !!}</div>
+        @endif
+        @if(count($negatives))
+            <div class="pt-1"><b>Negative for</b>: {!!  implode(', ', $negatives) !!}</div>
+        @endif
+    </div>
+    <?php if(isset($contentData['items'][$i]['comments']) && !empty($contentData['items'][$i]['comments'])): ?>
+    <div class="ml-3 pt-1 client-rs-contents">
+        <b>Comments: </b><?= $contentData['items'][$i]['comments'] ?>
+    </div>
+    <?php endif; ?>
+</div>
+<?php
+    }
+}
+else {
+?>
+<div class="text-secondary">-</div>
+<?php
+}
+?>

+ 281 - 1
resources/views/app/patient/segment-templates/omega_history_past_medical/edit.blade.php

@@ -1 +1,281 @@
-<h1>omega_history_past_medical</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+/** @var Segment $segment */
+
+if(!@$segment) $segment = null;
+
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$fields = [
+    [
+        "Head" => ["Trauma"],
+        "Eyes" => ["Blindness", "Cataracts", "Glaucoma", "Wears glasses/contacts"],
+        "Ears" => ["Hearing aids"],
+        "Nose/Sinuses" => ["Allergic Rhinitis", "Sinus infections"],
+        "Mouth/Throat/Teeth" => ["Dentures"],
+        "Cardiovascular" => ["Aneurysm", "Angina", "DVT", "Dysrhythmia", "HTN", "Murmur", "Myocardial infarction", "Other heart disease"],
+    ],
+    [
+        "Respiratory" => ["Asthma", "Bronchitis", "COPD - Bronchitis/Emphysema", "Pleuritis", "Pneumonia"],
+        "Gastrointestinal" => ["Cirrhosis", "GERD", "Gallbladder disease", "Heartburn", "Hemorrhoids", "Hepatitis", "Hiatal hernia", "Jaundice", "Ulcer"],
+        "Genitourinary" => ["Hernia", "Incontinence", "Nephrolithiasis", "Other kidney disease", "STDs", "UTI(s)"],
+    ],
+    [
+        "Musculoskeletal" => ["Arthritis", "Gout", "M/S injury"],
+        "Skin" => ["Dermatitis", "Mole(s)", "Other skin condition(s)", "Psoriasis"],
+        "Neurological" => ["Epilepsy", "Seizures", "Severe headaches, migraines", "Stroke", "TIA"],
+        "Psychiatric" => ["Bipolar disorder", "Depression", "Hallucinations, delusions", "Suicidal ideation", "Suicide attempts"],
+    ],
+    [
+        "Endocrine" => ["Goiter", "Hyperlipidemia", "Hypothyroidism", "Thyroid disease", "Thyroiditis", "Type I DM", "Type II DM"],
+        "Heme/Onc" => ["Anemia", "Cancer"],
+        "Infectious" => ["HIV", "STDs", "Tuberculosis (dz)", "Tuberculosis (exposure)"],
+    ]
+];
+
+$customFields = $pro->canvasCustomItems('pmhx');
+/*$customFields = array_map(function($_item) {
+    return $_item['label'];
+}, $customFields->toArray());*/
+
+if(!$customFields) $customFields = [];
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'PAST_MEDICAL_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "bloodType" => "",
+        "bloodRH" => "",
+        "common" => [],
+        "custom" => [],
+        "comments" => "",
+    ];
+}
+
+for ($i = 0; $i < count($fields); $i++) {
+    foreach($fields[$i] as $head => $values) {
+        for($k = 0; $k < count($values); $k++) {
+            $fName = $head . '_' . sanitize_field_name($values[$k]);
+            if(!isset($contentData["common"][$fName])) $contentData["common"][$fName] = null;
+        }
+    }
+}
+?>
+<hr class="hide-outside-popup mt-3 mb-0">
+<div class="p-3 mcp-theme-1">
+    <div {{!!$segment ? 'visit-moe' : 'moe'}} close-on-save close-on-cancel class="d-block">
+        <form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1"
+                {{!$segment ? 'hook=onHxPopupClosure' : ''}}>
+            @if(!!@$segment)
+                <input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
+            @else
+                <input type="hidden" name="segmentUid" value="<?= $note->coreSegment->uid ?>">
+            @endif
+            <input type="hidden" name="uid" value="<?= $point->uid ?>">
+            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+            <input type="hidden" name="data">
+
+            <div id="edit-univ_history_past_medical-container">
+                <div class="d-flex align-items-center mb-2">
+                    <div class="width-100px mr-3">
+                        <label class="text-secondary mb-1">Blood Type</label>
+                        <select class="form-control form-control-sm width-100px" v-model="bloodType">
+                            <option value=""> -- select -- </option>
+                            <option value="A">A</option>
+                            <option value="AB">AB</option>
+                            <option value="B">B</option>
+                            <option value="O">O</option>
+                        </select>
+                    </div>
+                    <div class="width-100px mr-3">
+                        <label class="text-secondary mb-1">RH</label>
+                        <select class="form-control form-control-sm width-100px" v-model="bloodRH">
+                            <option value=""> -- select -- </option>
+                            <option value="+ve">+ve</option>
+                            <option value="-ve">-ve</option>
+                        </select>
+                    </div>
+                </div>
+                <div class="d-flex align-items-start flex-wrap custom-items-container">
+                    @for ($i = 0; $i < count($fields); $i++)
+                        <div class="w-25">
+                            @foreach($fields[$i] as $head => $values)
+                                <div class="font-weight-bold mb-2">{{ $head }}</div>
+                                <div class="mb-3">
+                                    @for($k = 0; $k < count($values); $k++)
+                                        <?php $fName = $head . '_' . sanitize_field_name($values[$k]); ?>
+                                        <label class="d-flex align-items-start mb-1">
+                                            <input type="checkbox" name="{{ $fName }}" class="mx-0 mt-1"
+                                                   v-model="common['{{$fName}}']">
+                                            <div class="ml-2">
+                                                <div>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
+                                                    <div moe relative no-mask v-show="common['{{$fName}}']" >
+                                                        <a href="#" start show>
+                                                            <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
+                                                        </a>
+                                                        <div url="/nop">
+                                                            <div class="mb-2">
+                                                                <textarea class="form-control form-control-sm ns-custom-comment min-width-200px"
+                                                                          v-model="common['{{$fName}}__comments']"></textarea>
+                                                            </div>
+                                                            <div class="">
+                                                                <button type="button" class="btn btn-sm btn-primary" cancel>Close
+                                                                </button>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                    <a v-show="common['{{$fName}}']"
+                                                       class="ml-1"
+                                                       open-in-stag-popup
+                                                       mc-initer="problems-center-{{$note->id}}"
+                                                       title="Problems Center"
+                                                       popup-style="wide overflow-visible"
+                                                       href="/problems-center/{{$patient->uid}}/{{$note->uid}}?dx={{urlencode($values[$k])}}">
+                                                        <i class="fa fa-plus-circle on-hover-opaque"></i>
+                                                    </a>
+                                                </div>
+                                                <span v-show="common['{{$fName}}'] && common['{{$fName}}__comments']"
+                                                      v-html="common['{{$fName}}__comments']"
+                                                      class="text-sm text-secondary">
+                                                </span>
+                                            </div>
+                                        </label>
+                                    @endfor
+                                </div>
+                            @endforeach
+                        </div>
+                    @endfor
+                </div>
+                <div class="row border-top pt-3">
+                    <div class="col-12">
+                        @include('app.patient.segment-templates._custom_items.edit')
+                    </div>
+                </div>
+                <hr class="m-neg-4">
+                <div class="mb-2">
+                    <textarea class="form-control form-control-sm" v-model="comments">{!! $parsed && @$parsed->content ? @$parsed->content : '' !!}</textarea>
+                </div>
+            </div>
+
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                        <i class="fa fa-check"></i>
+                        Saved
+                    </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
+
+        </form>
+    </div>
+</div>
+<script>
+    (function() {
+
+        window.segmentInitializers.<?= !!@$segment ? $segment->segmentTemplate->internal_name : $segmentInternalName ?> = function() {
+
+            let model = <?= $contentData ? json_encode($contentData) : '{}' ?>;
+            model.newCustomItemLabel = '';
+            let myCustomFields = <?= json_encode($customFields) ?>;
+            if(!model.customFields) {
+                model.customFields = [];
+            }
+            for (let i = 0; i < myCustomFields.length; i++) {
+                let foundAt = -1;
+                for (let j = 0; j < model.customFields.length; j++) {
+                    if(model.customFields[j].label === myCustomFields[i].label) {
+                        foundAt = j;
+                        break;
+                    }
+                }
+                if(foundAt === -1) {
+                    model.customFields.push({
+                        label: myCustomFields[i].label,
+                        value: '',
+                        comments: '',
+                        uid: myCustomFields[i].uid
+                    })
+                }
+                else {
+                    model.customFields[foundAt].uid = myCustomFields[i].uid;
+                }
+            }
+
+            // if not own AND not active - remove from model.customFields
+            for (let i = model.customFields.length - 1; i >= 0 ; i--) {
+                let foundAt = -1;
+                for (let j = 0; j < myCustomFields.length; j++) {
+                    if(model.customFields[i].label === myCustomFields[j].label) {
+                        foundAt = j;
+                        break;
+                    }
+                }
+                if(foundAt === -1) {
+                    if(!!model.customFields[i].value) {
+                        model.customFields[i].other = true;
+                    }
+                    else {
+                        model.customFields.splice(i, 1);
+                    }
+                }
+            }
+
+            // sort by label
+            model.customFields.sort(function (a, b) {
+                return a.label.localeCompare(b.label);
+            });
+
+            model.itemKey = 'pmhx';
+
+            new Vue({
+                el: '#edit-univ_history_past_medical-container',
+                delimiters: ["@{{","}}"],
+                data: model,
+                mounted: function() {
+                    $('#edit-univ_history_past_medical-container [moe][initialized]').removeAttr('initialized');
+                    initMoes();
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            let parent = $('#edit-univ_history_past_medical-container').closest('form');
+                            parent.find('[name="data"]').val(JSON.stringify(this.$data));
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+                    @include('app.patient.segment-templates._custom_items.script')
+                }
+            });
+
+            window.segmentInitializers.<?= !!@$segment ? $segment->segmentTemplate->internal_name : $segmentInternalName ?> = function() {};
+
+        };
+
+    }).call(window);
+</script>

+ 128 - 1
resources/views/app/patient/segment-templates/omega_history_past_medical/summary.blade.php

@@ -1 +1,128 @@
-<h1>omega_history_past_medical</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+if(!@$note) {
+    $note = $patient->coreNote;
+}
+
+$fields = [
+    [
+        "Head" => ["Trauma"],
+        "Eyes" => ["Blindness", "Cataracts", "Glaucoma", "Wears glasses/contacts"],
+        "Ears" => ["Hearing aids"],
+        "Nose/Sinuses" => ["Allergic Rhinitis", "Sinus infections"],
+        "Mouth/Throat/Teeth" => ["Dentures"],
+        "Cardiovascular" => ["Aneurysm", "Angina", "DVT", "Dysrhythmia", "HTN", "Murmur", "Myocardial infarction", "Other heart disease"],
+    ],
+    [
+        "Respiratory" => ["Asthma", "Bronchitis", "COPD - Bronchitis/Emphysema", "Pleuritis", "Pneumonia"],
+        "Gastrointestinal" => ["Cirrhosis", "GERD", "Gallbladder disease", "Heartburn", "Hemorrhoids", "Hepatitis", "Hiatal hernia", "Jaundice", "Ulcer"],
+        "Genitourinary" => ["Hernia", "Incontinence", "Nephrolithiasis", "Other kidney disease", "STDs", "UTI(s)"],
+    ],
+    [
+        "Musculoskeletal" => ["Arthritis", "Gout", "M/S injury"],
+        "Skin" => ["Dermatitis", "Mole(s)", "Other skin condition(s)", "Psoriasis"],
+        "Neurological" => ["Epilepsy", "Seizures", "Severe headaches, migraines", "Stroke", "TIA"],
+        "Psychiatric" => ["Bipolar disorder", "Depression", "Hallucinations, delusions", "Suicidal ideation", "Suicide attempts"],
+    ],
+    [
+        "Endocrine" => ["Goiter", "Hyperlipidemia", "Hypothyroidism", "Thyroid disease", "Thyroiditis", "Type I DM", "Type II DM"],
+        "Heme/Onc" => ["Anemia", "Cancer"],
+        "Infectious" => ["HIV", "STDs", "Tuberculosis (dz)", "Tuberculosis (exposure)"],
+    ]
+];
+
+$contentData = [
+    "bloodType" => "",
+    "bloodRH" => "",
+    "common" => [],
+    "customFields" => [],
+    "comments" => "",
+];
+$isempty = false;
+
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'PAST_MEDICAL_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+if ($contentData) {
+
+    $blood = [];
+    if(isset($contentData['bloodType'])) {
+        $blood[] = $contentData['bloodType'];
+    }
+    if(isset($contentData['bloodRH'])) {
+        $blood[] = $contentData['bloodRH'];
+    }
+    $blood = implode(" ", $blood);
+    if(!empty(trim($blood))) { ?>
+        <div class="mb-2">
+            <div>Blood Type &amp; RH: <b><?= $blood ?></b></div>
+        </div>
+    <?php }
+
+    for ($i = 0; $i < count($fields); $i++):
+        foreach($fields[$i] as $head => $values):
+            for($k = 0; $k < count($values); $k++):
+                $fName = $head . '_' . sanitize_field_name($values[$k]);
+                if(@$contentData['common'][$fName]): ?>
+                    <div>
+                        <?= ucwords($head) ?>
+                        <i class="fa fa-arrow-right text-sm text-secondary"></i>
+                        <span class="font-weight-bold"><?= $values[$k] ?></span>
+                        <?php if(@$contentData['common'][$fName . '__comments']): ?>
+                            <span class="text-sm ml-1 text-secondary">(<?= $contentData['common'][$fName . '__comments'] ?>)</span>
+                        <?php endif; ?>
+                    </div>
+                <?php
+                endif;
+            endfor;
+        endforeach;
+    endfor;
+
+    // custom fields
+
+    if(isset($contentData['customFields']) && count($contentData['customFields'])):
+        ?> <div class=""> <?php
+        for ($i = 0; $i < count($contentData['customFields']); $i++):
+            $item = $contentData['customFields'][$i];
+            if($item['value']): ?>
+                <div>
+                    Custom
+                    <i class="fa fa-arrow-right text-sm text-secondary"></i>
+                    <span class="font-weight-bold"><?= $item['label'] ?></span>
+                    <?php if($item['comments']): ?>
+                        <span class="text-sm ml-1 text-secondary">(<?= $item['comments'] ?>)</span>
+                    <?php endif; ?>
+                </div>
+            <?php
+            endif;
+        endfor;
+        ?> </div> <?php
+    endif;
+
+    if(isset($contentData['comments']) && !empty(trim($contentData['comments']))) { ?>
+        <div class="mt-2 mb-1">
+            <b>Comments: </b><?= $contentData['comments'] ?>
+        </div>
+    <?php }
+
+} else {
+    echo '<div class="text-secondary">-</div>';
+}
+?>
+

+ 239 - 1
resources/views/app/patient/segment-templates/omega_history_surgical/edit.blade.php

@@ -1 +1,239 @@
-<h1>omega_history_surgical</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+/** @var Segment $segment */
+
+if(!@$segment) $segment = null;
+
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$fields = [
+    [
+        "" => ["Aneurysm repair", "Appendectomy", "Back surgery", "Bariatric surgery/gastric bypass", "Bilateral tubal ligation", "Breast resection/mastectomy", "CABG", "Carotid endarterectomy/stent", "Carpal tunnel release surgery",]
+    ],
+    [
+        "" => ["Cataract/lens surgery", "Cesarean section", "Cholecystectomy/bile duct surgery", "Dilation and curettage", "Hemorrhoid surgery", "Hip arthroplasty", "Hip replacement", "Hysterectomy", "Inguinal hernia repair",]
+    ],
+    [
+        "" => ["Knee arthroplasty", "LASIK", "Laminectomy", "Nasal surgery", "PTCA/PCI", "Pacemaker/defibrillator", "Prostate surgery", "Prostatectomy", "Rotator cuff surgery",]
+    ],
+    [
+        "" => ["Sinus surgery", "Skin cancer excision", "Spinal fusion", "TAH-BSO", "TURP", "Tonsillectomy/Adenoidectomy", "Vasectomy",]
+    ]
+];
+
+$customFields = $pro->canvasCustomItems('pshx');
+/*$customFields = array_map(function($_item) {
+    return $_item['label'];
+}, $customFields->toArray());*/
+
+if(!$customFields) $customFields = [];
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'SURGICAL_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "common" => [],
+        "custom" => [],
+        "comments" => "",
+    ];
+}
+
+for ($i = 0; $i < count($fields); $i++) {
+    foreach($fields[$i] as $head => $values) {
+        for($k = 0; $k < count($values); $k++) {
+            $fName = $head . '_' . sanitize_field_name($values[$k]);
+            if(!isset($contentData["common"][$fName])) $contentData["common"][$fName] = null;
+        }
+    }
+}
+?>
+<hr class="hide-outside-popup mt-3 mb-0">
+<div class="p-3 mcp-theme-1">
+    <div {{!!$segment ? 'visit-moe' : 'moe'}} close-on-save close-on-cancel class="d-block">
+        <form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1"
+                {{!$segment ? 'hook=onHxPopupClosure' : ''}}>
+            @if(!!@$segment)
+                <input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
+            @else
+                <input type="hidden" name="segmentUid" value="<?= $note->coreSegment->uid ?>">
+            @endif
+            <input type="hidden" name="uid" value="<?= $point->uid ?>">
+            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+            <input type="hidden" name="data">
+
+            <div id="edit-univ_history_surgical-container">
+                <div class="d-flex align-items-center mb-2">
+                    <span class="font-weight-bold">Common Surgeries</span>
+                </div>
+                <div class="d-flex align-items-start flex-wrap custom-items-container">
+                    @for ($i = 0; $i < count($fields); $i++)
+                        <div class="w-25">
+                            @foreach($fields[$i] as $head => $values)
+                                <div class="font-weight-bold mb-2">{{ $head }}</div>
+                                <div class="mb-3">
+                                    @for($k = 0; $k < count($values); $k++)
+                                        <?php $fName = $head . '_' . sanitize_field_name($values[$k]); ?>
+                                        <label class="d-flex align-items-start mb-1">
+                                            <input type="checkbox" name="{{ $fName }}" class="mx-0 mt-1"
+                                                   v-model="common['{{$fName}}']">
+                                            <div class="ml-2">
+                                                <div>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
+                                                    <div moe relative no-mask v-show="common['{{$fName}}']" >
+                                                        <a href="#" start show>
+                                                            <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
+                                                        </a>
+                                                        <div url="/nop" right>
+                                                            <div class="mb-2">
+                                                                <textarea class="form-control form-control-sm ns-custom-comment min-width-200px"
+                                                                          v-model="common['{{$fName}}__comments']"></textarea>
+                                                            </div>
+                                                            <div class="">
+                                                                <button type="button" class="btn btn-sm btn-primary" cancel>Close
+                                                                </button>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                </div>
+                                                <span v-show="common['{{$fName}}'] && common['{{$fName}}__comments']"
+                                                      v-html="common['{{$fName}}__comments']"
+                                                      class="text-sm text-secondary">
+                                                </span>
+                                            </div>
+                                        </label>
+                                    @endfor
+                                </div>
+                            @endforeach
+                        </div>
+                    @endfor
+                </div>
+                <div class="row border-top pt-3">
+                    <div class="col-12">
+                        @include('app.patient.segment-templates._custom_items.edit')
+                    </div>
+                </div>
+                <hr class="m-neg-4">
+                <div class="mb-2">
+                    <textarea class="form-control form-control-sm" v-model="comments">{!! $parsed && @$parsed->content ? @$parsed->content : '' !!}</textarea>
+                </div>
+            </div>
+
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
+
+        </form>
+    </div>
+</div>
+<script>
+    (function() {
+
+        window.segmentInitializers.<?= !!@$segment ? $segment->segmentTemplate->internal_name : $segmentInternalName ?> = function() {
+
+            let model = <?= $contentData ? json_encode($contentData) : '{}' ?>;
+            model.newCustomItemLabel = '';
+            let myCustomFields = <?= json_encode($customFields) ?>;
+            if(!model.customFields) {
+                model.customFields = [];
+            }
+            for (let i = 0; i < myCustomFields.length; i++) {
+                let foundAt = -1;
+                for (let j = 0; j < model.customFields.length; j++) {
+                    if(model.customFields[j].label === myCustomFields[i].label) {
+                        foundAt = j;
+                        break;
+                    }
+                }
+                if(foundAt === -1) {
+                    model.customFields.push({
+                        label: myCustomFields[i].label,
+                        value: '',
+                        comments: '',
+                        uid: myCustomFields[i].uid
+                    })
+                }
+                else {
+                    model.customFields[foundAt].uid = myCustomFields[i].uid;
+                }
+            }
+
+            // if not own AND not active - remove from model.customFields
+            for (let i = model.customFields.length - 1; i >= 0 ; i--) {
+                let foundAt = -1;
+                for (let j = 0; j < myCustomFields.length; j++) {
+                    if(model.customFields[i].label === myCustomFields[j].label) {
+                        foundAt = j;
+                        break;
+                    }
+                }
+                if(foundAt === -1) {
+                    if(!!model.customFields[i].value) {
+                        model.customFields[i].other = true;
+                    }
+                    else {
+                        model.customFields.splice(i, 1);
+                    }
+                }
+            }
+
+            // sort by label
+            model.customFields.sort(function (a, b) {
+                return a.label.localeCompare(b.label);
+            });
+
+            model.itemKey = 'pshx';
+
+            new Vue({
+                el: '#edit-univ_history_surgical-container',
+                delimiters: ["@{{","}}"],
+                data: model,
+                mounted: function() {
+                    $('#edit-univ_history_surgical-container [moe][initialized]').removeAttr('initialized');
+                    initMoes();
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            let parent = $('#edit-univ_history_surgical-container').closest('form');
+                            parent.find('[name="data"]').val(JSON.stringify(this.$data));
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+                    @include('app.patient.segment-templates._custom_items.script')
+                }
+            });
+
+        };
+
+    }).call(window);
+</script>

+ 88 - 0
resources/views/app/patient/segment-templates/omega_history_surgical/log.blade.php

@@ -0,0 +1,88 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+$fields = [
+    [
+        "" => ["Aneurysm repair", "Appendectomy", "Back surgery", "Bariatric surgery/gastric bypass", "Bilateral tubal ligation", "Breast resection/mastectomy", "CABG", "Carotid endarterectomy/stent", "Carpal tunnel release surgery",]
+    ],
+    [
+        "" => ["Cataract/lens surgery", "Cesarean section", "Cholecystectomy/bile duct surgery", "Dilation and curettage", "Hemorrhoid surgery", "Hip arthroplasty", "Hip replacement", "Hysterectomy", "Inguinal hernia repair",]
+    ],
+    [
+        "" => ["Knee arthroplasty", "LASIK", "Laminectomy", "Nasal surgery", "PTCA/PCI", "Pacemaker/defibrillator", "Prostate surgery", "Prostatectomy", "Rotator cuff surgery",]
+    ],
+    [
+        "" => ["Sinus surgery", "Skin cancer excision", "Spinal fusion", "TAH-BSO", "TURP", "Tonsillectomy/Adenoidectomy", "Vasectomy",]
+    ]
+];
+
+
+$point = Point::getOnlyTopLevelPointOfCategory($note, 'SURGICAL_HISTORY', true);
+
+if($point) {
+    ?> <div class="popup-content-container px-3"> <?php
+    foreach ($point->childReviews as $childReview) {
+        $contentData = $parsed = false;
+        if ($childReview->data) {
+            $childReview->data = json_decode($childReview->data, true);
+            $contentData = $parsed = $childReview->data;
+
+            ?>
+            <div class="mb-1 font-weight-bold">{{$childReview->creatorPro->displayName()}} - {{friendly_date($childReview->note->effective_dateest)}}</div>
+            <div class="pl-3 bg-light border p-3 mb-3">
+            <?php
+
+            for ($i = 0; $i < count($fields); $i++):
+            foreach($fields[$i] as $head => $values):
+            for($k = 0; $k < count($values); $k++):
+            $fName = $head . '_' . sanitize_field_name($values[$k]);
+            if(@$contentData['common'][$fName]): ?>
+            <div>
+                <!--Common
+                <i class="fa fa-arrow-right text-sm text-secondary"></i>-->
+                <span class="font-weight-bold"><?= $values[$k] ?></span>
+                <?php if(@$contentData['common'][$fName . '__comments']): ?>
+                <span class="text-sm ml-1 text-secondary">(<?= $contentData['common'][$fName . '__comments'] ?>)</span>
+                <?php endif; ?>
+            </div>
+            <?php
+            endif;
+            endfor;
+            endforeach;
+            endfor;
+
+            // custom fields
+
+            if(isset($contentData['customFields']) && count($contentData['customFields'])):
+            ?> <div class=""> <?php
+                for ($i = 0; $i < count($contentData['customFields']); $i++):
+                $item = $contentData['customFields'][$i];
+                if($item['value']): ?>
+                <div>
+                    <!--Custom
+                    <i class="fa fa-arrow-right text-sm text-secondary"></i>-->
+                    <span class="font-weight-bold"><?= $item['label'] ?></span>
+                    <?php if($item['comments']): ?>
+                    <span class="text-sm ml-1 text-secondary">(<?= $item['comments'] ?>)</span>
+                    <?php endif; ?>
+                </div>
+                <?php
+                endif;
+                endfor;
+                ?> </div> <?php
+            endif;
+
+            if(isset($contentData['comments']) && !empty(trim($contentData['comments']))) { ?>
+            <div class="mt-2 mb-1">
+                <b>Comments: </b><?= $contentData['comments'] ?>
+            </div>
+            <?php }
+        }
+    }
+    ?> </div> <?php
+}

+ 89 - 1
resources/views/app/patient/segment-templates/omega_history_surgical/summary.blade.php

@@ -1 +1,89 @@
-<h1>omega_history_surgical</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+/** @var Segment $segment */
+
+if(!@$note) {
+    $note = $patient->coreNote;
+}
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$fields = [
+    [
+        "" => ["Aneurysm repair", "Appendectomy", "Back surgery", "Bariatric surgery/gastric bypass", "Bilateral tubal ligation", "Breast resection/mastectomy", "CABG", "Carotid endarterectomy/stent", "Carpal tunnel release surgery",]
+    ],
+    [
+        "" => ["Cataract/lens surgery", "Cesarean section", "Cholecystectomy/bile duct surgery", "Dilation and curettage", "Hemorrhoid surgery", "Hip arthroplasty", "Hip replacement", "Hysterectomy", "Inguinal hernia repair",]
+    ],
+    [
+        "" => ["Knee arthroplasty", "LASIK", "Laminectomy", "Nasal surgery", "PTCA/PCI", "Pacemaker/defibrillator", "Prostate surgery", "Prostatectomy", "Rotator cuff surgery",]
+    ],
+    [
+        "" => ["Sinus surgery", "Skin cancer excision", "Spinal fusion", "TAH-BSO", "TURP", "Tonsillectomy/Adenoidectomy", "Vasectomy",]
+    ]
+];
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'SURGICAL_HISTORY', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+
+    for ($i = 0; $i < count($fields); $i++):
+        foreach($fields[$i] as $head => $values):
+            for($k = 0; $k < count($values); $k++):
+                $fName = $head . '_' . sanitize_field_name($values[$k]);
+                if(@$contentData['common'][$fName]): ?>
+                    <div>
+                        <!--Common
+                        <i class="fa fa-arrow-right text-sm text-secondary"></i>-->
+                        <span class="font-weight-bold"><?= $values[$k] ?></span>
+                        <?php if(@$contentData['common'][$fName . '__comments']): ?>
+                            <span class="text-sm ml-1 text-secondary">(<?= $contentData['common'][$fName . '__comments'] ?>)</span>
+                        <?php endif; ?>
+                    </div>
+                <?php
+                endif;
+            endfor;
+        endforeach;
+    endfor;
+
+    // custom fields
+
+    if(isset($contentData['customFields']) && count($contentData['customFields'])):
+        ?> <div class=""> <?php
+        for ($i = 0; $i < count($contentData['customFields']); $i++):
+            $item = $contentData['customFields'][$i];
+            if($item['value']): ?>
+                <div>
+                    <!--Custom
+                    <i class="fa fa-arrow-right text-sm text-secondary"></i>-->
+                    <span class="font-weight-bold"><?= $item['label'] ?></span>
+                    <?php if($item['comments']): ?>
+                        <span class="text-sm ml-1 text-secondary">(<?= $item['comments'] ?>)</span>
+                    <?php endif; ?>
+                </div>
+            <?php
+            endif;
+        endfor;
+        ?> </div> <?php
+    endif;
+
+    if(isset($contentData['comments']) && !empty(trim($contentData['comments']))) { ?>
+        <div class="mt-2 mb-1">
+            <b>Comments: </b><?= $contentData['comments'] ?>
+        </div>
+    <?php }
+}
+else {
+    echo '<span class="text-secondary">-</span>';
+}
+?>

+ 413 - 1
resources/views/app/patient/segment-templates/omega_ros/edit.blade.php

@@ -1 +1,413 @@
-<h1>omega_ros</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+use App\Models\Segment;
+/** @var Client $patient */
+/** @var Note $note */
+/** @var Segment $segment */
+
+if(!@$segment) $segment = null;
+
+$fields = [
+    [
+        "Constitutional" => [
+            "Fatigue",
+            "Fever",
+            "Weight gain",
+            "Weight loss"],
+
+        "Eyes" => [
+            "Blurry vision",
+            "Double vision",
+            "Dry eyes",
+            "Floaters",
+            "Halos",
+            "Headache",
+            "Irritation",
+            "Loss of peripheral vision",
+            "Pain",
+            "Pinpoint pupils",
+            "Teary",
+            "Visual changes"],
+
+        "ENMT" => [
+            "Altered sense of smell",
+            "Dental caries",
+            "Dentures",
+            "Dizziness",
+            "Dry mouth",
+            "Ear pain/pressure",
+            "Hearing loss",
+            "Mouth pain",
+            "Nasal congestion",
+            "Neck pain/stiffness",
+            "Post nasal drainage",
+            "Sinus pain / pressure",
+            "Sore throat",
+            "Teeth missing",
+            "Tinnitus",
+            "Trouble swallowing"],
+        "Allergy / Immune" => [
+            "Congestion",
+            "Difficulty healing",
+            "Frequent infections",
+            "Headache",
+            "Hives",
+            "Itching",
+            "Running nose",
+            "Sneezing",
+            "Watery eyes"],
+
+        "Cardiovascular" => [
+            "Chest pain / pressure at rest",
+            "Chest pain / pressure with excursion",
+            "Cold hands / feet",
+            "Dizziness",
+            "Exercise intolerance",
+            "Fainting",
+            "Feeling faint",
+            "Left arm pain",
+            "Light headed",
+            "Lower leg cramps",
+            "Muscle weakness",
+            "Palpitations",
+            "Shortness of breath",
+            "Sweating",
+            "Swelling"],
+
+    ],
+    [
+        "Respiratory" => [
+            "Cough – dry",
+            "Cough – wet",
+            "Coughing up blood",
+            "Pain with breathing",
+            "Productive cough",
+            "Shortness of breath at rest",
+            "Shortness of breath on excursion",
+            "Wheezing"],
+
+        "Gastrointestinal" => [
+            "Abdominal pain",
+            "Constipation",
+            "Coughing up blood",
+            "Diarrhea",
+            "Difficulty swallowing",
+            "Fecal incontinence",
+            "Heartburn",
+            "Loose stool",
+            "Nausea",
+            "Painful swallowing",
+            "Rectal pain",
+            "Stool – black tarry",
+            "Stool – bloody"],
+
+        "Genitourinary" => [
+            "Blood in urine",
+            "Discharge",
+            "Foley",
+            "Incontinence",
+            "Lesions",
+            "Sexual dysfunction",
+            "Tenderness",
+            "Urinary retention",
+            "Urination - frequent",
+            "Urination - painful",
+            "Urination wakes you up at night"],
+
+        "Musculoskeletal" => [
+            "Decreased range of motion",
+            "Fracture",
+            "Gait - unstable",
+            "Joint instability",
+            "Joint pain",
+            "Joint stiffness",
+            "Joint swelling",
+            "Muscle pain",
+            "Muscle weakness",
+            "Sprain"],
+
+        "Skin" => [
+            "Bruises",
+            "Color changes",
+            "Dry skin",
+            "Goosebumps",
+            "Itchy",
+            "IVDU marks",
+            "Lesions",
+            "Nodules",
+            "Rash",
+            "Scars",
+            "Swelling",
+            "Track marks",
+            "Ulcer",
+            "Wound"],
+    ],
+    [
+        "Neurological" => [
+            "Coordination problem",
+            "Dizziness",
+            "Double vision",
+            "Fainting",
+            "Head trauma",
+            "Headache",
+            "Imbalance",
+            "Muscle twitching",
+            "Numbness",
+            "Problems walking",
+            "Restlessness",
+            "Seizures",
+            "Speech disturbance",
+            "TBI",
+            "Tingling",
+            "Tinnitus",
+            "Tremor",
+            "Vertigo",
+            "Weakness"],
+
+        "Endocrine" => [
+            "Change in hair growth",
+            "Cold intolerance",
+            "Diabetes",
+            "Excessive hunger",
+            "Excessive thirst",
+            "Excessive urination",
+            "Exhausted",
+            "Goiter",
+            "Heat intolerance",
+            "Hot and cold flashes",
+            "Sleeplessness",
+            "Weight gain",
+            "Weight loss"],
+
+        "Lymphatic" => [
+            "Anemia",
+            "Bleeding tendency",
+            "Bruises",
+            "Lymph node pain enlargement",
+            "Pain",
+            "Swelling",
+            "Transfusions"],
+    ]
+];
+
+// only for ros - since ros edit markup is loaded via AJAX GET from the UI
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'ROS', $sessionKey, true);
+
+$contentData = $parsed = false;
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $parsed = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "declaration" => false,
+        "common" => [],
+        "comments" => "",
+    ];
+}
+
+for ($i = 0; $i < count($fields); $i++) {
+    foreach($fields[$i] as $head => $values) {
+        for($k = 0; $k < count($values); $k++) {
+            $fName = $head . '_' . sanitize_field_name($values[$k]);
+            if(!isset($contentData["common"][$fName])) $contentData["common"][$fName] = null;
+        }
+    }
+}
+?>
+<hr class="hide-outside-popup mt-3 mb-0">
+<div class="p-3 mcp-theme-1">
+    <div {{!!$segment ? 'visit-moe' : 'moe'}} close-on-save close-on-cancel class="d-block">
+        <form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1"
+                {{!$segment ? 'hook=onHxPopupClosure' : ''}}>
+            @if(!!@$segment)
+                <input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
+            @endif
+            <input type="hidden" name="uid" value="<?= $point->uid ?>">
+            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+            <input type="hidden" name="data" value='{!! json_encode($contentData) !!}'>
+
+            <div id="edit-ros-container">
+                <label class="d-flex align-items-center mb-3">
+                    <input type="checkbox" class="my-0 mr-2" v-model="declaration">
+                    <span>Except for the systems documented in the HPI or detailed below, all other systems were reviewed and negative.</span>
+                </label>
+                <div class="d-flex align-items-start flex-wrap custom-items-container">
+                    @for ($i = 0; $i < count($fields); $i++)
+                        <div class="w-33">
+                            @foreach($fields[$i] as $head => $values)
+                                <div class="font-weight-bold mb-2">{{ $head }}</div>
+                                <div class="d-flex flex-nowrap align-items-center mb-1">
+                                    <span class="rspace"><i class="fa fa-plus-circle text-success on-hover-opaque"></i></span>
+                                    <span class="rspace ros-minus-all c-pointer" data-category="{{$head}}"><i class="fa fa-minus-circle text-danger on-hover-opaque"></i></span>
+                                </div>
+                                <div class="mb-3 ros-category" data-category="{{$head}}">
+                                    @for($k = 0; $k < count($values); $k++)
+                                        <?php $fName = $head . '_' . sanitize_field_name($values[$k]); ?>
+                                        <div class="d-flex align-items-stretch mb-1">
+                                            <div class="d-inline-flex flex-nowrap align-items-center">
+                                                <span class="rspace">
+                                                    <input type="radio" name="{{ $fName }}" class="m-0 c-pointer"
+                                                           v-model="common['{{$fName}}']" value="+">
+                                                </span>
+                                                <span class="rspace">
+                                                    <input type="radio" name="{{ $fName }}" class="m-0 c-pointer"
+                                                           v-model="common['{{$fName}}']" value="-">
+                                                </span>
+                                            </div>
+                                            <div class="ml-2">
+                                                <div>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
+                                                    <div moe relative no-mask v-show="common['{{$fName}}']" >
+                                                        <a href="#" start show>
+                                                            <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
+                                                        </a>
+                                                        <div url="/nop" right>
+                                                            <div class="mb-2">
+                                                                <textarea class="form-control form-control-sm ns-custom-comment min-width-200px"
+                                                                          v-model="common['{{$fName}}__comments']"></textarea>
+                                                            </div>
+                                                            <div class="">
+                                                                <button type="button" class="btn btn-sm btn-primary" cancel>Close
+                                                                </button>
+                                                            </div>
+                                                        </div>
+                                                    </div>
+                                                    <a href="#" v-show="common['{{$fName}}']" v-on:click.prevent="clearValue('{{$fName}}')">
+                                                        <i class="text-danger on-hover-opaque fa fa-trash-alt ml-1"></i>
+                                                    </a>
+                                                </div>
+                                                <span v-show="common['{{$fName}}'] && common['{{$fName}}__comments']"
+                                                      v-html="common['{{$fName}}__comments']"
+                                                      class="text-sm text-secondary">
+                                                </span>
+                                            </div>
+                                        </div>
+                                    @endfor
+                                </div>
+                            @endforeach
+                        </div>
+                    @endfor
+                </div>
+                <hr class="m-neg-4 mt-0">
+                <div class="mb-2">
+                    <textarea class="form-control form-control-sm" v-model="comments">{!! $parsed && @$parsed->content ? @$parsed->content : '' !!}</textarea>
+                </div>
+                <div class="mt-3">
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                        <i class="fa fa-check"></i>
+                        Saved
+                    </span>
+                    </div>
+                </div>
+            </div>
+
+        </form>
+    </div>
+</div>
+<script>
+    (function() {
+
+        const debounce = (func, wait) => {
+            let timeout;
+            return function executedFunction(...args) {
+                const later = () => {
+                    clearTimeout(timeout);
+                    func(...args);
+                };
+                clearTimeout(timeout);
+                timeout = setTimeout(later, wait);
+            };
+        };
+
+        let debouncedROSSaver = debounce(function(_trigger) {
+            $(_trigger).closest('.stag-popup').find('.autosave-indicator').removeClass('show');
+            $(_trigger).closest('.stag-popup').find('.autosave-indicator.saving').addClass('show');
+            saveVisitForm(_trigger, true, false, () => {
+                $(_trigger).closest('.stag-popup').find('.autosave-indicator').removeClass('show');
+                $(_trigger).closest('.stag-popup').find('.autosave-indicator.saved').addClass('show');
+            });
+        }, 500);
+
+        function initROS() {
+
+            let model = <?= $contentData ? json_encode($contentData) : '{}' ?>;
+
+            model.itemKey = 'pmhx';
+
+            new Vue({
+                el: '#edit-ros-container',
+                delimiters: ["@{{","}}"],
+                data: model,
+                mounted: function() {
+                    $('#edit-ros-container [moe][initialized]').removeAttr('initialized');
+                    initMoes();
+
+                    // custom buttons on title bar
+                    $('.button-container').remove();
+                    let buttonContainer = $('<div/>').addClass('button-container ml-4 mr-auto');
+                    let titleElem = $('#edit-ros-container').closest('.stag-popup').find('.stag-popup-title>span');
+                    titleElem.next().removeClass('ml-auto');
+                    titleElem.parent().addClass('align-items-center');
+
+                    // add button for "Edit Mode"
+                    $('<div class="d-inline-flex align-self-stretch align-items-center">' +
+                        '<span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>' +
+                        '<span class="autosave-indicator saved text-sm text-secondary">' +
+                        '<i class="fa fa-check"></i>' +
+                        ' Saved' +
+                        '</span>' +
+                        '</div>').appendTo(buttonContainer);
+
+                    buttonContainer.insertAfter(titleElem);
+
+                    $('#edit-ros-container')
+                        .off('click.ros-minus-all')
+                        .on('click.ros-minus-all', '.ros-minus-all[data-category]', function() {
+                            let category = $(this).attr('data-category');
+                            $('.ros-category[data-category="' + category + '"]').find('input[type="radio"][value="-"]').click();
+                            return false;
+                        });
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            let parent = $('#edit-ros-container').closest('form');
+                            parent.find('[name="data"]').val(JSON.stringify(this.$data));
+                            debouncedROSSaver($('#edit-ros-container')[0]);
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+                    clearValue: function(_key) {
+                        this.common[_key] = null;
+                        Vue.nextTick(function() {
+                            $('#edit-ros-container').find('textarea').first().trigger('input');
+                        });
+                    },
+                    saveROS: function() {
+                        saveVisitForm($('#edit-ros-container')[0], false, true);
+                    }
+                }
+            });
+
+        }
+
+        // window.segmentInitializers.<?= !!@$segment ? $segment->segmentTemplate->internal_name : $segmentInternalName ?> = initROS;
+
+        addMCInitializer('init-ros-{{$note->id}}', initROS, '#edit-ros-container');
+
+    }).call(window);
+</script>

+ 261 - 0
resources/views/app/patient/segment-templates/omega_ros/log.blade.php

@@ -0,0 +1,261 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+$fields = [
+    [
+        "Constitutional" => [
+            "Fatigue",
+            "Fever",
+            "Weight gain",
+            "Weight loss"],
+
+        "Eyes" => [
+            "Blurry vision",
+            "Double vision",
+            "Dry eyes",
+            "Floaters",
+            "Halos",
+            "Headache",
+            "Irritation",
+            "Loss of peripheral vision",
+            "Pain",
+            "Pinpoint pupils",
+            "Teary",
+            "Visual changes"],
+
+        "ENMT" => [
+            "Altered sense of smell",
+            "Dental caries",
+            "Dentures",
+            "Dizziness",
+            "Dry mouth",
+            "Ear pain/pressure",
+            "Hearing loss",
+            "Mouth pain",
+            "Nasal congestion",
+            "Neck pain/stiffness",
+            "Post nasal drainage",
+            "Sinus pain / pressure",
+            "Sore throat",
+            "Teeth missing",
+            "Tinnitus",
+            "Trouble swallowing"],
+        "Allergy / Immune" => [
+            "Congestion",
+            "Difficulty healing",
+            "Frequent infections",
+            "Headache",
+            "Hives",
+            "Itching",
+            "Running nose",
+            "Sneezing",
+            "Watery eyes"]
+    ],
+    [
+        "Cardiovascular" => [
+            "Chest pain / pressure at rest",
+            "Chest pain / pressure with excursion",
+            "Cold hands / feet",
+            "Dizziness",
+            "Exercise intolerance",
+            "Fainting",
+            "Feeling faint",
+            "Left arm pain",
+            "Light headed",
+            "Lower leg cramps",
+            "Muscle weakness",
+            "Palpitations",
+            "Shortness of breath",
+            "Sweating",
+            "Swelling"],
+
+        "Respiratory" => [
+            "Cough – dry",
+            "Cough – wet",
+            "Coughing up blood",
+            "Pain with breathing",
+            "Productive cough",
+            "Shortness of breath at rest",
+            "Shortness of breath on excursion",
+            "Wheezing"],
+
+        "Gastrointestinal" => [
+            "Abdominal pain",
+            "Constipation",
+            "Coughing up blood",
+            "Diarrhea",
+            "Difficulty swallowing",
+            "Fecal incontinence",
+            "Heartburn",
+            "Loose stool",
+            "Nausea",
+            "Painful swallowing",
+            "Rectal pain",
+            "Stool – black tarry",
+            "Stool – bloody"],
+    ],
+    [
+        "Genitourinary" => [
+            "Blood in urine",
+            "Discharge",
+            "Foley",
+            "Incontinence",
+            "Lesions",
+            "Sexual dysfunction",
+            "Tenderness",
+            "Urinary retention",
+            "Urination - frequent",
+            "Urination - painful",
+            "Urination wakes you up at night"],
+
+        "Musculoskeletal" => [
+            "Decreased range of motion",
+            "Fracture",
+            "Gait - unstable",
+            "Joint instability",
+            "Joint pain",
+            "Joint stiffness",
+            "Joint swelling",
+            "Muscle pain",
+            "Muscle weakness",
+            "Sprain"],
+
+        "Skin" => [
+            "Bruises",
+            "Color changes",
+            "Dry skin",
+            "Goosebumps",
+            "Itchy",
+            "IVDU marks",
+            "Lesions",
+            "Nodules",
+            "Rash",
+            "Scars",
+            "Swelling",
+            "Track marks",
+            "Ulcer",
+            "Wound"],
+
+    ],
+    [
+        "Neurological" => [
+            "Coordination problem",
+            "Dizziness",
+            "Double vision",
+            "Fainting",
+            "Head trauma",
+            "Headache",
+            "Imbalance",
+            "Muscle twitching",
+            "Numbness",
+            "Problems walking",
+            "Restlessness",
+            "Seizures",
+            "Speech disturbance",
+            "TBI",
+            "Tingling",
+            "Tinnitus",
+            "Tremor",
+            "Vertigo",
+            "Weakness"],
+
+        "Endocrine" => [
+            "Change in hair growth",
+            "Cold intolerance",
+            "Diabetes",
+            "Excessive hunger",
+            "Excessive thirst",
+            "Excessive urination",
+            "Exhausted",
+            "Goiter",
+            "Heat intolerance",
+            "Hot and cold flashes",
+            "Sleeplessness",
+            "Weight gain",
+            "Weight loss"],
+
+        "Lymphatic" => [
+            "Anemia",
+            "Bleeding tendency",
+            "Bruises",
+            "Lymph node pain enlargement",
+            "Pain",
+            "Swelling",
+            "Transfusions"],
+    ]
+];
+
+$point = Point::getOnlyTopLevelPointOfCategory($note, 'ROS', true);
+
+if($point) {
+    ?> <div class="popup-content-container px-3"> <?php
+    foreach ($point->childReviews as $childReview) {
+        $contentData = $parsed = false;
+        if ($childReview->data) {
+            $childReview->data = json_decode($childReview->data, true);
+            $contentData = $parsed = $childReview->data;
+
+            ?>
+            <div class="mb-1 font-weight-bold">{{$childReview->creatorPro->displayName()}} - {{friendly_date($childReview->note->effective_dateest)}}</div>
+            <div class="pl-3 bg-light border p-3 mb-3">
+            <?php
+
+            if(!!@$contentData['declaration']) {
+                echo '<div class="mb-2">';
+                echo '<i class="fa fa-check"></i>&nbsp;';
+                echo "Except for the systems documented in the HPI or detailed below, all other systems were reviewed and negative.";
+                echo '</div>';
+            }
+
+            // group by "head" and separate fields with values
+            $grouped = [];
+            for ($i = 0; $i < count($fields); $i++) {
+                foreach ($fields[$i] as $head => $values) {
+                    for ($k = 0; $k < count($values); $k++) {
+                        $fName = $head . '_' . sanitize_field_name($values[$k]);
+                        if (@$contentData['common'][$fName]) {
+                            if(!isset($grouped[$head])) $grouped[$head] = [];
+                            $grouped[$head][] = [
+                                "label" => $values[$k],
+                                "value" => @$contentData['common'][$fName],
+                                "comments" => @$contentData['common'][$fName . '__comments']
+                            ];
+                        }
+                    }
+                }
+            }
+
+            $display = [];
+            foreach($grouped as $head => $items) {
+                $combined = [];
+                for ($i = 0; $i < count($items); $i++) {
+                    $combined[] = $items[$i]['label'] . ' (' . $items[$i]['value'] . ')' .
+                        (@$items[$i]['comments'] ? '<span class="text-secondary font-italic text-sm">&nbsp;' . @$items[$i]['comments'] . '</span>' : '');
+                }
+                $display[$head] = implode(' • ', $combined);
+            }
+
+            foreach($display as $head => $line) {
+            ?>
+            <div class="mb-2">
+                <span class="font-weight-bold mr-1">{{$head}}:</span>
+                <span class="">{!! $line !!}</span>
+            </div>
+            <?php
+            }
+            if(isset($contentData['comments']) && !empty(trim($contentData['comments']))) {
+            ?>
+                <div class="mt-2 mb-1">
+                    <b>Comments: </b><?= $contentData['comments'] ?>
+                </div>
+            <?php
+            }
+        }
+    }
+    ?> </div> <?php
+}

+ 252 - 1
resources/views/app/patient/segment-templates/omega_ros/summary.blade.php

@@ -1 +1,252 @@
-<h1>omega_ros</h1>
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+$fields = [
+    [
+        "Constitutional" => [
+            "Fatigue",
+            "Fever",
+            "Weight gain",
+            "Weight loss"],
+
+        "Eyes" => [
+            "Blurry vision",
+            "Double vision",
+            "Dry eyes",
+            "Floaters",
+            "Halos",
+            "Headache",
+            "Irritation",
+            "Loss of peripheral vision",
+            "Pain",
+            "Pinpoint pupils",
+            "Teary",
+            "Visual changes"],
+
+        "ENMT" => [
+            "Altered sense of smell",
+            "Dental caries",
+            "Dentures",
+            "Dizziness",
+            "Dry mouth",
+            "Ear pain/pressure",
+            "Hearing loss",
+            "Mouth pain",
+            "Nasal congestion",
+            "Neck pain/stiffness",
+            "Post nasal drainage",
+            "Sinus pain / pressure",
+            "Sore throat",
+            "Teeth missing",
+            "Tinnitus",
+            "Trouble swallowing"],
+        "Allergy / Immune" => [
+            "Congestion",
+            "Difficulty healing",
+            "Frequent infections",
+            "Headache",
+            "Hives",
+            "Itching",
+            "Running nose",
+            "Sneezing",
+            "Watery eyes"]
+    ],
+    [
+        "Cardiovascular" => [
+            "Chest pain / pressure at rest",
+            "Chest pain / pressure with excursion",
+            "Cold hands / feet",
+            "Dizziness",
+            "Exercise intolerance",
+            "Fainting",
+            "Feeling faint",
+            "Left arm pain",
+            "Light headed",
+            "Lower leg cramps",
+            "Muscle weakness",
+            "Palpitations",
+            "Shortness of breath",
+            "Sweating",
+            "Swelling"],
+
+        "Respiratory" => [
+            "Cough – dry",
+            "Cough – wet",
+            "Coughing up blood",
+            "Pain with breathing",
+            "Productive cough",
+            "Shortness of breath at rest",
+            "Shortness of breath on excursion",
+            "Wheezing"],
+
+        "Gastrointestinal" => [
+            "Abdominal pain",
+            "Constipation",
+            "Coughing up blood",
+            "Diarrhea",
+            "Difficulty swallowing",
+            "Fecal incontinence",
+            "Heartburn",
+            "Loose stool",
+            "Nausea",
+            "Painful swallowing",
+            "Rectal pain",
+            "Stool – black tarry",
+            "Stool – bloody"],
+    ],
+    [
+        "Genitourinary" => [
+            "Blood in urine",
+            "Discharge",
+            "Foley",
+            "Incontinence",
+            "Lesions",
+            "Sexual dysfunction",
+            "Tenderness",
+            "Urinary retention",
+            "Urination - frequent",
+            "Urination - painful",
+            "Urination wakes you up at night"],
+
+        "Musculoskeletal" => [
+            "Decreased range of motion",
+            "Fracture",
+            "Gait - unstable",
+            "Joint instability",
+            "Joint pain",
+            "Joint stiffness",
+            "Joint swelling",
+            "Muscle pain",
+            "Muscle weakness",
+            "Sprain"],
+
+        "Skin" => [
+            "Bruises",
+            "Color changes",
+            "Dry skin",
+            "Goosebumps",
+            "Itchy",
+            "IVDU marks",
+            "Lesions",
+            "Nodules",
+            "Rash",
+            "Scars",
+            "Swelling",
+            "Track marks",
+            "Ulcer",
+            "Wound"],
+
+    ],
+    [
+        "Neurological" => [
+            "Coordination problem",
+            "Dizziness",
+            "Double vision",
+            "Fainting",
+            "Head trauma",
+            "Headache",
+            "Imbalance",
+            "Muscle twitching",
+            "Numbness",
+            "Problems walking",
+            "Restlessness",
+            "Seizures",
+            "Speech disturbance",
+            "TBI",
+            "Tingling",
+            "Tinnitus",
+            "Tremor",
+            "Vertigo",
+            "Weakness"],
+
+        "Endocrine" => [
+            "Change in hair growth",
+            "Cold intolerance",
+            "Diabetes",
+            "Excessive hunger",
+            "Excessive thirst",
+            "Excessive urination",
+            "Exhausted",
+            "Goiter",
+            "Heat intolerance",
+            "Hot and cold flashes",
+            "Sleeplessness",
+            "Weight gain",
+            "Weight loss"],
+
+        "Lymphatic" => [
+            "Anemia",
+            "Bleeding tendency",
+            "Bruises",
+            "Lymph node pain enlargement",
+            "Pain",
+            "Swelling",
+            "Transfusions"],
+    ]
+];
+
+$point = Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'ROS', $sessionKey, true);
+
+if ($point->lastChildReview && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $point->lastChildReview->data;
+
+    if(!!@$contentData['declaration']) {
+        echo '<div class="mb-2">';
+        echo '<i class="fa fa-check"></i>&nbsp;';
+        echo "Except for the systems documented in the HPI or detailed below, all other systems were reviewed and negative.";
+        echo '</div>';
+    }
+
+    // group by "head" and separate fields with values
+    $grouped = [];
+    for ($i = 0; $i < count($fields); $i++) {
+        foreach ($fields[$i] as $head => $values) {
+            for ($k = 0; $k < count($values); $k++) {
+                $fName = $head . '_' . sanitize_field_name($values[$k]);
+                if (@$contentData['common'][$fName]) {
+                    if(!isset($grouped[$head])) $grouped[$head] = [];
+                    $grouped[$head][] = [
+                        "label" => $values[$k],
+                        "value" => @$contentData['common'][$fName],
+                        "comments" => @$contentData['common'][$fName . '__comments']
+                    ];
+                }
+            }
+        }
+    }
+
+    $display = [];
+    foreach($grouped as $head => $items) {
+        $combined = [];
+        for ($i = 0; $i < count($items); $i++) {
+            $combined[] = $items[$i]['label'] . ' (' . $items[$i]['value'] . ')' .
+                (@$items[$i]['comments'] ? '<span class="text-secondary font-italic text-sm">&nbsp;' . @$items[$i]['comments'] . '</span>' : '');
+        }
+        $display[$head] = implode(' • ', $combined);
+    }
+
+    foreach($display as $head => $line) {
+        ?>
+        <div class="mb-2">
+            <span class="font-weight-bold mr-1">{{$head}}:</span>
+            <span class="">{!! $line !!}</span>
+        </div>
+        <?php
+    }
+    ?>
+    @if(isset($contentData['comments']) && !empty(trim($contentData['comments'])))
+        <div class="mt-2 mb-1">
+            <b>Comments: </b><?= $contentData['comments'] ?>
+        </div>
+    @endif
+    <?php
+} else {
+    echo '<div class="text-secondary">-</div>';
+}
+?>