Initial commit

This commit is contained in:
2020-07-20 21:51:24 -04:00
commit 1bb466762f
30 changed files with 15407 additions and 0 deletions

69
toolbox-web/src/App.vue Normal file
View File

@@ -0,0 +1,69 @@
<template>
<v-app>
<v-navigation-drawer app>
<v-list dense>
<v-list-item link to="/">
<v-list-item-action>
<v-icon>mdi-apps</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>Home</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-list-item link v-for="tool in tools" :key="tool.name" :to="`/tool/${tool.name}`">
<v-list-item-action>
<v-icon>{{ tool.icon }}</v-icon>
</v-list-item-action>
<v-list-item-content>
<v-list-item-title>{{ tool.name }}</v-list-item-title>
</v-list-item-content>
</v-list-item>
</v-list>
</v-navigation-drawer>
<v-app-bar color="lime" app>
<v-toolbar-title>Toolbox</v-toolbar-title>
</v-app-bar>
<v-main>
<v-container fluid>
<router-view></router-view>
</v-container>
</v-main>
<v-footer app>
<span class="monospace">{{ status }}</span>
</v-footer>
</v-app>
</template>
<script lang="ts">
import Vue from 'vue'
import {Component} from 'vue-property-decorator'
import {namespace} from 'vuex-class'
import {Tool} from '@/models';
import {tools} from "@/tools";
const def = namespace('def')
@Component
export default class App extends Vue {
@def.State
public status!: string
public tools: Tool[] = tools;
}
</script>
<style>
html, body {
padding: 0;
margin: 0;
overflow: hidden !important;
}
.monospace {
font-family: monospace;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

View File

@@ -0,0 +1,51 @@
<template>
<v-container>
<p>Run with <code>perf record -F997 --call-graph dwarf -q &lt;program&gt;</code></p>
<v-file-input :loading="loading" label="perf.data" id="flamegraph-upload" @change="onUpload()"></v-file-input>
<object v-if="key" type="image/svg+xml" :data="getGraphUrl()"></object>
</v-container>
</template>
<script lang="ts">
import Vue from 'vue'
import {Component} from 'vue-property-decorator'
import {namespace} from 'vuex-class'
import {toolByName} from '@/tools'
import axios from 'axios'
import {FlameGraphResult} from "@/models";
import {API_URL} from "@/config";
const def = namespace('def')
@Component
export default class FlameGraph extends Vue {
public tool = toolByName('FlameGraph')
public key: string | null = null
public loading = false
getGraphUrl() {
return `${API_URL}/flame_graph/${this.key}`
}
onUpload() {
this.loading = true;
const formData = new FormData();
const input = document.getElementById('flamegraph-upload') as any;
formData.append('file', input.files[0]);
axios.post('http://localhost:8000/flame_graph', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(resp => {
const result = resp.data as FlameGraphResult
this.key = result.key
this.loading = false;
})
}
}
</script>

View File

@@ -0,0 +1,21 @@
<template>
<div>
<v-row>
<v-col>
<v-card max-width="344" to="/tool/FlameGraph">
<v-img :src="require('@/assets/FlameGraph.png')" height="200px"></v-img>
<v-card-title>FlameGraph</v-card-title>
<v-card-subtitle><i>perf</i> profiling data visualization</v-card-subtitle>
</v-card>
</v-col>
</v-row>
</div>
</template>
<script>
export default {
name: 'Home',
components: {}
}
</script>

View File

@@ -0,0 +1 @@
export const API_URL = "http://localhost:8000"

14
toolbox-web/src/main.ts Normal file
View File

@@ -0,0 +1,14 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
Vue.config.productionTip = false
new Vue({
router,
store,
vuetify,
render: h => h(App)
}).$mount('#app')

11
toolbox-web/src/models.ts Normal file
View File

@@ -0,0 +1,11 @@
export interface Tool {
icon?: string
name: string
}
export interface FlameGraphResult {
key: string
script_err: string
fold_err: string
graph_err: string
}

View File

@@ -0,0 +1,7 @@
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
export default new Vuetify({
})

View File

@@ -0,0 +1,18 @@
import Vue from 'vue'
import VueRouter, {RouteConfig} from 'vue-router'
import Home from '../components/Home.vue'
import FlameGraph from '@/components/FlameGraph.vue'
Vue.use(VueRouter)
const routes: Array<RouteConfig> = [
{path: '/', component: Home},
{path: '/tool/FlameGraph', component: FlameGraph}
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router

13
toolbox-web/src/shims-tsx.d.ts vendored Normal file
View File

@@ -0,0 +1,13 @@
import Vue, { VNode } from 'vue'
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {}
interface IntrinsicElements {
[elem: string]: any;
}
}
}

4
toolbox-web/src/shims-vue.d.ts vendored Normal file
View File

@@ -0,0 +1,4 @@
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}

View File

@@ -0,0 +1,13 @@
import {VuexModule, Module, Mutation, Action} from 'vuex-module-decorators'
@Module({namespaced: true, name: 'def'})
class DefaultModule extends VuexModule {
public status = '>'
@Mutation
public setStatus(newStatus: string): void {
this.status = newStatus
}
}
export default DefaultModule

View File

@@ -0,0 +1,11 @@
import Vue from 'vue'
import Vuex from 'vuex'
import DefaultModule from '@/store/DefaultModule'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
def: DefaultModule
}
})

9
toolbox-web/src/tools.ts Normal file
View File

@@ -0,0 +1,9 @@
import {Tool} from "@/models";
export const tools: Tool[] = [
{name: "FlameGraph", icon: "mdi-bug"}
]
export const toolByName = (name: string) => {
return tools.find(t => t.name == name)
}