feat: add a new CardModal component
Signed-off-by: Luka Trovic <luka@nextcloud.com>
This commit is contained in:
3
img/flash-black.svg
Normal file
3
img/flash-black.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve"><g><g><polygon points="426.667,213.333 288.36,213.333 333.706,0 148.817,0 85.333,298.667 227.556,298.667 227.556,512 " /></g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg>
|
||||
|
After Width: | Height: | Size: 594 B |
1
img/plus.svg
Normal file
1
img/plus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="#26e07f" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24px" height="24px"><path fill-rule="evenodd" d="M 11 2 L 11 11 L 2 11 L 2 13 L 11 13 L 11 22 L 13 22 L 13 13 L 22 13 L 22 11 L 13 11 L 13 2 Z"/></svg>
|
||||
|
After Width: | Height: | Size: 235 B |
@@ -160,7 +160,7 @@ export default {
|
||||
width: 50vw;
|
||||
max-width: 800px;
|
||||
min-height: 200px;
|
||||
height: 80vh;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -170,4 +170,7 @@ export default {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.modal-wrapper--normal .modal-container{
|
||||
width: 800px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
287
src/components/card/CardModal.vue
Normal file
287
src/components/card/CardModal.vue
Normal file
@@ -0,0 +1,287 @@
|
||||
<!--
|
||||
- @copyright Copyright (c) 2018 Julius Härtl <jus@bitgrid.net>
|
||||
-
|
||||
- @author Julius Härtl <jus@bitgrid.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="container">
|
||||
<div class="top">
|
||||
<h1 class="top-title">
|
||||
Example task 3
|
||||
</h1>
|
||||
<p class="top-modified">
|
||||
Modified: 2 days go. Created 3 days ago
|
||||
</p>
|
||||
</div>
|
||||
<div class="tabs">
|
||||
<div class="tab members">
|
||||
<i class="icon-user icon" />
|
||||
Members
|
||||
</div>
|
||||
<div class="tab tags">
|
||||
<i class="icon icon-tag" />
|
||||
Tags
|
||||
</div>
|
||||
<div class="tab due-date">
|
||||
<i class="icon icon-calendar-dark" />
|
||||
Due date
|
||||
</div>
|
||||
<div class="tab project">
|
||||
<i class="icon icon-deck" />
|
||||
Project
|
||||
</div>
|
||||
<div class="tab attachments">
|
||||
<i class="icon-attach icon icon-attach-dark" />
|
||||
Attachments
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="description">
|
||||
<h2>Description</h2>
|
||||
<p>Write a description</p>
|
||||
</div>
|
||||
<div class="edit-btns">
|
||||
<ActionButton icon="icon-info" class="action-btn" />
|
||||
<ActionButton icon="icon-rename" class="action-btn" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="activities">
|
||||
<h2 class="activities-title">
|
||||
<div class="icon-flash-black" /> Activities
|
||||
</h2>
|
||||
<div class="comment">
|
||||
<Avatar :user="currentUser.uid" />
|
||||
<input v-model="comment"
|
||||
type="text"
|
||||
:placeholder="t('deck', 'Leave a comment')"
|
||||
class="comment-input">
|
||||
</div>
|
||||
<div class="activities-logs">
|
||||
<p class="log-item">
|
||||
<i class="icon-plus" /> You have created card Example Task 3 in list To do on board Personal
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ActionButton, Avatar } from '@nextcloud/vue'
|
||||
import { generateUrl } from '@nextcloud/router'
|
||||
import { mapState, mapGetters } from 'vuex'
|
||||
import relativeDate from '../../mixins/relativeDate'
|
||||
import { showError } from '@nextcloud/dialogs'
|
||||
import { getCurrentUser } from '@nextcloud/auth'
|
||||
|
||||
const capabilities = window.OC.getCapabilities()
|
||||
|
||||
export default {
|
||||
name: 'CardModal',
|
||||
components: { Avatar, ActionButton },
|
||||
mixins: [relativeDate],
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
tabId: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
tabQuery: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
titleEditable: false,
|
||||
titleEditing: '',
|
||||
hasActivity: capabilities && capabilities.activity,
|
||||
currentUser: getCurrentUser(),
|
||||
comment: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
currentBoard: state => state.currentBoard,
|
||||
}),
|
||||
...mapGetters(['canEdit', 'assignables', 'cardActions', 'stackById']),
|
||||
title() {
|
||||
return this.titleEditable ? this.titleEditing : this.currentCard.title
|
||||
},
|
||||
currentCard() {
|
||||
return this.$store.getters.cardById(this.id)
|
||||
},
|
||||
subtitle() {
|
||||
return t('deck', 'Modified') + ': ' + this.relativeDate(this.currentCard.lastModified * 1000) + ' ' + t('deck', 'Created') + ': ' + this.relativeDate(this.currentCard.createdAt * 1000)
|
||||
},
|
||||
cardRichObject() {
|
||||
return {
|
||||
id: '' + this.currentCard.id,
|
||||
name: this.currentCard.title,
|
||||
boardname: this.currentBoard.title,
|
||||
stackname: this.stackById(this.currentCard.stackId)?.title,
|
||||
link: window.location.protocol + '//' + window.location.host + generateUrl('/apps/deck/') + `#/board/${this.currentBoard.id}/card/${this.currentCard.id}`,
|
||||
}
|
||||
},
|
||||
cardDetailsInModal: {
|
||||
get() {
|
||||
return this.$store.getters.config('cardDetailsInModal')
|
||||
},
|
||||
set(newValue) {
|
||||
this.$store.dispatch('setConfig', { cardDetailsInModal: newValue })
|
||||
},
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleUpdateTitleEditable(value) {
|
||||
this.titleEditable = value
|
||||
if (value) {
|
||||
this.titleEditing = this.currentCard.title
|
||||
}
|
||||
},
|
||||
handleUpdateTitle(value) {
|
||||
this.titleEditing = value
|
||||
},
|
||||
handleSubmitTitle(value) {
|
||||
if (value.trim === '') {
|
||||
showError(t('deck', 'The title cannot be empty.'))
|
||||
return
|
||||
}
|
||||
this.titleEditable = false
|
||||
this.$store.dispatch('updateCardTitle', { ...this.currentCard, title: this.titleEditing })
|
||||
},
|
||||
|
||||
closeSidebar() {
|
||||
this.$router.push({ name: 'board' })
|
||||
},
|
||||
|
||||
showModal() {
|
||||
this.$store.dispatch('setConfig', { cardDetailsInModal: true })
|
||||
},
|
||||
closeModal() {
|
||||
this.$store.dispatch('setConfig', { cardDetailsInModal: false })
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icon-flash-black{
|
||||
background-image: url(../../../img/flash-black.svg);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.icon-plus{
|
||||
background-image: url(../../../img/plus.svg);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.log-item{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
line-height: 45px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.activities{
|
||||
&-title{
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.comment{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
&-input{
|
||||
width: 100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.container{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.top{
|
||||
&-title{
|
||||
color: black;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
&-modified{
|
||||
color: #767676;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs{
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
grid-gap: 30px;
|
||||
}
|
||||
|
||||
.tab{
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
background-color: #ededed;
|
||||
color: rgb(0, 0, 0);
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
padding: 10px 10px;
|
||||
border-radius: 5px;
|
||||
font-size: 85%;
|
||||
margin-bottom: 3px;
|
||||
margin-right: 5px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.action-btn{
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.content{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.edit-btns{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -28,7 +28,7 @@ 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 CardModal from './components/card/CardModal'
|
||||
import Overview from './components/overview/Overview'
|
||||
|
||||
Vue.use(Router)
|
||||
@@ -119,7 +119,7 @@ export default new Router({
|
||||
path: 'card/:cardId/:tabId?/:tabQuery?',
|
||||
name: 'card',
|
||||
components: {
|
||||
sidebar: CardSidebar,
|
||||
sidebar: CardModal,
|
||||
},
|
||||
props: {
|
||||
default: (route) => {
|
||||
|
||||
Reference in New Issue
Block a user