feat: refactor single album page to use vuex

This commit is contained in:
Zephyrrus 2020-07-05 04:17:09 +03:00
parent ba5a740885
commit 04fdd63cee
5 changed files with 152 additions and 71 deletions

View File

@ -21,7 +21,7 @@ class albumGET extends Route {
const files = await db.table('albumsFiles')
.where({ albumId: link.albumId })
.join('files', 'albumsFiles.fileId', 'files.id')
.select('files.name')
.select('files.name', 'files.id')
.orderBy('files.id', 'desc');
// Create the links for each file
@ -36,7 +36,7 @@ class albumGET extends Route {
message: 'Successfully retrieved files',
name: album.name,
downloadEnabled: link.enableDownload,
files
files,
});
}
}

View File

@ -13,7 +13,14 @@
<nav class="level">
<div class="level-left">
<div class="level-item">
<h2 class="subtitle">Files</h2>
<h1 class="title is-3">
{{ name }}
</h1>
</div>
<div class="level-item">
<h2 class="subtitle is-5">
({{ totalFiles }} files)
</h2>
</div>
</div>
<div class="level-right">
@ -21,7 +28,7 @@
<b-field>
<b-input
placeholder="Search"
type="search"/>
type="search" />
<p class="control">
<button
outlined
@ -36,14 +43,15 @@
<hr>
<Grid v-if="files.length"
:files="files"
:total="count">
<Grid
v-if="totalFiles"
:files="album.files"
:total="totalFiles">
<template v-slot:pagination>
<b-pagination
v-if="count > perPage"
:total="count"
:per-page="perPage"
v-if="shouldPaginate"
:total="totalFiles"
:per-page="limit"
:current.sync="current"
range-before="2"
range-after="2"
@ -64,53 +72,65 @@
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
import Sidebar from '~/components/sidebar/Sidebar.vue';
import Grid from '~/components/grid/Grid.vue';
export default {
components: {
Sidebar,
Grid
Grid,
},
middleware: 'auth',
middleware: ['auth', ({ route, store }) => {
store.dispatch('album/fetchById', { id: route.params.id });
}],
data() {
return {
name: null,
files: [],
count: 0,
current: 1,
perPage: 30
};
},
computed: {
...mapGetters({
totalFiles: 'album/getTotalFiles',
shouldPaginate: 'album/shouldPaginate',
limit: 'album/getLimit',
name: 'album/getName',
}),
...mapState(['album']),
id() {
return this.$route.params.id;
},
},
metaInfo() {
return { title: 'Album' };
},
watch: {
current: 'getFiles'
},
async asyncData({ $axios, route }) {
const perPage = 30;
const current = 1; // current page
try {
const response = await $axios.$get(`album/${route.params.id}/full`, { params: { page: current, limit: perPage }});
return {
files: response.files || [],
count: response.count || 0,
current,
perPage
};
} catch (error) {
console.error(error);
return { files: [] };
}
current: 'fetchPaginate',
},
methods: {
async getFiles() {
const response = await this.$axios.$get(`album/${this.$route.params.id}/full`, { params: { page: this.current, limit: this.perPage }});
this.files = response.files;
this.count = response.count;
}
...mapActions({
fetch: 'album/fetchById',
}),
fetchPaginate() {
this.fetch({ id: this.id, page: this.current });
},
},
};
</script>
<style lang="scss" scoped>
div.grid {
margin-bottom: 1rem;
}
.pagination-slot {
padding: 1rem 0;
}
</style>
<style lang="scss">
.pagination-slot > .pagination-previous, .pagination-slot > .pagination-next {
display: none !important;
}
</style>

View File

@ -7,26 +7,33 @@
<Sidebar />
</div>
<div class="column">
<h2 class="subtitle">Manage your albums</h2>
<h2 class="subtitle">
Manage your albums
</h2>
<hr>
<div class="search-container">
<b-field>
<b-input v-model="newAlbumName"
<b-input
v-model="newAlbumName"
placeholder="Album name..."
type="text"
@keyup.enter.native="createAlbum" />
<p class="control">
<button outlined
<button
outlined
class="button is-black"
:disabled="isCreatingAlbum"
@click="createAlbum">Create album</button>
@click="createAlbum">
Create album
</button>
</p>
</b-field>
</div>
<div class="view-container">
<AlbumEntry v-for="album in albums.list"
<AlbumEntry
v-for="album in albums.list"
:key="album.id"
:album="album" />
</div>
@ -45,15 +52,19 @@ import AlbumEntry from '~/components/album/AlbumEntry.vue';
export default {
components: {
Sidebar,
AlbumEntry
AlbumEntry,
},
middleware: ['auth', ({ store }) => {
store.dispatch('albums/fetch');
try {
store.dispatch('albums/fetch');
} catch (e) {
this.alert({ text: e.message, error: true });
}
}],
data() {
return {
newAlbumName: null,
isCreatingAlbum: false
isCreatingAlbum: false,
};
},
computed: mapState(['config', 'albums']),
@ -62,7 +73,7 @@ export default {
},
methods: {
...mapActions({
'alert': 'alert/set'
'alert': 'alert/set',
}),
async createAlbum() {
if (!this.newAlbumName || this.newAlbumName === '') return;
@ -78,8 +89,8 @@ export default {
this.isCreatingAlbum = false;
this.newAlbumName = null;
}
}
}
},
},
};
</script>

View File

@ -0,0 +1,54 @@
/* eslint-disable no-shadow */
export const state = () => ({
files: [],
name: null,
isLoading: false,
pagination: {
page: 1,
limit: 30,
totalFiles: 0,
},
downloadEnabled: false,
});
export const getters = {
getTotalFiles: ({ pagination }) => pagination.totalFiles,
getFetchedCount: ({ files }) => files.length,
shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit,
getLimit: ({ pagination }) => pagination.limit,
getName: ({ name }) => name,
};
export const actions = {
async fetchById({ commit, dispatch, state }, { id, page }) {
commit('setIsLoading');
page = page || 1;
try {
const response = await this.$axios.$get(`album/${id}/full`, {
params: { limit: state.pagination.limit, page },
});
commit('setFiles', response);
commit('updatePaginationMeta', { totalFiles: response.count, page });
} catch (e) {
dispatch('alert/set', { text: e.message, error: true }, { root: true });
}
},
};
export const mutations = {
setIsLoading(state) {
state.isLoading = true;
},
setFiles(state, { files, name }) {
state.files = files || [];
state.name = name;
state.isLoading = false;
},
updatePaginationMeta(state, { page, totalFiles }) {
state.pagination.page = page || 1;
state.pagination.totalFiles = totalFiles || 0;
},
};

View File

@ -5,26 +5,22 @@ export const state = () => ({
list: [],
isListLoading: false,
albumDetails: {},
expandedAlbums: []
expandedAlbums: [],
});
export const getters = {
isExpanded: state => id => state.expandedAlbums.indexOf(id) > -1,
getDetails: state => id => state.albumDetails[id] || {}
isExpanded: (state) => (id) => state.expandedAlbums.indexOf(id) > -1,
getDetails: (state) => (id) => state.albumDetails[id] || {},
};
export const actions = {
async fetch({ commit, dispatch }) {
try {
commit('albumsRequest');
const response = await this.$axios.$get(`albums/mini`);
async fetch({ commit }) {
commit('albumsRequest');
const response = await this.$axios.$get('albums/mini');
commit('setAlbums', response.albums);
commit('setAlbums', response.albums);
return response;
} catch (e) {
dispatch('alert/set', { text: e.message, error: true }, { root: true });
}
return response;
},
async fetchDetails({ commit }, albumId) {
@ -33,15 +29,15 @@ export const actions = {
commit('setDetails', {
id: albumId,
details: {
links: response.links
}
links: response.links,
},
});
return response;
},
async createAlbum({ commit }, name) {
const response = await this.$axios.$post(`album/new`, { name });
const response = await this.$axios.$post('album/new', { name });
commit('addAlbum', response.data);
@ -57,7 +53,7 @@ export const actions = {
},
async createLink({ commit }, albumId) {
const response = await this.$axios.$post(`album/link/new`, { albumId });
const response = await this.$axios.$post('album/link/new', { albumId });
commit('addAlbumLink', { albumId, data: response.data });
@ -65,10 +61,10 @@ export const actions = {
},
async updateLinkOptions({ commit }, { albumId, linkOpts }) {
const response = await this.$axios.$post(`album/link/edit`, {
const response = await this.$axios.$post('album/link/edit', {
identifier: linkOpts.identifier,
enableDownload: linkOpts.enableDownload,
enabled: linkOpts.enabled
enabled: linkOpts.enabled,
});
commit('updateAlbumLinkOpts', { albumId, linkOpts: response.data });
@ -82,7 +78,7 @@ export const actions = {
commit('removeAlbumLink', { albumId, identifier });
return response;
}
},
};
export const mutations = {
@ -109,7 +105,7 @@ export const mutations = {
},
updateAlbumLinkOpts(state, { albumId, linkOpts }) {
const foundIndex = state.albumDetails[albumId].links.findIndex(
({ identifier }) => identifier === linkOpts.identifier
({ identifier }) => identifier === linkOpts.identifier,
);
const link = state.albumDetails[albumId].links[foundIndex];
state.albumDetails[albumId].links[foundIndex] = { ...link, ...linkOpts };
@ -125,5 +121,5 @@ export const mutations = {
} else {
state.expandedAlbums.push(id);
}
}
},
};