<|start_filename|>resources/js/store/device/mutations.js<|end_filename|>
export default {
  setDevice: (state, data) => state.device = data,
  setParameters: (state, data) => state.parameters = data,
  setCachedParameters: (state, data) => state.cachedParameters = data,
  hasCachedParams: (state, data) => state.hasCachedParams = data,
  setQueuedTasks: (state, data) => state.queuedTasks = data,
  setDeviceTemplates: (state, data) => state.deviceTemplates = data,
}


<|start_filename|>resources/js/store/dashboard/state.js<|end_filename|>
export default {
  dashboard: {
    devices_count: 0,
    informs_count: 0,
    faults_count: 0,
    faults: []
  },
}


<|start_filename|>resources/js/store/config/state.js<|end_filename|>
export default {
  config: {},
  debug: {},
}


<|start_filename|>resources/js/helpers/FlagParser.js<|end_filename|>
export class FlagParser {
  constructor(flag_obj) {
    this.flag = flag_obj
  }

  toString() {
    let ret = ""
    Object.keys(this.flag).forEach((item) => {
      if(this.flag[item] === true) {
        ret += `${item} `
      }
    })

    return ret
  }
}


<|start_filename|>resources/js/store/tasks/actions.js<|end_filename|>
// import axios from 'axios'

export default {
  async fetchTasks() {
    return await this._vm.$http.get('/api/settings/tasks')
  },
  async storeTask(context, data) {
    return await this._vm.$http.post('/api/settings/tasks', data)
  },
  async updateTask(context, data) {
    return await this._vm.$http.put(`/api/settings/tasks/${data.id}`, data)
  },
  async deleteTask(context, taskid) {
    return await this._vm.$http.delete(`/api/settings/tasks/${taskid}`)
  }
}


<|start_filename|>resources/js/store/user/mutations.js<|end_filename|>
export default {
  setUser: (state, data) => state.user = data,
}


<|start_filename|>resources/js/store/dashboard/mutations.js<|end_filename|>
export default {
  setDashboard: (state, data) => state.dashboard = data,
}


<|start_filename|>resources/js/helpers/Task.js<|end_filename|>
export class Task {
    constructor() {
        this.id = 0
        this.infinite = false
        this.for_type = ''
        this.for_id = ''
        this.not_before = new Date()
        this.name = ''
        this.payload = {}
    }

    for(id, name) {
        this.for_id = id
        this.for_type = name
        return this
    }

    notBefore(date) {
        this.not_before = date
    }

    asInfinite() {
        this.infinite = true
        return this
    }

    asAddObject(path) {
        this.name = 'AddObject'
        this.payload = {
            parameter: path
        }
    }

    asDeleteObjectTask(path) {
        this.name = 'DeleteObject'
        this.payload = {
            parameter: path
        }
    }

    asScriptTask(script) {
        this.name = 'RunScript'
        this.payload = {
            script: script
        }
    }

    asFirmwareUpdateTask(filetype, filename) {
        this.name = 'Download'
        this.payload = {
            filetype: filetype,
            filename: filename,
        }
    }

    asReboot() {
        this.name = 'Reboot'
        this.payload = {}
    }
}

export function taskFromObject(obj) {
    let task = new Task()
    task = Object.assign(task, obj)
    return task
}


<|start_filename|>resources/js/store/dashboard/getters.js<|end_filename|>
export default {
  getDashboard: state => state.dashboard,
}


<|start_filename|>resources/js/store/user/getters.js<|end_filename|>
export default {
  getUser: state => state.user,
}


<|start_filename|>resources/js/store/tasks/getters.js<|end_filename|>
export default {
  getTasks: state => state.tasks,
}


<|start_filename|>resources/js/store/index.js<|end_filename|>
import Vue from 'vue';
import Vuex from 'vuex';

import config from './config';
import device from './device';
import dashboard from './dashboard';
import template from './template';
import tasks from './tasks';
import file from './file';
import faults from './faults';
import user from './user';

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    sidebarShow: true,
    sidebarMinimize: false,
  },
  mutations: {
    toggleSidebarDesktop (state) {
      const sidebarOpened = [true, 'responsive'].includes(state.sidebarShow)
      state.sidebarShow = sidebarOpened ? false : 'responsive'
    },
    toggleSidebarMobile (state) {
      const sidebarClosed = [false, 'responsive'].includes(state.sidebarShow)
      state.sidebarShow = sidebarClosed ? true : 'responsive'
    },
    set (state, [variable, value]) {
      state[variable] = value
    },
  },
  actions: {
  },
  modules: {
    config,
    device,
    dashboard,
    template,
    tasks,
    file,
    faults,
    user,
  }
});

Vue.store = store;

export default store;


<|start_filename|>resources/js/app.js<|end_filename|>
import CoreuiVue from '@coreui/vue'
import { freeSet as icons } from "@coreui/icons";
import axios from 'axios';
import VueAxios from 'vue-axios'
import vSelect from 'vue-select'
import VueAuth, { DEFAULT_OPTIONS } from '@d0whc3r/vue-auth-plugin';
import VueRouter from 'vue-router';
import {ValidationObserver, ValidationProvider, extend} from 'vee-validate'
import * as rules from 'vee-validate/dist/rules';
import App from "./App.vue";
import Vue from "vue";
import moment from 'moment';
import router from "./router";
import store from "./store";
import errorsMixin from './helpers/errors.mixin'
import JsonTree from 'vue-json-tree'

window.Vue = require('vue').default;

Vue.config.productionTip = false;

axios.defaults.baseURL = process.env.VUE_APP_API_URL;
axios.defaults.headers['Authorization'] = 'Bearer {auth_token}';

moment.defaultFormat = "YYYY-MM-DD HH:mm:ss";
Vue.use(CoreuiVue)
Vue.use(VueRouter);
Vue.use(require('vue-moment'), { moment })
Vue.use(VueAxios, axios);
Vue.component('v-select', vSelect)
Vue.component('json-tree', JsonTree)


Object.keys(rules).forEach(rule => {
  extend(rule, rules[rule]);
});


Vue.component('ValidationProvider', ValidationProvider);
Vue.component('ValidationObserver', ValidationObserver);
Vue.mixin(errorsMixin);

const authPluginOptions = { ...DEFAULT_OPTIONS,
  ...{
    authRedirect: '/auth/login',
    loginData: {
      url: '/api/auth/login',
      method: 'POST',
      redirect: '/',
      customToken: (response) => response.data['token'],
      fetchUser: false,
      fetchData: (response) => response.data['user'],
    },
  },
  logoutData: {
    url: '/auth/logout',
    method: 'POST',
    redirect: '/auth/login',
    makeRequest: false,
  },
}

Vue.use(VueAuth, authPluginOptions);

const app = new Vue({
  el: '#app',
  render: h => h(App),
  router,
  store,
  icons,
});


<|start_filename|>resources/js/store/config/getters.js<|end_filename|>
export default {
  getConfig: state => state.config,
  getDebug: state => state.debug,
}


<|start_filename|>resources/js/router/index.js<|end_filename|>
import Vue from 'vue'
import VueRouter from 'vue-router'
import Base from "@/views/Base";
import LoginBase from "@/views/LoginBase";

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    component: Base,
    children: [
      {
        path: '',
        redirect: 'dashboard'
      },
      {
        path: 'dashboard',
        name: 'dashboard',
        component: () => import('@/views/home/Dashboard.vue')
      },
      {
        path: 'devices',
        name: 'devices-list',
        component: () => import('@/views/device/DeviceList.vue')
      },
      {
        path: 'devices/:id',
        name: 'devices-view',
        component: () => import('@/views/device/DeviceView.vue')
      },

      {
        path: 'templates',
        name: 'template-list',
        component: () => import('@/views/template/TemplateList.vue')
      },
      {
        path: 'templates/:id',
        name: 'template-view',
        component: () => import('@/views/template/TemplateView.vue')
      },
      {
        path: 'files',
        name: 'file-list',
        component: () => import('@/views/files/FileList.vue')
      },
      {
        path: 'settings',
        name: 'settings',
        component: () => import('@/views/settings/SettingsView.vue'),
        children: [
          {
            path: '',
            name: 'settings-main',
            component: () => import('@/views/settings/ConfigurationView.vue'),
          },
          {
            path: 'tasks',
            name: 'settings-tasks',
            component: () => import('@/views/settings/tasks/TasksList.vue'),
          },
          {
            path: 'users',
            name: 'settings-users',
            component: () => import('@/views/settings/users/UsersList.vue'),
          },
          {
            path: 'debug',
            name: 'settings-debug',
            component: () => import('@/views/settings/debug/DebugView.vue'),
          }
        ]
      }
    ],
    meta: {
      auth: true,
    },
  },
  {
    path: '/auth',
    name: 'auth',
    component: LoginBase,
    children: [
      {
        path: 'login',
        name: 'login',
        component: () => import('@/views/auth/Login.vue')
      },
      {
        path: 'logout',
        name: 'logout',
        component: () => import('@/views/auth/Logout.vue')
      }
    ]

  }
]

const router = new VueRouter({
  mode: 'history',
  routes
})

Vue.router = router;

export default router


<|start_filename|>resources/js/store/tasks/mutations.js<|end_filename|>
export default {
  setTasks: (state, data) => state.tasks = data,
}


<|start_filename|>resources/js/store/device/getters.js<|end_filename|>
export default {
  getDevice: state => state.device,
  getParameters: state => state.parameters,
  getCachedParameters: state => state.cachedParameters,
  hasCachedParams: state => state.hasCachedParams,
  getQueuedTasks: state => state.queuedTasks,
  getDeviceTemplates: state => state.deviceTemplates,
}


<|start_filename|>resources/js/store/template/state.js<|end_filename|>
export default {
  template: {},
  parameters: [],
}


<|start_filename|>resources/js/store/template/getters.js<|end_filename|>
export default {
  getTemplate: state => state.template,
  getParameters: state => state.parameters,
}


<|start_filename|>resources/js/store/template/mutations.js<|end_filename|>
export default {
  setTemplate: (state, data) => state.template = data,
  setParameters: (state, data) => state.parameters = data,
}


<|start_filename|>resources/js/store/config/actions.js<|end_filename|>
// import axios from 'axios'

export default {
  async getConfig() {
    return await this._vm.$http.get('/api/settings')
  },
  async saveConfig(context, config) {
    return await this._vm.$http.post('/api/settings', config)
  },
  async fetchDebugConfig({ commit }) {
    const response = await this._vm.$http.get('/api/settings/debug');
    commit('setDebug', response.data.data);
  },
  async saveDebugConfig({ commit }, debugConfig) {
    const response = await this._vm.$http.post('/api/settings/debug', debugConfig)
    commit('setDebug', response.data.data);
  }
}


<|start_filename|>resources/js/store/config/mutations.js<|end_filename|>
export default {
  setConfig: (state, data) => state.config = data,
  setDebug: (state, data) => state.debug = data,
}


<|start_filename|>resources/js/store/file/getters.js<|end_filename|>
export default {
  getFilesList: state => state.files,
}


<|start_filename|>resources/js/store/template/actions.js<|end_filename|>
// import axios from 'axios'

import {filterToQueryString} from "../../helpers/URL";

export default {
  async list(context, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    return await this._vm.$http.get(`/api/template?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
  },
  async fetchTemplate({ commit }, templateId) {
    try {
      const response = await this._vm.$http.get(`/api/template/${templateId}`)
      commit('setTemplate', response.data.data)
    } catch (e) {
      console.error("Cannot fetch template")
    }
  },
  async listParameters({ commit }, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    try {
      const response = await this._vm.$http.get(`/api/template/${parameters.templateId}/parameters?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
      commit('setParameters', response.data.data)
      return response
    } catch (e) {
      console.error("Cannot fetch template parameters")
    }
  },
  async addTemplate(context, params) {
    return await this._vm.$http.post(`/api/template`, {
      name: params.name,
    })
  },
  async updateTemplate(context, params) {
    return await this._vm.$http.patch(`/api/template/${params.id}`, {
      name: params.name,
    })
  },
  async storeParameter(context, parameters) {
    return await this._vm.$http.post(`/api/template/${parameters.templateId}/parameters`, {
      ...parameters
    })
  },
  async updateParameter(context, parameters) {
    return await this._vm.$http.put(`/api/template/${parameters.templateId}/parameters/${parameters.id}`, {
      ...parameters
    })
  },
  async deleteParameter(context, parameters) {
    return await this._vm.$http.delete(`/api/template/${parameters.templateId}/parameters/${parameters.id}`)
  }
}


<|start_filename|>resources/js/store/faults/actions.js<|end_filename|>
// import axios from 'axios'

import {filterToQueryString} from "../../helpers/URL";

export default {
  async list(context, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    return await this._vm.$http.get(`/api/faults?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
  },
}


<|start_filename|>resources/js/helpers/errors.mixin.js<|end_filename|>
export default {
  data() {
    return {
      errors: [],
    }
  },
  methods: {
    isvalid(scope) {
      if(scope.validated === false) {
        return null;
      }
      return scope.valid;
    }
  }
}


<|start_filename|>resources/js/store/file/actions.js<|end_filename|>
// import axios from 'axios'


import {filterToQueryString} from "@/helpers/URL";

export default {
  async list(context, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    return await this._vm.$http.get(`/api/file?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
  },
  async all({ commit }) {
    const response = await this._vm.$http.get('/api/file')
    commit('setFilesList', response.data.data)
    return response
  },
  async upload(context, params) {
    const formData = new FormData();
    formData.append('file', params.file)
    formData.append('type', params.type)
    return await this._vm.$http.post('/api/file', formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  },
  async download(context, file_id) {
      return await this._vm.$http.get(`/api/file/${file_id}/download`, {
        responseType: 'blob',
      })
  },
  async delete(context, file_id) {
    return await this._vm.$http.delete(`/api/file/${file_id}`);
  }
}


<|start_filename|>resources/js/store/device/state.js<|end_filename|>
export default {
  device: {},
  parameters: [],
  cachedParameters: [],
  queuedTasks: [],
  deviceTemplates: [],
  hasCachedParams: false,
}


<|start_filename|>resources/js/store/file/mutations.js<|end_filename|>
export default {
  setFilesList: (state, data) => state.files = data,
}


<|start_filename|>resources/js/store/dashboard/actions.js<|end_filename|>
// import axios from 'axios'

export default {
  async fetchDashboard({ commit }) {
    try {
      const response = await this._vm.$http.get(`/api/dashboard`)
      commit('setDashboard', response.data)
    } catch (e) {
      console.error("Cannot fetch dashboard data")
    }
  },
}


<|start_filename|>resources/js/helpers/URL.js<|end_filename|>
import { isEmpty } from 'lodash'

export function filterToQueryString(filterObject) {
  let str = "";


  Object.keys(filterObject).forEach(key => {
    let value = filterObject[key];
    if (isEmpty(value) === false) {
      str += '&filter[' + key + ']=' + value;
    }
  });

  return str
}


<|start_filename|>docker/php-fpm/Dockerfile<|end_filename|>
FROM php:8.0-fpm
WORKDIR "/app"

# Fix debconf warnings upon build
ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update -y && \
    apt-get install git -y

# Install selected extensions
RUN apt-get update && \
    apt-get install -y libpq-dev       \
            inotify-tools              \
            libcurl4-openssl-dev       \
            libssl-dev                 \
            supervisor                 \
            unzip                      \
            zlib1g-dev                 \
            nodejs                     \
            npm                        \
            httpie                     \
            --no-install-recommends

RUN pecl install swoole redis

RUN npm install chokidar

RUN docker-php-ext-install \
    pdo \
    pdo_pgsql \
    pcntl \
    pdo_mysql

RUN docker-php-ext-enable swoole
RUN docker-php-ext-enable redis
RUN docker-php-ext-enable pcntl

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
ADD https://github.com/moparisthebest/static-curl/releases/download/v7.77.0/curl-amd64 /usr/local/bin/curl
RUN chmod +x /usr/local/bin/curl

RUN mkdir -p /var/log/supervisor && \
        rm -rf /var/lib/apt/lists/* $HOME/.composer/*-old.phar /usr/bin/qemu-*-static

RUN composer install --no-dev

CMD ["/usr/bin/supervisord","-c","/etc/supervisor/supervisord.conf"]


<|start_filename|>resources/js/store/device/actions.js<|end_filename|>
// import axios from 'axios'

import {filterToQueryString} from "../../helpers/URL";

export default {
  async list(context, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    return await this._vm.$http.get(`/api/device?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
  },
  async fetchDevice({ commit }, id) {
    try {
      const response = await this._vm.$http.get(`/api/device/${id}`)
      commit('setDevice', response.data.data)
    } catch (e) {
      console.error("Cannot fetch device")
    }
  },
  async updateDevice({commit}, device) {
    try {
      const response = await this._vm.$http.patch(`/api/device/${device.id}`, device);
      commit('setDevice', response.data.data)
    } catch (e) {
      console.error("Cannot update device")
    }
  },
  async fetchParameters({ commit }, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    try {
      const response = await this._vm.$http.get(`/api/device/${parameters.id}/parameters?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
      const data = response.data.data.map(item => {
        if(item.source === 'template') {
          item._classes = 'template-item';
        }

        return item;
      })
      commit('setParameters', response.data.data)
      commit('hasCachedParams', response.data.has_cached_items)
      return response
    } catch (e) {
      console.error("Cannot fetch device parameters")
    }
  },
  async fetchCachedParameters({ commit }, device_id) {
    try {
      const response = await this._vm.$http.get(`/api/device/${device_id}/parameters/cached`)
      commit('setCachedParameters', response.data.data)
      return response
    } catch (e) {
      console.error("Cannot fetch device cached parameters")
    }
  },
  async storeParameter(context, data) {
    return await this._vm.$http.post(`/api/device/${data.device_id}/parameters`, {
      ...data
    })
  },
  async updateParameters(context, data) {
    return await this._vm.$http.put(`/api/device/${data.device_id}/parameters/${data.id}`, {
      ...data
    })
  },
  async deleteParameter(context, data) {
    return await this._vm.$http.delete(`/api/device/${data.device_id}/parameters/${data.id}`)
  },
  async kickDevice(context, id) {
    return await this._vm.$http.get(`/api/device/${id}/provision`)
  },
  async deleteDevice(context, id) {
    return await this._vm.$http.delete(`/api/device/${id}`)
  },
  async addObject(context, params) {
    const {id, name, key} = params
    return await this._vm.$http.post(`/api/device/${id}/addobject`, {
      name,
      key,
    })
  },
  async lookup(context, id) {
    return await this._vm.$http.get(`/api/device/${id}/lookup`)
  },
  async fetchQueuedTasks({ commit }, id) {
    try {
      const response = await this._vm.$http.get(`/api/device/${id}/tasks`)
      commit('setQueuedTasks', response.data.data)
      return response
    } catch (e) {
      console.log('cannot fetch queued tasks', e)
    }
  },
  async fetchDeviceTemplates({ commit }, id) {
    try {
      const response = await this._vm.$http.get(`/api/device/${id}/templates`)
      commit('setDeviceTemplates', response.data.data)
      return response
    } catch (e) {
      console.log('cannot fetch device templates', e)
    }
  },
  async assignTemplate(context, params) {
    return await this._vm.$http.post(`/api/device/${params.device_id}/templates`, {
      template_id: params.template_id,
      priority: params.priority,
    })
  },
  async unAssignTemplate(context, params) {
    return await this._vm.$http.delete(`/api/device/${params.device_id}/templates/${params.template_id}`)
  },

  async addTask(context, params) {
    return await this._vm.$http.post(`/api/device/${params.device_id}/tasks`, params.task)
  },
  async listLogs(context, parameters) {
    const filterStr = filterToQueryString(parameters.filter)
    return await this._vm.$http.get(`/api/device/${parameters.device_id}/logs?page=${parameters.page}&per_page=${parameters.perPage}${filterStr}`)
  },
}
