ソースを参照

Merge branch 'master' of rav.triplestart.com:jmudaka/stagfe2 into dev

= 3 年 前
コミット
eaaef60959
21 ファイル変更1019 行追加76 行削除
  1. 1 1
      config/app.php
  2. 22 0
      public/css/style.css
  3. 0 3
      resources/views/app/patient/note/dashboard.blade.php
  4. 5 1
      resources/views/app/patient/note/note-segment-list-slim.blade.php
  5. 4 0
      resources/views/app/patient/note/rm-setup.blade.php
  6. 74 0
      resources/views/app/patient/note/segment-always-open.blade.php
  7. 56 41
      resources/views/app/patient/partials/client_bp_weight_phone_number_status.blade.php
  8. 3 0
      resources/views/app/patient/partials/rm-setup.blade.php
  9. 0 2
      resources/views/app/patient/rm-setup.blade.php
  10. 5 5
      resources/views/app/patient/segment-templates/biopsychosocial_assessment/edit.blade.php
  11. 21 22
      resources/views/app/patient/segment-templates/current_mental-status/edit.blade.php
  12. 4 0
      resources/views/app/patient/segment-templates/medication_comments/edit.blade.php
  13. 3 0
      resources/views/app/patient/segment-templates/medication_comments/summary.blade.php
  14. 1 1
      resources/views/app/patient/segment-templates/omega_cc/edit.blade.php
  15. 4 0
      resources/views/app/patient/segment-templates/physical_exam/edit.blade.php
  16. 3 0
      resources/views/app/patient/segment-templates/physical_exam/summary.blade.php
  17. 279 0
      resources/views/app/patient/segment-templates/psych_risk_assessment/edit.blade.php
  18. 49 0
      resources/views/app/patient/segment-templates/psych_risk_assessment/log.blade.php
  19. 57 0
      resources/views/app/patient/segment-templates/psych_risk_assessment/summary.blade.php
  20. 327 0
      resources/views/app/patient/segment-templates/psych_vitals/edit.blade.php
  21. 101 0
      resources/views/app/patient/segment-templates/psych_vitals/summary.blade.php

+ 1 - 1
config/app.php

@@ -65,7 +65,7 @@ return [
 
     'hrm2_url' => env('HRM2_URL'),
 
-    'asset_version' => 80,
+    'asset_version' => 81,
 
     'temp_dir' => env('TEMP_DIR'),
 

+ 22 - 0
public/css/style.css

@@ -436,6 +436,9 @@ body>nav.navbar {
 .mcp-theme-1 .min-width-140px {
     min-width: 140px !important;
 }
+.mcp-theme-1 .max-width-140px {
+    max-width: 140px !important;
+}
 .mcp-theme-1 .min-width-200px {
     min-width: 200px !important;
 }
@@ -3496,3 +3499,22 @@ table.v-top th {
     text-overflow: ellipsis;
     display: inline-block;
 }
+.note_template_psych_visit .edit-container .ql-editor[contenteditable] {
+    min-height: 80px;
+    background: #fff;
+}
+.note_template_psych_visit .edit-container .ql-toolbar {
+    height: 0;
+    overflow: hidden;
+    padding: 0;
+    border-bottom: 0;
+}
+/*.note_template_psych_visit .edit-container [visit-moe]>form>div:last-child {
+    margin: 0 !important;
+}*/
+.note_template_psych_visit .edit-container [visit-moe]>form>div:last-child>.btn.btn-primary {
+    display: none;
+}
+.note_template_psych_visit .edit-container [visit-moe]>form>div:last-child>.d-inline-flex {
+    display: flex !important;
+}

+ 0 - 3
resources/views/app/patient/note/dashboard.blade.php

@@ -955,9 +955,6 @@ use App\Models\Handout;
                                 <p class="font-weight-bold text-secondary m-0 font-size-14">Remote Monitoring</p>
                             </div>
                             @include('app.patient.note.rm-setup')
-                            <div class="p-2">
-                                @include('app.patient.partials.client_bp_weight_phone_number_status')
-                            </div>
                         </div>
                        
                     </div>

+ 5 - 1
resources/views/app/patient/note/note-segment-list-slim.blade.php

@@ -30,7 +30,11 @@
                 @if($suggestionModeOn)
                     @include('app.patient.note.segment.suggestions_and_updates')
                 @else
-                    @include('app.patient.note.segment-slim')
+                    @if($note->visitTemplate->segments_always_open && !$note->is_signed_by_hcp)
+                        @include('app.patient.note.segment-always-open')
+                    @else
+                        @include('app.patient.note.segment-slim')
+                    @endif
                 @endif
             </div>
            

+ 4 - 0
resources/views/app/patient/note/rm-setup.blade.php

@@ -420,6 +420,10 @@
                 </table>
             </div>
         @endif
+        <div class="border-top mt-2 pt-2">
+            @include('app.patient.partials.client_bp_weight_phone_number_status')
+        </div>
+        
     </div>
     <div class="col-6 border-left">
         <?php

+ 74 - 0
resources/views/app/patient/note/segment-always-open.blade.php

@@ -0,0 +1,74 @@
+<?php
+$iName = $segment->segmentTemplate->internal_name;
+$wizardPowered = [
+    'omega_medications',
+    'omega_problems',
+    'omega_allergies',
+    'omega_ros'
+];
+?>
+
+<div class="border-bottom note-section visit-segment outline-0 {{$note->is_signed_by_hcp ? 'events-none' : (in_array($iName, $wizardPowered) !== FALSE ? 'edit-trigger' : 'edit')}}"
+     data-segment-uid="{{ $segment->uid }}"
+     data-segment-template-uid="{{ $segment->segmentTemplate->uid }}"
+     data-segment-template-name="{{ $segment->segmentTemplate->internal_name }}">
+
+    <div class="bg-white text-dark px-2 py-1">
+        <div class="d-flex align-items-baseline">
+
+            @if(!!$segment->display_title)
+                <div class="text-dark font-weight-bold font-size-13 mr-2 mt-2">
+                    {{$segment->display_title}}:
+                </div>
+            @endif
+
+            @if(!$note->is_signed_by_hcp)
+                @if(!$note->visitTemplate->segments_always_open)
+                    <a class="edit-trigger d-none if-edit c-pointer ml-3">
+                        <i class="fas fa-caret-up font-size-16"></i>
+                    </a>
+                @endif
+
+            <!-- refresh -->
+                <a class="ml-3 font-weight-normal refresh-segment c-pointer {{$iName === 'medrisk_vigilence' ? 'on-hover-only' : ''}} screen-only"
+                   data-segment-uid="{{$segment->uid}}"
+                   title="Update with latest patient data">
+                    <i class="fa fa-sync on-hover-opaque"></i>
+                </a>
+
+            @endif
+
+            {{-- if segment has log feature, link --}}
+            @if($pro->pro_type === 'ADMIN' && file_exists(resource_path("views/app/patient/segment-templates/{$segment->segmentTemplate->internal_name}/log.blade.php")))
+                <a native="" target="_blank"
+                   class="c-pointer ml-2 text-decoration-none"
+                   open-in-stag-popup=""
+                   title="{{$segment->display_title}} - Change Log"
+                   popup-style="medium"
+                   href="/note-segment-view/{{$patient->uid}}/{{$note->uid}}/{{$segment->uid}}/<?= $segment->segmentTemplate->internal_name ?>/log">
+                    <i class="fas fa-history on-hover-opaque"></i>
+                </a>
+            @endif
+
+        </div>
+
+        <div class="py-1">
+            @if(in_array($iName, $wizardPowered) !== FALSE)
+                <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
+                        {!! $segment->summary_html !!}
+                    @endif
+                </div>
+            @else
+                <div class="{{!$note->visitTemplate->segments_always_open ? 'd-none if-edit' : ''}} edit-container">
+                    {!! $segment->edit_html !!}
+                </div>
+            @endif
+
+        </div>
+
+    </div>
+
+</div>

+ 56 - 41
resources/views/app/patient/partials/client_bp_weight_phone_number_status.blade.php

@@ -1,44 +1,59 @@
-<div class="mb-1">
-    <div class="border-bottom mb-2">
-        <div>
-            Please ask the client to save the following numbers for receiving measurement SMS messages.
+<div class="">
+    <div class="mb-1">
+        <span class="mb-0 mr-2"><b>Please ask the client to save the following numbers for receiving measurement SMS messages.</b>
+        <div moe>
+            <a start show><i class="fa fa-edit"></i></a>
+            <form url="/api/client/updateClientBpWeightPhoneNumberStatus" class="mcp-theme-1">
+                <input type="hidden" name="uid" value="{{$patient->uid}}">
+                <div class="mb-2 checkbox">
+                    <input type="checkbox" name="hasClientSavedBpPhoneNumber">
+                    <label class="mb-1 text-secondary text-sm">Has client saved bp phone number?</label>
+                </div>
+                <div class="mb-2">
+                    <label class="mb-1 text-secondary text-sm">Saved BP phone number</label>
+                    <input type="text" name="savedBpPhoneNumber" class="form-control form-control-sm" value="{{config('app.bpSmsNumber')}}">
+                </div>
+                <div class="mb-2 checkbox">
+                    <input type="checkbox" name="hasClientSavedWeightPhoneNumber">
+                    <label class="mb-1 text-secondary text-sm">Has client saved weight phone number?</label>
+                </div>
+                <div class="mb-2">
+                    <label class="mb-1 text-secondary text-sm">Saved weight phone number</label>
+                    <input type="text" name="savedWeightPhoneNumber" class="form-control form-control-sm" value="{{config('app.weightSmsNumber')}}">
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
         </div>
-        <div>
-            Cardio1st BP sms number: {{config('app.bpSmsNumber')}}   
-        </div>
-        <div>
-            Cardio1st Weight sms number: {{config('app.weightSmsNumber')}}   
-        </div>
-    </div>
-    
-    <div>Has client saved BP phone number: <b>{{ $patient->clientBpWeightPhoneNumberStatus && $patient->clientBpWeightPhoneNumberStatus->has_client_saved_bp_phone_number ? 'Yes': 'No' }}</b></div>
-    <div>Saved BP Phone number: <b>{{ $patient->clientBpWeightPhoneNumberStatus ?  $patient->clientBpWeightPhoneNumberStatus->saved_bp_phone_number: '-'}}</b></div>
-    <div>Has client saved Weight phone number: <b>{{ $patient->clientBpWeightPhoneNumberStatus && $patient->clientBpWeightPhoneNumberStatus->has_client_saved_weight_phone_number ? 'Yes': 'No' }}</b></div>
-    <div>Saved Weight Phone number: <b>{{ $patient->clientBpWeightPhoneNumberStatus ? $patient->clientBpWeightPhoneNumberStatus->saved_weight_phone_number : '-' }}</b></div>
-    <div moe>
-        <a start show><i class="fa fa-edit"></i></a>
-        <form url="/api/client/updateClientBpWeightPhoneNumberStatus" class="mcp-theme-1">
-            <input type="hidden" name="uid" value="{{$patient->uid}}">
-            <div class="mb-2 checkbox">
-                <input type="checkbox" name="hasClientSavedBpPhoneNumber">
-                <label class="mb-1 text-secondary text-sm">Has client saved bp phone number?</label>
-            </div>
-            <div class="mb-2">
-                <label class="mb-1 text-secondary text-sm">Saved BP phone number</label>
-                <input type="text" name="savedBpPhoneNumber" class="form-control form-control-sm" value="{{config('app.bpSmsNumber')}}">
-            </div>
-            <div class="mb-2 checkbox">
-                <input type="checkbox" name="hasClientSavedWeightPhoneNumber">
-                <label class="mb-1 text-secondary text-sm">Has client saved weight phone number?</label>
-            </div>
-            <div class="mb-2">
-                <label class="mb-1 text-secondary text-sm">Saved weight phone number</label>
-                <input type="text" name="savedWeightPhoneNumber" class="form-control form-control-sm" value="{{config('app.weightSmsNumber')}}">
-            </div>
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
-                <button cancel class="btn btn-sm btn-default border">Cancel</button>
-            </div>
-        </form>
+        </span>
+        
     </div>
+    <table class="table table-sm table-striped table-bordered">
+        <tr>
+            <td>Cardio1st BP sms number:</td>
+            <td>{{config('app.bpSmsNumber')}}</td>
+        </tr>
+        <tr>
+            <td>Cardio1st Weight sms number:</td>
+            <td>{{config('app.weightSmsNumber')}}</td>
+        </tr>
+        <tr>
+            <td>Has client saved BP phone number:</td>
+            <td>{{ $patient->clientBpWeightPhoneNumberStatus && $patient->clientBpWeightPhoneNumberStatus->has_client_saved_bp_phone_number ? 'Yes': 'No' }}</td>
+        </tr>
+        <tr>
+            <td>Saved BP Phone number:</td>
+            <td>{{ $patient->clientBpWeightPhoneNumberStatus ?  $patient->clientBpWeightPhoneNumberStatus->saved_bp_phone_number: '-'}}</td>
+        </tr>
+        <tr>
+            <td>Has client saved Weight phone number:</td>
+            <td>{{ $patient->clientBpWeightPhoneNumberStatus && $patient->clientBpWeightPhoneNumberStatus->has_client_saved_weight_phone_number ? 'Yes': 'No' }}</td>
+        </tr>
+        <tr>
+            <td>Saved Weight Phone number:</td>
+            <td>{{ $patient->clientBpWeightPhoneNumberStatus ? $patient->clientBpWeightPhoneNumberStatus->saved_weight_phone_number : '-' }}</td>
+        </tr>
+    </table>
 </div>

+ 3 - 0
resources/views/app/patient/partials/rm-setup.blade.php

@@ -256,6 +256,9 @@
                 </div>
             </div>
         @endif
+        <div class="border-top mt-2 pt-2">
+            @include('app.patient.partials.client_bp_weight_phone_number_status')
+        </div>
     </div>
     <div class="col-6 border-left">
         <?php

+ 0 - 2
resources/views/app/patient/rm-setup.blade.php

@@ -5,6 +5,4 @@
     <h4 class="font-weight-bold mb-3" id="rm-setup">RM Setup</h4>
 
     @include('app.patient.partials.rm-setup')
-
-    @include('app.patient.partials.client_bp_weight_phone_number_status')
 @endsection

+ 5 - 5
resources/views/app/patient/segment-templates/biopsychosocial_assessment/edit.blade.php

@@ -210,7 +210,7 @@ $labels = [
 	'other_important_information' => 'Other Important Information', 
 ];
 ?>
-<div class="p-3">
+<div class="">
 	@foreach($contents as $field => $content)
 		<div visit-moe close-on-save close-on-cancel class="d-block" id="biopsychosocial_assessment-{{$field}}-{{$note->id}}">
 			<form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1 frm-upsert-review-psych-intake-current-mental-status">
@@ -219,12 +219,12 @@ $labels = [
 				<input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
 				<input type="hidden" name="data" value="{{json_encode($content)}}">
 
-				<div class="row align-items-center mb-1">
-					<div class="col-md-4">
+				<div class="row align-items-center mb-1 mx-0">
+					<div class="col-md-4 pl-0">
 						<label class="control-label mb-0" style="font-size:13px;">{{$labels[$field]}}:</label>
 					</div>
-					<div class="col-md-8">
-						<input type="text" name="value" class="form-control input-sm" placeholder="{{$placeholders[$field]}}" value="{{$content['value']}}" data-name="value">
+					<div class="col-md-8 pr-0">
+						<input type="text" name="value" class="form-control form-control-sm" placeholder="{{$placeholders[$field]}}" value="{{$content['value']}}" data-name="value">
 					</div>
 				</div>
 			</form> 

+ 21 - 22
resources/views/app/patient/segment-templates/current_mental-status/edit.blade.php

@@ -190,7 +190,7 @@ $keyToLabelMap = [
 	'insight' => 'Insight',
 	'judgment' => 'Judgment/Impulse Control',
 	'memory' => 'Memory',
-	'attentionConcentration' => 'Attention/Concentration',
+	'attentionConcentration' => 'Attention / Concentration',
 	'thoughtProcess' => 'Thought Process',
 	'thoughtContent' => 'Thought Content',
 	'perception' => 'Perception',
@@ -247,7 +247,7 @@ if ($point->lastChildReview && $point->lastChildReview->data) {
 $submitFormUrl = "/api/visitPoint/upsertChildReview";
 ?>
 
-<div visit-moe close-on-save close-on-cancel class="d-block p-3" id="psych-intake-current-mental-status-{{$note->id}}">
+<div visit-moe close-on-save close-on-cancel class="d-block" id="psych-intake-current-mental-status-{{$note->id}}">
     <form id="pychIntakeForm" show url="{{ $submitFormUrl }}" class="mcp-theme-1 frm-upsert-review-typical-day-ls">
         <input type="hidden" name="uid" value="<?= $point->uid ?>">
         <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
@@ -255,7 +255,7 @@ $submitFormUrl = "/api/visitPoint/upsertChildReview";
         <input type="hidden" name="data" value="{{json_encode($contentData)}}">
 
         <div class="mb-2 d-flex align-items-center justify-content-between">
-			<p class="mb-0 font-weight-bold">Psych Intake Current Mental Status</p>
+			<p class="mb-0 font-weight-bold">&nbsp;</p>
 			<div>
 				<a class="mr-2 font-weight-bold c-pointer" all-normal><i class="fas fa-thumbs-up"></i> All Normal</a>
 				<a class="font-weight-bold c-pointer" all-not-assessed><i class="fas fa-times-circle"></i> All Not assessed</a>
@@ -263,43 +263,42 @@ $submitFormUrl = "/api/visitPoint/upsertChildReview";
 		</div>
 
         <div>
-            <div class="row">
+            <div class="row mx-0">
                 
-                <div class="col-md-6">
+                <div class="col-md-6 pl-0">
                     @foreach($keyToInputMap as  $field => $options)
                         @if(in_array($field, $displayColumns['left']))
-							<div class="row align-items-center mb-1">
-								<div class="col-md-4">
+							<div class="row align-items-center mb-1 mx-0">
+								<div class="col-md-4 pl-0">
 									<label class="control-label mb-0">{{$keyToLabelMap[$field]}}:</label>
 								</div>
-								<div class="col-md-8">
-									<input type="text" list="{{$field}}s" data-name="{{$field}}" name="{{$field}}" id="{{$field}}" class="form-control" value="{{ @$contentData[$field] }}">
-									<datalist id="{{$field}}s">
+								<div class="col-md-8 pr-0">
+									<input type="text" list="{{$field}}s" data-option-list data-name="{{$field}}" name="{{$field}}" id="{{$field}}" class="form-control form-control-sm" value="{{ @$contentData[$field] }}">
+									<div class="data-option-list">
 										@foreach($options as $option)
-											<option value="{{$option}}">{{$option}}</option>
+											<div>{{$option}}</div>
 										@endforeach
-									</datalist>
-									
+									</div>
 								</div>
 							</div>
                         @endif
                     @endforeach
                 </div>
                     
-                <div class="col-md-6">
+                <div class="col-md-6 px-0">
                     @foreach($keyToInputMap as  $field => $options)
                         @if(in_array($field, $displayColumns['right']))
-						<div class="row align-items-center mb-1">
-							<div class="col-md-4">
+						<div class="row align-items-center mb-1 mx-0">
+							<div class="col-md-4 pl-0">
 								<label class="control-label mb-0">{{$keyToLabelMap[$field]}}:</label>
 							</div>
-							<div class="col-md-8">
-								<input type="text" list="{{$field}}s" data-name="{{$field}}" name="{{$field}}" id="{{$field}}" class="form-control" value="{{ @$contentData[$field] }}">
-								<datalist id="{{$field}}s">
+							<div class="col-md-8 pr-0">
+								<input type="text" list="{{$field}}s" data-option-list data-name="{{$field}}" name="{{$field}}" id="{{$field}}" class="form-control form-control-sm" value="{{ @$contentData[$field] }}">
+								<div class="data-option-list">
 									@foreach($options as $option)
-                                        <option value="{{$option}}">{{$option}}</option>
-                                    @endforeach
-								</datalist>
+										<div>{{$option}}</div>
+									@endforeach
+								</div>
 							</div>
 						</div>
                         @endif

+ 4 - 0
resources/views/app/patient/segment-templates/medication_comments/edit.blade.php

@@ -0,0 +1,4 @@
+<?php
+$category = 'MEDICATION_COMMENTS';
+$endPoint = 'upsertNoteSingleton';
+include resource_path('views/app/patient/segment-templates/_simple_text_segment/edit.php');

+ 3 - 0
resources/views/app/patient/segment-templates/medication_comments/summary.blade.php

@@ -0,0 +1,3 @@
+<?php
+$category = 'MEDICATION_COMMENTS';
+include resource_path('views/app/patient/segment-templates/_simple_text_segment/summary.php');

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

@@ -50,7 +50,7 @@ if(!$parsed || !@$parsed->free_text) {
              class="form-group mb-2 border-left border-right rte-holder"
              data-field-name="free_text"
         ><?= $parsed && @$parsed->free_text ? $parsed->free_text : '' ?></div>
-        <div class="m-2">
+        <div class="my-2">
             <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>

+ 4 - 0
resources/views/app/patient/segment-templates/physical_exam/edit.blade.php

@@ -0,0 +1,4 @@
+<?php
+$category = 'PHYSICAL_EXAM';
+$endPoint = 'upsertNoteSingleton';
+include resource_path('views/app/patient/segment-templates/_simple_text_segment/edit.php');

+ 3 - 0
resources/views/app/patient/segment-templates/physical_exam/summary.blade.php

@@ -0,0 +1,3 @@
+<?php
+$category = 'PHYSICAL_EXAM';
+include resource_path('views/app/patient/segment-templates/_simple_text_segment/summary.php');

+ 279 - 0
resources/views/app/patient/segment-templates/psych_risk_assessment/edit.blade.php

@@ -0,0 +1,279 @@
+<?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, 'PSYCH_RISK_ASSESSMENT', $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,
+        "no_risks" => false,
+        "items" => [
+            [
+                "area" => '',
+                "level" => null,
+                "intent" => null,
+                "plan" => null,
+                "means" => null,
+                "risk_factors" => '',
+                "protective_factors" => '',
+                "additional_details" => ''
+            ]
+        ]
+    ];
+}
+
+?>
+
+<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">
+            @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_psych_risk_assessment-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="no_risks" name="no_risks">
+                        <span>Patient denies all areas of risk. No contrary clinical indications present.</span>
+                    </label>
+                </div>
+
+                <div v-if="!no_risks" v-for="(item, index) in items" class="note-section-item-row">
+                    <hr v-if="index > 0" class="row">
+                    <div class="d-flex align-items-baseline mb-2">
+                        <label class="width-140px my-0">Area of Risk:</label>
+                        <div class="flex-grow-1">
+                            <input type="text" class="form-control form-control-sm min-width-unset fg-1" data-option-list v-model="item.area" required>
+                            <div class="data-option-list">
+                                <div>Suicidal ideation</div>
+                                <div>Homicidal ideation</div>
+                                <div>Inability to care for self</div>
+                                <div>Inability to care for others</div>
+                                <div>Aggression toward others</div>
+                                <div>Aggression toward property</div>
+                                <div>Self-harm</div>
+                                <div>Elopement</div>
+                                <div>Substance misuse</div>
+                            </div>
+                        </div>
+                        <div moe relative v-if="items.length > 1" class="ml-3">
+                            <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 class="row mb-1">
+                        <div class="col-3">
+                            <div class="mb-1">Level of Risk:</div>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.level" value="Low">
+                                <span class="ml-1">Low</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.level" value="Medium">
+                                <span class="ml-1">Medium</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.level" value="High">
+                                <span class="ml-1">High</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.level" value="Imminent">
+                                <span class="ml-1">Imminent</span>
+                            </label>
+                        </div>
+                        <div class="col-3">
+                            <div class="mb-1">Intent to Act:</div>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.intent" value="Yes">
+                                <span class="ml-1">Yes</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.intent" value="No">
+                                <span class="ml-1">No</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.intent" value="Not Applicable">
+                                <span class="ml-1">Not Applicable</span>
+                            </label>
+                        </div>
+                        <div class="col-3">
+                            <div class="mb-1">Plan to Act:</div>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.plan" value="Yes">
+                                <span class="ml-1">Yes</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.plan" value="No">
+                                <span class="ml-1">No</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.plan" value="Not Applicable">
+                                <span class="ml-1">Not Applicable</span>
+                            </label>
+                        </div>
+                        <div class="col-3">
+                            <div class="mb-1">Means to Act:</div>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.means" value="Yes">
+                                <span class="ml-1">Yes</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.means" value="No">
+                                <span class="ml-1">No</span>
+                            </label>
+                            <label class="my-0 d-flex align-items-center">
+                                <input type="radio" v-model="item.means" value="Not Applicable">
+                                <span class="ml-1">Not Applicable</span>
+                            </label>
+                        </div>
+                    </div>
+                    <div class="d-flex align-items-baseline mb-1">
+                        <label class="width-140px my-0">Risk Factors:</label>
+                        <input type="text" class="form-control form-control-sm min-width-unset fg-1" v-model="item.risk_factors" required>
+                    </div>
+                    <div class="d-flex align-items-baseline mb-1">
+                        <label class="width-140px my-0">Protective Factors:</label>
+                        <input type="text" class="form-control form-control-sm min-width-unset fg-1" v-model="item.protective_factors" required>
+                    </div>
+                    <div class="d-flex align-items-baseline mb-1">
+                        <label class="width-140px my-0">Additional Details:</label>
+                        <input type="text" class="form-control form-control-sm min-width-unset fg-1" v-model="item.additional_details" required>
+                    </div>
+                </div>
+
+                <div class="form-group my-2">
+                    <button v-if="!no_risks" class="btn btn-sm btn-default text-primary border border-primary mr-2"
+                            v-on:click.prevent="addItem()"
+                    >Add Area of Risk</button>
+                </div>
+
+            </div>
+
+            @if(!!$segment)
+                <div>
+                    <button onclick="return saveVisitForm(this, false, false)" type="button" 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 type="button" class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel type="button" class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
+
+        </form>
+    </div>
+</div>
+<script>
+    (function() {
+
+        function init() {
+
+            new Vue({
+                el: '#edit-univ_psych_risk_assessment-container',
+                data: {
+                    count: {{ $contentData['count'] }},
+                    no_risks: {{ $contentData['no_risks'] ? 'true' : 'false' }},
+                    items: <?= json_encode($contentData['items']) ?>
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            let parent = $('#edit-univ_psych_risk_assessment-container').closest('form');
+                            parent.find('[name="data"]').val(JSON.stringify(this.$data)).trigger('save-trigger');
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+
+                    clearValue: function(_item, _key) {
+                        _item[_key] = null;
+                        Vue.nextTick(function() {
+                            $('#edit-univ_psych_risk_assessment-container').find('textarea').first().trigger('input');
+                        });
+                    },
+
+                    addItem: function() {
+                        this.items.push({
+                            area: '',
+                            level: null,
+                            intent: null,
+                            plan: null,
+                            means: null,
+                            risk_factors: '',
+                            protective_factors: '',
+                            additional_details: ''
+                        });
+                        this.count = this.items.length;
+
+                        // trigger autosave!
+                        Vue.nextTick(() => {
+                            let parent = $('#edit-univ_psych_risk_assessment-container').closest('form');
+                            parent.find('[name="no_risks"]').trigger('change');
+                            $('#edit-univ_psych_risk_assessment-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_psych_risk_assessment-container').closest('form');
+                            parent.find('[name="no_risks"]').trigger('change');
+                            hideMoeFormMask();
+                        });
+                    }
+                },
+                mounted: function() {
+                    $('#edit-univ_psych_risk_assessment-container').find('[moe][initialized]').removeAttr('initialized');
+                    initMoes();
+                }
+            });
+
+        }
+
+        window.segmentInitializers.psych_risk_assessment = init;
+
+    }).call(window);
+</script>

+ 49 - 0
resources/views/app/patient/segment-templates/psych_risk_assessment/log.blade.php

@@ -0,0 +1,49 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Point;
+use App\Models\Note;
+/** @var Client $patient */
+/** @var Note $note */
+
+$point = Point::getOnlyTopLevelPointOfCategory($note, 'PSYCH_RISK_ASSESSMENT', 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['no_risks'] && !!$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-1' : '' ?>">
+                        <div class="d-flex align-items-baseline mb-1">
+                            <b class="mr-3"><?= @($contentData['items'][$i]['area']) ?></b>
+                            <div class="mr-2">Level: <?= @($contentData['items'][$i]['level']) ?></div>
+                            <div class="mr-2">Intent: <?= @($contentData['items'][$i]['intent']) ?></div>
+                            <div class="mr-2">Plan: <?= @($contentData['items'][$i]['plan']) ?></div>
+                            <div class="mr-2">Means: <?= @($contentData['items'][$i]['means']) ?></div>
+                            <div class="ml-3">
+                                <div class="">Risk Factors: <?= @($contentData['items'][$i]['risk_factors']) ?></div>
+                                <div class="">Protective Factors: <?= @($contentData['items'][$i]['protective_factors']) ?></div>
+                                <div class="">Additional Details: <?= @($contentData['items'][$i]['additional_details']) ?></div>
+                            </div>
+                        </div>
+                    </div>
+                    <?php
+                }
+                ?>
+                </div>
+                <?php
+            }
+        }
+    }
+    ?> </div> <?php
+}

+ 57 - 0
resources/views/app/patient/segment-templates/psych_risk_assessment/summary.blade.php

@@ -0,0 +1,57 @@
+<?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, 'PSYCH_RISK_ASSESSMENT', $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['no_risks'] && !!$contentData['count']) {
+    for ($i = 0; $i < $contentData['count']; $i++) {
+?>
+<div class="<?= $i > 0 ? 'mt-1' : '' ?>">
+    @if(@($contentData['items'][$i]['area']))
+    <div class="d-flex align-items-baseline mb-1">
+        <b class="mr-3"><?= @($contentData['items'][$i]['area']) ?></b>
+        <div class="mr-2"><span class="text-secondary text-sm">Level:</span> <?= @($contentData['items'][$i]['level']) ?></div>
+        <div class="mr-2"><span class="text-secondary text-sm">Intent:</span> <?= @($contentData['items'][$i]['intent']) ?></div>
+        <div class="mr-2"><span class="text-secondary text-sm">Plan:</span> <?= @($contentData['items'][$i]['plan']) ?></div>
+        <div class="mr-2"><span class="text-secondary text-sm">Means:</span> <?= @($contentData['items'][$i]['means']) ?></div>
+    </div>
+    <div class="ml-3">
+        <div class="">Risk Factors: <?= @($contentData['items'][$i]['risk_factors']) ?></div>
+        <div class="">Protective Factors: <?= @($contentData['items'][$i]['protective_factors']) ?></div>
+        <div class="">Additional Details: <?= @($contentData['items'][$i]['additional_details']) ?></div>
+    </div>
+    @endif
+</div>
+<?php
+    }
+}
+else if(@$contentData['no_risks']) {
+?>
+<div class="text-secondary">Patient denies all areas of risk. No contrary clinical indications present.</div>
+<?php
+}
+else {
+?>
+<div class="text-secondary">-</div>
+<?php
+}
+?>

+ 327 - 0
resources/views/app/patient/segment-templates/psych_vitals/edit.blade.php

@@ -0,0 +1,327 @@
+<?php
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+$point = App\Models\Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'VITALS', $sessionKey, true);
+$vitalLabels = [
+    "heightInInches" => "Ht. (in.)",
+    "weightPounds" => "Wt. (lbs.)",
+    "bmi" => "BMI (kg/m²)",
+    "temperatureF" => "Temp. (F)",
+    "systolicBP" => "SBP",
+    "diastolicBP" => "DBP",
+    "pulseRatePerMinute" => "Pulse",
+    "respirationRatePerMinute" => "Resp.",
+    "pulseOx" => "Pulse Ox.",
+    "smokingStatus" => "Smoking Status",
+];
+$contentData = null;
+if ($point->lastChildReview && $point->lastChildReview->note->id === $note->id && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "date" => $note->effective_dateest,
+        "heightInInches" => '',
+        "weightPounds" => '',
+        "bmi" => '',
+        "temperatureF" => '',
+        "systolicBP" => '',
+        "diastolicBP" => '',
+        "pulseRatePerMinute" => '',
+        "respirationRatePerMinute" => '',
+        "pulseOx" => '',
+        "smokingStatus" => '',
+    ];
+}else {
+    if(!isset($contentData['date'])) $contentData['date'] = $note->effective_dateest;
+    foreach ($vitalLabels as $k => $v) {
+        if (!isset($contentData[$k]) || is_array($contentData[$k])) {
+            $contentData[$k] = '';
+        }
+    }
+}
+
+$previousVitals = [];
+
+$previousVitals = \App\Models\Point::where('parent_point_id', $point->id)
+    ->where('category', 'REVIEW')
+    ->where('added_in_note_id', '!=', $note->id)
+    ->orderBy('id', 'DESC')
+    ->limit(4)
+    ->get();
+
+// convert to new format
+$previousData = [];
+$previousDataAssoc = [];
+foreach ($previousVitals as $p) {
+    if (!!@$p->data) {
+        $parsedP = json_decode($p->data, true);
+        $newFormat = [];
+        foreach ($vitalLabels as $k => $v) {
+            if (isset($parsedP[$k]) && is_array($parsedP[$k]) && isset($parsedP[$k]['value'])) {
+                $newFormat[$k] = $parsedP[$k]['value'];
+            }
+            else if(isset($parsedP[$k]) && !is_array($parsedP[$k])) {
+                $newFormat[$k] = $parsedP[$k];
+            }
+            else {
+                $newFormat[$k] = '';
+            }
+        }
+        $newFormat['date'] = $p->note->effective_dateest; // unfriendly_date($p->created_at);
+        $previousData[] = $newFormat;
+        $previousDataAssoc[$newFormat['date']] = $newFormat; // for easy iter to cols
+    }
+}
+
+$copyTriggerAdded = [];
+
+if(!@$segment) {
+    $segment = $note->coreSegment;
+}
+
+?>
+<div visit-moe close-on-save close-on-cancel class="d-block">
+    <form show url="/api/visitPoint/upsertChildReview" class="mcp-theme-1">
+        <input type="hidden" name="uid" value="<?= $point->uid ?>">
+        <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+        <input type="hidden" name="segmentUid" value="<?= $segment->uid ?>">
+        <input type="hidden" name="category" value="VITALS">
+        <input type="hidden" name="data" value="{{json_encode($contentData)}}">
+
+        <table class="table table-sm table-bordered mb-2 table-edit-sheet">
+            <thead>
+            <tr class="bg-light">
+                <th class="px-2 text-secondary border-bottom-0 width-150px">Vital</th>
+                <th class="px-2 text-secondary border-bottom-0 w-25">{{friendly_date($contentData['date'])}}</th>
+                @if(!$previousData || !count($previousData))
+                    <th class="px-2 text-secondary border-bottom-0">Previous</th>
+                @else
+                    @foreach($previousData as $pDay)
+                        <th class="px-2 text-secondary border-bottom-0 on-hover-opaque position-relative">
+                            {{friendly_date($pDay['date'])}}
+                        </th>
+                    @endforeach
+                @endif
+            </tr>
+            </thead>
+            <tbody>
+                @foreach($vitalLabels as $k => $v)
+                    @if($k !== 'diastolicBP')
+                    <tr>
+                        <td>
+                            <input type="text" tabindex="-1"
+                                   class="form-control form-control-sm events-none border-0"
+                                   value="{{ $k === 'systolicBP' ? 'Blood Pressure' : ($k === 'heightInInches' ? 'Height' : $v) }}" readonly>
+                        </td>
+                        <td class="position-relative">
+                            @if($k === "bmi")
+                                <div class="d-flex align-items-stretch">
+                                    <input type="text" readonly bmi
+                                           class="form-control form-control-sm vitals-title border-bottom-0 border-top-0 border-left-0 border-right width-70px"
+                                           data-name="bmi" value="{{$contentData['bmi']}}">
+                                    <div class="flex-grow-1 py-1 m-0 px-2 font-weight-bold bg-light" bmi-category>
+                                        @if(isset($contentData['bmi']) && $contentData['bmi'] != "" )
+                                            <?php $bmi = $contentData['bmi']; ?>
+                                            @if($bmi < 18.5)
+                                                <span class="text-sm text-warning-mellow">Underweight</span>
+                                            @endif
+                                            @if($bmi >= 18.5 && $bmi < 25)
+                                                <span class="text-sm text-success">Healthy Weight</span>
+                                            @endif
+                                            @if($bmi >= 25 && $bmi < 30)
+                                                <span class="text-sm text-warning-mellow">Overweight</span>
+                                            @endif
+                                            @if($bmi >= 30)
+                                                <span class="text-sm text-warning-mellow">Obese</span>
+                                            @endif
+                                        @endif
+                                    </div>
+                                </div>
+                            @elseif($k === "smokingStatus")
+                                <input type="text"
+                                       class="form-control form-control-sm border-0"
+                                       data-name="smokingStatus"
+                                       placeholder="{{$v}}"
+                                       data-option-list="smokingStatus" value="{{$contentData['smokingStatus']}}">
+                                <div id="smoking-status-options" class="data-option-list">
+                                    <div>Current every day smoker</div>
+                                    <div>Former some day smoker</div>
+                                    <div>Former smoker</div>
+                                    <div>Never smoker</div>
+                                    <div>Smoker, current status unknown</div>
+                                    <div>Unknown if ever smoked</div>
+                                    <div>Heavy tobacco smoker</div>
+                                    <div>Light tobacco smoker</div>
+                                </div>
+                            @elseif($k === 'systolicBP')
+                                <div class="d-flex align-items-center bg-white">
+                                    <input type="text" class="form-control form-control-sm min-width-unset w-auto-input width-70px border-0 edit"
+                                           data-name="systolicBP" systolicBP
+                                           value="{{$contentData['systolicBP']}}" placeholder="Systolic">
+                                    <span class="px-2 text-secondary bg-white">/</span>
+                                    <input type="text" class="form-control form-control-sm min-width-unset w-auto-input width-70px border-0 edit"
+                                           data-name="diastolicBP" diastolicBP
+                                           value="{{$contentData['diastolicBP']}}" placeholder="Diastolic">
+                                </div>
+                            @elseif($k === 'heightInInches')
+                                <div class="d-flex align-items-center bg-white">
+                                    <input type="text" class="form-control form-control-sm min-width-unset w-auto-input width-30px border-0 edit"
+                                           heightFeetInput
+                                           value="{{feetFromInches($contentData['heightInInches']) ?: ''}}">
+                                    <span class="pl-1 pr-2 text-secondary bg-white">ft.</span>
+                                    <input type="text" class="form-control form-control-sm min-width-unset w-auto-input width-30px border-0 edit pr-0"
+                                           heightInchesInput
+                                           value="{{inchesAfterFeetFromInches($contentData['heightInInches']) ?: ''}}">
+                                    <span class="pl-1 text-secondary bg-white">in.</span>
+                                    <input type="hidden" data-name="heightInInches" value="{{$contentData['heightInInches']}}">
+                                </div>
+                            @else
+                                <input type="text"
+                                       class="form-control form-control-sm border-0" data-name="{{$k}}" {{$k}}
+                                       value="{{$contentData[$k]}}"
+                                       placeholder="{{$v}}"
+                                       @if($k == 'heightInInches' || $k == 'weightPounds') refresh-bmi @endif>
+                            @endif
+                        </td>
+                        @if(!$previousData || !count($previousData))
+                            <td class="bg-light"></td>
+                        @else
+                            @foreach($previousData as $pDay)
+                                <td class="bg-light {{!isset($copyTriggerAdded[$k]) ? 'px-2' : 'px-2'}} py-1 text-secondary position-relative">
+                                    <span data-type="{{$k}}">
+                                    @if($k === 'systolicBP')
+                                        {{ @$previousDataAssoc[$pDay['date']]['systolicBP'] ?: '-' }}/{{ @$previousDataAssoc[$pDay['date']]['diastolicBP'] ?: '-' }}
+                                    @elseif($k === 'heightInInches')
+                                        {{$previousDataAssoc[$pDay['date']][$k] ? toFeetAndInches($previousDataAssoc[$pDay['date']][$k]) : '-' }}
+                                    @elseif($k === 'bmi')
+                                        {{$previousDataAssoc[$pDay['date']][$k] ?: '-' }}
+                                        <?php
+                                        $prevBMI = $previousDataAssoc[$pDay['date']][$k] ? +($previousDataAssoc[$pDay['date']][$k]) : false;
+                                        ?>
+                                        @if($prevBMI < 18.5)
+                                            <span class="text-sm text-warning-mellow ml-1">Underweight</span>
+                                        @endif
+                                        @if($prevBMI >= 18.5 && $prevBMI < 25)
+                                            <span class="text-sm text-success ml-1">Healthy Weight</span>
+                                        @endif
+                                        @if($prevBMI >= 25 && $prevBMI < 30)
+                                            <span class="text-sm text-warning-mellow ml-1">Overweight</span>
+                                        @endif
+                                        @if($prevBMI >= 30)
+                                            <span class="text-sm text-warning-mellow ml-1">Obese</span>
+                                        @endif
+                                    @else
+                                        {{$previousDataAssoc[$pDay['date']][$k] ?: '-' }}
+                                    @endif
+                                    </span>
+                                    @if(!isset($copyTriggerAdded[$k]) && $k !== "bmi")
+                                        <a href="#" title="Copy to this note" class="vitals-copy-trigger"><i class="fa fa-chevron-circle-left font-size-14"></i></a>
+                                    @endif
+                                </td>
+                                <?php $copyTriggerAdded[$k] = true ?>
+                            @endforeach
+                        @endif
+                    </tr>
+                    @endif
+                @endforeach
+            </tbody>
+        </table>
+        <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>
+    </form>
+</div>
+<script>
+    window.segmentInitializers.omega_vitals = function () {
+        let parentSegment = $('[data-segment-template-name="omega_vitals"] ');
+
+        function __refreshBMI() {
+            var height = parseInt(parentSegment.find('[data-name="heightInInches"]').val());
+            var weight = parseInt(parentSegment.find('[data-name="weightPounds"]').val());
+            var bmi = '', bmiCategory = '';
+            if(!isNaN(height) && !isNaN(weight)) {
+                bmi = Math.round((weight / (height * height)) * 703.06957964);
+                if(bmi < 18.5) {
+                    bmiCategory = '<span class="text-sm text-warning-mellow">Underweight</span>';
+                }
+                else if(bmi >= 18.5 && bmi < 25) {
+                    bmiCategory = '<span class="text-sm text-success">Healthy Weight</span>';
+                }
+                else if(bmi >= 25 && bmi < 30) {
+                    bmiCategory = '<span class="text-sm text-warning-mellow">Overweight</span>';
+                }
+                else if(bmi >= 30) {
+                    bmiCategory = '<span class="text-sm text-warning-mellow">Obese</span>';
+                }
+            }
+            parentSegment.find('[bmi]').val(bmi);
+            parentSegment.find('[bmi-category]').empty().append(bmiCategory);
+        }
+
+        parentSegment.find('[refresh-bmi]').off('change input');
+        parentSegment.find('[refresh-bmi]').on('change input', __refreshBMI);
+
+        parentSegment.find('[heightFeetInput], [heightInchesInput]').off('change input paste');
+        parentSegment.find('[heightFeetInput], [heightInchesInput]').on('change input paste', function () {
+            let inches = 0;
+            let ft = +(parentSegment.find('[heightFeetInput]').val()),
+                inc = +(parentSegment.find('[heightInchesInput]').val());
+            inches = Math.round(ft * 12 + inc);
+            parentSegment.find('[data-name="heightInInches"]').val(inches);
+            __refreshBMI();
+        });
+
+        parentSegment.find('.vitals-copy-trigger').off('click.copy-vital');
+        parentSegment.find('.vitals-copy-trigger').on('click.copy-vital', function () {
+            let td = $(this).closest('td'), value = $.trim(td.text());
+            let type = td.find('>span').first().attr('data-type');
+            if(!type) return false;
+            switch (type) {
+                case 'heightInInches':
+                    if(value.indexOf('ft.') !== -1 && value.indexOf('in.') !== -1) {
+                        value = value.replace('in.', '');
+                        value = value.replace('ft.', '|');
+                        value = value.replace('/\s/gi', '');
+                        let parts = value.split('|');
+                        if (parts.length >= 1 && parts[0] !== '-') {
+                            td.prev().find('input:eq(0)').val(parts[0]).trigger('change');
+                        }
+                        if (parts.length >= 2 && parts[1] !== '-') {
+                            td.prev().find('input:eq(1)').val(parts[1]).trigger('change');
+                        }
+                    }
+                    break;
+                case 'systolicBP':
+                    if(value.indexOf('/') !== -1) {
+                        let parts = value.split('/');
+                        if (parts.length >= 1 && parts[0] !== '-') {
+                            td.prev().find('input:eq(0)').val(parts[0]).trigger('change');
+                        }
+                        if (parts.length >= 2 && parts[1] !== '-') {
+                            td.prev().find('input:eq(1)').val(parts[1]).trigger('change');
+                        }
+                    }
+                    break;
+                default:
+                    if(value && value !== '-') {
+                        td.prev().find('input').val(value).trigger('change');
+                    }
+                    break;
+            }
+
+            return false;
+        });
+
+    };
+</script>

+ 101 - 0
resources/views/app/patient/segment-templates/psych_vitals/summary.blade.php

@@ -0,0 +1,101 @@
+<?php
+if(!@$sessionKey) {
+    $sessionKey = request()->cookie('sessionKey');
+}
+$point = App\Models\Point::getOrCreateOnlyTopLevelPointOfCategory($note, 'VITALS', $sessionKey, true);
+$vitalLabels = [
+    "heightInInches" => "Ht. (in.)",
+    "weightPounds" => "Wt. (lbs.)",
+    "bmi" => "BMI (kg/m²)",
+    "temperatureF" => "Temp. (F)",
+    "systolicBP" => "SBP",
+    "diastolicBP" => "DBP",
+    "pulseRatePerMinute" => "Pulse",
+    "respirationRatePerMinute" => "Resp.",
+    "pulseOx" => "Pulse Ox.",
+    "smokingStatus" => "Smoking Status",
+];
+$contentData = null;
+if ($point->lastChildReview && $point->lastChildReview->note->id === $note->id && $point->lastChildReview->data) {
+    $point->lastChildReview->data = json_decode($point->lastChildReview->data, true);
+    $contentData = $point->lastChildReview->data;
+}
+
+if(!$contentData) {
+    $contentData = [
+        "date" => $note->effective_dateest,
+        "heightInInches" => '',
+        "weightPounds" => '',
+        "bmi" => '',
+        "temperatureF" => '',
+        "systolicBP" => '',
+        "diastolicBP" => '',
+        "pulseRatePerMinute" => '',
+        "respirationRatePerMinute" => '',
+        "pulseOx" => '',
+        "smokingStatus" => '',
+    ];
+}else {
+    if(!isset($contentData['date'])) $contentData['date'] = $note->effective_dateest;
+    foreach ($vitalLabels as $k => $v) {
+        if (!isset($contentData[$k]) || is_array($contentData[$k])) {
+            $contentData[$k] = '';
+        }
+    }
+}
+?>
+
+{{--<div class="mb-2">Effective Date: <b>{{friendly_date($contentData['date'])}}</b></div>--}}
+<div class="d-flex flex-wrap">
+@foreach ($vitalLabels as $k => $v)
+    @if($k !== 'diastolicBP')
+        <div class="d-inline-flex vital-item align-items-center mr-3 mb-1">
+            <span class="content-html text-nowrap">
+                <?php $vital = @$contentData[$k]; ?>
+                @if($k === 'systolicBP')
+                    <span>BP:</span>
+                    <b>{{ @$contentData['systolicBP'] ?: '-' }}/{{ @$contentData['diastolicBP'] ?: '-' }}</b>
+                @elseif($k === 'diastolicBP')
+                    <!--ignore-->
+                @elseif($k === 'heightInInches')
+                    <span>Ht:</span>
+                    <b>{{ !empty($vital) ? toFeetAndInches($vital, "'", '"') : '-' }}</b>
+                @elseif($k === 'weightPounds')
+                    <span>Wt:</span>
+                    <b>{{ !empty($vital) ? $vital : '-' }}</b>
+                @elseif($k === 'bmi')
+                    <span>BMI:</span>
+                    <b>{{ !empty($vital) ? $vital : '-' }}</b>
+                @elseif($k === 'temperatureF')
+                    <span>Temp:</span>
+                    <b>{{ !empty($vital) ? $vital : '-' }}</b>
+                @elseif($k === 'smokingStatus')
+                    <span>Smoking:</span>
+                    <b>{{ !empty($vital) ? $vital : '-' }}</b>
+                @else
+                    <span>{{$v}}:</span>
+                    <b>{{ !empty($vital) ? $vital : '-' }}</b>
+                @endif
+                @if($k === 'bmi' && !empty($vital))
+                    <?php $bmi = floatval($vital); ?>
+                    <span class="ml-1 py-1 m-0">
+                         @if($bmi < 18.5)
+                            <span class="text-warning-mellow">(Underweight)</span>
+                         @endif
+                        @if($bmi >= 18.5 && $bmi < 25)
+                            <span class="text-success">(Healthy Weight)</span>
+                        @endif
+                        @if($bmi >= 25 && $bmi < 30)
+                            <span class="text-warning-mellow">(Overweight)</span>
+                        @endif
+                        @if($bmi >= 30)
+                            <span class="text-warning-mellow">(Obese)</span>
+                        @endif
+                    </span>
+                @endif
+            </span>
+        </div>
+        @if(in_array($k, ['bmi', 'temperatureF', 'respirationRatePerMinute']))<br>@endif
+    @endif
+@endforeach
+</div>