Use vue-components for app-navigation

Signed-off-by: Raimund Schlüßler <raimund.schluessler@mailbox.org>
This commit is contained in:
Raimund Schlüßler 2020-01-21 22:47:40 +01:00
parent 8f7118db07
commit 5d22e8d4ea
No known key found for this signature in database
GPG key ID: 036FA7EB1A599178
5 changed files with 178 additions and 283 deletions

View file

@ -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%;

View file

@ -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({

View file

@ -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'
},
},
}

View file

@ -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>

View file

@ -54,5 +54,6 @@ const routes = [
Vue.use(VueRouter)
export default new VueRouter({
linkActiveClass: 'active',
routes, // short for `routes: routes`
})