refactor: finish refactoring all the components to use vuex

This commit is contained in:
Zephyrrus 2020-07-10 01:13:51 +03:00
parent 7e78a03931
commit 0f66d80703
8 changed files with 105 additions and 90 deletions

View File

@ -287,7 +287,7 @@ export default {
} catch (e) {
this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true });
}
this.showingModalForFile.albums = this.images.filesAlbums[id];
this.showingModalForFile.albums = this.images.fileAlbumsMap[id];
this.isAlbumsModalActive = true;
},

View File

@ -28,7 +28,7 @@
<b-icon class="is-pulled-right" :icon="props.expanded ? 'menu-down' : 'menu-up'" />
</template>
<b-menu-item icon="account" label="Users" tag="nuxt-link" to="/dashboard/admin/users" exact />
<b-menu-item icon="cog-outline" label="Settings" disabled />
<b-menu-item icon="cog-outline" label="Settings" tag="nuxt-link" to="/dashboard/admin/settings" exact />
</b-menu-item>
<b-menu-item
class="item"

View File

@ -19,99 +19,101 @@
<b-field
label="ID"
horizontal>
<span>{{ file.id }}</span>
<span>{{ admin.file.id }}</span>
</b-field>
<b-field
label="Name"
horizontal>
<span>{{ file.name }}</span>
<span>{{ admin.file.name }}</span>
</b-field>
<b-field
label="Original Name"
horizontal>
<span>{{ file.original }}</span>
<span>{{ admin.file.original }}</span>
</b-field>
<b-field
label="IP"
horizontal>
<span class="underline">{{ file.ip }}</span>
<span class="underline">{{ admin.file.ip }}</span>
</b-field>
<b-field
label="Link"
horizontal>
<a
:href="file.url"
target="_blank">{{ file.url }}</a>
:href="admin.file.url"
target="_blank">{{ admin.file.url }}</a>
</b-field>
<b-field
label="Size"
horizontal>
<span>{{ formatBytes(file.size) }}</span>
<span>{{ formatBytes(admin.file.size) }}</span>
</b-field>
<b-field
label="Hash"
horizontal>
<span>{{ file.hash }}</span>
<span>{{ admin.file.hash }}</span>
</b-field>
<b-field
label="Uploaded"
horizontal>
<span><timeago :since="file.createdAt" /></span>
<span><timeago :since="admin.file.createdAt" /></span>
</b-field>
</div>
<div class="column is-6">
<b-field
label="User Id"
horizontal>
<span>{{ user.id }}</span>
<span>{{ admin.user.id }}</span>
</b-field>
<b-field
label="Username"
horizontal>
<span>{{ user.username }}</span>
<span>{{ admin.user.username }}</span>
</b-field>
<b-field
label="Enabled"
horizontal>
<span>{{ user.enabled }}</span>
<span>{{ admin.user.enabled }}</span>
</b-field>
<b-field
label="Registered"
horizontal>
<span><timeago :since="user.createdAt" /></span>
<span><timeago :since="admin.user.createdAt" /></span>
</b-field>
<b-field
label="Files"
horizontal>
<span>
<nuxt-link :to="`/dashboard/admin/user/${user.id}`">{{ user.fileCount }}</nuxt-link>
<nuxt-link :to="`/dashboard/admin/user/${admin.user.id}`">{{ admin.user.fileCount }}</nuxt-link>
</span>
</b-field>
</div>
</div>
<div class="mb2 mt2 text-center">
<button
class="button is-danger"
<b-button
v-if="admin.user.id !== auth.user.id"
type="is-danger"
@click="promptBanIP">
Ban IP
</button>
<button
class="button is-danger"
</b-button>
<b-button
v-if="admin.user.id !== auth.user.id"
type="is-danger"
@click="promptDisableUser">
Disable user
</button>
</b-button>
</div>
</div>
</div>
@ -120,35 +122,22 @@
</template>
<script>
import { mapState } from 'vuex';
import Sidebar from '~/components/sidebar/Sidebar.vue';
export default {
components: {
Sidebar,
},
middleware: ['auth', 'admin'],
data() {
return {
options: {},
file: null,
user: null,
};
},
async asyncData({ $axios, route }) {
middleware: ['auth', 'admin', ({ route, store }) => {
try {
const response = await $axios.$get(`file/${route.params.id}`);
return {
file: response.file ? response.file : null,
user: response.user ? response.user : null,
};
} catch (error) {
console.error(error);
return {
file: null,
user: null,
};
store.dispatch('admin/fetchFile', route.params.id);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
},
}],
computed: mapState(['admin', 'auth']),
methods: {
promptDisableUser() {
this.$buefy.dialog.confirm({
@ -157,11 +146,8 @@ export default {
onConfirm: () => this.disableUser(),
});
},
async disableUser() {
const response = await this.$axios.$post('admin/users/disable', {
id: this.user.id,
});
this.$buefy.toast.open(response.message);
disableUser() {
this.$handler.executeAction('admin/disableUser', this.user.id);
},
promptBanIP() {
this.$buefy.dialog.confirm({
@ -170,11 +156,8 @@ export default {
onConfirm: () => this.banIP(),
});
},
async banIP() {
const response = await this.$axios.$post('admin/ban/ip', {
ip: this.file.ip,
});
this.$buefy.toast.open(response.message);
banIP() {
this.$handler.executeAction('admin/banIP', this.file.ip);
},
formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';

View File

@ -16,7 +16,7 @@
message="Please enter the name which this service is gonna be identified as"
horizontal>
<b-input
v-model="options.serviceName"
v-model="settings.serviceName"
expanded />
</b-field>
@ -25,7 +25,7 @@
message="Where to store the files relative to the working directory"
horizontal>
<b-input
v-model="options.uploadFolder"
v-model="settings.uploadFolder"
expanded />
</b-field>
@ -34,7 +34,7 @@
message="Maximum links allowed per album"
horizontal>
<b-input
v-model="options.linksPerAlbum"
v-model="settings.linksPerAlbum"
type="number"
expanded />
</b-field>
@ -44,7 +44,7 @@
message="Maximum allowed file size in MB"
horizontal>
<b-input
v-model="options.maxUploadSize"
v-model="settings.maxUploadSize"
expanded />
</b-field>
@ -53,7 +53,7 @@
message="How many characters long should the generated filenames be"
horizontal>
<b-input
v-model="options.filenameLength"
v-model="settings.filenameLength"
expanded />
</b-field>
@ -62,7 +62,7 @@
message="How many characters a link for an album should have"
horizontal>
<b-input
v-model="options.albumLinkLength"
v-model="settings.albumLinkLength"
expanded />
</b-field>
@ -71,7 +71,7 @@
message="Generate thumbnails when uploading a file if possible"
horizontal>
<b-switch
v-model="options.generateThumbnails"
v-model="settings.generateThumbnails"
:true-value="true"
:false-value="false" />
</b-field>
@ -81,7 +81,7 @@
message="Allow generating zips to download entire albums"
horizontal>
<b-switch
v-model="options.generateZips"
v-model="settings.generateZips"
:true-value="true"
:false-value="false" />
</b-field>
@ -91,7 +91,7 @@
message="Enable anonymous uploades"
horizontal>
<b-switch
v-model="options.publicMode"
v-model="settings.publicMode"
:true-value="true"
:false-value="false" />
</b-field>
@ -101,7 +101,7 @@
message="Enable creating new accounts in the platform"
horizontal>
<b-switch
v-model="options.enableAccounts"
v-model="settings.enableAccounts"
:true-value="true"
:false-value="false" />
</b-field>
@ -120,38 +120,36 @@
</template>
<script>
import { mapState } from 'vuex';
import Sidebar from '~/components/sidebar/Sidebar.vue';
export default {
components: {
Sidebar,
},
middleware: ['auth', 'admin'],
data() {
return {
options: {},
};
},
middleware: ['auth', 'admin', ({ store }) => {
try {
store.dispatch('admin/fetchSettings');
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
}
}],
metaInfo() {
return { title: 'Settings' };
},
mounted() {
this.getSettings();
},
computed: mapState({
settings: (state) => state.admin.settings,
}),
methods: {
async getSettings() {
const response = await this.$axios.$get('service/config');
this.options = response.config;
},
promptRestartService() {
this.$buefy.dialog.confirm({
message: 'Keep in mind that restarting only works if you have PM2 or something similar set up. Continue?',
onConfirm: () => this.restartService(),
});
},
async restartService() {
const response = await this.$axios.$post('service/restart');
this.$buefy.toast.open(response.message);
restartService() {
this.$handler.executeAction('admin/restartService');
},
},
};

View File

@ -24,9 +24,9 @@ export default function ({ $axios, store }) {
}
}
if (error.response?.data?.message.indexOf('Token expired') !== -1) {
/* if (error.response?.data?.message.indexOf('Token expired') !== -1) {
store.dispatch('auth/logout');
}
} */
}
});
}

View File

@ -15,6 +15,12 @@ export const state = () => ({
});
export const actions = {
async fetchSettings({ commit }) {
const response = await this.$axios.$get('service/config');
commit('setSettings', response);
return response;
},
async fetchUsers({ commit }) {
const response = await this.$axios.$get('admin/users');
commit('setUsers', response);
@ -22,11 +28,23 @@ export const actions = {
return response;
},
async fetchUser({ commit }, id) {
const response = await this.$axios.$get(`/admin/users/${id}`);
const response = await this.$axios.$get(`admin/users/${id}`);
commit('setUserInfo', response);
return response;
},
async fetchFile({ commit }, id) {
const response = await this.$axios.$get(`file/${id}`);
commit('setFile', response);
commit('setUserInfo', response);
return response;
},
async banIP(_, ip) {
const response = await this.$axios.$post('admin/ban/ip', { ip });
return response;
},
async enableUser({ commit }, id) {
const response = await this.$axios.$post('admin/users/enable', { id });
@ -58,11 +76,19 @@ export const actions = {
async purgeUserFiles(_, id) {
const response = await this.$axios.$post('admin/users/purge', { id });
return response;
},
async restartService() {
const response = await this.$axios.$post('service/restart');
return response;
},
};
export const mutations = {
setSettings(state, { config }) {
state.settings = config;
},
setUsers(state, { users }) {
state.users = users;
},
@ -70,6 +96,9 @@ export const mutations = {
state.user = { ...state.user, ...user };
state.user.files = files || [];
},
setFile(state, { file }) {
state.file = file || {};
},
changeUserState(state, { userId, enabled, isAdmin }) {
const foundIndex = state.users.findIndex(({ id }) => id === userId);
if (foundIndex > -1) {

View File

@ -1,6 +1,10 @@
const getDefaultState = () => ({
loggedIn: false,
user: null,
user: {
id: null,
isAdmin: false,
username: null,
},
token: null,
});

View File

@ -10,7 +10,8 @@ export const getDefaultState = () => ({
},
name: null,
downloadEnabled: false,
filesAlbums: {}, // map of file ids with a list of album objects the file is in
fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in
filesTags: {}, // map of file ids with a list of tag objects for the file
});
export const state = getDefaultState;
@ -105,19 +106,19 @@ export const mutations = {
}
},
setFileAlbums(state, { fileId, albums }) {
Vue.set(state.filesAlbums, fileId, albums);
Vue.set(state.fileAlbumsMap, fileId, albums);
},
addAlbumToFile(state, { fileId, album }) {
if (!state.filesAlbums[fileId]) return;
if (!state.fileAlbumsMap[fileId]) return;
state.filesAlbums[fileId].push(album);
state.fileAlbumsMap[fileId].push(album);
},
removeAlbumFromFile(state, { fileId, albumId }) {
if (!state.filesAlbums[fileId]) return;
if (!state.fileAlbumsMap[fileId]) return;
const foundIndex = state.filesAlbums[fileId].findIndex(({ id }) => id === albumId);
const foundIndex = state.fileAlbumsMap[fileId].findIndex(({ id }) => id === albumId);
if (foundIndex > -1) {
state.filesAlbums[fileId].splice(foundIndex, 1);
state.fileAlbumsMap[fileId].splice(foundIndex, 1);
}
},
resetState(state) {