turn more things into components

This commit is contained in:
Evert Prants 2017-12-06 20:16:28 +02:00
parent 04e0c77a46
commit efeca0d5bd
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
10 changed files with 254 additions and 89 deletions

9
package-lock.json generated
View File

@ -6148,6 +6148,15 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.5.9.tgz", "resolved": "https://registry.npmjs.org/vue/-/vue-2.5.9.tgz",
"integrity": "sha512-9B9XBpCtj8y5eJFrspIcKxIWt+lG9FMdF8qgyOlUeOIvcS4xSAvcARygbzHA6Pi0KWFj4BvxjtWbuPVWRx/wuA==" "integrity": "sha512-9B9XBpCtj8y5eJFrspIcKxIWt+lG9FMdF8qgyOlUeOIvcS4xSAvcARygbzHA6Pi0KWFj4BvxjtWbuPVWRx/wuA=="
}, },
"vue-clickaway": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/vue-clickaway/-/vue-clickaway-2.1.0.tgz",
"integrity": "sha1-OS3nZHUfMc0geH6Ps6bjGYJfjU8=",
"dev": true,
"requires": {
"loose-envify": "1.3.1"
}
},
"vue-hot-reload-api": { "vue-hot-reload-api": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz", "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz",

View File

@ -68,6 +68,7 @@
"mustache": "^2.3.0", "mustache": "^2.3.0",
"standard": "^10.0.3", "standard": "^10.0.3",
"uglifyjs-webpack-plugin": "^0.4.6", "uglifyjs-webpack-plugin": "^0.4.6",
"vue-clickaway": "^2.1.0",
"vue-loader": "^13.5.0", "vue-loader": "^13.5.0",
"vue-resource": "^1.3.4", "vue-resource": "^1.3.4",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",

View File

@ -0,0 +1,31 @@
<template lang="pug">
.ban.list-item
.stamps
.noactive.stamp(title='Expired', v-if='expired')
i.fa.fa-fw.fa-ban
.info
.section
span.key User
span.value {{ user.display_name }}
.section
span.key Admin
span.value {{ admin.display_name }}
.section
span.key Reason
span.value {{ reason }}
.section
span.key Placed
span.value {{ new Date(created_at).toString() }}
.section
span.key Expires
span.value(v-if='expires_at') {{ new Date(expires_at).toString() }}
span.value(v-else='v-else')
b This ban is permanent.
.button.remove(@click='$parent.$emit("pardon", id)') Pardon
</template>
<script type="text/javascript">
export default {
props: ['expired', 'user', 'admin', 'reason', 'created_at', 'expires_at', 'email', 'id']
}
</script>

View File

@ -2,39 +2,16 @@
#banlist #banlist
h3 Bans ({{pagination.total}}) h3 Bans ({{pagination.total}})
.message.error(v-if='error') {{ error }} .message.error(v-if='error') {{ error }}
.entry(v-else='v-else') .entry(v-else)
.pgn pagination(v-bind="pagination" v-on:page="getBans")
span.pagenum Page {{ pagination.page }} of {{ pagination.pages }}
.button(v-if='pagination.page > 1', v-on:click='getBans(pagination.page - 1)') Previous
.button(v-for='n in pagination.pages', v-on:click='getBans(n)', v-bind:class='{active: n == pagination.page}') {{ n }}
.button(v-if='pagination.page < pagination.pages', v-on:click='getBans(pagination.page + 1)') Next
.list.bans .list.bans
.ban.list-item(v-for='ban in bans') ban(v-for='ban in bans' v-bind="ban")
.stamps
.noactive(title='Expired', v-if='ban.expired')
i.fa.fa-fw.fa-ban
.info
.section
span.key User
span.value {{ ban.user.display_name }}
.section
span.key Admin
span.value {{ ban.admin.display_name }}
.section
span.key Reason
span.value {{ ban.reason }}
.section
span.key Placed
span.value {{ new Date(ban.created_at).toString() }}
.section
span.key Expires
span.value(v-if='ban.expires_at') {{ new Date(ban.expires_at).toString() }}
span.value(v-else='v-else')
b This ban is permanent.
.button.remove(@click='pardon(ban.id)') Pardon
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
import Pagination from './Pagination.vue'
import Ban from './Ban.vue'
export default { export default {
data: function () { data: function () {
return { return {
@ -49,6 +26,9 @@
bans: [] bans: []
} }
}, },
components: {
Pagination, Ban
},
methods: { methods: {
getBans: function (page) { getBans: function (page) {
this.error = '' this.error = ''
@ -75,6 +55,10 @@
this.$root.$on('reload_bans', () => { this.$root.$on('reload_bans', () => {
this.getBans(1) this.getBans(1)
}) })
this.$on('pardon', (id) => {
this.pardon(id)
})
} }
} }
</script> </script>

View File

@ -0,0 +1,71 @@
<template lang="pug">
.application.list-item
.picture
img(v-if="icon" :src="'/usercontent/images/' + icon")
.noicon(v-else)
i.fa.fa-fw.fa-gears
.info
.stamps
.verified.stamp(v-if="verified")
i.fa.fa-fw.fa-check
.dropdown-wrapper.stamp(@click="dropdown = !dropdown" v-on-clickaway='away')
i.fa.fa-fw.fa-ellipsis-v
transition(name="modal")
.dropdown(v-show="dropdown")
.title Actions
.action(@click="$parent.$emit('edit', id)")
i.fa.fa-fw.fa-pencil
|&nbsp;Edit
.action(@click="$parent.$emit('delete', id)")
i.fa.fa-fw.fa-trash
|&nbsp;Delete
.name {{ title }}
.description {{ description }}
a.url(:href='url', target='_blank', rel='nofollow') {{ url }}
.section
span.key Scopes
span.value {{ scope }}
.section
span.key Redirect
span.value {{ redirect_url }}
.section
span.key Client ID
span.value {{ id }}
.section
span.key Secret
span.value Client Secret:
#showbutton(@click="secretShown = !secretShown")
span(v-show="!secretShown") Click here to reveal secret
#hiddensecret(v-show="secretShown") {{ secret }}
.section
span.key Created
span.value {{ new Date(created_at).toString() }}
.section
span.key Owner
span.value {{ user.display_name }}
</template>
<script type="text/javascript">
import { directive as onClickaway } from 'vue-clickaway'
export default {
props: ['icon', 'verified', 'title', 'description', 'url', 'scope', 'redirect_url', 'id', 'secret', 'created_at', 'user'],
data: function () {
return {
dropdown: false,
secretShown: false
}
},
directives: {
onClickaway: onClickaway,
},
methods: {
away: function () {
this.dropdown = false
}
}
}
</script>

View File

@ -1,38 +1,17 @@
<template lang="pug"> <template lang="pug">
#clientlist #clientlist
button(@click="editing = -1") New Client button(@click="editing = -1") New Client
.pgn .message.error(v-if="error") {{ error }}
span.pagenum Page {{ pagination.page }} of {{ pagination.pages }} .entry(v-else)
.button(v-if='pagination.page > 1', v-on:click='getClients(pagination.page - 1)') Previous pagination(v-bind="pagination" v-on:page="getClients")
.button(v-for='n in pagination.pages', v-on:click='getClients(n)', v-bind:class='{active: n == pagination.page}') {{ n }} .list.client
.button(v-if='pagination.page < pagination.pages', v-on:click='getClients(pagination.page + 1)') Next o-auth-client(v-for="client in clients" v-bind="client")
.list.client client-modal(:show="editing != 0" @close='editing = 0', :id='editing')
.message.error(v-if="error") {{ error }}
.application.list-item(v-else v-for="client in clients")
.picture
img(v-if="client.icon" :src="'/usercontent/images/' + client.icon")
.noicon(v-else)
i.fa.fa-fw.fa-gears
.info
.stamps
.verified(v-if="client.verified")
i.fa.fa-fw.fa-check
.name {{ client.title }}
.description {{ client.description }}
a.url(:href='client.url', target='_blank', rel='nofollow') {{ client.url }}
.scope Scopes: {{ client.scope }}
.redirect_url Redirect: {{ client.redirect_url }}
.id Client ID: {{ client.id }}
.secret
| Client Secret:
#showbutton Hover
#hiddensecret {{ client.secret }}
.button.edit(@click="editing = client.id") Edit
.button.delete(@click="deleteClient(client.id)") Delete
client-modal(:show="editing != 0" @close='editing = 0', :id='editing')
</template> </template>
<script type="text/javascript"> <script type="text/javascript">
import Pagination from './Pagination.vue'
import OAuthClient from './OAuthClient.vue'
import ClientModal from './ClientModal.vue' import ClientModal from './ClientModal.vue'
export default { export default {
@ -51,7 +30,7 @@
} }
}, },
components: { components: {
ClientModal ClientModal, Pagination, OAuthClient
}, },
methods: { methods: {
getClients: function (page) { getClients: function (page) {
@ -80,6 +59,14 @@
this.$root.$on('reload_clients', () => { this.$root.$on('reload_clients', () => {
this.getClients(1) this.getClients(1)
}) })
this.$on('edit', function (id) {
this.editing = id
})
this.$on('delete', function (id) {
this.deleteClient(id)
})
} }
} }
</script> </script>

View File

@ -0,0 +1,13 @@
<template lang="pug">
.pgn
span.pagenum Page {{ page }} of {{ pages }}
.button(v-if='page > 1' v-on:click='$emit("page", page - 1)') Previous
.button(v-for='n in pages' v-on:click='$emit("page", n)' v-bind:class='{active: n == page}') {{ n }}
.button(v-if='page < pages' v-on:click='$emit("page", page + 1)') Next
</template>
<script type="text/javascript">
export default {
props: ['page', 'pages']
}
</script>

View File

@ -0,0 +1,48 @@
<template lang="pug">
.user.list-item
.avatar
img(v-if='avatar_file', v-bind:src="'/usercontent/images/' + avatar_file")
img(v-else='v-else', src='/static/image/avatar.png')
.info
.stamps
.noactive.stamp(v-if='activated == false', title='Not activated.')
i.fa.fa-fw.fa-envelope
.dropdown-wrapper.stamp(@click="dropdown = !dropdown" v-on-clickaway='away')
i.fa.fa-fw.fa-ellipsis-v
transition(name="modal")
.dropdown(v-show="dropdown")
.title Actions
.action(v-if='bannable' v-on:click='$parent.$emit("ban", id)')
i.fa.fa-fw.fa-ban
|&nbsp;Ban User
.display_name {{ display_name }}
.ame {{ id }} - {{ username }} ({{ uuid }})
.email {{ email }}
.privilege Privilege: level {{ nw_privilege }}
.timestamp {{ new Date(created_at).toString() }}
.external(v-if='!password')
b Used external login
</template>
<script type="text/javascript">
import { directive as onClickaway } from 'vue-clickaway';
export default {
props: ['avatar_file', 'activated', 'display_name', 'id', 'username', 'uuid', 'email', 'nw_privilege', 'created_at', 'password', 'bannable'],
directives: {
onClickaway: onClickaway,
},
data: function () {
return {
dropdown: false
}
},
methods: {
away: function () {
this.dropdown = false
}
}
}
</script>

View File

@ -1,34 +1,15 @@
<template lang="pug"> <template lang="pug">
#userlist #userlist
h3 Registered Users ({{ pagination.total }}) h3 Registered Users ({{ pagination.total }})
.pgn pagination(v-bind="pagination" v-on:page="getUsers")
span.pagenum Page {{ pagination.page }} of {{ pagination.pages }}
.button(v-if='pagination.page > 1', v-on:click='getUsers(pagination.page - 1)') Previous
.button(v-for='n in pagination.pages', v-on:click='getUsers(n)', v-bind:class='{active: n == pagination.page}') {{ n }}
.button(v-if='pagination.page < pagination.pages', v-on:click='getUsers(pagination.page + 1)') Next
.list.users .list.users
.user.list-item(v-for='user in users') user(v-for='user in users' v-bind="user")
.avatar ban-modal(:show='banning' @close='banning = 0' :id='banning')
img(v-if='user.avatar_file', v-bind:src="'/usercontent/images/' + user.avatar_file")
img(v-else='v-else', src='/static/image/avatar.png')
.info
.stamps
.noactive(v-if='user.activated == false', title='Not activated.')
i.fa.fa-fw.fa-envelope
.display_name {{ user.display_name }}
.username {{ user.id }} - {{ user.username }} ({{ user.uuid }})
.email {{ user.email }}
.privilege Privilege: level {{ user.nw_privilege }}
.timestamp {{ new Date(user.created_at).toString() }}
.external(v-if='!user.password')
b Used external login
.button.ban(v-if='user.bannable', v-on:click='banning = user.id')
i.fa.fa-fw.fa-ban
| Ban User
ban-modal(:show='banning', @close='banning = 0', :id='banning')
</template> </template>
<script> <script>
import Pagination from './Pagination.vue'
import User from './User.vue'
import BanModal from './BanModal.vue' import BanModal from './BanModal.vue'
export default { export default {
@ -46,7 +27,7 @@
} }
}, },
components: { components: {
BanModal Pagination, User, BanModal
}, },
methods: { methods: {
getUsers: function (page) { getUsers: function (page) {
@ -59,6 +40,10 @@
}, },
mounted: function () { mounted: function () {
this.getUsers(1) this.getUsers(1)
this.$on('ban', function (id) {
this.banning = id
})
} }
} }
</script> </script>

View File

@ -42,9 +42,13 @@ nav
float: right float: right
.stamps .stamps
float: right float: right
.stamp
padding: 5px
font-size: 120%
display: inline-block
.user .user
min-height: 180px min-height: 160px
.avatar .avatar
float: left float: left
.info .info
@ -74,24 +78,56 @@ nav
min-height: 200px min-height: 200px
#hiddensecret #hiddensecret
display: none
color: #ff796f color: #ff796f
background-color: #f1f1f1 background-color: #f1f1f1
padding: 5px
min-width: 250px min-width: 250px
#showbutton #showbutton
font-style: italic font-style: italic
display: inline-block display: inline-block
cursor: pointer cursor: pointer
&:hover > #hiddensecret
display: block
.link .link
color: green color: green
cursor: pointer cursor: pointer
display: inline-block display: inline-block
.dropdown-wrapper
padding: 3px 0px
border-radius: 5px
position: relative
cursor: pointer
.dropdown
cursor: default
position: absolute
top: 25px
right: 0
background-color: #fff
border: 1px solid #ddd
border-radius: 5px
min-width: 180px
font-size: 120%
.title
padding: 5px
color: #a5a5a5
.action
transition: background-color .3s linear
cursor: pointer
padding: 5px
&:hover
background-color: #ececec
.separator
margin: 0 15px
margin-top: 10px
border-bottom: 1px solid #ddd
margin-bottom: 9px
.modal-mask .modal-mask
position: fixed position: fixed
z-index: 9998 z-index: 9998