Update UI to be more minimialistic

Test: N/A
Change-Id: I922edcb62d9c8fd61e4dc5fb3499ba87351422fc
This commit is contained in:
Pablo Gamito
2020-07-01 16:41:56 +01:00
parent 3cebeac9ef
commit 050e20b8a9
13 changed files with 380 additions and 155 deletions

View File

@@ -15,39 +15,51 @@
<template>
<div id="app">
<md-app>
<md-app-toolbar md-tag="md-toolbar">
<md-app-toolbar md-tag="md-toolbar" class="top-toolbar">
<h1 class="md-title" style="flex: 1">{{title}}</h1>
<md-button
class="md-accent md-raised md-theme-default"
class="md-primary md-theme-default download-all-btn"
@click="downloadAsZip(files)"
v-if="dataLoaded"
>Download All</md-button>
<md-button
class="md-accent md-raised md-theme-default"
class="md-accent md-raised md-theme-default clear-btn"
style="box-shadow: none;"
@click="clear()"
v-if="dataLoaded"
>Clear</md-button>
</md-app-toolbar>
<md-app-content class="main-content">
<div class="md-layout m-2" v-if="!dataLoaded">
<dataadb ref="adb" :store="store" @dataReady="onDataReady" @statusChange="setStatus" />
<datainput ref="input" :store="store" @dataReady="onDataReady" @statusChange="setStatus" />
</div>
<dataview
v-for="file in files"
:key="file.filename"
:ref="file.filename"
:store="store"
:file="file"
@click="onDataViewFocus(file)"
/>
<section class="data-inputs" v-if="!dataLoaded">
<div class="input">
<dataadb class="adbinput" ref="adb" :store="store" @dataReady="onDataReady" @statusChange="setStatus" />
</div>
<div class="input">
<datainput class="fileinput" ref="input" :store="store" @dataReady="onDataReady" @statusChange="setStatus" />
</div>
</section>
<overlay
:store="store"
:ref="overlayRef"
v-if="dataLoaded"
/>
<section class="data-view">
<div
class="data-view-container"
v-for="file in dataViewFiles"
:key="file.filename"
>
<dataview
:ref="file.filename"
:store="store"
:file="file"
@click="onDataViewFocus(file)"
/>
</div>
<overlay
:store="store"
:ref="overlayRef"
v-if="dataLoaded"
/>
</section>
</md-app-content>
</md-app>
</div>
@@ -143,6 +155,9 @@ export default {
}
return this.activeDataView;
},
dataViewFiles() {
return this.files.filter(f => this.hasDataView(f));
}
},
watch: {
title() {
@@ -158,16 +173,36 @@ export default {
};
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@600&display=swap');
#app .md-app-container {
transform: none!important; /* Get rid of tranforms which prevent fixed position from being used */
min-height: 100vh;
}
.main-content {
padding-bottom: 75px;
#app .top-toolbar {
box-shadow: none;
background-color: #fff;
background-color: var(--md-theme-default-background, #fff);
border-bottom: thin solid rgba(0,0,0,.12);
padding: 0 40px;
}
.main-content .md-layout>* {
margin: 1em;
#app .top-toolbar .md-title {
font-family: 'Open Sans', sans-serif;
white-space: nowrap;
color: #5f6368;
margin: 0;
padding: 0;
font-size: 22px;
letter-spacing: 0;
font-weight: 600;
}
.data-view {
display: flex;
flex-direction: column;
padding-bottom: 75px; /* TODO: Disable if no bottom bar */
}
.card-toolbar {
@@ -200,4 +235,30 @@ ul {
a {
color: #42b983;
}
.data-inputs {
display: flex;
flex-wrap: wrap;
height: 100%;
width: 100%;
align-self: center;
/* align-items: center; */
align-content: center;
justify-content: center;
}
.data-inputs .input {
padding: 15px;
flex: 1 1 0;
max-width: 840px;
/* align-self: center; */
}
.data-inputs .input > div {
height: 100%;
}
.data-view-container {
padding: 25px 20px 0 20px;
}
</style>

View File

@@ -13,7 +13,7 @@
limitations under the License.
-->
<template>
<md-card style="min-width: 50em">
<flat-card style="min-width: 50em">
<md-card-header>
<div class="md-title">ADB Connect</div>
</md-card-header>
@@ -72,24 +72,30 @@
<md-progress-spinner :md-size="30" md-indeterminate></md-progress-spinner>
</md-card-content>
<md-card-content v-if="status === STATES.START_TRACE">
<md-list>
<md-list-item>
<md-icon>smartphone</md-icon>
<span class="md-list-item-text">{{ devices[selectedDevice].model }} ({{ selectedDevice }})</span>
</md-list-item>
</md-list>
<div>
<p>Trace targets:</p>
<md-checkbox v-for="file in TRACE_FILES" :key="file" v-model="adbStore[file]">{{FILE_TYPES[file].name}}</md-checkbox>
<div class="device-choice">
<md-list>
<md-list-item>
<md-icon>smartphone</md-icon>
<span class="md-list-item-text">{{ devices[selectedDevice].model }} ({{ selectedDevice }})</span>
</md-list-item>
</md-list>
<md-button class="md-primary" @click="resetLastDevice">Change device</md-button>
</div>
<div>
<p>Dump targets:</p>
<md-checkbox v-for="file in DUMP_FILES" :key="file" v-model="adbStore[file]">{{FILE_TYPES[file].name}}</md-checkbox>
<div class="trace-section">
<h3>Trace targets:</h3>
<div class="selection">
<md-checkbox class="md-primary" v-for="file in TRACE_FILES" :key="file" v-model="adbStore[file]">{{FILE_TYPES[file].name}}</md-checkbox>
</div>
<md-button class="md-primary trace-btn" @click="startTrace">Start trace</md-button>
</div>
<div class="md-layout">
<md-button class="md-accent md-raised" @click="startTrace">Start trace</md-button>
<md-button class="md-accent md-raised" @click="dumpState">Dump state</md-button>
<md-button class="md-raised" @click="resetLastDevice">Device list</md-button>
<div class="dump-section">
<h3>Dump targets:</h3>
<div class="selection">
<md-checkbox class="md-primary" v-for="file in DUMP_FILES" :key="file" v-model="adbStore[file]">{{FILE_TYPES[file].name}}</md-checkbox>
</div>
<div class="md-layout">
<md-button class="md-primary dump-btn" @click="dumpState">Dump state</md-button>
</div>
</div>
</md-card-content>
<md-card-content v-if="status === STATES.ERROR">
@@ -98,24 +104,25 @@
<pre>
{{ errorText }}
</pre>
<md-button class="md-raised md-accent" @click="restart">Retry</md-button>
<md-button class="md-primary" @click="restart">Retry</md-button>
</md-card-content>
<md-card-content v-if="status === STATES.END_TRACE">
<span class="md-subheading">Tracing...</span>
<md-progress-bar md-mode="indeterminate"></md-progress-bar>
<div class="md-layout">
<md-button class="md-accent md-raised" @click="endTrace">End trace</md-button>
<md-button class="md-primary" @click="endTrace">End trace</md-button>
</div>
</md-card-content>
<md-card-content v-if="status === STATES.LOAD_DATA">
<span class="md-subheading">Loading data...</span>
<md-progress-bar md-mode="determinate" :md-value="loadProgress"></md-progress-bar>
</md-card-content>
</md-card>
</flat-card>
</template>
<script>
import { FILE_TYPES, DATA_TYPES } from './decode.js'
import LocalStore from './localstore.js'
import FlatCard from './components/FlatCard.vue';
const STATES = {
ERROR: 0,
@@ -178,6 +185,9 @@ export default {
}
},
props: ["store"],
components: {
'flat-card': FlatCard,
},
methods: {
getDevices() {
if (this.status !== STATES.DEVICES && this.status !== STATES.CONNECTING) {
@@ -345,3 +355,17 @@ export default {
}
</script>
<style scoped>
.device-choice {
display: inline-flex;
}
h3 {
margin-bottom: 0;
}
.trace-btn, .dump-btn {
margin-top: 0;
}
pre {
white-space: pre-wrap;
}
</style>

View File

@@ -13,49 +13,51 @@
limitations under the License.
-->
<template>
<md-card style="min-width: 50em">
<md-card-header>
<div class="md-title">Open files</div>
</md-card-header>
<md-card-content>
<md-list>
<md-list-item v-for="file in dataFiles" v-bind:key="file.filename">
<md-icon>{{file.type.icon}}</md-icon>
<span class="md-list-item-text">{{file.filename}} ({{file.type.name}})</span>
<md-button class="md-icon-button md-accent" @click="onRemoveFile(file.type.name)">
<md-icon>close</md-icon>
</md-button>
</md-list-item>
</md-list>
<md-progress-spinner :md-diameter="30" :md-stroke="3" md-mode="indeterminate" v-show="loadingFiles"/>
<div>
<md-checkbox v-model="store.displayDefaults">Show default properties
<md-tooltip md-direction="bottom">
If checked, shows the value of all properties.
Otherwise, hides all properties whose value is the default for its data type.
</md-tooltip>
</md-checkbox>
<flat-card style="min-width: 50em">
<md-card-header>
<div class="md-title">Open files</div>
</md-card-header>
<md-card-content>
<md-list>
<md-list-item v-for="file in dataFiles" v-bind:key="file.filename">
<md-icon>{{file.type.icon}}</md-icon>
<span class="md-list-item-text">{{file.filename}} ({{file.type.name}})</span>
<md-button class="md-icon-button md-accent" @click="onRemoveFile(file.type.name)">
<md-icon>close</md-icon>
</md-button>
</md-list-item>
</md-list>
<md-progress-spinner :md-diameter="30" :md-stroke="3" md-mode="indeterminate" v-show="loadingFiles"/>
<div>
<md-checkbox v-model="store.displayDefaults" class="md-primary">
Show default properties
<md-tooltip md-direction="bottom">
If checked, shows the value of all properties.
Otherwise, hides all properties whose value is the default for its data type.
</md-tooltip>
</md-checkbox>
</div>
<div class="md-layout">
<div class="md-layout-item md-small-size-100">
<md-field>
<md-select v-model="fileType" id="file-type" placeholder="File type">
<md-option value="auto">Detect type</md-option>
<md-option value="bugreport">Bug Report (.zip)</md-option>
<md-option :value="k" v-for="(v,k) in FILE_TYPES" v-bind:key="v.name">{{v.name}}</md-option>
</md-select>
</md-field>
</div>
<div class="md-layout">
<div class="md-layout-item md-small-size-100">
<md-field>
<md-select v-model="fileType" id="file-type" placeholder="File type">
<md-option value="auto">Detect type</md-option>
<md-option value="bugreport">Bug Report (.zip)</md-option>
<md-option :value="k" v-for="(v,k) in FILE_TYPES" v-bind:key="v.name">{{v.name}}</md-option>
</md-select>
</md-field>
</div>
</div>
<div class="md-layout">
<input type="file" @change="onLoadFile" ref="fileUpload" v-show="false" :multiple="fileType === 'auto'" />
<md-button class="md-accent md-raised md-theme-default" @click="$refs.fileUpload.click()">Add File</md-button>
<md-button v-if="dataReady" @click="onSubmit" class="md-button md-primary md-raised md-theme-default">Submit</md-button>
</div>
</md-card-content>
</md-card>
</div>
<div class="md-layout">
<input type="file" @change="onLoadFile" ref="fileUpload" v-show="false" :multiple="fileType === 'auto'" />
<md-button class="md-primary md-theme-default" @click="$refs.fileUpload.click()">Add File</md-button>
<md-button v-if="dataReady" @click="onSubmit" class="md-button md-primary md-raised md-theme-default">Submit</md-button>
</div>
</md-card-content>
</flat-card>
</template>
<script>
import FlatCard from './components/FlatCard.vue';
import JSZip from 'jszip';
import { detectAndDecode, FILE_TYPES, DATA_TYPES } from './decode.js';
import { WebContentScriptMessageType } from './utils/consts';
@@ -279,7 +281,10 @@ export default {
},
computed: {
dataReady: function() { return Object.keys(this.dataFiles).length > 0 }
}
},
components: {
'flat-card': FlatCard,
},
}
</script>

View File

@@ -14,7 +14,7 @@
-->
<template>
<div @click="onClick($event)">
<md-card v-if="(isLog(file) || isTrace(file) || isTransactions(file))">
<flat-card v-if="hasDataView(file)">
<md-card-header>
<md-card-header-text>
<div class="md-title">
@@ -32,7 +32,7 @@
<div v-if="!(isTrace(file) || isVideo(file) || isLog(file) || isTransactions(file))">
<h1 class="bad">Unrecognized DataType</h1>
</div>
</md-card>
</flat-card>
</div>
</template>
<script>
@@ -40,6 +40,7 @@ import TraceView from "./TraceView.vue";
import TransactionsView from "./TransactionsView.vue";
import LogView from "./LogView.vue";
import FileType from "./mixins/FileType.js";
import FlatCard from "./components/FlatCard.vue";
export default {
name: "dataview",
@@ -61,9 +62,10 @@ export default {
props: ["store", "file"],
mixins: [FileType],
components: {
traceview: TraceView,
transactionsview: TransactionsView,
logview: LogView
'traceview': TraceView,
'transactionsview': TransactionsView,
'logview': LogView,
'flat-card': FlatCard,
}
};
</script>

View File

@@ -45,7 +45,7 @@ export default {
}
.time-column .time-link {
width: 8.5em;
width: 9em;
}
.tag-column {

View File

@@ -60,7 +60,7 @@
</md-field>
</div>
<virtual-list style="height: 360px; overflow-y: auto;"
<virtual-list style="height: 600px; overflow-y: auto;"
:data-key="'uid'"
:data-sources="processedData"
:data-component="logEntryComponent"
@@ -196,6 +196,11 @@ export default {
</script>
<style>
.container {
display: flex;
flex-wrap: wrap;
}
.filters, .navigation {
width: 100%;
display: flex;

View File

@@ -14,66 +14,81 @@
-->
<template>
<md-card-content class="container">
<md-card class="rects" v-if="hasScreenView">
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title">Screen</h2>
</md-content>
<md-content class="md-elevation-8">
<rects :bounds="bounds" :rects="rects" :highlight="highlight" @rect-click="onRectClick" />
</md-content>
</md-card>
<md-card class="hierarchy">
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1;">Hierarchy</h2>
<md-checkbox
v-model="showHierachyDiff"
v-if="diffVisualizationAvailable"
>
Show Diff
</md-checkbox>
<md-checkbox v-model="store.onlyVisible">Only visible</md-checkbox>
<md-checkbox v-model="store.flattened">Flat</md-checkbox>
<input id="filter" type="search" placeholder="Filter..." v-model="hierarchyPropertyFilterString" />
</md-content>
<tree-view
class="data-card"
:item="tree"
@item-selected="itemSelected"
:selected="hierarchySelected"
:filter="hierarchyFilter"
:flattened="store.flattened"
:items-clickable="true"
:useGlobalCollapsedState="true"
ref="hierarchy"
/>
</md-card>
<md-card class="properties">
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1">Properties</h2>
<div class="filter">
<div class="rects" v-if="hasScreenView">
<rects :bounds="bounds" :rects="rects" :highlight="highlight" @rect-click="onRectClick" />
</div>
<div class="hierarchy">
<flat-card>
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1;">Hierarchy</h2>
<md-checkbox
v-model="showHierachyDiff"
v-if="diffVisualizationAvailable"
>
Show Diff
</md-checkbox>
<md-checkbox v-model="store.onlyVisible">Only visible</md-checkbox>
<md-checkbox v-model="store.flattened">Flat</md-checkbox>
<md-field md-inline class="filter">
<label>Filter...</label>
<md-input v-model="hierarchyPropertyFilterString"></md-input>
</md-field>
</md-content>
<tree-view
class="data-card"
:item="tree"
@item-selected="itemSelected"
:selected="hierarchySelected"
:filter="hierarchyFilter"
:flattened="store.flattened"
:items-clickable="true"
:useGlobalCollapsedState="true"
ref="hierarchy"
/>
</flat-card>
</div>
<div class="properties">
<flat-card>
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1">Properties</h2>
<md-checkbox
v-model="showPropertiesDiff"
v-if="diffVisualizationAvailable"
>
Show Diff
</md-checkbox>
<input id="filter" type="search" placeholder="Filter..." v-model="propertyFilterString" />
<md-field md-inline class="filter">
<label>Filter...</label>
<md-input v-model="propertyFilterString"></md-input>
</md-field>
</md-content>
<div v-if="selectedTree">
<tree-view
class="pre-line-data-card"
:item="selectedTree"
:filter="propertyFilter"
:collapseChildren="true"
:useGlobalCollapsedState="true"
/>
</div>
</md-content>
<tree-view
class="pre-line-data-card"
:item="selectedTree"
:filter="propertyFilter"
:collapseChildren="true"
:useGlobalCollapsedState="true"
/>
</md-card>
<div class="no-properties" v-else>
<i class="material-icons none-icon">
filter_none
</i>
<span>No element selected in the hierachy.</span>
</div>
</flat-card>
</div>
</md-card-content>
</template>
<script>
import TreeView from './TreeView.vue'
import Timeline from './Timeline.vue'
import Rects from './Rects.vue'
import FlatCard from './components/FlatCard.vue'
import { ObjectTransformer } from './transform.js'
import { DiffGenerator, defaultModifiedCheck } from './utils/diff.js'
@@ -315,6 +330,7 @@ export default {
components: {
'tree-view': TreeView,
'rects': Rects,
'flat-card': FlatCard,
}
}
@@ -340,7 +356,12 @@ function getFilter(filterString) {
}
</script>
<style>
<style scoped>
.container {
display: flex;
flex-wrap: wrap;
}
.rects {
flex: none;
margin: 8px;
@@ -353,6 +374,16 @@ function getFilter(filterString) {
min-width: 400px;
}
.rects,
.hierarchy,
.properties {
padding: 5px;
}
.flat-card {
height: 100%;
}
.hierarchy>.tree-view,
.properties>.tree-view {
margin: 16px;
@@ -360,7 +391,7 @@ function getFilter(filterString) {
.data-card {
overflow: auto;
max-height: 48em;
max-height: 730px;
}
.pre-line-data-card {
@@ -369,4 +400,27 @@ function getFilter(filterString) {
white-space: pre-line;
}
.no-properties {
display: flex;
flex-direction: column;
align-self: center;
align-items: center;
justify-content: center;
height: calc(100% - 50px);
padding: 50px 25px;
}
.no-properties .none-icon {
font-size: 35px;
margin-bottom: 10px;
}
.no-properties span {
font-weight: 100;
}
.filter {
width: auto;
}
</style>

View File

@@ -98,7 +98,7 @@ export default {
}
.time-column .time-link {
width: 8.5em;
width: 9em;
}
.type-column {

View File

@@ -15,10 +15,7 @@
<template>
<md-card-content class="container">
<md-card class="changes card">
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1">Log</h2>
</md-content>
<flat-card class="changes card">
<div class="filters">
<md-field>
<label>Transaction Type</label>
@@ -40,27 +37,33 @@
</md-chips>
</div>
<virtual-list style="height: 360px; overflow-y: auto;"
<virtual-list style="height: 600px; overflow-y: auto;"
:data-key="'timestamp'"
:data-sources="filteredData"
:data-component="transactionEntryComponent"
:extra-props="{'onClick': transactionSelected}"
ref="loglist"
/>
</md-card>
</flat-card>
<md-card class="changes card">
<flat-card class="changes card">
<md-content md-tag="md-toolbar" md-elevation="0" class="card-toolbar md-transparent md-dense">
<h2 class="md-title" style="flex: 1">Changes</h2>
</md-content>
<div class="changes-content">
<div class="changes-content" v-if="selectedTree">
<tree-view
:item="selectedTree"
:collapseChildren="true"
:useGlobalCollapsedState="true"
/>
</div>
</md-card>
<div class="no-properties" v-else>
<i class="material-icons none-icon">
filter_none
</i>
<span>No transaction selected.</span>
</div>
</flat-card>
</md-card-content>
</template>
@@ -68,9 +71,10 @@
import TreeView from './TreeView.vue';
import VirtualList from '../libs/virtualList/VirtualList';
import TransactionEntry from './TransactionEntry.vue';
import FlatCard from './components/FlatCard.vue';
import { transform_json } from './transform.js';
import { stableIdCompatibilityFixup } from './utils/utils.js'
import { stableIdCompatibilityFixup } from './utils/utils.js';
export default {
name: 'transactionsview',
@@ -268,6 +272,7 @@ export default {
components: {
'virtual-list': VirtualList,
'tree-view': TreeView,
'flat-card': FlatCard,
}
}
@@ -280,7 +285,8 @@ export default {
.transaction-table,
.changes {
flex: 1;
flex: 1 1 0;
width: 0;
margin: 8px;
}
@@ -301,4 +307,22 @@ export default {
overflow: auto;
}
.no-properties {
display: flex;
flex-direction: column;
align-self: center;
align-items: center;
justify-content: center;
height: calc(100% - 50px);
padding: 50px 25px;
}
.no-properties .none-icon {
font-size: 35px;
margin-bottom: 10px;
}
.no-properties span {
font-weight: 100;
}
</style>

View File

@@ -0,0 +1,38 @@
<template>
<div class="flat-card">
<slot />
</div>
</template>
<script>
export default {
name: 'FlatCard',
}
</script>
<style scoped>
.flat-card {
word-break: normal;
tab-size: 4;
font-size: 14px;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: rgba(0,0,0,0);
font-family: Roboto, sans-serif;
line-height: 1.5;
background-repeat: no-repeat;
box-sizing: inherit;
padding: 0;
margin: 0;
display: block;
max-width: 100%;
outline: none;
text-decoration: none;
transition-property: box-shadow,opacity;
overflow-wrap: break-word;
position: relative;
white-space: normal;
border: thin solid rgba(0,0,0,.12);
background-color: #fff;
color: rgba(0,0,0,.87);
border-radius: 4px;
}
</style>

View File

@@ -16,6 +16,9 @@ const mixin = {
},
isLog(file) {
return file.type == DATA_TYPES.PROTO_LOG
},
hasDataView(file) {
return this.isLog(file) || this.isTrace(file) || this.isTransactions(file);
}
}

View File

@@ -66,7 +66,16 @@ module.exports = {
options: {
name: '[name].[ext]?[hash]'
}
}
},
{
test: /\.(ttf|otf|eot|woff|woff2)$/,
use: {
loader: "file-loader",
options: {
name: "fonts/[name].[ext]",
},
},
},
]
},
resolve: {

View File

@@ -3531,7 +3531,7 @@ lodash.words@^3.0.0:
dependencies:
lodash._root "^3.0.0"
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3:
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.3:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==