Fixed UX/autoreload issues in import screen
This commit is contained in:
parent
55c4a05b31
commit
73d8dd9a45
|
@ -1,9 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<table class="ui compact very basic single line unstackable table">
|
<table class="ui compact very basic single line unstackable table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr v-if="actionUrl && actions.length > 0">
|
<tr>
|
||||||
<th colspan="1000">
|
<th colspan="1000">
|
||||||
<div class="ui small form">
|
<div v-if="refreshable" class="right floated">
|
||||||
|
<span v-if="needsRefresh">
|
||||||
|
<translate>Content have been updated, click refresh to see up-to-date content</translate>
|
||||||
|
</span>
|
||||||
|
<button
|
||||||
|
@click="$emit('refresh')"
|
||||||
|
class="ui basic icon button"
|
||||||
|
:title="labels.refresh"
|
||||||
|
:aria-label="labels.refresh">
|
||||||
|
<i class="refresh icon"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui small left floated form" v-if="actionUrl && actions.length > 0">
|
||||||
<div class="ui inline fields">
|
<div class="ui inline fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label><translate>Actions</translate></label>
|
<label><translate>Actions</translate></label>
|
||||||
|
@ -132,6 +145,8 @@ export default {
|
||||||
props: {
|
props: {
|
||||||
actionUrl: {type: String, required: false, default: null},
|
actionUrl: {type: String, required: false, default: null},
|
||||||
idField: {type: String, required: false, default: 'id'},
|
idField: {type: String, required: false, default: 'id'},
|
||||||
|
refreshable: {type: Boolean, required: false, default: false},
|
||||||
|
needsRefresh: {type: Boolean, required: false, default: false},
|
||||||
objectsData: {type: Object, required: true},
|
objectsData: {type: Object, required: true},
|
||||||
actions: {type: Array, required: true, default: () => { return [] }},
|
actions: {type: Array, required: true, default: () => { return [] }},
|
||||||
filters: {type: Object, required: false, default: () => { return {} }},
|
filters: {type: Object, required: false, default: () => { return {} }},
|
||||||
|
@ -244,13 +259,18 @@ export default {
|
||||||
let self = this
|
let self = this
|
||||||
return this.objectsData.results.map((o) => {
|
return this.objectsData.results.map((o) => {
|
||||||
let custom = self.customObjects.filter((co) => {
|
let custom = self.customObjects.filter((co) => {
|
||||||
return self.getId(co) == self.getId(o)
|
return self.getId(co) === self.getId(o)
|
||||||
})[0]
|
})[0]
|
||||||
if (custom) {
|
if (custom) {
|
||||||
return custom
|
return custom
|
||||||
}
|
}
|
||||||
return o
|
return o
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
labels () {
|
||||||
|
return {
|
||||||
|
refresh: this.$gettext('Refresh table content')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -115,7 +115,8 @@
|
||||||
</div>
|
</div>
|
||||||
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'processing'}]">
|
<div :class="['ui', 'bottom', 'attached', 'segment', {hidden: currentTab != 'processing'}]">
|
||||||
<library-files-table
|
<library-files-table
|
||||||
:key="String(processTimestamp)"
|
:needs-refresh="needsRefresh"
|
||||||
|
@fetch-start="needsRefresh = false"
|
||||||
:filters="{import_reference: importReference}"
|
:filters="{import_reference: importReference}"
|
||||||
:custom-objects="Object.values(uploads.objects)"></library-files-table>
|
:custom-objects="Object.values(uploads.objects)"></library-files-table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -142,6 +143,7 @@ export default {
|
||||||
this.$router.replace({ query: { import: importReference } });
|
this.$router.replace({ query: { import: importReference } });
|
||||||
return {
|
return {
|
||||||
files: [],
|
files: [],
|
||||||
|
needsRefresh: false,
|
||||||
currentTab: "summary",
|
currentTab: "summary",
|
||||||
uploadUrl: "/api/v1/uploads/",
|
uploadUrl: "/api/v1/uploads/",
|
||||||
importReference,
|
importReference,
|
||||||
|
@ -199,31 +201,6 @@ export default {
|
||||||
value: this.uploadedFilesCount + this.finishedJobs
|
value: this.uploadedFilesCount + this.finishedJobs
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
disconnect() {
|
|
||||||
if (!this.bridge) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.bridge.socket.close(1000, "goodbye", { keepClosed: true });
|
|
||||||
},
|
|
||||||
openWebsocket() {
|
|
||||||
this.disconnect();
|
|
||||||
let self = this;
|
|
||||||
let token = this.$store.state.auth.token;
|
|
||||||
const bridge = new WebSocketBridge();
|
|
||||||
this.bridge = bridge;
|
|
||||||
let url = this.$store.getters["instance/absoluteUrl"](
|
|
||||||
`api/v1/activity?token=${token}`
|
|
||||||
);
|
|
||||||
url = url.replace("http://", "ws://");
|
|
||||||
url = url.replace("https://", "wss://");
|
|
||||||
bridge.connect(url);
|
|
||||||
bridge.listen(function(event) {
|
|
||||||
self.handleEvent(event);
|
|
||||||
});
|
|
||||||
bridge.socket.addEventListener("open", function() {
|
|
||||||
console.log("Connected to WebSocket");
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleImportEvent(event) {
|
handleImportEvent(event) {
|
||||||
let self = this;
|
let self = this;
|
||||||
if (event.upload.import_reference != self.importReference) {
|
if (event.upload.import_reference != self.importReference) {
|
||||||
|
@ -232,17 +209,10 @@ export default {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
self.uploads[event.old_status] -= 1;
|
self.uploads[event.old_status] -= 1;
|
||||||
self.uploads[event.new_status] += 1;
|
self.uploads[event.new_status] += 1;
|
||||||
self.uploads.objects[event.upload.uuid] = event.track_file;
|
self.uploads.objects[event.upload.uuid] = event.upload;
|
||||||
self.triggerReload();
|
self.needsRefresh = true
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
triggerReload: _.throttle(
|
|
||||||
function() {
|
|
||||||
this.processTimestamp = new Date();
|
|
||||||
},
|
|
||||||
10000,
|
|
||||||
{ leading: true }
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
labels() {
|
labels() {
|
||||||
|
|
|
@ -49,8 +49,8 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
websocketEvent ({state}, event) {
|
websocketEvent ({state}, event) {
|
||||||
console.log('Dispatching websocket event', event)
|
|
||||||
let handlers = state.websocketEventsHandlers[event.type]
|
let handlers = state.websocketEventsHandlers[event.type]
|
||||||
|
console.log('Dispatching websocket event', event, handlers)
|
||||||
if (!handlers) {
|
if (!handlers) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,6 @@ export default {
|
||||||
if (toNull && !newValue) {
|
if (toNull && !newValue) {
|
||||||
newValue = null
|
newValue = null
|
||||||
}
|
}
|
||||||
console.log(newValue, typeof newValue)
|
|
||||||
let params = {}
|
let params = {}
|
||||||
if (attr === "permissions") {
|
if (attr === "permissions") {
|
||||||
params["permissions"] = {}
|
params["permissions"] = {}
|
||||||
|
|
|
@ -46,7 +46,10 @@
|
||||||
:objects-data="result"
|
:objects-data="result"
|
||||||
:custom-objects="customObjects"
|
:custom-objects="customObjects"
|
||||||
:actions="actions"
|
:actions="actions"
|
||||||
|
:refreshable="true"
|
||||||
|
:needs-refresh="needsRefresh"
|
||||||
:action-url="'uploads/action/'"
|
:action-url="'uploads/action/'"
|
||||||
|
@refresh="fetchData"
|
||||||
:filters="actionFilters">
|
:filters="actionFilters">
|
||||||
<template slot="header-cells">
|
<template slot="header-cells">
|
||||||
<th><translate>Title</translate></th>
|
<th><translate>Title</translate></th>
|
||||||
|
@ -133,6 +136,7 @@ export default {
|
||||||
mixins: [OrderingMixin, TranslationsMixin],
|
mixins: [OrderingMixin, TranslationsMixin],
|
||||||
props: {
|
props: {
|
||||||
filters: {type: Object, required: false},
|
filters: {type: Object, required: false},
|
||||||
|
needsRefresh: {type: Boolean, required: false, default: false},
|
||||||
defaultQuery: {type: String, default: ''},
|
defaultQuery: {type: String, default: ''},
|
||||||
customObjects: {type: Array, required: false, default: () => { return [] }}
|
customObjects: {type: Array, required: false, default: () => { return [] }}
|
||||||
},
|
},
|
||||||
|
@ -199,12 +203,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fetchData () {
|
fetchData () {
|
||||||
|
this.$emit('fetch-start')
|
||||||
let params = _.merge({
|
let params = _.merge({
|
||||||
'page': this.page,
|
'page': this.page,
|
||||||
'page_size': this.paginateBy,
|
'page_size': this.paginateBy,
|
||||||
'ordering': this.getOrderingAsString(),
|
'ordering': this.getOrderingAsString(),
|
||||||
'q': this.search.query
|
'q': this.search.query
|
||||||
}, {})
|
}, this.filters || {})
|
||||||
let self = this
|
let self = this
|
||||||
self.isLoading = true
|
self.isLoading = true
|
||||||
self.checked = []
|
self.checked = []
|
||||||
|
@ -302,7 +307,7 @@ export default {
|
||||||
search (newValue) {
|
search (newValue) {
|
||||||
this.page = 1
|
this.page = 1
|
||||||
this.fetchData()
|
this.fetchData()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue