diff options
author | Matthias <ilovemilk@wusa.io> | 2020-04-10 13:25:49 +0300 |
---|---|---|
committer | Matthias <ilovemilk@wusa.io> | 2020-04-10 13:25:49 +0300 |
commit | 133a820b88a78a4281e017d88d11bed169b5fdbf (patch) | |
tree | 0bd785eb085699b18a8283891248d77b194f5c12 /src/views | |
parent | 0a92726e3f3d082ad87101dfb9819e736bcd9df7 (diff) |
add first vuejs ui version
Diffstat (limited to 'src/views')
-rw-r--r-- | src/views/History.vue | 123 | ||||
-rw-r--r-- | src/views/Protection.vue | 85 | ||||
-rw-r--r-- | src/views/Recover.vue | 153 |
3 files changed, 361 insertions, 0 deletions
diff --git a/src/views/History.vue b/src/views/History.vue new file mode 100644 index 0000000..18bd197 --- /dev/null +++ b/src/views/History.vue @@ -0,0 +1,123 @@ +<template> + <AppContent> + <iron-pages :selected="page"> + <div id="loading" class="page"> + <paper-spinner active></paper-spinner> + </div> + <div class="page"> + <Header header="History"> + <RecoverAction id="recover" label="Recover selected files" v-on:recover="onRecover" primary></RecoverAction> + </Header> + <FileOperationsTable id="ransomware-table" :data="fileOperations" v-on:table-state-changed="tableStateChanged"></FileOperationsTable> + </div> + </iron-pages> + </AppContent> +</template> + +<script> +import '@polymer/paper-spinner/paper-spinner.js'; +import '@polymer/iron-pages/iron-pages.js'; +import FileOperationsTable from '../components/FileOperationsTable' +import Header from '../components/Header' +import RecoverAction from '../components/RecoverAction' +import AppContent from 'nextcloud-vue/dist/Components/AppContent' + +export default { + name: 'History', + components: { + AppContent, + FileOperationsTable, + Header, + RecoverAction + }, + data() { + return { + fileOperations: [], + page: 0 + }; + }, + mounted() { + this.page = 0; + this.fetchData(); + setInterval(() => this.fetchData(), 3000); + }, + computed: { + recoverUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operation') + }, + fileOperationsUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operation') + } + }, + methods: { + tableStateChanged() { + this.page = 1; + }, + fetchData() { + this.$axios({ + method: 'GET', + url: this.fileOperationsUrl + }) + .then(json => { + this.fileOperations = json.data; + }) + .catch( error => { console.error(error); }); + }, + onRecover() { + const items = document.querySelector('#ransomware-table').items; + const selected = document.querySelector('#ransomware-table').selectedItems; + for (var i = 0; i < selected.length; i++) { + this.recover(selected[i].id); + } + }, + remove(id) { + for (var i = 0; i < this.fileOperations.length; i++) { + if (this.fileOperations[i].id === id) { + this.fileOperations.splice(i, 1); + } + } + }, + async recover(id) { + await this.$axios({ + method: 'PUT', + url: this.recoverUrl + '/' + id + '/recover' + }) + .then(response => { + switch(response.status) { + case 204: + this.remove(id); + break; + default: + console.log(response); + break; + } + }) + .catch(error => { + console.error(error); + }); + } + } +} +</script> + +<style scoped> + #ransomware-table { + height: calc(100% - 50px); + } + #recover { + background-color: grey; + color: #fff; + } + iron-pages { + height: 100%; + } + .page { + height: 100%; + } + #loading { + display: flex; + align-items: center; + height: 90vh; + justify-content: center; + } +</style>
\ No newline at end of file diff --git a/src/views/Protection.vue b/src/views/Protection.vue new file mode 100644 index 0000000..3ce0848 --- /dev/null +++ b/src/views/Protection.vue @@ -0,0 +1,85 @@ +<template> + <AppContent> + <iron-pages selected="0"> + <div id="loading"> + <paper-spinner active></paper-spinner> + </div> + <div> + <ProtectionStatus :detection-link="detectionUrl" :protection-link="servicesUrl" id="protection-status" v-on:protection-state-changed="protectionStateChanged"></ProtectionStatus> + <div id="services"> + <ServiceStatus :link="detectionServiceUrl" description="Your files currently cannot be analyzed for ransomware. To enable ransomware detection, contact your system administator." v-on:service-state-changed="detectionStateChanged" class="service"></ServiceStatus> + <ServiceStatus :link="monitorServiceUrl" description="There may be a problem with your Nextcloud installation. Please contact your system administator." v-on:service-state-changed="monitorStateChanged" class="service"></ServiceStatus> + </div> + </div> + </iron-pages> + </AppContent> +</template> + +<script> +import '@polymer/paper-spinner/paper-spinner.js'; +import '@polymer/iron-pages/iron-pages.js'; +import AppContent from 'nextcloud-vue/dist/Components/AppContent' +import ProtectionStatus from '../components/ProtectionStatus' +import ServiceStatus from '../components/ServiceStatus' + +export default { + name: 'Protection', + components: { + AppContent, + ProtectionStatus, + ServiceStatus + }, + data() { + return { + protectionReady: false, + detectionReady: false, + monitorReady: false + }; + }, + computed: { + detectionUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/detection'); + }, + servicesUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/service'); + }, + detectionServiceUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/service/0'); + }, + monitorServiceUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/service/1'); + } + }, + methods: { + protectionStateChanged() { + this.protectionReady = true; + this.hideSpinner(); + }, + monitorStateChanged() { + this.monitorReady = true; + this.hideSpinner(); + }, + detectionStateChanged() { + this.detectionReady = true; + this.hideSpinner(); + }, + hideSpinner() { + if (this.protectionReady && this.monitorReady && this.detectionReady) { + document.querySelector('iron-pages').selectIndex(1); + } + } + } +} +</script> + +<style scoped> + #protection-status { + height: 40vh; + } + #loading { + display: flex; + align-items: center; + height: 90vh; + justify-content: center; + } +</style>
\ No newline at end of file diff --git a/src/views/Recover.vue b/src/views/Recover.vue new file mode 100644 index 0000000..51aa6ca --- /dev/null +++ b/src/views/Recover.vue @@ -0,0 +1,153 @@ +<template> + <AppContent> + <iron-pages :selected="page"> + <div id="loading" class="page"> + <paper-spinner active></paper-spinner> + </div> + <div class="page"> + <Header header="Recover"> + <RecoverAction v-if="detected" id="recover" label="Recover" v-on:recover="onRecover" primary></RecoverAction> + </Header> + <FileOperationsTable v-if="detected" id="ransomware-table" :data="fileOperations" v-on:table-state-changed="tableStateChanged"></FileOperationsTable> + <span id="message" v-if="!detected"> + <iron-icon icon="verified-user"></iron-icon> + Nothing found. You are safe. + </span> + </div> + </iron-pages> + </AppContent> +</template> + +<script> +import '@polymer/paper-spinner/paper-spinner.js'; +import '@polymer/iron-pages/iron-pages.js'; +import '@polymer/iron-icon/iron-icon.js'; +import '@polymer/iron-icons/iron-icons.js'; +import FileOperationsTable from '../components/FileOperationsTable' +import Header from '../components/Header' +import RecoverAction from '../components/RecoverAction' +import AppContent from 'nextcloud-vue/dist/Components/AppContent' + +export default { + name: 'Recover', + components: { + AppContent, + FileOperationsTable, + Header, + RecoverAction + }, + data() { + return { + detected: 0, + fileOperations: [], + page: 0 + }; + }, + mounted() { + this.page = 0; + this.fetchDetectionStatus(); + this.fetchData(); + }, + methods: { + fetchDetectionStatus() { + this.$axios({ + method: 'GET', + url: this.detectionsUrl + }) + .then(json => { + if (json.data.length > 0) { + this.detected = 1; + } else { + this.page = 1; + } + }) + .catch( error => { console.error(error); }); + }, + tableStateChanged() { + this.page = 1; + }, + fetchData() { + this.$axios({ + method: 'GET', + url: this.fileOperationsUrl + }) + .then(json => { + this.fileOperations = json.data; + }) + .catch( error => { console.error(error); }); + }, + onRecover() { + const items = document.querySelector('#ransomware-table').items; + const selected = document.querySelector('#ransomware-table').selectedItems; + for (var i = 0; i < selected.length; i++) { + this.recover(selected[i].id); + } + }, + remove(id) { + for (var i = 0; i < this.fileOperations.length; i++) { + if (this.fileOperations[i].id === id) { + this.fileOperations.splice(i, 1); + } + } + }, + async recover(id) { + await this.$axios({ + method: 'PUT', + url: this.recoverUrl + '/' + id + '/recover' + }) + .then(response => { + switch(response.status) { + case 204: + this.remove(id); + break; + default: + console.log(response); + break; + } + }) + .catch(error => { + console.error(error); + }); + } + }, + computed: { + detectionsUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/detection'); + }, + recoverUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operation') + }, + fileOperationsUrl() { + return OC.generateUrl('/apps/ransomware_detection/api/v1/file-operation') + } + } +} +</script> + +<style scoped> + #ransomware-table { + height: calc(100% - 50px); + } + #recover { + background-color: green; + color: #fff; + } + #message { + display: flex; + justify-content: center; + font-size: 1.5em; + font-weight: bold; + } + iron-pages { + height: 100%; + } + .page { + height: 100%; + } + #loading { + display: flex; + align-items: center; + height: 90vh; + justify-content: center; + } +</style>
\ No newline at end of file |