Removed event bus and switched to vuex. Implemented vue dropzone.

This commit is contained in:
krzysiej
2022-06-15 15:19:46 +02:00
parent 5350c5c46b
commit 4536195a4c
16 changed files with 151 additions and 88 deletions

View File

@@ -1,42 +0,0 @@
// filedropzone_controller.js
import { Controller } from '@hotwired/stimulus';
import axios from 'axios';
export default class extends Controller {
connect() {
this.element.addEventListener('dropzone:connect', this._onConnect);
this.element.addEventListener('dropzone:change', this._onChange);
this.element.addEventListener('dropzone:clear', this._onClear);
}
disconnect() {
// You should always remove listeners when the controller is disconnected to avoid side-effects
this.element.removeEventListener('dropzone:connect', this._onConnect);
this.element.removeEventListener('dropzone:change', this._onChange);
this.element.removeEventListener('dropzone:clear', this._onClear);
}
_onConnect(event) {
// The dropzone was just created
console.info('onconnect');
}
_onChange(event) {
// The dropzone just changed
console.info('onchange');
axios.post(document.URL, new FormData(event.target.closest('form')), {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(() => {
event.target.querySelector('.dropzone-preview-button').click();
window.EventBus.$emit('fileUploaded');
})
}
_onClear(event) {
// The dropzone has just been cleared
console.info('onclear');
}
}

View File

@@ -8,8 +8,6 @@ export default {
})
},
bookUpdateProgress(bookId, progress) {
console.info(bookId);
console.info(progress);
return axios.post('/progress/update', {
bookId: bookId,
progress: progress

20
assets/js/api/file.js Normal file
View File

@@ -0,0 +1,20 @@
import axios from 'axios';
export default {
deleteFile: function (fileId) {
return axios.get(window.location.origin + '/file/delete/' + fileId);
},
getFiles: function (bookId) {
return axios.get(this.getFilesEndpoint(bookId), {
headers: {
'accept': 'application/json'
}
});
},
getFilesEndpoint: function (bookId) {
if (bookId) {
return `/api/books/${bookId}/files`;
}
return `/api/files`;
}
}

View File

@@ -1,3 +0,0 @@
import Vue from 'vue';
window.EventBus = new Vue();
export const EventBus = window.EventBus;

View File

@@ -25,54 +25,63 @@
<td class="text-end">{{ file.file_size_human }}</td>
<td>{{ file.extension }}</td>
<td><a :href="'/file/'+ file.id" class="link-secondary">download</a></td>
<td><a :href="'/file/delete/'+file.id" @click.prevent="deleteFile(file.id)" class="link-danger">remove</a>
<td><a @click.prevent="deleteFile(file.id)" class="link-danger cursor-pointer">remove</a>
</td>
</tr>
</tbody>
</table>
</div>
<vue-dropzone v-if="bookId"
ref="myVueDropzone"
id="dropzone"
:options="dropzoneOptions"
:useCustomSlot="true"
@vdropzone-success="vdropzoneSuccess"
>
<div class="dropzone-custom-content">
<h3 class="dropzone-custom-title">Drag and drop to upload content!</h3>
<div class="subtitle">
...or click to select a file from your computer
</div>
</div>
</vue-dropzone>
</div>
</template>
<script>
import axios from 'axios';
import {EventBus} from "../event-bus";
import vue2Dropzone from "vue2-dropzone";
import {mapActions, mapState} from "vuex";
export default {
name: 'Files',
components: {
EventBus
vueDropzone: vue2Dropzone
},
data() {
return {
files: []
dropzoneOptions: {
capture: 'image/',
url: '/book/' + this.bookId,
thumbnailWidth: 150,
maxFilesize: 50.5,
acceptedFiles: '.pdf, .epub, .mobi'
}
}
},
props: {
bookId: {type: Number, default: null}
},
mounted() {
this.getFiles();
this.getFiles(this.bookId);
},
created() {
window.EventBus.$on('fileUploaded', this.getFiles);
computed: {
...mapState('filemodule', ['files'])
},
methods: {
deleteFile: function (fileId) {
axios.get(window.location.origin + '/file/delete/' + fileId).then(() => this.getFiles())
},
getFiles: function () {
axios.get(this.getFilesEndpoint(), {
headers: {
'accept': 'application/json'
}
}).then(response => this.files = response.data)
},
getFilesEndpoint: function () {
if (this.bookId) {
return `/api/books/${this.bookId}/files`;
}
return `/api/files`;
...mapActions('filemodule', ['getFiles', 'deleteFile']),
vdropzoneSuccess(file) {
this.$refs.myVueDropzone.removeFile(file);
this.getFiles(this.bookId);
}
}
}

View File

@@ -11,15 +11,11 @@
</template>
<script>
import {EventBus} from "../event-bus";
import {mapActions, mapGetters} from "vuex";
import {TURN_ON_EDIT_MODE, TURN_OFF_EDIT_MODE} from '../store/mutation-types'
export default {
name: 'Progresseditor',
components: {
EventBus
},
props: {
totalPages: Number,
readPages: Number,

View File

@@ -2,13 +2,15 @@ import Vue from 'vue'
import Vuex from 'vuex'
import booksmodule from './modules/books';
import bookprogressmodule from './modules/bookprogress';
import filemodule from './modules/filemodule';
Vue.use(Vuex)
export default new Vuex.Store({
modules:{
booksmodule,
bookprogressmodule
bookprogressmodule,
filemodule
}
})

View File

@@ -0,0 +1,68 @@
import FileApi from "../../api/file";
import {
REMOVE_FILE_FROM_LIST,
FETCHING_FILES,
FETCHING_FILES_SUCCESS,
FETCHING_FILES_ERROR
} from '../mutation-types.js'
export default {
namespaced: true,
state: {
isLoading: false,
error: null,
files: []
},
getters: {
isLoading(state) {
return state.isLoading;
},
hasError(state) {
return state.error !== null;
},
error(state) {
return state.error;
}
},
mutations: {
[FETCHING_FILES](state) {
state.isLoading = true;
state.error = null;
},
[FETCHING_FILES_SUCCESS](state, files) {
state.isLoading = false;
state.error = null;
state.files = files;
},
[FETCHING_FILES_ERROR](state, error) {
state.isLoading = false;
state.error = error;
state.files = [];
},
[REMOVE_FILE_FROM_LIST](state, fileId) {
const index = state.files.findIndex(file => file.id === fileId);
state.files.splice(index, 1);
}
},
actions: {
async deleteFile({commit}, fileId) {
try {
await FileApi.deleteFile(fileId);
commit(REMOVE_FILE_FROM_LIST, fileId)
} catch (error) {
commit(FETCHING_FILES_ERROR, error);
}
},
async getFiles({commit}, bookId) {
commit(FETCHING_FILES);
try {
let response = await FileApi.getFiles(bookId);
commit(FETCHING_FILES_SUCCESS, response.data);
return response.data;
} catch (error) {
commit(FETCHING_FILES_ERROR, error);
}
},
}
};

View File

@@ -3,5 +3,10 @@ export const
UPDATING_PROGRESS_SUCCESS = "UPDATING_PROGRESS_SUCCESS",
UPDATING_PROGRESS_ERROR = "UPDATING_PROGRESS_ERROR",
TURN_ON_EDIT_MODE = "TURN_ON_EDIT_MODE",
TURN_OFF_EDIT_MODE = "TURN_OFF_EDIT_MODE"
TURN_OFF_EDIT_MODE = "TURN_OFF_EDIT_MODE",
FETCHING_FILES = "FETCHING_FILES",
FETCHING_FILES_SUCCESS = "FETCHING_FILES_SUCCESS",
FETCHING_FILES_ERROR = "FETCHING_FILES_ERROR",
REMOVE_FILE_FROM_LIST = "REMOVE_FILE_FROM_LIST"
;

View File

@@ -1,4 +1,5 @@
@import "~bootstrap";
@import "vue2-dropzone/dist/vue2Dropzone.min.css";
body {
//background-color: lightblue !important;