Merge "Refactor the frontend for batch generation." am: 89e47defef

Original change: https://android-review.googlesource.com/c/platform/development/+/1775725

Change-Id: I0e9ccb6d87ced9b6bdf2d0f0035bbeb18a45ea29
This commit is contained in:
Treehugger Robot
2021-07-23 17:30:24 +00:00
committed by Automerger Merge Worker
5 changed files with 248 additions and 137 deletions

View File

@@ -1,16 +1,4 @@
<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"
@@ -19,16 +7,16 @@
md="4"
>
<BaseCheckbox
v-model="input[flag.key]"
v-model="otaConfig[flag.key]"
:label="flag.label"
/>
</v-col>
</v-row>
<div v-if="input.isPartial">
<div v-if="otaConfig.isPartial">
<v-divider />
<h3>Select Partitions</h3>
<PartialCheckbox
v-model="input.partial"
v-model="otaConfig.partial"
:labels="updatablePartitions"
/>
<v-divider />
@@ -47,30 +35,21 @@
md="4"
>
<BaseCheckbox
v-model="input[flag.key]"
v-model="otaConfig[flag.key]"
:label="flag.label"
/>
</v-col>
</v-row>
<v-divider class="my-5" />
<BaseInput
v-model="input.extra"
v-model="otaConfig.extra"
:label="'Extra Configurations'"
/>
<v-divider class="my-5" />
<v-btn
block
type="submit"
>
Submit
</v-btn>
</form>
</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 () {
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
)
deep: true
}
}
this.input = new OTAInput()
},
},
}
</script>

View File

@@ -38,7 +38,7 @@ export default {
default: new Array(),
},
modelValue: {
type: String,
type: Array,
required: true
},
},

View 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>

View File

@@ -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 = [

View File

@@ -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,22 +40,35 @@
</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>
@@ -52,4 +77,31 @@ export default {
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>>