Webclient: Reworked most components, intergrated vuex getters

This commit is contained in:
MaMe82 2018-09-05 17:39:57 +02:00
parent 2b32f25188
commit 6d51820f76
9 changed files with 372 additions and 317 deletions

2
dist/www/index.html vendored
View File

@ -49,7 +49,7 @@
<q-tabs>
<q-route-tab default slot="title" to="usb" name="tab-usb" icon="usb" label="USB Settings"></q-route-tab>
<q-route-tab slot="title" to="hid" name="tab-hid-script" icon="code" label="HIDScript"></q-route-tab>
<q-route-tab slot="title" to="hidjobs" name="tab-hid-jobs" icon="schedule" label="HID Jobs"></q-route-tab>
<q-route-tab slot="title" to="hidjobs" name="tab-hid-jobs" icon="schedule" label="HID Events"></q-route-tab>
<q-route-tab slot="title" to="logger" name="tab-logger" icon="message" label="Event Log"></q-route-tab>
<q-route-tab slot="title" to="network" name="tab-network" icon="settings_ethernet" label="Network settings"></q-route-tab>
<q-route-tab slot="title" to="wifi" name="tab-wifi" icon="wifi" label="WiFi settings"></q-route-tab>

View File

@ -0,0 +1,72 @@
// +build js
package main
import (
"github.com/HuckRidgeSW/hvue"
"github.com/mame82/P4wnP1_go/common_web"
"github.com/gopherjs/gopherjs/js"
)
type CompHIDEventsData struct {
*js.Object
Pagination *jsDataTablePagination `js:"pagination"`
}
func newCompHIDEventsData(vm *hvue.VM) interface{} {
data := &CompHIDEventsData{ Object: O() }
data.Pagination = newPagination(0, 1)
return data
}
func InitCompHIDEvents() {
hvue.NewComponent(
"hid-job-event-overview",
hvue.Template(compHIDJobEventOverviewTemplate),
hvue.DataFunc(newCompHIDEventsData),
hvue.Computed("events",
func(vm *hvue.VM) interface{} {
return vm.Get("$store").Get("state").Get("eventReceiver").Get("eventHidArray")
}),
hvue.Method("evIdToString", func(vm *hvue.VM, evID int64) (res string) {
println("EvID", evID)
return common_web.EventType_name[evID]
}),
)
}
const (
//{ "evtype": 0, "vmId": 2, "jobId": 3, "hasError": false, "result": "null", "error": "", "message": "Script started", "time": "2018-07-30 04:56:42.297533 +0000 UTC m=+7625.097825001" }
compHIDJobEventOverviewTemplate = `
<q-card>
<!-- <div class="scroll" style="overflow: auto;max-height: 20vh;"> -->
<div>
<q-table
:data="events"
:columns="[{name:'type', field: 'evtype', label: 'Event Type', align: 'left'}, {name:'vmid', field: 'vmId', label: 'VM ID', align: 'left'}, {name:'jobid', field: 'jobId', label: 'Job ID', align: 'left'}, {name:'haserror', field: 'hasError', label: 'Has error', align: 'left'}, {name:'res', field: 'result', label: 'Result', align: 'left'}, {name:'errormsg', field: 'error', label: 'Error', align: 'left'}, {name:'msg', field: 'message', label: 'Message', align: 'left'}, {name:'timestamp', field: 'time', label: 'Time', align: 'left'}]"
row-key="name"
:pagination="pagination"
hide-bottom
>
<q-td slot="body-cell-type" slot-scope="props" :props="props">
{{ evIdToString(props.value) }}
</q-td>
<q-td slot="body-cell-msg" slot-scope="props" :props="props">
{{ props.value.slice(0,30) }}
<q-btn v-if="props.value.length > 30" dense icon="more_horiz">
<q-popover>
<div class="q-ma-md" style="max-width: 400px; max-height: 400px;">
<pre>{{ props.value }}</pre>
</div>
</q-popover>
</q-btn>
</q-td>
</q-table>
</div>
</q-card>
`
)

View File

@ -5,7 +5,6 @@ package main
import (
"github.com/gopherjs/gopherjs/js"
"github.com/HuckRidgeSW/hvue"
"github.com/mame82/P4wnP1_go/common_web"
)
type CompHIDJobsData struct {
@ -28,22 +27,8 @@ func InitCompHIDJobs() {
hvue.DataFunc(newCompHIDJobsData),
hvue.Computed("jobs",
func(vm *hvue.VM) interface{} {
jobList := vm.Get("$store").Get("state").Get("hidJobList").Get("jobs")
return js.Global.Get("Object").Call("values",jobList)
}),
)
hvue.NewComponent(
"hid-job-event-overview",
hvue.Template(compHIDJobEventOverviewTemplate),
hvue.DataFunc(newCompHIDJobsData),
hvue.Computed("events",
func(vm *hvue.VM) interface{} {
return vm.Get("$store").Get("state").Get("eventReceiver").Get("eventHidArray")
}),
hvue.Method("evIdToString", func (vm *hvue.VM, evID int64) (res string) {
println("EvID",evID)
return common_web.EventType_name[evID]
//return vm.Get("$store").Get("state").Get("hidJobList").Get("jobs")
return vm.Get("$store").Get("getters").Get("hidjobs")
}),
)
@ -142,44 +127,21 @@ ScriptSource string `js:"textSource"`
//{ "evtype": 0, "vmId": 2, "jobId": 3, "hasError": false, "result": "null", "error": "", "message": "Script started", "time": "2018-07-30 04:56:42.297533 +0000 UTC m=+7625.097825001" }
compHIDJobOverviewTemplate = `
<q-card class="q-ma-sm">
<q-card class="full-height">
<q-card-title>
HIDScript jobs
</q-card-title>
<q-list>
<q-list-header>HID Script jobs</q-list-header>
<hid-job-overview-item v-for="job in jobs" :job="job" :key="job.id"></hid-job-overview-item>
<q-list-header>Running</q-list-header>
<hid-job-overview-item v-for="job in $store.getters.hidjobsRunning" :job="job" :key="job.id"></hid-job-overview-item>
<q-list-header>Succeeded</q-list-header>
<hid-job-overview-item v-for="job in $store.getters.hidjobsSucceeded" :job="job" :key="job.id"></hid-job-overview-item>
<q-list-header>Failed</q-list-header>
<hid-job-overview-item v-for="job in $store.getters.hidjobsFailed" :job="job" :key="job.id"></hid-job-overview-item>
</q-list>
</q-card>
`
//{ "evtype": 0, "vmId": 2, "jobId": 3, "hasError": false, "result": "null", "error": "", "message": "Script started", "time": "2018-07-30 04:56:42.297533 +0000 UTC m=+7625.097825001" }
compHIDJobEventOverviewTemplate = `
<q-page>
<div>
<table border="1">
<tr>
<th>Event Type</th>
<th>VM ID</th>
<th>Job ID</th>
<th>Has error</th>
<th>Result</th>
<th>Error</th>
<th>Message</th>
<th>Time</th>
</tr>
<tr v-for="e in events">
<td>{{ evIdToString(e.evtype) }}</td>
<td>{{ e.vmId }}</td>
<td>{{ e.jobId }}</td>
<td>{{ e.hasError }}</td>
<td>{{ e.result }}</td>
<td>{{ e.error }}</td>
<td>{{ e.message }}</td>
<td>{{ e.time }}</td>
</tr>
</table>
</div>
</q-page>
`
)

View File

@ -100,24 +100,22 @@ func InitComponentsHIDScript() {
const (
compHIDScriptTemplate = `
<q-page>
<div class="row content-stretch">
<div class="col-10 self-stretch">
<q-page padding>
<div class="row gutter-sm">
<div class="col-12 col-md-7 col-lg-8 col-xl-9">
<hid-script-code-editor></hid-script-code-editor>
</div>
<div class="col-2">
<div class="col-12 col-md-5 col-lg-4 col-xl-3">
<hid-job-overview></hid-job-overview>
</div>
</div>
<div class="row content-stretch">
<div class="col-12" style="overflow: auto; max-height: 40vh;">
<hid-job-event-overview></hid-job-event-overview>
</div>
</div>
</q-page>
`
compHIDScriptCodeEditorTemplate = `
<q-card class="q-ma-sm">
<q-card class="full-height">
<q-card-title>
HIDScript editor
</q-card-title>

View File

@ -63,10 +63,12 @@ func newCompUSBSettingsData(vm *hvue.VM) interface{} {
const (
compUSBSettingsTemplate = `
<q-page>
<q-card inline class="q-ma-sm">
<q-page padding>
<div class="row gutter-sm">
<div class="col-12 col-sm-6 col-md-5 col-xl-4">
<q-card class="full-height">
<q-card-title>
USB Gadget Settings
Generic USB Gadget Settings
</q-card-title>
<q-card-actions>
<q-btn :loading="deploying" color="primary" @click="ApplyGadgetSettings" label="deploy"></q-btn>
@ -79,7 +81,6 @@ const (
<q-list link>
<q-item-separator />
<q-list-header>Generic</q-list-header>
<q-item tag="label">
<q-item-side>
<q-toggle v-model="currentGadgetSettings.Enabled"></q-toggle>
@ -134,10 +135,18 @@ const (
</q-item-tile>
</q-item-main>
</q-item>
</q-list>
</q-card>
</div>
<div class="col-12 col-sm-6 col-md-5 col-xl-4">
<q-card class="full-height">
<q-card-title>
USB Gadget Functions
</q-card-title>
<q-list link>
<q-item-separator />
<q-list-header>Functions</q-list-header>
<q-item tag="label">
<q-item-side>
<q-toggle v-model="currentGadgetSettings.Use_CDC_ECM"></q-toggle>
@ -249,9 +258,10 @@ const (
</q-item>
</q-list>
</q-card>
</div>
</div>
</q-page>
`
)

View File

@ -88,8 +88,10 @@ func InitComponentsWiFi() {
}
const templateWiFi = `
<q-page>
<q-card inline class="q-ma-sm">
<q-page padding>
<div class="row gutter-sm">
<div class="col-lg-4">
<q-card class="full-height">
<q-card-title>
WiFi settings
</q-card-title>
@ -139,9 +141,18 @@ const templateWiFi = `
</q-item-main>
</q-item>
<template v-if="settings.mode != 0">
</q-list>
</q-card>
</div>
<div class="col-lg-4" v-if="settings.mode != 0">
<q-card class="full-height">
<q-card-title>
WiFi client settings
</q-card-title>
<q-list link>
<q-item-separator />
<q-list-header>WiFi client settings (station mode)</q-list-header>
<q-item tag="label">
<q-item-main>
<q-item-tile label>SSID</q-item-tile>
@ -160,20 +171,30 @@ const templateWiFi = `
</q-item-tile>
</q-item-main>
</q-item>
</template>
<template v-if="settings.mode == 2">
<q-item-separator />
<q-item>
<q-item-main>
<q-alert type="warning">
If the SSID provided for station mode couldn't be connected, an attempt is started to failo-over to Access Point mode with settings below
If the SSID provided for client mode couldn't be connected, an attempt is started to fail over to Access Point mode with the respective settings.
</q-alert>
</q-item-main>
</q-item>
</template>
</q-list>
</q-card>
</div>
<template v-if="settings.mode != 1">
<div class="col-lg-4" v-if="settings.mode != 1">
<q-card class="full-height">
<q-card-title>
WiFi Access Point settings
</q-card-title>
<q-list link>
<template>
<q-item-separator />
<q-list-header>Access Point settings</q-list-header>
<q-item tag="label">
@ -225,6 +246,8 @@ const templateWiFi = `
</template>
</q-list>
</q-card>
</div>
</div>
</q-page>
`

View File

@ -219,8 +219,10 @@ func InitComponentsNetwork() {
}
const templateNetwork = `
<q-page>
<q-card class="q-ma-sm" :inline="$q.platform.is.desktop">
<q-page padding>
<div class="row gutter-sm">
<div class="col-xl-3">
<q-card class="full-height">
<q-card-title>
Network interface settings
</q-card-title>
@ -243,15 +245,19 @@ const templateNetwork = `
</q-list>
<network-interface-settings v-if="current" :interface="current"></network-interface-settings>
</q-card>
</div>
<div class="col-xl-9">
<dhcp-config :interface="current" v-if="currentWithDhcp"></dhcp-config>
</div>
</div>
</q-page>
`
const templateDHCPConfig = `
<q-card class="q-ma-sm" :inline="$q.platform.is.desktop">
<q-card>
<q-card-title>
DHCP Server settings for {{ interface.name }}
</q-card-title>

View File

@ -67,6 +67,7 @@ func main() {
InitCompHIDJobs()
InitCompHIDEvents()
InitCompModal()
InitCompEthernetAddresses2()
InitCompToggleSwitch()

View File

@ -63,9 +63,6 @@ type GlobalState struct {
FailedConnectionAttempts int `js:"failedConnectionAttempts"`
InterfaceSettings *jsEthernetSettingsList `js:"InterfaceSettings"`
WiFiSettings *jsWiFiSettings `js:"wifiSettings"`
Counter int `js:"count"`
Text string `js:"text"`
}
func createGlobalStateStruct() GlobalState {
@ -93,8 +90,6 @@ func createGlobalStateStruct() GlobalState {
}
state.WiFiSettings = wifiSettings
state.Counter = 1337
state.Text = "Hi there says MaMe82"
return state
}
@ -218,33 +213,10 @@ func initMVuex() *mvuex.Store {
globalState = &state //make accessible through global var
store := mvuex.NewStore(
mvuex.State(state),
mvuex.Action("actiontest", func(store *mvuex.Store, context *mvuex.ActionContext, state *GlobalState) {
go func() {
for i := 0; i < 10; i++ {
println(state.Counter)
time.Sleep(1 * time.Second)
context.Commit("increment", 5)
}
}()
}),
mvuex.Mutation("setModalEnabled", func(store *mvuex.Store, state *GlobalState, enabled bool) {
state.IsModalEnabled = enabled
return
}),
mvuex.Mutation("increment", func(store *mvuex.Store, state *GlobalState, add int) {
state.Counter += add
return
}),
mvuex.Mutation("decrement", func(store *mvuex.Store, state *GlobalState) {
state.Counter--
return
}),
mvuex.Mutation("setText", func(store *mvuex.Store, state *GlobalState, newText string) {
state.Text = newText
return
}),
mvuex.Mutation(VUEX_MUTATION_SET_CURRENT_HID_SCRIPT_SOURCE_TO, func(store *mvuex.Store, state *GlobalState, newText string) {
state.CurrentHIDScriptSource = newText
return
@ -274,27 +246,38 @@ func initMVuex() *mvuex.Store {
mvuex.Action(VUEX_ACTION_UPDATE_WIFI_SETTINGS_FROM_DEPLOYED, actionUpdateWifiSettingsFromDeployed),
mvuex.Action(VUEX_ACTION_DEPLOY_WIFI_SETTINGS, actionDeployWifiSettings),
mvuex.Getter("testgetterProperty", func(state *GlobalState) interface{} {
//Note: GlobalState is a custom struct, used for the vuex store state
println("getter returning a property, for given state", state)
return state
mvuex.Getter("hidjobs", func(state *GlobalState) interface{} {
return state.HidJobList.Jobs
}),
mvuex.Getter("testgetterPropertyMulti", func(state *GlobalState) (string, int) {
println("getter returning a property with multiple results converted to an array, for given state", state)
return "two", 2
mvuex.Getter("hidjobsRunning", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return !(job.HasSucceeded || job.HasFailed)
})
return filtered
}),
mvuex.Getter("testgetterMethodWithArg", func(state interface{}) interface{} {
println("getter returning a function which takes an argument, input state isn't casted to known struct", state)
return func(i int) int { return i * 2 } // function returning given int multiplied by two
mvuex.Getter("hidjobsFailed", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return job.HasFailed
})
return filtered
}),
mvuex.Getter("testgetterConsumeGetters", func(state *GlobalState, getters *js.Object) interface{} {
println("getter consuming state and getters as input", state)
println("getter3 getters", getters)
return getters
mvuex.Getter("hidjobsSucceeded", func(state *GlobalState) interface{} {
vJobs := state.HidJobList.Jobs //vue object, no real array --> values have to be extracted to filter
jobs := js.Global.Get("Object").Call("values", vJobs) //converted to native JS array (has filter method available
filtered := jobs.Call("filter", func(job *jsHidJobState) bool {
return job.HasSucceeded
})
return filtered
}),
)
// fetch deployed gadget settings