feat: refactor single album page to use vuex
This commit is contained in:
parent
ba5a740885
commit
04fdd63cee
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue