create new list UI

This commit is contained in:
Henry Jameson 2022-08-17 20:21:10 +03:00
parent b4f4b370d4
commit faefd05c03
8 changed files with 61 additions and 198 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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