flesh out frontend to have a front page

This commit is contained in:
Chris Sexton 2019-11-03 15:01:13 -05:00
parent 9b4e482e3a
commit f7dfee399e
16 changed files with 276 additions and 52 deletions

1
entry/entry.go Normal file
View File

@ -0,0 +1 @@
package entry

View File

@ -10,12 +10,13 @@
"dependencies": { "dependencies": {
"bootstrap": "^4.3.1", "bootstrap": "^4.3.1",
"bootstrap-vue": "^2.0.4", "bootstrap-vue": "^2.0.4",
"brace": "latest",
"core-js": "^3.3.2", "core-js": "^3.3.2",
"lodash": "^4.17.15",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vue2-ace-editor": "^0.0.15", "vue2-ace-editor": "^0.0.15",
"vuex": "^3.0.1", "vuex": "^3.0.1"
"brace": "latest"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.0.0", "@vue/cli-plugin-babel": "^4.0.0",

View File

@ -8,6 +8,7 @@
<b-nav-item to="/about">About</b-nav-item> <b-nav-item to="/about">About</b-nav-item>
</b-navbar-nav> </b-navbar-nav>
</b-navbar> </b-navbar>
<Error/>
<router-view/> <router-view/>
</div> </div>
</template> </template>
@ -33,3 +34,14 @@
color: #42b983; color: #42b983;
} }
</style> </style>
<script>
import Error from "./components/Error";
export default {
name: 'app',
components: {
Error
}
}
</script>

View File

@ -0,0 +1,25 @@
<template>
<div>
<b-alert
v-for="(e, i) in errs"
v-bind:key="i"
variant="danger"
dismissible
show="true"
v-show="errs.length > 0">{{e}}</b-alert>
</div>
</template>
<script>
import {mapState} from 'vuex';
export default {
name: "Error",
computed: mapState({
errs: state => state.errs
}),
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,74 @@
<template>
<div :hidden="!content">
<b-container fluid>
<b-row>
<b-col>
<Viewer :content="content" />
</b-col>
</b-row>
<b-row>
<b-col cols="10">
<label for="tagList" >Tags</label>
</b-col>
</b-row>
<b-row>
<b-col cols="10">
<TagList id="tagList" :tags="tags" :readOnly="true" />
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import Viewer from "./Viewer";
import TagList from "./TagList";
export default {
name: "MainView",
props: {
slug: String
},
created() {
if (this.$props.slug) {
this.getFile(this.$props.slug)
}
},
data: function () {
return {
file: ''
}
},
computed: {
tags: function() {
if (this.file) {
return this.file.tags
}
return []
},
content: function () {
if (this.file) {
return this.file.contents
}
return null
}
},
watch: {
slug: function (newValue) {
this.getFile(newValue)
}
},
methods: {
getFile: function(slug) {
this.$store.dispatch('getFile', slug)
.then(file => {
this.file = file
})
}
},
components: {TagList, Viewer}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,54 @@
<template>
<b-container fluid>
<b-row>
<b-input placeholder="Search" @update="runQuery" v-model="query" />
</b-row>
<b-row v-for="item in results" v-bind:key="item.id">
<b-col>
<b-link
:to="{ name: target, params: { slug: item.slug } }"
>{{item.title}}</b-link>
</b-col>
</b-row>
</b-container>
</template>
<script>
const _ = require('lodash');
export default {
name: "SearchResults",
data: function() {
return {
results: []
}
},
props: {
target: String,
query: String
},
created() {
this.getResults()
this.runQuery = _.debounce(this.runQuery, 1000)
},
methods: {
getResults: function () {
this.$store.dispatch('getSearchResults')
.catch(res => {
this.$store.commit('addError', res.message);
})
.then(res => {
this.results = res
})
},
runQuery: function() {
this.$store.dispatch('getSearchResults', this.query)
.catch(res => {
this.$store.commit('addError', res.message);
})
.then(res => {
this.results = res
})
}
}
}
</script>

View File

@ -1,35 +0,0 @@
<template>
<b-container fluid>
<b-row v-for="item in results" v-bind:key="item.id">
<b-col>
<b-link
:to="{ name: 'console-slug', params: { slug: item.slug } }"
>{{item.title}}</b-link>
</b-col>
</b-row>
</b-container>
</template>
<script>
export default {
name: "SearchResults",
data: function() {
return {
results: []
}
},
created() {
this.getResults()
},
methods: {
getResults: function () {
console.log('getResults')
this.$store.dispatch('getSearchResults')
.then(res => {
console.log('then'+res)
this.results = res
})
}
}
}
</script>

View File

@ -1,12 +1,20 @@
<template> <template>
<b-input type="text" placeholder="tags" :value="tagString"/> <div>
<b-input type="text" placeholder="tags" :value="tagString" :hidden="readOnly"/>
<div :hidden="!readOnly">
<b-badge pill v-for="(tag, idx) in tags" v-bind:key="idx" class="tag">
{{tag}}
</b-badge>
</div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "TagList", name: "TagList",
props: { props: {
tags: Array tags: Array,
readOnly: Boolean
}, },
computed: { computed: {
tagString: function() { tagString: function() {
@ -17,5 +25,7 @@
</script> </script>
<style scoped> <style scoped>
.tag {
margin-right: 0.5em;
}
</style> </style>

View File

@ -0,0 +1,20 @@
<template>
<div>
<pre>
{{content}}
</pre>
</div>
</template>
<script>
export default {
name: "Viewer",
props: {
content: String
}
}
</script>
<style scoped>
</style>

View File

@ -11,6 +11,21 @@ const routes = [
name: 'home', name: 'home',
component: Home component: Home
}, },
{
path: '/view/:slug',
name: 'home-slug',
component: Home
},
{
path: '/search/:query',
name: 'home-search',
component: Home
},
{
path: '/console/search/:query',
name: 'console-search',
component: Console
},
{ {
path: '/console/:slug', path: '/console/:slug',
name: 'console-slug', name: 'console-slug',

View File

@ -1,5 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import _ from 'lodash'
Vue.use(Vuex) Vue.use(Vuex)
@ -18,8 +19,15 @@ var files = {
export default new Vuex.Store({ export default new Vuex.Store({
state: { state: {
errs: []
}, },
mutations: { mutations: {
clearError(state) {
state.errs = []
},
addError(state, err) {
state.errs.push(err)
}
}, },
actions: { actions: {
getFile: function(_, slug) { getFile: function(_, slug) {
@ -28,9 +36,15 @@ export default new Vuex.Store({
setTimeout(() => resolve(files[slug]), getRandomInt(0, 1000)) setTimeout(() => resolve(files[slug]), getRandomInt(0, 1000))
}) })
}, },
getSearchResults: function () { getSearchResults: function (state, query) {
console.log('getSearchResults: '+query)
let values = Object.values(files)
if (query)
values = _.filter(values, (o) => {
return o.title.indexOf(query) != -1
})
return new Promise(function (resolve) { return new Promise(function (resolve) {
setTimeout(() => resolve(Object.values(files)), getRandomInt(0, 1000)) setTimeout(() => resolve(values, getRandomInt(0, 1000)))
}) })
} }
}, },

View File

@ -16,7 +16,7 @@
</b-col> </b-col>
<b-col md="2"> <b-col md="2">
<h2>Search Results</h2> <h2>Search Results</h2>
<SearchResults /> <SearchResults target="console-slug" />
</b-col> </b-col>
</b-row> </b-row>
</b-container> </b-container>
@ -26,7 +26,7 @@
// @ is an alias to /src // @ is an alias to /src
import MainEditor from "../components/MainEditor"; import MainEditor from "../components/MainEditor";
import ScratchPad from "../components/ScratchPad"; import ScratchPad from "../components/ScratchPad";
import SearchResults from "../components/SearchResults"; import SearchResults from "../components/Search";
export default { export default {
name: 'home', name: 'home',

View File

@ -1,18 +1,35 @@
<template> <template>
<div class="home"> <b-container fluid>
<img alt="Vue logo" src="../assets/logo.png"> <b-row><b-col>
<HelloWorld msg="Welcome to Your Vue.js App"/> <h1>Home</h1>
</div> </b-col></b-row>
<b-row>
<b-col md="2">
<SearchResults target="home-slug" :query="$route.params.query" />
</b-col>
<b-col>
<MainView :slug="$route.params.slug" />
</b-col>
</b-row>
</b-container>
</template> </template>
<script> <script>
// @ is an alias to /src import SearchResults from '../components/Search.vue'
import HelloWorld from '@/components/HelloWorld.vue' import MainView from '../components/MainView.vue'
export default { export default {
name: 'home', name: 'home',
components: { components: {
HelloWorld SearchResults,
MainView
} }
} }
</script> </script>
<style scoped>
h2 {
font-size: large;
}
</style>

View File

@ -1641,7 +1641,7 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0" balanced-match "^1.0.0"
concat-map "0.0.1" concat-map "0.0.1"
brace@^0.11.0: brace@^0.11.0, brace@latest:
version "0.11.1" version "0.11.1"
resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58" resolved "https://registry.yarnpkg.com/brace/-/brace-0.11.1.tgz#4896fcc9d544eef45f4bb7660db320d3b379fe58"
integrity sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg= integrity sha1-SJb8ydVE7vRfS7dmDbMg07N5/lg=

15
web/entry.go Normal file
View File

@ -0,0 +1,15 @@
package web
import "net/http"
func editFile(w http.ResponseWriter, r *http.Request) {
}
func newFile(w http.ResponseWriter, r *http.Request) {
}
func getFile(w http.ResponseWriter, r *http.Request) {
}

1
web/search.go Normal file
View File

@ -0,0 +1 @@
package web