|
@@ -0,0 +1,131 @@
|
|
|
|
+<?php
|
|
|
|
+$parsed = null;
|
|
|
|
+if($patient->rtm_msk_protocol_detail_json) {
|
|
|
|
+ try {
|
|
|
|
+ $parsed = json_decode($patient->rtm_msk_protocol_detail_json);
|
|
|
|
+ }
|
|
|
|
+ catch (Exception $e) {}
|
|
|
|
+}
|
|
|
|
+?>
|
|
|
|
+<div class="popup-content-container px-3 min-height-300px" id="protocol-builder-{{$patient->uid}}">
|
|
|
|
+ <div class="d-flex align-items-baseline mb-2">
|
|
|
|
+ <b>Program Notes</b>
|
|
|
|
+ <div class="flex-grow-1" v-if="!programNotesEditMode">
|
|
|
|
+ <span class="ml-2" v-if="protocol.program_notes">@{{protocol.program_notes}}</span>
|
|
|
|
+ <a href="#" class="ml-2" v-on:click.prevent="programNotesEditMode = !programNotesEditMode">Edit</a>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="flex-grow-1 d-inline-flex align-items-stretch" v-if="programNotesEditMode">
|
|
|
|
+ <input type="text" class="form-control form-control-sm ml-2" v-model="protocol.program_notes">
|
|
|
|
+ <button class="btn btn-sm btn-primary ml-2" v-on:click.prevent="programNotesEditMode = !programNotesEditMode">Done</button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="d-flex align-items-baseline mb-2">
|
|
|
|
+ <b>Exercises</b>
|
|
|
|
+ <div class="ml-2 position-relative">
|
|
|
|
+ <a href="#" v-on:click.prevent="showLibrary = !showLibrary">Add From Library</a>
|
|
|
|
+ <div v-if="showLibrary" class="position-absolute px-2 pt-2 border bg-white min-width-500px">
|
|
|
|
+ <p class="mb-2 text-nowrap text-secondary d-flex align-items-baseline">
|
|
|
|
+ <span class="font-weight-bold">Exercises Library</span>
|
|
|
|
+ <span class="text-sm ml-2">(click to add)</span>
|
|
|
|
+ <a href="#" class="ml-auto text-secondary" v-on:click.prevent="showLibrary = !showLibrary"><i class="fa fa-times-circle"></i></a>
|
|
|
|
+ </p>
|
|
|
|
+ <div class="max-height-400px overflow-auto">
|
|
|
|
+ <div v-for="(exercise, index) in library"
|
|
|
|
+ class="p-2 border mb-2 on-hover-aliceblue c-pointer"
|
|
|
|
+ v-on:click.prevent="addActivity(exercise)">
|
|
|
|
+ <div class="d-flex align-items-baseline">
|
|
|
|
+ <img v-if="exercise.image" :src="exercise.image" :alt="exercise.name" class="image-w90px mr-2 align-self-start">
|
|
|
|
+ <div>
|
|
|
|
+ <div class="font-weight-bold">@{{exercise.name}}</div>
|
|
|
|
+ <div class="text-secondary text-sm">@{{exercise.description}}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div v-if="!protocol.activities || !protocol.activities.length" class="text-secondary min-height-300px">No exercises defined yet!</div>
|
|
|
|
+ <div v-else class="min-height-300px">
|
|
|
|
+ <div v-for="(activity, activityIndex) in protocol.activities">
|
|
|
|
+ <div class="d-flex align-items-baseline p-2 border mb-2">
|
|
|
|
+ <img v-if="activity.image" :src="activity.image" :alt="activity.name" class="image-w90px mr-2 align-self-start">
|
|
|
|
+ <div class="flex-grow-1">
|
|
|
|
+ <div class="font-weight-bold">@{{activity.name}}</div>
|
|
|
|
+ <div class="d-flex align-items-baseline mt-2">
|
|
|
|
+ <div v-for="(prop, propIndex) in activity.props" class="d-inline-flex align-items-end mr-3">
|
|
|
|
+ <label class="d-inline-flex align-items-end m-0">
|
|
|
|
+ <input type="checkbox" v-model="activity.props[propIndex].index" class="align-self-end mb-1">
|
|
|
|
+ <span class="ml-2">@{{activity.props[propIndex].name}}</span>
|
|
|
|
+ </label>
|
|
|
|
+ <input type="text" class="form-control form-control-sm min-width-unset width-70px ml-2 rtm-prop-input" v-model="activity.props[propIndex].value">
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <a href="#" class="text-danger on-hover-opaque" v-on:click.prevent="protocol.activities.splice(activityIndex, 1)">Remove</a>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="d-flex align-items-baseline my-3">
|
|
|
|
+ <button class="btn btn-sm btn-primary font-weight-bold" v-on:click.prevent="saveProtocol()">Save</button>
|
|
|
|
+ <button class="btn btn-sm btn-default border bg-white text-dark ml-2" onclick="return closeStagPopup()">Close</button>
|
|
|
|
+ </div>
|
|
|
|
+</div>
|
|
|
|
+<?php
|
|
|
|
+ $data = [
|
|
|
|
+ 'program_notes' => @$parsed->program_notes ?: '',
|
|
|
|
+ 'activities' => @$parsed->activities && count($parsed->activities) ? $parsed->activities : []
|
|
|
|
+ ];
|
|
|
|
+?>
|
|
|
|
+<script>
|
|
|
|
+ (function() {
|
|
|
|
+ function init() {
|
|
|
|
+ new Vue({
|
|
|
|
+ 'el': '#protocol-builder-{{$patient->uid}}',
|
|
|
|
+ delimiters: ['@{{', '}}'],
|
|
|
|
+ data: {
|
|
|
|
+ programNotesEditMode: false,
|
|
|
|
+ showLibrary: false,
|
|
|
|
+ protocol: {!! json_encode($data) !!},
|
|
|
|
+ library: {!! json_encode(config('rtm.exercises')) !!}
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ addActivity: function(_exercise) {
|
|
|
|
+ let activity = {
|
|
|
|
+ name: _exercise.name,
|
|
|
|
+ description: _exercise.description,
|
|
|
|
+ image: _exercise.image,
|
|
|
|
+ video: _exercise.video,
|
|
|
|
+ props: [],
|
|
|
|
+ };
|
|
|
|
+ for(let i = 0; i < _exercise.props.length; i++) {
|
|
|
|
+ activity.props.push({
|
|
|
|
+ name: _exercise.props[i],
|
|
|
|
+ value: '',
|
|
|
|
+ include: true,
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.protocol.activities.push(activity);
|
|
|
|
+ this.showLibrary = false;
|
|
|
|
+ },
|
|
|
|
+ saveProtocol: function() {
|
|
|
|
+ $.post('/api/clientRtm/updateRtmMskProtocolDetailJson', {
|
|
|
|
+ uid: '{{$patient->uid}}',
|
|
|
|
+ rtmMskProtocolDetailJson: JSON.stringify(this.protocol)
|
|
|
|
+ }, _data => {
|
|
|
|
+ if(!hasResponseError(_data)) {
|
|
|
|
+ toastr.success('Protocol saved!');
|
|
|
|
+ }
|
|
|
|
+ }, 'json');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ mounted: function () {
|
|
|
|
+ Vue.nextTick(() => {
|
|
|
|
+ initMoes();
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ addMCInitializer('protocol-builder-{{$patient->uid}}', init, '#protocol-builder-{{$patient->uid}}');
|
|
|
|
+ }).call(window);
|
|
|
|
+</script>
|