app improvements

This commit is contained in:
Jonathan Shook
2020-08-25 15:32:30 -05:00
parent 630cf74888
commit 7b140ed2f9
21 changed files with 1157 additions and 1451 deletions

View File

@@ -1,32 +1,17 @@
<template>
<v-container>
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<v-btn title="App Selector" v-bind="attrs" v-on="on">APPS</v-btn>
</template>
<v-list>
<v-btn to="/ui/run" title="Run a workload">Run</v-btn>
<v-btn to="/ui/build" title="Build a workload from a schema" >Build</v-btn>
<v-btn to="/ui/status" title="See running workloads" >Status</v-btn>
<v-btn to="/ui/workspaces" title="Run a workload">Workspaces</v-btn>
</v-list>
</v-menu>
<!-- <v-select dense-->
<!-- hide-details="auto"-->
<!-- label="app"-->
<!-- v-model="thisapp"-->
<!-- :items="empty"-->
<!-- @select="selected(thisapp)"-->
<!-- @change="selected(thisapp)"-->
<!-- >-->
<!-- <template v-slot:append-item>-->
<!-- <v-list-item><nuxt-link to="/ui/run">Run</nuxt-link></v-list-item>-->
<!-- <v-list-item><nuxt-link to="/ui/build">Build</nuxt-link></v-list-item>-->
<!-- <v-list-item><nuxt-link to="/ui/status">Status</nuxt-link></v-list-item>-->
<!-- <v-list-item><nuxt-link to="/ui/workspaces">Workspaces</nuxt-link></v-list-item>-->
<!-- </template>-->
<!-- </v-select>-->
</v-container>
<div class="d-flex align-center ma-2 pa-1 text-center">
<v-btn to="/ui/build/" title="Build a workload from a schema">Build</v-btn>
<v-btn to="/ui/run/" title="Run a workload">Run</v-btn>
<v-btn to="/ui/watch/" title="Watch workload status">Watch</v-btn>
<v-btn to="/docs/" title="Documentation">Docs</v-btn>
<v-btn
title="Give us your feedback!"
href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">
<v-icon>mdi-lightbulb-on-outline</v-icon>
</v-btn>
</div>
</template>
<script>
@@ -35,24 +20,10 @@ export default {
data() {
let data = {
empty: [],
apps: ['build','run','status','workspaces'],
apps: ['build', 'run', 'status', 'workspaces'],
thisapp: 'build'
};
return data;
},
computed: {
current: {
get: function() {}
}
},
methods: {
selected(evt) {
console.log("selected:" + JSON.stringify(evt))
let selected_path = "/ui/" + evt;
if (!this.$route.fullPath.includes(selected_path)) {
// this.$router.
}
}
}
}
</script>

View File

@@ -1,126 +1,148 @@
<template>
<v-navigation-drawer v-model="drawer" :permanent="lockmenu" @transitionend="setDrawer" app class="secondary">
<v-navigation-drawer app
v-model="isDrawerOpen"
:permanent="isMenuLocked"
@transitionend="toggleDrawerOpened"
:title="drawerTitle">
<div class="menu">
<!-- active_category: {{active_category}} active_topic: {{active_topic}}-->
<!-- Use active_category and active_topic to select inactive -->
<div class="menu">
<v-list nav dense>
<!-- active_category: {{ active_category.name }} active_topic: {{ active_topic.name }}-->
<!-- Use active_category and active_topic to select inactive -->
<!-- KEEP OPEN -->
<v-list-item v-if="$vuetify.breakpoint.mdAndDown">
<v-list-item-action>
<v-switch inset dark color="accent" v-model="lockmenu" label="keep open"
@change="setLockMenu"></v-switch>
</v-list-item-action>
</v-list-item>
<v-list nav dense>
<!-- by category -->
<v-list-group v-for="(category,c) in categories" :key="c"
:value="active_category === category.category" active-class="isactive">
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title @click="$nuxt.$router.push({path: category.categoryPath})">
{{category.categoryName}}
</v-list-item-title>
</v-list-item-content>
</template>
<v-list-item v-for="(doc, i) in category.docs" :key="i" link :to="doc.filename">
<v-list-item-title @click="$nuxt.$router.push({path: doc.filename})">{{doc.attributes.title}}</v-list-item-title>
</v-list-item>
<!-- KEEP OPEN -->
<v-list-item>
<!-- <v-list-item v-if="$vuetify.breakpoint.mdAndDown">-->
<v-list-item-action>
<v-switch inset v-model="isMenuLocked" label="keep open"
@change="toggleMenuLocked"></v-switch>
</v-list-item-action>
</v-list-item>
</v-list-group>
</v-list>
<!-- by category -->
<v-list-group v-for="(category,c) in categories" :key="c"
:value="active_category.title === category.title" active-class="isactive">
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title link :to="category.path">{{ category.title }}</v-list-item-title>
</v-list-item-content>
</template>
</div>
</v-navigation-drawer>
<!-- by topic -->
<v-list-item v-for="(topic, i) in category.topics" :key="i" link :to="topic.path">
<v-list-item-title>{{ topic.title }}</v-list-item-title>
</v-list-item>
</v-list-group>
</v-list>
</div>
</v-navigation-drawer>
</template>
<script>
export default {
name: 'DocsMenu',
props: {
categories: Array,
active_category: String,
active_topic: String
},
data(context) {
let lockmenu = this.$store.state.docs.isDrawerPinned;
if (lockmenu == null) {
lockmenu = false
}
console.log("data says context is: " + context);
// console.log("g says" + this.$getters.docs.drawerState);
return {
lockmenu: lockmenu,
drawer: null
}
},
methods: {
setLockMenu() {
this.$store.commit('docs/setMenuLock', this.lockmenu);
},
setDrawer() {
this.$store.commit('docs/setDrawer', this.drawer);
}
},
created() {
this.setDrawer();
this.$store.subscribe((mutation, state) => {
console.log("mutation type " + mutation.type);
if (mutation.type === 'docs/toggleDrawerState') {
this.drawer = this.$store.state.docs.isDrawerOpen;
} else if (mutation.type === 'docs/setMenuLock') {
this.lockmenu = this.$store.state.docs.isDrawerPinned;
}
});
}
// computed: {
// drawerState() {
// console.log("getting drawerState...");
// return this.$store.getters.drawerState;
// }
// },
export default {
name: 'DocsMenu',
props: {
categories: Array,
active_category: Object,
active_topic: Object
},
data() {
let drawer = null;
return {
drawer
}
},
computed: {
drawerTitle: {
get() {
return "category=" + this.active_category.name
+"\ntopic=" + this.active_topic.name
}
},
isMenuLocked: {
get() {
return this.$store.getters["docs/getIsMenuLocked"]
}
},
isDrawerOpen: {
get() {
return this.$store.getters["docs/getIsDrawerOpen"]
},
set(val) {
this.$store.dispatch("docs/setIsDrawerOpen", val)
}
}
},
methods: {
clickCategory(category) {
this.$store.dispatch("docs/setActiveCategory", category)
this.$nuxt.$router.push({path: category.path})
},
clickTopic(category, topic) {
this.$store.dispatch("docs/setActiveCategory", category)
this.$store.dispatch("docs/setActiveTopic", topic)
this.$nuxt.$router.push({path: topic.path})
},
toggleDrawerOpened() {
this.drawer = !this.drawer;
},
toggleMenuLocked() {
this.$store.dispatch("docs/setIsMenuLocked", !this.$store.getters["docs/getIsMenuLocked"])
},
setIsDrawerOpen() {
this.$store.commit('docs/setIsDrawerOpen', this.drawer);
}
},
async created() {
await this.$store.dispatch("docs/loadCategories");
}
}
</script>
<style>
.v-list-item {
color: #FFFFFF;
}
/*.v-list-item {*/
/* color: #FFFFFF;*/
/*}*/
.v-list-item--title {
color: #FFFFFF;
}
/*.v-list-item--title {*/
/* color: #FFFFFF;*/
/*}*/
.v-list-item--active {
color: #FFFFFF !important;
}
.v-list-item--disabled {
color: #DDDDDD !important;
}
.v-list-item--active {
/*border: 1px black;*/
background-color: #EEEEEE;
/*color: #FFFFFF !important;*/
}
div.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: #DDDDDD !important;
}
a.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: #DDDDDD !important;
}
/*.v-list-item--disabled {*/
/* color: #DDDDDD !important;*/
/*}*/
.nuxt-link-exact-active {
/*color: #52c41a;*/
background-color: #7F828B;
color: #52c41a;
/*color: #000000;*/
}
/*div.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {*/
/* color: #DDDDDD !important;*/
/*}*/
/*a.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {*/
/* color: #DDDDDD !important;*/
/*}*/
.isactive {
background-color: #7F828B;
color: #52c41a;
}
/*.nuxt-link-exact-active {*/
/* !*color: #52c41a;*!*/
/* background-color: #7F828B;*/
/* color: #52c41a;*/
/* !*color: #000000;*!*/
/*}*/
.router-link-active {
background-color: #FFFFFF;
color: #FFFFFF;
/*.isactive {*/
/* background-color: #7F828B;*/
/* color: #52c41a;*/
/*}*/
}
/*.router-link-active {*/
/* background-color: #FFFFFF;*/
/* color: #FFFFFF;*/
/*}*/
</style>

View File

@@ -0,0 +1,25 @@
<template>
<v-app-bar app fluid>
<!-- <v-app-bar app dark fluid dense flat>-->
<v-toolbar-title><slot></slot></v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<app-selector></app-selector>
<workspace-selector></workspace-selector>
</v-toolbar-items>
</v-app-bar>
</template>
<script>
import AppSelector from "@/components/AppSelector";
import WorkspaceSelector from "@/components/WorkspaceSelector";
export default {
name: "MainAppBar",
components: {WorkspaceSelector, AppSelector}
}
</script>
<style scoped>
</style>

View File

@@ -1,149 +1,197 @@
<template>
<div>
<markdown-it-vue class="md-body" :content="mdcontent" :options="mdoptions"/>
</div>
<!-- <v-main fluid class="d-block">-->
<!-- <markdown-it-vue class="d-block" :content="mdcontent" :options="mdoptions"/>-->
<markdown-it-vue class="md-body" ref="myMarkdownItVue" :content="mdcontent" :options="options"/>
<!-- </v-main>-->
</template>
<script>
import MarkdownItVue from 'markdown-it-vue'
// import 'markdown-it-vue/dist/markdown-it-vue.css'
// var hljs = require('highlight.js');
import MarkdownItVue from 'markdown-it-vue'
// https://www.npmjs.com/package/markdown-it-replace-link
// https://www.npmjs.com/package/markdown-it-relativelink
// import 'markdown-it-link-attributes'
// import 'markdown-it-relativelink'
// let mireli = require('markdown-it-relativelink')({prefix: 'http://example.com/'})
// let msa = require('markdown-it-smartarrows');
// this.use(msa);
import 'markdown-it-replace-link'
export default {
name: "MarkdownVue",
components: {MarkdownItVue},
mounted() {
console.log("mounted");
},
let mireplink = require('markdown-it-replace-link')
props: {
mdcontent: String,
mdoptions: Object
export default {
name: "MarkdownVue",
components: {MarkdownItVue},
mounted() {
let mmd = this.$refs.myMarkdownItVue;
mmd.use(mireplink);
// mdoptions: {
// type: Object,
// default: {
// markdownIt: {
// linkify: true
// },
// linkAttributes: {
// attrs: {
// target: '_blank',
// rel: 'noopener'
// }
// }
// }
// }
}
// mmd.use(mirl)
// console.log("typeof(mmd):" + typeof (mmd))
},
// data() {
// let options = {
// markdownIt: {
// linkify: true
// },
// linkAttributes: {
// attrs: {
// target: '_blank',
// rel: 'noopener'
// }
// },
// replaceLink: function(link, env) {
// return "LINK:" + link;
// }
// }
// return {options}
// },
props: {
mdcontent: String,
options: {
testing: "one two three"
}
}
}
</script>
<style>
code.hljs::before,code:before {
content: '';
}
.v-application code:before,.v-application code:after {
content: '';
}
.v-application code {
background-color: #E3FFE3;
/*background-color: #FBE5E1;*/
padding: unset;
/*padding: 10px;*/
color: unset;
}
code::before {
content: '';
}
code:after {
content: '';
}
.markdown-body pre {
/*background-color: #52c41a;*/
padding: 10px 10px 10px 0;
}
pre {
padding: 5px;
margin: 0px 0px 10px 5px;
}
ul {
padding-bottom: 10px;
}
div.markdown-body p {
padding: 10px 0 0 0;
}
code::after {
content: '';
}
.hljs code {
background-color: #E3FFE3;
padding: unset;
color: unset;
/*padding: 100px;*/
}
.md-body {
padding-left: 10px;
justify-content: left;
align-items: left;
text-align: left;
vertical-align: top;
alignment: top;
text-align: top;
webkit-box-align: initial;
}
pre {
background-color: #E3FFE3;
padding: unset;
color: unset;
}
.markdown-it-vue-alter-info {
border: 1px solid #91d5ff;
background-color: #e6f7ff;
}
.markdown-body {
padding: 15px;
}
.markdown-it-vue-alert-icon-info {
color: #1890ff;
}
/* code.hljs::before,code:before {*/
/* content: '';*/
/* }*/
/* .v-application code:before,.v-application code:after {*/
/* content: unset;*/
/* }*/
.markdown-it-vue-alter-success {
border: 1px solid #b7eb8f;
background-color: #f6ffed;
}
/* code::before {*/
/* content: '';*/
/* }*/
/* code:after {*/
/* content: '';*/
/* }*/
.markdown-it-vue-alert-icon-success {
color: #52c41a;
}
/* pre {*/
/* padding: 5px;*/
/* margin: 0px 0px 10px 5px;*/
/* }*/
/* ul {*/
/* padding-bottom: 10px;*/
/* }*/
.markdown-it-vue-alter-error {
border: 1px solid #f5222d;
background-color: #fff1f0;
}
/* code::after {*/
/* content: '';*/
/* }*/
.markdown-it-vue-alert-icon-error {
color: #f5222d;
}
/* .md-body {*/
/* padding-left: 10px;*/
/* justify-content: left;*/
/* align-items: left;*/
/* text-align: left;*/
/* vertical-align: top;*/
/* alignment: top;*/
/* text-align: top;*/
/* webkit-box-align: initial;*/
/* }*/
.markdown-it-vue-alter-warning {
border: 1px solid #ffe58f;
background-color: #fffbe6;
}
.markdown-it-vue-alter-info {
border: 1px solid #91d5ff;
background-color: #e6f7ff;
}
.markdown-it-vue-alert-icon-warning {
color: #faad14;
}
.markdown-it-vue-alert-icon-info {
color: #1890ff;
}
.markdown-it-vue-alter {
border-radius: 0;
border: 0;
margin-bottom: 0;
display: inline-flex;
font-family: 'Chinese Quote', -apple-system, BlinkMacSystemFont, 'Segoe UI',
'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue',
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol';
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
color: rgba(0, 0, 0, 0.65);
box-sizing: border-box;
padding: 0;
list-style: none;
position: relative;
padding: 8px 15px 8px 37px;
border-radius: 4px;
width: 100%;
margin-bottom: 16px;
}
.markdown-it-vue-alter-success {
border: 1px solid #b7eb8f;
background-color: #f6ffed;
}
.markdown-it-vue-alter p {
margin-bottom: 2px;
}
.markdown-it-vue-alert-icon-success {
color: #52c41a;
}
.markdown-it-vue-alert-icon {
top: 11.5px;
left: 16px;
position: absolute;
}
.markdown-it-vue-alter-error {
border: 1px solid #f5222d;
background-color: #fff1f0;
}
.markdown-it-vue-alert-icon-error {
color: #f5222d;
}
.markdown-it-vue-alter-warning {
border: 1px solid #ffe58f;
background-color: #fffbe6;
}
.markdown-it-vue-alert-icon-warning {
color: #faad14;
}
.markdown-it-vue-alter {
border-radius: 0;
border: 0;
margin-bottom: 0;
display: inline-flex;
font-family: 'Chinese Quote', -apple-system, BlinkMacSystemFont, 'Segoe UI',
'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue',
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol';
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
color: rgba(0, 0, 0, 0.65);
box-sizing: border-box;
padding: 0;
list-style: none;
position: relative;
padding: 8px 15px 8px 37px;
border-radius: 4px;
width: 100%;
margin-bottom: 16px;
}
.markdown-it-vue-alter p {
margin-bottom: 2px;
}
.markdown-it-vue-alert-icon {
top: 11.5px;
left: 16px;
position: absolute;
}
</style>

View File

@@ -1,31 +1,42 @@
<template>
<v-container>
<v-text-field dense
<!-- <v-container fluid class="d-flex pa-3">-->
<v-row>
<v-col cols="12">
<v-text-field dense
full-width
label="Name of new workspace"
v-if="mode==='adding'"
v-model="new_workspace"
ref="new_workspace_input"
hint="workspace name"
@blur="commitWorkspace(new_workspace)"
@keydown.enter="commitWorkspace(new_workspace)"
@keydown.esc="cancelWorkspace()"
></v-text-field>
<!-- label="workspace"-->
<v-select dense outlined
full-width
label="Name of new workspace"
v-if="mode==='adding'"
v-model="new_workspace"
ref="new_workspace_input"
hint="workspace name"
@blur="commitWorkspace(new_workspace)"
@keydown.enter="commitWorkspace(new_workspace)"
></v-text-field>
<v-select dense
hide-details="auto"
label="workspace"
v-if="mode==='showing'"
v-model="workspace"
:items="workspaces"
item-text="name"
item-value="name"
>
<template v-slot:append-item>
<v-list-item>
<v-btn @click="addWorkspace()">+ Add Workspace</v-btn>
</v-list-item>
</template>
</v-select>
</v-container>
hide-details="true"
hint="current workspace"
v-if="mode==='showing'"
v-model="workspace"
:items="workspaces"
item-text="name"
item-value="name"
prepend-inner-icon="mdi-folder"
title="active workspace"
>
<template v-slot:append-item>
<v-list-item>
<v-btn link @click="addWorkspace()">+ Add Workspace</v-btn>
<v-spacer></v-spacer>
<v-btn to="/ui/workspaces">Manage</v-btn>
</v-list-item>
</template>
</v-select>
</v-col>
</v-row>
<!-- </v-container>-->
</template>
<script>
@@ -55,58 +66,26 @@ export default {
}
},
methods: {
cancelWorkspace: function () {
this.mode = "showing";
this.new_workspace = "";
},
addWorkspace: function () {
this.mode = "adding";
// this.$refs.new_workspace_input.focus();
this.$nextTick(() => {
this.$refs.new_workspace_input.focus();
});
},
commitWorkspace: function ({$store}) {
console.log("commit:" + JSON.stringify(this.new_workspace));
this.$store.dispatch("workspaces/activateWorkspace", this.new_workspace);
this.new_workspace = "";
this.mode = "showing";
//
//
// WorkspaceService.getWorkspace({'name': this.new_workspace})
// .then(res => {
// console.log("async create workspace: " + JSON.stringify(res));
// })
// .then(res => {
// return WorkspaceService.getWorkspaces();
// })
// .then(res => {
// console.log("get workspaces: " + JSON.stringify(res));
// this.setWorkspaces(res)
// this.setWorkspace(this.new_workspace)
// this.new_workspace = "";
// this.mode = "showing"
// })
// .catch((e) => {
// console.log("error in commitWorkspaces: " + e)
// })
}
// async getWorkspaces() {
// const response = await WorkspaceService.getWorkspaces()
// this.setWorkspaces()
// },
// setWorkspaces: function (workspaces) {
// this.workspaces = workspaces;
// this.$store.commit('workspaces/setWorkspaces', this.workspaces);
// },
// selectWorkspace: function (selected) {
// this.workspace = selected;
// this.$store.commit('workspaces/setWorkspace', this.workspace);
// }
},
created() {
console.log("created component...");
// this.$store.subscribe((mutation, state) => {
// console.log("mutation type " + mutation.type);
// if (mutation.type === 'workspaces/setWorkspace') {
// this.workspace = this.$store.state.workspaces.workspace;
// } else if (mutation.type === 'workspaces/setWorkspaces') {
// this.workspacaes = this.$store.state.workspaces.workspaces;
// } else {
// console.error("Unrecognized mutation", mutation)
// }
// })
this.$store.dispatch('workspaces/initWorkspaces', "selector load");
}
}

View File

@@ -0,0 +1,55 @@
/**
* Path scheme:
* /docs/cat1/t1/t2/t3.md
* _____ docs prefix
* / delimiter
* ____ category name
* / delimiter
* ___________ topic path, including separators
* ________ topic name, without extension
*
* /docs/cat1/index.md summary doc for cat1
* ______________________ topic path
* __________ category path
*/
export default {
getCategory(route, categories) {
let active_category = categories[0];
if (!route.path) {
active_category = categories[0];
} else {
let parts = route.path.split(/\/|%2F/)
if (parts[1]!=="docs" || parts.length===1) {
throw "invalid path for docs: '" + route.path + "' parts[0]=" + parts[0] + " parts=" + JSON.stringify(parts,null,2)
}
if (parts.length>2) {
let active_category_name = parts[2];
active_category = categories.find(x => x.name === active_category_name);
if (active_category === undefined) {
console.error("unable to find category named '" + active_category_name + "', resetting to root")
// console.log("categories:" + JSON.stringify(categories, null, 2))
active_category = categories[0];
}
}
}
return active_category;
},
getTopic(route, categories, active_category) {
let active_topic = active_category.summary_topic;
if (!route.path) {
active_topic = active_category.topics[0]
} else {
let found_topic = active_category.topics.find(x => {return x.path === route.path})
if (found_topic) {
active_topic = found_topic;
}
}
return active_topic;
}
}

View File

@@ -9,51 +9,51 @@ export default {
}
</script>
<style>
html {
font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, 'Helvetica Neue', Arial, sans-serif;
font-size: 16px;
word-spacing: 1px;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
/*html {*/
/* font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',*/
/* Roboto, 'Helvetica Neue', Arial, sans-serif;*/
/* font-size: 16px;*/
/* word-spacing: 1px;*/
/* -ms-text-size-adjust: 100%;*/
/* -webkit-text-size-adjust: 100%;*/
/* -moz-osx-font-smoothing: grayscale;*/
/* -webkit-font-smoothing: antialiased;*/
/* box-sizing: border-box;*/
/*}*/
*,
*:before,
*:after {
box-sizing: border-box;
margin: 0;
}
/**,*/
/**:before,*/
/**:after {*/
/* box-sizing: border-box;*/
/* margin: 0;*/
/*}*/
.button--purple {
display: inline-block;
border-radius: 4px;
border: 1px solid #0C1439;
color: #0C1439;
text-decoration: none;
padding: 10px 30px;
}
/*.button--purple {*/
/* display: inline-block;*/
/* border-radius: 4px;*/
/* border: 1px solid #0C1439;*/
/* color: #0C1439;*/
/* text-decoration: none;*/
/* padding: 10px 30px;*/
/*}*/
.button--purple:hover {
color: #fff;
background-color: #0C1439;
}
/*.button--purple:hover {*/
/* color: #fff;*/
/* background-color: #0C1439;*/
/*}*/
.button--grey {
display: inline-block;
border-radius: 4px;
border: 1px solid #35495e;
color: #35495e;
text-decoration: none;
padding: 10px 30px;
margin-left: 15px;
}
/*.button--grey {*/
/* display: inline-block;*/
/* border-radius: 4px;*/
/* border: 1px solid #35495e;*/
/* color: #35495e;*/
/* text-decoration: none;*/
/* padding: 10px 30px;*/
/* margin-left: 15px;*/
/*}*/
.button--grey:hover {
color: #fff;
background-color: #35495e;
}
/*.button--grey:hover {*/
/* color: #fff;*/
/* background-color: #35495e;*/
/*}*/
</style>

View File

@@ -1,5 +1,5 @@
<template>
<v-app dark>
<v-app>
<h1 v-if="error.statusCode === 404">
{{ pageNotFound }}
</h1>

View File

@@ -1,219 +0,0 @@
// asyncData in multiple mixins seems to be broken, or worse, working as designed
export default {
async asyncData(context) {
function fetchStatusHandler(response) {
if (response.status === 200) {
return response;
} else {
throw new Error(response.statusText);
}
}
if (context.req) {
console.log("avoiding server-side async");
return;
}
let baseurl = document.location.href.split('/').slice(0, 3).join('/');
if (context.isDev && baseurl.includes(":3000")) {
console.log("Dev mode: remapping 3000 to 12345 for split dev environment.");
baseurl = baseurl.replace("3000", "12345");
}
let services = baseurl + "/services";
console.log("async loading get_categories data: context: " + context);
var fm = require('front-matter');
let paths = await fetch(services + "/docs/markdown.csv")
.then(res => {
return res.text()
})
.then(body => {
return body.split("\n")
})
.catch(err => {
console.log("error:" + err)
});
let imports = [];
let promises = [];
for (let index in paths) {
let key = paths[index];
if (key == null || key == "") {
continue
}
const [, name] = key.match(/(.+)\.md$/);
let detailName = key.split("/").filter(x => x.includes(".md"))[0];
detailName = detailName.substr(0, detailName.length - 3);
let categories = key.split("/").filter(x => !x.includes("."))
//const mdMeta = resolve(key);
promises.push(fetch(services + "/docs/markdown/" + key)
.then(res => res.text())
.then(body => {
return {
"rawMD": body,
"detailName": detailName,
"categories": categories,
"name": name
}
}));
}
var mdData = await Promise.all(
promises
);
for (var data of mdData) {
let rawMD = data.rawMD;
var mdMeta = fm(rawMD);
if (mdMeta.attributes == null || mdMeta.attributes.title == null) {
mdMeta.attributes.title = data.detailName;
}
if (typeof mdMeta.attributes.weight === 'undefined') {
mdMeta.attributes.weight = 0;
}
mdMeta.categories = data.categories;
// mdMeta.filename = encodeURIComponent(data.name);
console.log("data.name="+data.name);
mdMeta.filename = "/docs/"+data.name;
console.log("mdMeta.filename="+mdMeta.filename);
// console.log("mdMeta:" + JSON.stringify(mdMeta));
imports.push(mdMeta);
}
const categorySet = new Set();
imports.forEach(x => {
categorySet.add(x.categories.toString())
});
const categories = Array.from(categorySet).map(category => {
let docs = imports.filter(x => x.categories.toString() === category);
let summarydoc = docs.find(x => x.filename.endsWith('index'));
docs = docs.filter(x => !x.filename.endsWith('index'));
docs.forEach(d => delete d.body);
docs.sort((a, b) => a.attributes.weight - b.attributes.weight);
let weight = summarydoc ? summarydoc.attributes.weight : 0;
let categoryName = summarydoc ? (summarydoc.attributes.title ? summarydoc.attributes.title : category) : category;
let categoryPath = "/docs/" + category;
let entry = {category, categoryName, docs, summarydoc, weight, categoryPath}
console.log("category=> " + category);
return entry;
}
).sort((c1, c2) => c1.weight - c2.weight);
let active_category = '';
let active_category_name = '';
let active_topic = '';
// IFF no category was active, then make the first category active.
// fullPath: "/docs/designing_workloads%2F00_yaml_org"
// hash: ""
// name: "docs-all"
// params.pathMatch: "designing_workloads/00_yaml_org"
// path: "/docs/designing_workloads%2F00_yaml_org"
// query:
if (!context.params.slug && !context.route.path) {
console.log("params.slug was not defined");
active_category = categories[0].category;
active_category_name = categories[0].categoryName;
if (categories[0].summarydoc == null && categories[0].docs.length > 0) {
active_topic = categories[0].docs[0].filename;
}
} else if (context.route.path.startsWith("/docs/")) {
console.log("context.path docs path was defined:" + context.route.path)
let docpath = context.route.path.replace(/^(\/docs\/)/,"");
let parts = docpath.split(/\/|%2F/,2);
if (docpath==="") {
active_category = categories[0].category;
active_category_name = categories[0].categoryName;
} else {
active_category = parts[0];
console.log("==> docpath[" + docpath + "] active_category[" + active_category + "]");
active_topic = parts.length > 1 ? parts[1] : null;
}
} else {
let parts = context.params.slug.split("/", 2);
active_category = parts[0];
console.log("==> params.slug[" + context.params.slug + "] active_category[" + active_category + "]");
active_topic = parts.length > 1 ? parts[1] : null;
}
if (active_topic !== null && active_topic.endsWith(".html")) {
active_topic = active_topic.substr(0, active_topic.length - 5);
}
if (active_topic !== null && active_topic.endsWith(".md")) {
active_topic = active_topic.substr(0, active_topic.length - 3);
}
if (active_category !== null && active_category.endsWith(".html")) {
active_category = active_category.substr(0, active_category.length - 5);
}
if (active_category !== null && active_category.endsWith(".md")) {
active_category = active_category.substr(0, active_category.length - 3);
}
let foundCategory = categories.find(c => c.category === active_category);
if (foundCategory != undefined) {
active_category_name = categories.find(c => c.category === active_category).categoryName;
}
console.log("==> active category[" + active_category + "] topic[" + active_topic + "]");
// At this point, we have an active category or even a topic.
// We're all in on loading markdown, but which one?
let docname = active_category;
console.log("docname (active_category only): " + docname);
if (active_topic) {
docname += '/' + active_topic + '.md';
} else {
docname += '/' + 'index.md';
}
console.log("docname: " + docname);
var fm = require('front-matter');
let docbody = "";
let mdPath = services + '/docs/markdown/' + docname;
let rawMD = await fetch(services + "/docs/markdown/" + docname)
.then(fetchStatusHandler)
.then(res => res.text())
.then(body => docbody = body)
.catch(function (error) {
console.log(error);
});
;
var markdown = fm(rawMD);
// console.log("markdown_body:\n" + markdown.body);
let mydata = {
markdown_attr: markdown.attributes,
markdown_body: markdown.body,
categories: categories,
active_category: active_category,
active_category_name: active_category_name,
active_topic: active_topic
};
return mydata;
}
}

View File

@@ -55,23 +55,23 @@ export default {
** https://github.com/nuxt-community/vuetify-module
*/
vuetify: {
theme: {
dark: false,
themes: {
light: {
primary: '#51DDBD',
secondary: '#2D4ADE',
accent: '#FA7D2B',
// primary: '#1976D2',
// secondary: '#424242',
// accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107'
}
}
}
// theme: {
// dark: false,
// themes: {
// light: {
// primary: '#51DDBD',
// secondary: '#2D4ADE',
// accent: '#FA7D2B',
// // primary: '#1976D2',
// // secondary: '#424242',
// // accent: '#82B1FF',
// error: '#FF5252',
// info: '#2196F3',
// success: '#4CAF50',
// warning: '#FFC107'
// }
// }
// }
},
router: {
mode: 'hash'

View File

@@ -56,23 +56,23 @@ export default {
** https://github.com/nuxt-community/vuetify-module
*/
vuetify: {
theme: {
dark: false,
themes: {
light: {
primary: '#51DDBD',
secondary: '#2D4ADE',
accent: '#FA7D2B',
// primary: '#1976D2',
// secondary: '#424242',
// accent: '#82B1FF',
error: '#FF5252',
info: '#2196F3',
success: '#4CAF50',
warning: '#FFC107'
}
}
}
// theme: {
// dark: false,
// themes: {
// light: {
// primary: '#51DDBD',
// secondary: '#2D4ADE',
// accent: '#FA7D2B',
// // primary: '#1976D2',
// // secondary: '#424242',
// // accent: '#82B1FF',
// error: '#FF5252',
// info: '#2196F3',
// success: '#4CAF50',
// warning: '#FFC107'
// }
// }
// }
},
router: {
mode: 'hash'

View File

@@ -1,129 +0,0 @@
var glob = require('glob');
var path = require('path');
export default {
node: {
fs: 'empty',
dgram: 'empty'
},
mode: 'spa',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
plugins: [
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Simple usage
'@nuxtjs/vuetify'
],
/*
** Nuxt.js modules
*/
modules: [
],
/*
** Build configuration
*/
build: {
babel: {
presets({ envName }) {
const envTargets = {
client: { "chrome": "78" },
server: { node: "current" },
};
return [
[
"@nuxt/babel-preset-app",
{
targets: envTargets[envName]
}
]
]
}
},
html: {
minify: {
minifyJS: false,
minifyCSS: false,
collapseBooleanAttributes: false,
decodeEntities: false,
processConditionalComments: false,
removeEmptyAttributes: false,
removeRedundantAttributes: false,
trimCustomFragments: false,
useShortDoctype: false
}
},
optimization: {
minimize: false
}
,extend(config,ctx) {
config.devtool = ctx.isClient ? 'eval-source-map' : 'inline-source-map'
}
// , extend(config,ctx) {
// config.devtool = ctx.isClient ? 'eval-source-map' : 'inline-source-map';
// }
},
vuetify: {
theme: {
dark: true,
themes:{
dark:{
primary: '#FF7D2B',
secondary: '#0C153A',
accent: '#FF7D2B',
}
}
}
},
generate: {
routes: dynamicRoutes
}
}
var dynamicRoutes = getDynamicPaths({
'/docs': 'docs/*.md'
});
/* https://github.com/jake-101/bael-template */
function getDynamicPaths(urlFilepathTable) {
return [].concat(
...Object.keys(urlFilepathTable).map(url => {
var filepathGlob = urlFilepathTable[url];
return glob
.sync(filepathGlob, { cwd: 'content' })
.map(filepath => `${url}/${path.basename(filepath, '.md')}`);
})
);
}

View File

@@ -1,105 +1,115 @@
<template>
<v-app>
<docs-menu v-model="isDrawerOpen"
:categories="categories"
:active_category="active_category"
:active_category_name="active_category_name"
:active_topic="active_topic"/>
<docs-menu
:active_category="active_category"
:active_topic="active_topic"
:categories="categories"
@change="menuChanged()"
@select="menuChanged()"></docs-menu>
<v-app-bar app dark color="secondary" collapse-on-scroll dense>
<v-app-bar app collapse-on-scroll dense>
<v-app-bar-nav-icon @click.stop="toggleDrawer"/>
<v-toolbar-title>NoSQLBench Docs</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-title>{{ toolbarTitle }}</v-toolbar-title>
<v-toolbar-items>
</v-toolbar-items>
</v-app-bar>
<v-main>
<v-container>
<v-row align-content="start" align="start" justify="start">
<div>{{ testdata }}</div>
<div class="Doc">
<div class="doc-title">
<h1></h1>
</div>
<div>
<markdown-vue class="md-body content" :mdcontent="markdown_body"/>
</div>
</div>
</v-row>
</v-container>
<markdown-vue :mdcontent="markdown_body"/>
</v-main>
<v-footer app dark color="secondary">
<v-footer app>
<span>&copy; 2020</span>
</v-footer>
</v-app>
</template>
<script>
import get_data from '~/mixins/get_data.js';
import DocsMenu from '~/components/DocsMenu.vue'
import MarkdownVue from "~/components/MarkdownVue";
import docpaths from "@/js/docpaths.js"
export default {
mixins: [get_data],
data() {
return {
markdown_body: "testing",
active_category: null,
active_topic: null
}
},
components: {
DocsMenu, MarkdownVue
},
computed: {
isDrawerOpen() {
return this.$store.state.docs.isDrawerOpen;
categories: {
get() {
return this.$store.getters["docs/getCategories"]
}
},
isDrawerOpen2() {
return this.$store.getters.drawerState;
toolbarTitle: {
get() {
if (this.active_category) {
return this.active_category.title
}
return "NoSQLBench Docs"
}
},
// markdown_body: {
// get() {
// return this.$store.getters["docs/getActiveMarkdownContent"]
// }
// },
active_category: {
get() {
return this.$store.getters["docs/getActiveCategory"]
},
async set(val) {
await this.$store.dispatch("docs/setCategories", val)
}
},
active_topic: {
get() {
return this.$store.getters["docs/getActiveTopic"]
},
async set(val) {
await this.$store.dispatch("docs/setActiveTopic")
}
}
},
async asyncData({params, route, store}) {
await store.dispatch("docs/loadCategories")
let categories = await store.getters["docs/getCategories"]
let active_category =docpaths.getCategory(route,categories);
let active_topic = docpaths.getTopic(route,categories, active_category);
return {
active_category,
active_topic,
markdown_body: active_topic.content
}
},
methods: {
toggleDrawer() {
this.$store.commit('docs/toggleDrawerState');
}
},
data(context) {
console.log("data context.params:" + JSON.stringify(context.params));
console.log("data context.route:" + JSON.stringify(context.route));
console.log("data context.query:" + JSON.stringify(context.query));
return {
testdata: this.$store.state.docs.example,
categories_list: [],
markdown_body: '',
active_topic: null,
active_category: null,
options: function () {
return {
markdownIt: {
linkify: true
},
linkAttributes: {
attrs: {
target: '_blank',
rel: 'noopener'
}
}
}
}
async toggleDrawer() {
await this.$store.dispatch("docs/setIsDrawerOpen", this.$store.getters["docs/getIsDrawerOpen"])
},
menuChanged(evt) {
console.log("menu changed:" + JSON.stringify(evt, null, 2))
this.$forceUpdate()
}
}
}
</script>
<style>
.container {
margin: 0 auto;
min-height: 60vh;
display: flex;
justify-content: flex-start;
align-items: flex-start;
text-align: start;
margin-left: 15px;
margin: 0 auto 0 15px;
}
.title {

View File

@@ -1,126 +0,0 @@
<template>
<v-app>
<docs-menu v-model="isDrawerOpen"
:categories="categories"
:active_category="active_category"
:active_topic="active_topic"/>
<v-app-bar app dark color="secondary">
<v-app-bar-nav-icon color="primary" @click.stop="toggleDrawer"/>
<v-toolbar-title>NoSQLBench Docs</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>
</v-toolbar-items>
</v-app-bar>
<v-main>
<v-container>
<v-row>
<div>{{testdata}}</div>
<div class="Doc">
<div class="doc-title">
<h1></h1>
</div>
<div>
<markdown-vue class="md-body content" :mdcontent="markdown_body"/>
</div>
</div>
</v-row>
</v-container>
</v-main>
<v-footer app dark color="secondary">
<span>&copy; 2020</span>
</v-footer>
</v-app>
</template>
<script>
import get_data from '~/mixins/get_data.js';
import DocsMenu from '~/components/DocsMenu.vue'
import MarkdownVue from "~/components/MarkdownVue";
export default {
mixins: [get_data],
components: {
DocsMenu, MarkdownVue
},
computed: {
isDrawerOpen() {
return this.$store.state.docs.isDrawerOpen;
},
isDrawerOpen2() {
return this.$store.getters.drawerState;
}
},
methods: {
toggleDrawer() {
this.$store.commit('docs/toggleDrawerState');
}
},
data(context) {
console.log("data context.params:" + JSON.stringify(context.params));
console.log("data context.route:" + JSON.stringify(context.route));
console.log("data context.query:" + JSON.stringify(context.query));
return {
testdata: this.$store.state.docs.example,
categories_list: [],
markdown_body: '',
active_topic: null,
active_category: null,
options: function () {
return {
markdownIt: {
linkify: true
},
linkAttributes: {
attrs: {
target: '_blank',
rel: 'noopener'
}
}
}
}
}
}
}
</script>
<style>
.container {
margin: 0 auto;
min-height: 60vh;
display: flex;
justify-content: flex-start;
align-items: center;
text-align: center;
margin-left: 15px;
}
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
.links {
padding-top: 15px;
}
</style>

View File

@@ -1,9 +1,9 @@
<template>
<v-app>
<v-main>
<div>
<v-list v-model="namespaces">
<v-list-item v-for="(namespace,idx) in namespaces" :key="idx" :title="namespace.namespace">
<div display="inline">ns:{{namespace.namespace + ": " + namespace.show}}</div>
<div>ns:{{namespace.namespace + ": " + namespace.show}}</div>
<v-list-item-title>{{namespace.namespace}}</v-list-item-title>
<v-switch v-model="namespace.show"></v-switch>
<!-- <v-list-item-action>-->
@@ -28,11 +28,11 @@
<!-- <v-list-item><v-label :v-bind="ns"/></v-list-item>-->
<!-- {{ns}}-->
<!-- </v-list>-->
</v-app>
</v-main>
</template>
<script>
import get_namespaces from '~/mixins/get_namespaces.js';
import get_namespaces from '@/mixins/get_namespaces.js';
export default {
name: "namespaces",

View File

@@ -25,34 +25,34 @@
</script>
<style>
.container {
margin: 0 auto;
min-height: 60vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
/*.container {*/
/* margin: 0 auto;*/
/* min-height: 60vh;*/
/* display: flex;*/
/* justify-content: center;*/
/* align-items: center;*/
/* text-align: center;*/
/*}*/
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
/*.title {*/
/* font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,*/
/* 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;*/
/* display: block;*/
/* font-weight: 300;*/
/* font-size: 100px;*/
/* color: #35495e;*/
/* letter-spacing: 1px;*/
/*}*/
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
/*.subtitle {*/
/* font-weight: 300;*/
/* font-size: 42px;*/
/* color: #526488;*/
/* word-spacing: 5px;*/
/* padding-bottom: 15px;*/
/*}*/
.links {
padding-top: 15px;
}
/*.links {*/
/* padding-top: 15px;*/
/*}*/
</style>

View File

@@ -1,300 +1,319 @@
<template>
<v-app>
<v-app-bar app dark color="secondary">
<v-toolbar-title>NoSQLBench - Worlkoad Generator</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<app-selector></app-selector>
<workspace-selector></workspace-selector>
<v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>
</v-toolbar-items>
</v-app-bar>
<main-app-bar>NoSQLBench - Workload Builder</main-app-bar>
<v-layout
justify-center
align-center>
justify-center
align-center>
<v-main>
<v-main>
<v-container fluid>
<v-layout row>
<v-flex>
<v-card>
<v-card-title>
Workload details
</v-card-title>
<v-col
cols="12"
sm="6"
md="10"
lg="10"
>
<v-text-field
outlined
label="Workload name"
v-model="workloadName"
></v-text-field>
<v-layout row>
<v-flex>
<v-card>
<v-card-title>
Workload details
</v-card-title>
<v-col
cols="12"
sm="6"
md="10"
lg="10"
>
<v-text-field
outlined
label="Workload name"
v-model="workloadName"
></v-text-field>
<v-textarea
outlined
label="Create Table Statement"
v-model="createTableDef"
v-on:blur="parseStatement()"
></v-textarea>
<v-textarea
outlined
label="Create Table Statement"
v-model="createTableDef"
v-on:blur="parseStatement()"
></v-textarea>
</v-col>
</v-col>
<v-col cols="12">
</v-col>
</v-card>
</v-flex>
<v-col cols="12">
<v-btn :title="save_title" v-if="parseSuccess" v-on:click="saveWorkloadToWorkspace()">{{ save_button }}</v-btn>
<v-btn :title="dl_title" v-if="parseSuccess" v-on:click="downloadWorkload()">{{ dl_button }}</v-btn>
</v-col>
</v-card>
</v-flex>
</v-layout>
</v-layout>
</v-container>
</v-main>
</v-main>
</v-layout>
<v-footer app dark color="secondary">
<span>&copy; 2020</span>
</v-footer>
<v-footer app>
<span>&copy; 2020</span>
</v-footer>
</v-app>
</template>
<script>
import get_data from '~/mixins/get_data.js';
import antlr4 from "antlr4";
import { saveAs } from "file-saver";
import yamlDumper from "js-yaml";
import CQL3Parser from '~/antlr/CQL3Parser.js';
import CQL3Lexer from '~/antlr/CQL3Lexer.js';
import defaultYaml from '~/assets/default.yaml';
import basictypes from '~/assets/basictypes.yaml';
import WorkspaceSelector from "~/components/WorkspaceSelector";
import AppSelector from "@/components/AppSelector";
import antlr4 from "antlr4";
import {saveAs} from "file-saver";
import yamlDumper from "js-yaml";
import CQL3Parser from '@/antlr/CQL3Parser.js';
import CQL3Lexer from '@/antlr/CQL3Lexer.js';
import defaultYaml from '~/assets/default.yaml';
import basictypes from '@/assets/basictypes.yaml';
import WorkspaceSelector from "~/components/WorkspaceSelector";
import AppSelector from "@/components/AppSelector";
import MainAppBar from "@/components/MainAppBar";
export default {
mixins: [get_data],
components: {
AppSelector,
WorkspaceSelector
},
computed: {
},
methods: {
async parseStatement() {
console.log(this.$data.createTableDef);
export default {
components: {
MainAppBar,
AppSelector,
WorkspaceSelector
},
data(context) {
let data = {
enabled: false,
createTableDef: "",
workloadName: "",
parseSuccess: false,
blob: null,
};
return data;
},
computed: {
save_button: function () {
return "Save to workspace '" + this.$store.getters["workspaces/getWorkspace"] + "'";
},
dl_button: function () {
return "Download as " + this.filename;
},
dl_title: function () {
return "Click to download the workload as '" + this.filename + "'";
},
filename: function () {
return this.workloadName + ".yaml";
},
save_title: function () {
return "Click to save this workload in the '" + this.workspace + "' workspace, or change the workspace in the app bar first.\n"
},
workspace: function () {
return this.$store.getters["workspaces/getWorkspace"]
},
},
methods: {
async parseStatement() {
console.log(this.$data.createTableDef);
const input = this.$data.createTableDef;
const input = this.$data.createTableDef;
const chars = new antlr4.InputStream(input);
const lexer = new CQL3Lexer.CQL3Lexer(chars);
const chars = new antlr4.InputStream(input);
const lexer = new CQL3Lexer.CQL3Lexer(chars);
lexer.strictMode = false; // do not use js strictMode
lexer.strictMode = false; // do not use js strictMode
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new CQL3Parser.CQL3Parser(tokens);
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new CQL3Parser.CQL3Parser(tokens);
const context = parser.create_table_stmt();
const context = parser.create_table_stmt();
try {
const keyspaceName = context.table_name().keyspace_name().getChild(0).getText()
const tableName = context.table_name().table_name_noks().getChild(0).getText()
try {
const keyspaceName = context.table_name().keyspace_name().getChild(0).getText()
const tableName = context.table_name().table_name_noks().getChild(0).getText()
const columnDefinitions = context.column_definitions().column_definition();
const columnDefinitions = context.column_definitions().column_definition();
let columns = [];
let partitionKeys = [];
let clusteringKeys = [];
columnDefinitions.forEach(columnDef => {
if (columnDef.column_name() != null) {
columns.push({
"name": columnDef.column_name().getText(),
"type": columnDef.column_type().getText()
})
} else {
const primaryKeyContext = columnDef.primary_key()
if (primaryKeyContext.partition_key() != null) {
const partitionKeysContext = primaryKeyContext.partition_key().column_name();
partitionKeysContext.map((partitionKey, i) => {
const partitionKeyName = partitionKey.getText()
const col = {
"name": partitionKeyName,
"type": columns.filter(x => x.name == partitionKeyName)[0].type
}
partitionKeys.push(col)
})
}
if (primaryKeyContext.clustering_column().length != 0) {
const clusteringKeysContext = primaryKeyContext.clustering_column();
clusteringKeysContext.map((clusteringKey, i) => {
const clusteringKeyName = clusteringKey.getText()
const col = {
"name": clusteringKeyName,
"type": columns.filter(x => x.name == clusteringKeyName)[0].type
}
clusteringKeys.push(col)
})
}
}
})
columns = columns.filter(col => {
return partitionKeys.filter(pk => pk.name == col.name).length == 0 && clusteringKeys.filter(cc => cc.name == col.name).length == 0
})
const allColumns = [].concat(columns,partitionKeys, clusteringKeys)
this.$data.tableName = tableName;
this.$data.keyspaceName = keyspaceName;
this.$data.columns = columns;
this.$data.clusteringKeys = clusteringKeys;
this.$data.partitionKeys = partitionKeys;
this.$data.allColumns = allColumns;
console.log(this.$data)
console.log(defaultYaml)
// schema and bindings
let createTableStatement = "CREATE TABLE IF NOT EXISTS <<keyspace:"+keyspaceName+">>."+tableName +" (\n";
console.log(basictypes)
defaultYaml.bindings = {}
allColumns.forEach(column => {
let recipe = basictypes.bindings[column.type+"val"];
if (recipe == undefined){
const chars = new antlr4.InputStream(column.type);
const lexer = new CQL3Lexer.CQL3Lexer(chars);
lexer.strictMode = false; // do not use js strictMode
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new CQL3Parser.CQL3Parser(tokens);
const typeContext = parser.column_type();
const collectionTypeContext = typeContext.data_type().collection_type();
const collectionType = collectionTypeContext.children[0].getText();
if (collectionType.toLowerCase() == "set"){
const type = collectionTypeContext.children[2].getText();
recipe = "Set(HashRange(1,<<set-count-"+column.name+":5>>),"+basictypes.bindings[type+"val"]+") -> java.util.Set"
}
else if (collectionType.toLowerCase() == "list"){
const type = collectionTypeContext.children[2].getText();
recipe = "List(HashRange(1,<<list-count-"+column.name+":5>>),"+basictypes.bindings[type+"val"]+") -> java.util.List"
}
else if (collectionType.toLowerCase() == "map"){
const type1 = collectionTypeContext.children[2].getText();
const type2 = collectionTypeContext.children[4].getText();
recipe = "Map(HashRange(1,<<map-count-"+column.name+":5>>),"+basictypes.bindings[type1+"val"]+","+basictypes.bindings[type2+"val"]+") -> java.util.Map"
}
else{
alert("Could not generate recipe for type: " + column.type + " for column: " + column.name)
}
}
defaultYaml.bindings[column.name] = recipe
createTableStatement = createTableStatement+ column.name+ " " + column.type + ",\n";
})
let pk = "PRIMARY KEY (("
pk = pk +partitionKeys.map(x => x.name).reduce((x, acc)=> acc= acc+","+x)
pk = pk + ")"
if (clusteringKeys.length > 0){
pk = pk + ","+ clusteringKeys.map(x => x.name).reduce((x, acc)=> acc= acc+","+x)
}
pk = pk + ")"
createTableStatement = createTableStatement+pk+"\n);"
defaultYaml.blocks[0].statements[0] = {"create-table": createTableStatement}
//rampup
let insertStatement= "INSERT INTO <<keyspace:"+keyspaceName+">>."+tableName +" (\n";
insertStatement = insertStatement + allColumns.map(x => x.name).reduce((x, acc)=> acc = acc+",\n"+x) + "\n) VALUES (\n";
insertStatement = insertStatement + allColumns.map(x => "{"+x.name+"}").reduce((x, acc)=> acc = acc+",\n"+x) +"\n);"
defaultYaml.blocks[1].statements[0] = {"insert-rampup": insertStatement}
//main-write
defaultYaml.blocks[2].statements[0] = {"insert-main": insertStatement}
//main-read-partition
let readPartitionStatement= "SELECT * from <<keyspace:"+keyspaceName+">>."+tableName +" WHERE ";
readPartitionStatement = readPartitionStatement + partitionKeys.map(x => x.name + "={" +x.name+ "}").reduce((x, acc)=> acc = acc+" AND "+x);
let readRowStatement = readPartitionStatement + ";";
if (clusteringKeys.length >0) {
readPartitionStatement = readPartitionStatement + " AND " + clusteringKeys.map(x => x.name + "={" + x.name + "}").reduce((x, acc) => acc = acc + " AND " + x);
}
readPartitionStatement = readPartitionStatement + ";";
defaultYaml.blocks[3].statements[0] = {"read-partition": readPartitionStatement}
//main-read-row
defaultYaml.blocks[4].statements[0] = {"read-row": readRowStatement}
defaultYaml.description = this.$data.workloadName
const yamlOutputText = yamlDumper.dump(defaultYaml)
var blob = new Blob([yamlOutputText], {type: "text/plain;charset=utf-8"});
saveAs(blob, this.$data.workloadName +".yaml");
}catch(e){
console.log("blur, invalid create table def")
console.log(e)
let columns = [];
let partitionKeys = [];
let clusteringKeys = [];
columnDefinitions.forEach(columnDef => {
if (columnDef.column_name() != null) {
columns.push({
"name": columnDef.column_name().getText(),
"type": columnDef.column_type().getText()
})
} else {
const primaryKeyContext = columnDef.primary_key()
if (primaryKeyContext.partition_key() != null) {
const partitionKeysContext = primaryKeyContext.partition_key().column_name();
partitionKeysContext.map((partitionKey, i) => {
const partitionKeyName = partitionKey.getText()
const col = {
"name": partitionKeyName,
"type": columns.filter(x => x.name == partitionKeyName)[0].type
}
},
},
data(context) {
let data = {
enabled: false,
createTableDef: "",
workloadName: "",
};
return data;
},
async asyncData({ $axios, store }) {
let enabled = await $axios.$get("/status")
.then(res => {
return res
})
.catch((e) => {
console.log("back-end not found");
})
return {
enabled: enabled,
partitionKeys.push(col)
})
}
},
if (primaryKeyContext.clustering_column().length != 0) {
const clusteringKeysContext = primaryKeyContext.clustering_column();
clusteringKeysContext.map((clusteringKey, i) => {
const clusteringKeyName = clusteringKey.getText()
const col = {
"name": clusteringKeyName,
"type": columns.filter(x => x.name == clusteringKeyName)[0].type
}
clusteringKeys.push(col)
})
}
}
})
columns = columns.filter(col => {
return partitionKeys.filter(pk => pk.name == col.name).length == 0 && clusteringKeys.filter(cc => cc.name == col.name).length == 0
})
const allColumns = [].concat(columns, partitionKeys, clusteringKeys)
this.$data.tableName = tableName;
this.$data.keyspaceName = keyspaceName;
this.$data.columns = columns;
this.$data.clusteringKeys = clusteringKeys;
this.$data.partitionKeys = partitionKeys;
this.$data.allColumns = allColumns;
console.log(this.$data)
console.log(defaultYaml)
// schema and bindings
let createTableStatement = "CREATE TABLE IF NOT EXISTS <<keyspace:" + keyspaceName + ">>." + tableName + " (\n";
console.log(basictypes)
defaultYaml.bindings = {}
allColumns.forEach(column => {
let recipe = basictypes.bindings[column.type + "val"];
if (recipe == undefined) {
const chars = new antlr4.InputStream(column.type);
const lexer = new CQL3Lexer.CQL3Lexer(chars);
lexer.strictMode = false; // do not use js strictMode
const tokens = new antlr4.CommonTokenStream(lexer);
const parser = new CQL3Parser.CQL3Parser(tokens);
const typeContext = parser.column_type();
const collectionTypeContext = typeContext.data_type().collection_type();
const collectionType = collectionTypeContext.children[0].getText();
if (collectionType.toLowerCase() == "set") {
const type = collectionTypeContext.children[2].getText();
recipe = "Set(HashRange(1,<<set-count-" + column.name + ":5>>)," + basictypes.bindings[type + "val"] + ") -> java.util.Set"
} else if (collectionType.toLowerCase() == "list") {
const type = collectionTypeContext.children[2].getText();
recipe = "List(HashRange(1,<<list-count-" + column.name + ":5>>)," + basictypes.bindings[type + "val"] + ") -> java.util.List"
} else if (collectionType.toLowerCase() == "map") {
const type1 = collectionTypeContext.children[2].getText();
const type2 = collectionTypeContext.children[4].getText();
recipe = "Map(HashRange(1,<<map-count-" + column.name + ":5>>)," + basictypes.bindings[type1 + "val"] + "," + basictypes.bindings[type2 + "val"] + ") -> java.util.Map"
} else {
alert("Could not generate recipe for type: " + column.type + " for column: " + column.name)
}
}
defaultYaml.bindings[column.name] = recipe
createTableStatement = createTableStatement + column.name + " " + column.type + ",\n";
})
let pk = "PRIMARY KEY (("
pk = pk + partitionKeys.map(x => x.name).reduce((x, acc) => acc = acc + "," + x)
pk = pk + ")"
if (clusteringKeys.length > 0) {
pk = pk + "," + clusteringKeys.map(x => x.name).reduce((x, acc) => acc = acc + "," + x)
}
pk = pk + ")"
createTableStatement = createTableStatement + pk + "\n);"
defaultYaml.blocks[0].statements[0] = {"create-table": createTableStatement}
//rampup
let insertStatement = "INSERT INTO <<keyspace:" + keyspaceName + ">>." + tableName + " (\n";
insertStatement = insertStatement + allColumns.map(x => x.name).reduce((x, acc) => acc = acc + ",\n" + x) + "\n) VALUES (\n";
insertStatement = insertStatement + allColumns.map(x => "{" + x.name + "}").reduce((x, acc) => acc = acc + ",\n" + x) + "\n);"
defaultYaml.blocks[1].statements[0] = {"insert-rampup": insertStatement}
//main-write
defaultYaml.blocks[2].statements[0] = {"insert-main": insertStatement}
//main-read-partition
let readPartitionStatement = "SELECT * from <<keyspace:" + keyspaceName + ">>." + tableName + " WHERE ";
readPartitionStatement = readPartitionStatement + partitionKeys.map(x => x.name + "={" + x.name + "}").reduce((x, acc) => acc = acc + " AND " + x);
let readRowStatement = readPartitionStatement + ";";
if (clusteringKeys.length > 0) {
readPartitionStatement = readPartitionStatement + " AND " + clusteringKeys.map(x => x.name + "={" + x.name + "}").reduce((x, acc) => acc = acc + " AND " + x);
}
readPartitionStatement = readPartitionStatement + ";";
defaultYaml.blocks[3].statements[0] = {"read-partition": readPartitionStatement}
//main-read-row
defaultYaml.blocks[4].statements[0] = {"read-row": readRowStatement}
defaultYaml.description = this.$data.workloadName
const yamlOutputText = yamlDumper.dump(defaultYaml)
this.blob = new Blob([yamlOutputText], {type: "text/plain;charset=utf-8"});
this.parseSuccess = true;
} catch (e) {
console.log("blur, invalid create table def")
console.log(e)
}
},
downloadWorkload() {
saveAs(this.blob, this.$data.filename);
},
saveWorkloadToWorkspace() {
this.$store.dispatch("workspaces/putFile",{
workspace: this.workspace,
filename: this.filename,
content: this.blob
})
}
},
async asyncData({$axios, store}) {
let enabled = await $axios.$get("/status")
.then(res => {
return res
})
.catch((e) => {
console.log("back-end not found");
})
return {
enabled: enabled,
}
},
}
</script>
<style>
.container {
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
/*.container {*/
/* margin: 0 auto;*/
/* display: flex;*/
/* justify-content: center;*/
/* align-items: center;*/
/* text-align: center;*/
/*}*/
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
/*.title {*/
/* font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,*/
/* 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;*/
/* display: block;*/
/* font-weight: 300;*/
/* font-size: 100px;*/
/* color: #35495e;*/
/* letter-spacing: 1px;*/
/*}*/
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
/*.subtitle {*/
/* font-weight: 300;*/
/* font-size: 42px;*/
/* color: #526488;*/
/* word-spacing: 5px;*/
/* padding-bottom: 15px;*/
/*}*/
.links {
padding-top: 15px;
}
/*.links {*/
/* padding-top: 15px;*/
/*}*/
</style>

View File

@@ -0,0 +1,16 @@
<template>
<v-app>
<main-app-bar></main-app-bar>
</v-app>
</template>
<script>
import MainAppBar from "~/components/MainAppBar";
export default {
name: "ui-index",
components: {MainAppBar}
}
</script>
<style>
</style>

View File

@@ -1,28 +1,56 @@
<template>
<v-app>
<v-app-bar app dark color="secondary">
<v-toolbar-title>NoSQLBench</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<app-selector></app-selector>
<workspace-selector></workspace-selector>
<v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>
</v-toolbar-items>
</v-app-bar>
<v-layout
justify-center
align-center>
<main-app-bar>NoSQLBench - Workload Executor</main-app-bar>
<v-container class="d-flex justify-center">
<v-main>
<v-container fluid v-if="enabled">
<v-row fluid class="d-flex">
<v-col cols="12" fluid class="d-flex justify-space-between justify-center">
<v-btn-toggle max="1" v-model="toggle_workspaces" @change="validateAndSearch()">
<v-btn :disabled="this.toggle_builtins===undefined && this.toggle_workspaces===0">
<v-container fluid class="d-flex">
<v-icon title="'include ' + workspace">mdi-folder-star</v-icon>
<div class="ma-2">workspace '{{ workspace }}'</div>
<v-icon v-if="this.toggle_workspaces===0">mdi-check</v-icon>
</v-container>
</v-btn>
<v-btn :disabled="this.toggle_builtins===undefined && this.toggle_workspaces===1">
<v-container fluid class="d-flex">
<v-icon title="search workspaces">mdi-folder-star-multiple</v-icon>
<div class="ma-2">all workspaces</div>
<v-icon v-if="this.toggle_workspaces===1">mdi-check</v-icon>
</v-container>
</v-btn>
</v-btn-toggle>
<v-btn-toggle v-model="toggle_builtins" @change="validateAndSearch()">
<v-btn :disabled="this.toggle_workspaces===undefined">
<v-container fluid class="d-flex">
<v-icon title="include built-in workloads">mdi-folder-open</v-icon>
<div class="ma-2">bundled</div>
<v-icon v-if="this.toggle_builtins===0">mdi-check</v-icon>
</v-container>
</v-btn>
</v-btn-toggle>
</v-col>
</v-row>
<v-container fluid v-if="workloads!==undefined">
<v-select
:items="workloadNames"
:items="availableWorkloads"
item-text="description"
item-value="workloadName"
v-model="workloadName"
chips
v-on:change="getTemplates();"
v-on:change="loadTemplates();"
label="Workload"
></v-select>
@@ -41,7 +69,7 @@
<v-card>
<v-card-title>
{{ workloadName }}
{{ this.workloadName }}
</v-card-title>
<v-col
v-for="(item, j) in Object.keys(templates)"
@@ -60,7 +88,7 @@
</v-col>
<v-col cols="12">
<v-btn v-if="workloadName" v-on:click="runWorkload()">Run Workload</v-btn>
<v-btn :title="runtitle" v-if="this.workloadName" v-on:click="runWorkload()">{{ runin }}</v-btn>
</v-col>
</v-card>
</v-col>
@@ -71,103 +99,176 @@
</v-container>
</v-main>
</v-layout>
</v-container>
<v-footer app dark color="secondary">
<v-footer app>
<span>&copy; 2020</span>
</v-footer>
</v-app>
</template>
<script>
import get_data from '~/mixins/get_data.js';
import WorkspaceSelector from "~/components/WorkspaceSelector";
import WorkspaceSelector from "@/components/WorkspaceSelector";
import AppSelector from "@/components/AppSelector";
import MainAppBar from "@/components/MainAppBar";
export default {
name: 'app-run',
mixins: [get_data],
components: {
AppSelector,
WorkspaceSelector
},
computed: {},
methods: {
async getTemplates() {
const data = await this.$axios.$get('/workloads/parameters?workloadName=' + this.workloadName)
if (!data.err) {
this.$data.templates = data;
}
},
WorkspaceSelector,
MainAppBar
},
data(context) {
let data = {
workloadNames: [],
availableWorkloads: [],
enabled: false,
workloadName: null,
templates: null,
toggle_builtins: 0,
toggle_workspaces: 0,
workspace_names: ['current', 'all'],
sample: {
"workspace": "default",
"yamlPath": "test1.yaml",
"scenarioNames": [
"default",
"main"
],
"templates": {
"keyspace": "a",
"main-cycles": "10000000",
"rampup-cycles": "10000000",
"read_cl": "LOCAL_QUORUM",
"read_partition_ratio": "1",
"read_row_ratio": "1",
"write_cl": "LOCAL_QUORUM",
"write_ratio": "1"
},
"description": "test1",
"workloadName": "test1"
},
};
return data;
},
async asyncData({$axios, store}) {
let enabled = await $axios.$get("/status")
.then(res => {
return res
computed: {
searchin: function () {
let searchin = Array();
if (this.toggle_workspaces === 0) {
searchin.push(this.workspace);
} else if (this.toggle_workspaces === 1) {
console.log("workspaces typeof: '" + typeof (this.workspaces) + "'");
this.workspaces.forEach(w => {
searchin.push(w.name);
})
.catch((e) => {
console.log("back-end not found");
})
let workloadNames = await $axios.$get("/workloads")
.then(res => {
return res
})
.catch((e) => {
console.log("back-end not found");
})
let workspaces = await $axios.$get("/workspaces")
.then(res => {
return res
}).catch((e) => {
console.log("back-end not found")
});
return {
enabled: enabled,
workloadNames: workloadNames,
workspaces: workspaces
}
if (this.toggle_builtins === 0) {
searchin.push("builtins");
}
let joined = searchin.join(",");
console.log("joined:'" + joined + "'")
return joined;
},
runin: function () {
return "Run Workload in " + this.$store.getters["workspaces/getWorkspace"];
},
runtitle: function () {
return "Click to run this workload in the '" + this.workspace + "' workspace, or change the workspace in the app bar.\n"
},
workspace: function () {
return this.$store.getters["workspaces/getWorkspace"]
},
workspaces: function () {
return this.$store.getters["workspaces/getWorkspaces"]
},
workloads: function () {
return this.$store.getters["workloads/getWorkloads"];
},
templates: function () {
return this.$store.getters["workloads/getTemplates"];
},
workloadNames: function () {
for (const [key, value] of Object.entries(this.workloads)) {
console.log("key=[" + key + "] value=[" + value + "]");
}
}
},
watch: {
toggle_builtins: function (val) {
this.validateAndSearch();
},
toggle_workspaces: function (val) {
this.validateAndSearch();
}
},
created() {
this.validateAndSearch();
this.$store.subscribe((mutation, state) => {
console.log("mutation type " + mutation.type);
if (mutation.type === 'workloads/setWorkloads') {
console.log("detected update to workloads:" + JSON.stringify(this.workloads));
this.availableWorkloads = state.workloads.workloads;
}
});
},
methods: {
validateAndSearch() {
let params = {
searchin: this.searchin,
reason: "search params changed"
}
this.$store.dispatch("workloads/fetchWorkloads", params);
},
loadTemplates() {
let params = {
workload: this.workloadName,
searchin: this.searchin,
reason: "workload selected"
}
this.$store.dispatch("workloads/fetchTemplates", params);
},
runWorkload() {
console.log("running workload...")
let workload = this.availableWorkloads.filter(w => w.workloadName===this.workloadName);
let erq = {
name: "run_"+workload.workloadName,
workspace: this.workspace,
commands: [this.workloadName]
}
console.log("submitting:" + JSON.stringify(erq));
this.$axios.$post("services/executor/cli",erq);
}
}
}
</script>
<style>
.container {
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
/*.container {*/
/* margin: 0 auto;*/
/* display: flex;*/
/* justify-content: center;*/
/* align-items: center;*/
/* text-align: center;*/
/*}*/
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
/*.title {*/
/* font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,*/
/* 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;*/
/* display: block;*/
/* font-weight: 300;*/
/* font-size: 100px;*/
/* color: #35495e;*/
/* letter-spacing: 1px;*/
/*}*/
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
/*.subtitle {*/
/* font-weight: 300;*/
/* font-size: 42px;*/
/* color: #526488;*/
/* word-spacing: 5px;*/
/* padding-bottom: 15px;*/
/*}*/
.links {
padding-top: 15px;
}
/*.links {*/
/* padding-top: 15px;*/
/*}*/
</style>

View File

@@ -1,14 +1,6 @@
<template>
<v-app>
<v-app-bar app dark color="secondary">
<v-toolbar-title>NoSQLBench - Scenario Status</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<app-selector></app-selector>
<workspace-selector></workspace-selector>
<v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>
</v-toolbar-items>
</v-app-bar>
<main-app-bar>NoSQLBench - Execution Status</main-app-bar>
<!--
{
@@ -30,11 +22,11 @@
<v-card min-width="300" max-width="300" max-height="400" raised elevation="5"
v-for="(invocation,w) in invocations" :key="w"
class="pa-4 ma-4" :loading="is_loading(invocation)">
<v-row>
<v-row :title="JSON.stringify(invocation)">
<v-card-title title="running scenario name">{{ invocation.scenario_name }}</v-card-title>
<!-- <v-icon v-if="workspace === cardspace.name">mdi-check-bold</v-icon>-->
</v-row>
<v-card-subtitle :title="sdf">sdf</v-card-subtitle>
<v-card-subtitle title="title">sdf</v-card-subtitle>
<v-card-subtitle title="started at">{{invocation.started_at}}</v-card-subtitle>
@@ -87,40 +79,42 @@
<script>
import WorkspaceSelector from "~/components/WorkspaceSelector";
import WorkspaceSelector from "@/components/WorkspaceSelector";
import {mapActions, mapGetters, mapMutations} from "vuex";
import AppSelector from "@/components/AppSelector";
import MainAppBar from "@/components/MainAppBar";
export default {
name: "workspaces.vue",
components: {
MainAppBar,
AppSelector,
WorkspaceSelector
},
data(context) {
let data = {
invocations: [
{
"scenario_name": "mytestscenario",
"progress": [
{
"name": "/tmp/nosqlbench/mytestscenario3888869514662003808file1.yaml",
"state": "Running",
"details": "min=0 cycle=1692 max=10000000",
"completed": 1.692E-4
}
],
"started_at": 1597749369800,
"ended_at": -1,
"activity_states": [
{
"completion": "1.692E-4",
"name": "/tmp/nosqlbench/mytestscenario3888869514662003808file1.yaml",
"state": "Running"
}
]
}
]
// invocations: [
// {
// "scenario_name": "mytestscenario",
// "progress": [
// {
// "name": "/tmp/nosqlbench/mytestscenario3888869514662003808file1.yaml",
// "state": "Running",
// "details": "min=0 cycle=1692 max=10000000",
// "completed": 1.692E-4
// }
// ],
// "started_at": 1597749369800,
// "ended_at": -1,
// "activity_states": [
// {
// "completion": "1.692E-4",
// "name": "/tmp/nosqlbench/mytestscenario3888869514662003808file1.yaml",
// "state": "Running"
// }
// ]
// }
// ]
};
return data;
},
@@ -140,14 +134,13 @@ export default {
return name;
}
},
// created() {
// console.log("created component...");
// this.$store.dispatch("invocations/loadInvocations", "status panel load");
// }
created() {
console.log("created component...");
this.$store.dispatch("invocations/loadInvocations", "watch panel load");
}
}
</script>
<style scoped>
<style>
</style>

View File

@@ -1,45 +1,24 @@
<template>
<v-app>
<v-app-bar app dark color="secondary">
<v-toolbar-title>NoSQLBench - Workspaces</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<app-selector></app-selector>
<workspace-selector></workspace-selector>
<!-- <workspace-selector @changed="seenChange(workspace)"></workspace-selector>-->
<main-app-bar></main-app-bar>
<!-- <v-btn title="start a new workspace" @click="startNewWorkspace()">-->
<!-- <v-icon>mdi-folder-plus-outline</v-icon>-->
<!-- </v-btn>-->
<v-btn title="upload a workspace zip file">
<v-icon>mdi-folder-upload</v-icon>
</v-btn>
<v-btn title="download workspaces.zip">
<v-icon>mdi-briefcase-download</v-icon>
</v-btn>
<v-btn title="upload workspaces.zip">
<v-icon>mdi-briefcase-upload</v-icon>
</v-btn>
<!-- <v-btn text href="https://github.com/nosqlbench/nosqlbench/wiki/Submitting-Feedback">SUBMIT FEEDBACK</v-btn>-->
</v-toolbar-items>
</v-app-bar>
<!-- <workspace-selector @changed="seenChange(workspace)"></workspace-selector>-->
<!--
{
"summary": {
"total_bytes": 24,
"total_files": 1,
"last_change": 1597293397043,
"last_file_changed": "README.md"
},
"name": "default",
"modified": 1597293397043,
"changed": "README.md (1H17M27S ago)"
}
]
-->
<!-- <v-btn title="start a new workspace" @click="startNewWorkspace()">-->
<!-- <v-icon>mdi-folder-plus-outline</v-icon>-->
<!-- </v-btn>-->
<v-main justify-start align-start class="d-inline-block pa-4 ma-10">
<!-- <v-btn icon title="upload a workspace zip file">-->
<!-- <v-icon>mdi-folder-upload</v-icon>-->
<!-- </v-btn>-->
<!-- <v-btn icon title="download workspaces.zip">-->
<!-- <v-icon>mdi-briefcase-download</v-icon>-->
<!-- </v-btn>-->
<!-- <v-btn icon title="upload workspaces.zip">-->
<!-- <v-icon>mdi-briefcase-upload</v-icon>-->
<!-- </v-btn>-->
<v-content justify-start align-start class="d-inline-block pa-4 ma-10">
<div class="row no-gutters">
<v-card min-width="300" max-width="300" max-height="400" raised elevation="5" v-for="(cardspace,w) in workspaces" :key="w"
class="pa-4 ma-4">
@@ -70,10 +49,6 @@
<v-icon>mdi-magnify</v-icon>
</v-btn>
<!-- <v-btn title="use this workspace">-->
<!-- <v-icon>mdi-play</v-icon>-->
<!-- </v-btn>-->
<v-spacer></v-spacer>
<v-btn title="download zipped workspace">
@@ -90,7 +65,7 @@
</v-list>
</v-card>
</div>
</v-main>
</v-content>
</v-app>
</template>
@@ -100,22 +75,17 @@
import WorkspaceSelector from "~/components/WorkspaceSelector";
import {mapActions, mapGetters, mapMutations} from "vuex";
import AppSelector from "@/components/AppSelector";
import MainAppBar from "@/components/MainAppBar";
export default {
name: "workspaces.vue",
components: {
MainAppBar,
AppSelector,
WorkspaceSelector
},
data(context) {
let data = {
// workspace: this.$store.state.workspaces.workspace,
// workspaces: [
// {
// "name": "test"
// }
// ]
};
let data = {};
return data;
},
computed: {
@@ -135,54 +105,25 @@ export default {
this.$store.dispatch("workspaces/setWorkspaces", val)
}
},
// workspace: {
// get: function () {
// return this.$store.getters.workspaces.workspace;
// },
// set: function (val) {
// return this.$store.dispatch('workspaces/getWorkspace')
// }
// },
// workspaces: {
// get: function () {
// return this.$store.getters.workspaces.workspaces;
// },
// set: function (val) {
// return this.$store.dispatch('workspaces/getWorkspaces');
// }
// }
},
methods: {
// ...mapActions({
// workspaces: "workspaces/setWorkspaces",
// // workspace: "workspaces/setWorkspace"
// }),
abbrev(name) {
return name;
},
purgeWorkspace: function (ws) {
console.log("purging " + ws);
this.$store.dispatch('workspaces/purgeWorkspace', ws);
// this.$store.dispatch("workspaces/setWorkspace")
this.$forceUpdate();
},
},
created() {
console.log("created component...");
// this.$store.subscribe((mutation, state) => {
// console.log("mutation type " + mutation.type);
// if (mutation.type === 'workspaces/setWorkspace') {
// this.workspace = this.$store.state.workspaces.workspace;
// } else if (mutation.type === 'workspaces/setWorkspaces') {
// this.workspacaes = this.$store.state.workspaces.workspaces;
// } else {
// console.error("Unrecognized mutation", mutation)
// }
// })
this.$store.dispatch('workspaces/initWorkspaces', "workspace panel load");
}
}
</script>
<style scoped>
<style>
</style>