diff options
author | dartcafe <github@dartcafe.de> | 2019-01-13 16:01:06 +0300 |
---|---|---|
committer | dartcafe <github@dartcafe.de> | 2019-01-13 16:01:06 +0300 |
commit | 9352b93dd7452f71756cf04e5f1199570e4f669a (patch) | |
tree | 8fa7f27166d9d6d58a0316d8fdfe47ff3d3b99c0 | |
parent | b0e0e5bc8f5ad519f73e8b27068a0fd864d45bcf (diff) |
Added modal confirmation dialog
Added comment counter
Added voting indicator
-rw-r--r-- | appinfo/routes.php | 4 | ||||
-rw-r--r-- | lib/Controller/PageController.php | 4 | ||||
-rw-r--r-- | src/css-oc-fixes/oc-colors-fix.scss | 3 | ||||
-rw-r--r-- | src/css-oc-fixes/oc-container-fix.scss | 37 | ||||
-rw-r--r-- | src/css-oc/createpoll.scss | 2 | ||||
-rw-r--r-- | src/css-oc/flex.scss | 1 | ||||
-rw-r--r-- | src/css-oc/list.scss | 3 | ||||
-rw-r--r-- | src/css-oc/main.scss | 1 | ||||
-rw-r--r-- | src/css-oc/public.scss | 1 | ||||
-rw-r--r-- | src/css-oc/sidebar.scss | 2 | ||||
-rw-r--r-- | src/css-oc/vote.scss | 2 | ||||
-rw-r--r-- | src/js/components/pollItem.vue | 28 | ||||
-rw-r--r-- | src/js/main.js | 4 | ||||
-rw-r--r-- | src/js/plugins/modalDialog.vue | 92 | ||||
-rw-r--r-- | src/js/plugins/plugin.js | 29 | ||||
-rw-r--r-- | src/js/router.js | 1 | ||||
-rw-r--r-- | src/js/views/List.vue | 41 | ||||
-rw-r--r-- | templates/main.tmpl.php | 2 | ||||
-rw-r--r-- | templates/vote.tmpl.php | 2 |
19 files changed, 180 insertions, 79 deletions
diff --git a/appinfo/routes.php b/appinfo/routes.php index 5d956a0c..c2a8602c 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -23,8 +23,8 @@ return [ 'routes' => [ - ['name' => 'page#list_polls', 'url' => '/', 'verb' => 'GET'], - ['name' => 'page#index', 'url' => '/list', 'verb' => 'GET'], + ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], + ['name' => 'page#index_old', 'url' => '/list', 'verb' => 'GET'], ['name' => 'page#goto_poll', 'url' => '/poll/{hash}', 'verb' => 'GET'], ['name' => 'page#create_poll', 'url' => '/new', 'verb' => 'GET'], diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index ee6b0217..1450cd9e 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -134,7 +134,7 @@ class PageController extends Controller { * @NoAdminRequired * @NoCSRFRequired */ - public function index() { + public function indexOld() { $polls = $this->eventMapper->findAllForUserWithInfo($this->userId); $comments = $this->commentMapper->findDistinctByUser($this->userId); $votes = $this->voteMapper->findDistinctByUser($this->userId); @@ -164,7 +164,7 @@ class PageController extends Controller { * @NoAdminRequired * @NoCSRFRequired */ - public function listPolls() { + public function index() { return new TemplateResponse('polls', 'polls.tmpl', ['urlGenerator' => $this->urlGenerator]); } diff --git a/src/css-oc-fixes/oc-colors-fix.scss b/src/css-oc-fixes/oc-colors-fix.scss deleted file mode 100644 index 1e1f4d59..00000000 --- a/src/css-oc-fixes/oc-colors-fix.scss +++ /dev/null @@ -1,3 +0,0 @@ -$color-main-background: #fff; -$color-border: #ebebeb; - diff --git a/src/css-oc-fixes/oc-container-fix.scss b/src/css-oc-fixes/oc-container-fix.scss deleted file mode 100644 index 26d79370..00000000 --- a/src/css-oc-fixes/oc-container-fix.scss +++ /dev/null @@ -1,37 +0,0 @@ -#content-wrapper { - padding-top: unset; -} - -#content { - box-sizing: border-box; - position: relative; - display: flex; - padding-top: 45px; - min-height: 100%; - height: unset; - width: unset; -} - -#app-content { - position: initial; - height: initial; - overflow-y: initial; - flex-basis: 100vw; -} - -#content[class*="app-"] * { - box-sizing: border-box; -} - -#controls { - position: sticky; - top: 45px; - right: unset; - left: unset; - display: flex; - height: 40px; - padding: 0; - margin: 0; - z-index: 60; - position: webkit-sticky; -} diff --git a/src/css-oc/createpoll.scss b/src/css-oc/createpoll.scss deleted file mode 100644 index b619a7cb..00000000 --- a/src/css-oc/createpoll.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import '../css-oc-fixes/oc-container-fix.scss'; -@import '../../css/createpoll.scss'; diff --git a/src/css-oc/flex.scss b/src/css-oc/flex.scss deleted file mode 100644 index ea82c336..00000000 --- a/src/css-oc/flex.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../css/flex.scss'; diff --git a/src/css-oc/list.scss b/src/css-oc/list.scss deleted file mode 100644 index f36d1360..00000000 --- a/src/css-oc/list.scss +++ /dev/null @@ -1,3 +0,0 @@ -@import '../css-oc-fixes/oc-colors-fix.scss'; -@import '../css-oc-fixes/oc-container-fix.scss'; -@import '../../css/list.scss'; diff --git a/src/css-oc/main.scss b/src/css-oc/main.scss deleted file mode 100644 index feccbcd0..00000000 --- a/src/css-oc/main.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../css/main.scss'; diff --git a/src/css-oc/public.scss b/src/css-oc/public.scss deleted file mode 100644 index 87cc7f4e..00000000 --- a/src/css-oc/public.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../css/public.scss'; diff --git a/src/css-oc/sidebar.scss b/src/css-oc/sidebar.scss deleted file mode 100644 index 5386facd..00000000 --- a/src/css-oc/sidebar.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import '../css-oc-fixes/oc-colors-fix.scss'; -@import '../../css/sidebar.scss'; diff --git a/src/css-oc/vote.scss b/src/css-oc/vote.scss deleted file mode 100644 index 56972cbd..00000000 --- a/src/css-oc/vote.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import '../css-oc-fixes/oc-container-fix.scss'; -@import '../../css/vote.scss'; diff --git a/src/js/components/pollItem.vue b/src/js/components/pollItem.vue index 9e11e9b5..f68b533e 100644 --- a/src/js/components/pollItem.vue +++ b/src/js/components/pollItem.vue @@ -24,7 +24,11 @@ <div> <div class="wrapper group-master"> <div class="wrapper group-1"> - <div class="thumbnail" :class="[poll.event.type, {expired : poll.event.expired}] " /> + <div v-if="countComments" class="comment-badge"> + {{ countComments }} + </div> + <div class="thumbnail" :class="[poll.event.type, {expired : poll.event.expired}] "> + </div> <a :href="voteUrl" class="wrapper group-1-1"> <div class="flex-column name"> {{ poll.event.title }} @@ -59,8 +63,7 @@ {{ timeSpanExpiration }} </div> <div class="flex-column participants"> - <div class="symbol alt-tooltip partic_voted icon-voted" /> - <div class="symbol alt-tooltip partic_commented icon-comment-yes" /> + <div v-if="votedBycurrentUser" class="symbol icon-voted" /> </div> </div> </div> @@ -69,7 +72,7 @@ </template> <script> -import moment from 'moment' +// import moment from 'moment' export default { props: { @@ -212,6 +215,23 @@ export default { &.expired { background-color: var(--color-error); } + } +.icon-voted { + background-image: var(--icon-checkmark-49bc49); +} +.comment-badge { + position: absolute; + top: 0px; + width: 26px; + line-height: 26px; + text-align: center; + font-size: 0.7rem; + color: white; + background-image: var(--icon-comment-49bc49); + background-repeat: no-repeat; + background-size: 26px; + z-index: 1; +} </style> diff --git a/src/js/main.js b/src/js/main.js index caaf5b26..8c3651c4 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -27,6 +27,7 @@ import axios from 'nextcloud-axios' import App from './App.vue' import vClickOutside from 'v-click-outside' import VueClipboard from 'vue-clipboard2' +import Modal from './plugins/plugin.js' import { DatetimePicker, PopoverMenu } from 'nextcloud-vue' @@ -48,10 +49,13 @@ Vue.component('ShareDiv', ShareDiv) Vue.use(vClickOutside) Vue.use(VueClipboard) +Vue.use(Modal) Vue.prototype.t = t Vue.prototype.n = n Vue.prototype.$http = axios +Vue.prototype.OC = OC +Vue.prototype.OCA = OCA // CSP config for webpack dynamic chunk loading // eslint-disable-next-line diff --git a/src/js/plugins/modalDialog.vue b/src/js/plugins/modalDialog.vue new file mode 100644 index 00000000..052c461f --- /dev/null +++ b/src/js/plugins/modalDialog.vue @@ -0,0 +1,92 @@ +<template> + <div class="modal-wrapper" v-if="visible"> + <div class="modal-header"> + <h2>{{ title }}</h2> + </div> + <div class="modal-text"> + <p>{{ text }}</p> + </div> + <div class="modal-buttons"> + <button class="button" @click="hide">{{ t('polls','No') }}</button> + <button class="button primary" @click="confirm">{{ t('polls','yes') }}</button> + </div> + </div> +</template> + + +<script> +// we must import our Modal plugin instance +// because it contains reference to our Eventbus +import Modal from './plugin.js'; + +export default { + data() { + return { + visible: false, + title: '', + text: '', + onConfirm: {} + } + }, + methods: { + hide() { + this.visible = false; + }, + confirm() { + // we must check if this.onConfirm is function + if(typeof this.onConfirm === 'function') { + // run passed function and then close the modal + this.onConfirm(); + this.hide(); + } else { + // we only close the modal + this.hide(); + } + }, + show(params) { + // making modal visible + this.visible = true; + // setting title and text + this.title = params.title; + this.text = params.text; + // setting callback function + this.onConfirm = params.onConfirm; + } + }, + beforeMount() { + // here we need to listen for emited events + // we declared those events inside our plugin + Modal.EventBus.$on('show', (params) => { + this.show(params) + }) + } +} + +</script> + +<style scoped lang="scss"> +.modal-wrapper { + display: flex; + flex-direction: column; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: 300px; + max-width: 500px; + z-index: 1000; + background-color: var(--color-main-background); + box-shadow: 10px 10px 30px 1px rgba(0, 0, 0, 0.24); + & > * { + padding: 7px; + } +} + +.modal-header { + background-color: var(--color-primary); + & > * { + color: var(--color-primary-text); + } +} + +</style> diff --git a/src/js/plugins/plugin.js b/src/js/plugins/plugin.js new file mode 100644 index 00000000..02e34215 --- /dev/null +++ b/src/js/plugins/plugin.js @@ -0,0 +1,29 @@ +// we need our modal component +import ModalDialog from './modalDialog.vue' + +const Modal = { + // every plugin for Vue.js needs install method + // this method will run after Vue.use(<your-plugin-here>) is executed + install(Vue, options) { + // We must create new Eventbus + // which is just another Vue instance that will be listening for and emiting events from our main instance + // this EventBus will be available as Modal.EventBus + this.EventBus = new Vue() + + // making our modal component global + Vue.component('modal-dialog', ModalDialog) + + // exposing global $modal object with method show() + // method show() takes object params as argument + // inside this object we can have modal title, text, styles... and also our callback confirm function + Vue.prototype.$modal = { + show(params) { + // if we use this.$modal.show(params) inside our original Vue instance + // we will emit 'show' event with parameters 'params' + Modal.EventBus.$emit('show', params) + } + } + } +} + +export default Modal diff --git a/src/js/router.js b/src/js/router.js index b0625232..6c09ae37 100644 --- a/src/js/router.js +++ b/src/js/router.js @@ -1,3 +1,4 @@ +/* jshint esversion: 6 */ /** * @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net> * @copyright Copyright (c) 2018 John Molakvoæ <skjnldsv@protonmail.com> diff --git a/src/js/views/List.vue b/src/js/views/List.vue index a16eeb91..5b1e57cb 100644 --- a/src/js/views/List.vue +++ b/src/js/views/List.vue @@ -23,7 +23,8 @@ <template> <div id="app-content"> <controls> - <router-link :to="{ name: 'create'}" class="button symbol icon-add"> + <router-link :to="{ name: 'create'}" class="button"> + <span class="symbol icon-add"></span> <span class="hidden-visually"> {{ t('polls', 'New') }} </span> @@ -57,6 +58,7 @@ @deletePoll="removePoll(index, poll.event)" /> </transition-group> + <modal-dialog/> </div> </template> @@ -101,22 +103,27 @@ export default { }) }, - removePoll: function (index, event) { - this.loading = true - this.$http.post(OC.generateUrl('apps/polls/remove/poll'), event ) - .then((response) => { - OC.Notification.showTemporary(t('polls', 'Poll "%n" deleted', 1, event.title)) - this.polls.splice(index, 1) - this.loading = false - console.log(response.data) - - }, (error) => { - /* eslint-disable-next-line no-console */ - OC.Notification.showTemporary(t('polls', 'Error while deleting Poll "%n"', 1, event.title)) - console.log(error.response) - this.loading = false - }) - } + removePoll: function(index, event) { + const params = { + title: t('polls','Delete poll'), + text: t('polls', 'Do you want to delete "%n"?', 1, event.title), + onConfirm: () => { + // this.deletePoll(index, event) + this.$http.post(OC.generateUrl('apps/polls/remove/poll'), event) + .then((response) => { + this.polls.splice(index, 1) + OC.Notification.showTemporary(t('polls', 'Poll "%n" deleted', 1, event.title)) + }, (error) => { + OC.Notification.showTemporary(t('polls', 'Error while deleting Poll "%n"', 1, event.title)) + /* eslint-disable-next-line no-console */ + console.log(error.response) + } + ) + } + } + this.$modal.show(params) + }, + } } </script> diff --git a/templates/main.tmpl.php b/templates/main.tmpl.php index 067ef559..a0dd594f 100644 --- a/templates/main.tmpl.php +++ b/templates/main.tmpl.php @@ -49,7 +49,7 @@ </div> </div> <div class="actions creatable" style=""> - <a href="<?php p($urlGenerator->linkToRoute('polls.page.polls_app')); ?>" class="button new"> + <a href="<?php p($urlGenerator->linkToRoute('polls.page.create_poll')); ?>" class="button new"> <span class="symbol icon-add"></span><span class="hidden-visually">Neu</span> </a> <input class="stop icon-close" style="display:none" value="" type="button"> diff --git a/templates/vote.tmpl.php b/templates/vote.tmpl.php index 154cb568..629177fb 100644 --- a/templates/vote.tmpl.php +++ b/templates/vote.tmpl.php @@ -116,7 +116,7 @@ <?php if (User::isLoggedIn()) : ?> <div class="crumb svg crumbhome"> - <a class="icon-home" href="<?php p($urlGenerator->linkToRoute('polls.page.list_polls')); ?>"> Home </a> + <a class="icon-home" href="<?php p($urlGenerator->linkToRoute('polls.page.index')); ?>"> Home </a> </div> <?php endif; ?> |