chore: working target selector

This commit is contained in:
0x1a8510f2 2023-05-14 17:24:37 +01:00
parent c6c8586af4
commit b183f0d26c
Signed by: 0x1a8510f2
GPG Key ID: 1C692E355D76775D
4 changed files with 51 additions and 136 deletions

View File

@ -1,4 +1,5 @@
export type Client = {
address: string,
lastHeartbeatTime: string,
lastHeartbeat:{
"StrainId": string,
@ -9,6 +10,6 @@ export type Client = {
"Hostname": string,
"HostUser": string,
"HostUserId": string,
"Errors": string[] | null
"Errors": number
}
}

View File

@ -3,14 +3,21 @@
<div class="col-12">
<div class="card">
<h5>Console Page</h5>
<p>Use this page to start from scratch and place your custom content.</p>
<p>{{ store.targets }}</p>
</div>
</div>
</div>
</template>
<script lang="ts">
export default {
import { defineComponent } from 'vue';
import { store } from '../../state/state'
}
export default defineComponent({
data() {
return {
store
}
}
})
</script>

View File

@ -3,6 +3,19 @@
<div class="col-12">
<div class="card">
<Toast/>
<Toolbar class="mb-4">
<template v-slot:start>
<div class="my-2">
<Button label="Send To All" icon="pi pi-send" class="p-button-success mr-2" @click="selectTargets('all')" />
<Button
label="Send To Selected"
icon="pi pi-send"
class="p-button-success mr-2"
@click="selectTargets(clientsSelected.map((client) => client.address))"
:disabled="!clientsSelected || !clientsSelected.length" />
</div>
</template>
</Toolbar>
<DataTable ref="dt" :value="clients" v-model:selection="clientsSelected" dataKey="address" :paginator="true" :rows="clientsCount" :filters="filters"
paginatorTemplate="FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink CurrentPageReport RowsPerPageDropdown" :rowsPerPageOptions="[10, 25, 50, 100]"
@ -18,6 +31,11 @@
</template>
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
<Column headerStyle="min-width:3rem;">
<template #body="slotProps">
<Button icon="pi pi-send" class="p-button-rounded p-button-success mr-2" @click="selectTargets([slotProps.data.address])" />
</template>
</Column>
<Column field="address" header="Address" headerStyle="width:14%; min-width:10rem;">
<template #body="slotProps">
<span class="p-column-title">Address</span>
@ -42,6 +60,12 @@
{{slotProps.data.lastHeartbeat.Modules}}
</template>
</Column>
<Column field="hostname" header="Hostname" headerStyle="width:14%; min-width:10rem;">
<template #body="slotProps">
<span class="p-column-title">Hostname</span>
{{slotProps.data.lastHeartbeat.Hostname}}
</template>
</Column>
<Column field="hostos" header="Host OS" headerStyle="width:14%; min-width:8rem;">
<template #body="slotProps">
<span class="p-column-title">Host OS</span>
@ -54,12 +78,6 @@
{{slotProps.data.lastHeartbeat.HostArch}}
</template>
</Column>
<Column field="hostname" header="Hostname" headerStyle="width:14%; min-width:10rem;">
<template #body="slotProps">
<span class="p-column-title">Hostname</span>
{{slotProps.data.lastHeartbeat.Hostname}}
</template>
</Column>
<Column field="hostuser" header="Host User" headerStyle="width:14%; min-width:10rem;">
<template #body="slotProps">
<span class="p-column-title">Host User</span>
@ -78,12 +96,6 @@
{{slotProps.data.lastHeartbeat.Errors}}
</template>
</Column>
<Column headerStyle="min-width:10rem;">
<template #body="slotProps">
<Button icon="pi pi-pencil" class="p-button-rounded p-button-success mr-2" @click="" />
<Button icon="pi pi-trash" class="p-button-rounded p-button-warning mt-2" @click="" />
</template>
</Column>
</DataTable>
</div>
</div>
@ -95,14 +107,16 @@
import { defineComponent } from 'vue'
import { FilterMatchMode } from 'primevue/api'
import API from '../../api/api'
import { store } from '../../state/state'
import { Client } from '../../api/types'
export default defineComponent({
data() {
return {
api: new API(),
store,
clients: [] as Client[],
clientsSelected: [],
clientsSelected: []as Client[],
clientsCount: 0,
clientsOffset: 0,
clientsLimit: 50,
@ -113,7 +127,7 @@ export default defineComponent({
matchMode: FilterMatchMode.CONTAINS,
}
},
timer: 0
timer: 0,
}
},
mounted() {
@ -136,128 +150,14 @@ export default defineComponent({
cancelAutoUpdate() {
clearInterval(this.timer)
},
selectTargets(targets: string[] | 'all') {
store.targets = targets
window.location.hash = '#/clients/console'
}
},
})
</script>
<!-- <script lang="ts">
import {FilterMatchMode} from 'primevue/api';
import ProductService from '../../api/api';
export default {
data() {
return {
products: null,
productDialog: false,
deleteProductDialog: false,
deleteProductsDialog: false,
product: {},
selectedProducts: null,
filters: {},
submitted: false,
statuses: [
{label: 'INSTOCK', value: 'instock'},
{label: 'LOWSTOCK', value: 'lowstock'},
{label: 'OUTOFSTOCK', value: 'outofstock'}
]
}
},
productService: null,
created() {
this.productService = new ProductService();
this.initFilters();
},
mounted() {
this.productService.getProducts().then(data => this.products = data);
},
methods: {
formatCurrency(value) {
if(value)
return value.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
return;
},
openNew() {
this.product = {};
this.submitted = false;
this.productDialog = true;
},
hideDialog() {
this.productDialog = false;
this.submitted = false;
},
saveProduct() {
this.submitted = true;
if (this.product.name.trim()) {
if (this.product.id) {
this.product.inventoryStatus = this.product.inventoryStatus.value ? this.product.inventoryStatus.value: this.product.inventoryStatus;
this.products[this.findIndexById(this.product.id)] = this.product;
this.$toast.add({severity:'success', summary: 'Successful', detail: 'Product Updated', life: 3000});
}
else {
this.product.id = this.createId();
this.product.code = this.createId();
this.product.image = 'product-placeholder.svg';
this.product.inventoryStatus = this.product.inventoryStatus ? this.product.inventoryStatus.value : 'INSTOCK';
this.products.push(this.product);
this.$toast.add({severity:'success', summary: 'Successful', detail: 'Product Created', life: 3000});
}
this.productDialog = false;
this.product = {};
}
},
editProduct(product) {
this.product = {...product};
this.productDialog = true;
},
confirmDeleteProduct(product) {
this.product = product;
this.deleteProductDialog = true;
},
deleteProduct() {
this.products = this.products.filter(val => val.id !== this.product.id);
this.deleteProductDialog = false;
this.product = {};
this.$toast.add({severity:'success', summary: 'Successful', detail: 'Product Deleted', life: 3000});
},
findIndexById(id) {
let index = -1;
for (let i = 0; i < this.products.length; i++) {
if (this.products[i].id === id) {
index = i;
break;
}
}
return index;
},
createId() {
let id = '';
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for ( var i = 0; i < 5; i++ ) {
id += chars.charAt(Math.floor(Math.random() * chars.length));
}
return id;
},
exportCSV() {
this.$refs.dt.exportCSV();
},
confirmDeleteSelected() {
this.deleteProductsDialog = true;
},
deleteSelectedProducts() {
this.products = this.products.filter(val => !this.selectedProducts.includes(val));
this.deleteProductsDialog = false;
this.selectedProducts = null;
this.$toast.add({severity:'success', summary: 'Successful', detail: 'Products Deleted', life: 3000});
},
initFilters() {
this.filters = {
'global': {value: null, matchMode: FilterMatchMode.CONTAINS},
}
}
}
}
</script> -->
<style scoped lang="scss">
@import '../../assets/styles/badges.scss';
</style>

View File

@ -0,0 +1,7 @@
import { reactive } from 'vue'
export const store: {
targets: string[] | 'all'
} = reactive({
targets: []
})