ソースを参照

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

Josh 4 年 前
コミット
7208de6c93

+ 7 - 2
app/Http/Controllers/NoteController.php

@@ -90,8 +90,13 @@ class NoteController extends Controller
 
                 // for canvas section where we have pro mapped data, use hcpProId
                 $hcpPro = null;
-                if(\request()->input('hcpProId')) {
-                    $hcpPro = Pro::where('id', \request()->input('hcpProId'))->first();
+                if(\request()->input('hcpProUid')) {
+                    $hcpPro = Pro::where('uid', \request()->input('hcpProUid'))->first();
+                }
+
+                $note = null;
+                if(\request()->input('noteUid')) {
+                    $note = Note::where('uid', \request()->input('noteUid'))->first();
                 }
 
                 // default should simply assign to $contentData

+ 8 - 0
app/Http/Controllers/PracticeManagementController.php

@@ -1064,6 +1064,7 @@ SELECT claim.uid AS uid,
        (sp.name_last || ' ' || sp.name_first) AS status_pro,
        note.uid AS note_uid,
        note.method,
+       note.new_or_fu_or_na,
        -- claim.status_updated_at,
        (DATE(claim.status_updated_at) || ' ' || 
             LPAD(EXTRACT(hour FROM claim.status_updated_at)::text, 2, '0') || ':' || 
@@ -1105,6 +1106,13 @@ ORDER BY claim.created_at ASC
 
     public function currentClaimLines(Request $request, $claimUid) {
         $claim = Claim::where('uid', $claimUid)->first();
+        if($request->input('json')) {
+            foreach ($claim->lines as $line) {
+                $line->expected_total = round($line->expected_total, 3);
+                $x = $line->claimLineIcds;
+            }
+            return json_encode($claim->lines);
+        }
         return  view('app.practice-management._claim-lines', compact('claim'));
     }
 

+ 3 - 0
public/css/style.css

@@ -153,6 +153,9 @@ body.stag_rhs_collapsed .app-right-panel {
 .mcp-theme-1 .on-hover-opaque:hover {
     opacity: 1;
 }
+.mcp-theme-1 .opacity-0 {
+    opacity: 0 !important;
+}
 .mcp-theme-1 .opacity-60 {
     opacity: .6;
 }

+ 3 - 0
public/js/click-to-copy.js

@@ -16,6 +16,7 @@
             var successful = document.execCommand('copy');
             var msg = successful ? 'successful' : 'unsuccessful';
             console.log('Fallback: Copying text command was ' + msg);
+            toastr.success('Copied!');
         } catch (err) {
             console.error('Fallback: Oops, unable to copy', err);
         }
@@ -29,6 +30,7 @@
         }
         navigator.clipboard.writeText(text).then(function() {
             console.log('Async: Copying to clipboard was successful!');
+            toastr.success('Copied!');
         }, function(err) {
             console.error('Async: Could not copy text: ', err);
         });
@@ -40,6 +42,7 @@
             .on('click.click-to-copy', '.click-to-copy', function(event) {
             copyTextToClipboard($(this).text());
         });
+        window.copyTextToClipboard = copyTextToClipboard;
     }
 
     addMCInitializer('click-to-copy', init);

+ 54 - 0
resources/views/app/patient/canvas-sections/cc_may21/default.php

@@ -0,0 +1,54 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Note;
+
+/** @var Client $patient */
+/** @var Note $note */
+
+$canvasData = [
+    "text" => '',
+    "was_confirmed" => false,
+    "note_uid" => '',
+];
+
+$patientDx = null;
+
+if ($patient->canvas_data) {
+    $canvasData = json_decode($patient->canvas_data, true);
+    if (isset($canvasData["dx"])) {
+        $patientDx = $canvasData["dx"];
+    }
+    if (isset($canvasData["cc_may21"])) {
+        $canvasData = $canvasData["cc_may21"];
+    }
+}
+$contentData = $canvasData;
+
+if (!isset($contentData['note_uid']) || $contentData['note_uid'] !== @$note->uid) {
+    $prefix = $patient->name_prefix ?: '';
+    if (!$prefix) {
+        $prefix = $patient->sex === 'M' ? 'Mr. ' : 'Ms. ';
+    }
+
+    $lines = [];
+    $output = '';
+    if ($patientDx && isset($patientDx['items'])) {
+        $lines = $patientDx['items'];
+        foreach ($lines as $i => $line) {
+            if ($i > 0) {
+                $output .= ($i < count($lines) - 2 ? ', ' : ($i === count($lines) - 2 ? ' and ' : ''));
+            }
+            $output .= $line['title'];
+        }
+    }
+
+    $contentData['text'] =
+        $prefix . $patient->name_first . ' ' . $patient->name_last . ' ' .
+        'is a ' . $patient->age_in_years . ' y.o. ' . $patient->sex . ' ' .
+        (!empty($output) ? (' with ' . $output) : '') . ' ' .
+        'presenting today ' .
+        (@$note ? (@$note->new_or_fu_or_na === 'NEW' ? 'to establish care' : 'for follow-up') : '') . '.';
+    $contentData['was_confirmed'] = false;
+    $contentData['note_uid'] = @$note->uid;
+}

+ 106 - 0
resources/views/app/patient/canvas-sections/cc_may21/form.blade.php

@@ -0,0 +1,106 @@
+<?php
+if(!$contentData || !isset($contentData['text']) || !isset($contentData['was_confirmed'])) {
+    $contentData = [
+        "text" => '',
+        "was_confirmed" => false,
+        "note_uid" => (@$note ? $note->uid : ''),
+    ];
+}
+
+$formID = rand(0, 100000);
+?>
+<div id="ccMay21Section">
+    <input type="hidden" name="data" value="{{json_encode($contentData)}}">
+    <div class="border-right border-left">
+        <textarea class="form-group mb-2">{{$contentData['text']}}</textarea>
+    </div>
+    <label class="d-flex align-items-center my-3">
+        <input type="checkbox" v-model="data.was_confirmed" {{$contentData['was_confirmed'] ? 'checked' : ''}} class="my-0 mr-2">
+        <span>Confirm</span>
+    </label>
+</div>
+<script>
+    (function() {
+        function init() {
+            window.clientCCMay21App = new Vue({
+                el: '#ccMay21Section',
+                data: {
+                    data: <?= json_encode($contentData) ?>
+                },
+                mounted: function() {
+                    this.initRTE();
+                },
+                watch: {
+                    $data: {
+                        handler: function(val, oldVal) {
+                            $(this.$el).closest('#ccMay21Section').find('[name="data"]').val(JSON.stringify({
+                                text: this.data.text,
+                                was_confirmed: this.data.was_confirmed,
+                                note_uid: '{{(@$note ? $note->uid : '')}}',
+                            }));
+                        },
+                        deep: true
+                    }
+                },
+                methods: {
+                    cleanArray: function(_source) {
+                        let plItems = [], plObject = {};
+                        for (let x=0; x<_source.length; x++) {
+                            plObject = {};
+                            for (let y in _source[x]) {
+                                if(_source[x].hasOwnProperty(y)) {
+                                    plObject[y] = _source[x][y];
+                                }
+                            }
+                            plItems.push(plObject);
+                        }
+                        return plItems;
+                    },
+                    initRTE: function() {
+                        let self = this;
+                        $('#ccMay21Section textarea').each(function() {
+
+                            $(this).wrap(
+                                $('<div class="rte-holder"/>')
+                                    .attr('data-shortcuts', '')
+                            );
+
+                            // give a unique id to this editor instance
+                            var editorID = Math.ceil(Math.random() * 99999);
+
+                            $('<div data-editor-id="' + editorID + '" data-field="' + this.name + '"/>')
+                                .html(this.value)
+                                .insertBefore(this);
+
+                            $(this).remove();
+
+                            var qe = new Quill('[data-editor-id="' + editorID + '"]', {
+                                theme: 'snow',
+                                modules: stagQuillConfig
+                            });
+
+                            var toolbar = $(qe.container).prev('.ql-toolbar');
+
+                            // add button for new shortcut
+                            var newSCButton = $('<button type="button" tabindex="-1" ' +
+                                'class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
+                                'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
+                            toolbar.append(newSCButton);
+
+                            qe.on('text-change', function() {
+                                self.data.text = qe.root.innerHTML;
+                            });
+
+                            $(qe.container)
+                                .find('.ql-editor[contenteditable]')
+                                .attr('data-editor-id', editorID)
+                                .attr('with-shortcuts', 1);
+
+                        });
+                    }
+                }
+            });
+        }
+        addMCInitializer('client-ccMay21', init, '#ccMay21Section');
+    })();
+</script>

+ 26 - 0
resources/views/app/patient/canvas-sections/cc_may21/summary.php

@@ -0,0 +1,26 @@
+<?php
+
+use App\Models\Client;
+use App\Models\Note;
+
+/** @var Client $patient */
+/** @var Note $note */
+
+if(!@$contentData) {
+    $contentData = [
+        "text" => '',
+        "was_confirmed" => false,
+        "note_uid" => (@$note ? $note->uid : '')
+    ];
+    if ($patient->canvas_data) {
+        $canvasData = json_decode($patient->canvas_data, true);
+        if (isset($canvasData["cc_may21"])) {
+            $contentData = $canvasData["cc_may21"];
+            if (!isset($contentData['text'])) $contentData['text'] = '';
+            if (!isset($contentData['was_confirmed'])) $contentData['was_confirmed'] = false;
+        }
+    }
+}
+?>
+
+<p><?= $contentData['text'] ? $contentData['text'] : '-' ?></p>

+ 9 - 9
resources/views/app/patient/canvas-sections/lifestyle_rx_review/summary.php

@@ -294,17 +294,17 @@ else {
                                 <?= @$exercise['reps'] ? ' / ' . $exercise['reps'] . ' reps' : '' ?>
                                 <?= @$exercise['days_per_week'] ? ' / ' . $exercise['days_per_week'] . ' days/wk' : '' ?>
                             </td>
-                            <td class="px-2 align-middle py-1 bg-white"><?= $exercise['memo'] ?></td>
-                            <td class="px-2 align-middle py-1 bg-white"><?= $exercise['adherence'] ?></td>
-                            <td class="px-2 align-middle py-1 bg-white"><?= $exercise['adherence_memo'] ?></td>
+                            <td class="px-2 align-middle py-1 bg-white"><?= @$exercise['memo'] ? $exercise['memo'] : '-' ?></td>
+                            <td class="px-2 align-middle py-1 bg-white"><?= @$exercise['adherence'] ? $exercise['adherence'] : '-' ?></td>
+                            <td class="px-2 align-middle py-1 bg-white"><?= @$exercise['adherence_memo'] ? $exercise['adherence_memo'] : '-' ?></td>
                         </tr>
                     <?php endforeach; ?>
                     </tbody>
                 <?php endif; ?>
 
-                <?php if ($contentData['adherence']['neat']['active']): ?>
+                <?php if (@$contentData['adherence']['neat']['active']): ?>
                     <tbody class="border-0">
-                    <?php if ($contentData['adherence']['neat']['recommendations']['park_farther']): ?>
+                    <?php if (@$contentData['adherence']['neat']['recommendations']['park_farther']): ?>
                         <tr>
                             <td class="px-2 align-middle py-1 bg-white" colspan="2">
                                 NEAT → Park farther away from entrances
@@ -313,7 +313,7 @@ else {
                             <td class="px-2 align-middle py-1 bg-white"><?= @$contentData['adherence']['neat']['recommendations']['park_farther_adherence_memo'] ?></td>
                         </tr>
                     <?php endif; ?>
-                    <?php if ($contentData['adherence']['neat']['recommendations']['steps_instead_of_elevator']): ?>
+                    <?php if (@$contentData['adherence']['neat']['recommendations']['steps_instead_of_elevator']): ?>
                         <tr>
                             <td class="px-2 align-middle py-1 bg-white" colspan="2">
                                 NEAT → Take the stairs instead of escalator/elevator
@@ -322,7 +322,7 @@ else {
                             <td class="px-2 align-middle py-1 bg-white"><?= @$contentData['adherence']['neat']['recommendations']['steps_instead_of_elevator_adherence_memo'] ?></td>
                         </tr>
                     <?php endif; ?>
-                    <?php if ($contentData['adherence']['neat']['recommendations']['stand_instead_of_sit']): ?>
+                    <?php if (@$contentData['adherence']['neat']['recommendations']['stand_instead_of_sit']): ?>
                         <tr>
                             <td class="px-2 align-middle py-1 bg-white" colspan="2">
                                 NEAT → Stand instead of sit
@@ -331,7 +331,7 @@ else {
                             <td class="px-2 align-middle py-1 bg-white"><?= @$contentData['adherence']['neat']['recommendations']['stand_instead_of_sit_adherence_memo'] ?></td>
                         </tr>
                     <?php endif; ?>
-                    <?php if ($contentData['adherence']['neat']['recommendations']['steps_goal_per_day']): ?>
+                    <?php if (@$contentData['adherence']['neat']['recommendations']['steps_goal_per_day']): ?>
                         <tr>
                             <td class="px-2 align-middle py-1 bg-white" colspan="2">
                                 NEAT → Steps goal / day:
@@ -341,7 +341,7 @@ else {
                             <td class="px-2 align-middle py-1 bg-white"><?= @$contentData['adherence']['neat']['recommendations']['steps_goal_per_day_adherence_memo'] ?></td>
                         </tr>
                     <?php endif; ?>
-                    <?php if ($contentData['adherence']['neat']['recommendations']['other']): ?>
+                    <?php if (@$contentData['adherence']['neat']['recommendations']['other']): ?>
                         <tr>
                             <td class="px-2 align-middle py-1 bg-white" colspan="2">
                                 NEAT → Other: <b><?= @$contentData['adherence']['neat']['recommendations']['other'] ?></b>

+ 41 - 5
resources/views/app/patient/canvas-sections/rx/form.blade.php

@@ -52,7 +52,8 @@ $formID = rand(0, 100000);
         <thead>
         <tr class="bg-light">
             <th class="px-2 text-secondary border-bottom-0 width-30px text-center">#</th>
-            <th class="px-2 text-secondary border-bottom-0 w-35">
+            <th class="px-2 text-secondary border-bottom-0 width-30px text-center">Active</th>
+            <th class="px-2 text-secondary border-bottom-0 w-25">
                 <div class="d-flex align-items-center font-weight-normal">
                     <span>Title</span>
                     <div class="hide-if-dashboard ml-auto">
@@ -82,14 +83,20 @@ $formID = rand(0, 100000);
                     </div>
                 </div>
             </th>
-            <th class="px-2 text-secondary border-bottom-0">Strength/Form/Freq.</th>
-            <th class="px-2 text-secondary border-bottom-0 w-35">Detail</th>
+            <th class="px-2 text-secondary border-bottom-0 width-150px">Strength/Form/Freq.</th>
+            <th class="px-2 text-secondary border-bottom-0 w-25">Detail</th>
+            <th class="px-2 text-secondary border-bottom-0">Notes</th>
             <th class="px-2 text-secondary border-bottom-0"></th>
         </tr>
         </thead>
         <tbody>
         <tr v-for="(item, index) in items">
             <td class="px-2 pt-2 text-center text-sm font-weight-bold">@{{ index + 1 }}</td>
+            <td>
+                <label class="d-block text-center py-2">
+                    <input type="checkbox" v-model="item.is_currently_active">
+                </label>
+            </td>
             <td>
                 <input type="text" :data-index="index"
                        class="form-control form-control-sm canvas-rx-title"
@@ -112,6 +119,9 @@ $formID = rand(0, 100000);
                           rx-rte :data-index="index" data-field="detail"
                           v-model="item.detail"></textarea>
             </td>
+            <td>
+                <textarea class="form-control form-control-sm" v-model="item.notes[item.notes.length-1].text"></textarea>
+            </td>
             <td class="px-2 text-nowrap">
                 <a href="#"
                    v-if="!isFavorite(item)" v-on:click.prevent="addToFavorites(item)"
@@ -147,11 +157,24 @@ $formID = rand(0, 100000);
         for (let i = 0; i < favorites.length; i++) {
             favorites[i].data = JSON.parse(favorites[i].data);
         }
+        let dbItems = <?= json_encode($contentData['items']) ?>;
+        for (let i = 0; i < dbItems.length; i++) {
+            if(typeof dbItems[i].is_currently_active === 'undefined') {
+                dbItems[i].is_currently_active = true;
+            }
+            if(typeof dbItems[i].notes === 'undefined') {
+                dbItems[i].notes = [];
+            }
+            dbItems[i].notes.push({
+                date: '{{@$note ? $note->effective_dateest : date('Y-m-d')}}',
+                text: '',
+            });
+        }
         function init() {
             window.clientRXApp_{{$formID}} = new Vue({
                 el: '#rxSection_{{$formID}}',
                 data: {
-                    items: <?= json_encode($contentData['items']) ?>,
+                    items: dbItems,
                     favorites: favorites,
                 },
                 mounted: function() {
@@ -163,8 +186,14 @@ $formID = rand(0, 100000);
                 watch: {
                     $data: {
                         handler: function(val, oldVal) {
+                            let payload = JSON.parse(JSON.stringify(this.cleanArray(this.items)));
+                            for (let i = 0; i < payload.length; i++) {
+                                payload[i].notes = payload[i].notes.filter(_x => {
+                                    return !!_x.text;
+                                })
+                            }
                             $(this.$el).closest('#rxSection_{{$formID}}').find('[name="data"]').val(JSON.stringify({
-                                items: this.cleanArray(this.items)
+                                items: payload
                             }));
                         },
                         deep: true
@@ -178,6 +207,13 @@ $formID = rand(0, 100000);
                             strength: '',
                             frequency: '',
                             detail: '',
+                            is_currently_active: true,
+                            notes: [
+                                {
+                                    date: '{{@$note ? $note->effective_dateest : date('Y-m-d')}}',
+                                    text: '',
+                                }
+                            ]
                         });
                         Vue.nextTick(function() {
                             self.initRTE();

+ 16 - 1
resources/views/app/patient/canvas-sections/rx/summary.php

@@ -20,7 +20,9 @@ if(count($contentData['items'])) {
         <div class="mb-2">
             <div class="">
                 <?php if(isset($item["title"]) && !empty($item["title"])): ?>
-                    <b><?= $item["title"] ?></b>
+                    <b class="<?= isset($item["is_currently_active"]) && $item["is_currently_active"] === false ? 'text-secondary' : '' ?>">
+                        <?= $item["title"] ?>
+                    </b>
                 <?php endif; ?>
                 <?= !!$item["strength"] ? '/&nbsp;' . $item["strength"] : '' ?>
                 <?= !!$item["frequency"] ? '/&nbsp;' . $item["frequency"] : '' ?>
@@ -32,6 +34,19 @@ if(count($contentData['items'])) {
             ?>
                 <div class="text-secondary"><?= $detailPlain ?></div>
             <?php endif; ?>
+            <?php if(isset($item["is_currently_active"]) && $item["is_currently_active"] === false): ?>
+                <span class="pl-3 text-secondary text-sm mr-2 font-weight-bold">(CURRENTLY INACTIVE)</span>
+            <?php endif; ?>
+            <?php if(isset($item["notes"]) && count($item["notes"])): ?>
+                <div class="pl-3">
+                <?php foreach($item["notes"] as $rxNote): ?>
+                    <div>
+                        <span class="text-secondary text-sm mr-2"><?= $rxNote["date"] ?></span>
+                        <span class="text-secondary"><?= $rxNote["text"] ?></span>
+                    </div>
+                <?php endforeach; ?>
+                </div>
+            <?php endif; ?>
         </div>
 <?php
     }

+ 10 - 0
resources/views/app/patient/canvas-sections/vitals_may21/default.php

@@ -0,0 +1,10 @@
+<?php
+
+$canvasData = [];
+if ($patient->canvas_data) {
+    $canvasData = json_decode($patient->canvas_data, true);
+    if (isset($canvasData["vitals_may21"])) {
+        $canvasData = $canvasData["vitals_may21"];
+    }
+}
+$contentData = $canvasData;

+ 375 - 0
resources/views/app/patient/canvas-sections/vitals_may21/form.blade.php

@@ -0,0 +1,375 @@
+<?php
+$cdFormat = [
+    "effectiveDate" => (@$note ? friendlier_date($note->effective_dateest) : date('Y-m-d')),
+    "note_uid" => (@$note ? $note->uid : ''),
+    "temperature" => [
+        "value" => '',
+        "baseline" => '',
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "bp" => [
+        "valueSystolic" => '',
+        "valueDiastolic" => '',
+        "baselineSystolicMin" => '',
+        "baselineSystolicMax" => '',
+        "baselineDiastolicMin" => '',
+        "baselineDiastolicMax" => '',
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "pulse" => [
+        "value" => '',
+        "baseline" => '',
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "spO2" => [
+        "value" => '',
+        "baseline" => '',
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "weight" => [
+        "value" => '',
+        "baselineMin" => '',
+        "baselineMax" => '',
+        "isCHF" => null,
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "height" => [
+        "valueFeet" => '',
+        "valueInches" => '',
+        "baselineFeet" => '',
+        "baselineInches" => '',
+        "isCHF" => null,
+        "deviceRemarks" => [
+            "hasDevice" => null,
+            "issues" => null,
+            "other" => null,
+        ]
+    ],
+    "other" => null,
+];
+if(!$contentData) {
+    $contentData = $cdFormat;
+}
+else {
+    foreach ($cdFormat as $k => $v) {
+        if(!isset($contentData[$k])) {
+            $contentData[$k] = $v;
+        }
+    }
+}
+$formID = rand(0, 100000);
+?>
+<div id="vitalsMay21Section">
+
+    <input type="hidden" name="data" value="{{json_encode($contentData)}}">
+
+    <table class="table table-sm table-bordered mb-2 table-edit-sheet">
+        <thead class="bg-light text-secondary font-weight-bold">
+        <tr>
+            <th class="border-bottom-0">&nbsp;</th>
+            <th class="border-bottom-0">Value ({{@$note ? friendlier_date($note->effective_dateest) : date('Y-m-d')}})</th>
+            <th class="border-bottom-0">Baseline</th>
+            <th class="border-bottom-0">Device Remarks</th>
+        </tr>
+        </thead>
+        <tbody class="bg-white">
+        <!--temp-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">Temperature</td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Value (℉)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.temperature.value">
+            </td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Baseline (℉)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.temperature.baseline">
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.temperature.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.temperature.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.temperature.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.temperature.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--bp-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">BP</td>
+            <td>
+                <div class="d-flex align-items-center">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Systolic (mmHg)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.bp.valueSystolic">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Diastolic (mmHg)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.bp.valueDiastolic">
+                    </div>
+                </div>
+            </td>
+            <td>
+                <div class="d-flex align-items-center">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Systolic Min (mmHg)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.bp.baselineSystolicMin">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Diastolic Min (mmHg)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.bp.baselineDiastolicMin">
+                    </div>
+                </div>
+                <div class="d-flex align-items-center mt-2">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Systolic Max (mmHg)</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.bp.baselineSystolicMax">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Diastolic Max (mmHg)</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.bp.baselineDiastolicMax">
+                    </div>
+                </div>
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.bp.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.bp.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.bp.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.bp.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--pulse-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">Pulse</td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Value (bpm)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.pulse.value">
+            </td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Baseline (bpm)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.pulse.baseline">
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.pulse.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.pulse.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.pulse.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.pulse.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--spO2-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">SpO2</td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Value (%)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.spO2.value">
+            </td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Baseline (%)</div>
+                <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.spO2.baseline">
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.spO2.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.spO2.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.spO2.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.spO2.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--weight-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">Weight</td>
+            <td>
+                <div class="px-2 text-sm text-secondary my-1">Value (lbs)</div>
+                <input class="form-control form-control-sm border-top" type="text" v-model="data.weight.value">
+            </td>
+            <td>
+                <div class="d-flex align-items-center">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Baseline Min (lbs)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.weight.baselineMin">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Baseline Max (lbs)</div>
+                        <input class="form-control form-control-sm border-top" type="text" v-model="data.weight.baselineMax">
+                    </div>
+                </div>
+                <label class="my-2 text-left px-2">
+                    <input type="checkbox" v-model="data.weight.isCHF">
+                    Is CHF?
+                </label>
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.weight.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.weight.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.weight.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.weight.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--height-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">Height</td>
+            <td>
+                <div class="d-flex align-items-center">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Feet</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.height.valueFeet">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Inches</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.height.valueInches">
+                    </div>
+                </div>
+            </td>
+            <td>
+                <div class="d-flex align-items-center">
+                    <div class="w-50 border-right">
+                        <div class="px-2 text-sm text-secondary my-1">Baseline Feet</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.height.baselineFeet">
+                    </div>
+                    <div class="w-50">
+                        <div class="px-2 text-sm text-secondary my-1">Baseline Inches</div>
+                        <input class="form-control form-control-sm border-top border-bottom-0" type="text" v-model="data.height.baselineInches">
+                    </div>
+                </div>
+            </td>
+            <td class="pt-1">
+                <label class="d-flex align-items-center px-2">
+                    <input type="checkbox" v-model="data.height.deviceRemarks.hasDevice">
+                    <span class="py-1 ml-1">Has device at home?</span>
+                </label>
+                <div v-if="data.height.deviceRemarks.hasDevice">
+                    <div class="text-sm text-secondary my-1 px-2">Any issues?</div>
+                    <input class="form-control form-control-sm" type="text" v-model="data.height.deviceRemarks.issues">
+                    <div class="text-sm text-secondary my-1 px-2">Other</div>
+                    <input class="form-control form-control-sm border-bottom-0" type="text" v-model="data.height.deviceRemarks.other">
+                </div>
+            </td>
+        </tr>
+
+        <!--other-->
+        <tr>
+            <td class="text-secondary font-weight-bold px-2 py-1 bg-white">Other</td>
+            <td colspan="3"><input class="form-control form-control-sm" type="text" v-model="data.other"></td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+<script>
+    (function() {
+        function init() {
+            window.clientVitalsMay21App = new Vue({
+                el: '#vitalsMay21Section',
+                data: {
+                    data: <?= json_encode($contentData) ?>
+                },
+                mounted: function() {
+                    // $(this.$el).closest('#vitalsMay21Section').find('[name="data"]').val(
+                    //     JSON.stringify(this.cleanObject(this.data))
+                    // );
+                },
+                watch: {
+                    data: {
+                        handler: function(val, oldVal) {
+                            $(this.$el).closest('#vitalsMay21Section').find('[name="data"]').val(
+                                JSON.stringify(this.cleanObject(this.data))
+                            );
+                        },
+                        deep: true
+                    },
+                },
+                computed: {
+                    // bmi: function () {
+                    //     let result = '';
+                    //     let h = this.items.heightInInches, w = this.items.weightPounds;
+                    //     if(!h || !w) {
+                    //         return result;
+                    //     }
+                    //     h = h.value;
+                    //     w = w.value;
+                    //     try {
+                    //         h = parseFloat(h);
+                    //         w = parseFloat(w);
+                    //         if(!h || !w) {
+                    //             this.items.bmi.value = '';
+                    //             return result;
+                    //         }
+                    //         let result = (w / [ h * h]) * 703;
+                    //         return result.toFixed(1);
+                    //     }
+                    //     catch (e) {
+                    //         return result;
+                    //     }
+                    // }
+                },
+                methods: {
+                    cleanObject: function(_source) {
+                        let plObject = {};
+                        for (let y in _source) {
+                            if(_source.hasOwnProperty(y)) {
+                                plObject[y] = _source[y];
+                            }
+                        }
+                        plObject.bmi = {
+                            label: "BMI (kg/m²)",
+                            value: this.bmi,
+                            date: this.bmi ? this.today : '',
+                        };
+                        return plObject;
+                    }
+                }
+            });
+        }
+        addMCInitializer('client-vitals-may21', init, '#vitalsMay21Section');
+    })();
+</script>

+ 277 - 0
resources/views/app/patient/canvas-sections/vitals_may21/summary.php

@@ -0,0 +1,277 @@
+<?php
+use App\Models\Note;
+use App\Models\Client;
+/** @var Note $note */
+/** @var Client $patient */
+if(!@$contentData) {
+    $contentData = [
+        "effectiveDate" => (@$note ? friendlier_date($note->effective_dateest) : date('Y-m-d')),
+        "note_uid" => (@$note ? $note->uid : ''),
+        "temperature" => [
+            "value" => '',
+            "baseline" => '',
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "bp" => [
+            "valueSystolic" => '',
+            "valueDiastolic" => '',
+            "baselineSystolicMin" => '',
+            "baselineSystolicMax" => '',
+            "baselineDiastolicMin" => '',
+            "baselineDiastolicMax" => '',
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "pulse" => [
+            "value" => '',
+            "baseline" => '',
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "spO2" => [
+            "value" => '',
+            "baseline" => '',
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "weight" => [
+            "value" => '',
+            "baselineMin" => '',
+            "baselineMax" => '',
+            "isCHF" => null,
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "height" => [
+            "valueFeet" => '',
+            "valueInches" => '',
+            "baselineFeet" => '',
+            "baselineInches" => '',
+            "isCHF" => null,
+            "deviceRemarks" => [
+                "hasDevice" => null,
+                "issues" => null,
+                "other" => null,
+            ]
+        ],
+        "other" => null,
+    ];
+    if ($patient->canvas_data) {
+        $canvasData = json_decode($patient->canvas_data, true);
+        if (isset($canvasData["vitals_may21"])) {
+            if (isset($canvasData["vitals_may21"]["note_uid"]) && $canvasData["vitals_may21"]["note_uid"] === @$note->uid) {
+                $contentData = $canvasData["vitals_may21"];
+            }
+        }
+    }
+}
+?>
+<table class="table table-sm table-bordered mb-2">
+    <thead>
+    <tr class="text-secondary font-weight-bold">
+        <td class="border-bottom-0">&nbsp;</td>
+        <td class="border-bottom-0">Value (<?= @$note ? friendlier_date($note->effective_dateest) : date('Y-m-d') ?>)</td>
+        <td class="border-bottom-0">Baseline</td>
+        <td class="border-bottom-0">Device Remarks</td>
+    </tr>
+    </thead>
+    <tbody>
+    <!--temp-->
+    <?php if (isset($contentData["temperature"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">Temperature</td>
+            <td><?= @$contentData["temperature"]["value"] ? $contentData["temperature"]["value"] . ' ℉' : '-' ?></td>
+            <td><?= @$contentData["temperature"]["baseline"] ? $contentData["temperature"]["baseline"] . ' ℉' : '-' ?></td>
+            <td>
+                <?php if (isset($contentData["temperature"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["temperature"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["temperature"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["temperature"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["temperature"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["temperature"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["temperature"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--bp-->
+    <?php if (isset($contentData["bp"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">BP</td>
+            <td><?= $contentData["bp"]["valueSystolic"] . '/' . $contentData["bp"]["valueDiastolic"] . ' mmHg' ?></td>
+            <td>
+                <div>
+                    Systolic: <?= @$contentData["bp"]["baselineSystolicMin"] . ' - ' . $contentData["bp"]["baselineSystolicMax"] . 'mmHg' ?>
+                </div>
+                <div>
+                    Diastolic: <?= @$contentData["bp"]["baselineDiastolicMin"] . ' - ' . $contentData["bp"]["baselineDiastolicMax"] . 'mmHg' ?>
+                </div>
+            </td>
+            <td>
+                <?php if (isset($contentData["bp"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["bp"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["bp"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["bp"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["bp"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["bp"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["bp"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--pulse-->
+    <?php if (isset($contentData["pulse"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">Pulse</td>
+            <td><?= @$contentData["pulse"]["value"] ? $contentData["pulse"]["value"] . ' bpm' : '-' ?></td>
+            <td><?= @$contentData["pulse"]["baseline"] ? $contentData["pulse"]["baseline"] . ' bpm' : '-' ?></td>
+            <td>
+                <?php if (isset($contentData["pulse"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["pulse"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["pulse"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["pulse"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["pulse"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["pulse"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["pulse"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--spO2-->
+    <?php if (isset($contentData["spO2"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">SpO2</td>
+            <td><?= @$contentData["spO2"]["value"] ? $contentData["spO2"]["value"] . ' %' : '-' ?></td>
+            <td><?= @$contentData["spO2"]["baseline"] ? $contentData["spO2"]["baseline"] . ' %' : '-' ?></td>
+            <td>
+                <?php if (isset($contentData["spO2"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["spO2"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["spO2"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["spO2"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["spO2"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["spO2"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["spO2"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--weight-->
+    <?php if (isset($contentData["weight"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">Weight</td>
+            <td><?= @$contentData["weight"]["value"] ? $contentData["weight"]["value"] . ' lbs' : '-' ?></td>
+            <td>
+                <?= @$contentData["weight"]["baselineMin"] . ' - ' . $contentData["weight"]["baselineMax"] . 'lbs' ?>
+                <div>
+                    CHF: <?= @$contentData["weight"]["isCHF"] ? 'Yes' : 'No' ?>
+                </div>
+            </td>
+            <td>
+                <?php if (isset($contentData["weight"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["weight"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["weight"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["weight"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["weight"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["weight"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["weight"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--height-->
+    <?php if (isset($contentData["height"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">Height</td>
+            <td>
+                <?= @$contentData["height"]["valueFeet"] . ' ft ' . @$contentData["height"]["valueInches"] . ' in' ?>
+            </td>
+            <td>
+                <?= @$contentData["height"]["baselineFeet"] . ' ft ' . $contentData["height"]["baselineInches"] . ' in' ?>
+            </td>
+            <td>
+                <?php if (isset($contentData["height"]["deviceRemarks"]["hasDevice"])): ?>
+                    Has device: <b><?= $contentData["height"]["deviceRemarks"]["hasDevice"] ? 'Yes' : 'No ' ?></b>
+                    <?php if ($contentData["height"]["deviceRemarks"]["hasDevice"]): ?>
+                        <?php if (isset($contentData["height"]["deviceRemarks"]["issues"])): ?>
+                            <div class="text-sm">
+                                Issues: <?= $contentData["height"]["deviceRemarks"]["issues"] ?></div>
+                        <?php endif; ?>
+                        <?php if (isset($contentData["height"]["deviceRemarks"]["other"])): ?>
+                            <div class="text-sm">
+                                Other: <?= $contentData["height"]["deviceRemarks"]["other"] ?></div>
+                        <?php endif; ?>
+                    <?php endif; ?>
+                <?php else: ?>
+                    -
+                <?php endif; ?>
+            </td>
+        </tr>
+    <?php endif; ?>
+
+    <!--other-->
+    <?php if (isset($contentData["other"])): ?>
+        <tr>
+            <td class="bg-white text-secondary font-weight-bold">Other</td>
+            <td colspan="3"><?= @$contentData["other"] ?></td>
+        </tr>
+    <?php endif; ?>
+    </tbody>
+    </thead>
+</table>
+

+ 4 - 4
resources/views/app/patient/partials/mcp-queue.blade.php

@@ -73,7 +73,6 @@
             },
             methods: {
                 refresh: function() {
-                    console.log("Refreshing");
                     let self = this;
                     $.get('/patients-in-queue', function(_data) {
                         self.items = _data;
@@ -100,11 +99,12 @@
             mounted:function(){
                 let self = this;
                 self.refresh();
-                window.setInterval(function(){
-                    self.refresh();
-                }, 60000);
+                // window.setInterval(function(){
+                //     self.refresh();
+                // }, 60000);
                 let socket = new SockJS("{{ config('app.backend_ws_url') }}");
                 self.socketClient = Stomp.over(socket);
+                self.socketClient.debug = function(str) {};
                 self.socketClient.connect({}, (frame) => {
 
                     self.socketClient.send("/app/register", {},     // register self

+ 59 - 11
resources/views/app/practice-management/process-claims.blade.php

@@ -55,15 +55,15 @@
                             <b class="p-2 border-right mr-2 bg-aliceblue" :class="claim.status === 'PICKED_UP' ? 'text-dark' : 'text-secondary'">@{{ claim.created }}</b>
 
                             <span class="text-secondary text-sm mr-1">Patient</span>
-                            <span class="click-to-copy" title="Click to copy">@{{ claim.client }}</span>
+                            <span class="" title="Click to copy">@{{ claim.client }}</span>
 
                             <span class="mx-2 text-secondary">/</span>
                             <span class="text-secondary text-sm mr-1">Pro</span>
-                            <span class="click-to-copy" title="Click to copy">@{{ claim.claim_pro }}</span>
+                            <span class="" title="Click to copy">@{{ claim.claim_pro }}</span>
 
                             <span class="mx-2 text-secondary">/</span>
                             <span class="text-secondary text-sm mr-1">CPT</span>
-                            <span class="click-to-copy" title="Click to copy">@{{ claim.cpts }}</span>
+                            <span class="" title="Click to copy">@{{ claim.cpts }}</span>
 
                             <span class="mx-2 text-secondary">/</span>
                             <span>@{{ claim.icds }} ICDs</span>
@@ -71,7 +71,7 @@
                             <span class="mx-2 text-secondary">/</span>
                             <div class="d-inline-flex align-items-center font-weight-bold text-secondary">
                                 <span class="text-sm mr-1">$</span>
-                                <span class="click-to-copy" title="Click to copy">@{{ claim.expected_total ? claim.expected_total : 0 }}</span>
+                                <span class="" title="Click to copy">@{{ claim.expected_total ? claim.expected_total : 0 }}</span>
                             </div>
                             <div class="ml-auto px-2" v-if="currentClaim && currentClaim.uid === claim.uid">
                                 <button v-if="claim.status !== 'PICKED_UP'"
@@ -101,6 +101,14 @@
                                     <div class="d-flex align-items-center mb-1">
                                         <div class="text-secondary mr-3 min-width-140px">Payer</div>
                                         <b class="text-secondary"><span class="click-to-copy" title="Click to copy">@{{ currentMBClaim.payer_name }}</span></b>
+                                        <div class="ml-auto d-inline-flex align-items-center">
+                                            <textarea class="copy-source opacity-0" v-html="jsonCopySource()"></textarea>
+                                            <button class="btn btn-sm btn-success on-hover-opaque text-sm font-weight-bold"
+                                                    v-on:click.prevent="fastCopy()">
+                                                <i class="fa fa-copy"></i>
+                                                Copy All
+                                            </button>
+                                        </div>
                                     </div>
 
                                     <hr class="my-2">
@@ -215,7 +223,36 @@
                                     <!--cpt, doc, icd-->
                                     <div class="d-flex align-items-start mb-1">
                                         <div class="text-secondary mr-3 min-width-140px">CPT Codes</div>
-                                        <div v-html="currentClaimLines"></div>
+                                        <div>
+                                            <table class="table table-sm table-condensed mb-0 table-bordered">
+                                                <thead>
+                                                <tr class="bg-light">
+                                                    <th class="border-0 width-100px">CPT</th>
+                                                    <th class="border-0 width-100px">Modifier</th>
+                                                    <th class="border-0 width-100px">DOS</th>
+                                                    <th class="border-0 width-100px">Amount</th>
+                                                    <th class="border-0 width-100px">POS</th>
+                                                    <th class="border-0 text-nowrap">ICDs</th>
+                                                </tr>
+                                                </thead>
+                                                <tbody>
+                                                <tr class="claim-line" v-for="(claimLine) in currentClaimLines">
+                                                    <td class="width-100px"><span class="click-to-copy" title="Click to copy">@{{ claimLine.cpt }}</span></td>
+                                                    <td class="text-nowrap width-100px"><span class="click-to-copy" title="Click to copy">95</span></td>
+                                                    <td class="text-nowrap width-100px"><span class="click-to-copy" title="Click to copy">@{{ claimLine.date_of_service }}</span></td>
+                                                    <td class="text-nowrap width-100px">$ <span class="click-to-copy" title="Click to copy">@{{ claimLine.expected_total }}</span></td>
+                                                    <td class="text-nowrap width-100px"><span class="click-to-copy" title="Click to copy">11</span></td>
+                                                    <td class="">
+                                                        <span v-for="(claimLineICD) in claimLine.claim_line_icds"
+                                                              class="c-pointer border-secondary border-bottom mr-2"
+                                                              :title="claimLineICD.description">
+                                                            <span class="click-to-copy" title="Click to copy">@{{ claimLineICD.code }}</span>
+                                                        </span>
+                                                    </td>
+                                                </tr>
+                                                </tbody>
+                                            </table>
+                                        </div>
                                     </div>
                                 </div>
                             </div>
@@ -328,9 +365,9 @@
                                 }
                                 this.currentMBClaim = _data;
                                 this.currentClaim = this.claims[_index];
-                                $.get('/claims/current-claim-lines/' + claim.uid, (_data) => {
+                                $.get('/claims/current-claim-lines/' + claim.uid + '?json=1', (_data) => {
                                     this.currentClaimLines = _data;
-                                });
+                                }, 'json');
                             }, 'json');
                         },
                         updateClaimStatus: function(_index, _status) {
@@ -347,7 +384,7 @@
                                     if(_status === 'SUBMITTED') {
                                         this.resetCurrentClaim();
                                     }
-                                    this.recaclculateNumUnsubmitted();
+                                    this.recalculateNumUnsubmitted();
                                 }
                             }, 'json');
                         },
@@ -373,7 +410,7 @@
                             $.get('{{route('practice-management.process-claims')}}?' + ql, _data => {
                                 this.claims = _data;
                                 this.resetCurrentClaim();
-                                this.recaclculateNumUnsubmitted();
+                                this.recalculateNumUnsubmitted();
                                 hideMask();
                             }, 'json');
                         },
@@ -384,7 +421,7 @@
                             this.filter.hcp = '';
                             this.doFilter();
                         },
-                        recaclculateNumUnsubmitted: function() {
+                        recalculateNumUnsubmitted: function() {
                             let count = 0;
                             if(this.claims && this.claims.length) {
                                 for (let i = 0; i < this.claims.length; i++) {
@@ -395,12 +432,23 @@
                                 }
                             }
                             this.numUnsubmitted = count;
+                        },
+                        jsonCopySource: function() {
+                            if(!this.currentClaim || !this.currentMBClaim || !this.currentClaimLines) return '';
+                            return JSON.stringify({
+                                claim: this.currentClaim,
+                                mbClaim: this.currentMBClaim,
+                                claimLines: this.currentClaimLines
+                            }, null, 2);
+                        },
+                        fastCopy: function() {
+                            copyTextToClipboard($('.copy-source').first().val());
                         }
                     },
                     mounted: function() {
                         let self = this;
                         this.resetCurrentClaim();
-                        this.recaclculateNumUnsubmitted();
+                        this.recalculateNumUnsubmitted();
                         window.setTimeout(() => {
                             $('[pro-suggest-initialized]').removeAttr('pro-suggest-initialized');
                             $('.pro-suggest-input').remove();

+ 1 - 0
resources/views/app/video/call-agora-v2.blade.php

@@ -287,6 +287,7 @@
                     registerSocket: function(_done) {
                         let socket = new SockJS(this.backendWsURL);
                         this.socketClient = Stomp.over(socket);
+                        this.socketClient.debug = function(str) {};
                         this.socketClient.connect({}, (frame) => {
                             console.log('Connected: ' + frame);
                             this.initSocketListeners();                     // init listeners

+ 1 - 0
resources/views/app/video/call-minimal-ws.blade.php

@@ -390,6 +390,7 @@
                 registerSocket: function (_done) {
                     let socket = new SockJS(this.backendWsURL);
                     this.socketClient = Stomp.over(socket);
+                    this.socketClient.debug = function(str) {};
                     this.socketClient.connect({}, (frame) => {
                         console.log('Connected: ' + frame);
                         this.initSocketListeners();                     // init listeners

+ 1 - 0
resources/views/app/video/call-minimal.blade.php

@@ -204,6 +204,7 @@
             registerSocket: function (_done) {
                 let socket = new SockJS(this.backendWsURL);
                 this.socketClient = Stomp.over(socket);
+                this.socketClient.debug = function(str) {};
                 this.socketClient.connect({}, (frame) => {
                     this.socketClient.send("/app/register", {},
                         JSON.stringify({

+ 1 - 0
resources/views/app/video/check-video-minimal.blade.php

@@ -206,6 +206,7 @@
             registerSocket: function (_done) {
                 let socket = new SockJS(this.backendWsURL);
                 this.socketClient = Stomp.over(socket);
+                this.socketClient.debug = function(str) {};
                 this.socketClient.connect({}, (frame) => {
                     this.socketClient.send("/app/register", {},
                         JSON.stringify({

+ 1 - 0
resources/views/layouts/template-no-mc.blade.php

@@ -313,6 +313,7 @@
     @include('app/pdf/viewer')
     <script>
         window.socketClient = Stomp.over(new SockJS("{{ config('app.backend_ws_url') }}"));
+        window.socketClient.debug = function(str) {};
         window.socketClient.connect({}, (frame) => {
 
             window.socketClient.send("/app/register", {},     // register self

+ 1 - 1
resources/views/layouts/template.blade.php

@@ -328,7 +328,7 @@
     @if(config('app.enableSockets'))
     <script>
         window.socketClient = Stomp.over(new SockJS("{{ config('app.backend_ws_url') }}"));
-        //TODO: disable logging
+        window.socketClient.debug = function(str) {};
         window.socketClient.connect({}, (frame) => {
 
             window.socketClient.send("/app/register", {},     // register self