1
0

3 Revīzijas 8657dd8527 ... 591c7904e6

Autors SHA1 Ziņojums Datums
  Christopher Leggett 591c7904e6 Adds a helpful comment to the workorder edit modal 5 gadi atpakaļ
  Christopher Leggett 9421292e88 Reimplements WO summary in SPA. 5 gadi atpakaļ
  Christopher Leggett b9287ecebf Implements basic dashboard page in SPA 5 gadi atpakaļ

+ 70 - 0
app/Http/Controllers/Api/UsersController.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\Controllers\Controller;
+use App\User;
+use Illuminate\Http\Request;
+
+class UsersController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     *
+     * @return \Illuminate\Http\Response
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return \Illuminate\Http\Response
+     */
+    public function store(Request $request)
+    {
+        //
+    }
+
+    /**
+     * Display the specified resource.
+     *
+     * @param  \App\User  $user
+     * @return \Illuminate\Http\Response
+     */
+    public function show(User $user)
+    {
+        //
+    }
+
+    public function workOrders(User $user) {
+        $workOrders = \App\WorkOrder::where('cibyuser', $user->username)->get();
+        return response()->json($workOrders->values(), 200);
+    }
+
+    /**
+     * Update the specified resource in storage.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \App\User  $user
+     * @return \Illuminate\Http\Response
+     */
+    public function update(Request $request, User $user)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     *
+     * @param  \App\User  $user
+     * @return \Illuminate\Http\Response
+     */
+    public function destroy(User $user)
+    {
+        //
+    }
+}

+ 8 - 0
app/User.php

@@ -44,4 +44,12 @@ class User extends Authenticatable
     {
         return $this->userpass;
     }
+
+    public function workOrders() {
+        return $this->hasMany('App\WorkOrder', 'cibyuser', 'username');
+    }
+
+    public function getRouteKeyName() {
+        return 'username';
+    }
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 983 - 2
public/js/app.js


+ 11 - 4
resources/js/app.js

@@ -15,7 +15,8 @@ import VueRouter from 'vue-router'
 Vue.use(VueRouter)
 
 import App from './views/App'
-// import WorkOrder from './views/WorkOrder'
+import Dashboard from './views/Dashboard'
+import WorkOrder from './views/WorkOrder'
 import Login from './views/Login'
 import Home from './views/Welcome'
 
@@ -32,11 +33,17 @@ const router = new VueRouter({
             name: 'login',
             component: Login,
         },
-        /* {
-            path: '/workorders',
+        {
+            path: '/dashboard',
+            name: 'dashboard',
+            component: Dashboard,
+        },
+        {
+            path: '/workorders/:id',
             name: 'workorders',
             component: WorkOrder,
-        } */
+            props: true,
+        }
     ],
 })
 

+ 0 - 0
resources/js/components/autocomplete-custom-dropdown.vue → resources/js/components/AutocompleteCustomDropdown.vue


+ 0 - 0
resources/js/components/modal.vue → resources/js/components/Modal.vue


+ 30 - 7
resources/js/components/woinfo-edit-modal.vue → resources/js/components/WoInfoEditModal.vue

@@ -32,25 +32,25 @@
 </modal>
 </template>
 <script>
+import Modal from '../components/Modal'
+import AutocompleteCustomDropdown from '../components/AutocompleteCustomDropdown'
 export default {
+    components: {
+        Modal,
+        AutocompleteCustomDropdown
+    },
     props:['populateWith', 'storeList', 'modalId'],
     data() {
         return {
             // Copies object from prop, so it doesn't mutate the object
             // from the parent component. Parent component will be updated via
             // Websocket if updateWorkOrder is successful.
-            data: JSON.parse(JSON.stringify(this.populateWith)),
+            data: {},
             id: this.modalId,
             store: {},
             errors: []
         }
     },
-    mounted () {
-        this.store = {
-            'id': this.data.storeid,
-            'name': this.storeList[this.data.storeid]
-        }
-    },
     methods: {
         updateWorkOrder() {
             this.data.storeid = this.store.id
@@ -58,6 +58,29 @@ export default {
                 .then((response) => { $('#workordereditModal').modal('hide'); })
                 .catch((error) => { this.errors = JSON.parse(error.response.request.response).errors; });
         }
+    },
+    // The props are obtained in parent components via axios,
+    // so the values may change after the initial render, these
+    // Watchers fill in our initial values when the values of the
+    // props change. As a side effect if they are updated while we
+    // are editing they will change right underneath us, not sure
+    // probably will implement a notice when they change during edit
+    // with the option to view changes or override them or something
+    // that.
+    watch: {
+        populateWith: function (value) {
+            this.data = JSON.parse(JSON.stringify(this.populateWith))
+            this.store = {
+                'id': this.data.storeid,
+                'name': this.storeList[this.data.storeid]
+            }
+        },
+        storeList: function (value) {
+            this.store = {
+                'id': this.data.storeid,
+                'name': this.storeList[this.data.storeid]
+            }
+        }
     }
 }
 </script>

+ 14 - 21
resources/js/components/woinfo.vue → resources/js/components/WorkOrderInfo.vue

@@ -1,18 +1,18 @@
 <template>
     <div>
-        <woinfo-edit-modal modal-id="workordereditModal" :populate-with="this.data" :store-list="this.storeList"></woinfo-edit-modal>
-        <p><i class="fas fa-fw fa-info-circle"></i> <span v-text="this.data.probdesc"></span></p>
-        <p><i class="far fa-fw fa-lightbulb"></i> <span v-text="this.data.suggested"></span></p>
-        <p><i class="fas fa-fw fa-paste"></i> <span v-text="this.data.woid"></span></p>
-        <p><i class="fas fa-fw fa-building"></i> <span>{{ storeList[data.storeid] }}</span></p>
+        <wo-info-edit-modal modal-id="workordereditModal" :populate-with="workOrder" :store-list="this.storeList"></wo-info-edit-modal>
+        <p><i class="fas fa-fw fa-info-circle"></i> <span v-text="workOrder.probdesc"></span></p>
+        <p><i class="far fa-fw fa-lightbulb"></i> <span v-text="workOrder.suggested"></span></p>
+        <p><i class="fas fa-fw fa-paste"></i> <span v-text="workOrder.woid"></span></p>
+        <p><i class="fas fa-fw fa-building"></i> <span>{{ storeList[workOrder.storeid] }}</span></p>
         <p><i class="fas fa-fw fa-sign-in-alt"></i> 
-            <span class="dashed-underline" data-toggle="tooltip" data-placement="bottom" v-bind:title=this.getHRDate(this.data.dropdate)>
-                {{ Math.floor(this.daysSinceToday(this.data.dropdate)) }} days ago
+            <span class="dashed-underline" data-toggle="tooltip" data-placement="bottom" v-bind:title=this.getHRDate(workOrder.dropdate)>
+                {{ Math.floor(this.daysSinceToday(workOrder.dropdate)) }} days ago
             </span>
         </p>
         <p><i class="fas fa-sign-out-alt"></i> 
-            <span class="dashed-underline" data-toggle="tooltip" data-placement="bottom" v-if="!this.isZero(this.data.pickupdate)" v-bind:title=this.getHRDate(this.data.pickupdate)>
-                {{ Math.floor(this.daysSinceToday(this.data.pickupdate)) }} days ago
+            <span class="dashed-underline" data-toggle="tooltip" data-placement="bottom" v-if="!this.isZero(workOrder.pickupdate)" v-bind:title=this.getHRDate(workOrder.pickupdate)>
+                {{ Math.floor(this.daysSinceToday(workOrder.pickupdate)) }} days ago
             </span>
         </p>
         <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#workordereditModal">Edit</button>
@@ -20,28 +20,21 @@
 </template>
 <script>
     import dateMixin from '../mixins/dateMixin'
+    import WoInfoEditModal from '../components/WoInfoEditModal'
     export default {
+        components: {
+            WoInfoEditModal
+        },
         mixins: [dateMixin],
         props: ['workOrder', 'stores'],
-        data() {
-            return {
-                data: JSON.parse(this.workOrder),
-            }
-        },
         computed: {
             storeList: function () {
                 let list = {}
-                JSON.parse(this.stores).map(val => {
+                Object.values(this.stores).map(val => {
                     list[val.storeid] = val.storesname
                 })
                 return list
             }
         },
-        mounted() {
-            Echo.channel('work-order.'+this.data.woid)
-                .listen('WorkOrderUpdated', (e) => {
-                    this.data = e.data;
-                });
-        }
     }
 </script>

+ 1 - 1
resources/js/views/App.vue

@@ -19,7 +19,7 @@
                             <a href="#" class="nav-link"><i class="fas fa-sign-out-alt"></i> <span class="d-none d-sm-block d-md-inline">Check-Out</span></a>
                         </li>
                         <li class="nav-item">
-                            <a href="#" class="nav-link"><i class="fas fa-tachometer-alt"></i> <span class="d-none d-sm-block d-md-inline">Dashboard</span></a>
+                            <router-link :to="{ name: 'dashboard' }" class="nav-link"><i class="fas fa-tachometer-alt"></i> <span class="d-none d-sm-block d-md-inline">Dashboard</span></router-link>
                         </li>
                         <li class="nav-item">
                             <a href="#" class="nav-link"><i class="fas fa-chart-bar"></i> <span class="d-none d-sm-block d-md-inline">Reports</span></a>

+ 52 - 0
resources/js/views/Dashboard.vue

@@ -0,0 +1,52 @@
+<template>
+    <div class="container">
+        <div class="row justify-content-center">
+            <div class="col-md-12">
+                <div class="col-md-4" v-for="(workOrder, index) in workOrders" :key="workOrder.woid">
+                    <div class="card">
+                        <div class="card-header">
+                            <h4 class="card-title">{{workOrder.woid}}</h4>
+                        </div>
+                        <div class="card-body card-body-dark">
+                            <div>
+                                {{ workOrder.probdesc }}
+                            </div>
+                            <div>
+                                {{ workOrder.suggested }}
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    data () {
+        return {
+            workOrders: []
+        }
+    },
+    mounted () {
+        let token = localStorage.getItem('jwt')
+        let user = localStorage.getItem('user')
+
+        axios.defaults.headers.common['Content-Type'] = 'application/json'
+        axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
+
+        axios.get('api/users/'+user+'/workorders').then(response => {
+            this.workOrders = response.data
+        }).catch(error => {
+            console.log(error)
+        })
+    },
+    beforeRouteEnter (to, from, next) {
+        if ( ! localStorage.getItem('jwt')) {
+            return next('login')
+        }
+
+        next()
+    }
+}
+</script>

+ 1 - 1
resources/js/views/Login.vue

@@ -59,7 +59,7 @@
                         localStorage.setItem('jwt',response.data.success.token)
 
                         if (localStorage.getItem('jwt') != null){
-                            this.$router.go('/')
+                            this.$router.go('/dashboard')
                         }
                         })
                         .catch(function (error) {

+ 135 - 0
resources/js/views/WorkOrder.vue

@@ -0,0 +1,135 @@
+<template>
+    <div class="container-fluid">
+        <div class="row my-3">
+            <div class="col-lg-6">
+                <div class="card h-100">
+                    <div class="card-header text-right">
+                        <button type="button" class="btn btn-default xs-toggle" data-toggle="collapse" data-target="#assetTab">
+                            <span class="sr-only">Toggle Navigation</span>
+                            <span class="icon-bar"></span>
+                            <span class="icon-bar"></span>
+                            <span class="icon-bar"></span>
+                        </button>
+                        <ul class="nav nav-pills card-header-pills nav-justified xs-collapse collapse" id="assetTab" role="tablist">
+                            <li class="nav-item">
+                                <a class="nav-link active" id="assetinfo-tab" data-toggle="pill" href="#assetinfo" role="tab" aria-controls="assetinfo" aria-selected="true">Hardware</a>
+                            </li>
+                            <!-- @if($workOrder->asset->group !== null)
+                            <li class="nav-item">
+                                <a class="nav-link" id="group-tab" data-toggle="pill" href="#group" role="tab" aria-controls="group" aria-selected="false">Group</a>
+                            </li>
+                            @endif -->
+                            <li class="nav-item">
+                                <a class="nav-link" id="credentials-tab" data-toggle="pill" href="#credentials" role="tab" aria-controls="credentials" aria-selected="false">Credentials</a>
+                            </li>
+                        </ul>
+                    </div>
+                    <div class="card-body">
+                        <div class="tab-content">
+                            <div class="tab-pane active" id="assetinfo" role="tabpanel" aria-labelledby="assetinfo-tab">
+                                <!-- <assetinfo asset="{{$asset}}"></assetinfo> -->
+                            </div>
+                            <!-- @if($workOrder->asset->group !== null)
+                            <div class="tab-pane" id="group" role="tabpanel" aria-labelledby="group-tab">
+                                Name: {{$workOrder->asset->group->pcgroupname}}
+                            </div>
+                            @endif
+                            <div class="tab-pane" id="credentials" role="tabpanel" aria-labelledby="credentials-tab">
+                                <credential-list :credential-list="{{$workOrder->asset->credentials->sortByDesc('creddate')->values()}}" :descriptions="{{App\CredDesc::all()}}" :pcid="{{$workOrder->asset->pcid}}"></credential-list>
+                            </div> -->
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="col-lg-6">
+                <div class="card h-100">
+                    <div class="card-header text-right">
+                        <button type="button" class="btn btn-default xs-toggle" data-toggle="collapse" data-target="#workorderTab">
+                            <span class="sr-only">Toggle Navigation</span>
+                            <span class="icon-bar"></span>
+                            <span class="icon-bar"></span>
+                            <span class="icon-bar"></span>
+                        </button>
+                        <ul class="nav nav-pills card-header-pills nav-justified xs-collapse collapse" id="workorderTab" role="tablist">
+                            <li class="nav-item">
+                                <a class="nav-link active" id="workordersumm-tab" data-toggle="pill" href="#workordersumm" role="tab" aria-controls="workordersumm" aria-selected="true">Summary</a>
+                            </li>
+                            <li class="nav-item">
+                                <a class="nav-link" id="attachments-tab" data-toggle="pill" href="#attachments" role="tab" aria-controls="attachments" aria-selected="false">Attachments</a>
+                            </li>
+                        </ul>
+                    </div>
+                    <div class='card-body'>
+                        <div class='tab-content'>
+                            <div class="tab-pane active" id="workordersumm" role="tabpanel" aria-labelledby="workordersumm-tab">
+                                <work-order-info :work-order="workOrder" :stores="stores"></work-order-info>
+                            </div>
+                            <div class="tab-pane" id="attachments" role="tabpanel" aria-labelledby="attachments-tab">
+                                TODO 2
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <!-- <div class="row my-3 no-gutters">
+            <div class="col-12">
+                <div class="card">
+                    <div class="card-body">
+                        <h5 class="card-title">Customer Notes</h5>
+                        <notes :initialnotes='{{ $workOrder->notes->where('notetype', '0')->values() }}' authusername="{{Auth::user()->username}}" :note-type="0" :woid="{{$workOrder->woid}}"></notes>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="row my-3 no-gutters">
+            <div class="col-12">
+                <div class="card">
+                    <div class="card-body">
+                        <h5 class="card-title">Private/Billing Notes</h5>
+                        <notes :initialnotes='{{ $workOrder->notes->where('notetype', '1')->values() }}' authusername="{{Auth::user()->username}}" :note-type="1" :woid="{{$workOrder->woid}}"></notes>
+                    </div>
+                </div>
+            </div>
+        </div> -->
+    </div>
+</template>
+<script>
+import WorkOrderInfo from '../components/WorkOrderInfo.vue'
+export default {
+    components: {
+        WorkOrderInfo,
+    },
+    props: ['id'],
+    data () {
+        return {
+            workOrder: {},
+            stores: {},
+        }
+    },
+    mounted () {
+        let token = localStorage.getItem('jwt')
+        let user = localStorage.getItem('user')
+
+        axios.defaults.headers.common['Content-Type'] = 'application/json'
+        axios.defaults.headers.common['Authorization'] = 'Bearer ' + token
+
+        axios.get('/api/workorders/'+this.id).then(response => {
+            this.workOrder = response.data
+        }).catch(error => {
+            console.log(error)
+        })
+
+        axios.get('/api/stores/').then(response => {
+            this.stores = response.data
+        }).catch(error => {
+            console.log(error)
+        })
+        
+        Echo.channel('work-order.'+this.id)
+                .listen('WorkOrderUpdated', (e) => {
+                    this.workOrder = e.data;
+                });
+    },
+}
+</script>

+ 2 - 0
routes/api.php

@@ -21,6 +21,8 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
 });
 
 Route::middleware('auth:api')->group( function() {
+    Route::get('/users/{user}/workorders', 'Api\UsersController@workOrders');
+
     Route::get('/workorders/{workOrder}/assets');
     Route::get('/workorders/{workOrder}', 'Api\WorkOrdersController@show');
     Route::put('/workorders/{workOrder}', 'Api\WorkOrdersController@update');

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels