create new list UI
This commit is contained in:
parent
b4f4b370d4
commit
faefd05c03
|
@ -80,6 +80,7 @@ export default (store) => {
|
||||||
{ name: 'lists', path: '/lists', component: Lists },
|
{ name: 'lists', path: '/lists', component: Lists },
|
||||||
{ name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline },
|
{ name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline },
|
||||||
{ name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit },
|
{ name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit },
|
||||||
|
{ name: 'lists-edit', path: '/lists/new', component: ListsEdit },
|
||||||
{ name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute }
|
{ name: 'edit-navigation', path: '/nav-edit', component: NavPanel, props: () => ({ forceExpand: true, forceEditMode: true }), beforeEnter: validateAuthenticatedRoute }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import ListsCard from '../lists_card/lists_card.vue'
|
import ListsCard from '../lists_card/lists_card.vue'
|
||||||
import ListsNew from '../lists_new/lists_new.vue'
|
|
||||||
|
|
||||||
const Lists = {
|
const Lists = {
|
||||||
data () {
|
data () {
|
||||||
|
@ -8,8 +7,7 @@ const Lists = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
ListsCard,
|
ListsCard
|
||||||
ListsNew
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
lists () {
|
lists () {
|
||||||
|
|
|
@ -1,21 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="isNew">
|
<div class="Lists panel panel-default">
|
||||||
<ListsNew @cancel="cancelNewList" />
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="settings panel panel-default"
|
|
||||||
>
|
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
{{ $t('lists.lists') }}
|
{{ $t('lists.lists') }}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<router-link
|
||||||
class="button-default"
|
:to="{ name: 'lists-edit' }"
|
||||||
@click="newList"
|
class="button-default btn new-list-button"
|
||||||
>
|
>
|
||||||
{{ $t("lists.new") }}
|
{{ $t("lists.new") }}
|
||||||
</button>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ListsCard
|
<ListsCard
|
||||||
|
@ -29,3 +23,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./lists.js"></script>
|
<script src="./lists.js"></script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.Lists {
|
||||||
|
.new-list-button {
|
||||||
|
padding: 0 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -36,6 +36,7 @@ const ListsNew = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
|
if (!this.id) return
|
||||||
this.$store.dispatch('fetchList', { listId: this.id })
|
this.$store.dispatch('fetchList', { listId: this.id })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.title = this.findListTitle(this.id)
|
this.title = this.findListTitle(this.id)
|
||||||
|
@ -71,19 +72,19 @@ const ListsNew = {
|
||||||
},
|
},
|
||||||
toggleRemoveMember (user) {
|
toggleRemoveMember (user) {
|
||||||
if (this.removedUserIds.has(user.id)) {
|
if (this.removedUserIds.has(user.id)) {
|
||||||
this.addUser(user)
|
this.id && this.addUser(user)
|
||||||
this.removedUserIds.delete(user.id)
|
this.removedUserIds.delete(user.id)
|
||||||
} else {
|
} else {
|
||||||
this.removeUser(user.id)
|
this.id && this.removeUser(user.id)
|
||||||
this.removedUserIds.add(user.id)
|
this.removedUserIds.add(user.id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleAddFromSearch (user) {
|
toggleAddFromSearch (user) {
|
||||||
if (this.addedUserIds.has(user.id)) {
|
if (this.addedUserIds.has(user.id)) {
|
||||||
this.removeUser(user.id)
|
this.id && this.removeUser(user.id)
|
||||||
this.addedUserIds.delete(user.id)
|
this.addedUserIds.delete(user.id)
|
||||||
} else {
|
} else {
|
||||||
this.addUser(user)
|
this.id && this.addUser(user)
|
||||||
this.addedUserIds.add(user.id)
|
this.addedUserIds.add(user.id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -115,6 +116,25 @@ const ListsNew = {
|
||||||
this.title = this.findListTitle(this.id)
|
this.title = this.findListTitle(this.id)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
createList () {
|
||||||
|
this.$store.dispatch('createList', { title: this.titleDraft })
|
||||||
|
.then((list) => {
|
||||||
|
return this
|
||||||
|
.$store
|
||||||
|
.dispatch('setListAccounts', { listId: list.id, accountIds: [...this.addedUserIds] })
|
||||||
|
.then(() => list.id)
|
||||||
|
})
|
||||||
|
.then((listId) => {
|
||||||
|
this.$router.push({ name: 'lists-timeline', params: { id: listId } })
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
this.$store.dispatch('pushGlobalNotice', {
|
||||||
|
messageKey: 'lists.error',
|
||||||
|
messageArgs: [e.message],
|
||||||
|
level: 'error'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
deleteList () {
|
deleteList () {
|
||||||
this.$store.dispatch('deleteList', { listId: this.id })
|
this.$store.dispatch('deleteList', { listId: this.id })
|
||||||
this.$router.push({ name: 'lists' })
|
this.$router.push({ name: 'lists' })
|
||||||
|
|
|
@ -15,12 +15,17 @@
|
||||||
</button>
|
</button>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<i18n-t
|
<i18n-t
|
||||||
|
v-if="id"
|
||||||
keypath="lists.editing_list"
|
keypath="lists.editing_list"
|
||||||
>
|
>
|
||||||
<template #listTitle>
|
<template #listTitle>
|
||||||
{{ title }}
|
{{ title }}
|
||||||
</template>
|
</template>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
|
<i18n-t
|
||||||
|
v-else
|
||||||
|
keypath="lists.creating_list"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
@ -33,6 +38,7 @@
|
||||||
v-model="titleDraft"
|
v-model="titleDraft"
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
v-if="id"
|
||||||
class="btn button-default follow-button"
|
class="btn button-default follow-button"
|
||||||
@click="updateListTitle"
|
@click="updateListTitle"
|
||||||
>
|
>
|
||||||
|
@ -44,6 +50,7 @@
|
||||||
:scrollable-tabs="true"
|
:scrollable-tabs="true"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
v-if="id || addedUserIds.size > 0"
|
||||||
:label="$t('lists.manage_members')"
|
:label="$t('lists.manage_members')"
|
||||||
class="members-list"
|
class="members-list"
|
||||||
>
|
>
|
||||||
|
@ -122,8 +129,15 @@
|
||||||
<div class="panel-footer">
|
<div class="panel-footer">
|
||||||
<span class="spacer" />
|
<span class="spacer" />
|
||||||
<button
|
<button
|
||||||
v-if="!reallyDelete"
|
v-if="!id"
|
||||||
class="btn button-default delete-button"
|
class="btn button-default footer-button"
|
||||||
|
@click="createList"
|
||||||
|
>
|
||||||
|
{{ $t('lists.create') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
v-else-if="!reallyDelete"
|
||||||
|
class="btn button-default footer-button"
|
||||||
@click="reallyDelete = true"
|
@click="reallyDelete = true"
|
||||||
>
|
>
|
||||||
{{ $t('lists.delete') }}
|
{{ $t('lists.delete') }}
|
||||||
|
@ -131,13 +145,13 @@
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ $t('lists.really_delete') }}
|
{{ $t('lists.really_delete') }}
|
||||||
<button
|
<button
|
||||||
class="btn button-default delete-button"
|
class="btn button-default footer-button"
|
||||||
@click="deleteList"
|
@click="deleteList"
|
||||||
>
|
>
|
||||||
{{ $t('general.yes') }}
|
{{ $t('general.yes') }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="btn button-default delete-button"
|
class="btn button-default footer-button"
|
||||||
@click="reallyDelete = false"
|
@click="reallyDelete = false"
|
||||||
>
|
>
|
||||||
{{ $t('general.no') }}
|
{{ $t('general.no') }}
|
||||||
|
@ -206,7 +220,7 @@
|
||||||
.panel-footer {
|
.panel-footer {
|
||||||
grid-template-columns: minmax(10%, 1fr);
|
grid-template-columns: minmax(10%, 1fr);
|
||||||
|
|
||||||
.delete-button {
|
.footer-button {
|
||||||
min-width: 9em;
|
min-width: 9em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
import { mapState, mapGetters } from 'vuex'
|
|
||||||
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
|
|
||||||
import UserAvatar from '../user_avatar/user_avatar.vue'
|
|
||||||
import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
|
|
||||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
|
||||||
import {
|
|
||||||
faSearch,
|
|
||||||
faChevronLeft
|
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
|
||||||
|
|
||||||
library.add(
|
|
||||||
faSearch,
|
|
||||||
faChevronLeft
|
|
||||||
)
|
|
||||||
|
|
||||||
const ListsNew = {
|
|
||||||
components: {
|
|
||||||
BasicUserCard,
|
|
||||||
UserAvatar,
|
|
||||||
ListsUserSearch
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
title: '',
|
|
||||||
userIds: [],
|
|
||||||
selectedUserIds: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
users () {
|
|
||||||
return this.userIds.map(userId => this.findUser(userId))
|
|
||||||
},
|
|
||||||
selectedUsers () {
|
|
||||||
return this.selectedUserIds.map(userId => this.findUser(userId))
|
|
||||||
},
|
|
||||||
...mapState({
|
|
||||||
currentUser: state => state.users.currentUser
|
|
||||||
}),
|
|
||||||
...mapGetters(['findUser'])
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
goBack () {
|
|
||||||
this.$emit('cancel')
|
|
||||||
},
|
|
||||||
onInput () {
|
|
||||||
this.search(this.query)
|
|
||||||
},
|
|
||||||
selectUser (user) {
|
|
||||||
if (this.selectedUserIds.includes(user.id)) {
|
|
||||||
this.removeUser(user.id)
|
|
||||||
} else {
|
|
||||||
this.addUser(user)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isSelected (user) {
|
|
||||||
return this.selectedUserIds.includes(user.id)
|
|
||||||
},
|
|
||||||
addUser (user) {
|
|
||||||
this.selectedUserIds.push(user.id)
|
|
||||||
},
|
|
||||||
removeUser (userId) {
|
|
||||||
this.selectedUserIds = this.selectedUserIds.filter(id => id !== userId)
|
|
||||||
},
|
|
||||||
onResults (results) {
|
|
||||||
this.userIds = results
|
|
||||||
},
|
|
||||||
createList () {
|
|
||||||
// the API has two different endpoints for "creating a list with a name"
|
|
||||||
// and "updating the accounts on the list".
|
|
||||||
this.$store.dispatch('createList', { title: this.title })
|
|
||||||
.then((list) => {
|
|
||||||
this.$store.dispatch('setListAccounts', { listId: list.id, accountIds: this.selectedUserIds })
|
|
||||||
this.$router.push({ name: 'lists-timeline', params: { listId: list.id } })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ListsNew
|
|
|
@ -1,95 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="panel-default panel list-new">
|
|
||||||
<div
|
|
||||||
ref="header"
|
|
||||||
class="panel-heading"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="button-unstyled go-back-button"
|
|
||||||
@click="goBack"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
size="lg"
|
|
||||||
icon="chevron-left"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="input-wrap">
|
|
||||||
<input
|
|
||||||
ref="title"
|
|
||||||
v-model="title"
|
|
||||||
:placeholder="$t('lists.title')"
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="member-list">
|
|
||||||
<div
|
|
||||||
v-for="user in selectedUsers"
|
|
||||||
:key="user.id"
|
|
||||||
class="member"
|
|
||||||
>
|
|
||||||
<BasicUserCard
|
|
||||||
:user="user"
|
|
||||||
:class="isSelected(user) ? 'selected' : ''"
|
|
||||||
@click.capture.prevent="selectUser(user)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ListsUserSearch
|
|
||||||
@results="onResults"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
v-for="user in users"
|
|
||||||
:key="user.id"
|
|
||||||
class="member"
|
|
||||||
>
|
|
||||||
<BasicUserCard
|
|
||||||
:user="user"
|
|
||||||
:class="isSelected(user) ? 'selected' : ''"
|
|
||||||
@click.capture.prevent="selectUser(user)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
:disabled="title && title.length === 0"
|
|
||||||
class="btn button-default"
|
|
||||||
@click="createList"
|
|
||||||
>
|
|
||||||
{{ $t('lists.create') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script src="./lists_new.js"></script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import '../../_variables.scss';
|
|
||||||
|
|
||||||
.list-new {
|
|
||||||
.search-icon {
|
|
||||||
margin-right: 0.3em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.member-list {
|
|
||||||
padding-bottom: 0.7rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.basic-user-card:hover,
|
|
||||||
.basic-user-card.selected {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: var(--selectedPost, $fallback--lightBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.go-back-button {
|
|
||||||
text-align: center;
|
|
||||||
line-height: 1;
|
|
||||||
height: 100%;
|
|
||||||
align-self: start;
|
|
||||||
width: var(--__panel-heading-height-inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
margin: 0.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -991,8 +991,10 @@
|
||||||
"add_to_list": "Add to list",
|
"add_to_list": "Add to list",
|
||||||
"is_in_list": "Already in list",
|
"is_in_list": "Already in list",
|
||||||
"editing_list": "Editing list {listTitle}",
|
"editing_list": "Editing list {listTitle}",
|
||||||
|
"creating_list": "Creating new list",
|
||||||
"update_title": "Save Title",
|
"update_title": "Save Title",
|
||||||
"really_delete": "Really delete list?"
|
"really_delete": "Really delete list?",
|
||||||
|
"error": "Error manipulating lists: {0}"
|
||||||
},
|
},
|
||||||
"file_type": {
|
"file_type": {
|
||||||
"audio": "Audio",
|
"audio": "Audio",
|
||||||
|
|
Loading…
Reference in New Issue