TT#47515 User can upload a sound file

Change-Id: I0a82dc3fe6648073fab556b74b18837a782b1e2a
changes/62/28762/7
Robert Axelsen 6 years ago
parent 79cda25d2a
commit caaa202d90

@ -802,3 +802,44 @@ export function playSoundFile(options) {
export function removeSoundFile(id) { export function removeSoundFile(id) {
return Vue.http.delete('api/soundfiles/' + id); return Vue.http.delete('api/soundfiles/' + id);
} }
export function uploadSoundFile(options, onProgress) {
return new Promise((resolve, reject) => {
let formData = new FormData();
let loopplay = options.item.loopplay ? 1 : 2;
let fields = {
loopplay: loopplay,
filename: options.file.name,
set_id: options.item.set_id,
handle: options.item.handle,
};
let json = JSON.stringify(fields);
let requestKey = `previous-${options.item.handle}-request`;
formData.append('json', json);
if (options.file) {
formData.append('soundfile', options.file);
}
Vue.http.post('api/soundfiles/', formData, {
before(request) {
Vue[requestKey] = request;
},
progress(e) {
if (e.lengthComputable) {
onProgress(Math.ceil((e.loaded / e.total ) * 100));
}
}
}).then(() => {
resolve();
}).catch((err) => {
reject(err);
});
});
}
export function abortPreviousSoundFileUpload(handle) {
return new Promise((resolve) => {
let requestKey = `previous-${handle}-request`;
Vue[requestKey].abort();
resolve();
});
}

@ -114,10 +114,10 @@ export function createNewGreeting(formData, onProgress, type) {
export function uploadGreeting(options) { export function uploadGreeting(options) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var formData = new FormData(); let formData = new FormData();
var fields = _.clone(options.data); let fields = _.clone(options.data);
delete fields.file; delete fields.file;
var json = JSON.stringify(fields); let json = JSON.stringify(fields);
formData.append('json', json); formData.append('json', json);
if (options.data.file) { if (options.data.file) {
formData.append('greetingfile', options.data.file); formData.append('greetingfile', options.data.file);

@ -150,7 +150,8 @@
'disable', 'disable',
'floatLabel', 'floatLabel',
'deleteTerm', 'deleteTerm',
'updating' 'updating',
'stopAll'
], ],
data () { data () {
return { return {

@ -14,6 +14,7 @@
:item="item" :item="item"
:group="groupLabel" :group="groupLabel"
:updating="isRemoveFileRequesting(item.id)" :updating="isRemoveFileRequesting(item.id)"
:set-id="setId"
@remove-file="removeFile" @remove-file="removeFile"
/> />
</q-list> </q-list>
@ -41,7 +42,8 @@
props: { props: {
group: Object, group: Object,
groupLabel: String, groupLabel: String,
invalidGroup: Boolean invalidGroup: Boolean,
setId: Number
}, },
components: { components: {
CscPbxSoundItem, CscPbxSoundItem,

@ -6,31 +6,34 @@
<q-item-main> <q-item-main>
<csc-sound-file-upload <csc-sound-file-upload
ref="uploadSoundFile" ref="uploadSoundFile"
icon="music_note"
file-types=".wav,.mp3" file-types=".wav,.mp3"
delete-term="remove"
icon="music_note"
:label="handleName" :label="handleName"
:value="fileLabel" :value="fileLabel"
:progress="uploadSoundFileProgress(item.handle)"
:file-url="playSoundFileUrl(item.id)" :file-url="playSoundFileUrl(item.id)"
:loaded="playSoundFileLoaded(item.id)" :loaded="playSoundFileLoaded(item.id)"
:stop-all="!isLastPlayed(item.id)" :stop-all="!isLastPlayed(item.id)"
:uploading="uploadSoundFileRequesting(item.handle)"
:uploaded="file" :uploaded="file"
:disable="true"
:invalid="isInvalid" :invalid="isInvalid"
:updating="updating" :updating="updating"
delete-term="remove"
@remove="removeFile" @remove="removeFile"
@init="initSoundFileAudio" @init="initSoundFileAudio"
@upload="uploadSoundFile"
@abort="abortUpload"
> >
<div <div
slot="additional" slot="additional"
> >
<q-toggle <q-toggle
:class="loopClasses"
:label="$t('pbxConfig.playingInLoop')"
v-model="loop" v-model="loop"
:disable="true"
checked-icon="loop"
unchecked-icon="loop" unchecked-icon="loop"
checked-icon="loop"
:disable="true"
:class="loopClasses"
:label="$t('pbxConfig.playingInLoop')"
/> />
<q-tooltip> <q-tooltip>
{{ loopTooltipLabel }} {{ loopTooltipLabel }}
@ -53,12 +56,14 @@
import { import {
mapGetters mapGetters
} from 'vuex' } from 'vuex'
import { showToast } from '../../../helpers/ui'
export default { export default {
name: 'csc-pbx-sound-item', name: 'csc-pbx-sound-item',
props: { props: {
item: Object, item: Object,
group: String, group: String,
updating: Boolean updating: Boolean,
setId: Number
}, },
components: { components: {
CscSoundFileUpload, CscSoundFileUpload,
@ -81,7 +86,10 @@
...mapGetters('pbxConfig', [ ...mapGetters('pbxConfig', [
'playSoundFileUrl', 'playSoundFileUrl',
'playSoundFileLoaded', 'playSoundFileLoaded',
'isLastPlayed' 'isLastPlayed',
'uploadSoundFileProgress',
'uploadSoundFileRequesting',
'uploadSoundFileState'
]), ]),
handleName() { handleName() {
return `${this.group}: ${this.item.handle}`; return `${this.group}: ${this.item.handle}`;
@ -120,6 +128,9 @@
classes.push('csc-item-invalid'); classes.push('csc-item-invalid');
} }
return classes; return classes;
},
uploadFileState() {
return this.uploadSoundFileState(this.item.handle);
} }
}, },
methods: { methods: {
@ -141,10 +152,33 @@
this.$refs.uploadSoundFile.setPausedFalse(); this.$refs.uploadSoundFile.setPausedFalse();
}, },
removeFile() { removeFile() {
this.$emit('remove-file', this.item) this.$emit('remove-file', this.item);
},
uploadSoundFile(file) {
let item = Object.assign(this.item, { set_id: this.setId });
this.$store.dispatch('pbxConfig/uploadSoundFile', {
item: item,
file: file
});
},
abortUpload() {
this.$store.dispatch('pbxConfig/abortPreviousSoundFileUpload', this.item.handle);
},
resetFile() {
this.$refs.uploadSoundFile.reset();
this.$store.commit('pbxConfig/resetSoundFileProgress', this.item.handle);
} }
}, },
watch: { watch: {
uploadFileState(state) {
if (state === 'succeeded') {
showToast(this.$t('pbxConfig.toasts.uploadSoundFileToast', { handle: this.item.handle }));
this.resetFile();
}
else if (state === 'failed' && this.uploadProgress > 0) {
this.resetFile();
}
}
} }
} }
</script> </script>

@ -93,6 +93,7 @@
:invalid-group="invalidGroup(group)" :invalid-group="invalidGroup(group)"
:group="group" :group="group"
:group-label="groupLabel(group.name)" :group-label="groupLabel(group.name)"
:set-id="set.id"
:key="index" :key="index"
@remove-file="removeFile" @remove-file="removeFile"
/> />

@ -106,7 +106,7 @@
</q-btn> </q-btn>
</div> </div>
<q-inner-loading :visible="loading"> <q-inner-loading :visible="loading">
<q-spinner-mat size="60px" color="primary" /> <q-spinner-dots size="60px" color="primary" />
</q-inner-loading> </q-inner-loading>
</div> </div>
</template> </template>
@ -119,7 +119,7 @@
import { import {
QBtn, QBtn,
QInnerLoading, QInnerLoading,
QSpinnerMat, QSpinnerDots,
QField, QField,
QInput, QInput,
QSelect, QSelect,
@ -134,7 +134,7 @@
components: { components: {
QBtn, QBtn,
QInnerLoading, QInnerLoading,
QSpinnerMat, QSpinnerDots,
QField, QField,
QInput, QInput,
QSelect, QSelect,

@ -403,7 +403,8 @@
"updatedIdentifier": "Updated identifier to {identifier}", "updatedIdentifier": "Updated identifier to {identifier}",
"createdDevice": "Created device {name} successfully", "createdDevice": "Created device {name} successfully",
"addedCallQueueToast": "Added call queue configuration for {name}", "addedCallQueueToast": "Added call queue configuration for {name}",
"addedSoundSetToast": "Added sound set {name}" "addedSoundSetToast": "Added sound set {name}",
"uploadSoundFileToast": "Uploaded new sound for handle {handle}"
}, },
"addDevice": "Add device", "addDevice": "Add device",
"addDeviceShort": "Add", "addDeviceShort": "Add",

@ -47,7 +47,9 @@ import {
getSoundSetWithFiles, getSoundSetWithFiles,
playSoundFile, playSoundFile,
createSoundSet, createSoundSet,
removeSoundFile removeSoundFile,
uploadSoundFile,
abortPreviousSoundFileUpload
} from '../../api/pbx-config' } from '../../api/pbx-config'
export default { export default {
@ -682,5 +684,23 @@ export default {
}).catch((err) => { }).catch((err) => {
context.commit('removeItemFailed', err.message); context.commit('removeItemFailed', err.message);
}); });
},
uploadSoundFile(context, options) {
let handle = options.item.handle;
context.commit('uploadSoundFileRequesting', handle);
uploadSoundFile(
options, function onProgress(progress) {
context.commit('uploadSoundFileProgress', {handle: handle, progress: progress });
}
).then(() => {
return context.dispatch('reloadSoundSet', { id: options.item.set_id });
}).then(() => {
context.commit('uploadSoundFileSucceeded', handle);
}).catch(() => {
context.commit('uploadSoundFileFailed', handle);
});
},
abortPreviousSoundFileUpload(state, handle) {
abortPreviousSoundFileUpload(handle);
} }
} }

@ -392,5 +392,20 @@ export default {
return (id) => { return (id) => {
return id ? state.removeItem === id : false; return id ? state.removeItem === id : false;
} }
},
uploadSoundFileRequesting(state) {
return (handle) => {
return state.uploadSoundFileStates[handle] === 'requesting';
}
},
uploadSoundFileState(state) {
return (handle) => {
return state.uploadSoundFileStates[handle];
}
},
uploadSoundFileProgress(state) {
return (handle) => {
return state.uploadSoundFileProgresses[handle] || 0;
}
} }
} }

@ -549,5 +549,23 @@ export default {
}, },
lastAddedCallQueue(state, callQueue) { lastAddedCallQueue(state, callQueue) {
state.lastAddedCallQueue = callQueue.name; state.lastAddedCallQueue = callQueue.name;
},
uploadSoundFileRequesting(state, handle) {
reactiveSet(state.uploadSoundFileStates, handle, RequestState.requesting);
reactiveSet(state.uploadSoundFileErrors, handle, null);
},
uploadSoundFileSucceeded(state, handle) {
reactiveSet(state.uploadSoundFileStates, handle, RequestState.succeeded);
reactiveSet(state.uploadSoundFileErrors, handle, null);
},
uploadSoundFileFailed(state, handle, error) {
reactiveSet(state.uploadSoundFileStates, handle, RequestState.failed);
reactiveSet(state.uploadSoundFileErrors, handle, error);
},
uploadSoundFileProgress(state, options) {
reactiveSet(state.uploadSoundFileProgresses, options.handle, options.progress);
},
resetSoundFileProgress(state, handle) {
reactiveSet(state.uploadSoundFileProgresses, handle, 0);
} }
} }

@ -95,5 +95,8 @@ export default {
createSoundSetState: RequestState.initiated, createSoundSetState: RequestState.initiated,
createSoundSetItem: null, createSoundSetItem: null,
createSoundSetError: null, createSoundSetError: null,
lastAddedCallQueue: null lastAddedCallQueue: null,
uploadSoundFileStates: {},
uploadSoundFileErrors: {},
uploadSoundFileProgresses: {}
} }

Loading…
Cancel
Save