Commit abc961ec authored by Anton Koch's avatar Anton Koch
Browse files

Merge branch '576-tags-page' into 'master'

Resolve "create tags page"

See merge request !157
parents 9ad395e1 2a11a873
<template lang="pug">
.dialog
mb-input-text(label="Title" v-model="itemTitle")
.q-mt-md
mb-btn(:label="$t('general.save_changes')")
</template>
<script>
export default {
name: 'DialogTagsCollectionsMore',
props: ['item'],
data () {
return {
itemTitle: this.item.title
}
}
}
</script>
<style scoped>
</style>
......@@ -6,12 +6,12 @@
v-model="mediaObj.file"
:label="$t('messages.drop_upload_media')"
:clearable="true"
:hint="$t('messages.supported_files', { files: ' *.mp3, *.png, *.jpg, *.mp4, *.wav' })"
:hint="$t('messages.supported_files', { files: '*.mp3, *.png, *.jpg, *.mp4, *.wav' })"
)
// Define uploaded file ----------------------------------------------------------------------------------------------
.handle-file(v-if="mediaObj.file")
.text-body2.q-mb-sm {{$t('messages.define_media')}}}
.text-body2.q-mb-sm {{$t('messages.define_media')}}
// Display File and Text Inputs ------------------------------------------------------------------------------------
.row.q-mb-xl
......
<template lang="pug">
.tag-overlay-
mb-list
// projects ------------------------------------------------------------------------------------------------------
div
mb-list(:dense="true")
q-item
// grids
mb-expansion-item(
mb-expansion-item.full-width(
icon="grid_on"
:label="$('grids.title')"
:label="$t('grids.title')"
:group="expansionItems.group"
:slim-header="true"
)
......@@ -18,12 +15,12 @@
.col-3
mb-card(:data="{title: 'this is a card title', previewSrc: 'https://picsum.photos/200/300' }")
// timelines
mb-expansion-item(
// timelines
q-item
mb-expansion-item.full-width(
icon="linear_scale"
:label="$('timelines.title')"
:label="$t('timelines.title')"
:group="expansionItems.group"
:no-border="true"
:slim-header="true"
)
.row.q-col-gutter-md.q-pt-md
......@@ -31,12 +28,10 @@
.col-3
mb-card(:data="{title: 'this is a card title', previewSrc: 'https://picsum.photos/200/300' }")
// ---------------------------------------------------------------------------------------------------------------
.q-mt-xl
// media
mb-expansion-item(
:label="$('general.assets')"
// media
q-item
mb-expansion-item.full-width(
:label="$t('general.assets')"
:slim-header="true"
)
.row.q-col-gutter-md.q-pt-md
......@@ -44,9 +39,10 @@
.col-3
mb-card(:data="{title: 'this is a card title', previewSrc: 'https://picsum.photos/200/300' }")
// annotations
mb-expansion-item(
:label="$('timelines.annotations.title')"
// annotations
q-item
mb-expansion-item.full-width(
:label="$t('timelines.annotations.title')"
:slim-header="true"
)
// annotation list
......@@ -60,31 +56,12 @@
@click.native="createDummyAnnotations()"
:label="$t('timelines.annotations.load_more')"
)
// collections
mb-expansion-item(
:label="$t('general.collections')"
:slim-header="true"
:no-border="true"
)
// annotation list
mb-table-list.q-my-md(
:items="dummyData.annotations"
)
// load more button
.text-center
mb-btn(
@click.native="createDummyAnnotations()"
:label="$t('timelines.annotations.load_more')"
)
</template>
<script>
export default {
name: 'TagOverlayContent',
props: ['data'],
name: 'DialogOverlayTag',
props: ['tag'],
data () {
return {
expansionItems: {
......@@ -99,6 +76,7 @@ export default {
}
},
mounted () {
// TODO: Get everything tagged with this.tag by user. To display it.
this.createDummyAnnotations()
},
methods: {
......
......@@ -5,14 +5,15 @@
.mb-subheadline.q-mb-sm(v-if="$slots['list-header']")
slot(name="list-header")
q-list
q-list(:dense="dense")
slot
</template>
<script>
export default {
name: 'MbList'
name: 'MbList',
props: ['dense']
}
</script>
......
......@@ -35,7 +35,7 @@
:multiple="true",
:model="model.visibleColumns"
:option-value="'name'",
:display-value="$t('general.optionalColumns')"
:display-value="$t('general.optional_columns')"
:class="{'full-width': forceGridMode}"
@input="onColumnSelectInput"
)
......
......@@ -24,6 +24,7 @@
// Pagination ----------------------------------------------------------------------------------------------------
template(v-slot:pagination="scope")
table-pagination-module(
v-if="items.length > pagination.rowsPerPage"
:scope="scope"
@input="onRowsPerPage"
)
......
......@@ -27,5 +27,7 @@ export default {
add: 'Add',
add_user: 'Add user',
assets: 'Assets',
search: 'Search'
search: 'Search',
preview: 'Preview',
optional_columns: 'Optional Columns'
}
......@@ -11,5 +11,6 @@ export default {
define_media: 'Define Media',
supported_files: 'Supported files: {files}',
drop_upload_media: 'Drop or upload media',
edit_collection: 'Edit Collection'
edit_assets_collection: 'Edit assets collection',
edit_tags_collection: 'Edit tags collection'
}
......@@ -15,7 +15,7 @@
behavior="mobile"
content-class="mb-bg-bg mb-border-r-light"
)
q-scroll-area.full-width.full-height
q-scroll-area.fit
nav-drawer-content(v-model="left")
// PAGE ------------------------------------------------------------------------------------------------------------
......
......@@ -478,6 +478,9 @@
title="mb-list"
link="https://quasar.dev/vue-components/list-and-list-items#introduction"
)
template(v-slot:props)
div dense :
span.text-mb-green-100 Boolean
template(v-slot:slots)
div.text-mb-red-100 list-header
div.text-mb-red-100 default (unnamed)
......
......@@ -10,7 +10,7 @@ div
// More Clicked
mb-dialog(
width="50vw"
:label="$t('messages.edit_collection')"
:label="$t('messages.edit_assets_collection')"
v-model="moreClick.showMore"
)
dialog-assets-collections-more(
......
......@@ -36,13 +36,13 @@
{
name: 'preview',
field: 'preview',
label: this.$t('fields.preview'),
label: this.$t('general.preview'),
align: 'left'
},
{
name: 'title',
field: 'title',
label: this.$t('fields.title'),
label: this.$t('general.title'),
align: 'left',
sortable: true,
filter: true,
......@@ -51,7 +51,7 @@
{
name: 'updatedAt',
field: 'updatedAt',
label: this.$t('fields.updated'),
label: this.$t('general.updated'),
align: 'left',
sortable: true,
format: val => val ? DateTime.fromISO(val).toLocaleString(DateTime.DATETIME_SHORT) : ''
......@@ -59,7 +59,7 @@
{
name: 'createdAt',
field: 'createdAt',
label: this.$t('fields.created'),
label: this.$t('general.created'),
align: 'left',
sortable: true,
format: val => val ? DateTime.fromISO(val).toLocaleString(DateTime.DATETIME_SHORT) : ''
......
<template lang="pug">
div
.mb-subheadline.q-mb-lg {{$t('general.collections')}}
mb-table-list(
:items="collections"
@itemSelected="selectCollection"
@moreClicked="handleMore"
)
// More Clicked
mb-dialog(
width="50vw"
:label="$t('messages.edit_tag_collection')"
v-model="moreClick.showMore"
)
dialog-tags-collections-more(
:item="moreClick.clickedItem"
)
</template>
<script>
import DialogTagsCollectionsMore from 'components/MbComponents/MbDialog/DialogContents/Tags/DialogTagsCollectionsMore'
export default {
name: 'TagsCollections',
components: { DialogTagsCollectionsMore },
data () {
return {
collections: [
{
id: '1',
title: 'Collection 1'
}, {
id: '2',
title: 'Collection 2'
}, {
id: '3',
title: 'Collection 3'
}, {
id: '4',
title: 'Collection 4'
}
],
moreClick: {
clickedItem: undefined,
showMore: false
}
}
},
methods: {
selectCollection (item) {
this.$emit('setSelectedCollection', item)
},
handleMore (item) {
this.moreClick.clickedItem = item
this.moreClick.showMore = true
}
}
}
</script>
<style scoped>
</style>
<template lang="pug">
.row
template(v-for="alphabeticalGroup in tags")
// List for each Letter Group
mb-list.q-mb-xl.col-lg-2.col-md-3.col-sm-4.col-xs-6(:dense="true")
// Letter Headline
template(v-slot:list-header)
.mb-subheadline {{alphabeticalGroup[0].label.charAt(0).toUpperCase()}}
// Tags for each Letter
q-item(dense v-for="tag in alphabeticalGroup" :key="tag.id")
mb-chip(
:clickable="true"
@click.native="showTagOverlay(tag)"
:label="`#${tag.label}`"
)
</template>
<script>
export default {
name: 'TagsList',
props: ['tags'],
data () {
return {
showOverlay: false
}
},
methods: {
showTagOverlay (tag) {
this.$emit('showTagOverlay', tag)
}
}
}
</script>
<style scoped>
</style>
export default {
name: 'TagsDataProvider',
data () {
return {
searchString: undefined,
tags: [
// Dummy Data
{
id: 'tag-1',
label: 'probe',
type: 'tag',
collections: [4]
}, {
id: 'tag-2',
label: 'Motion Bank',
type: 'tag',
collections: [1]
}, {
id: 'tag-3',
label: 'summer semester 2017',
type: 'tag',
collections: [2, 1]
}, {
id: 'tag-4',
label: 'WS2018',
type: 'tag',
collections: [2, 4]
}, {
id: 'tag-5',
label: 'motion capture',
type: 'tag',
collections: [1, 3]
}, {
id: 'tag-6',
label: 'Proberaum',
type: 'tag',
collections: []
}, {
id: 'tag-7',
label: 'Staatstheater Mainz',
type: 'tag',
collections: [3]
}, {
id: 'tag-8',
label: 'Hochschule Mainz',
type: 'tag',
collections: [2, 1, 4]
}, {
id: 'tag-9',
label: 'Frankfurt',
type: 'tag',
collections: [1, 2, 3, 4]
}, {
id: 'tag-10',
label: 'Mainz',
type: 'tag',
collections: []
}, {
id: 'tag-11',
label: 'Kunsthalle Mainz',
type: 'tag',
collections: [4]
}
]
}
},
computed: {
sortedTags () {
if (this.tagsToSort) {
return this.tagsToSort.sort((a, b) => a.label.localeCompare(b.label)).reduce((obj, tag) => {
const key = tag.label.charAt(0).toLowerCase()
if (!obj[key]) obj[key] = []
obj[key].push(tag)
return obj
}, {})
}
else {
return undefined
}
},
// Applying the Search string
tagsToSort () {
if (this.searchString || this.selectedCollection) {
return this.tags.filter(tag => {
const label = tag.label.toLowerCase()
const searchStr = this.searchString
? this.searchString.toLowerCase().replace('#', '')
: undefined
const collections = tag.collections
// Filter Tags
if (searchStr && this.selectedCollection) {
return label.includes(searchStr) && collections.includes(Number(this.selectedCollection))
}
else if (searchStr) {
return label.includes(searchStr)
}
else if (this.selectedCollection) {
// TODO: Rewite with real data
return collections.includes(Number(this.selectedCollection))
}
})
}
else {
return this.tags
}
}
}
// TODO: Get tags used by user
}
<template lang="pug">
div
// Right Side Drawer // Collections ----------------------------------------------------------------------------------
q-drawer(
v-if="!mobileLayout"
v-model="collections"
side="right"
behavior="desktop"
show-if-above
content-class="mb-bg-bg mb-border-l-light"
)
q-scroll-area.drawer.fit.q-pa-md.q-pt-lg
tags-collections(@setSelectedCollection="setSelectedCollection")
// Mobile Collections
mb-dialog-overlay(
v-else
v-model="collections"
:label="$t('general.collections')"
)
template(v-slot:overlay-body)
tags-collections(@setSelectedCollection="setSelectedCollection")
// Left Side Content -------------------------------------------------------------------------------------------------
.mb-content-outer
.mb-content-inner.q-py-lg
// Search bar & Collections toggle
q-item.q-pa-none.q-mb-md
q-item-section
// Search and tools
mb-input-text(
label="Search"
v-model="searchString"
icon-name="search"
:clearable="true"
)
q-item-section.flex.items-end
// Hide / Show Collections
mb-btn(
:icon-name="collections ? 'visibility_off' : 'visibility'"
:label="$t('general.collections')"
@click.native="collections = !collections"
)
// Display selected collection on mobile
.q-mb-md(v-if="$q.screen.lt.md && selectedCollection")
.text-caption.q-mb-xs Selected Collections
// TODO: Rewrite with mBtableList
mb-btn(
:label="'Collection ' + selectedCollection"
@click.native="removeSelectedCollection"
:secondary="true"
icon-name="close"
)
// Tags Content
tags-list(:tags="sortedTags" @showTagOverlay="showTagOverlay")
// Tag Overlay
mb-dialog-overlay(v-model="tagOverlay.model" v-if="tagOverlay.tag")
// Label
template(v-slot:overlay-header)
span
mb-chip(
:clickable="true"
:label="`#${tagOverlay.tag.label}`"
)
// Overlay Content
template(v-slot:overlay-body)
dialog-overlay-tag(:tag="tagOverlay.tag")
</template>
<script>
import TagsCollections from 'pages/tags/Sub/TagsCollections'
import TagsDataProvider from 'pages/tags/tags-data-provider'
import TagsList from 'pages/tags/Sub/TagsList'
import DialogOverlayTag from 'components/MbComponents/MbDialogOverlay/OverlayContents/Tags/DialogOverlayTag'
export default {
name: 'tags',
extends: TagsDataProvider,
components: { DialogOverlayTag, TagsList, TagsCollections },
data () {
return {
collections: false,
tagOverlay: {
model: false,
tag: undefined
},
selectedCollection: undefined
}
},
computed: {
mobileLayout () {
return this.$q.screen.lt.md
}
},
methods: {
showTagOverlay (tag) {
this.tagOverlay.model = true
this.tagOverlay.tag = tag
},
// TODO: Rewrite with new MbTableList Component (Return the complete item)
setSelectedCollection (item) {
this.selectedCollection = item ? item.id : undefined
},
removeSelectedCollection () {
this.selectedCollection = undefined
}
}
}
</script>
<style lang="stylus" scoped>
</style>
import users from './users'
import piecemaker from './piecemaker'
import tags from './tags'
import assets from './assets'
import projects from './projects'
import groups from './groups'
......@@ -28,6 +29,7 @@ const routes = [
},
users,
piecemaker,
tags,
projects,
assets,
groups
......