implement card reference widget, fix DeckIcon.vue

bring back eslint and stylelint on compilation, fix almost all warnings, ignore some

Signed-off-by: Julien Veyssier <eneiluj@posteo.net>
This commit is contained in:
Julien Veyssier
2022-09-06 18:03:44 +02:00
parent 89068641ee
commit 3c83320c20
54 changed files with 1029 additions and 200 deletions

View File

@@ -43,9 +43,9 @@
<script>
import { mapState } from 'vuex'
import AppNavigation from './components/navigation/AppNavigation'
import AppNavigation from './components/navigation/AppNavigation.vue'
import { NcModal, NcContent, NcAppContent } from '@nextcloud/vue'
import { BoardApi } from './services/BoardApi'
import { BoardApi } from './services/BoardApi.js'
import { emit, subscribe } from '@nextcloud/event-bus'
const boardApi = new BoardApi()

View File

@@ -92,11 +92,11 @@
<script>
import { generateUrl } from '@nextcloud/router'
import NcModal from '@nextcloud/vue/dist/Components/NcModal'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
import NcMultiselect from '@nextcloud/vue/dist/Components/NcMultiselect.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import axios from '@nextcloud/axios'
import { CardApi } from './services/CardApi'
import { CardApi } from './services/CardApi.js'
const cardApi = new CardApi()

View File

@@ -39,7 +39,7 @@ import RichText from '@juliushaertl/vue-richtext'
import { NcUserBubble } from '@nextcloud/vue'
import moment from '@nextcloud/moment'
import DOMPurify from 'dompurify'
import relativeDate from '../mixins/relativeDate'
import relativeDate from '../mixins/relativeDate.js'
const InternalLink = {
name: 'InternalLink',

View File

@@ -37,7 +37,7 @@
<script>
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import ActivityEntry from './ActivityEntry'
import ActivityEntry from './ActivityEntry.vue'
import InfiniteLoading from 'vue-infinite-loading'
const ACTIVITY_FETCH_LIMIT = 50

View File

@@ -63,7 +63,7 @@
<script>
import { NcModal } from '@nextcloud/vue'
import attachmentUpload from '../mixins/attachmentUpload'
import attachmentUpload from '../mixins/attachmentUpload.js'
import { loadState } from '@nextcloud/initial-state'
let maxUploadSizeState

View File

@@ -217,13 +217,13 @@
<script>
import { mapState, mapGetters } from 'vuex'
import { NcActions, NcActionButton, NcAvatar, NcButton, NcPopover } from '@nextcloud/vue'
import labelStyle from '../mixins/labelStyle'
import CardCreateDialog from '../CardCreateDialog'
import ArchiveIcon from 'vue-material-design-icons/Archive'
import FilterIcon from 'vue-material-design-icons/Filter'
import FilterOffIcon from 'vue-material-design-icons/FilterOff'
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical'
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical'
import labelStyle from '../mixins/labelStyle.js'
import CardCreateDialog from '../CardCreateDialog.vue'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
import FilterIcon from 'vue-material-design-icons/Filter.vue'
import FilterOffIcon from 'vue-material-design-icons/FilterOff.vue'
import ArrowCollapseVerticalIcon from 'vue-material-design-icons/ArrowCollapseVertical.vue'
import ArrowExpandVerticalIcon from 'vue-material-design-icons/ArrowExpandVertical.vue'
export default {
name: 'Controls',

View File

@@ -73,11 +73,11 @@
import { Container, Draggable } from 'vue-smooth-dnd'
import { mapState, mapGetters } from 'vuex'
import Controls from '../Controls'
import Stack from './Stack'
import Controls from '../Controls.vue'
import Stack from './Stack.vue'
import { NcEmptyContent } from '@nextcloud/vue'
import GlobalSearchResults from '../search/GlobalSearchResults'
import { showError } from '../../helpers/errors'
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
import { showError } from '../../helpers/errors.js'
export default {
name: 'Board',

View File

@@ -59,10 +59,10 @@
<script>
import { mapState, mapGetters } from 'vuex'
import SharingTabSidebar from './SharingTabSidebar'
import TagsTabSidebar from './TagsTabSidebar'
import DeletedTabSidebar from './DeletedTabSidebar'
import TimelineTabSidebar from './TimelineTabSidebar'
import SharingTabSidebar from './SharingTabSidebar.vue'
import TagsTabSidebar from './TagsTabSidebar.vue'
import DeletedTabSidebar from './DeletedTabSidebar.vue'
import TimelineTabSidebar from './TimelineTabSidebar.vue'
import { NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
const capabilities = window.OC.getCapabilities()

View File

@@ -32,7 +32,7 @@
<script>
import { mapState } from 'vuex'
import relativeDate from '../../mixins/relativeDate'
import relativeDate from '../../mixins/relativeDate.js'
export default {
name: 'DeletedTabSidebar',

View File

@@ -133,10 +133,10 @@ import { Container, Draggable } from 'vue-smooth-dnd'
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
import { showError, showUndo } from '@nextcloud/dialogs'
import CardItem from '../cards/CardItem'
import CardItem from '../cards/CardItem.vue'
import '@nextcloud/dialogs/styles/toast.scss'
import ArchiveIcon from 'vue-material-design-icons/Archive'
import ArchiveIcon from 'vue-material-design-icons/Archive.vue'
export default {
name: 'Stack',

View File

@@ -70,7 +70,7 @@
<script>
import { mapGetters } from 'vuex'
import Color from '../../mixins/color'
import Color from '../../mixins/color.js'
import { NcColorPicker, NcActions, NcActionButton } from '@nextcloud/vue'
export default {

View File

@@ -7,7 +7,7 @@
</template>
<script>
import ActivityList from '../ActivityList'
import ActivityList from '../ActivityList.vue'
export default {
name: 'TimelineTabSidebar',

View File

@@ -43,8 +43,8 @@
<script>
import BoardItem from './BoardItem'
import Controls from '../Controls'
import BoardItem from './BoardItem.vue'
import Controls from '../Controls.vue'
export default {
name: 'Boards',

View File

@@ -104,14 +104,14 @@
<script>
import axios from '@nextcloud/axios'
import { NcActions, NcActionButton, ActionLink } from '@nextcloud/vue'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop'
import relativeDate from '../../mixins/relativeDate'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
import relativeDate from '../../mixins/relativeDate.js'
import { formatFileSize } from '@nextcloud/files'
import { getCurrentUser } from '@nextcloud/auth'
import { generateUrl, generateOcsUrl, generateRemoteUrl } from '@nextcloud/router'
import { mapState, mapActions } from 'vuex'
import { loadState } from '@nextcloud/initial-state'
import attachmentUpload from '../../mixins/attachmentUpload'
import attachmentUpload from '../../mixins/attachmentUpload.js'
import { getFilePickerBuilder } from '@nextcloud/dialogs'
const maxUploadSizeState = loadState('deck', 'maxUploadSize')

View File

@@ -85,11 +85,11 @@
import { NcActionButton, NcAppSidebar, NcAppSidebarTab } from '@nextcloud/vue'
import { generateUrl } from '@nextcloud/router'
import { mapState, mapGetters } from 'vuex'
import CardSidebarTabDetails from './CardSidebarTabDetails'
import CardSidebarTabAttachments from './CardSidebarTabAttachments'
import CardSidebarTabComments from './CardSidebarTabComments'
import CardSidebarTabActivity from './CardSidebarTabActivity'
import relativeDate from '../../mixins/relativeDate'
import CardSidebarTabDetails from './CardSidebarTabDetails.vue'
import CardSidebarTabAttachments from './CardSidebarTabAttachments.vue'
import CardSidebarTabComments from './CardSidebarTabComments.vue'
import CardSidebarTabActivity from './CardSidebarTabActivity.vue'
import relativeDate from '../../mixins/relativeDate.js'
import moment from '@nextcloud/moment'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'

View File

@@ -30,7 +30,7 @@
</template>
<script>
import ActivityList from '../ActivityList'
import ActivityList from '../ActivityList.vue'
export default {
name: 'CardSidebarTabActivity',

View File

@@ -28,7 +28,7 @@
</template>
<script>
import AttachmentList from './AttachmentList'
import AttachmentList from './AttachmentList.vue'
export default {
name: 'CardSidebarTabAttachments',
components: {

View File

@@ -36,8 +36,8 @@
<script>
import { mapState, mapGetters } from 'vuex'
import { NcAvatar } from '@nextcloud/vue'
import CommentItem from './CommentItem'
import CommentForm from './CommentForm'
import CommentItem from './CommentItem.vue'
import CommentForm from './CommentForm.vue'
import InfiniteLoading from 'vue-infinite-loading'
import { getCurrentUser } from '@nextcloud/auth'

View File

@@ -129,14 +129,14 @@ import { NcAvatar, NcActions, NcActionButton, NcMultiselect, NcDatetimePicker }
import { loadState } from '@nextcloud/initial-state'
import { CollectionList } from 'nextcloud-vue-collections'
import Color from '../../mixins/color'
import Color from '../../mixins/color.js'
import {
getLocale,
getDayNamesMin,
getFirstDay,
getMonthNamesShort,
} from '@nextcloud/l10n'
import Description from './Description'
import Description from './Description.vue'
export default {
name: 'CardSidebarTabDetails',

View File

@@ -65,7 +65,7 @@
import { mapState } from 'vuex'
import { NcUserBubble, NcAvatar } from '@nextcloud/vue'
import At from 'vue-at'
import { rawToParsed } from '../../helpers/mentions'
import { rawToParsed } from '../../helpers/mentions.js'
export default {
name: 'CommentForm',

View File

@@ -66,10 +66,10 @@
<script>
import { NcAvatar, NcActions, NcActionButton, NcUserBubble } from '@nextcloud/vue'
import RichText from '@juliushaertl/vue-richtext'
import CommentForm from './CommentForm'
import CommentForm from './CommentForm.vue'
import { getCurrentUser } from '@nextcloud/auth'
import md5 from 'blueimp-md5'
import relativeDate from '../../mixins/relativeDate'
import relativeDate from '../../mixins/relativeDate.js'
import ReplyIcon from 'vue-material-design-icons/Reply'
const AtMention = {

View File

@@ -78,7 +78,7 @@
import MarkdownIt from 'markdown-it'
import MarkdownItTaskCheckbox from 'markdown-it-task-checkbox'
import MarkdownItLinkAttributes from 'markdown-it-link-attributes'
import AttachmentList from './AttachmentList'
import AttachmentList from './AttachmentList.vue'
import { NcActions, NcActionButton, NcModal } from '@nextcloud/vue'
import { formatFileSize } from '@nextcloud/files'
import { generateUrl } from '@nextcloud/router'

View File

@@ -49,8 +49,8 @@
</div>
</template>
<script>
import NcAvatarList from './AvatarList'
import CardMenu from './CardMenu'
import NcAvatarList from './AvatarList.vue'
import CardMenu from './CardMenu.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import AttachmentIcon from 'vue-material-design-icons/Paperclip.vue'
import CheckmarkIcon from 'vue-material-design-icons/CheckboxMarked.vue'

View File

@@ -83,12 +83,12 @@
<script>
import ClickOutside from 'vue-click-outside'
import { mapState, mapGetters } from 'vuex'
import CardBadges from './CardBadges'
import Color from '../../mixins/color'
import labelStyle from '../../mixins/labelStyle'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop'
import CardMenu from './CardMenu'
import DueDate from './badges/DueDate'
import CardBadges from './CardBadges.vue'
import Color from '../../mixins/color.js'
import labelStyle from '../../mixins/labelStyle.js'
import AttachmentDragAndDrop from '../AttachmentDragAndDrop.vue'
import CardMenu from './CardMenu.vue'
import DueDate from './badges/DueDate.vue'
export default {
name: 'CardItem',

View File

@@ -1,38 +1,55 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg"
:height="size"
:width="size"
version="1.1"
viewBox="0 0 16 16">
<rect ry="1"
height="8"
width="14"
y="7"
x="1" />
<rect ry=".5"
height="1"
width="12"
y="5"
x="2" />
<rect ry=".5"
height="1"
width="10"
y="3"
x="3" />
<rect ry=".5"
height="1"
width="8"
y="1"
x="4" />
</svg>
<span :aria-hidden="!title"
:aria-label="title"
class="material-design-icon deck-icon"
role="img"
v-bind="$attrs"
@click="$emit('click', $event)">
<svg xmlns="http://www.w3.org/2000/svg"
:fill="fillColor"
:height="size"
:width="size"
version="1.1"
viewBox="0 0 16 16">
<rect ry="1"
height="8"
width="14"
y="7"
x="1" />
<rect ry=".5"
height="1"
width="12"
y="5"
x="2" />
<rect ry=".5"
height="1"
width="10"
y="3"
x="3" />
<rect ry=".5"
height="1"
width="8"
y="1"
x="4" />
</svg>
</span>
</template>
<script>
export default {
name: 'DeckIcon',
props: {
title: {
type: String,
default: '',
},
fillColor: {
type: String,
default: 'currentColor',
},
size: {
type: Number,
default: 16,
default: 24,
},
},
}

View File

@@ -107,8 +107,8 @@ import axios from '@nextcloud/axios'
import { mapGetters } from 'vuex'
import ClickOutside from 'vue-click-outside'
import { NcAppNavigation, NcAppNavigationItem, NcAppNavigationSettings, NcMultiselect } from '@nextcloud/vue'
import AppNavigationAddBoard from './AppNavigationAddBoard'
import AppNavigationBoardCategory from './AppNavigationBoardCategory'
import AppNavigationAddBoard from './AppNavigationAddBoard.vue'
import AppNavigationBoardCategory from './AppNavigationBoardCategory.vue'
import { loadState } from '@nextcloud/initial-state'
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'

View File

@@ -34,7 +34,7 @@
</template>
<script>
import AppNavigationBoard from './AppNavigationBoard'
import AppNavigationBoard from './AppNavigationBoard.vue'
import { NcAppNavigationItem } from '@nextcloud/vue'
export default {

View File

@@ -80,11 +80,11 @@
<script>
import Controls from '../Controls'
import CardItem from '../cards/CardItem'
import Controls from '../Controls.vue'
import CardItem from '../cards/CardItem.vue'
import { mapGetters } from 'vuex'
import moment from '@nextcloud/moment'
import GlobalSearchResults from '../search/GlobalSearchResults'
import GlobalSearchResults from '../search/GlobalSearchResults.vue'
const FILTER_UPCOMING = 'upcoming'

View File

@@ -52,13 +52,13 @@
</template>
<script>
import CardItem from '../cards/CardItem'
import CardItem from '../cards/CardItem.vue'
import { mapState } from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import InfiniteLoading from 'vue-infinite-loading'
import RichText from '@juliushaertl/vue-richtext'
import Placeholder from './Placeholder'
import Placeholder from './Placeholder.vue'
import { NcActions, NcActionButton } from '@nextcloud/vue'
const createCancelToken = () => axios.CancelToken.source()

View File

@@ -0,0 +1,49 @@
/**
* @copyright Copyright (c) 2022 Julien Veyssier <eneiluj@posteo.net>
*
* @author Julien Veyssier <eneiluj@posteo.net>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { registerWidget } from '@nextcloud/vue-richtext'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import Vue from 'vue'
import CardReferenceWidget from './views/CardReferenceWidget.vue'
import { translate, translatePlural } from '@nextcloud/l10n'
Vue.prototype.t = translate
Vue.prototype.n = translatePlural
Vue.prototype.OC = window.OC
Vue.prototype.OCA = window.OCA
Vue.directive('tooltip', Tooltip)
registerWidget('deck-card', (el, { richObjectType, richObject, accessible }) => {
// trick to change the wrapper element size, otherwise it always is 100%
// which is not very nice with a simple card
el.parentNode.style['max-width'] = '400px'
el.parentNode.style['min-width'] = '200px'
const Widget = Vue.extend(CardReferenceWidget)
new Widget({
propsData: {
richObjectType,
richObject,
accessible,
},
}).$mount(el)
})

View File

@@ -23,8 +23,8 @@
import Vue from 'vue'
import './../css/collections.css'
import FileSharingPicker from './views/FileSharingPicker'
import { buildSelector } from './helpers/selector'
import FileSharingPicker from './views/FileSharingPicker.js'
import { buildSelector } from './helpers/selector.js'
// eslint-disable-next-line
__webpack_nonce__ = btoa(OC.requestToken);
@@ -44,7 +44,7 @@ window.addEventListener('DOMContentLoaded', () => {
window.OCP.Collaboration.registerType('deck', {
action: () => {
const BoardSelector = () => import('./BoardSelector')
const BoardSelector = () => import('./BoardSelector.vue')
return buildSelector(BoardSelector)
},
typeString: t('deck', 'Link to a board'),
@@ -53,7 +53,7 @@ window.addEventListener('DOMContentLoaded', () => {
window.OCP.Collaboration.registerType('deck-card', {
action: () => {
const CardSelector = () => import('./CardSelector')
const CardSelector = () => import('./CardSelector.vue')
return buildSelector(CardSelector)
},
typeString: t('deck', 'Link to a card'),

View File

@@ -23,7 +23,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import overview from './store/overview'
import overview from './store/overview.js'
import './css/dashboard.scss'

View File

@@ -23,9 +23,9 @@
import Vue from 'vue'
import { generateUrl } from '@nextcloud/router'
import CardCreateDialog from './CardCreateDialog'
import { buildSelector } from './helpers/selector'
import './init-collections'
import CardCreateDialog from './CardCreateDialog.vue'
import { buildSelector } from './helpers/selector.js'
import './init-collections.js'
// eslint-disable-next-line
__webpack_nonce__ = btoa(OC.requestToken);

View File

@@ -20,9 +20,9 @@
*
*/
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/main'
import App from './App.vue'
import router from './router.js'
import store from './store/main.js'
import { sync } from 'vuex-router-sync'
import { translate, translatePlural } from '@nextcloud/l10n'
import { generateFilePath } from '@nextcloud/router'
@@ -30,7 +30,7 @@ import { showError } from '@nextcloud/dialogs'
import { subscribe } from '@nextcloud/event-bus'
import { Tooltip } from '@nextcloud/vue'
import ClickOutside from 'vue-click-outside'
import './models'
import './models/index.js'
// the server snap.js conflicts with vertical scrolling so we disable it
document.body.setAttribute('data-snap-ignore', 'true')

View File

@@ -20,7 +20,7 @@
*
*/
import Color from './color'
import Color from './color.js'
export default {
mixins: [Color],

View File

@@ -23,13 +23,13 @@
import Vue from 'vue'
import Router from 'vue-router'
import { generateUrl } from '@nextcloud/router'
import { BOARD_FILTERS } from './store/main'
import Boards from './components/boards/Boards'
import Board from './components/board/Board'
import Sidebar from './components/Sidebar'
import BoardSidebar from './components/board/BoardSidebar'
import CardSidebar from './components/card/CardSidebar'
import Overview from './components/overview/Overview'
import { BOARD_FILTERS } from './store/main.js'
import Boards from './components/boards/Boards.vue'
import Board from './components/board/Board.vue'
import Sidebar from './components/Sidebar.vue'
import BoardSidebar from './components/board/BoardSidebar.vue'
import CardSidebar from './components/card/CardSidebar.vue'
import Overview from './components/overview/Overview.vue'
Vue.use(Router)

View File

@@ -22,7 +22,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import './../models'
import '../models/index.js'
/**
* This class handles all the api communication with the Deck backend.

View File

@@ -22,7 +22,7 @@
import axios from '@nextcloud/axios'
import { generateUrl } from '@nextcloud/router'
import './../models'
import '../models/index.js'
export class StackApi {

View File

@@ -20,7 +20,7 @@
*
*/
import { AttachmentApi } from './../services/AttachmentApi'
import { AttachmentApi } from './../services/AttachmentApi.js'
import Vue from 'vue'
const apiClient = new AttachmentApi()

View File

@@ -20,7 +20,7 @@
*
*/
import { CardApi } from './../services/CardApi'
import { CardApi } from './../services/CardApi.js'
import moment from 'moment'
import Vue from 'vue'

View File

@@ -20,7 +20,7 @@
*
*/
import { CommentApi } from '../services/CommentApi'
import { CommentApi } from '../services/CommentApi.js'
import Vue from 'vue'
const apiClient = new CommentApi()

View File

@@ -27,14 +27,14 @@ import Vue from 'vue'
import Vuex from 'vuex'
import axios from '@nextcloud/axios'
import { generateOcsUrl, generateUrl } from '@nextcloud/router'
import { BoardApi } from '../services/BoardApi'
import actions from './actions'
import stack from './stack'
import card from './card'
import comment from './comment'
import trashbin from './trashbin'
import attachment from './attachment'
import overview from './overview'
import { BoardApi } from '../services/BoardApi.js'
import actions from './actions.js'
import stack from './stack.js'
import card from './card.js'
import comment from './comment.js'
import trashbin from './trashbin.js'
import attachment from './attachment.js'
import overview from './overview.js'
Vue.use(Vuex)
const apiClient = new BoardApi()

View File

@@ -22,7 +22,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import { OverviewApi } from '../services/OverviewApi'
import { OverviewApi } from '../services/OverviewApi.js'
Vue.use(Vuex)
const apiClient = new OverviewApi()

View File

@@ -21,8 +21,8 @@
*/
import Vue from 'vue'
import { StackApi } from './../services/StackApi'
import applyOrderToArray from './../helpers/applyOrderToArray'
import { StackApi } from './../services/StackApi.js'
import applyOrderToArray from './../helpers/applyOrderToArray.js'
const apiClient = new StackApi()

View File

@@ -20,8 +20,8 @@
*
*/
import { StackApi } from '../services/StackApi'
import { CardApi } from '../services/CardApi'
import { StackApi } from '../services/StackApi.js'
import { CardApi } from '../services/CardApi.js'
const stackApi = new StackApi()
const cardApi = new CardApi()

View File

@@ -0,0 +1,235 @@
<!--
- @copyright Copyright (c) 2022 2022 Julien Veyssier <eneiluj@posteo.net>
-
- @author 2022 Julien Veyssier <eneiluj@posteo.net>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<template>
<div class="deck-card-reference">
<h3>
<DeckIcon :size="20" class="icon" />
<a v-tooltip.top="{ content: boardTooltip }"
:href="boardLink"
target="_blank"
class="link">
{{ board.title }}
</a>
<a v-tooltip.top="{ content: stackTooltip }"
:href="boardLink"
target="_blank"
class="link">
/ {{ stack.title }}
</a>
</h3>
<div class="line">
<a :href="cardLink"
:title="cardTooltip"
target="_blank"
class="link">
{{ card.title }}
</a>
<div class="spacer" />
<span v-show="dueDate"
v-tooltip.top="{ content: formattedDueDate }"
class="due-date">
<CalendarBlankIcon :size="20"
class="icon" />
{{ dueDate }}
</span>
</div>
<div>
<transition-group v-if="card.labels && card.labels.length"
name="zoom"
tag="ul"
class="labels"
@click.stop="openCard">
<li v-for="label in labelsSorted" :key="label.id" :style="labelStyle(label)">
<span>{{ label.title }}</span>
</li>
</transition-group>
</div>
<div class="line description-assignees">
<TextIcon v-if="card.description" :size="20" class="icon" />
<div class="description"
:title="card.description">
{{ card.description }}
</div>
<div class="spacer" />
<AvatarList :users="card.assignedUsers" class="card-assignees" />
</div>
</div>
</template>
<script>
import CalendarBlankIcon from 'vue-material-design-icons/CalendarBlank.vue'
import TextIcon from 'vue-material-design-icons/Text.vue'
import DeckIcon from '../components/icons/DeckIcon.vue'
import AvatarList from '../components/cards/AvatarList.vue'
import labelStyle from '../mixins/labelStyle.js'
import moment from '@nextcloud/moment'
import { generateUrl } from '@nextcloud/router'
export default {
name: 'CardReferenceWidget',
components: {
AvatarList,
DeckIcon,
CalendarBlankIcon,
TextIcon,
},
mixins: [labelStyle],
props: {
richObjectType: {
type: String,
default: '',
},
richObject: {
type: Object,
default: null,
},
accessible: {
type: Boolean,
default: true,
},
},
data() {
return {
}
},
computed: {
card() {
return this.richObject.card
},
board() {
return this.richObject.board
},
stack() {
return this.richObject.stack
},
cardLink() {
return generateUrl('/apps/deck/#/board/{boardId}/card/{cardId}', { boardId: this.board.id, cardId: this.card.id })
},
boardLink() {
return generateUrl('/apps/deck/#/board/{boardId}', { boardId: this.board.id })
},
cardTooltip() {
return t('deck', '* Created on {created}\n* Last modified on {lastMod}\n* {nbAttachments} attachments\n* {nbComments} comments', {
created: moment.unix(this.card.createdAt).format('LLL'),
lastMod: moment.unix(this.card.lastModified).format('LLL'),
nbAttachments: this.card.attachments.length,
nbComments: this.card.commentsCount,
})
},
boardTooltip() {
return t('deck', 'Owned by {dn}', { dn: this.board.owner.displayname })
},
stackTooltip() {
return t('deck', '{nbCards} cards', { nbCards: this.stack.cards.length })
},
dueDate() {
return this.card.duedate
? moment(this.card.duedate).fromNow()
: null
},
formattedDueDate() {
return this.card.duedate
? t('deck', 'Due on {date}', { date: moment(this.card.duedate).format('LLL') })
: null
},
labelsSorted() {
return [...this.card.labels].sort((a, b) => (a.title < b.title) ? -1 : 1)
},
},
methods: {
},
}
</script>
<style scoped lang="scss">
/* stylelint-disable-next-line no-invalid-position-at-import-rule */
@import '../css/labels';
.deck-card-reference {
width: 100%;
white-space: normal;
padding: 12px;
h3 {
display: flex;
align-items: center;
justify-content: center;
margin: 0 0 8px 0;
font-weight: bold;
.icon {
margin-right: 8px;
}
}
.link:hover {
text-decoration: underline;
}
.line {
display: flex;
align-items: center;
.icon {
margin-right: 4px;
}
}
.due-date {
display: flex;
align-items: center;
}
.labels {
margin: 8px 0;
}
.description-assignees {
width: 100%;
display: flex;
align-items: center;
.description {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
margin-right: 8px;
}
.card-assignees {
margin-top: 0;
height: 36px;
flex-grow: unset;
}
}
.spacer {
flex-grow: 1;
}
}
</style>

View File

@@ -59,10 +59,10 @@
<script>
import { NcDashboardWidget } from '@nextcloud/vue'
import { mapGetters } from 'vuex'
import labelStyle from './../mixins/labelStyle'
import DueDate from '../components/cards/badges/DueDate'
import labelStyle from './../mixins/labelStyle.js'
import DueDate from '../components/cards/badges/DueDate.vue'
import { generateUrl } from '@nextcloud/router'
import CardCreateDialog from '../CardCreateDialog'
import CardCreateDialog from '../CardCreateDialog.vue'
export default {
name: 'Dashboard',

View File

@@ -21,7 +21,7 @@
*/
import Vue from 'vue'
import { createShare } from '../services/SharingApi'
import { createShare } from '../services/SharingApi.js'
export default {
icon: 'icon-deck',
@@ -33,7 +33,7 @@ export default {
container.id = 'deck-board-select'
const body = document.getElementById('body-user')
body.append(container)
const CardSelector = () => import('./../CardSelector')
const CardSelector = () => import('./../CardSelector.vue')
const ComponentVM = new Vue({
render: (h) => h(CardSelector, {
title: t('deck', 'Share {file} with a Deck card', { file: decodeURIComponent(self.fileInfo.name) }),