瀏覽代碼

updated master on server

root 3 年之前
父節點
當前提交
4f91de84c2
共有 60 個文件被更改,包括 2892 次插入1426 次删除
  1. 16 9
      app/Helpers/fdb.php
  2. 4 2
      app/Http/Controllers/AppointmentController.php
  3. 2 2
      app/Http/Controllers/DnaController.php
  4. 37 24
      app/Http/Controllers/HomeController.php
  5. 34 2
      app/Http/Controllers/McpController.php
  6. 10 0
      app/Http/Controllers/PatientController.php
  7. 38 0
      app/Http/Controllers/PracticeManagementController.php
  8. 5 0
      app/Models/ClientMemo.php
  9. 56 11
      app/Models/Pro.php
  10. 3 1
      public/css/style.css
  11. 1 1
      public/css/z.css
  12. 7 0
      public/js/stag-suggest.js
  13. 213 677
      resources/views/app/dashboard-dna.blade.php
  14. 915 0
      resources/views/app/dashboard-dna_old.blade.php
  15. 3 3
      resources/views/app/dashboard-mcp.blade.php
  16. 57 0
      resources/views/app/dna/dashboard/measurements-pending-stamping.blade.php
  17. 85 0
      resources/views/app/mcp/clients_bdt_devices.blade.php
  18. 107 0
      resources/views/app/mcp/clients_bdt_devices_filters.blade.php
  19. 127 93
      resources/views/app/mcp/dashboard/appointments-list.blade.php
  20. 10 3
      resources/views/app/mcp/dashboard/calls_memos.blade.php
  21. 9 13
      resources/views/app/mcp/dashboard/measurements-pending-stamping.blade.php
  22. 7 2
      resources/views/app/mcp/dashboard/messages.blade.php
  23. 95 0
      resources/views/app/mcp/memos.blade.php
  24. 110 0
      resources/views/app/mcp/memos_filters.blade.php
  25. 10 1
      resources/views/app/mcp/patients-table.blade.php
  26. 189 361
      resources/views/app/patient/canvas-migrate.blade.php
  27. 28 0
      resources/views/app/patient/memos-thread.blade.php
  28. 32 0
      resources/views/app/patient/messages-thread.blade.php
  29. 0 7
      resources/views/app/patient/note/dashboard.blade.php
  30. 39 47
      resources/views/app/patient/note/rhs-sidebar.blade.php
  31. 4 4
      resources/views/app/patient/note/segment_script.blade.php
  32. 4 9
      resources/views/app/patient/partials/appointments.blade.php
  33. 1 1
      resources/views/app/patient/point-based-partials/allergies.blade.php
  34. 1 1
      resources/views/app/patient/point-based-partials/care-team.blade.php
  35. 1 1
      resources/views/app/patient/point-based-partials/dx.blade.php
  36. 1 1
      resources/views/app/patient/point-based-partials/fhx.blade.php
  37. 1 1
      resources/views/app/patient/point-based-partials/pmhx.blade.php
  38. 1 1
      resources/views/app/patient/point-based-partials/rx.blade.php
  39. 1 1
      resources/views/app/patient/point-based-partials/shx.blade.php
  40. 1 1
      resources/views/app/patient/point-based-partials/sochx.blade.php
  41. 1 1
      resources/views/app/patient/problems-center.blade.php
  42. 1 1
      resources/views/app/patient/segment-templates/_custom_items/edit.blade.php
  43. 55 0
      resources/views/app/patient/segment-templates/_custom_items/script.blade.php
  44. 8 2
      resources/views/app/patient/segment-templates/_simple_text_segment/edit.php
  45. 8 2
      resources/views/app/patient/segment-templates/chief_complaint/edit.blade.php
  46. 17 4
      resources/views/app/patient/segment-templates/history_family/edit.blade.php
  47. 17 4
      resources/views/app/patient/segment-templates/history_screenings/edit.blade.php
  48. 21 36
      resources/views/app/patient/segment-templates/history_social/edit.blade.php
  49. 21 36
      resources/views/app/patient/segment-templates/history_surgical/edit.blade.php
  50. 21 36
      resources/views/app/patient/segment-templates/past_medical_history/edit.blade.php
  51. 8 2
      resources/views/app/patient/segment-templates/vitals/edit.blade.php
  52. 9 4
      resources/views/app/patient/wizard-partials/common-script.blade.php
  53. 90 0
      resources/views/app/practice-management/clients_bdt_devices.blade.php
  54. 107 0
      resources/views/app/practice-management/clients_bdt_devices_filters.blade.php
  55. 100 0
      resources/views/app/practice-management/memos.blade.php
  56. 110 0
      resources/views/app/practice-management/memos_filters.blade.php
  57. 1 1
      resources/views/app/practice-management/remote-monitoring-report.blade.php
  58. 21 15
      resources/views/layouts/patient.blade.php
  59. 4 1
      resources/views/layouts/template.blade.php
  60. 7 1
      routes/web.php

+ 16 - 9
app/Helpers/fdb.php

@@ -328,8 +328,8 @@ if(!function_exists('drug_drug_interaction_info_with_pivot')) {
 
         $output = [];
 
-        for ($i=0; $i<count($_drugs); $i++) {
-            $output[] = drugDrugInteractionSinglePair($_pivot, $_drugs[$i]);
+        foreach ($_drugs as $drug) {
+            $output[] = drugDrugInteractionSinglePair($_pivot, $drug);
         }
 
         $output = array_filter($output, function($_x) {
@@ -514,11 +514,18 @@ if(!function_exists('duplicate_therapy_info')) {
 
         $leftIndex = 0;
         $matches = [];
-        for ($i = $leftIndex; $i < count($_drugs) - 1; $i++) {
-            for ($j = $i + 1; $j < count($_drugs); $j++) {
-                $compareResult = compareDPTs($_drugs[$i]->dpt, $_drugs[$j]->dpt);
+
+        // convert to simple array
+        $drugsArray = [];
+        foreach ($_drugs as $drug) {
+            $drugsArray[] = $drug;
+        }
+
+        for ($i = $leftIndex; $i < count($drugsArray) - 1; $i++) {
+            for ($j = $i + 1; $j < count($drugsArray); $j++) {
+                $compareResult = compareDPTs($drugsArray[$i]->dpt, $drugsArray[$j]->dpt);
                 foreach ($compareResult as $c) {
-                    $matches[] = "<b>{$_drugs[$i]->data->name}</b> and <b>{$_drugs[$j]->data->name}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
+                    $matches[] = "<b>{$drugsArray[$i]->data->name}</b> and <b>{$drugsArray[$j]->data->name}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
                 }
             }
         }
@@ -545,10 +552,10 @@ if(!function_exists('duplicate_therapy_info_with_pivot')) {
 
         $leftIndex = 0;
         $matches = [];
-        for ($i = 0; $i < count($_drugs); $i++) {
-            $compareResult = compareDPTs($_pivot->dpt, $_drugs[$i]->dpt);
+        foreach ($_drugs as $drug) {
+            $compareResult = compareDPTs($_pivot->dpt, $drug->dpt);
             foreach ($compareResult as $c) {
-                $matches[] = "<b>{$_pivot->data->name}</b> and <b>{$_drugs[$i]->data->name}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
+                $matches[] = "<b>{$_pivot->data->name}</b> and <b>{$drug->data->name}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
             }
         }
 

+ 4 - 2
app/Http/Controllers/AppointmentController.php

@@ -66,9 +66,11 @@ class AppointmentController extends Controller
                         ->orWhere('client_id', '=', $clientId)
                         ->orWhereRaw('client_id IN (SELECT shadow_client_id FROM pro WHERE id IN (' . implode(',', $proIds) . '))');
                 });
+            $appointments = $appointments->get();
+        }
+        else {
+            $appointments = [];
         }
-
-        $appointments = $appointments->get();
 
         $events = [];
         foreach ($appointments as $appointment) {

+ 2 - 2
app/Http/Controllers/DnaController.php

@@ -84,12 +84,12 @@ class DnaController extends Controller
         return view('app.dna.patients', compact('patients', 'filters'));
     }
 
-    private function filterSimpleQuery(Request $request, $query, $columnName, $valueName) {
+    public function filterSimpleQuery(Request $request, $query, $columnName, $valueName) {
         if($request->input($valueName)) {
             $query->where($columnName, $request->input($valueName));
         }
     }
-    private function filterMultiQuery(Request $request, $query, $columnName, $keyName, $valueName1, $valueName2) {
+    public function filterMultiQuery(Request $request, $query, $columnName, $keyName, $valueName1, $valueName2) {
         switch($request->input($keyName)) {
             case 'EXACTLY':
                 if($request->input($valueName1)) {

+ 37 - 24
app/Http/Controllers/HomeController.php

@@ -572,31 +572,13 @@ WHERE cl.shadow_pro_id IS NULL
     }
 
     private function dashboard_DNA(Request $request){
-        $performer = $this->performer();
-        $pro = $performer->pro;
-
-        $keyNumbers = [];
-
-        // Patients // SELECT * FROM client WHERE mcp_pro_id = :me.id;
-        // New Patients Awaiting Visit // SELECT * FROM client WHERE mcp_pro_id = :me.id AND hasMcpDoneOnboardingVisit != 'YES';
-        // Notes Pending Signature // SELECT * FROM note WHERE hcp_pro_id = :me.id AND is_cancelled IS NOT TRUE AND has_hcp_signed IS NOT TRUE;
-        // Notes Pending Billing // SELECT * FROM note WHERE hcp_pro_id = :me.id AND is_cancelled IS NOT TRUE AND has_hcp_signed IS TRUE AND is_billing_marked_done IS FALSE;
-        // Reports Pending Signature // SELECT * FROM incoming_report WHERE hcp_pro_id = :me.id AND isEntryError IS NOT TRUE AND hasHcpProSigned IS NOT TRUE;
-        // Patients w/o Appointments // SELECT * FROM client WHERE mcp_pro_id = :me.id AND client.next_mcp_appointment_date < today();
-        // Patients Overdue for Visit // SELECT * FROM client WHERE mcp_pro_id = :me.id AND client.next_expected_mcp_visit_date < today();
-        // Cancelled Appts. Pending Review // SELECT * FROM appointment WHERE hcp_pro_id = :me.id AND status = 'REJECTED' AND wasAcknowledgedByAppointmentPro IS NOT TRUE;
-        // Cancelled Bills Pending Review // SELECT * FROM bill WHERE bill_service_type = 'NOTE' AND is_cancelled IS TRUE AND isCancellationAcknowledged IS FALSE;
-        // Cancelled Supply Orders Pending Review // SELECT * FROM supply_order WHERE signed_by_pro_id = :me.id AND is_cancelled IS TRUE AND isCancellationAcknowledged IS NOT TRUE;
-        // ERx & Orders Pending Signature // SELECT * FROM erx WHERE hcp_pro_id = :me.id AND pro_declared_status <> 'CANCELLED' AND hasHcpProSigned IS NOT TRUE;
-        // Supply Orders Pending Signature // SELECT supply_order.id FROM supply_order WHERE signed_by_pro_id IS NOT TRUE AND is_cancelled IS NOT TRUE AND created_by_pro_id = :me.id;
-
         $performer = $this->performer();
         $pro = $performer->pro;
         $performerProID = $performer->pro->id;
 
         $keyNumbers  = [];
 
-        $queryClients = $this->performer()->pro->getAccessibleClientsQuery();
+        $queryClients = $pro->getAccessibleClientsQuery();
         $keyNumbers['patients'] = $queryClients->count();
 
         $pendingNotesToSign = Note::where('ally_pro_id', $performerProID)->where('is_signed_by_ally', false)->where('is_cancelled', false)->where('is_core_note', false)->count();
@@ -606,10 +588,10 @@ WHERE cl.shadow_pro_id IS NULL
         $pendingNotesToSignMCP = Note::where('ally_pro_id', $performerProID)->where('is_signed_by_hcp', false)->where('is_cancelled', false)->where('is_core_note', false)->count();
         $keyNumbers['$pendingNotesToSignMCP'] = $pendingNotesToSignMCP;
 
-        $pendingNotesToSignAllySigned = Note::where(function ($query) use ($performerProID) {
-            $query->where('hcp_pro_id', $performerProID)->where('is_signed_by_hcp', false)->where('is_signed_by_ally', true)->where('is_cancelled', false)->where('is_core_note', false);
+        $pendingNotesToSignAlly = Note::where(function ($query) use ($performerProID) {
+            $query->where('ally_pro_id', $performerProID)->where('is_signed_by_ally', false)->where('is_cancelled', false)->where('is_core_note', false);
         })->count();
-        $keyNumbers['pendingNotesToSignAllySigned'] = $pendingNotesToSignAllySigned;
+        $keyNumbers['$pendingNotesToSignAlly'] = $pendingNotesToSignAlly;
 
 
         $signedNotesWithoutBills = Note::where(function ($query) use ($performerProID) {
@@ -887,13 +869,44 @@ WHERE cl.shadow_pro_id IS NULL
 
         }
 
+        $incomingSmsMessagesPendingReply = DB::select("
+            SELECT cs.* ,c.uid as client_uid, c.name_first as client_name_first, c.name_last as client_name_last FROM client_sms cs LEFT JOIN client c ON c.id = cs.client_id
+            WHERE cs.is_reply_needed = 'YES' AND c.mcp_pro_id = :mcp_pro_id AND incoming_or_outgoing = 'INCOMING'
+            AND (cs.created_at > c.last_sms_sent_to_client_at OR c.last_sms_sent_to_client_at IS NULL)
+            ORDER BY created_at DESC
+        ", ['mcp_pro_id' => $performer->pro->id]);
+
+        $careMonthsWithMeasurementsPendingStamping = CareMonth::select('id')
+            ->where('mcp_pro_id', $this->performer->pro->id)
+            ->where('rm_num_measurements_not_stamped_by_mcp', '>', 0)
+            ->whereNotNull('rm_num_measurements_not_stamped_by_mcp')
+            ->orderBy('created_at', 'DESC')
+            ->get()
+            ->map(function($_x) {
+                return $_x->id;
+            })
+            ->toArray();
+
+        $measurementsPendingStamping = Measurement::whereIn('care_month_id', $careMonthsWithMeasurementsPendingStamping)
+            ->orderBy('created_at', 'DESC')
+            ->whereNotNull('ts')
+            ->whereNotIn('label', ['SBP', 'DBP'])
+            ->where('is_cellular_zero', '<>', true)
+            ->where('is_removed', false)
+            ->where('has_been_stamped_by_mcp', false)
+            ->whereNotNull('client_bdt_measurement_id')
+            ->whereHas('client', function($clientQuery) use ($performerProID){
+               return $clientQuery->where('default_na_pro_id', $performerProID);
+            })
+            ->paginate(15);
+
 
         return view('app/dashboard-dna', compact('keyNumbers', 'reimbursement', 'milliseconds',
             'businessNumbers',
             'incomingReports', 'tickets', 'supplyOrders',
             'numERx', 'numLabs', 'numImaging', 'numSupplyOrders',
             'newMCPAssociations', 'newNAAssociations',
-            'mcpClientMemos', 'naClientMemos'));
+            'mcpClientMemos', 'naClientMemos', 'measurementsPendingStamping', 'careMonthsWithMeasurementsPendingStamping', 'incomingSmsMessagesPendingReply'));
     }
 
     private function dashboard_ADMIN(Request $request){
@@ -1412,7 +1425,7 @@ WHERE measurement.label NOT IN ('SBP', 'DBP')
         }
 
         $appointments = $appointments
-            
+
 	    // ->whereRaw('status NOT IN (\'CANCELLED\', \'COMPLETED\')')
             ->orderBy('start_time', 'asc')
             ->get();

+ 34 - 2
app/Http/Controllers/McpController.php

@@ -29,7 +29,7 @@ use Illuminate\Support\Facades\File;
 use App\Models\Bill;
 use App\Models\ClientSMS;
 use App\Models\AccountInvite;
-
+use App\Models\ClientMemo;
 use Illuminate\Support\Facades\Http;
 use PDF;
 
@@ -77,7 +77,7 @@ class McpController extends Controller
 
         $this->filterMultiQuery($request, $patients, 'age_in_years', 'age_category', 'age_value_1', 'age_value_2');
         $this->filterSimpleQuery($request, $patients, 'sex', 'sex');
-        $this->filterMultiQuery($request, $patients, 'usual_bmi', 'bmi_category', 'bmi_value_1', 'bmi_value_2');
+        $this->filterMultiQuery($request, $patients, 'usual_bmi_max', 'bmi_category', 'bmi_value_1', 'bmi_value_2');
         $this->filterMultiQuery($request, $patients, 'most_recent_weight_at', 'last_weighed_in_category', 'last_weighed_in_value_1', 'last_weighed_in_value_2');
         $this->filterMultiQuery($request, $patients, 'most_recent_bp_at', 'last_bp_category', 'last_bp_value_1', 'last_bp_value_2');
 
@@ -134,6 +134,38 @@ class McpController extends Controller
         return view('app.mcp.bills', compact('bills', 'filters'));
     }
 
+    public function clients_bdt_devices(Request $request){
+        $filters = $request->all();
+        
+        $devices = ClientBDTDevice::select('client_bdt_device.*')
+        ->join('client', 'client.id', '=', 'client_bdt_device.client_id')
+        ->where('client.mcp_pro_id', $this->performer->pro->id);
+
+        $this->filterMultiQuery($request, $devices, 'client_bdt_device.created_at', 'date_category', 'date_value_1', 'date_value_2');
+        $status = $request->get('status');
+        if($status){
+            if($status === 'ACTIVE') $devices = $devices->where('client_bdt_device.is_active', true);
+            if($status === 'DEACTIVATED') $devices = $devices->where('client_bdt_device.is_active', false);
+        }
+        $devices = $devices->orderBy('created_at', 'DESC')->paginate(20);
+
+        return view('app.mcp.clients_bdt_devices', compact('devices', 'filters'));
+    }
+
+    public function memos(Request $request){
+        $filters = $request->all();
+        
+        $memos = ClientMemo::select('client_memo.*')
+        ->join('client', 'client.id', '=', 'client_memo.client_id')
+        ->where('client.mcp_pro_id', $this->performer->pro->id);
+
+        $this->filterMultiQuery($request, $memos, 'client_memo.created_at', 'date_category', 'date_value_1', 'date_value_2');
+        $this->filterSimpleQuery($request, $memos, 'category', 'category');
+        $memos = $memos->orderBy('created_at', 'DESC')->paginate(20);
+
+        return view('app.mcp.memos', compact('memos', 'filters'));
+    }
+
     public function erx_and_orders(Request $request)
     {
         $filters = $request->all();

+ 10 - 0
app/Http/Controllers/PatientController.php

@@ -267,6 +267,16 @@ class PatientController extends Controller
         return view('app.patient.memos', compact('patient'));
     }
 
+    public function memosThread(Request $request, Client $patient )
+    {
+        return view('app.patient.memos-thread', compact('patient'));
+    }
+
+    public function messagesThread(Request $request, Client $patient )
+    {
+        return view('app.patient.messages-thread', compact('patient'));
+    }
+
     public function sms(Request $request, Client $patient )
     {
         return view('app.patient.sms', compact('patient'));

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

@@ -34,6 +34,8 @@ use App\Models\Team;
 use App\Models\Ticket;
 use App\Models\AccountInvite;
 use App\Models\ClientMeasurementDaysPerMonth;
+use App\Models\ClientBDTDevice;
+use App\Models\ClientMemo;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Http;
 use PDF;
@@ -2021,6 +2023,42 @@ ORDER BY c.name_last, c.name_first
         return view('app.practice-management.patients-accounts-invites', compact('accountInvites','filters'));
     }
 
+    public function clientsBdtDevices(Request $request){
+        $filters = $request->all();
+        
+        $devices = ClientBDTDevice::select('client_bdt_device.*')
+        ->join('client', 'client.id', '=', 'client_bdt_device.client_id');
+
+        if($this->performer->pro->pro_type !== 'ADMIN'){
+            $devices = $devices->where('client.mcp_pro_id', $this->performer->pro->id);
+        }
+
+        $this->filterMultiQuery($request, $devices, 'client_bdt_device.created_at', 'date_category', 'date_value_1', 'date_value_2');
+        $status = $request->get('status');
+        if($status){
+            if($status === 'ACTIVE') $devices = $devices->where('client_bdt_device.is_active', true);
+            if($status === 'DEACTIVATED') $devices = $devices->where('client_bdt_device.is_active', false);
+        }
+        $devices = $devices->orderBy('created_at', 'DESC')->paginate(20);
+        return view('app.practice-management.clients_bdt_devices', compact('devices','filters'));
+    }
+
+    public function memos(Request $request){
+        $filters = $request->all();
+        
+        $memos = ClientMemo::select('client_memo.*')
+        ->join('client', 'client.id', '=', 'client_memo.client_id');
+
+        if($this->performer->pro->pro_type !== 'ADMIN'){
+            $memos = $memos->where('client.mcp_pro_id', $this->performer->pro->id);
+        }
+
+        $this->filterMultiQuery($request, $memos, 'client_memo.created_at', 'date_category', 'date_value_1', 'date_value_2');
+        $this->filterSimpleQuery($request, $memos, 'category', 'category');
+        $memos = $memos->orderBy('created_at', 'DESC')->paginate(20);
+
+        return view('app.practice-management.memos', compact('memos', 'filters'));
+    }
 
     
 

+ 5 - 0
app/Models/ClientMemo.php

@@ -14,6 +14,11 @@ class ClientMemo extends Model
         return $this->hasOne(AppSession::class, 'id', 'created_by_session_id');
     }
 
+    public function client(): HasOne
+    {
+        return $this->hasOne(Client::class, 'id', 'client_id');
+    }
+
     public function updates(): HasMany{
         return $this->hasMany(ClientMemoUpdate::class, 'client_memo_id', 'id')->orderBy('created_at', 'DESC');
     }

+ 56 - 11
app/Models/Pro.php

@@ -380,6 +380,25 @@ class Pro extends Model
             ->count();
     }
 
+    function get_notes_pending_billing_count_as_dna() {
+        return Note::where('ally_pro_id', $this->id)
+            ->where('is_cancelled', '<>', true)
+            ->where('is_signed_by_hcp', true)
+            ->where('is_billing_marked_done', '<>', true)
+            ->count();
+    }
+
+    function get_measurements_awaiting_review_count_as_mcp() {
+        $result = DB::select(DB::raw("
+SELECT SUM(rm_num_measurements_not_stamped_by_mcp) AS count
+FROM care_month
+WHERE mcp_pro_id = :pro_id
+  AND rm_num_measurements_not_stamped_by_mcp IS NOT NULL
+  AND rm_num_measurements_not_stamped_by_mcp > 0;
+        "), ["pro_id" => $this->id]);
+        if($result) return $result[0]->count;
+    }
+
     function get_bills_pending_signature_count_as_mcp(){
         return;
         $pendingBillsToSign = Bill::where('bill_service_type', '<>', 'CARE_MONTH')->where(function ($query) use ($performerProID) {
@@ -396,17 +415,6 @@ class Pro extends Model
         $keyNumbers['pendingBillsToSign'] = $pendingBillsToSign;
     }
 
-    function get_measurements_awaiting_review_count_as_mcp() {
-        $result = DB::select(DB::raw("
-SELECT SUM(rm_num_measurements_not_stamped_by_mcp) AS count
-FROM care_month
-WHERE mcp_pro_id = :pro_id
-  AND rm_num_measurements_not_stamped_by_mcp IS NOT NULL
-  AND rm_num_measurements_not_stamped_by_mcp > 0;
-        "), ["pro_id" => $this->id]);
-        if($result) return $result[0]->count;
-    }
-
     function get_incoming_reports_pending_signature_count_as_mcp() {
         return IncomingReport::where('hcp_pro_id', $this->id)
             ->where('has_hcp_pro_signed', '<>', true)
@@ -423,10 +431,23 @@ WHERE mcp_pro_id = :pro_id
                     });
     }
 
+    function get_patients_without_appointment_for_dna_query() {
+        return Client::where('default_na_pro_id', $this->id)
+            ->whereNull('today_mcp_appointment_date')
+            ->where(function($q){
+                $q->whereNull('next_mcp_appointment_id')
+                    ->orWhere('next_mcp_appointment_date', '<=', DB::raw('NOW()::DATE'));
+            });
+    }
+
     function get_patients_without_appointment_count_as_mcp() {
         return $this->get_patients_without_appointment_query()->count();
     }
 
+    function get_patients_without_appointment_count_as_dna() {
+        return $this->get_patients_without_appointment_for_dna_query()->count();
+    }
+
     function get_patients_overdue_for_visit_query() {
         return Client::where('mcp_pro_id', $this->id)
                     ->where(function($q){
@@ -435,13 +456,28 @@ WHERE mcp_pro_id = :pro_id
                     });
     }
 
+    function get_patients_overdue_for_visit_for_dna_query() {
+        return Client::where('default_na_pro_id', $this->id)
+            ->where(function($q){
+                $q->whereNull('most_recent_completed_mcp_note_id')
+                    ->orWhere('most_recent_completed_mcp_note_date', '<', DB::raw("NOW()::DATE - INTERVAL '45 DAY'"));
+            });
+    }
+
     function get_patients_overdue_count_as_mcp() {
         return $this->get_patients_overdue_for_visit_query()->count();
     }
 
+    function get_patients_overdue_count_as_dna() {
+        return $this->get_patients_overdue_for_visit_for_dna_query()->count();
+    }
+
     function get_patients_without_remote_measurement_in_48_hours_count_as_mcp() {
     }
 
+    function get_patients_without_remote_measurement_in_48_hours_count_as_dna() {
+    }
+
     function get_cancelled_appointments_pending_acknowledgement_count_as_mcp_query() {
         // SELECT * FROM appointment WHERE hcp_pro_id = :me.id AND status = 'REJECTED' AND wasAcknowledgedByAppointmentPro IS NOT TRUE;
         return Appointment::where('pro_id', $this->id)
@@ -462,6 +498,15 @@ WHERE mcp_pro_id = :pro_id
             ->count();
     }
 
+    function get_cancelled_bills_awaiting_review_count_as_dna() {
+        // SELECT * FROM bill WHERE bill_service_type = 'NOTE' AND is_cancelled IS TRUE AND isCancellationAcknowledged IS FALSE;
+        return Bill::where('na_pro_id', $this->id)
+            ->where('bill_service_type', 'NOTE')
+            ->where('is_cancelled', true)
+            ->where('is_cancellation_acknowledged', '<>', true)
+            ->count();
+    }
+
     function get_cancelled_supply_orders_awaiting_review_count_as_mcp() {
         // SELECT * FROM supply_order WHERE signed_by_pro_id = :me.id AND is_cancelled IS TRUE AND isCancellationAcknowledged IS NOT TRUE;
         return SupplyOrder::where('signed_by_pro_id', $this->id)

+ 3 - 1
public/css/style.css

@@ -180,6 +180,9 @@ body.stag_rhs_collapsed .app-right-panel {
 .mcp-theme-1 .on-hover-opaque:hover {
     opacity: 1;
 }
+.mcp-theme-1 .on-hover-aliceblue:hover {
+    background: aliceblue;
+}
 .mcp-theme-1 .opacity-0 {
     opacity: 0 !important;
 }
@@ -2177,7 +2180,6 @@ body.in-iframe .main-row > .sidebar {
     max-width: 180px;
     align-self: stretch;
     border-right: 1px solid #ddd;
-    padding-top: 0.85rem;
     height: 300px;
     overflow: hidden;
     max-height: calc(100vh - 55px);

+ 1 - 1
public/css/z.css

@@ -55,7 +55,7 @@
     --size: 25px;
     align-items: center;
     background: #ccc;
-    box-shadow: 0 0 20px var(--shadow-color);
+    box-shadow: 0 0 6px var(--shadow-color);
     border-radius: 50%;
     display: flex;
     flex-shrink: 0;

+ 7 - 0
public/js/stag-suggest.js

@@ -158,6 +158,13 @@
                     suggestionsOuter = $(this).next('.stag-suggestions-container').find('>.suggestions-outer');
                     return handleKeydown($(this), e);
                 })
+                .off('paste.stag-suggest')
+                .on('paste.stag-suggest', function (e) {
+                    window.setTimeout(() => {
+                        suggestionsOuter = $(this).next('.stag-suggestions-container').find('>.suggestions-outer');
+                        return handleKeypress($(this), e);
+                    }, 100);
+                })
                 .off('keypress.stag-suggest')
                 .on('keypress.stag-suggest', function (e) {
                     suggestionsOuter = $(this).next('.stag-suggestions-container').find('>.suggestions-outer');

文件差異過大導致無法顯示
+ 213 - 677
resources/views/app/dashboard-dna.blade.php


+ 915 - 0
resources/views/app/dashboard-dna_old.blade.php

@@ -0,0 +1,915 @@
+@extends ('layouts.template')
+
+@section('content')
+
+    <style>
+        tr.thin th, tr.thin td {
+            padding: 0.25em;
+        }
+    </style>
+
+    <div class="p-3">
+        <div class="">
+            <div class="row mcp-theme-1" id="pro-dashboard-container" v-cloak>
+                <div class="col-md-3 mcp-theme-1">
+                    <div class="mb-4" v-show="tab==='appointments'">
+                        <div class="pro-dashboard-inline-calendar"></div>
+                    </div>
+                    <div class="card mb-4">
+                        <div class="card-header pl-2">
+                            <strong>
+                                Key Numbers
+                            </strong>
+                        </div>
+                        <div class="card-body p-0">
+                            <table class="table mb-0 dashboard-stats-table">
+                                <tbody>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_patients_count_as_dna()}}</th>
+                                    <th class="pl-2">Patients</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_new_patients_awaiting_visit_count_as_mcp()}}</th>
+                                    <th class="pl-2">New Patients Awaiting Visit</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_notes_pending_signature_count_as_dna()}}</th>
+                                    <th class="pl-2">Notes Pending Signature</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_notes_pending_billing_count_as_mcp()}}</th>
+                                    <th class="pl-2">Notes Pending Billing</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_incoming_reports_pending_signature_count_as_mcp()}}</th>
+                                    <th class="pl-2">Reports Pending Signature</th>
+                                </tr>
+
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_patients_without_appointment_count_as_mcp()}}</th>
+                                    <th class="pl-2">Patients w/o Appointments</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_patients_not_seen_in_45_days_count_as_mcp()}}</th>
+                                    <th class="pl-2">Patients Not Seen in 45 Days</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_cancelled_appointments_pending_acknowledgement_count_as_mcp()}}</th>
+                                    <th class="pl-2">Cancelled Appts. Pending Review</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_cancelled_bills_awaiting_review_count_as_mcp()}}</th>
+                                    <th class="pl-2">Cancelled Bills Pending Review</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_cancelled_supply_orders_awaiting_review_count_as_mcp()}}</th>
+                                    <th class="pl-2">Cancelled Supply Orders</th>
+                                </tr>
+
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_erx_and_orders_awaiting_signature_count_as_mcp()}}</th>
+                                    <th class="pl-2">ERx & Orders Pending Signature</th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_supply_orders_awaiting_signature_count_as_mcp()}}</th>
+                                    <th class="pl-2">Supply Orders Pending Signature</th>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                    <div class="card mb-4">
+                        <div class="card-header pl-2">
+                            <strong>
+                                Remote Monitoring: {{friendly_month(date('Y-m-d'))}}
+                            </strong>
+                        </div>
+                        <div class="card-body p-0">
+                            <table class="table mb-0 dashboard-stats-table">
+                                <tbody>
+                                
+                                <tr>
+                                    <th class="px-2 text-center">{{$pro->get_patients_without_remote_measurement_in_48_hours_count_as_mcp() ?? '-'}}</th>
+                                    <th class="pl-2">Patients w/o Measurement in 48 hrs.</th>
+                                </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                    <div class="card mb-4">
+                        <div class="card-header pl-2">
+                            <strong>
+                                Practice Management
+                            </strong>
+                        </div>
+                        <div class="card-body p-0">
+                            <table class="table mb-0 dashboard-stats-table">
+                                <tbody>
+                                <tr>
+                                    <th colspan="2">Revenue Cycle Management</th>
+                                </tr>
+                                <tr class="thin">
+                                    <th class="font-weight-normal px-2 pl-4">
+                                        ${{friendly_money($reimbursement['currentBalance'])}}</th>
+                                    <th class="font-weight-normal pl-2 w-100"><a
+                                            href="/practice-management/financial-transactions">Current balance</a></th>
+                                </tr>
+                                <!-- <tr>
+                                    <th class="px-2">{{friendly_date_time($reimbursement['nextPaymentDate'], false)}}</th>
+                                    <th class="pl-2">Next Payment Date</th>
+                                </tr> -->
+                                <tr class="thin">
+                                    <th class="font-weight-normal px-2 pl-4">${{friendly_money($reimbursement['nextPaymentAmount'])}}</th>
+                                    <th class="font-weight-normal pl-2"><a
+                                            href="/practice-management/bills-under-processing">Processing</a></th>
+                                </tr>
+                                <!-- <tr class="thin">
+                                    <th class="font-weight-normal px-2 pl-5">${{friendly_money($reimbursement['nextPaymentAmount'])}}</th>
+                                    <th class="font-weight-normal pl-2"><a
+                                            href="/practice-management/bills-under-processing">Treatment Services</a></th>
+                                </tr>
+                                <tr class="thin">
+                                    <th class="font-weight-normal px-2 pl-5">${{friendly_money($reimbursement['nextPaymentAmount'])}}</th>
+                                    <th class="font-weight-normal pl-2"><a
+                                            href="/practice-management/bills-under-processing">Remote Monitoring</a></th>
+                                </tr>
+                                <tr class="thin">
+                                    <th class="font-weight-normal px-2 pl-5">${{friendly_money($reimbursement['nextPaymentAmount'])}}</th>
+                                    <th class="font-weight-normal pl-2"><a
+                                            href="/practice-management/bills-under-processing">Other Services</a></th>
+                                </tr> -->
+                                {{--
+                                <tr>
+                                    <th class="px-2">{{$reimbursement['lastPayment']}}</th>
+                                    <th class="pl-2"><a href="/practice-management/financial-transactions">Last payment</a></th>
+                                </tr>
+                                <tr>
+                                    <th class="px-2">{{friendly_date_time($reimbursement['lastPaymentDate'], false)}}</th>
+                                    <th class="pl-2"><a href="/practice-management/financial-transactions">Last payment date</a></th>
+                                </tr>
+                                --}}
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                    @if($pro->pro_type === 'ADMIN')
+                        <div class="card mb-4">
+                            <div class="card-header pl-2">
+                                <strong>
+                                    Bills &amp; Claims
+                                </strong>
+                            </div>
+                            <div class="card-body p-0">
+                                <table class="table mb-0 dashboard-stats-table">
+                                    <tbody>
+
+                                    <tr>
+                                        <th class="border-top-1 px-2 text-center">{{$businessNumbers['notesWithBillsToResolve']}}</th>
+                                        <th class="border-top-1 pl-2">
+                                            <a href="/practice-management/billing-manager">Notes with bills to
+                                                resolve</a>
+                                        </th>
+                                    </tr>
+                                    <tr>
+                                        <th class="border-top-1 px-2 text-center">{{$businessNumbers['notesPendingBillingClosure']}}</th>
+                                        <th class="border-top-1 pl-2">
+                                            <a href="/practice-management/billing-manager">Notes pending billing
+                                                closure</a>
+                                        </th>
+                                    </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    @endif
+                </div>
+                <div class="col-md-9">
+
+                    <div class="row">
+                        <div class="col-6">
+
+                        <!-- new associations -->
+                            @if(count($newMCPAssociations))
+                                <div class="mb-3 border rounded px-3 py-2 ack-container">
+                                    <p class="pt-1 mb-2"><b>New Patients</b></p>
+                                    @foreach($newMCPAssociations as $assoc)
+                                        <div class="d-flex align-items-start bg-light mb-2 px-2 py-1">
+                                            <div class="flex-grow-1">
+                                                You are now the MCP for
+                                                <a href="/patients/view/{{$assoc->patient->uid}}"
+                                                   class="">{{$assoc->patient->displayName()}}</a>
+                                                <?php $nextAppt = $assoc->patient->nextAppointment(); ?>
+                                                @if($nextAppt)
+                                                    <div class="font-size-11">
+                                                        <span class="text-secondary font-size-11">Appt.</span>
+                                                        {{$nextAppt->pro->displayName()}}
+                                                        <span class="text-secondary font-size-11">on</span>
+                                                        {{friendlier_date_time($nextAppt->raw_date . ' ' . $nextAppt->raw_start_time)}}
+                                                    </div>
+                                                    @if($nextAppt->status === 'PENDING') {{-- WIP: ALIX overhaul --}}
+                                                        <div
+                                                            class="text-warning-mellow font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-exclamation-triangle"></i>
+                                                            Confirmation pending
+                                                        </div>
+                                                    @endif
+                                                    @if($nextAppt->status === 'CONFIRMED')
+                                                        <div class="text-success font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-check"></i>
+                                                            Confirmed by the patient
+                                                        </div>
+                                                    @endif
+                                                    @if($nextAppt->status === 'CANCELLED')
+                                                        <div class="text-danger font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-stop"></i>
+                                                            Cancelled
+                                                        </div>
+                                                    @endif
+                                                @endif
+                                            </div>
+                                            <a href="#" class="ack-client-pro-change ml-3" data-uid="{{$assoc->uid}}">Ack.</a>
+                                        </div>
+                                    @endforeach
+                                </div>
+                            @endif
+
+                            @if(count($newNAAssociations))
+                                <div class="mb-3 border rounded px-3 py-2 ack-container">
+                                    <p class="pt-1 mb-2"><b>New Patients</b></p>
+                                    @foreach($newNAAssociations as $assoc)
+                                        <div class="d-flex align-items-start bg-light mb-2 px-2 py-1">
+                                            <div class="flex-grow-1">
+                                                You are now the Care Coordinator for
+                                                <a href="/patients/view/{{$assoc->patient->uid}}"
+                                                   class="">{{$assoc->patient->displayName()}}</a>
+                                                <?php $nextAppt = $assoc->patient->nextAppointment(); ?>
+                                                @if($nextAppt)
+                                                    <div class="font-size-11">
+                                                        <span class="text-secondary font-size-11">Appt.</span>
+                                                        {{$nextAppt->pro->displayName()}}
+                                                        <span class="text-secondary font-size-11">on</span>
+                                                        {{friendlier_date_time($nextAppt->raw_date . ' ' . $nextAppt->raw_start_time)}}
+                                                    </div>
+                                                    @if($nextAppt->status === 'PENDING')
+                                                        <div
+                                                            class="text-warning-mellow font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-exclamation-triangle"></i>
+                                                            Confirmation pending
+                                                        </div>
+                                                    @endif
+                                                    @if($nextAppt->status === 'CONFIRMED')
+                                                        <div class="text-success font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-check"></i>
+                                                            Confirmed by the patient
+                                                        </div>
+                                                    @endif
+                                                    @if($nextAppt->status === 'CANCELLED')
+                                                        <div class="text-danger font-weight-bold font-size-11 mt-1">
+                                                            <i class="fa fa-stop"></i>
+                                                            Cancelled
+                                                        </div>
+                                                    @endif
+                                                @endif
+                                            </div>
+                                            <a href="#" class="ack-client-pro-change"
+                                               data-uid="{{$assoc->uid}}">Ack.</a>
+                                        </div>
+                                    @endforeach
+                                </div>
+                            @endif
+                        </div>
+                        <div class="col-6">
+                            @if(count($mcpClientMemos))
+                                <div class="mb-3 border rounded px-3 py-2 ack-container">
+                                    <p class="pt-1 mb-2"><b>New Patients Memos (MCP)</b></p>
+                                    <table class="table table-sm table-hover table-bordered">
+                                        <thead>
+                                        <tr>
+                                            <th>Patient</th>
+                                            <th>Memo</th>
+                                            <th>Created</th>
+                                            <th></th>
+                                        </tr>
+                                        </thead>
+                                        <tbody>
+                                        @foreach($mcpClientMemos as $memo)
+                                            <tr>
+                                                <td class="">
+                                                    <a href="/patients/view/{{$memo->client_uid}}">{{$memo->name_first}} {{$memo->name_last}}</a>
+                                                </td>
+                                                <td>{!! $memo->content !!}</td>
+                                                <td class="text-nowrap">{{friendlier_date_time($memo->created_at)}}</td>
+                                                <td><a href="#" class="ack-client-memo"
+                                                       data-uid="{{$memo->uid}}">Ack.</a></td>
+                                            </tr>
+                                        @endforeach
+                                        </tbody>
+                                    </table>
+                                </div>
+                            @endif
+                            @if(count($naClientMemos))
+                                <div class="mb-3 border rounded px-3 py-2 ack-container">
+                                    <p class="pt-1 mb-2"><b>New Patients Memos (NA)</b></p>
+                                    <table class="table table-sm table-hover table-bordered">
+                                        <thead>
+                                        <tr>
+                                            <th>Patient</th>
+                                            <th>Memo</th>
+                                            <th>Created</th>
+                                            <th></th>
+                                        </tr>
+                                        </thead>
+                                        <tbody>
+                                        @foreach($naClientMemos as $memo)
+                                            <tr>
+                                                <td class="">
+                                                    <a href="/patients/view/{{$memo->client_uid}}">{{$memo->name_first}} {{$memo->name_last}}</a>
+                                                </td>
+                                                <td>{!! $memo->content !!}</td>
+                                                <td class="text-nowrap">{{friendlier_date_time($memo->created_at)}}</td>
+                                                <td><a href="#" class="ack-client-memo"
+                                                       data-uid="{{$memo->uid}}">Ack.</a></td>
+                                            </tr>
+                                        @endforeach
+                                        </tbody>
+                                    </table>
+                                </div>
+                            @endif
+                        </div>
+                    </div>
+
+                    <ul class="nav nav-tabs">
+                        <li class="nav-item">
+                            <a native data-tab="appointments" class="nav-link"
+                               :class="tab == 'appointments' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='appointments'; initLoadAppointments();">
+                                Appointments
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="measurements" class="nav-link"
+                               :class="tab == 'measurements' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='measurements'; loadMeasurements();">
+                                Measurements
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="incoming_reports"
+                               class="nav-link {{count($incomingReports) ? 'text-danger font-weight-bold' : ''}}"
+                               :class="tab == 'incoming_reports' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='incoming_reports'">
+                                Incoming Reports ({{count($incomingReports)}})
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="erx" class="nav-link {{$numERx ? 'text-danger font-weight-bold' : ''}}"
+                               :class="tab == 'erx' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='erx'">
+                                ERx ({{$numERx}})
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="labs"
+                               class="nav-link {{$numLabs ? 'text-danger font-weight-bold' : ''}}"
+                               :class="tab == 'labs' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='labs'">
+                                Labs ({{$numLabs}})
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="imaging"
+                               class="nav-link {{$numImaging ? 'text-danger font-weight-bold' : ''}}"
+                               :class="tab == 'imaging' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='imaging'">
+                                Imaging ({{$numImaging}})
+                            </a>
+                        </li>
+                        <li class="nav-item">
+                            <a native data-tab="supply_orders"
+                               class="nav-link {{$numSupplyOrders ? 'text-danger font-weight-bold' : ''}}"
+                               :class="tab == 'supply_orders' ? 'active' : ''" href="#"
+                               v-on:click.prevent="tab='supply_orders'">
+                                Supply Orders ({{$numSupplyOrders}})
+                            </a>
+                        </li>
+                    </ul>
+
+                    <div class="border-left border-right border-bottom p-3">
+                        <div v-show="tab==='appointments'" class="appointments-tab">
+                            <div v-show="selectedDate">
+                                <div class="d-flex align-items-end mb-3">
+                                    <b class="large"><span class="text-secondary">Today:</span> @{{ selectedDate }}</b>
+                                    <div class="ml-auto d-inline-flex align-items-center">
+                                        <label class="text-secondary mr-2 my-0 text-nowrap">Filter by status:</label>
+                                        <select v-model="filterStatus"
+                                                class="form-control form-control-sm">
+                                            <option value="">All</option>
+                                            <option value="PENDING">Pending</option>
+                                            <option value="CONFIRMED">Confirmed</option>
+                                            <option value="CANCELLED">Cancelled</option>
+                                            <option value="COMPLETED">Completed</option>
+                                        </select>
+                                    </div>
+                                </div>
+                                <div v-for="event in events" class="align-items-end p-3 border rounded mb-3"
+                                     :class="(event.dateYMD === selectedDate && (filterStatus === '' || filterStatus === event.status) ? 'd-flex' : 'd-none') + ' ' + (event.isClientShadowOfPro ? 'training-event' : '')">
+                                    <div class="patient-avatar mr-3 align-self-center">
+                                        <i v-if="event.isClientShadowOfPro" class="fa fa-graduation-cap training-icon"
+                                           :title="event.proInitials"></i>
+                                        <span v-else class="">@{{ event.proInitials }}</span>
+                                    </div>
+                                    <div>
+                                        <div class="pb-1">
+                                            <b class="text-info">@{{ event.proName }}</b>
+                                            &nbsp;/&nbsp;
+                                            @{{ event.friendlyStartTime }} - @{{ event.friendlyEndTime }} <span
+                                                class="text-secondary">@{{ event.timezone }}</span>
+                                            &nbsp;/&nbsp;
+                                            <span class="d-inline-block ml- 2 text-secondary font-weight-bold">@{{ event.title }}</span>
+                                        </div>
+                                        <div class="pb-1">
+                                            <a :href="'/patients/view/' + event.clientUid" class="font-weight-bold">@{{
+                                                event.clientName }}</a>
+                                            <span class="small d-inline-block pl-2 text-secondary font-weight-normal">@{{ event.clientSummary }}</span>
+                                        </div>
+                                        <div class="d-flex align-items-baseline">
+                                            <div v-if="event.status === 'PENDING'"
+                                                 class="text-warning-mellow font-weight-bold">
+                                                <i class="fa fa-exclamation-triangle"></i>
+                                                Confirmation pending
+                                            </div>
+                                            <div v-else-if="event.status === 'CONFIRMED'"
+                                                 class="text-success font-weight-bold">
+                                                <i class="fa fa-check"></i>
+                                                Confirmed by the patient
+                                            </div>
+                                            <div v-else-if="event.status === 'CANCELLED'"
+                                                 class="text-danger font-weight-bold">
+                                                <i class="fa fa-stop"></i>
+                                                Cancelled
+                                            </div>
+                                            <div v-else class="text-secondary">
+                                                Status: <b>@{{ event.status }}</b>
+                                            </div>
+                                            <span class="mx-2 text-secondary">|</span>
+                                            <a :href="'/patients/view/' + event.clientUid + '/calendar/' + event.uid">
+                                                <i class="fa fa-edit"></i>
+                                                Edit Appointment
+                                            </a>
+                                        </div>
+                                        <div class="mt-1"
+                                             :class="event.coverage !== 'YES' ? (event.coverage === 'NO' ? 'text-danger' : 'text-warning-mellow') : 'text-success'">
+                                            Coverage Status: <b>@{{ event.coverage }}</b>
+                                        </div>
+                                    </div>
+                                    <div class="ml-auto">
+                                        <select v-model="event.newStatus"
+                                                class="form-control form-control-sm bg-light"
+                                                v-on:change="updateStatus(event)">
+                                            <option value="PENDING">PENDING</option>
+                                            <option value="CONFIRMED">CONFIRMED</option>
+                                            <option value="CANCELLED">CANCELLED</option>
+                                            <option value="COMPLETED">COMPLETED</option>
+                                        </select>
+                                        <div v-if="selectedDate === '{{ date('Y-m-d') }}'"
+                                             class="pt-1 text-right"
+                                             :class="event.started ? 'text-danger': 'text-secondary'">
+                                            @{{ event.inHowManyHours }}
+                                        </div>
+                                    </div>
+                                </div>
+                                <div v-if="numEventsForDate === 0" class="bg-light p-3 text-secondary border bounded">
+                                    <span
+                                        v-if="filterStatus === ''">You have no appointments on <b>@{{ selectedDate }}</b></span>
+                                    <span
+                                        v-if="filterStatus !== ''">You have no appointments on <b>@{{ selectedDate }}</b> with status <b>@{{ filterStatus }}</b></span>
+                                </div>
+                            </div>
+                            <div v-show="!selectedDate" class="bg-light p-3 text-secondary border bounded">
+                                Please select a date from the calendar on the left
+                            </div>
+                        </div>
+                        <div v-show="tab==='measurements'">
+                            <div id="measurements-tab">Loading...</div>
+                        </div>
+                        <div v-show="tab==='incoming_reports'">
+                            @include('app.dashboard.incoming_reports')
+                        </div>
+                        <div v-show="tab==='erx'">
+                            @include('app.dashboard.erx')
+                        </div>
+                        <div v-show="tab==='labs'">
+                            @include('app.dashboard.labs')
+                        </div>
+                        <div v-show="tab==='imaging'">
+                            @include('app.dashboard.imaging')
+                        </div>
+                        <div v-show="tab==='supply_orders'">
+                            @include('app.dashboard.supply_orders')
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="stag-popup stag-popup-md ticket-popup mcp-theme-1" stag-popup-key="ticket-popup"></div>
+
+    <script>
+        (function () {
+            function init() {
+                window.apapp = new Vue({
+                    el: '#pro-dashboard-container',
+                    delimiters: ['@{{', '}}'],
+                    data: {
+                        tab: '{{ request()->input('tab') ? request()->input('tab') : 'measurements' }}',
+                        datesWithEvents: [],
+                        selectedDate: '{{ date('Y-m-d') }}',
+                        selectedStatus: 'PENDING',
+                        events: [],
+                        numEventsForDate: 0,
+                        filterStatus: '',
+                        calendarElem: null,
+                        currentMonth: null,
+                        currentYear: null,
+                        measurementFilterStatus: 'ALL',
+                        measurements: {!! $pro->pro_type === 'ADMIN' ? '[]' : json_encode($pro->getMeasurements()) !!},
+                        appointmentsLoaded: false,
+                    },
+                    methods: {
+                        formatDate: function (date) {
+                            let d = new Date(date),
+                                month = '' + (d.getMonth() + 1),
+                                day = '' + d.getDate(),
+                                year = d.getFullYear();
+
+                            if (month.length < 2)
+                                month = '0' + month;
+                            if (day.length < 2)
+                                day = '0' + day;
+
+                            return [year, month, day].join('-');
+                        },
+                        onDateChange: function (_newDate) {
+                            let self = this;
+                            window.setTimeout(() => {
+                                // let dayValue = $('.pro-dashboard-inline-calendar td.day.active').first().text();
+                                // if(dayValue.length === 1) dayValue = '0' + dayValue;
+                                // self.selectedDate = _newDate.substr(0, 8) + dayValue;
+                                self.selectedDate = _newDate;
+                                showMask();
+                                self.loadEvents(self.selectedDate, function () {
+                                    hideMask();
+                                    Vue.nextTick(() => {
+                                        // self.highlightDatesWithEvents(self.datesWithEvents);
+                                        initFastLoad($('.appointments-tab'));
+                                    });
+                                });
+                            }, 25);
+                        },
+                        selectToday: function () {
+                            $('.pro-dashboard-inline-calendar table td[data-date]').removeClass('active');
+                            $('.pro-dashboard-inline-calendar table td[data-date="{{ $milliseconds }}"]')
+                                .addClass('active');
+                            // this.onDateChange('{{ date('Y-m-d') }}');
+                        },
+                        highlightDatesWithEvents: function (_dates) {
+                            $('.pro-dashboard-inline-calendar table td[data-date]').removeAttr('has-events');
+                            for (let i = 0; i < _dates.length; i++) {
+                                $('.pro-dashboard-inline-calendar table td[data-date="' + _dates[i] + '"]')
+                                    .attr('has-events', 1);
+                            }
+                        },
+                        updateStatus: function (_event) {
+                            $.post('/api/appointment/updateStatus', {
+                                uid: _event.uid,
+                                status: _event.newStatus
+                            }, function (_data) {
+                                if (!_data) {
+                                    toastr.error('Unable to update appointment status!');
+                                } else {
+                                    if (!_data.success) {
+                                        toastr.error(_data.message);
+                                    } else {
+                                        _event.status = _event.newStatus;
+                                        toastr.success('The appointment has been updated');
+                                    }
+                                }
+                            }, 'json')
+                        },
+                        showEditForm: function (_trigger) {
+                            let form = $(_trigger).closest('[moe]').find('form').first();
+                            showMoeFormMask();
+                            form.show();
+                            setTimeout(function () {
+                                initPrimaryForm(form);
+                            }, 0);
+                        },
+                        submitEditForm: function (_trigger) {
+                            let form = $(_trigger).closest('[moe]').find('form').first();
+                            if (!form[0].checkValidity()) {
+                                form[0].reportValidity();
+                                return;
+                            }
+                            $.post(form.attr('url'), form.serialize(), function (_data) {
+                                if (_data && _data.success) {
+                                    fastReload();
+                                } else {
+                                    if (_data.message) {
+                                        toastr.error(_data.message);
+                                    } else {
+                                        toastr.error('Unable to update the appointment');
+                                    }
+                                }
+                            });
+                        },
+                        cancelEditForm: function (_trigger) {
+                            let form = $(_trigger).closest('[moe]').find('form').first();
+                            hideMoeFormMask();
+                            form.hide();
+                        },
+                        loadEventDates: function (_refDate = false) {
+                            let today = new Date(_refDate ? _refDate : '{{date('Y-m-d')}}'),
+                                firstOfMonth = new Date(today.getFullYear(), today.getMonth(), 1),
+                                lastOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
+
+                            this.selectedDate = null;
+                            $('td.day.active').removeClass('active');
+
+                            $.get('/pro-dashboard-event-dates/' +
+                                this.formatDate(firstOfMonth) + '/' +
+                                this.formatDate(lastOfMonth), (_data) => {
+                                this.datesWithEvents = _data;
+                                console.log(this.datesWithEvents);
+                                this.calendarElem.datepicker('refresh');
+                                // this.highlightDatesWithEvents(this.datesWithEvents);
+
+                                this.currentMonth = firstOfMonth.getMonth();
+                                this.currentYear = firstOfMonth.getFullYear();
+
+                                if (!_refDate && $('td.day[data-date="{{$milliseconds}}"]:visible').length) {
+                                    $('td.day[data-date="{{$milliseconds}}"]:visible').first().click();
+                                }
+
+                                this.appointmentsLoaded = true;
+                            }, 'json');
+                        },
+                        loadEvents: function (_date, _callback) {
+                            let self = this;
+                            $.get('/pro-dashboard-events/' + _date + '/' + _date, function (_data) {
+                                self.events = _data;
+                                self.numEventsForDate = (_data && _data.length) ? 1 : 0;
+                                _callback.call(self);
+                            }, 'json');
+                        },
+                        updateMeasurements: function () {
+                            $.get('/pro-dashboard-measurements/' + this.measurementFilterStatus, (_data) => {
+                                this.measurements = _data;
+                                Vue.nextTick(() => {
+                                    // this.initCMRTE();
+                                    $('#pro-dashboard-container').find('[moe][initialized]').removeAttr('initialized');
+                                    initMoes();
+                                });
+                            }, 'json');
+                        },
+                        setMeasurementStatus: function (_uid, _status) {
+                            $.post('/api/measurement/updateStatus', {
+                                uid: _uid,
+                                status: _status
+                            }, (_data) => {
+                                this.updateMeasurements();
+                            }, 'json');
+                        },
+                        initCMRTE: function () {
+                            $('#pro-dashboard-container [cm-rte]').each(function () {
+
+                                $(this).wrap(
+                                    $('<div class="border-left border-right rte-holder"/>')
+                                        .attr('data-shortcuts', '')
+                                );
+
+                                // give a unique id to this editor instance
+                                var editorID = Math.ceil(Math.random() * 99999), fieldName = $(this).attr('data-name');
+
+                                var el = this;
+                                var existingContent = $(el).attr('data-content');
+                                var quill = new Quill(el, {
+                                    theme: 'snow',
+                                    modules: stagQuillConfig
+                                });
+
+                                var toolbar = $(quill.container).prev('.ql-toolbar');
+
+                                // add button for new shortcut
+                                var newSCButton = $('<button 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);
+
+                                quill.root.innerHTML = existingContent;
+
+                                $('<input type="hidden" name="' + fieldName + '">').val(existingContent).insertAfter(el);
+
+                                quill.on('text-change', function (delta, oldDelta, source) {
+                                    $(el).next('[name="' + fieldName + '"]').val(quill.root.innerHTML);
+                                });
+
+                                $(quill.container)
+                                    .find('.ql-editor[contenteditable]')
+                                    .attr('data-field', fieldName)
+                                    .attr('data-editor-id', editorID)
+                                    .attr('with-shortcuts', 1);
+
+                            })
+                        },
+                        initLoadAppointments: function () {
+                            if (this.appointmentsLoaded) return false;
+                            this.loadEventDates();
+                        },
+                        loadMeasurements: function () {
+                            $('#measurements-tab').load('/pro-dashboard-measurements-tab', () => {
+                                initMoes();
+                                initFastLoad($('#measurements-tab'));
+                            });
+                        }
+                    },
+                    mounted: function () {
+                        let self = this;
+                        this.calendarElem = $('.pro-dashboard-inline-calendar');
+                        this.calendarElem.datepicker({
+                            dateFormat: 'yy-mm-dd',
+                            onSelect: function (_date) {
+                                self.onDateChange(_date);
+                            },
+                            onChangeMonthYear: function (_year, _month) {
+                                let date = _year + '-' + (_month < 10 ? '0' : '') + _month + '-05';
+                                self.loadEventDates(date);
+                            },
+                            beforeShowDay: function (d) {
+                                if (self.datesWithEvents && self.datesWithEvents.indexOf(self.formatDate(d)) !== -1) {
+                                    return [true, 'has-events'];
+                                }
+                                return [true, 'no-events'];
+                            }
+                        });
+                        // this.calendarElem
+                        //     .on('changeDate', function () {
+                        //         self.onDateChange(self.calendarElem.datepicker('getFormattedDate'));
+                        //     })
+                        //     .on('changeMonth', function () {
+                        //         window.setTimeout(function() {
+                        //             let ts = $('td.day[data-date]').first().closest('tr').find('td.day[data-date]').last().attr('data-date');
+                        //             if(ts) {
+                        //                 self.loadEventDates(ts);
+                        //             }
+                        //         }, 10);
+                        //     });
+
+
+                        $('#pro-dashboard-container').find('[moe][initialized]').removeAttr('initialized');
+                        initMoes();
+
+                        // init fast load
+                        initFastLoad($('#pro-dashboard-container'));
+
+                        $(document)
+                            .off('click', '.dashboard-measurements.pagination a.page-link')
+                            .on('click', '.dashboard-measurements.pagination a.page-link', function () {
+                                $('#measurements-tab').text('Loading...').load('/pro-dashboard-measurements-tab/' + $(this).attr('data-target-page'), () => {
+                                    initMoes();
+                                    initFastLoad($('#measurements-tab'));
+                                });
+                                return false;
+                            });
+
+                        this.loadMeasurements();
+                    }
+                });
+                /*// refresh once ticket popup is closed
+                $('body').off('stag-popup-closed')
+                $('body').on('stag-popup-closed', function() {
+                    if($('#pro-dashboard-container').length) {
+                        let activeTab = $('.nav-link.active[data-tab]').attr('data-tab');
+                        if(activeTab) {
+                            fastLoad('/?tab=' + activeTab);
+                        }
+                    }
+                });*/
+                // ticket-popup
+                $(document)
+                    .off('click', '.ticket-popup-trigger')
+                    .on('click', '.ticket-popup-trigger', function () {
+                        showMask();
+                        window.noMc = true;
+                        $.get(this.href, (_data) => {
+                            $('.ticket-popup').html(_data);
+                            showStagPopup('ticket-popup');
+                            $('.ticket-popup .stag-popup.stag-slide').attr('close-all-with-self', 1);
+                            runMCInitializer('patient-tickets'); // run specific mc initer
+                            hideMask();
+                        });
+                        return false;
+                    });
+
+                $(document)
+                    .off('click', '.ack-client-pro-change')
+                    .on('click', '.ack-client-pro-change', function () {
+                        let trigger = $(this).text('…');
+                        $.post('/api/clientProChange/accept', {
+                            uid: $(this).attr('data-uid')
+                        }, _data => {
+                            if (!hasResponseError(_data)) {
+                                trigger.hide();
+                                let doneElem = $('<i class="text-success fa fa-check"></i>');
+                                doneElem.insertAfter(trigger);
+                                setTimeout(() => {
+                                    let ackContainer = trigger.closest('.ack-container');
+                                    trigger.closest('div').slideUp('fast', function () {
+                                        $(this).remove();
+                                        if (!ackContainer.find('>div').length) {
+                                            ackContainer.remove();
+                                        }
+                                    });
+                                }, 500);
+                            }
+                        }, 'json');
+                        return false;
+                    });
+
+                $(document)
+                    .off('click', '.ack-client-memo')
+                    .on('click', '.ack-client-memo', function () {
+                        let trigger = $(this).text('…');
+                        $.post('/api/clientMemo/stamp', {
+                            uid: $(this).attr('data-uid')
+                        }, _data => {
+                            if (!hasResponseError(_data)) {
+                                trigger.hide();
+                                let doneElem = $('<i class="text-success fa fa-check"></i>');
+                                doneElem.insertAfter(trigger);
+                                setTimeout(() => {
+                                    let tbody = trigger.closest('tbody');
+                                    trigger.closest('tr').remove();
+                                    if (!tbody.find('>tr').length) {
+                                        tbody.closest('.ack-container').remove();
+                                    }
+                                }, 500);
+                            }
+                        }, 'json');
+                        return false;
+                    });
+
+                $(document)
+                    .off('click', '.ack-pro-appt-update')
+                    .on('click', '.ack-pro-appt-update', function () {
+                        let trigger = $(this).text('…');
+                        $.post('/api/appointmentConfirmationDecision/acknowledgeAsAppointmentPro', {
+                            uid: $(this).attr('data-uid')
+                        }, _data => {
+                            if (!hasResponseError(_data)) {
+                                trigger.hide();
+                                let doneElem = $('<i class="text-success fa fa-check"></i>');
+                                doneElem.insertAfter(trigger);
+                                setTimeout(() => {
+                                    let ackContainer = trigger.closest('tbody');
+                                    trigger.closest('tr').slideUp('fast', function () {
+                                        $(this).remove();
+                                        if (!ackContainer.find('>tr').length) {
+                                            ackContainer.remove();
+                                        }
+                                    });
+                                }, 500);
+                            }
+                        }, 'json');
+                        return false;
+                    });
+
+                $(document)
+                    .off('click', '.ack-na-appt-update')
+                    .on('click', '.ack-na-appt-update', function () {
+                        let trigger = $(this).text('…');
+                        $.post('/api/appointmentConfirmationDecision/acknowledgeAsClientDefaultNa', {
+                            uid: $(this).attr('data-uid')
+                        }, _data => {
+                            if (!hasResponseError(_data)) {
+                                trigger.hide();
+                                let doneElem = $('<i class="text-success fa fa-check"></i>');
+                                doneElem.insertAfter(trigger);
+                                setTimeout(() => {
+                                    let ackContainer = trigger.closest('tbody');
+                                    trigger.closest('tr').slideUp('fast', function () {
+                                        $(this).remove();
+                                        if (!ackContainer.find('>tr').length) {
+                                            ackContainer.remove();
+                                        }
+                                    });
+                                }, 500);
+                            }
+                        }, 'json');
+                        return false;
+                    });
+            }
+
+            addMCInitializer('pro-dashboard', init, '#pro-dashboard-container');
+        })();
+    </script>
+@endsection

+ 3 - 3
resources/views/app/dashboard-mcp.blade.php

@@ -283,10 +283,10 @@
                         </div>
                     </div>
                 </div>
-                <div class="col-md-9">
+                <div class="col-md-9 pl-1">
                     <div class="row mcp-theme-1">
                         <div class="col-md-6 mcp-theme-1">
-                            <div id="mcp-dashboard-appointments" class="mb-4">
+                            <div id="mcp-dashboard-appointments" class="mb-4  max-height-200px overflow-auto">
 
                             </div>
                             <div class="card mb-4">
@@ -300,7 +300,7 @@
                                 </div>
                             </div>
                         </div>
-                        <div class="col-md-6 mcp-theme-1">
+                        <div class="col-md-6 mcp-theme-1 pl-1">
                             <div class="card mb-4">
                                 <div class="card-header pl-2">
                                     <strong>

+ 57 - 0
resources/views/app/dna/dashboard/measurements-pending-stamping.blade.php

@@ -0,0 +1,57 @@
+<div id="dashboard-measurements-pending-stamping">
+@if($measurementsPendingStamping && count($measurementsPendingStamping))
+    <table class="table table-sm table-striped mb-0">
+        <thead>
+        <tr>
+            <th class="border-bottom-0 border-top-0 text-secondary">Patient</th>
+            <th class="border-bottom-0 border-top-0 text-secondary">Care Month</th>
+            <th class="border-bottom-0 border-top-0 text-secondary">Type</th>
+            <th class="border-bottom-0 border-top-0 text-secondary">Value</th>
+            <th class="border-bottom-0 border-top-0 text-secondary">Timestamp</th>
+        </tr>
+        </thead>
+        <tbody>
+        @foreach($measurementsPendingStamping as $row)
+            <tr>
+                <td class="pl-2">
+                    <a href="{{ route('patients.view.dashboard', $row->client) }}">
+                        {{$row->client->displayName()}}
+                    </a>
+                </td>
+                <td>
+                    <a native target="_blank"
+                       open-in-stag-popup
+                       update-parent
+                       update-target="#dashboard-measurements-pending-stamping"
+                       mc-initer="cm-matrix-{{$row->client->id}}"
+                       title="Care Month Matrix: {{date('M Y', strtotime($row->careMonth->start_date))}}"
+                       href="/patient-care-month-matrix/{{$row->careMonth->uid}}">
+                        {{ friendly_month($row->careMonth->start_date) }}
+                    </a>
+                </td>
+                <td class="text-nowrap">
+                    {{$row->label}}
+                </td>
+                <td>
+                    @if($row->label === 'BP')
+                        {{ $row->sbp_mm_hg }}/{{ $row->dbp_mm_hg }}
+                    @elseif($row->label === 'Wt. (lbs.)')
+                        {{ round(floatval($row->numeric_value), 2) }}
+                    @endif
+                </td>
+                <td class="text-secondary">
+                    {{ friendly_date_time_short_with_tz_from_timestamp_divide1000($row->ts, 'EASTERN') }} EST
+                </td>
+            </tr>
+        @endforeach
+        </tbody>
+    </table>
+    <div class="m-2">
+        {{ $measurementsPendingStamping->onEachSide(0)->withQueryString()->links() }}
+    </div>
+@else
+    <div class="p-3">
+        No measurement pending stamping
+    </div>
+@endif
+</div>

+ 85 - 0
resources/views/app/mcp/clients_bdt_devices.blade.php

@@ -0,0 +1,85 @@
+@extends ('layouts/template')
+
+@section('content')
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-weight"></i>
+                Clients BDT Devices
+            </strong>
+        </div>
+
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.mcp.clients_bdt_devices_filters')
+            </div>
+            <table class="table table-condensed p-0 m-0">
+                <thead class="bg-light">
+                    <tr>
+                        <th class="px-3 border-0">IMEI</th>
+                        <th class="px-3 border-0">Client</th>
+                        <th class="px-3 border-0">Created</th>
+                        <th class="px-3 border-0">Category</th>
+                        <th class="px-3 border-0">Last Measurement</th>
+                        <th class="px-3 border-0">Status</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    @foreach($devices as $device)
+                    <tr>
+                        <td class="px-2">
+                            <pre class="m-0">{{ $device->device->imei }}</pre>
+                        </td>
+                        <td>
+                            <a target="_blank" native href="{{route('patients.view.dashboard', $device->client)}}">
+                                {{$device->client->displayName()}}
+                            </a>
+                        </td>
+                        <td class="px-2 text-nowrap">{{ friendly_date_time($device->device->created_at) }}</td>
+                        <td class="px-2">{{ $device->device->category }}</td>
+                        <td class="px-2 d-flex align-items-center">
+                            <?php $lastMeasurement = $device->lastDeviceMeasurement(); ?>
+                            @if($lastMeasurement)
+                            @if($lastMeasurement->is_cellular_zero)
+                            <i class="font-size-11 fa fa-rss"></i>
+                            @elseif($lastMeasurement->label === 'BP')
+                            {{ $lastMeasurement->sbp_mm_hg }} / {{ $lastMeasurement->dbp_mm_hg }}
+                            @elseif($lastMeasurement->label === 'Wt. (lbs.)')
+                            {{ round($lastMeasurement->numeric_value, 2) }} lbs
+                            @else
+                            {{ $lastMeasurement->value }}
+                            @endif
+                            <div class="ml-2">
+                                <i class="far fa-calendar-check"></i> <span class="text-secondary">{{ friendly_date_time($lastMeasurement->created_at) }}</span>
+                            </div>
+                            @else
+                            <small class="text-muted">-</small>
+                            @endif
+                        </td>
+                        <td>
+                            @if($device->is_active)
+                                <span class="text-success">Active</span>
+                            @else
+                                <span class="text-danger">Deactivated</span>
+                            @endif
+                        </td>
+                    </tr>
+                    @endforeach
+
+                    @if(count($devices) === 0)
+                    <tr>
+                        <td colspan="6">No records found!</td>
+                    </tr>
+                    @endif
+                </tbody>
+
+            </table>
+            <div class="ml-2 mt-2">
+                {{ $devices->appends(request()->input())->links() }}
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 107 - 0
resources/views/app/mcp/clients_bdt_devices_filters.blade.php

@@ -0,0 +1,107 @@
+<style>
+	#mcp-clients-bdt-devices-filters label {
+		font-weight: bold;
+	}
+
+	#mcp-clients-bdt-devices-filters .mw-100px {
+		min-width: 100px;
+	}
+	.filter-container {
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+	.filter-container >div {
+		width: 165px;
+	}
+	.filter-container >div:not(:last-child) {
+		margin-right: 15px;
+	}
+</style>
+<form id="mcp-clients-bdt-devices-filters" method="GET" action="{{ route('mcp.clients_bdt_devices') }}" class="filter-container" v-cloak>
+	<!-- DATE	 -->
+	<div>
+		<div class="form-group">
+			<label>Date:</label>
+			<select name="date_category" class="form-control input-sm" v-model="filters.date_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.date_category" class="mt-2">
+				<div>
+					<input name="date_value_1" v-model="filters.date_value_1" type="date" class="form-control input-sm"/>
+				</div>
+				<div v-show="filters.date_category === 'BETWEEN' || filters.date_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="date_value_2" v-model="filters.date_value_2" type="date" class="form-control input-sm"/>
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- STATUS -->
+	<div>
+		<div class="form-group">
+			<label>Status:</label>
+			<select name="status" class="form-control input-sm" v-model="filters.status">
+				<option value="">All</option>
+				<option value="ACTIVE">active</option>
+				<option value="DEACTIVATED">Deactivated</option>
+			</select>
+		</div>
+	</div>
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<div class="d-flex">
+				<button type="submit" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('mcp.clients_bdt_devices')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'date_category',
+	'date_value_1',
+	'date_value_2',
+	'status'
+];
+for ($i = 0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+<script>
+	(function() {
+		function init() {
+			window.apapp = new Vue({
+				el: '#mcp-clients-bdt-devices-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					doSubmit: function() {
+						fastLoad('{{ route("mcp.clients_bdt_devices") }}?' + $('#mcp-clients-bdt-devices-filters').serialize());
+						return false;
+					},
+					init: function() {
+
+					}
+				},
+				mounted: function() {
+					this.init();
+				},
+			});
+
+
+		}
+		addMCInitializer('mcp-clients-bdt-devices-filters', init, '#mcp-clients-bdt-devices-filters');
+	})();
+</script>

+ 127 - 93
resources/views/app/mcp/dashboard/appointments-list.blade.php

@@ -1,99 +1,133 @@
-@if(@$from)
-<div class="font-weight-bold mb-2">Appointments for {{friendly_date($from)}}</div>
-@endif
-@if(@$appointments && count($appointments))
-    <table class="mb-0 table table-sm table-bordered appointments">
-        @foreach($appointments as $appointment)
-            <tr class="{{$appointment->bgColor}}">
-                <td>
-                    <a href="/patients/view/{{$appointment->clientUid}}" class="font-weight-bold d-block">
-                        {{$appointment->clientName }}
-                    </a>
-                    <div class="mt-1">
-                        {{ $appointment->friendlyStartTime }} - {{ $appointment->friendlyEndTime }}
-                        <span class="text-secondary">{{ friendly_timezone($appointment->timezone) }}</span>
-                    </div>
-                    <a href="'/patients/view/{{$appointment->clientUid}}/calendar/{{$appointment->uid}}"
-                       class="d-block mt-1">
-                        <i class="fa fa-edit"></i>
-                    </a>
-                    @if($appointment->title)
-                        <span class="d-inline-block mt-1 text-secondary text-sm">
+<div class="card mb-4">
+    <div class="card-header pl-2">
+        <div class="font-weight-bold">
+            @if(@$from)
+                Appointments for {{friendly_date($from)}}
+            @else
+                Appointments
+            @endif
+        </div>
+    </div>
+    <div class="card-body p-0">
+        @if(@$appointments && count($appointments))
+            <table class="mb-0 table table-sm appointments border-top-0">
+                @foreach($appointments as $appointment)
+                    <tr class="{{$appointment->bgColor}}">
+                        <td>
+                            <a href="/patients/view/{{$appointment->clientUid}}" class="font-weight-bold d-block">
+                                {{$appointment->clientName }}
+                            </a>
+                            <div class="mt-1">
+                                <a href="/patients/view/{{$appointment->clientUid}}/calendar/{{$appointment->uid}}">
+                                    {{ $appointment->friendlyStartTime }} - {{ $appointment->friendlyEndTime }}</a>
+                                <span class="text-secondary">{{ friendly_timezone($appointment->timezone) }}</span>
+                            </div>
+                            @if($appointment->title)
+                                <span class="d-inline-block mt-1 text-secondary text-sm">
                             {{ $appointment->title }}
                         </span>
-                    @endif
-                </td>
-                <td>
-                    <div class="d-flex flex-column">
-                        <div class="d-flex align-items-baseline flex-nowrap">
-                            @if($appointment->status === 'PENDING')
-                                <div class="text-warning-mellow font-weight-bold text-nowrap">
-                                    <i class="fa fa-exclamation-triangle"></i>
-                                    Pending
-                                </div>
-                            @elseif($appointment->status === 'CONFIRMED')
-                                <div class="text-success font-weight-bold text-nowrap">
-                                    <i class="fa fa-check"></i>
-                                    Confirmed
-                                </div>
-                            @elseif($appointment->status === 'CANCELLED')
-                                <div class="text-danger font-weight-bold text-nowrap">
-                                    <i class="fa fa-stop"></i>
-                                    Cancelled
-                                </div>
-                            @elseif($appointment->status === 'COMPLETED')
-                                <div class="text-success font-weight-bold text-nowrap">
-                                    <i class="far fa-calendar-check"></i>
-                                    Completed
-                                </div>
                             @endif
-                            <div class="ml-2" moe relative>
-                                <a href="#" start show><i class="fa fa-edit"></i></a>
-                                <form url="/api/appointment/updateStatus" hook="refreshDashboardAppointments">
-                                    <input type="hidden" name="uid" value="{{$appointment->uid}}">
-                                    <p class="text-nowrap mb-2 font-weight-bold text-secondary">Change appointment status</p>
-                                    <select name="status" class="form-control form-control-sm input-sm bg-light mb-2">
-                                        <option value="PENDING" {{$appointment->status === 'PENDING' ? 'selected' : ''}}>PENDING</option>
-                                        <option value="CONFIRMED" {{$appointment->status === 'CONFIRMED' ? 'selected' : ''}}>CONFIRMED</option>
-                                        <option value="CANCELLED" {{$appointment->status === 'CANCELLED' ? 'selected' : ''}}>CANCELLED</option>
-                                        <option value="COMPLETED" {{$appointment->status === 'COMPLETED' ? 'selected' : ''}}>COMPLETED</option>
-                                    </select>
-                                    <div class="mb-0">
-                                        <button class="btn btn-primary btn-sm" submit>Submit</button>
-                                        <button class="btn btn-default border btn-sm" cancel>Cancel</button>
+                        </td>
+                        <td>
+                            <div class="d-flex flex-column">
+                                <div class="d-flex align-items-baseline flex-nowrap">
+                                    @if($appointment->status === 'PENDING')
+                                        <div class="text-warning-mellow font-weight-bold text-nowrap">
+                                            <i class="fa fa-exclamation-triangle"></i>
+                                            Pending
+                                        </div>
+                                    @elseif($appointment->status === 'CONFIRMED')
+                                        <div class="text-success font-weight-bold text-nowrap">
+                                            <i class="fa fa-check"></i>
+                                            Confirmed
+                                        </div>
+                                    @elseif($appointment->status === 'CANCELLED')
+                                        <div class="text-danger font-weight-bold text-nowrap">
+                                            <i class="fa fa-stop"></i>
+                                            Cancelled
+                                        </div>
+                                    @elseif($appointment->status === 'COMPLETED')
+                                        <div class="text-success font-weight-bold text-nowrap">
+                                            <i class="far fa-calendar-check"></i>
+                                            Completed
+                                        </div>
+                                    @endif
+                                    <div class="ml-2" moe relative center>
+                                        <a href="#" start show><i class="fa fa-edit"></i></a>
+                                        <form url="/api/appointment/updateStatus" hook="refreshDashboardAppointments" center>
+                                            <input type="hidden" name="uid" value="{{$appointment->uid}}">
+                                            <p class="text-nowrap mb-3 font-weight-bold text-secondary">Change appointment status</p>
+                                            <div class="mb-3 border bg-light p-2">
+                                                <div class="d-flex align-items-baseline mb-1">
+                                                    <span class="width-70px">Patient</span>
+                                                    <b>{{$appointment->clientName }}</b>
+                                                </div>
+                                                <div class="d-flex align-items-baseline mb-1">
+                                                    <span class="width-70px">Pro</span>
+                                                    <b>{{$appointment->proName}}</b>
+                                                </div>
+                                                <div class="d-flex align-items-baseline mb-1">
+                                                    <span class="width-70px">Date</span>
+                                                    <b>{{friendly_date($appointment->raw_date)}}</b>
+                                                </div>
+                                                <div class="d-flex align-items-baseline mb-1">
+                                                    <span class="width-70px">Time</span>
+                                                    <span>
+                                                        <b>{{ $appointment->friendlyStartTime }}</b> - <b>{{ $appointment->friendlyEndTime }}</b>
+                                                        <span class="text-secondary">{{ friendly_timezone($appointment->timezone) }}</span>
+                                                    </span>
+                                                </div>
+                                                <div class="d-flex align-items-baseline ">
+                                                    <span class="width-70px">Status</span>
+                                                    <b>{{ucwords(strtolower($appointment->status))}}</b>
+                                                </div>
+                                            </div>
+                                            <label for="" class="mb-2">New Status</label>
+                                            <select name="status" class="form-control form-control-sm input-sm bg-light mb-2">
+                                                <option value="PENDING" {{$appointment->status === 'PENDING' ? 'selected' : ''}}>PENDING</option>
+                                                <option value="CONFIRMED" {{$appointment->status === 'CONFIRMED' ? 'selected' : ''}}>CONFIRMED</option>
+                                                <option value="CANCELLED" {{$appointment->status === 'CANCELLED' ? 'selected' : ''}}>CANCELLED</option>
+                                                <option value="COMPLETED" {{$appointment->status === 'COMPLETED' ? 'selected' : ''}}>COMPLETED</option>
+                                            </select>
+                                            <div class="mb-0">
+                                                <button class="btn btn-primary btn-sm" submit>Submit</button>
+                                                <button class="btn btn-default border btn-sm" cancel>Cancel</button>
+                                            </div>
+                                        </form>
+                                    </div>
+                                </div>
+                                @if($from === date('Y-m-d'))
+                                    <div class="{{$appointment->started ? 'text-danger': 'text-secondary'}}">
+                                        {{ $appointment->inHowManyHours }}
                                     </div>
-                                </form>
+                                @endif
                             </div>
-                        </div>
-                        @if($from === date('Y-m-d'))
-                            <div class="{{$appointment->started ? 'text-danger': 'text-secondary'}}">
-                                {{ $appointment->inHowManyHours }}
+                        </td>
+                        <td>
+                            <div>
+                                @if($appointment->coverage === 'YES')
+                                    <b class="text-success">Covered</b>
+                                @elseif($appointment->coverage === 'NO')
+                                    <b class="text-danger">Not Covered</b>
+                                @else
+                                    <b v-else class="text-warning-mellow">Pending</b>
+                                @endif
                             </div>
-                        @endif
-                    </div>
-                </td>
-                <td>
-                    <div>
-                        @if($appointment->coverage === 'YES')
-                            <b class="text-success">Covered</b>
-                        @elseif($appointment->coverage === 'NO')
-                            <b class="text-danger">Not Covered</b>
-                        @else
-                            <b v-else class="text-warning-mellow">Pending</b>
-                        @endif
-                    </div>
-                </td>
-            </tr>
-        @endforeach
-    </table>
-@else
-    @if(@$from)
-        <div class="bg-light p-3 text-secondary border bounded">
-            <span>You have no appointments on <b>{{ $from }}</b></span>
-        </div>
-    @else
-        <div class="bg-light p-3 text-secondary border bounded">
-            Please select a date from the calendar on the left
-        </div>
-    @endif
-@endif
+                        </td>
+                    </tr>
+                @endforeach
+            </table>
+        @else
+            @if(@$from)
+                <div class="bg-light p-3 text-secondary">
+                    <span>You have no appointments on <b>{{ $from }}</b></span>
+                </div>
+            @else
+                <div class="bg-light p-3 text-secondary">
+                    Please select a date from the calendar on the left
+                </div>
+            @endif
+        @endif
+    </div>
+</div>
+

+ 10 - 3
resources/views/app/mcp/dashboard/calls_memos.blade.php

@@ -1,3 +1,4 @@
+<div id="mcp-phone-calls-memos">
 @if(!$mcpClientMemos || !count($mcpClientMemos))
 <div class="px-2 py-3">No memos</div>
 @else
@@ -9,16 +10,21 @@
 				<a href="{{route('patients.view.dashboard', $memo->client_uid)}}">
 					{{$memo->name_first}} {{$memo->name_last}}
 				</a>
-				<div class="text-secondary text-sm text-nowrap">
+				<a class="text-sm text-nowrap d-block"
+				   href="/memos-thread/{{$memo->client_uid}}"
+				   native target="_blank"
+				   open-in-stag-popup
+				   popup-style="tall"
+				   title="Memos for {{$memo->name_first}} {{$memo->name_last}}">
 					{{friendlier_date_time($memo->created_at)}}
-				</div>
+				</a>
 			</td>
 			<td class="px-1">
 				{{$memo->content}}
 			</td>
 			<td class="width-70px px-2 text-right">
 				<div moe relative class="ml-auto">
-					<form show url="/api/clientMemo/stamp">
+					<form show url="/api/clientMemo/stamp" target="#mcp-phone-calls-memos">
 						<input type="hidden" name="uid" value="{{$memo->uid}}">
 						<button submit class="bg-transparent border-0 p-0 text-primary font-underline">Ack.</button>
 					</form>
@@ -34,3 +40,4 @@
 	</div>
 @endif
 @endif
+</div>

+ 9 - 13
resources/views/app/mcp/dashboard/measurements-pending-stamping.blade.php

@@ -4,7 +4,6 @@
         <thead>
         <tr>
             <th class="border-bottom-0 border-top-0 text-secondary">Patient</th>
-            <th class="border-bottom-0 border-top-0 text-secondary">Care Month</th>
             <th class="border-bottom-0 border-top-0 text-secondary">Type</th>
             <th class="border-bottom-0 border-top-0 text-secondary">Value</th>
             <th class="border-bottom-0 border-top-0 text-secondary">Timestamp</th>
@@ -18,17 +17,6 @@
                         {{$row->client->displayName()}}
                     </a>
                 </td>
-                <td>
-                    <a native target="_blank"
-                       open-in-stag-popup
-                       update-parent
-                       update-target="#dashboard-measurements-pending-stamping"
-                       mc-initer="cm-matrix-{{$row->client->id}}"
-                       title="Care Month Matrix: {{date('M Y', strtotime($row->careMonth->start_date))}}"
-                       href="/patient-care-month-matrix/{{$row->careMonth->uid}}">
-                        {{ friendly_month($row->careMonth->start_date) }}
-                    </a>
-                </td>
                 <td class="text-nowrap">
                     {{$row->label}}
                 </td>
@@ -40,7 +28,15 @@
                     @endif
                 </td>
                 <td class="text-secondary">
-                    {{ friendly_date_time_short_with_tz_from_timestamp_divide1000($row->ts, 'EASTERN') }} EST
+                    <a native target="_blank"
+                       open-in-stag-popup
+                       update-parent
+                       update-target="#dashboard-measurements-pending-stamping"
+                       mc-initer="cm-matrix-{{$row->client->id}}"
+                       title="Care Month Matrix: {{date('M Y', strtotime($row->careMonth->start_date))}}"
+                       href="/patient-care-month-matrix/{{$row->careMonth->uid}}">
+                        {{ friendly_date_time_short_with_tz_from_timestamp_divide1000($row->ts, 'EASTERN') }} EST
+                    </a>
                 </td>
             </tr>
         @endforeach

+ 7 - 2
resources/views/app/mcp/dashboard/messages.blade.php

@@ -9,9 +9,14 @@
                     <a href="{{route('patients.view.sms', $msg->client_uid)}}">
                         {{$msg->client_name_first}} {{$msg->client_name_last}}
                     </a>
-                    <div class="text-secondary text-sm text-nowrap">
+                    <a class="text-sm text-nowrap d-block"
+                       href="/messages-thread/{{$msg->client_uid}}"
+                       native target="_blank"
+                       open-in-stag-popup
+                       popup-style="tall"
+                       title="Messages for {{$msg->client_name_first}} {{$msg->client_name_last}}">
                         {{friendlier_date_time($msg->created_at)}}
-                    </div>
+                    </a>
                 </td>
                 <td class="px-1">
                     {{$msg->body}}

+ 95 - 0
resources/views/app/mcp/memos.blade.php

@@ -0,0 +1,95 @@
+@extends ('layouts/template')
+
+@section('content')
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-notes-medical"></i>
+                Memos
+            </strong>
+        </div>
+
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.mcp.memos_filters')
+            </div>
+            <table class="table table-condensed p-0 m-0">
+                <thead class="bg-light">
+                    <tr>
+                        <th class="px-3 border-0">Category</th>
+                        <th class="px-3 border-0">Patient</th>
+                        <th class="px-3 border-0 w-25">Summary</th>
+                        <th class="px-3 border-0">Created</th>
+                        <th class="px-3 border-0 delete-column">&nbsp;</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    @foreach($memos as $memo)
+                    <tr>
+                        <td class="px-2">{{ $memo->category }}</td>
+                        <td>
+                            <a target="_blank" native href="{{route('patients.view.dashboard', $memo->client)}}">
+                                {{$memo->client->displayName()}}
+                            </a>
+                        </td>
+                        <td class="px-2">
+                            <pre class="m-0 break-spaces">{{ $memo->content }}</pre>
+                        </td>
+                        <td class="px-2">{{ friendly_date_time($memo->created_at) }}</td>
+                        <td class="px-2 text-center delete-column">
+                            <div moe wide relative class="mr-2">
+                                <a class="on-hover-opaque" start show title="Edit">
+                                    <i class="font-size-11 fa fa-edit"></i>
+                                </a>
+                                <form url="/api/clientMemo/update" right>
+                                    <input type="hidden" name="uid" value="{{ $memo->uid }}">
+                                    <div class="mb-2">
+                                        <select class="form-control form-control-sm" name="category" required>
+                                            <option value="">-- select --</option>
+                                            <option {{ $memo->category === "Incoming Call" ? "selected" : "" }} value="Incoming Call">Incoming Call</option>
+                                            <option {{ $memo->category === "Outgoing Call" ? "selected" : "" }} value="Outgoing Call">Outgoing Call</option>
+                                            <option {{ $memo->category === "Call Unspecified" ? "selected" : "" }} value="Call Unspecified">Call Unspecified</option>
+                                            <option {{ $memo->category === "Other" ? "selected" : "" }} value="Other">Other</option>
+                                        </select>
+                                    </div>
+                                    <div class="mb-2">
+                                        <textarea class="form-control form-control-sm" name="content" rows="5" placeholder="Content"><?= $memo->content ?></textarea>
+                                    </div>
+                                    <div class="d-flex align-items-center">
+                                        <button class="btn btn-sm btn-primary mr-2" type="button" submit>Save</button>
+                                        <button class="btn btn-sm btn-default mr-2 border" type="button" cancel>Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                            <div moe relative>
+                                <a start show class="on-hover-opaque"><i class="fa fa-trash-alt text-danger"></i></a>
+                                <form url="/api/clientMemo/cancel" right>
+                                    <input type="hidden" name="uid" value="{{ $memo->uid }}">
+                                    <p class="small">Are you sure you want to cancel this memo?</p>
+                                    <div class="d-flex align-items-center">
+                                        <button class="btn btn-sm btn-danger mr-2" submit>Delete</button>
+                                        <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        </td>
+                    </tr>
+                    @endforeach
+
+                    @if(count($memos) === 0)
+                    <tr>
+                        <td colspan="4">No records found!</td>
+                    </tr>
+                    @endif
+                </tbody>
+
+            </table>
+            <div class="ml-2 mt-2">
+                {{ $memos->appends(request()->input())->links() }}
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 110 - 0
resources/views/app/mcp/memos_filters.blade.php

@@ -0,0 +1,110 @@
+<style>
+	#mcp-memos-filters label {
+		font-weight: bold;
+	}
+
+	#mcp-memos-filters .mw-100px {
+		min-width: 100px;
+	}
+
+	.filter-container {
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+
+	.filter-container>div {
+		width: 165px;
+	}
+
+	.filter-container>div:not(:last-child) {
+		margin-right: 15px;
+	}
+</style>
+<form id="mcp-memos-filters" method="GET" action="{{ route('mcp.memos') }}" class="filter-container" v-cloak>
+	<!-- DATE	 -->
+	<div>
+		<div class="form-group">
+			<label>Date:</label>
+			<select name="date_category" class="form-control input-sm" v-model="filters.date_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.date_category" class="mt-2">
+				<div>
+					<input name="date_value_1" v-model="filters.date_value_1" type="date" class="form-control input-sm" />
+				</div>
+				<div v-show="filters.date_category === 'BETWEEN' || filters.date_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="date_value_2" v-model="filters.date_value_2" type="date" class="form-control input-sm" />
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- STATUS -->
+	<div>
+		<div class="form-group">
+			<label>Category:</label>
+			<select name="category" class="form-control input-sm" v-model="filters.category">
+				<option value="">All</option>
+				<option value="Incoming Call">Incoming Call</option>
+				<option value="Outgoing Call">Outgoing Call</option>
+				<option value="Call Unspecified">Call Unspecified</option>
+				<option value="Other">Other</option>
+			</select>
+		</div>
+	</div>
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<div class="d-flex">
+				<button type="submit" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('mcp.memos')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'date_category',
+	'date_value_1',
+	'date_value_2',
+	'category'
+];
+for ($i = 0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+<script>
+	(function() {
+		function init() {
+			window.apapp = new Vue({
+				el: '#mcp-memos-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					doSubmit: function() {
+						fastLoad('{{ route("mcp.memos") }}?' + $('#mcp-memos-filters').serialize());
+						return false;
+					},
+					init: function() {
+
+					}
+				},
+				mounted: function() {
+					this.init();
+				},
+			});
+		}
+		addMCInitializer('mcp-memos-filters', init, '#mcp-memos-filters');
+	})();
+</script>

+ 10 - 1
resources/views/app/mcp/patients-table.blade.php

@@ -30,7 +30,16 @@
 			<td class="text-nowrap">{{ friendly_date_time($patient->dob, false) }}</td>
 			<td>{{ $patient->age_in_years ?  $patient->age_in_years : '-' }}</td>
 			<td>{{ $patient->sex }}</td>
-			<td>{{ $patient->usual_bmi }}</td>
+			<td>
+				<div class="d-flex flex-column">
+					@if($patient->usual_bmi_min && $patient->usual_bmi_max)
+						<small class="text-muted">BMI (Usual): <b>{{ $patient->usual_bmi_min }}</b> {{ $patient->usual_bmi_min_category }} to <b>{{ $patient->usual_bmi_max }}</b> {{ $patient->usual_bmi_max_category }}</small>
+					@endif
+					@if($patient->ideal_bmi)
+						<small class="text-muted">BMI (Ideal) <b>{{ $patient->ideal_bmi }}</b> {{ $patient->ideal_bmi_category }}</small>
+					@endif
+				</div>
+			</td>
 			<td>
 				<?php $coverageStatus = $patient->getPrimaryCoverageStatus(); ?>
 				<div class="text-nowrap">

+ 189 - 361
resources/views/app/patient/canvas-migrate.blade.php

@@ -1,6 +1,25 @@
 @extends ('layouts.patient')
 
 @section('inner-content')
+    <style>
+        #patient-canvas-migrate .rhs .min-height-500px {
+          min-height: unset !important;
+        }
+        #patient-canvas-migrate .rhs .point-content #frm-add-allergy>.row>.col-4.border-left,
+        #patient-canvas-migrate .rhs .point-content #frm-add-problem>.row>.col-4.border-left,
+        #patient-canvas-migrate .rhs .point-content #frm-add-medication>.row>.col-4.border-left,
+        #patient-canvas-migrate .rhs .point-content #frm-add-care-team-member>.row>.col-4.border-left {
+          display: none;
+        }
+        #patient-canvas-migrate .rhs .point-content #allergies-center-{{$patient->coreNote->id}},
+        #patient-canvas-migrate .rhs .point-content #problems-center-{{$patient->coreNote->id}},
+        #patient-canvas-migrate .rhs .point-content #medications-center-{{$patient->coreNote->id}},
+        #patient-canvas-migrate .rhs .point-content #careteam-center-{{$patient->coreNote->id}} {
+          border: 0 !important;
+          padding: 0 !important;
+          margin: 0 !important;
+        }
+    </style>
     <?php
     $shortCutsObject = [];
     foreach ($pro->allShortcuts() as $shortcut) {
@@ -19,7 +38,7 @@
     <script>window.userShortcuts = <?= json_encode($shortCutsObject); ?>;</script>
     <link href="/select2/select2.min.css" rel="stylesheet" />
     <script src="/select2/select2.min.js"></script>
-    <div>
+    <div id="patient-canvas-migrate">
 
         {{-- CARE PLAN START --}}
         <?php $infoLines = json_decode($patient->info_lines);?>
@@ -27,394 +46,203 @@
         <?php $vitalLabels = ['Ht. (in.)','Wt. (lbs.)','Temp. (F)','Pulse','Resp.','Pulse Ox.','SBP','DBP','Smoking Status', 'BMI']; ?>
         <?php $isOldClient = (date_diff(date_create(config('app.point_impl_date')), date_create($patient->created_at))->invert === 1); ?>
 
-	    <div class="row client-single-dashboard">
-            <div class="col-6">
-
-                {{-- canvas based allergies --}}
-                @if($isOldClient)
-                <div class="pt-2 mt-2 border-top">
-                    <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">Allergies</h6>
-                        <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                    </div>
-                    <div class="bg-light border p-2 mb-3">
-                        @include('app.patient.canvas-sections.allergies.summary')
-                    </div>
-                </div>
-                @endif
-
-                {{-- canvas based dx --}}
-                @if($isOldClient)
-                    <div class="pt-2 mt-2 border-top">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Current Problems / Focus Areas</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                        </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.dx.summary')
+        <div class="client-single-dashboard">
+
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- canvas based allergies --}}
+                    @if($isOldClient)
+                        <div class="pt-2 mt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Allergies</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.allergies.summary')
+                            </div>
                         </div>
-                    </div>
-                @endif
-
-
-
-                {{-- canvas based rx --}}
-                @if($isOldClient)
-                <div class="pt-2 mt-2 border-top">
-                    <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">Current Medications</h6>
-                        <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                    </div>
-                    <div class="bg-light border p-2 mb-3">
-                        @include('app.patient.canvas-sections.rx.summary')
-                    </div>
+                    @endif
                 </div>
-                @endif
+                <div class="col-6 rhs">
+                    <!-- allergies - point -->
+                    @include('app.patient.point-based-partials.allergies')
+                </div>
+            </div>
 
-                {{-- canvas based careteam --}}
-                @if($isOldClient)
-                    <div class="pt-2 mt-2 border-top">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Care Team</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- canvas based dx --}}
+                    @if($isOldClient)
+                        <div class="mt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Current Problems / Focus Areas</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.dx.summary')
+                            </div>
                         </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.care-team.summary')
-                        </div>
-                    </div>
-                @endif
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- probs - point -->
+                    @include('app.patient.point-based-partials.dx')
+                </div>
+            </div>
 
-                {{-- history_medical --}}
-                @if($isOldClient)
-                    <div class="pt-2 mt-2 border-top">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Medical History</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                        </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.pmhx.summary')
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- canvas based rx --}}
+                    @if($isOldClient)
+                        <div class="pt-2 mt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Current Medications</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.rx.summary')
+                            </div>
                         </div>
-                    </div>
-                @endif
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- meds - point -->
+                    @include('app.patient.point-based-partials.rx')
+                </div>
+            </div>
 
-                {{-- history_surgical --}}
-                @if($isOldClient)
-                    <div class="mt-2 border-top pt-2">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Surgical History</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                        </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.pshx.summary')
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- canvas based careteam --}}
+                    @if($isOldClient)
+                        <div class="pt-2 mt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Care Team</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.care-team.summary')
+                            </div>
                         </div>
-                    </div>
-                @endif
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- careteam - point -->
+                    @include('app.patient.point-based-partials.care-team')
+                </div>
+            </div>
 
-                {{-- history_family --}}
-                @if($isOldClient)
-                    <div class="mt-2 border-top pt-2">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Family History</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- history_medical --}}
+                    @if($isOldClient)
+                        <div class="pt-2 mt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Medical History</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.pmhx.summary')
+                            </div>
                         </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.fhx.summary')
-                        </div>
-                    </div>
-                @endif
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- pmhx - point -->
+                    @include('app.patient.point-based-partials.pmhx')
+                </div>
+            </div>
 
-                {{-- history_social --}}
-                @if($isOldClient)
-                    <div class="mt-2 border-top pt-2">
-                        <div class="d-flex align-items-center pb-2">
-                            <h6 class="my-0 font-weight-bold text-secondary">Social History</h6>
-                            <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- history_surgical --}}
+                    @if($isOldClient)
+                        <div class="mt-2 pt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Surgical History</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.pshx.summary')
+                            </div>
                         </div>
-                        <div class="bg-light border p-2 mb-3">
-                            @include('app.patient.canvas-sections.sochx.summary')
-                        </div>
-                    </div>
-                @endif
-
-
-                {{-- vitals --}}
-                {{--@include('app/patient/partials/vitals')--}}
-
-                {{-- canvas based vitals --}}
-                @if($isOldClient)
-                <div class="pt-2 border-top">
-                    <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">Vitals</h6>
-                        <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
-                    </div>
-                    <div class="bg-light border p-2 mb-3">
-                        @include('app.patient.canvas-sections.vitals.summary')
-                    </div>
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- pshx - point -->
+                    @include('app.patient.point-based-partials.shx')
                 </div>
-                @endif
-
             </div>
-            <div class="col-6">
-
-                <!-- allergies - point -->
-                @include('app.patient.point-based-partials.allergies')
-
-
-                <!-- probs - point -->
-                @include('app.patient.point-based-partials.dx')
-
-                <!-- meds - point -->
-                @include('app.patient.point-based-partials.rx')
-
-
-                <!-- careteam - point -->
-                @include('app.patient.point-based-partials.care-team')
-
-
-                <!-- pmhx - point -->
-                @include('app.patient.point-based-partials.pmhx')
-
-                <!-- pshx - point -->
-                @include('app.patient.point-based-partials.shx')
-
-                <!-- fhx - point -->
-                @include('app.patient.point-based-partials.fhx')
-
 
-                <!-- sochx - point -->
-                @include('app.patient.point-based-partials.sochx')
-
-                <!-- vitals - point -->
-                <?php $latestVitals = \App\Models\Point::where('client_id', $patient->id)->where('category', 'VITALS')->orderBy('id', 'DESC')->first(); ?>
-                <div class="pt-2 mt-2">
-                    <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">Vitals
-                            @if(!!$latestVitals && $latestVitals->note && $latestVitals->note->effective_dateest)
-                                <span class="text-secondary font-weight-normal pl-1">(as on
-                                    <a href="{{route('patients.view.notes.view.dashboard', ['patient' => $patient, 'note' => $latestVitals->note])}}">{{friendlier_date($latestVitals->note->effective_dateest)}}</a>)
-                                </span>
-                            @endif
-                        </h6>
-                        @if($isOldClient)
-                            <div class="px-2 font-weight-bold alert alert-info text-sm my-0 ml-2 py-1">New</div>
-                        @endif
-                    </div>
-                    <div class="bg-light border p-2 mb-3">
-                        @if(!!$latestVitals)
-                            @include('app.patient.partials.latest-vitals', ['patient' => $patient, 'point' => $latestVitals])
-                        @else
-                            <div class="text-secondary">Nothing here yet</div>
-                        @endif
-                    </div>
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- history_family --}}
+                    @if($isOldClient)
+                        <div class="mt-2 pt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Family History</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.fhx.summary')
+                            </div>
+                        </div>
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- fhx - point -->
+                    @include('app.patient.point-based-partials.fhx')
                 </div>
-
-
             </div>
-        </div>
-        <?php /* <div class="row my-3">
-            <div class="col-12">
-                {{-- erx --}}
-                <div  class="mb-2 pt-3 pb-2 border-top">
-                    <style>
-                        td.fit {
-                            width:1%;
-                            white-space:nowrap;
-                        }
-                    </style>
-                    <div class="d-flex align-items-center pb-2">
-                        <h6 class="my-0 font-weight-bold text-secondary">ERx</h6>
-                        <span class="mx-2 text-secondary">|</span>
-                        <div moe>
-                            <a start show class="py-0 font-weight-normal">Add</a>
-                            <form url="/api/actionItem/create" wide>
-                                <input type="hidden" name="clientUid" value="{{ $patient->uid }}">
-                                <input type="hidden" name="prescriberProUid" value="{{ $pro->uid }}">
-                                <input type="hidden" name="category" value="DRUG">
-                                <div class="mb-2">
-                                    <label for="" class="control-label text-sm text-secondary mb-1">Pharmacy</label>
-                                    <select name="toFacilityUid"
-                                            class="form-control form-control-sm">
-                                        <option value="">-- Pharmacy --</option>
-                                        @foreach ($facilities as $facility)
-                                            <option value="{{$facility->uid}}">{{$facility->name}}</option>
-                                        @endforeach
-                                    </select>
-                                </div>
-                                <div class="mb-2">
-                                    <input type="text" class="form-control form-control-sm" name="contentText" value="" placeholder="Title *" required>
-                                </div>
-                                <div class="mb-2">
-                                    <input type="text" class="form-control form-control-sm" name="contentDetail" value="" placeholder="Directions">
-                                </div>
-                                <div class="d-flex align-items-center">
-                                    <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
-                                    <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
-                                </div>
-                            </form>
+
+            <div class="row border-bottom mb-4 pb-4">
+                <div class="col-6">
+                    {{-- history_social --}}
+                    @if($isOldClient)
+                        <div class="mt-2 pt-2">
+                            <div class="d-flex align-items-center pb-2">
+                                <h6 class="my-0 font-weight-bold text-secondary">Social History</h6>
+                                <div class="px-2 font-weight-bold alert alert-warning text-sm my-0 ml-2 py-1">Deprecated</div>
+                            </div>
+                            <div class="bg-light border p-2 mb-3">
+                                @include('app.patient.canvas-sections.sochx.summary')
+                            </div>
                         </div>
-                    </div>
-                    <table class="table table-sm table-bordered mb-0" style="table-layout: fixed">
-                        <thead>
-                        <tr>
-                            <th class="px-2 text-secondary border-bottom-0 w-25">Prescription</th>
-                            <th class="px-2 text-secondary border-bottom-0 fit">Created</th>
-                            <th class="px-2 text-secondary border-bottom-0 fit">Status</th>
-                            <th class="px-2 text-secondary border-bottom-0 fit">Pharmacy</th>
-                            <th class="px-2 text-secondary border-bottom-0">&nbsp;</th>
-                        </tr>
-                        </thead>
-                        <tbody>
-                        <?php $prevItemType = false; ?>
-                        @foreach($patient->actionItems as $item)
-                            @if($item->action_item_category === 'DRUG')
-                                <tr>
-                                    <td class="px-2">
-                                        {{$item->content_text}}
-                                        <span moe>
-                                        <a start show class="on-hover-opaque"><i class="fa fa-edit"></i></a>
-                                        <form url="/api/actionItem/updateContent" wide>
-                                            <input type="hidden" name="uid" value="{{ $item->uid }}">
-                                            <div class="mb-2">
-                                                <input type="text" class="form-control form-control-sm" name="contentText" value="{{ $item->content_text }}" placeholder="Title *" required>
-                                            </div>
-                                            <div class="mb-2">
-                                                <input type="text" class="form-control form-control-sm" name="contentDetail" value="{{ $item->content_detail }}" placeholder="Details">
-                                            </div>
-                                            <div class="d-flex align-items-center">
-                                                <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
-                                                <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
-                                            </div>
-                                        </form>
-                                    </span>
-                                        <div class="text-sm text-secondary">{{$item->content_detail}}</div>
-                                    </td>
-                                    <td class="px-2">{{friendly_date_time($item->created_at, false)}}</td>
-                                    <td class="px-2">
-                                        {{ucwords($item->status_category)}}
-                                        <span moe>
-                                        <a start show class="on-hover-opaque"><i class="fa fa-edit"></i></a>
-                                        <form url="/api/actionItem/updateStatus">
-                                            <input type="hidden" name="uid" value="{{ $item->uid }}">
-                                            <div class="mb-2">
-                                                <label for="" class="control-label text-sm text-secondary mb-1">Status *</label>
-                                                <select name="statusCategory" class="form-control form-control-sm" required>
-                                                    <option {{ $item->status_category === 'OPEN' ? 'selected' : '' }} value="OPEN">Open</option>
-                                                    <option {{ $item->status_category === 'CLOSED' ? 'selected' : '' }} value="CLOSED">Closed</option>
-                                                </select>
-                                            </div>
-                                            <div class="mb-2">
-                                                <input type="text" class="form-control form-control-sm" name="statusMemo" value="" placeholder="Memo">
-                                            </div>
-                                            <div class="d-flex align-items-center">
-                                                <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
-                                                <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
-                                            </div>
-                                        </form>
-                                    </span>
-                                    </td>
-                                    <td class="px-2">
-                                        {{$item->facility ? $item->facility->name : ''}}
-                                        <span moe>
-                                        <a start show class="on-hover-opaque"><i class="fa fa-edit"></i></a>
-                                        <form url="/api/actionItem/updateToFacility">
-                                            <input type="hidden" name="uid" value="{{ $item->uid }}">
-                                            <div class="mb-2">
-                                                <label for="" class="control-label text-sm text-secondary mb-1">Pharmacy *</label>
-                                                <select name="toFacilityUid" class="form-control form-control-sm" required>
-                                                    <option value="">-- Pharmacy --</option>
-                                                    @foreach ($facilities as $facility)
-                                                        <option {{ $item->to_facility_id === $facility->id ? 'selected' : '' }} value="{{$facility->uid}}">{{$facility->name}}</option>
-                                                    @endforeach
-                                                </select>
-                                            </div>
-                                            <div class="d-flex align-items-center">
-                                                <button class="btn btn-sm btn-primary mr-2" submit>Save</button>
-                                                <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
-                                            </div>
-                                        </form>
-                                    </span>
-                                    </td>
-                                    <td class="px-2 text-center">
-                                        <div class="d-flex align-items-center justify-content-start">
-                                            @if($item->is_signed_by_prescriber)
-                                                <span class="text-secondary">
-                                            <i class="fa fa-check"></i>
-                                            Signed
-                                        </span>
-                                                <span class="mx-2 text-secondary">|</span>
-                                            @else
-                                                @if($pro->id === $item->prescriber_pro_id)
-                                                    <span moe relative>
-                                                <a start show>Sign</a>
-                                                <form url="/api/actionItem/signAsPrescriber" right>
-                                                    <input type="hidden" name="uid" value="{{ $item->uid }}">
-                                                    <p class="small min-width-200px text-left">Sign this action items as the prescriber?</p>
-                                                    <div class="d-flex align-items-center">
-                                                        <button class="btn btn-sm btn-success mr-2" submit>Yes</button>
-                                                        <button class="btn btn-sm btn-default mr-2 border" cancel>No</button>
-                                                    </div>
-                                                </form>
-                                            </span>
-                                                    <span class="mx-2 text-secondary">|</span>
-                                                @endif
-                                            @endif
-                                            <span moe relative>
-                                        <a start show>eFax</a>
-                                        <form url="/api/actionItem/efax" right>
-                                            <input type="hidden" name="uid" value="{{ $item->uid }}">
-                                            <div class="mb-2">
-                                                <input type="text" class="form-control form-control-sm" name="toFaxNumber" value="" placeholder="To Number *" required>
-                                            </div>
-                                            <div class="d-flex align-items-center">
-                                                <button class="btn btn-sm btn-primary mr-2" submit>Send</button>
-                                                <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
-                                            </div>
-                                        </form>
-                                    </span>
-                                        </div>
-                                    </td>
-                                </tr>
-                            @endif
-                        @endforeach
-                        </tbody>
-                    </table>
+                    @endif
+                </div>
+                <div class="col-6 rhs">
+                    <!-- sochx - point -->
+                    @include('app.patient.point-based-partials.sochx')
                 </div>
             </div>
-        </div> */ ?>
+
+        </div>
+
 
     </div>
     <script>
         (function() {
             function init() {
-                $('select[name="deviceUid"]').select2({
-                    width: '100%'
-                });
+                $('#patient-canvas-migrate .rhs').each(function() {
+                    let trigger = $(this).find('[open-in-stag-popup]').first();
+                    $.get(trigger.attr('href'), _data => {
+                        trigger.closest('.rhs').find('.point-content').first().html(_data);
+                        runMCInitializer(trigger.attr('mc-initer'));
 
-                // refresh once ticket popup is closed
-                $('body').off('stag-popup-closed')
-                /*$('body').on('stag-popup-closed', function() {
-                    if($('#client-rx-container').length) {
-                        fastReload();
-                    }
-                });*/
-                // ticket-popup
-                $(document)
-                    .off('click', '.ticket-popup-trigger')
-                    .on('click', '.ticket-popup-trigger', function() {
-                        showMask();
-                        window.noMc = true;
-                        $.get(this.href, (_data) => {
-                            $('.ticket-popup').html(_data);
-                            showStagPopup('ticket-popup', true);
-                            // $('.ticket-popup .stag-popup.stag-slide').attr('close-all-with-self', 1);
-                            runMCInitializer('patient-tickets'); // run specific mc initer
-                            hideMask();
-                        });
-                        return false;
-                    });
+                        $('#patient-canvas-migrate .rhs .point-content #frm-add-allergy>.row>.col-8').removeClass('col-8').addClass('col-12');
+                        $('#patient-canvas-migrate .rhs .point-content #frm-add-problem>.row>.col-8').removeClass('col-8').addClass('col-12');
+                        $('#patient-canvas-migrate .rhs .point-content #frm-add-medication>.row>.col-8').removeClass('col-8').addClass('col-12');
+                        $('#patient-canvas-migrate .rhs .point-content #frm-add-care-team-member>.row>.col-8').removeClass('col-8').addClass('col-12');
+
+                        $('#patient-canvas-migrate .rhs .point-content>.p-3.border-top.mt-3.mcp-theme-1')
+                            .removeClass()
+                            .parent().addClass('overflow-hidden');
 
+                    });
+                    trigger.addClass('opacity-0');
+                })
             }
-            addMCInitializer('patient-dashboard-devices', init, '#patient-dashboard-devices');
+            addMCInitializer('patient-canvas-migrate', init, '#patient-canvas-migrate');
 
         }).call(window);
     </script>

+ 28 - 0
resources/views/app/patient/memos-thread.blade.php

@@ -0,0 +1,28 @@
+<div class="p-3 mt-3 border-top">
+    <table class="table table-striped table-sm table-bordered">
+        @if($patient->memos && count($patient->memos))
+            <thead>
+            <tr>
+                <th class="px-2 text-secondary border-bottom-0 w-25">Category</th>
+                <th class="px-2 text-secondary border-bottom-0 w-50">Summary</th>
+                <th class="px-2 text-secondary border-bottom-0">Created</th>
+            </tr>
+            </thead>
+            <tbody>
+            @foreach($patient->memos as $memo)
+                <tr>
+                    <td class="px-2">{{ $memo->category }}</td>
+                    <td class="px-2"><pre class="m-0 break-spaces">{{ $memo->content }}</pre></td>
+                    <td class="px-2">{{ friendly_date_time($memo->created_at) }}</td>
+                </tr>
+            @endforeach
+            </tbody>
+        @else
+            <tbody>
+            <tr>
+                <td class="text-secondary p-3">No memos have been created for this patient</td>
+            </tr>
+            </tbody>
+        @endif
+    </table>
+</div>

+ 32 - 0
resources/views/app/patient/messages-thread.blade.php

@@ -0,0 +1,32 @@
+<div class="p-3 mt-3 border-top">
+    <table class="table table-striped table-sm table-bordered">
+        @if($patient->smses && count($patient->smses))
+            <thead>
+            <tr>
+                <th class="px-2 text-secondary border-bottom-0">Date &amp; Time</th>
+                <th class="px-2 text-secondary border-bottom-0 w-25">Type</th>
+                <th class="px-2 text-secondary border-bottom-0 w-25">From</th>
+                <th class="px-2 text-secondary border-bottom-0 w-25">To</th>
+                <th class="px-2 text-secondary border-bottom-0 w-50">Content</th>
+            </tr>
+            </thead>
+            <tbody>
+            @foreach($patient->smses as $sms)
+                <tr>
+                    <td class="px-2">{{ friendly_date_time($sms->created_at) }}</td>
+                    <td class="px-2">{{ ucwords($sms->incoming_or_outgoing) }}</td>
+                    <td class="px-2">{{ $sms->from_number }}</td>
+                    <td class="px-2">{{ $sms->to_number }}</td>
+                    <td class="px-2">{{ $sms->body }}</td>
+                </tr>
+            @endforeach
+            </tbody>
+        @else
+            <tbody>
+            <tr>
+                <td class="text-secondary p-3">No messages for this patient</td>
+            </tr>
+            </tbody>
+        @endif
+    </table>
+</div>

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

@@ -2409,13 +2409,6 @@
                                 <span>Handouts</span>
                             </div>
                         </div>
-                        <div class="ml-auto mr-5 nbt-container border-info 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>
                     @endif
 

+ 39 - 47
resources/views/app/patient/note/rhs-sidebar.blade.php

@@ -5,17 +5,15 @@ $problems = \App\Models\Point::getPointsOfCategory($patient, "PROBLEM");
 $goals = \App\Models\Point::getPointsOfCategory($patient, "GOAL");
 $prescriptions = $patient->prescriptionsCreatedInNote($note);
 ?>
-<div id="active-allergies" class="px-2 pb-2 border-bottom mb-2">
-    <div class="font-weight-bold mb-2">Allergies
-        <a native target="_blank"
-             class="c-pointer pl-1 text-primary"
-             open-in-stag-popup
-             mc-initer="allergies-center-{{$note->id}}"
-             title="Allergies Center"
-             popup-style="wide overflow-visible"
-             href="/allergies-center/{{$patient->uid}}/{{$note->uid}}">
-            <i class="fa fa-bolt mr-1"></i>
-        </a>
+<div id="active-allergies" class="p-2 border-bottom c-pointer on-hover-aliceblue"
+     open-in-stag-popup
+     mc-initer="allergies-center-{{$note->id}}"
+     title="Allergies Center"
+     popup-style="wide overflow-visible"
+     href="/allergies-center/{{$patient->uid}}/{{$note->uid}}">
+    <div class="font-weight-bold mb-2">
+        Allergies
+        <i class="fa fa-bolt text-primary ml-1"></i>
     </div>
     @if($allergies && count($allergies))
         @foreach($allergies as $allergy)
@@ -29,17 +27,15 @@ $prescriptions = $patient->prescriptionsCreatedInNote($note);
         <span class="px-1 text-secondary">None</span>
     @endif
 </div>
-<div id="active-medications" class="px-2 pb-2 border-bottom mb-2">
-    <div class="font-weight-bold mb-2">Medications
-        <a native target="_blank"
-           class="c-pointer pl-1 text-primary"
-           open-in-stag-popup
-           mc-initer="medications-center-{{$note->id}}"
-           title="Medications Center"
-           popup-style="wide overflow-visible"
-           href="/medications-center/{{$patient->uid}}/{{$note->uid}}">
-            <i class="fa fa-bolt mr-1"></i>
-        </a>
+<div id="active-medications" class="p-2 border-bottom c-pointer on-hover-aliceblue"
+     open-in-stag-popup
+     mc-initer="medications-center-{{$note->id}}"
+     title="Medications Center"
+     popup-style="wide overflow-visible"
+     href="/medications-center/{{$patient->uid}}/{{$note->uid}}">
+    <div class="font-weight-bold mb-2">
+        Medications
+        <i class="fa fa-bolt text-primary ml-1"></i>
     </div>
     @if($medications && count($medications))
         @foreach($medications as $medication)
@@ -53,17 +49,15 @@ $prescriptions = $patient->prescriptionsCreatedInNote($note);
         <span class="px-1 text-secondary">None</span>
     @endif
 </div>
-<div id="active-problems" class="px-2 pb-2 border-bottom mb-2">
-    <div class="font-weight-bold mb-2">Problems
-        <a native target="_blank"
-           class="c-pointer pl-1 text-primary"
-           open-in-stag-popup
-           mc-initer="problems-center-{{$note->id}}"
-           title="Problems Center"
-           popup-style="wide overflow-visible"
-           href="/problems-center/{{$patient->uid}}/{{$note->uid}}">
-            <i class="fa fa-bolt mr-1"></i>
-        </a>
+<div id="active-problems" class="p-2 border-bottom c-pointer on-hover-aliceblue"
+     open-in-stag-popup
+     mc-initer="problems-center-{{$note->id}}"
+     title="Problems Center"
+     popup-style="wide overflow-visible"
+     href="/problems-center/{{$patient->uid}}/{{$note->uid}}">
+    <div class="font-weight-bold mb-2">
+        Problems
+        <i class="fa fa-bolt text-primary ml-1"></i>
     </div>
     @if($problems && count($problems))
         @foreach($problems as $problem)
@@ -77,17 +71,15 @@ $prescriptions = $patient->prescriptionsCreatedInNote($note);
         <span class="px-1 text-secondary">None</span>
     @endif
 </div>
-<div id="active-goals" class="px-2 pb-2 border-bottom mb-2">
-    <div class="font-weight-bold mb-2">Goals
-        <a native target="_blank"
-           class="c-pointer pl-1 text-primary"
-           open-in-stag-popup
-           mc-initer="goals-center-{{$note->id}}"
-           title="Goals Center"
-           popup-style="wide overflow-visible"
-           href="/goals-center/{{$patient->uid}}/{{$note->uid}}">
-            <i class="fa fa-bolt mr-1"></i>
-        </a>
+<div id="active-goals" class="p-2 border-bottom c-pointer on-hover-aliceblue"
+     open-in-stag-popup
+     mc-initer="goals-center-{{$note->id}}"
+     title="Goals Center"
+     popup-style="wide overflow-visible"
+     href="/goals-center/{{$patient->uid}}/{{$note->uid}}">
+    <div class="font-weight-bold mb-2">
+        Goals
+        <i class="fa fa-bolt text-primary ml-1"></i>
     </div>
     @if($goals && count($goals))
         @foreach($goals as $goal)
@@ -101,9 +93,9 @@ $prescriptions = $patient->prescriptionsCreatedInNote($note);
         <span class="px-1 text-secondary">None</span>
     @endif
 </div>
-<div id="note-prescriptions" class="px-2 pb-2 border-bottom mb-2">
-    <div class="font-weight-bold mb-2">ERx &amp; Orders
-        <a native="" target="_top" data-non-segment-target="Prescriptions" href="#" class="font-weight-normal">View All</a>
+<div id="note-prescriptions" class="p-2 border-bottom c-pointer on-hover-aliceblue" data-non-segment-target="Prescriptions">
+    <div class="font-weight-bold mb-2">
+        ERx &amp; Orders
     </div>
     @if($prescriptions && count($prescriptions))
         @foreach($prescriptions as $prescription)

+ 4 - 4
resources/views/app/patient/note/segment_script.blade.php

@@ -307,14 +307,14 @@
             };
 
             let debouncedSaver = debounce(function(_trigger) {
-                $('.autosave-indicator').removeClass('show');
-                $('.autosave-indicator.saving').addClass('show');
+                $(_trigger).closest('.visit-segment').find('.autosave-indicator').removeClass('show');
+                $(_trigger).closest('.visit-segment').find('.autosave-indicator.saving').addClass('show');
                 saveVisitForm(_trigger, true, false, () => {
                     $('.autosave-indicator').removeClass('show');
                     $('.autosave-indicator.saved').addClass('show');
-                    window.setTimeout(() => {
+                    /*window.setTimeout(() => {
                         $('.autosave-indicator').removeClass('show');
-                    }, 1000);
+                    }, 1000);*/
                 });
             }, 500);
 

+ 4 - 9
resources/views/app/patient/partials/appointments.blade.php

@@ -24,18 +24,13 @@
                 ?>
                 <tr class="{{$bgColor}}">
                     <td class="align-middle">
-                        <a href="/patients/view/{{$appointment->client->uid}}" class="font-weight-bold d-block">
-                            {{$appointment->client->displayName() }}
-                        </a>
+                        <b>{{$appointment->pro->displayName() }}</b>
                         <div class="mt-1">
-                            <b>{{friendly_date($appointment->raw_date)}}</b>&nbsp;&nbsp;
-                            {{ friendly_time($appointment->raw_start_time) }} - {{ friendly_time($appointment->raw_end_time) }}
+                            <a href="/patients/view/{{$appointment->client->uid}}/calendar/{{$appointment->uid}}">
+                                <b>{{friendly_date($appointment->raw_date)}}</b>
+                                {{ friendly_time($appointment->raw_start_time) }} - {{ friendly_time($appointment->raw_end_time) }}</a>
                             <span class="text-secondary">{{ friendly_timezone($appointment->timezone) }}</span>
                         </div>
-                        <a href="'/patients/view/{{$appointment->client->uid}}/calendar/{{$appointment->uid}}"
-                           class="d-block mt-1">
-                            <i class="fa fa-edit"></i>
-                        </a>
                         @if($appointment->title)
                             <span class="d-inline-block mt-1 text-secondary text-sm">
                             {{ $appointment->title }}

+ 1 - 1
resources/views/app/patient/point-based-partials/allergies.blade.php

@@ -21,7 +21,7 @@ $allergies = \App\Models\Point::getPointsOfCategory($patient, "ALLERGY");
             </a>
         @endif
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @foreach($allergies as $allergy)
             <div class="mb-1">
                 <b><?= !!@($allergy->data->name) ? @($allergy->data->name) : '-' ?></b>

+ 1 - 1
resources/views/app/patient/point-based-partials/care-team.blade.php

@@ -21,7 +21,7 @@ $careTeamMembers = \App\Models\Point::getPointsOfCategory($patient, "CARE_TEAM_M
             </a>
         @endif
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @foreach($careTeamMembers as $careTeamMember)
             <div class="mb-1">
                 <b><?= !!@($careTeamMember->data->name) ? @($careTeamMember->data->name) : '-' ?></b>

+ 1 - 1
resources/views/app/patient/point-based-partials/dx.blade.php

@@ -21,7 +21,7 @@ $problems = \App\Models\Point::getPointsOfCategory($patient, "PROBLEM");
             </a>
         @endif
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @foreach($problems as $problem)
             <div class="mb-1">
                 <b><?= !!@($problem->data->name) ? @($problem->data->name) : '-' ?></b>

+ 1 - 1
resources/views/app/patient/point-based-partials/fhx.blade.php

@@ -14,7 +14,7 @@
             <span>Manage</span>
         </a>
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @include('app.patient.segment-templates.history_family.summary', compact('patient'))
     </div>
 </div>

+ 1 - 1
resources/views/app/patient/point-based-partials/pmhx.blade.php

@@ -14,7 +14,7 @@
             <span>Manage</span>
         </a>
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @include('app.patient.segment-templates.past_medical_history.summary', compact('patient'))
     </div>
 </div>

+ 1 - 1
resources/views/app/patient/point-based-partials/rx.blade.php

@@ -21,7 +21,7 @@ $medications = \App\Models\Point::getPointsOfCategory($patient, "MEDICATION");
             </a>
         @endif
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @foreach($medications as $medication)
             <div class="mb-1">
                 <b><?= !!@($medication->data->name) ? @($medication->data->name) : '-' ?></b>

+ 1 - 1
resources/views/app/patient/point-based-partials/shx.blade.php

@@ -14,7 +14,7 @@
             <span>Manage</span>
         </a>
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @include('app.patient.segment-templates.history_surgical.summary', compact('patient'))
     </div>
 </div>

+ 1 - 1
resources/views/app/patient/point-based-partials/sochx.blade.php

@@ -14,7 +14,7 @@
             <span>Manage</span>
         </a>
     </div>
-    <div class="bg-light border p-2 mb-3">
+    <div class="bg-light border p-2 mb-3 point-content">
         @include('app.patient.segment-templates.history_social.summary', compact('patient'))
     </div>
 </div>

+ 1 - 1
resources/views/app/patient/problems-center.blade.php

@@ -250,7 +250,7 @@ $ccSegment = $ccSegment ?? $note->getSegmentByInternalName('mc_cc');
                                     <input type="text"
                                            data-name="icd"
                                            data-option-list
-                                           class="form-control form-control-sm"
+                                           class="form-control form-control-sm min-width-unset"
                                            disabled>
                                     <div class="data-option-list"></div>
                                 </div>

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

@@ -27,7 +27,7 @@
                            v-model="item.value">
                     <div class="ml-2 pr-3">
                         <div>
-                            <span class="mr-2">@{{ item.label }}</span>
+                            <span class="mr-2 custom-item">@{{ item.label }}</span>
                             <div moe relative no-mask v-show="item.value" >
                                 <a href="#" start show>
                                     <i class="fa-comment" :class="item.comments ? 'fas' : 'far'"></i>

+ 55 - 0
resources/views/app/patient/segment-templates/_custom_items/script.blade.php

@@ -0,0 +1,55 @@
+saveCustomItem: function(_label) {
+    if(!_label) return false;
+    let self = this;
+
+    // check for duplicates
+    let found = false;
+    $(this.$el).find('.common-item').each(function() {
+        if($.trim($(this).text()).toLowerCase() === $.trim(_label).toLowerCase()) {
+            found = true;
+            return false;
+        }
+    });
+    if(found) {
+        toastr.error(_label + ' is already available in common items.');
+        return false;
+    }
+    found = false;
+    $(this.$el).find('.custom-item').each(function() {
+        if($.trim($(this).text()).toLowerCase() === $.trim(_label).toLowerCase()) {
+            found = true;
+            return false;
+        }
+    });
+    if(found) {
+        toastr.error(_label + ' is already available in custom items.');
+        return false;
+    }
+
+    showMask();
+    $.post('/api/clientCanvasCustomItem/create', {
+        proUid: '{{ $pro->uid }}',
+        key: self.itemKey,
+        label: _label
+    }, function(_data) {
+        hideMask();
+        if(_data && _data.success) {
+            hideMoeFormMask();
+            $('[custom-item-form]').hide();
+            self.customFields.push({
+                label: _label,
+                value: '',
+                comments: '',
+            });
+        }
+        else {
+            toastr.error(_data.message);
+        }
+    }, 'json')
+    return false;
+},
+cancelCustomItem: function() {
+    hideMoeFormMask();
+    $('[custom-item-form]').hide();
+    return false;
+},

+ 8 - 2
resources/views/app/patient/segment-templates/_simple_text_segment/edit.php

@@ -18,8 +18,14 @@ if (!!@$point->data) {
              data-field-name="free_text"
         ><?= $parsed && @$parsed->free_text ? $parsed->free_text : '' ?></div>
         <div>
-            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+            <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>

+ 8 - 2
resources/views/app/patient/segment-templates/chief_complaint/edit.blade.php

@@ -51,8 +51,14 @@ if(!$parsed || !@$parsed->free_text) {
              data-field-name="free_text"
         ><?= $parsed && @$parsed->free_text ? $parsed->free_text : '' ?></div>
         <div>
-            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+            <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>

+ 17 - 4
resources/views/app/patient/segment-templates/history_family/edit.blade.php

@@ -278,10 +278,23 @@ if(!$contentData) {
 
             </div>
 
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-                <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
-            </div>
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
 
         </form>
     </div>

+ 17 - 4
resources/views/app/patient/segment-templates/history_screenings/edit.blade.php

@@ -65,10 +65,23 @@ if(!$contentData) {
 
             </div>
 
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-                <button cancel class="btn btn-sm btn-default border">Cancel</button>
-            </div>
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
 
         </form>
     </div>

+ 21 - 36
resources/views/app/patient/segment-templates/history_social/edit.blade.php

@@ -83,7 +83,7 @@ for ($i = 0; $i < count($fields); $i++) {
                                                    v-model="common['{{$fName}}']">
                                             <div class="ml-2">
                                                 <div>
-                                                    <span class="mr-2">{{ $values[$k] }}</span>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
                                                     <div moe relative no-mask v-show="common['{{$fName}}']" >
                                                         <a href="#" start show>
                                                             <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
@@ -123,10 +123,23 @@ for ($i = 0; $i < count($fields); $i++) {
                 </div>
             </div>
 
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-                <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
-            </div>
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
 
         </form>
     </div>
@@ -172,6 +185,8 @@ for ($i = 0; $i < count($fields); $i++) {
                 return a.label.localeCompare(b.label);
             });
 
+            model.itemKey = 'sochx';
+
             new Vue({
                 el: '#edit-univ_history_social-container',
                 delimiters: ["@{{","}}"],
@@ -190,37 +205,7 @@ for ($i = 0; $i < count($fields); $i++) {
                     }
                 },
                 methods: {
-                    saveCustomItem: function(_label) {
-                        if(!_label) return false;
-                        showMask();
-                        let self = this;
-                        $.post('/api/clientCanvasCustomItem/create', {
-                            proUid: '{{ $pro->uid }}',
-                            key: 'sochx',
-                            label: _label
-                        }, function(_data) {
-                            hideMask();
-                            if(_data && _data.success) {
-                                hideMoeFormMask();
-                                $('[custom-item-form]').hide();
-                                // $('.custom-items-container').closest('.visit-segment').find('.refresh-segment').trigger('click');
-                                self.customFields.push({
-                                    label: _label,
-                                    value: '',
-                                    comments: '',
-                                });
-                            }
-                            else {
-                                toastr.error(_data.message);
-                            }
-                        }, 'json')
-                        return false;
-                    },
-                    cancelCustomItem: function() {
-                        hideMoeFormMask();
-                        $('[custom-item-form]').hide();
-                        return false;
-                    }
+                    @include('app.patient.segment-templates._custom_items.script')
                 }
             });
 

+ 21 - 36
resources/views/app/patient/segment-templates/history_surgical/edit.blade.php

@@ -83,7 +83,7 @@ for ($i = 0; $i < count($fields); $i++) {
                                                    v-model="common['{{$fName}}']">
                                             <div class="ml-2">
                                                 <div>
-                                                    <span class="mr-2">{{ $values[$k] }}</span>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
                                                     <div moe relative no-mask v-show="common['{{$fName}}']" >
                                                         <a href="#" start show>
                                                             <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
@@ -123,10 +123,23 @@ for ($i = 0; $i < count($fields); $i++) {
                 </div>
             </div>
 
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-                <button class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : 'cancel' !!}>Close</button>
-            </div>
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                            <i class="fa fa-check"></i>
+                            Saved
+                        </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
 
         </form>
     </div>
@@ -172,6 +185,8 @@ for ($i = 0; $i < count($fields); $i++) {
                 return a.label.localeCompare(b.label);
             });
 
+            model.itemKey = 'pshx';
+
             new Vue({
                 el: '#edit-univ_history_surgical-container',
                 delimiters: ["@{{","}}"],
@@ -190,37 +205,7 @@ for ($i = 0; $i < count($fields); $i++) {
                     }
                 },
                 methods: {
-                    saveCustomItem: function(_label) {
-                        if(!_label) return false;
-                        showMask();
-                        let self = this;
-                        $.post('/api/clientCanvasCustomItem/create', {
-                            proUid: '{{ $pro->uid }}',
-                            key: 'pshx',
-                            label: _label
-                        }, function(_data) {
-                            hideMask();
-                            if(_data && _data.success) {
-                                hideMoeFormMask();
-                                $('[custom-item-form]').hide();
-                                // $('.custom-items-container').closest('.visit-segment').find('.refresh-segment').trigger('click');
-                                self.customFields.push({
-                                    label: _label,
-                                    value: '',
-                                    comments: '',
-                                });
-                            }
-                            else {
-                                toastr.error(_data.message);
-                            }
-                        }, 'json')
-                        return false;
-                    },
-                    cancelCustomItem: function() {
-                        hideMoeFormMask();
-                        $('[custom-item-form]').hide();
-                        return false;
-                    }
+                    @include('app.patient.segment-templates._custom_items.script')
                 }
             });
 

+ 21 - 36
resources/views/app/patient/segment-templates/past_medical_history/edit.blade.php

@@ -113,7 +113,7 @@ for ($i = 0; $i < count($fields); $i++) {
                                                    v-model="common['{{$fName}}']">
                                             <div class="ml-2">
                                                 <div>
-                                                    <span class="mr-2">{{ $values[$k] }}</span>
+                                                    <span class="mr-2 common-item">{{ $values[$k] }}</span>
                                                     <div moe relative no-mask v-show="common['{{$fName}}']" >
                                                         <a href="#" start show>
                                                             <i class="fa-comment" :class="common['{{$fName}}__comments'] ? 'fas' : 'far'"></i>
@@ -163,10 +163,23 @@ for ($i = 0; $i < count($fields); $i++) {
                 </div>
             </div>
 
-            <div>
-                <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-                <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
-            </div>
+            @if(!!$segment)
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2"><i class="fa fa-save"></i></button>
+                    <div class="d-inline-flex align-self-stretch align-items-center">
+                        <span class="autosave-indicator saving text-sm text-secondary">Saving changes &hellip;</span>
+                        <span class="autosave-indicator saved text-sm text-secondary">
+                        <i class="fa fa-check"></i>
+                        Saved
+                    </span>
+                    </div>
+                </div>
+            @else
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border" {!! @$closeOnSave ? 'onmousedown="return closeStagPopup()"' : '' !!}>Close</button>
+                </div>
+            @endif
 
         </form>
     </div>
@@ -212,6 +225,8 @@ for ($i = 0; $i < count($fields); $i++) {
                 return a.label.localeCompare(b.label);
             });
 
+            model.itemKey = 'pmhx';
+
             new Vue({
                 el: '#edit-univ_history_past_medical-container',
                 delimiters: ["@{{","}}"],
@@ -230,37 +245,7 @@ for ($i = 0; $i < count($fields); $i++) {
                     }
                 },
                 methods: {
-                    saveCustomItem: function(_label) {
-                        if(!_label) return false;
-                        showMask();
-                        let self = this;
-                        $.post('/api/clientCanvasCustomItem/create', {
-                            proUid: '{{ $pro->uid }}',
-                            key: 'pmhx',
-                            label: _label
-                        }, function(_data) {
-                            hideMask();
-                            if(_data && _data.success) {
-                                hideMoeFormMask();
-                                $('[custom-item-form]').hide();
-                                // $('.custom-items-container').closest('.visit-segment').find('.refresh-segment').trigger('click');
-                                self.customFields.push({
-                                    label: _label,
-                                    value: '',
-                                    comments: '',
-                                });
-                            }
-                            else {
-                                toastr.error(_data.message);
-                            }
-                        }, 'json')
-                        return false;
-                    },
-                    cancelCustomItem: function() {
-                        hideMoeFormMask();
-                        $('[custom-item-form]').hide();
-                        return false;
-                    }
+                    @include('app.patient.segment-templates._custom_items.script')
                 }
             });
 

+ 8 - 2
resources/views/app/patient/segment-templates/vitals/edit.blade.php

@@ -193,8 +193,14 @@ $copyTriggerAdded = [];
             </tbody>
         </table>
         <div>
-            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
-            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+            <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>

+ 9 - 4
resources/views/app/patient/wizard-partials/common-script.blade.php

@@ -241,7 +241,12 @@ parentSegment.find('#frm-add-{{$label}}')
                 refreshDynamicStagPopup();
                 $('.visit-segment[data-segment-template-name="intake_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                 $('.visit-segment[data-segment-template-name="plan_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
-                if(refreshRHSSidebar) refreshRHSSidebar();
+                if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
+
+                // only for canvas-migrate
+                if(form.closest('.point-content').length) {
+                    fastReload();
+                }
             }
         }, 'json');
         return false;
@@ -356,7 +361,7 @@ parentSegment.find('.frm-edit-{{$label}}')
                 refreshDynamicStagPopup();
                 $('.visit-segment[data-segment-template-name="intake_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                 $('.visit-segment[data-segment-template-name="plan_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
-                if(refreshRHSSidebar) refreshRHSSidebar();
+                if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
             }
         }, 'json');
         return false;
@@ -374,7 +379,7 @@ parentSegment.find('.toggle-relevance')
                     refreshDynamicStagPopup();
                     $('.visit-segment[data-segment-template-name="intake_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                     $('.visit-segment[data-segment-template-name="plan_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
-                    if(refreshRHSSidebar) refreshRHSSidebar();
+                    if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
                 }
             }, 'json');
         } else {
@@ -386,7 +391,7 @@ parentSegment.find('.toggle-relevance')
                         refreshDynamicStagPopup();
                         $('.visit-segment[data-segment-template-name="intake_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
                         $('.visit-segment[data-segment-template-name="plan_{{$segment_part}}"]').find('.refresh-segment').trigger('click');
-                        if(refreshRHSSidebar) refreshRHSSidebar();
+                        if(typeof refreshRHSSidebar !== 'undefined') refreshRHSSidebar();
                     }
                 }, 'json');
             } else {

+ 90 - 0
resources/views/app/practice-management/clients_bdt_devices.blade.php

@@ -0,0 +1,90 @@
+@extends ('layouts/template')
+
+@section('content')
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-weight"></i>
+                Clients BDT Devices
+            </strong>
+        </div>
+
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.practice-management.clients_bdt_devices_filters')
+            </div>
+            <table class="table table-condensed p-0 m-0">
+                <thead class="bg-light">
+                    <tr>
+                        <th class="px-3 border-0">IMEI</th>
+                        <th class="px-3 border-0">Client</th>
+                        <th class="px-3 border-0">MCP</th>
+                        <th class="px-3 border-0">Created</th>
+                        <th class="px-3 border-0">Category</th>
+                        <th class="px-3 border-0">Last Measurement</th>
+                        <th class="px-3 border-0">Status</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    @foreach($devices as $device)
+                    <?php 
+                    $mcpName = $device->client->mcp ? implode(', ', array_filter([$device->client->mcp->name_last, $device->client->mcp->name_first])) : null;
+                    ?>
+                    <tr>
+                        <td class="px-2">
+                            <pre class="m-0">{{ $device->device->imei }}</pre>
+                        </td>
+                        <td>
+                            <a target="_blank" native href="{{route('patients.view.dashboard', $device->client)}}">
+                                {{$device->client->displayName()}}
+                            </a>
+                        </td>
+                        <td>{{ $mcpName }}</td>
+                        <td class="px-2 text-nowrap">{{ friendly_date_time($device->device->created_at) }}</td>
+                        <td class="px-2">{{ $device->device->category }}</td>
+                        <td class="px-2 d-flex align-items-center">
+                            <?php $lastMeasurement = $device->lastDeviceMeasurement(); ?>
+                            @if($lastMeasurement)
+                            @if($lastMeasurement->is_cellular_zero)
+                            <i class="font-size-11 fa fa-rss"></i>
+                            @elseif($lastMeasurement->label === 'BP')
+                            {{ $lastMeasurement->sbp_mm_hg }} / {{ $lastMeasurement->dbp_mm_hg }}
+                            @elseif($lastMeasurement->label === 'Wt. (lbs.)')
+                            {{ round($lastMeasurement->numeric_value, 2) }} lbs
+                            @else
+                            {{ $lastMeasurement->value }}
+                            @endif
+                            <div class="ml-2">
+                                <i class="far fa-calendar-check"></i> <span class="text-secondary">{{ friendly_date_time($lastMeasurement->created_at) }}</span>
+                            </div>
+                            @else
+                            <small class="text-muted">-</small>
+                            @endif
+                        </td>
+                        <td>
+                            @if($device->is_active)
+                                <span class="text-success">Active</span>
+                            @else
+                                <span class="text-danger">Deactivated</span>
+                            @endif
+                        </td>
+                    </tr>
+                    @endforeach
+
+                    @if(count($devices) === 0)
+                    <tr>
+                        <td colspan="7">No records found!</td>
+                    </tr>
+                    @endif
+                </tbody>
+
+            </table>
+            <div class="ml-2 mt-2">
+                {{ $devices->appends(request()->input())->links() }}
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 107 - 0
resources/views/app/practice-management/clients_bdt_devices_filters.blade.php

@@ -0,0 +1,107 @@
+<style>
+	#mcp-clients-bdt-devices-filters label {
+		font-weight: bold;
+	}
+
+	#mcp-clients-bdt-devices-filters .mw-100px {
+		min-width: 100px;
+	}
+	.filter-container {
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+	.filter-container >div {
+		width: 165px;
+	}
+	.filter-container >div:not(:last-child) {
+		margin-right: 15px;
+	}
+</style>
+<form id="mcp-clients-bdt-devices-filters" method="GET" action="{{ route('practice-management.clientsBdtDevices') }}" class="filter-container" v-cloak>
+	<!-- DATE	 -->
+	<div>
+		<div class="form-group">
+			<label>Date:</label>
+			<select name="date_category" class="form-control input-sm" v-model="filters.date_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.date_category" class="mt-2">
+				<div>
+					<input name="date_value_1" v-model="filters.date_value_1" type="date" class="form-control input-sm"/>
+				</div>
+				<div v-show="filters.date_category === 'BETWEEN' || filters.date_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="date_value_2" v-model="filters.date_value_2" type="date" class="form-control input-sm"/>
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- STATUS -->
+	<div>
+		<div class="form-group">
+			<label>Status:</label>
+			<select name="status" class="form-control input-sm" v-model="filters.status">
+				<option value="">All</option>
+				<option value="ACTIVE">active</option>
+				<option value="DEACTIVATED">Deactivated</option>
+			</select>
+		</div>
+	</div>
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<div class="d-flex">
+				<button type="submit" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('practice-management.clientsBdtDevices')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'date_category',
+	'date_value_1',
+	'date_value_2',
+	'status'
+];
+for ($i = 0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+<script>
+	(function() {
+		function init() {
+			window.apapp = new Vue({
+				el: '#mcp-clients-bdt-devices-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					doSubmit: function() {
+						fastLoad('{{ route("practice-management.clientsBdtDevices") }}?' + $('#mcp-clients-bdt-devices-filters').serialize());
+						return false;
+					},
+					init: function() {
+
+					}
+				},
+				mounted: function() {
+					this.init();
+				},
+			});
+
+
+		}
+		addMCInitializer('mcp-clients-bdt-devices-filters', init, '#mcp-clients-bdt-devices-filters');
+	})();
+</script>

+ 100 - 0
resources/views/app/practice-management/memos.blade.php

@@ -0,0 +1,100 @@
+@extends ('layouts/template')
+
+@section('content')
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-notes-medical"></i>
+                Memos
+            </strong>
+        </div>
+
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.practice-management.memos_filters')
+            </div>
+            <table class="table table-condensed p-0 m-0">
+                <thead class="bg-light">
+                    <tr>
+                        <th class="px-3 border-0">Category</th>
+                        <th class="px-3 border-0">Patient</th>
+                        <th class="px-3 border-0">MCP</th>
+                        <th class="px-3 border-0 w-25">Summary</th>
+                        <th class="px-3 border-0">Created</th>
+                        <th class="px-3 border-0 delete-column">&nbsp;</th>
+                    </tr>
+                </thead>
+                <tbody>
+                    @foreach($memos as $memo)
+                    <?php 
+                    $mcpName = $memo->client->mcp ? implode(', ', array_filter([$memo->client->mcp->name_last, $memo->client->mcp->name_first])) : null;
+                    ?>
+                    <tr>
+                        <td class="px-2">{{ $memo->category }}</td>
+                        <td>
+                            <a target="_blank" native href="{{route('patients.view.dashboard', $memo->client)}}">
+                                {{$memo->client->displayName()}}
+                            </a>
+                        </td>
+                        <td class="px-2">{{ $mcpName }}</td>
+                        <td class="px-2">
+                            <pre class="m-0 break-spaces">{{ $memo->content }}</pre>
+                        </td>
+                        <td class="px-2">{{ friendly_date_time($memo->created_at) }}</td>
+                        <td class="px-2 text-center delete-column">
+                            <div moe wide relative class="mr-2">
+                                <a class="on-hover-opaque" start show title="Edit">
+                                    <i class="font-size-11 fa fa-edit"></i>
+                                </a>
+                                <form url="/api/clientMemo/update" right>
+                                    <input type="hidden" name="uid" value="{{ $memo->uid }}">
+                                    <div class="mb-2">
+                                        <select class="form-control form-control-sm" name="category" required>
+                                            <option value="">-- select --</option>
+                                            <option {{ $memo->category === "Incoming Call" ? "selected" : "" }} value="Incoming Call">Incoming Call</option>
+                                            <option {{ $memo->category === "Outgoing Call" ? "selected" : "" }} value="Outgoing Call">Outgoing Call</option>
+                                            <option {{ $memo->category === "Call Unspecified" ? "selected" : "" }} value="Call Unspecified">Call Unspecified</option>
+                                            <option {{ $memo->category === "Other" ? "selected" : "" }} value="Other">Other</option>
+                                        </select>
+                                    </div>
+                                    <div class="mb-2">
+                                        <textarea class="form-control form-control-sm" name="content" rows="5" placeholder="Content"><?= $memo->content ?></textarea>
+                                    </div>
+                                    <div class="d-flex align-items-center">
+                                        <button class="btn btn-sm btn-primary mr-2" type="button" submit>Save</button>
+                                        <button class="btn btn-sm btn-default mr-2 border" type="button" cancel>Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                            <div moe relative>
+                                <a start show class="on-hover-opaque"><i class="fa fa-trash-alt text-danger"></i></a>
+                                <form url="/api/clientMemo/cancel" right>
+                                    <input type="hidden" name="uid" value="{{ $memo->uid }}">
+                                    <p class="small">Are you sure you want to cancel this memo?</p>
+                                    <div class="d-flex align-items-center">
+                                        <button class="btn btn-sm btn-danger mr-2" submit>Delete</button>
+                                        <button class="btn btn-sm btn-default mr-2 border" cancel>Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        </td>
+                    </tr>
+                    @endforeach
+
+                    @if(count($memos) === 0)
+                    <tr>
+                        <td colspan="5">No records found!</td>
+                    </tr>
+                    @endif
+                </tbody>
+
+            </table>
+            <div class="ml-2 mt-2">
+                {{ $memos->appends(request()->input())->links() }}
+            </div>
+        </div>
+    </div>
+</div>
+@endsection

+ 110 - 0
resources/views/app/practice-management/memos_filters.blade.php

@@ -0,0 +1,110 @@
+<style>
+	#mcp-memos-filters label {
+		font-weight: bold;
+	}
+
+	#mcp-memos-filters .mw-100px {
+		min-width: 100px;
+	}
+
+	.filter-container {
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+
+	.filter-container>div {
+		width: 165px;
+	}
+
+	.filter-container>div:not(:last-child) {
+		margin-right: 15px;
+	}
+</style>
+<form id="mcp-memos-filters" method="GET" action="{{ route('practice-management.memos') }}" class="filter-container" v-cloak>
+	<!-- DATE -->
+	<div>
+		<div class="form-group">
+			<label>Date:</label>
+			<select name="date_category" class="form-control input-sm" v-model="filters.date_category">
+				<option value="">All</option>
+				<option value="EXACTLY">Exactly</option>
+				<option value="LESS_THAN">Less Than</option>
+				<option value="GREATER_THAN">Greater Than</option>
+				<option value="BETWEEN">Between</option>
+				<option value="NOT_BETWEEN">Not Between</option>
+			</select>
+			<div v-show="filters.date_category" class="mt-2">
+				<div>
+					<input name="date_value_1" v-model="filters.date_value_1" type="date" class="form-control input-sm" />
+				</div>
+				<div v-show="filters.date_category === 'BETWEEN' || filters.date_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="date_value_2" v-model="filters.date_value_2" type="date" class="form-control input-sm" />
+				</div>
+			</div>
+		</div>
+	</div>
+	<!-- STATUS -->
+	<div>
+		<div class="form-group">
+			<label>Category:</label>
+			<select name="category" class="form-control input-sm" v-model="filters.category">
+				<option value="">All</option>
+				<option value="Incoming Call">Incoming Call</option>
+				<option value="Outgoing Call">Outgoing Call</option>
+				<option value="Call Unspecified">Call Unspecified</option>
+				<option value="Other">Other</option>
+			</select>
+		</div>
+	</div>
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<div class="d-flex">
+				<button type="submit" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('practice-management.memos')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'date_category',
+	'date_value_1',
+	'date_value_2',
+	'category'
+];
+for ($i = 0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
+<script>
+	(function() {
+		function init() {
+			window.apapp = new Vue({
+				el: '#mcp-memos-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					doSubmit: function() {
+						fastLoad('{{ route("practice-management.memos") }}?' + $('#mcp-memos-filters').serialize());
+						return false;
+					},
+					init: function() {
+
+					}
+				},
+				mounted: function() {
+					this.init();
+				},
+			});
+		}
+		addMCInitializer('mcp-memos-filters', init, '#mcp-memos-filters');
+	})();
+</script>

+ 1 - 1
resources/views/app/practice-management/remote-monitoring-report.blade.php

@@ -80,7 +80,7 @@
                         <button class="btn btn-primary"><i class="fa fa-filter"></i> Filter</button>
                     </div>
                 </div>
-                <table class="table table-sm table-condensed p-0 m-0" style="table-layout: fixed">
+                <table class="table table-sm table-condensed p-0 m-0" style="">
                     <thead class="bg-light">
                         <tr>
 				@if($isAdmin)

+ 21 - 15
resources/views/layouts/patient.blade.php

@@ -369,8 +369,10 @@ $isVisitNote = ($routeName === 'patients.view.notes.view.dashboard' && @$note &&
 											<div class="screen-only mr-1 patient-presence-indicator thumbnail {{$online}}"
 											data-patient-uid="{{$patient->uid}}"
 											style="background-image:<?=$thumbnail?>"><?=$initials?></div>
-											<i class=chart>[#{{$patient->chart_number}}]</i>
-											<i class="fas fa-info-circle text-primary" data-toggle="tooltip" data-placement="right" title="Joined <?=$memberSince?>"></i>
+											<div class="d-inline-flex align-items-baseline">
+												<i class="chart mr-2">#{{$patient->chart_number}}</i>
+												<i class="fas fa-info-circle text-primary" data-toggle="tooltip" data-placement="right" title="Joined <?=$memberSince?>"></i>
+											</div>
 										</div>
 										<div class=separators>
 											<div>{{friendly_date_time($patient->dob, false,null, true)}} ({{$patient->age_in_years}}
@@ -814,19 +816,23 @@ $isVisitNote = ($routeName === 'patients.view.notes.view.dashboard' && @$note &&
 												{{$patient->phone_home}}
 											</li>
 										@endif
-										<li class="{{empty($confirmedEmail) || $confirmedEmail === '-' ? 'screen-only' : ''}}">
-											<span class="aligned-icon"><i class="fa fa-envelope" aria-hidden="true"></i></span>
-											{{$confirmedEmail}}
-										</li>
-										<li class="screen-only hide-inside-popup">
-											<span class="aligned-icon text-primary">
-												<i class="fa fa-link" aria-hidden="true"></i>
-											</span>
-											<?php $numLinkedAccounts = $patient->linkedAccounts ? count($patient->linkedAccounts) : 0; ?>
-											<a href="{{route('patients.view.accounts', ['patient' => $patient])}}">
-												{{ $numLinkedAccounts === 0 ? 'No' : $numLinkedAccounts }}
-												account{{ $numLinkedAccounts === 1 ? '' : 's' }} linked
-											</a>
+										<li class="d-flex align-items-baseline">
+											<div class="{{empty($confirmedEmail) || $confirmedEmail === '-' ? 'screen-only' : ''}}">
+												<span class="aligned-icon">
+													<i class="fa fa-envelope" aria-hidden="true"></i>
+												</span>
+												{{$confirmedEmail}}
+											</div>
+											<span class="mx-2 text-secondary text-sm">|</span>
+											<div>
+												<span class="aligned-icon text-primary">
+													<i class="fa fa-link" aria-hidden="true"></i>
+												</span>
+												<?php $numLinkedAccounts = $patient->linkedAccounts ? count($patient->linkedAccounts) : 0; ?>
+												<a href="{{route('patients.view.accounts', ['patient' => $patient])}}">
+													Accounts ({{$numLinkedAccounts}})
+												</a>
+											</div>
 										</li>
 									</ul>
 								</div>

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

@@ -181,6 +181,8 @@
 
                             <a class="dropdown-item" href="/practice-management/rates/all">Payment Rates</a>
                             <a class="dropdown-item" href="{{ route('practice-management.patientsAccountsInvites') }}">Patients Accounts Invites</a>
+                            <a class="dropdown-item" href="{{ route('practice-management.clientsBdtDevices') }}">Clients BDT Devices</a>
+                            <a class="dropdown-item" href="{{ route('practice-management.memos') }}">Memos</a>
 
                         @elseif($pro->is_enrolled_as_mcp)
 
@@ -192,6 +194,7 @@
                             <a class="dropdown-item" href="{{ route('practice-management.remoteMonitoringReport') }}">Remote Monitoring Report</a>
 
                             <a class="dropdown-item" href="{{ route('mcp.notes') }}">Notes</a>
+                            <a class="dropdown-item" href="{{ route('mcp.memos') }}">Memos</a>
                             <a class="dropdown-item" href="{{ route('mcp.appointments') }}">Appointments</a>
                             <a class="dropdown-item" href="{{ route('mcp.bills') }}">Bills</a>
                             <a class="dropdown-item" href="{{ route('mcp.erx_and_orders') }}">ERx & Orders</a>
@@ -199,7 +202,7 @@
                             <a class="dropdown-item" href="{{ route('mcp.supply_orders') }}">Supply Orders</a>
                             <a class="dropdown-item" href="{{ route('mcp.client_messages') }}">Messages</a>
                             <a class="dropdown-item" href="{{ route('mcp.patients_accounts_invites') }}">Patients Accounts Invites</a>
-
+                            <a class="dropdown-item" href="{{ route('mcp.clients_bdt_devices') }}">Clients BDT Devices</a>
                         @elseif($pro && $pro->isDefaultNA())
 
                             <a class="dropdown-item" href="/practice-management/my-teams">My Teams</a>

+ 7 - 1
routes/web.php

@@ -82,7 +82,9 @@ Route::middleware('pro.auth')->group(function () {
         Route::get('reports', 'McpController@reports')->name('reports');
         Route::get('supply-orders', 'McpController@supply_orders')->name('supply_orders');
         Route::get('client-messages', 'McpController@client_messages')->name('client_messages');
+        Route::get('clients-bdt-devices', 'McpController@clients_bdt_devices')->name('clients_bdt_devices');
         Route::get('patients-accounts-invites', 'McpController@patients_accounts_invites')->name('patients_accounts_invites');
+        Route::get('memos', 'McpController@memos')->name('memos');
 
 
         Route::get('new-patients-awaiting-visit', 'McpController@new_patients_awaiting_visit')->name('new_patients_awaiting_visit');
@@ -177,7 +179,9 @@ Route::middleware('pro.auth')->group(function () {
 
         Route::get('my-teams', 'PracticeManagementController@myTeams')->name('my-teams');
         Route::get('patients-accounts-invites', 'PracticeManagementController@patientsAccountsInvites')->name('patientsAccountsInvites');
-
+        Route::get('clients-bdt-devices', 'PracticeManagementController@clientsBdtDevices')->name('clientsBdtDevices');
+        Route::get('memos', 'PracticeManagementController@memos')->name('memos');
+        
         Route::middleware('pro.auth.admin')->group(function () {
 
             // BILLING REPORT
@@ -397,6 +401,8 @@ Route::middleware('pro.auth')->group(function () {
     Route::get('/goals-center/{patient}/{note}', 'NoteController@goalsCenter')->name('goals-center');
     Route::get('/allergies-center/{patient}/{note}', 'NoteController@allergiesCenter')->name('allergies-center');
     Route::get('/careteam-center/{patient}/{note}', 'NoteController@careteamCenter')->name('careteam-center');
+    Route::get('/memos-thread/{patient}', 'PatientController@memosThread')->name('memos-thread');
+    Route::get('/messages-thread/{patient}', 'PatientController@messagesThread')->name('messages-thread');
 
     Route::get('/problems-quick-add/{patient}/{note}', 'NoteController@problemsQuickAdd')->name('problems-quick-add');
 

部分文件因文件數量過多而無法顯示