aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZephyrrus <[email protected]>2020-10-02 22:18:16 +0300
committerGitHub <[email protected]>2020-10-02 22:18:16 +0300
commit443e63d05a95d41805bc1451a37246babfe778dd (patch)
tree129b30f93af6de3ef985d8774513eb359065b4f9 /src
parentfeat: add experimental query to sql generator for searching (diff)
parentfeat: allow administrators to create custom links for albums (diff)
downloadhost.fuwn.me-443e63d05a95d41805bc1451a37246babfe778dd.tar.xz
host.fuwn.me-443e63d05a95d41805bc1451a37246babfe778dd.zip
Merge pull request #3 from Zephyrrus/feature/custom_album_urls
feat: allow administrators to create custom links for albums
Diffstat (limited to 'src')
-rw-r--r--src/api/routes/albums/link/linkPOST.js27
-rw-r--r--src/site/components/album/AlbumDetails.vue58
-rw-r--r--src/site/components/sidebar/Sidebar.vue2
-rw-r--r--src/site/store/albums.js7
4 files changed, 87 insertions, 7 deletions
diff --git a/src/api/routes/albums/link/linkPOST.js b/src/api/routes/albums/link/linkPOST.js
index d58598a..ba247b5 100644
--- a/src/api/routes/albums/link/linkPOST.js
+++ b/src/api/routes/albums/link/linkPOST.js
@@ -30,11 +30,28 @@ class linkPOST extends Route {
.first();
if (count >= parseInt(process.env.MAX_LINKS_PER_ALBUM, 10)) return res.status(400).json({ message: 'Maximum links per album reached' });
- /*
- Try to allocate a new identifier on the db
- */
- const identifier = await Util.getUniqueAlbumIdentifier();
- if (!identifier) return res.status(500).json({ message: 'There was a problem allocating a link for your album' });
+ let { identifier } = req.body;
+ if (identifier) {
+ if (!user.isAdmin) return res.status(401).json({ message: 'Only administrators can create custom links' });
+
+ if (!(/^[a-zA-Z0-9-_]+$/.test(identifier))) return res.status(400).json({ message: 'Only alphanumeric, dashes, and underscore characters are allowed' });
+
+ /*
+ Make sure that the id doesn't already exists in the database
+ */
+ const idExists = await db
+ .table('links')
+ .where({ identifier })
+ .first();
+
+ if (idExists) return res.status(400).json({ message: 'Album with this identifier already exists' });
+ } else {
+ /*
+ Try to allocate a new identifier in the database
+ */
+ identifier = await Util.getUniqueAlbumIdentifier();
+ if (!identifier) return res.status(500).json({ message: 'There was a problem allocating a link for your album' });
+ }
try {
const insertObj = {
diff --git a/src/site/components/album/AlbumDetails.vue b/src/site/components/album/AlbumDetails.vue
index b411f13..ac6eba5 100644
--- a/src/site/components/album/AlbumDetails.vue
+++ b/src/site/components/album/AlbumDetails.vue
@@ -58,7 +58,30 @@
<div class="level is-paddingless">
<div class="level-left">
<div class="level-item">
+ <b-field v-if="auth.user.isAdmin">
+ <p class="control">
+ <button
+ :class="{ 'is-loading': isCreatingLink }"
+ class="button is-primary reset-font-size-button"
+ style="float: left"
+ @click="createLink(albumId)">
+ Create new link
+ </button>
+ </p>
+ <p class="control">
+ <b-dropdown>
+ <button slot="trigger" class="button is-primary reset-font-size-button">
+ <b-icon icon="menu-down" />
+ </button>
+
+ <b-dropdown-item @click="createCustomLink(albumId)">
+ Custom link
+ </b-dropdown-item>
+ </b-dropdown>
+ </p>
+ </b-field>
<button
+ v-else
:class="{ 'is-loading': isCreatingLink }"
class="button is-primary"
style="float: left"
@@ -107,13 +130,14 @@ export default {
isDeletingLinks: [],
};
},
- computed: mapState(['config']),
+ computed: mapState(['config', 'auth']),
methods: {
...mapActions({
deleteAlbumAction: 'albums/deleteAlbum',
deleteAlbumLinkAction: 'albums/deleteLink',
updateLinkOptionsAction: 'albums/updateLinkOptions',
createLinkAction: 'albums/createLink',
+ createCustomLinkAction: 'albums/createCustomLink',
alert: 'alert/set',
}),
promptDeleteAlbum(id) {
@@ -172,6 +196,17 @@ export default {
this.alert({ text: e.message, error: true });
}
},
+ async createCustomLink(albumId) {
+ this.$buefy.dialog.prompt({
+ message: 'Custom link identifier',
+ inputAttrs: {
+ placeholder: '',
+ maxlength: 10,
+ },
+ trapFocus: true,
+ onConfirm: (value) => this.$handler.executeAction('albums/createCustomLink', { albumId, value }),
+ });
+ },
isDeleting(identifier) {
return this.isDeletingLinks.indexOf(identifier) > -1;
},
@@ -182,6 +217,11 @@ export default {
<style lang="scss" scoped>
@import '~/assets/styles/_colors.scss';
+ .reset-font-size-button {
+ font-size: 1rem;
+ height: 2.25em;
+ }
+
div.details {
flex: 0 1 100%;
padding-left: 2em;
@@ -208,4 +248,20 @@ export default {
box-shadow: $boxShadowLight;
}
}
+
+ .dialog.modal .modal-card-body input {
+ border: 2px solid #21252d;
+ border-radius: 0.3em !important;
+ background: rgba(0, 0, 0, 0.15);
+ padding: 1rem;
+ color: $textColor;
+ height: 3rem;
+ &:focus,
+ &:hover {
+ border: 2px solid #21252d;
+ }
+ &::placeholder {
+ color: $textColor;
+ }
+ }
</style>
diff --git a/src/site/components/sidebar/Sidebar.vue b/src/site/components/sidebar/Sidebar.vue
index d586122..2e8ca9e 100644
--- a/src/site/components/sidebar/Sidebar.vue
+++ b/src/site/components/sidebar/Sidebar.vue
@@ -22,7 +22,7 @@
tag="nuxt-link"
to="/dashboard/tags"
exact />
- <b-menu-item icon="settings" expanded>
+ <b-menu-item icon="menu" expanded>
<template slot="label" slot-scope="props">
Administration
<b-icon class="is-pulled-right" :icon="props.expanded ? 'menu-down' : 'menu-up'" />
diff --git a/src/site/store/albums.js b/src/site/store/albums.js
index 8441182..c1ff696 100644
--- a/src/site/store/albums.js
+++ b/src/site/store/albums.js
@@ -55,6 +55,13 @@ export const actions = {
return response;
},
+ async createCustomLink({ commit }, { albumId, value }) {
+ const response = await this.$axios.$post('album/link/new', { albumId, identifier: value });
+
+ commit('addAlbumLink', { albumId, data: response.data });
+
+ return response;
+ },
async updateLinkOptions({ commit }, { albumId, linkOpts }) {
const response = await this.$axios.$post('album/link/edit', {
identifier: linkOpts.identifier,