Merge "Refactor the frontend for batch generation."
This commit is contained in:
@@ -1,76 +1,55 @@
|
||||
<template>
|
||||
<form @submit.prevent="sendForm">
|
||||
<FileSelect
|
||||
v-if="input.isIncremental"
|
||||
v-model="input.incremental"
|
||||
label="Select the source file"
|
||||
:options="targetDetails"
|
||||
/>
|
||||
<FileSelect
|
||||
v-model="input.target"
|
||||
label="Select a target file"
|
||||
:options="targetDetails"
|
||||
/>
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="flag in basicFlags"
|
||||
:key="flag.key"
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<BaseCheckbox
|
||||
v-model="input[flag.key]"
|
||||
:label="flag.label"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<div v-if="input.isPartial">
|
||||
<v-divider />
|
||||
<h3>Select Partitions</h3>
|
||||
<PartialCheckbox
|
||||
v-model="input.partial"
|
||||
:labels="updatablePartitions"
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="flag in basicFlags"
|
||||
:key="flag.key"
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<BaseCheckbox
|
||||
v-model="otaConfig[flag.key]"
|
||||
:label="flag.label"
|
||||
/>
|
||||
<v-divider />
|
||||
</div>
|
||||
<v-btn
|
||||
block
|
||||
@click="moreOptions = !moreOptions"
|
||||
>
|
||||
More Options
|
||||
</v-btn>
|
||||
<v-row v-if="moreOptions">
|
||||
<v-col
|
||||
v-for="flag in extraFlags"
|
||||
:key="flag.key"
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
<BaseCheckbox
|
||||
v-model="input[flag.key]"
|
||||
:label="flag.label"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-5" />
|
||||
<BaseInput
|
||||
v-model="input.extra"
|
||||
:label="'Extra Configurations'"
|
||||
</v-col>
|
||||
</v-row>
|
||||
<div v-if="otaConfig.isPartial">
|
||||
<v-divider />
|
||||
<h3>Select Partitions</h3>
|
||||
<PartialCheckbox
|
||||
v-model="otaConfig.partial"
|
||||
:labels="updatablePartitions"
|
||||
/>
|
||||
<v-divider class="my-5" />
|
||||
<v-btn
|
||||
block
|
||||
type="submit"
|
||||
<v-divider />
|
||||
</div>
|
||||
<v-btn
|
||||
block
|
||||
@click="moreOptions = !moreOptions"
|
||||
>
|
||||
More Options
|
||||
</v-btn>
|
||||
<v-row v-if="moreOptions">
|
||||
<v-col
|
||||
v-for="flag in extraFlags"
|
||||
:key="flag.key"
|
||||
cols="12"
|
||||
md="4"
|
||||
>
|
||||
Submit
|
||||
</v-btn>
|
||||
</form>
|
||||
<BaseCheckbox
|
||||
v-model="otaConfig[flag.key]"
|
||||
:label="flag.label"
|
||||
/>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-divider class="my-5" />
|
||||
<BaseInput
|
||||
v-model="otaConfig.extra"
|
||||
:label="'Extra Configurations'"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BaseInput from '@/components/BaseInput.vue'
|
||||
import BaseCheckbox from '@/components/BaseCheckbox.vue'
|
||||
import FileSelect from '@/components/FileSelect.vue'
|
||||
import PartialCheckbox from '@/components/PartialCheckbox.vue'
|
||||
import { OTAConfiguration, OTABasicFlags, OTAExtraFlags } from '@/services/JobSubmission.js'
|
||||
|
||||
@@ -78,7 +57,6 @@ export default {
|
||||
components: {
|
||||
BaseInput,
|
||||
BaseCheckbox,
|
||||
FileSelect,
|
||||
PartialCheckbox,
|
||||
},
|
||||
props: {
|
||||
@@ -86,18 +64,14 @@ export default {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
incrementalSource: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
targetBuild: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
targetBuilds: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
data () {
|
||||
return {
|
||||
input: new OTAConfiguration(),
|
||||
otaConfig: new OTAConfiguration(),
|
||||
moreOptions: false,
|
||||
basicFlags: OTABasicFlags,
|
||||
extraFlags: OTAExtraFlags
|
||||
@@ -109,49 +83,24 @@ export default {
|
||||
* @return Array<String>
|
||||
*/
|
||||
updatablePartitions() {
|
||||
if (!this.input.target) return []
|
||||
// TODO(lishutong): currently only give the partition list of first
|
||||
// build, should use the intersections of the partitions of
|
||||
// all given builds.
|
||||
if (!this.targetBuilds | this.targetBuilds.length===0) return []
|
||||
if (this.targetBuilds[0] === '') return []
|
||||
let target = this.targetDetails.filter(
|
||||
(d) => d.path === this.input.target
|
||||
(d) => d.path === this.targetBuilds[0]
|
||||
)
|
||||
return target[0].partitions
|
||||
},
|
||||
checkIncremental() {
|
||||
return this.input.isIncremental
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
incrementalSource: {
|
||||
handler: function () {
|
||||
this.input.isIncremental = true
|
||||
this.input.incremental = this.incrementalSource
|
||||
otaConfig: {
|
||||
handler () {
|
||||
this.$emit('update:otaConfig', this.otaConfig)
|
||||
},
|
||||
},
|
||||
targetBuild: {
|
||||
handler: function () {
|
||||
this.input.target = this.targetBuild
|
||||
},
|
||||
},
|
||||
checkIncremental: {
|
||||
handler: function () {
|
||||
this.$emit('update:isIncremental', this.checkIncremental)
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Send the configuration to the backend.
|
||||
*/
|
||||
async sendForm() {
|
||||
try {
|
||||
let response_message = await this.input.sendForm()
|
||||
alert(response_message)
|
||||
} catch (err) {
|
||||
alert(
|
||||
'Job cannot be started properly for the following reasons: ' + err
|
||||
)
|
||||
}
|
||||
this.input = new OTAInput()
|
||||
},
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -38,7 +38,7 @@ export default {
|
||||
default: new Array(),
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
},
|
||||
|
||||
92
tools/otagui/src/components/SingleOTAOptions.vue
Normal file
92
tools/otagui/src/components/SingleOTAOptions.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<form @submit.prevent="sendForm">
|
||||
<FileSelect
|
||||
v-if="otaConfig.isIncremental"
|
||||
v-model="incrementalSource"
|
||||
label="Select the source file"
|
||||
:options="targetDetails"
|
||||
/>
|
||||
<FileSelect
|
||||
v-model="targetBuild"
|
||||
label="Select a target file"
|
||||
:options="targetDetails"
|
||||
/>
|
||||
<OTAOptions
|
||||
:targetDetails="targetDetails"
|
||||
:targetBuilds="[targetBuild]"
|
||||
@update:otaConfig="otaConfig=$event"
|
||||
/>
|
||||
<v-divider class="my-5" />
|
||||
<v-btn
|
||||
block
|
||||
type="submit"
|
||||
>
|
||||
Submit
|
||||
</v-btn>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OTAOptions from '@/components/OTAOptions.vue'
|
||||
import FileSelect from '@/components/FileSelect.vue'
|
||||
import { OTAConfiguration } from '@/services/JobSubmission.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
OTAOptions,
|
||||
FileSelect,
|
||||
},
|
||||
props: {
|
||||
targetDetails: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
incrementalSource: '',
|
||||
targetBuild: '',
|
||||
otaConfig: new OTAConfiguration(),
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
checkIncremental() {
|
||||
return this.otaConfig.isIncremental
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
checkIncremental: {
|
||||
handler: function () {
|
||||
this.$emit('update:isIncremental', this.checkIncremental)
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$emit('update:isIncremental', this.checkIncremental)
|
||||
this.$emit('update:handler', this.setIncrementalSource, this.setTargetBuild)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* Send the configuration to the backend.
|
||||
*/
|
||||
async sendForm() {
|
||||
try {
|
||||
let response_message = await this.otaConfig.sendForm(
|
||||
this.targetBuild, this.incrementalSource)
|
||||
alert(response_message)
|
||||
this.otaConfig.reset()
|
||||
} catch (err) {
|
||||
alert(
|
||||
'Job cannot be started properly for the following reasons: ' + err
|
||||
)
|
||||
}
|
||||
},
|
||||
setIncrementalSource (build) {
|
||||
this.incrementalSource = build
|
||||
},
|
||||
setTargetBuild (build) {
|
||||
this.targetBuild = build
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -21,32 +21,50 @@ export class OTAConfiguration {
|
||||
* disable checkboxes of which dependencies are not fulfilled.
|
||||
*/
|
||||
this.verbose = false,
|
||||
this.target = '',
|
||||
this.incremental = '',
|
||||
this.isIncremental = false,
|
||||
this.partial = [],
|
||||
this.isPartial = false,
|
||||
this.extra_keys = [],
|
||||
this.extra = '',
|
||||
this.id = uuid.v1()
|
||||
this.extra = ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the generation process, will throw an error if not succeed
|
||||
* Start an OTA package generation from target build to incremental source.
|
||||
* Throw an error if not succeed, otherwise will return the message from
|
||||
* the backend.
|
||||
* @param {String} targetBuild
|
||||
* @param {String} incrementalSource
|
||||
* @return String
|
||||
*/
|
||||
async sendForm() {
|
||||
async sendForm(targetBuild, incrementalSource='') {
|
||||
let jsonOptions = Object.assign({}, this)
|
||||
jsonOptions.target = targetBuild
|
||||
jsonOptions.incremental = incrementalSource
|
||||
jsonOptions.id = uuid.v1()
|
||||
for (let flag of OTAExtraFlags) {
|
||||
if (this[flag.key]) {
|
||||
this.extra_keys.push(flag.key)
|
||||
if (jsonOptions[flag.key]) {
|
||||
jsonOptions.extra_keys.push(flag.key)
|
||||
}
|
||||
}
|
||||
try {
|
||||
let response = await ApiServices.postInput(JSON.stringify(this), this.id)
|
||||
let response = await ApiServices.postInput(JSON.stringify(jsonOptions), jsonOptions.id)
|
||||
return response.data
|
||||
} catch (err) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset all the flags being set in this object.
|
||||
*/
|
||||
reset() {
|
||||
for (let flag of OTAExtraFlags) {
|
||||
if (this[flag.key]) {
|
||||
delete this[flag.key]
|
||||
}
|
||||
}
|
||||
this.constructor()
|
||||
}
|
||||
}
|
||||
|
||||
export const OTABasicFlags = [
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
<template>
|
||||
<v-row>
|
||||
<v-col
|
||||
id="dynamic-component-demo"
|
||||
cols="12"
|
||||
md="6"
|
||||
>
|
||||
<OTAOptions
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
:key="tab.label"
|
||||
:class="['tab-button', { active: currentTab === tab.component }]"
|
||||
@click="currentTab = tab.component"
|
||||
>
|
||||
{{ tab.label }}
|
||||
</button>
|
||||
<component
|
||||
:is="currentTab"
|
||||
class="tab-component"
|
||||
:targetDetails="targetDetails"
|
||||
:incrementalSource="incrementalSource"
|
||||
:targetBuild="targetBuild"
|
||||
@update:isIncremental="isIncremental = $event"
|
||||
@update:handler="setHandler"
|
||||
/>
|
||||
</v-col>
|
||||
<v-divider vertical />
|
||||
@@ -17,10 +27,12 @@
|
||||
md="6"
|
||||
class="library"
|
||||
>
|
||||
<!-- the key-binding refresh has to be used to reload the methods-->
|
||||
<BuildLibrary
|
||||
:refresh="refresh"
|
||||
:isIncremental="isIncremental"
|
||||
@update:incrementalSource="incrementalSource = $event"
|
||||
@update:targetBuild="targetBuild = $event"
|
||||
@update:incrementalSource="addIncrementalSource"
|
||||
@update:targetBuild="addTargetBuild"
|
||||
@update:targetDetails="targetDetails = $event"
|
||||
/>
|
||||
</v-col>
|
||||
@@ -28,28 +40,68 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OTAOptions from '@/components/OTAOptions.vue'
|
||||
import SingleOTAOptions from '@/components/SingleOTAOptions.vue'
|
||||
import BuildLibrary from '@/components/BuildLibrary.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
OTAOptions,
|
||||
BuildLibrary
|
||||
SingleOTAOptions,
|
||||
BuildLibrary,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
incrementalSource: '',
|
||||
targetBuild: '',
|
||||
targetDetails: [],
|
||||
isIncremental: false
|
||||
isIncremental: false,
|
||||
currentTab: 'SingleOTAOptions',
|
||||
refresh: false,
|
||||
tabs: [
|
||||
{label: 'Single OTA', component: 'SingleOTAOptions'},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setHandler(addIncrementalSource, addTargetBuild) {
|
||||
this.refresh = true,
|
||||
this.addIncrementalSource = addIncrementalSource
|
||||
this.addTargetBuild = addTargetBuild
|
||||
this.refresh = false
|
||||
},
|
||||
addIncrementalSource: () => {},
|
||||
addTargetBuild: () => {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.library {
|
||||
overflow: scroll;
|
||||
height:calc(100vh - 80px);
|
||||
}
|
||||
.library {
|
||||
overflow: scroll;
|
||||
height: calc(100vh - 80px);
|
||||
}
|
||||
|
||||
.tab-component {
|
||||
border: 3px solid #eee;
|
||||
border-radius: 2px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
padding: 6px 10px;
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
border: 1px solid #ccc;
|
||||
cursor: pointer;
|
||||
background: #f0f0f0;
|
||||
margin-bottom: -1px;
|
||||
margin-right: -1px;
|
||||
}
|
||||
.tab-button:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.tab-button.active {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
.demo-tab {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>>
|
||||
Reference in New Issue
Block a user