diff options
author | Matthias <ilovemilk@wusa.io> | 2020-09-19 19:12:03 +0300 |
---|---|---|
committer | Matthias <ilovemilk@wusa.io> | 2020-09-19 19:12:03 +0300 |
commit | 95575d7688e50dfaddc34f9353f87556d61b82e4 (patch) | |
tree | 6312997dc305c4dd7872e343ed8429ecf73f8ed8 /src | |
parent | dfeda8d4bdd88d5ec99a87610b47ade98a8065d7 (diff) |
replace vaadin grid wie vuetify data table
Diffstat (limited to 'src')
-rw-r--r-- | src/App.vue | 2 | ||||
-rw-r--r-- | src/components/FileOperationsTable.vue | 135 | ||||
-rw-r--r-- | src/components/Header.vue | 2 | ||||
-rw-r--r-- | src/components/Notification.vue | 2 | ||||
-rw-r--r-- | src/components/ProtectionStatus.vue | 2 | ||||
-rw-r--r-- | src/components/RecoverAction.vue | 2 | ||||
-rw-r--r-- | src/css/global.scss (renamed from src/css/global.css) | 0 | ||||
-rw-r--r-- | src/main.js | 5 | ||||
-rw-r--r-- | src/plugins/vuetify.js | 8 | ||||
-rw-r--r-- | src/views/History.vue | 79 | ||||
-rw-r--r-- | src/views/Protection.vue | 2 | ||||
-rw-r--r-- | src/views/Recover.vue | 64 |
12 files changed, 140 insertions, 163 deletions
diff --git a/src/App.vue b/src/App.vue index 9456891..c85ec64 100644 --- a/src/App.vue +++ b/src/App.vue @@ -52,5 +52,5 @@ export default { } </script> -<style scoped> +<style lang="scss"> </style>
\ No newline at end of file diff --git a/src/components/FileOperationsTable.vue b/src/components/FileOperationsTable.vue deleted file mode 100644 index 2f4e60f..0000000 --- a/src/components/FileOperationsTable.vue +++ /dev/null @@ -1,135 +0,0 @@ -<template> - <vaadin-grid ref="grid" theme="row-dividers" height-by-rows column-reordering-allowed multi-sort :items.prop="fileOperations"> - <vaadin-grid-selection-column v-if="selectable" auto-select frozen></vaadin-grid-selection-column> - <vaadin-grid-column width="5em" flex-grow="0" header="Status" ref="status"></vaadin-grid-column> - <vaadin-grid-column width="9em" flex-grow="0" ref="operation" header="" class="operation"></vaadin-grid-column> - <vaadin-grid-sort-column width="9em" path="originalName" header="Name" ref="name"></vaadin-grid-sort-column> - <vaadin-grid-sort-column width="9em" path="timestamp" ref="time" header="File changed"></vaadin-grid-sort-column> - </vaadin-grid> -</template> - -<script> -import '@vaadin/vaadin-grid/vaadin-grid.js'; -import '@vaadin/vaadin-grid/vaadin-grid-selection-column.js'; -import '@vaadin/vaadin-grid/vaadin-grid-sort-column.js'; -import '@vaadin/vaadin-grid/vaadin-grid-column.js'; -import '@polymer/iron-icon/iron-icon.js'; -import '@polymer/iron-icons/iron-icons.js'; -import '@polymer/iron-icons/editor-icons.js'; -import '../webcomponents/ransomware-icons' -import 'time-elements/dist/time-elements'; -import moment from 'moment' - -export default { - name: 'FileOperationsTable', - data() { - return { - fileOperations: this.items - } - }, - props: { - data: { - type: Array, - required: true - }, - selectable: { - type: Boolean, - default: true - } - }, - watch: { - data: { - immediate: true, - handler (newVal, oldVal) { - this.fileOperations = newVal; - this.$emit('table-state-changed'); - } - } - }, - mounted () { - this.$refs.status.renderer = (root, grid, rowData) => { - const icon = document.createElement('iron-icon'); - if (rowData.item.suspicionClass > 1) { - icon.setAttribute('icon', 'ransomware:locked'); - icon.style = "color: #ED0012;" - } else if (rowData.item.suspicionClass == 1) { - if (rowData.item.type == "folder") { - icon.setAttribute('icon', 'folder'); - } - if (rowData.item.type == "file") { - icon.setAttribute('icon', 'editor:insert-drive-file'); - } - icon.style = "color: #7ED221;" - } else { - if (rowData.item.type == "folder") { - icon.setAttribute('icon', 'folder'); - } - if (rowData.item.type == "file") { - icon.setAttribute('icon', 'editor:insert-drive-file'); - } - icon.style = "color: #9B9A9B;" - } - root.innerHTML = ''; - root.appendChild(icon); - } - - this.$refs.time.renderer = (root, grid, rowData) => { - const localTime = document.createElement('local-time'); - localTime.setAttribute('datetime', moment.unix(rowData.item.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSS")); - localTime.textContent = moment.unix(rowData.item.timestamp).format('dddd, MMMM Do YYYY, HH:mm:ss'); - root.innerHTML = ''; - root.appendChild(localTime); - } - - this.$refs.operation.renderer = (root, grid, rowData) => { - root.style = "color: #878787;" - switch (rowData.item.command) { - case 1: - if (rowData.item.type == 'file') { - root.innerHTML = 'File deleted'; - } else { - root.innerHTML = 'Folder deleted'; - } - break; - case 2: - if (rowData.item.type == 'file') { - root.innerHTML = 'File renamed'; - } else { - root.innerHTML = 'Folder renamed'; - } - break; - case 3: - if (rowData.item.type == 'file') { - root.innerHTML = 'File written'; - } else { - root.innerHTML = 'Folder written'; - } - break; - case 4: - if (rowData.item.type == 'file') { - root.innerHTML = 'File read'; - } else { - root.innerHTML = 'Folder read'; - } - break; - case 5: - if (rowData.item.type == 'file') { - root.innerHTML = 'File created'; - } else { - root.innerHTML = 'Folder created'; - } - break; - default: - root.innerHTML = 'No information'; - break; - } - } - } -} -</script> - -<style scoped> - vaadin-grid { - border: none; - } -</style>
\ No newline at end of file diff --git a/src/components/Header.vue b/src/components/Header.vue index 456d065..e42b431 100644 --- a/src/components/Header.vue +++ b/src/components/Header.vue @@ -22,7 +22,7 @@ export default { } </script> -<style scoped> +<style lang="scss"> h2 { height: 100%; margin: 0px; diff --git a/src/components/Notification.vue b/src/components/Notification.vue index 9b691ba..5aeaa8b 100644 --- a/src/components/Notification.vue +++ b/src/components/Notification.vue @@ -36,7 +36,7 @@ export default { } </script> -<style lang="scss" scoped> +<style lang="scss"> .notification { background-color: #E7E7E7; color: #000; diff --git a/src/components/ProtectionStatus.vue b/src/components/ProtectionStatus.vue index f2dfc34..79258e7 100644 --- a/src/components/ProtectionStatus.vue +++ b/src/components/ProtectionStatus.vue @@ -53,7 +53,7 @@ export default { } </script> -<style lang="scss" scoped> +<style lang="scss"> .container { h1 { height: calc(100% - 52px); diff --git a/src/components/RecoverAction.vue b/src/components/RecoverAction.vue index 515b83b..225bd8a 100644 --- a/src/components/RecoverAction.vue +++ b/src/components/RecoverAction.vue @@ -27,7 +27,7 @@ export default { } </script> -<style lang="scss" scoped> +<style lang="scss"> button { --border-radius-pill: 0px; } diff --git a/src/css/global.css b/src/css/global.scss index 8ef68df..8ef68df 100644 --- a/src/css/global.css +++ b/src/css/global.scss diff --git a/src/main.js b/src/main.js index e2242b0..f2d4b58 100644 --- a/src/main.js +++ b/src/main.js @@ -6,8 +6,8 @@ import App from './App' import router from './router' import VueMoment from 'vue-moment' import AsyncComputed from 'vue-async-computed' -import {sync} from 'vuex-router-sync' import axios from "axios"; +import vuetify from './plugins/vuetify' // CSP config for webpack dynamic chunk loading @@ -19,7 +19,7 @@ __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-next-line __webpack_public_path__ = OC.linkTo('ransomware_detection', 'js/') -import "./css/global.css" +import "./css/global.scss" Vue.prototype.t = t Vue.prototype.n = n @@ -35,6 +35,7 @@ Vue.config.devtools = true /* eslint-disable-next-line no-new */ new Vue({ el: '#content', + vuetify, router, render: h => h(App) })
\ No newline at end of file diff --git a/src/plugins/vuetify.js b/src/plugins/vuetify.js new file mode 100644 index 0000000..3248e06 --- /dev/null +++ b/src/plugins/vuetify.js @@ -0,0 +1,8 @@ +import Vue from 'vue' +import Vuetify from 'vuetify' + +Vue.use(Vuetify) + +const opts = {} + +export default new Vuetify(opts)
\ No newline at end of file diff --git a/src/views/History.vue b/src/views/History.vue index 808245b..8603567 100644 --- a/src/views/History.vue +++ b/src/views/History.vue @@ -11,7 +11,41 @@ <Header header="History"> <RecoverAction id="recover" label="Recover selected files" v-on:recover="onRecover" primary></RecoverAction> </Header> - <FileOperationsTable ref="ransomware-table" id="ransomware-table" :data="fileOperations" v-on:table-state-changed="tableStateChanged"></FileOperationsTable> + <v-data-table + v-model="selected" + ref="ransomwareTable" + class="ransomware-table" + :headers="headers" + :items="fileOperations" + hide-default-footer + show-select + item-key="id" + > + <template v-slot:item.timestamp = "{ item }"> + <local-time>{{ moment(item.timestamp) }}</local-time> + </template> + <template v-slot:item.suspicionClass = "{ item }"> + <iron-icon v-if="item.suspicionClass > 1" style="color: #ED0012;" icon="ransomware:locked"></iron-icon> + <iron-icon v-if="item.suspicionClass == 1 && item.type == 'folder'" style="color: #7ED221;" icon="folder"></iron-icon> + <iron-icon v-if="item.suspicionClass == 1 && item.type == 'file'" style="color: #7ED221;" icon="editor:insert-drive-file"></iron-icon> + <iron-icon v-if="item.suspicionClass < 1 && item.type == 'folder'" style="color: #9B9A9B;" icon="folder"></iron-icon> + <iron-icon v-if="item.suspicionClass < 1 && item.type == 'file'" style="color: #9B9A9B;" icon="editor:insert-drive-file"></iron-icon> + </template> + <template v-slot:item.command = "{ item }"> + <span v-if="item.command == 1 && item.type == 'file'">File deleted</span> + <span v-if="item.command == 1 && item.type == 'folder'">Folder deleted</span> + <span v-if="item.command == 2 && item.type == 'file'">File renamed</span> + <span v-if="item.command == 2 && item.type == 'folder'">Folder renamed</span> + <span v-if="item.command == 3 && item.type == 'file'">File written</span> + <span v-if="item.command == 3 && item.type == 'folder'">Folder written</span> + <span v-if="item.command == 4 && item.type == 'file'">File read</span> + <span v-if="item.command == 4 && item.type == 'folder'">Folder read</span> + <span v-if="item.command == 5 && item.type == 'file'">File created</span> + <span v-if="item.command == 5 && item.type == 'folder'">Folder created</span> + <span v-if="item.command > 5 && item.command < 1 && item.type == 'file'">No information</span> + <span v-if="item.command > 5 && item.command < 1 && item.type == 'folder'">No information</span> + </template> + </v-data-table> </div> </iron-pages> </AppContent> @@ -20,7 +54,11 @@ <script> import '@polymer/paper-spinner/paper-spinner.js'; import '@polymer/iron-pages/iron-pages.js'; -import FileOperationsTable from '../components/FileOperationsTable' +import '@polymer/iron-icon/iron-icon.js'; +import '@polymer/iron-icons/iron-icons.js'; +import '@polymer/iron-icons/editor-icons.js'; +import '../webcomponents/ransomware-icons' +import 'time-elements/dist/time-elements'; import Header from '../components/Header' import Notification from '../components/Notification' import RecoverAction from '../components/RecoverAction' @@ -30,7 +68,6 @@ export default { name: 'History', components: { AppContent, - FileOperationsTable, Header, RecoverAction, Notification @@ -40,7 +77,19 @@ export default { fileOperations: [], page: 0, visible: false, - notificationText: "" + notificationText: "", + selected: [], + headers: [ + { + text: 'Status', + align: 'start', + sortable: false, + value: 'suspicionClass', + }, + { text: 'Operation', value: 'command' }, + { text: 'Name', value: 'originalName' }, + { text: 'File Changed', value: 'timestamp' }, + ], }; }, mounted() { @@ -80,9 +129,6 @@ export default { } this.notice(notificationText); }, - tableStateChanged() { - this.page = 1; - }, fetchData() { this.$axios({ method: 'GET', @@ -90,14 +136,17 @@ export default { }) .then(json => { this.fileOperations = json.data; + this.page = 1; }) .catch( error => { console.error(error); }); }, onRecover() { + console.log(this.selected); + }, + itemsToRecover(e) { var itemsToRecover = []; - const selected = this.$refs.ransomware-table.selectedItems; - for (var i = 0; i < selected.length; i++) { - itemsToRecover.push(selected[i].id); + for (var i = 0; i < e.length; i++) { + itemsToRecover.push(e[i].id); } this.recover(itemsToRecover); }, @@ -134,13 +183,19 @@ export default { }) .catch(error => { console.error(error); - }); + }); + }, + moment: function (date) { + return moment.unix(date).format('dddd, MMMM Do YYYY, HH:mm:ss') + }, + datetime: function(date) { + return moment.unix(rowData.item.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSS") } } } </script> -<style scoped> +<style lang="scss"> #ransomware-table { height: calc(100% - 50px); } diff --git a/src/views/Protection.vue b/src/views/Protection.vue index 201919f..46eb5da 100644 --- a/src/views/Protection.vue +++ b/src/views/Protection.vue @@ -47,7 +47,7 @@ export default { } </script> -<style scoped> +<style lang="scss"> #protection-status { height: 40vh; } diff --git a/src/views/Recover.vue b/src/views/Recover.vue index 75b0599..776a6eb 100644 --- a/src/views/Recover.vue +++ b/src/views/Recover.vue @@ -14,7 +14,38 @@ <Header :header="'Detection ' + detection.id"> <RecoverAction id="recover" label="Recover detected files" v-on:recover="onRecover(detection.id)" primary></RecoverAction> </Header> - <FileOperationsTable :selectable="false" :ref="'detection' + detection.id" class="ransomware-table" :data="detection.fileOperations" v-on:table-state-changed="tableStateChanged"></FileOperationsTable> + <v-data-table + :ref="'detection' + detection.id" + class="ransomware-table" + :headers="headers" + :items="detection.fileOperations" + hide-default-footer + > + <template v-slot:item.timestamp = "{ item }"> + <local-time>{{ moment(item.timestamp) }}</local-time> + </template> + <template v-slot:item.suspicionClass = "{ item }"> + <iron-icon v-if="item.suspicionClass > 1" style="color: #ED0012;" icon="ransomware:locked"></iron-icon> + <iron-icon v-if="item.suspicionClass == 1 && item.type == 'folder'" style="color: #7ED221;" icon="folder"></iron-icon> + <iron-icon v-if="item.suspicionClass == 1 && item.type == 'file'" style="color: #7ED221;" icon="editor:insert-drive-file"></iron-icon> + <iron-icon v-if="item.suspicionClass < 1 && item.type == 'folder'" style="color: #9B9A9B;" icon="folder"></iron-icon> + <iron-icon v-if="item.suspicionClass < 1 && item.type == 'file'" style="color: #9B9A9B;" icon="editor:insert-drive-file"></iron-icon> + </template> + <template v-slot:item.command = "{ item }"> + <span v-if="item.command == 1 && item.type == 'file'">File deleted</span> + <span v-if="item.command == 1 && item.type == 'folder'">Folder deleted</span> + <span v-if="item.command == 2 && item.type == 'file'">File renamed</span> + <span v-if="item.command == 2 && item.type == 'folder'">Folder renamed</span> + <span v-if="item.command == 3 && item.type == 'file'">File written</span> + <span v-if="item.command == 3 && item.type == 'folder'">Folder written</span> + <span v-if="item.command == 4 && item.type == 'file'">File read</span> + <span v-if="item.command == 4 && item.type == 'folder'">Folder read</span> + <span v-if="item.command == 5 && item.type == 'file'">File created</span> + <span v-if="item.command == 5 && item.type == 'folder'">Folder created</span> + <span v-if="item.command > 5 && item.command < 1 && item.type == 'file'">No information</span> + <span v-if="item.command > 5 && item.command < 1 && item.type == 'folder'">No information</span> + </template> + </v-data-table> </div> </div> <span id="message" v-if="!detected"> @@ -31,7 +62,10 @@ 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 '@polymer/iron-icons/editor-icons.js'; +import '../webcomponents/ransomware-icons' +import 'time-elements/dist/time-elements'; +import moment from 'moment' import Notification from '../components/Notification' import Header from '../components/Header' import RecoverAction from '../components/RecoverAction' @@ -41,7 +75,6 @@ export default { name: 'Recover', components: { AppContent, - FileOperationsTable, Header, RecoverAction, Notification @@ -52,7 +85,18 @@ export default { detections: [], page: 0, visible: false, - notificationText: "" + notificationText: "", + headers: [ + { + text: 'Status', + align: 'start', + sortable: false, + value: 'suspicionClass', + }, + { text: 'Operation', value: 'command' }, + { text: 'Name', value: 'originalName' }, + { text: 'File Changed', value: 'timestamp' }, + ], }; }, mounted() { @@ -99,9 +143,6 @@ export default { }) .catch( error => { console.error(error); }); }, - tableStateChanged() { - this.page = 1; - }, fetchDetections() { this.$axios({ method: 'GET', @@ -109,6 +150,7 @@ export default { }) .then(json => { this.detections = json.data; + this.page = 1; }) .catch( error => { console.error(error); }); }, @@ -153,6 +195,12 @@ export default { .catch(error => { console.error(error); }); + }, + moment: function (date) { + return moment.unix(date).format('dddd, MMMM Do YYYY, HH:mm:ss') + }, + datetime: function(date) { + return moment.unix(rowData.item.timestamp).format("YYYY-MM-DDTHH:mm:ss.SSS") } }, computed: { @@ -169,7 +217,7 @@ export default { } </script> -<style lang="scss" scoped> +<style lang="scss"> #tables { height: calc(100% - 50px); } |