Use vue-components for app-navigation
Signed-off-by: Raimund Schlüßler <raimund.schluessler@mailbox.org>
This commit is contained in:
parent
8f7118db07
commit
5d22e8d4ea
5 changed files with 178 additions and 283 deletions
|
@ -3,49 +3,30 @@
|
|||
*/
|
||||
|
||||
#app-navigation {
|
||||
&:not(.vue) {
|
||||
> ul > li {
|
||||
> a {
|
||||
background-position: inherit;
|
||||
}
|
||||
> .app-navigation-entry-edit {
|
||||
padding-left: 5px !important;
|
||||
}
|
||||
}
|
||||
.app-navigation-entry-menu {
|
||||
ul {
|
||||
align-items: unset;
|
||||
li {
|
||||
width: auto !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
> ul {
|
||||
> li {
|
||||
background-image: unset;
|
||||
|
||||
> a {
|
||||
background-image: unset;
|
||||
background-position: inherit;
|
||||
}
|
||||
|
||||
.sprite::before {
|
||||
&.collection .app-navigation-entry-icon::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background: var(--icon-tasks-bw-000) no-repeat;
|
||||
margin: 14px;
|
||||
margin-left: -30px;
|
||||
background-position: inherit;
|
||||
}
|
||||
|
||||
&.active .app-navigation-entry-bullet {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin: 14px;
|
||||
&.list {
|
||||
&.active .app-navigation-entry__icon-bullet > div {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin: -1px;
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
.app-navigation-entry__utils .action-item,
|
||||
.calendar__share {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.edit {
|
||||
|
@ -61,20 +42,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
&.animate-up {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.list:not(.active) {
|
||||
.app-navigation-entry-utils-menu-button,
|
||||
.calendar__share {
|
||||
&.list, &.collection {
|
||||
.task-item {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.list, &.collection {
|
||||
.task-item {
|
||||
display: none;
|
||||
button {
|
||||
&.icon-share {
|
||||
opacity: 0.3 !important;
|
||||
}
|
||||
|
||||
&.icon-shared,
|
||||
&.icon-public {
|
||||
opacity: 0.7 !important;
|
||||
}
|
||||
|
||||
&.icon-share:active,
|
||||
&.icon-share:focus,
|
||||
&.icon-share:hover,
|
||||
&.icon-shared:active,
|
||||
&.icon-shared:focus,
|
||||
&.icon-shared:hover,
|
||||
&.icon-public:active,
|
||||
&.icon-public:focus,
|
||||
&.icon-public:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,71 +107,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.app-navigation-entry-utils li {
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.app-navigation-entry-menu {
|
||||
ul {
|
||||
align-items: unset;
|
||||
}
|
||||
|
||||
li {
|
||||
float: inherit;
|
||||
width: auto !important;
|
||||
cursor: pointer;
|
||||
height: 44px;
|
||||
|
||||
/*
|
||||
* rules for confirmation directive
|
||||
*/
|
||||
> a {
|
||||
&:not(:empty).confirmation-confirm {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
span.countdown {
|
||||
background-color: inherit;
|
||||
color: $white;
|
||||
display: block;
|
||||
text-align: center;
|
||||
filter: alpha(opacity=100) !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover a {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
&.confirmed a {
|
||||
&.confirmation-confirm {
|
||||
display: inline-block !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.confirmation-abort {
|
||||
display: inline-block !important;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
margin-right: 5px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button {
|
||||
float: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
> ul ul.colorpicker-list {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
@ -237,39 +165,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.confirmation-default {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.confirmed {
|
||||
.confirmation-default {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&.active {
|
||||
.confirmation-confirm {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.countdown {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.confirmation-abort {
|
||||
width: 50% !important;
|
||||
display: none !important;
|
||||
padding: 0 !important;
|
||||
background-position: center !important;
|
||||
}
|
||||
|
||||
.confirmation-confirm {
|
||||
@extend .confirmation-abort;
|
||||
background-color: $red !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* rules for settings area
|
||||
*/
|
||||
|
@ -474,7 +369,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.content-wrapper {
|
||||
> div {
|
||||
padding: 6px 17px 75px;
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
|
|
22
src/App.vue
22
src/App.vue
|
@ -21,16 +21,16 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<template>
|
||||
<div id="content" class="app-tasks" @click="closeDetails($event)">
|
||||
<div id="app-navigation">
|
||||
<AppNavigation>
|
||||
<TheList />
|
||||
<TheSettings />
|
||||
</div>
|
||||
<AppNavigationSettings>
|
||||
<TheSettings />
|
||||
</AppNavigationSettings>
|
||||
</AppNavigation>
|
||||
|
||||
<div id="app-content">
|
||||
<div class="content-wrapper">
|
||||
<RouterView />
|
||||
</div>
|
||||
</div>
|
||||
<AppContent>
|
||||
<RouterView />
|
||||
</AppContent>
|
||||
|
||||
<div id="app-sidebar" :class="{disappear: $route.params.taskId === undefined}">
|
||||
<RouterView name="details" />
|
||||
|
@ -40,6 +40,9 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation'
|
||||
import AppContent from '@nextcloud/vue/dist/Components/AppContent'
|
||||
import AppNavigationSettings from '@nextcloud/vue/dist/Components/AppNavigationSettings'
|
||||
import TheList from './components/TheList'
|
||||
import TheSettings from './components/TheSettings'
|
||||
import client from './services/cdav.js'
|
||||
|
@ -49,6 +52,9 @@ export default {
|
|||
components: {
|
||||
TheSettings,
|
||||
TheList,
|
||||
AppNavigation,
|
||||
AppContent,
|
||||
AppNavigationSettings,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
|
|
|
@ -21,99 +21,85 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
|
||||
<template>
|
||||
<ul id="collections">
|
||||
<draggable
|
||||
<AppNavigationItem
|
||||
v-for="collection in collections"
|
||||
v-show="!hideCollection(collection)"
|
||||
:id="'collection_' + collection.id"
|
||||
:key="collection.id"
|
||||
:collection-id="collection.id"
|
||||
:component-data="{props: {tag: 'li', to: { name: 'collections', params: { collectionId: collection.id } }, 'active-class': 'active'}}"
|
||||
:class="[collection.icon, {'animate-up': hideCollection(collection) }]"
|
||||
tag="RouterLink"
|
||||
:icon="collection.icon"
|
||||
:to="{ name: 'collections', params: { collectionId: collection.id } }"
|
||||
:title="collection.displayName"
|
||||
class="collection reactive"
|
||||
v-bind="{group: 'tasks', filter: '*'}"
|
||||
@add="dropTaskOnCollection(...arguments, collection)">
|
||||
<a class="sprite">
|
||||
<span v-if="collection.id=='today'" class="date">
|
||||
{{ dayOfMonth }}
|
||||
</span>
|
||||
<span class="title">
|
||||
{{ collection.displayName }}
|
||||
</span>
|
||||
</a>
|
||||
<div v-if="collection.id!='completed'" class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter">
|
||||
{{ collectionCount(collection.id) | counterFormatter }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</draggable>
|
||||
<draggable
|
||||
<AppNavigationCounter slot="counter">
|
||||
{{ collectionCount(collection.id) | counterFormatter }}
|
||||
</AppNavigationCounter>
|
||||
</AppNavigationItem>
|
||||
<AppNavigationItem
|
||||
v-for="calendar in calendars"
|
||||
:id="'list_' + calendar.id"
|
||||
:key="calendar.id"
|
||||
v-click-outside="() => resetView(calendar)"
|
||||
:calendar-id="calendar.id"
|
||||
:component-data="{props: {tag: 'li', to: { name: 'calendars', params: { calendarId: calendar.id } }, 'active-class': 'active'}}"
|
||||
:to="{ name: 'calendars', params: { calendarId: calendar.id } }"
|
||||
:title="calendar.displayName"
|
||||
:class="{edit: editing == calendar.id}"
|
||||
tag="RouterLink"
|
||||
class="list with-menu editing"
|
||||
v-bind="{group: 'tasks', filter: '*', disabled: calendar.readOnly, preventOnFilter: false}"
|
||||
@add="dropTaskOnCalendar(...arguments, calendar)">
|
||||
<div :style="{'background-color': calendar.color}" class="app-navigation-entry-bullet" />
|
||||
<a>
|
||||
<span class="title">
|
||||
{{ calendar.displayName }}
|
||||
</span>
|
||||
</a>
|
||||
<AppNavigationIconBullet slot="icon" :color="calendar.color" />
|
||||
|
||||
<div class="app-navigation-entry-utils">
|
||||
<ul>
|
||||
<li class="app-navigation-entry-utils-counter">
|
||||
{{ calendarCount(calendar.id) | counterFormatter }}
|
||||
</li>
|
||||
<template slot="counter">
|
||||
<AppNavigationCounter>
|
||||
{{ calendarCount(calendar.id) | counterFormatter }}
|
||||
</AppNavigationCounter>
|
||||
<Actions v-if="!calendar.readOnly">
|
||||
<ActionButton
|
||||
:icon="sharingIconClass(calendar)"
|
||||
@click="toggleShare(calendar)">
|
||||
{{ sharedWithTooltip(calendar) }}
|
||||
</ActionButton>
|
||||
</Actions>
|
||||
<Avatar v-if="calendar.isSharedWithMe && calendar.loadedOwnerPrincipal" :user="calendar.ownerUserId" :display-name="calendar.ownerDisplayname" />
|
||||
<div v-if="calendar.isSharedWithMe && !calendar.loadedOwnerPrincipal" class="icon icon-loading" />
|
||||
</template>
|
||||
|
||||
<!-- sharing button -->
|
||||
<li v-if="!calendar.readOnly"
|
||||
v-tooltip.top="sharedWithTooltip(calendar)"
|
||||
:class="{'calendar__share--shared': hasShares(calendar)}"
|
||||
:title="sharedWithTooltip(calendar)"
|
||||
href="#"
|
||||
class="calendar__share icon-shared reactive"
|
||||
@click="toggleShare(calendar)" />
|
||||
<PopoverMenu tag="li" class="app-navigation-entry-utils-menu-button reactive">
|
||||
<ul>
|
||||
<li v-if="!calendar.readOnly">
|
||||
<a @click="edit(calendar)">
|
||||
<span class="icon-rename" />
|
||||
<span>{{ $t('tasks', 'Edit') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a @click="copyCalDAVUrl($event, calendar)">
|
||||
<span class="icon-public" />
|
||||
<span>
|
||||
{{ !copied
|
||||
? $t('tasks', 'Copy private link')
|
||||
: copySuccess
|
||||
? $t('tasks', 'Copied')
|
||||
: $t('tasks', 'Can not copy') }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a :href="exportUrl(calendar)" :download="calendar.id + '.ics'">
|
||||
<span class="icon-download" />
|
||||
<span>{{ $t('tasks', 'Download') }}</span>
|
||||
</a>
|
||||
</li>
|
||||
<Confirmation v-if="!calendar.readOnly" :message="deleteMessage(calendar.displayName)" @delete-calendar="deleteCalendar(calendar)" />
|
||||
</ul>
|
||||
</PopoverMenu>
|
||||
</ul>
|
||||
</div>
|
||||
<template slot="actions">
|
||||
<ActionButton
|
||||
v-if="!calendar.readOnly"
|
||||
icon="icon-rename"
|
||||
@click="edit(calendar)">
|
||||
{{ $t('tasks', 'Edit') }}
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
icon="icon-public"
|
||||
:close-after-click="true"
|
||||
@click="copyCalDAVUrl($event, calendar)">
|
||||
{{ !copied
|
||||
? $t('tasks', 'Copy private link')
|
||||
: copySuccess
|
||||
? $t('tasks', 'Copied')
|
||||
: $t('tasks', 'Can not copy') }}
|
||||
</ActionButton>
|
||||
<ActionLink
|
||||
icon="icon-download"
|
||||
:close-after-click="true"
|
||||
:href="exportUrl(calendar)">
|
||||
{{ $t('tasks', 'Download') }}
|
||||
</ActionLink>
|
||||
<ActionButton
|
||||
v-if="!calendar.readOnly"
|
||||
v-tooltip="{
|
||||
placement: 'left',
|
||||
boundariesElement: 'body',
|
||||
content: deleteMessage(calendar)
|
||||
}"
|
||||
icon="icon-delete"
|
||||
@click="deleteCalendar(calendar)">
|
||||
{{ !calendar.isSharedWithMe ? $t('calendar', 'Delete') : $t('calendar', 'Unshare') }}
|
||||
</ActionButton>
|
||||
</template>
|
||||
|
||||
<!-- sharing input -->
|
||||
<ShareCalendar v-if="shareOpen == calendar.id && !calendar.readOnly" :calendar="calendar" />
|
||||
|
||||
<div :class="{error: nameError}" class="app-navigation-entry-edit name">
|
||||
|
@ -140,8 +126,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
</form>
|
||||
<Colorpicker :selected-color="selectedColor" @color-selected="setColor(...arguments)" />
|
||||
</div>
|
||||
</draggable>
|
||||
<li v-click-outside="cancelCreate" :class="{edit: creating}" class="newList icon-add reactive editing">
|
||||
</AppNavigationItem>
|
||||
<!-- <li v-click-outside="cancelCreate" :class="{edit: creating}" class="newList icon-add reactive editing">
|
||||
<a class="icon icon-bw addlist sprite"
|
||||
@click="startCreate($event)">
|
||||
<span class="title">
|
||||
|
@ -174,27 +160,33 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
</form>
|
||||
<Colorpicker :selected-color="selectedColor" @color-selected="setColor(...arguments)" />
|
||||
</div>
|
||||
</li>
|
||||
</li> -->
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapGetters, mapActions } from 'vuex'
|
||||
import Colorpicker from './Colorpicker'
|
||||
import PopoverMenu from './PopoverMenu'
|
||||
import Confirmation from './Confirmation'
|
||||
import ShareCalendar from './CalendarShare'
|
||||
|
||||
import ClickOutside from 'vue-click-outside'
|
||||
import draggable from 'vuedraggable'
|
||||
import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem'
|
||||
import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter'
|
||||
import AppNavigationIconBullet from '@nextcloud/vue/dist/Components/AppNavigationIconBullet'
|
||||
import Actions from '@nextcloud/vue/dist/Components/Actions'
|
||||
import ActionButton from '@nextcloud/vue/dist/Components/ActionButton'
|
||||
import ActionLink from '@nextcloud/vue/dist/Components/ActionLink'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Colorpicker,
|
||||
PopoverMenu,
|
||||
Confirmation,
|
||||
ShareCalendar,
|
||||
draggable,
|
||||
AppNavigationItem,
|
||||
AppNavigationCounter,
|
||||
AppNavigationIconBullet,
|
||||
Actions,
|
||||
ActionButton,
|
||||
ActionLink,
|
||||
},
|
||||
directives: {
|
||||
ClickOutside,
|
||||
|
@ -439,8 +431,16 @@ export default {
|
|||
}
|
||||
return check
|
||||
},
|
||||
deleteMessage: function(name) {
|
||||
return this.$t('tasks', 'This will delete the calendar "{calendar}" and all corresponding events and tasks.', { calendar: name })
|
||||
deleteMessage: function(calendar) {
|
||||
return !calendar.isSharedWithMe
|
||||
? this.$t('tasks', 'This will delete the calendar "{calendar}" and all corresponding events and tasks.', { calendar: calendar.displayName })
|
||||
: this.$t('tasks', 'This will unshare the calendar "{calendar}".', { calendar: calendar.displayName })
|
||||
},
|
||||
sharingIconClass(calendar) {
|
||||
if (calendar.shares.length) {
|
||||
return 'icon-shared'
|
||||
}
|
||||
return 'icon-share'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -20,53 +20,46 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|||
-->
|
||||
|
||||
<template>
|
||||
<div id="app-settings" class="reactive">
|
||||
<div id="app-settings-header">
|
||||
<button class="settings-button" data-apps-slide-toggle="#app-settings-content">
|
||||
<span>{{ $t('tasks', 'Settings') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="app-settings-content">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="defaultCalendar">
|
||||
{{ $t('tasks', 'Default list') }}
|
||||
</label>
|
||||
<select id="defaultCalendar" v-model="defaultCalendarId">
|
||||
<option v-for="calendar in calendars"
|
||||
:key="calendar.id"
|
||||
:value="calendar.id">
|
||||
{{ calendar.displayName }}
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="headline">
|
||||
{{ $t('tasks', 'Visibility of Smart Collections') }}
|
||||
</li>
|
||||
<li v-for="collection in collections"
|
||||
:key="collection.id">
|
||||
<div class="label-container">
|
||||
<span :class="collection.icon" class="icon icon-bw">
|
||||
<span v-if="collection.id=='today'">
|
||||
{{ dayOfMonth }}
|
||||
</span>
|
||||
<div class="reactive">
|
||||
<ul>
|
||||
<li>
|
||||
<label for="defaultCalendar">
|
||||
{{ $t('tasks', 'Default list') }}
|
||||
</label>
|
||||
<select id="defaultCalendar" v-model="defaultCalendarId">
|
||||
<option v-for="calendar in calendars"
|
||||
:key="calendar.id"
|
||||
:value="calendar.id">
|
||||
{{ calendar.displayName }}
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
<li class="headline">
|
||||
{{ $t('tasks', 'Visibility of Smart Collections') }}
|
||||
</li>
|
||||
<li v-for="collection in collections"
|
||||
:key="collection.id">
|
||||
<div class="label-container">
|
||||
<span :class="collection.icon" class="icon icon-bw">
|
||||
<span v-if="collection.id=='today'">
|
||||
{{ dayOfMonth }}
|
||||
</span>
|
||||
<label :for="'visibilityCollection-' + collection.id" class="title">
|
||||
{{ collection.displayName }}
|
||||
</label>
|
||||
</div>
|
||||
<select :id="'visibilityCollection-' + collection.id"
|
||||
:value="collection.show"
|
||||
@change="setVisibility({ id: collection.id, show: +$event.target.value })">
|
||||
<option v-for="collectionOption in collectionOptions"
|
||||
:key="collectionOption.id"
|
||||
:value="collectionOption.id">
|
||||
{{ collectionOption.name }}
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</span>
|
||||
<label :for="'visibilityCollection-' + collection.id" class="title">
|
||||
{{ collection.displayName }}
|
||||
</label>
|
||||
</div>
|
||||
<select :id="'visibilityCollection-' + collection.id"
|
||||
:value="collection.show"
|
||||
@change="setVisibility({ id: collection.id, show: +$event.target.value })">
|
||||
<option v-for="collectionOption in collectionOptions"
|
||||
:key="collectionOption.id"
|
||||
:value="collectionOption.id">
|
||||
{{ collectionOption.name }}
|
||||
</option>
|
||||
</select>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -54,5 +54,6 @@ const routes = [
|
|||
Vue.use(VueRouter)
|
||||
|
||||
export default new VueRouter({
|
||||
linkActiveClass: 'active',
|
||||
routes, // short for `routes: routes`
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue