*: abort async fetch on component destroy
* Use AbortController to signal fetch to stop when component is destroyed * Remove polling and just schedule a new fetch at the end of the current one when not aborted.
This commit is contained in:
parent
c6ab1ae54e
commit
32bd112516
|
@ -29,6 +29,8 @@ export default {
|
||||||
formatter.use_classes = true;
|
formatter.use_classes = true;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
items: [],
|
items: [],
|
||||||
lastitem: "",
|
lastitem: "",
|
||||||
lines: [],
|
lines: [],
|
||||||
|
@ -62,75 +64,106 @@ export default {
|
||||||
path += "&follow";
|
path += "&follow";
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = await fetch(apiurl(path));
|
try {
|
||||||
if (res.status == 200) {
|
this.fetching = true;
|
||||||
const reader = res.body.getReader();
|
let res = await fetch(apiurl(path), { signal: this.fetchAbort.signal });
|
||||||
|
if (res.status == 200) {
|
||||||
|
const reader = res.body.getReader();
|
||||||
|
|
||||||
let lastline = "";
|
let lastline = "";
|
||||||
let j = 0;
|
let j = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
let { done, value } = await reader.read();
|
let { done, value } = await reader.read();
|
||||||
if (done) {
|
if (done) {
|
||||||
return;
|
this.fetching = false;
|
||||||
}
|
return;
|
||||||
|
|
||||||
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
|
||||||
|
|
||||||
let part = "";
|
|
||||||
for (var i = 0; i < data.length; i++) {
|
|
||||||
let c = data.charAt(i);
|
|
||||||
if (c == "\r") {
|
|
||||||
// replace lastline from start, simulating line feed (go to start of line)
|
|
||||||
// this isn't perfect since the previous line contents could have
|
|
||||||
// been written using different colors and this will lose them but
|
|
||||||
// in practically all cases this won't happen
|
|
||||||
lastline =
|
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
|
||||||
j = 0;
|
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
|
||||||
part = "";
|
|
||||||
} else if (c == "\n") {
|
|
||||||
lastline =
|
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
|
||||||
j += part.length;
|
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
|
||||||
this.items.push(this.lastitem);
|
|
||||||
this.lastitem = "";
|
|
||||||
lastline = "";
|
|
||||||
j = 0;
|
|
||||||
part = "";
|
|
||||||
} else {
|
|
||||||
part += c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let data = new TextDecoder("utf-8").decode(value, { stream: true });
|
||||||
|
|
||||||
|
let part = "";
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
let c = data.charAt(i);
|
||||||
|
if (c == "\r") {
|
||||||
|
// replace lastline from start, simulating line feed (go to start of line)
|
||||||
|
// this isn't perfect since the previous line contents could have
|
||||||
|
// been written using different colors and this will lose them but
|
||||||
|
// in practically all cases this won't happen
|
||||||
|
lastline =
|
||||||
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
|
j = 0;
|
||||||
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
|
part = "";
|
||||||
|
} else if (c == "\n") {
|
||||||
|
lastline =
|
||||||
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
|
j += part.length;
|
||||||
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
|
this.items.push(this.lastitem);
|
||||||
|
this.lastitem = "";
|
||||||
|
lastline = "";
|
||||||
|
j = 0;
|
||||||
|
part = "";
|
||||||
|
} else {
|
||||||
|
part += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastline =
|
||||||
|
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
||||||
|
j += part.length;
|
||||||
|
this.lastitem = this.formatter.ansi_to_html(lastline);
|
||||||
}
|
}
|
||||||
lastline =
|
|
||||||
lastline.slice(0, j) + part + lastline.slice(j + part.length);
|
|
||||||
j += part.length;
|
|
||||||
this.lastitem = this.formatter.ansi_to_html(lastline);
|
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// TODO(sgotti) show that log fetching has failed
|
||||||
}
|
}
|
||||||
|
this.fetching = false;
|
||||||
|
},
|
||||||
|
abortFetch() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
show: function(post, pre) {
|
show: function(post, pre) {
|
||||||
if (pre == false && post == true) {
|
if (pre == false && post == true) {
|
||||||
|
this.abortFetch();
|
||||||
this.fetch();
|
this.fetch();
|
||||||
}
|
}
|
||||||
|
if (pre == true && post == false) {
|
||||||
|
this.abortFetch();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
stepphase: function(post, pre) {
|
stepphase: function(post) {
|
||||||
if (pre == "notstarted" && post == "running") {
|
if (!this.show) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.fetching) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (post == "running") {
|
||||||
|
this.abortFetch();
|
||||||
this.getLogs(true);
|
this.getLogs(true);
|
||||||
} else {
|
} else {
|
||||||
|
this.abortFetch();
|
||||||
this.getLogs(false);
|
this.getLogs(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function() {
|
created: function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
if (this.show) {
|
if (this.show) {
|
||||||
this.fetch();
|
this.fetch();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.es !== null) {
|
if (this.es !== null) {
|
||||||
this.es.close();
|
this.es.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,16 +59,21 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
fetchProjectGroupsLoading: false,
|
fetchProjectGroupsLoading: false,
|
||||||
fetchProjectsLoading: false,
|
fetchProjectsLoading: false,
|
||||||
|
|
||||||
projects: [],
|
projects: [],
|
||||||
projectgroups: [],
|
projectgroups: []
|
||||||
polling: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: async function() {
|
$route: async function() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
this.fetchProjects(this.ownertype, this.ownername);
|
this.fetchProjects(this.ownertype, this.ownername);
|
||||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||||
}
|
}
|
||||||
|
@ -101,10 +106,14 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startFetchProjectsLoading();
|
this.startFetchProjectsLoading();
|
||||||
let { data, error } = await fetchProjectGroupProjects(
|
let { data, error, aborted } = await fetchProjectGroupProjects(
|
||||||
projectgroupref.join("/")
|
projectgroupref.join("/"),
|
||||||
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectsLoading();
|
this.stopFetchProjectsLoading();
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -117,10 +126,14 @@ export default {
|
||||||
projectgroupref.push(...this.projectgroupref);
|
projectgroupref.push(...this.projectgroupref);
|
||||||
}
|
}
|
||||||
this.startFetchProjectGroupsLoading();
|
this.startFetchProjectGroupsLoading();
|
||||||
let { data, error } = await fetchProjectGroupSubgroups(
|
let { data, error, aborted } = await fetchProjectGroupSubgroups(
|
||||||
projectgroupref.join("/")
|
projectgroupref.join("/"),
|
||||||
|
this.fetchAbort.signal
|
||||||
);
|
);
|
||||||
this.stopFetchProjectGroupsLoading();
|
this.stopFetchProjectGroupsLoading();
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -131,8 +144,14 @@ export default {
|
||||||
projectGroupLink: projectGroupLink
|
projectGroupLink: projectGroupLink
|
||||||
},
|
},
|
||||||
created: function() {
|
created: function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
this.fetchProjects(this.ownertype, this.ownername);
|
this.fetchProjects(this.ownertype, this.ownername);
|
||||||
this.fetchProjectGroups(this.ownertype, this.ownername);
|
this.fetchProjectGroups(this.ownertype, this.ownername);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -125,13 +125,17 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
now: moment(),
|
now: moment(),
|
||||||
|
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
fetchRunsLoading: false,
|
fetchRunsLoading: false,
|
||||||
fetchRunsLoadingTimeout: false,
|
fetchRunsLoadingTimeout: false,
|
||||||
fetchRunsError: null,
|
fetchRunsError: null,
|
||||||
|
fetchRunsSchedule: null,
|
||||||
|
|
||||||
runs: null,
|
runs: null,
|
||||||
wantedRunsNumber: 25,
|
wantedRunsNumber: 25,
|
||||||
hasMoreRuns: false,
|
hasMoreRuns: false,
|
||||||
polling: null,
|
|
||||||
project: null,
|
project: null,
|
||||||
user: null
|
user: null
|
||||||
};
|
};
|
||||||
|
@ -163,22 +167,32 @@ export default {
|
||||||
return run.tasks_waiting_approval.length > 0;
|
return run.tasks_waiting_approval.length > 0;
|
||||||
},
|
},
|
||||||
update() {
|
update() {
|
||||||
clearInterval(this.polling);
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunsSchedule);
|
||||||
if (this.projectref !== undefined) {
|
if (this.projectref !== undefined) {
|
||||||
this.fetchProject();
|
this.fetchProject();
|
||||||
} else {
|
} else {
|
||||||
this.fetchUser();
|
this.fetchUser();
|
||||||
}
|
}
|
||||||
this.pollData();
|
|
||||||
},
|
},
|
||||||
async fetchProject() {
|
async fetchProject() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
let projectref = [
|
let projectref = [
|
||||||
this.ownertype,
|
this.ownertype,
|
||||||
this.ownername,
|
this.ownername,
|
||||||
...this.projectref
|
...this.projectref
|
||||||
].join("/");
|
].join("/");
|
||||||
|
|
||||||
let { data, error } = await fetchProject(projectref);
|
let { data, error, aborted } = await fetchProject(
|
||||||
|
projectref,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -188,7 +202,15 @@ export default {
|
||||||
this.fetchRuns(true);
|
this.fetchRuns(true);
|
||||||
},
|
},
|
||||||
async fetchUser() {
|
async fetchUser() {
|
||||||
let { data, error } = await fetchUser(this.ownername);
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
|
let { data, error, aborted } = await fetchUser(
|
||||||
|
this.ownername,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -227,10 +249,20 @@ export default {
|
||||||
|
|
||||||
if (loading) this.startFetchRunsLoading();
|
if (loading) this.startFetchRunsLoading();
|
||||||
while (!stopFetch) {
|
while (!stopFetch) {
|
||||||
let { data, error } = await fetchRuns(group, startRunID, lastrun);
|
let { data, error, aborted } = await fetchRuns(
|
||||||
|
group,
|
||||||
|
startRunID,
|
||||||
|
lastrun,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.stopFetchRunsLoading();
|
this.stopFetchRunsLoading();
|
||||||
this.fetchRunsError = error;
|
this.fetchRunsError = error;
|
||||||
|
|
||||||
|
this.scheduleFetchRuns();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchRunsError = null;
|
this.fetchRunsError = null;
|
||||||
|
@ -247,10 +279,12 @@ export default {
|
||||||
this.stopFetchRunsLoading();
|
this.stopFetchRunsLoading();
|
||||||
this.runs = newRuns;
|
this.runs = newRuns;
|
||||||
this.hasMoreRuns = hasMoreRuns;
|
this.hasMoreRuns = hasMoreRuns;
|
||||||
|
|
||||||
|
this.scheduleFetchRuns();
|
||||||
},
|
},
|
||||||
pollData() {
|
scheduleFetchRuns() {
|
||||||
clearInterval(this.polling);
|
clearTimeout(this.fetchRunsSchedule);
|
||||||
this.polling = setInterval(() => {
|
this.fetchRunsSchedule = setTimeout(() => {
|
||||||
this.fetchRuns();
|
this.fetchRuns();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
|
@ -293,7 +327,10 @@ export default {
|
||||||
this.update();
|
this.update();
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
clearInterval(this.polling);
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunsSchedule);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -68,9 +68,11 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
fetchRunError: null,
|
fetchRunError: null,
|
||||||
|
fetchRunSchedule: null,
|
||||||
run: null,
|
run: null,
|
||||||
polling: null,
|
|
||||||
|
|
||||||
taskWidth: 200,
|
taskWidth: 200,
|
||||||
taskHeight: 40,
|
taskHeight: 40,
|
||||||
|
@ -81,6 +83,18 @@ export default {
|
||||||
tasksDisplay: "graph"
|
tasksDisplay: "graph"
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
$route: async function() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunSchedule);
|
||||||
|
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
|
this.fetchRun();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
runTaskLink(task) {
|
runTaskLink(task) {
|
||||||
if (this.projectref) {
|
if (this.projectref) {
|
||||||
|
@ -108,9 +122,17 @@ export default {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error } = await fetchRun(this.runid);
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
this.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.fetchRunError = error;
|
this.fetchRunError = error;
|
||||||
|
|
||||||
|
this.scheduleFetchRun();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchRunError = null;
|
this.fetchRunError = null;
|
||||||
|
@ -127,19 +149,25 @@ export default {
|
||||||
taskID
|
taskID
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.scheduleFetchRun();
|
||||||
},
|
},
|
||||||
pollData() {
|
scheduleFetchRun() {
|
||||||
this.polling = setInterval(() => {
|
clearTimeout(this.fetchRunSchedule);
|
||||||
|
this.fetchRunSchedule = setTimeout(() => {
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: function() {
|
created: function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
this.pollData();
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
clearInterval(this.polling);
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunSchedule);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<div>Error fetching Run: {{ fetchRunError }}</div>
|
<div>Error fetching Run: {{ fetchRunError }}</div>
|
||||||
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
<div>Error fetching Task: {{ fetchTaskError }}</div>
|
||||||
</div>
|
</div>
|
||||||
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref"/>
|
<rundetail :run="run" :ownertype="ownertype" :ownername="ownername" :projectref="projectref" />
|
||||||
<div v-if="task != null">
|
<div v-if="task != null">
|
||||||
<div class="mt-8 mb-4 flex justify-between items-center">
|
<div class="mt-8 mb-4 flex justify-between items-center">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
@ -64,13 +64,29 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
fetchRunError: null,
|
fetchRunError: null,
|
||||||
fetchTaskError: null,
|
fetchTaskError: null,
|
||||||
|
|
||||||
run: null,
|
run: null,
|
||||||
task: null,
|
task: null
|
||||||
polling: null
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
$route: async function() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunSchedule);
|
||||||
|
clearTimeout(this.fetchTaskSchedule);
|
||||||
|
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
|
this.fetchRun();
|
||||||
|
this.fetchTask();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
taskClass(task) {
|
taskClass(task) {
|
||||||
if (task.status == "success") return "is-success";
|
if (task.status == "success") return "is-success";
|
||||||
|
@ -81,38 +97,66 @@ export default {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
},
|
},
|
||||||
async fetchRun() {
|
async fetchRun() {
|
||||||
let { data, error } = await fetchRun(this.runid);
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
this.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.fetchRunError = error;
|
this.fetchRunError = error;
|
||||||
|
this.scheduleFetchRun();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchRunError = error;
|
this.fetchRunError = error;
|
||||||
this.run = data;
|
this.run = data;
|
||||||
|
this.scheduleFetchRun();
|
||||||
},
|
},
|
||||||
async fetchTask() {
|
async fetchTask() {
|
||||||
let { data, error } = await fetchTask(this.runid, this.taskid);
|
let { data, error, aborted } = await fetchTask(
|
||||||
|
this.runid,
|
||||||
|
this.taskid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.fetchTaskError = error;
|
this.fetchTaskError = error;
|
||||||
|
this.scheduleFetchTask();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.fetchTaskError = error;
|
this.fetchTaskError = error;
|
||||||
this.task = data;
|
this.task = data;
|
||||||
|
this.scheduleFetchTask();
|
||||||
},
|
},
|
||||||
pollData() {
|
scheduleFetchRun() {
|
||||||
this.polling = setInterval(() => {
|
clearTimeout(this.fetchRunSchedule);
|
||||||
this.fetchTask();
|
this.fetchRunSchedule = setTimeout(() => {
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
|
scheduleFetchTask() {
|
||||||
|
clearTimeout(this.fetchTaskSchedule);
|
||||||
|
this.fetchTaskSchedule = setTimeout(() => {
|
||||||
|
this.fetchTask();
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
approveTask: approveTask
|
approveTask: approveTask
|
||||||
},
|
},
|
||||||
created: function() {
|
created: function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
this.fetchRun();
|
this.fetchRun();
|
||||||
this.fetchTask();
|
this.fetchTask();
|
||||||
this.pollData();
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
clearInterval(this.polling);
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
clearTimeout(this.fetchRunSchedule);
|
||||||
|
clearTimeout(this.fetchTaskSchedule);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -71,13 +71,16 @@ export async function registerapi(init) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetch(url, init) {
|
export async function fetch(url, init, signal) {
|
||||||
if (init === undefined) {
|
if (!init) {
|
||||||
init = {}
|
init = {}
|
||||||
}
|
}
|
||||||
if (init.headers === undefined) {
|
if (init.headers === undefined) {
|
||||||
init["headers"] = {}
|
init["headers"] = {}
|
||||||
}
|
}
|
||||||
|
if (signal) {
|
||||||
|
init["signal"] = signal;
|
||||||
|
}
|
||||||
let idToken = getIdToken();
|
let idToken = getIdToken();
|
||||||
if (idToken) {
|
if (idToken) {
|
||||||
init.headers["Authorization"] = "bearer " + idToken
|
init.headers["Authorization"] = "bearer " + idToken
|
||||||
|
|
130
src/util/data.js
130
src/util/data.js
|
@ -1,10 +1,9 @@
|
||||||
import { apiurl, loginapi, registerapi } from "@/util/auth";
|
|
||||||
import { fetch as authfetch } from "@/util/auth";
|
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
import { apiurl, fetch as authfetch, loginapi, registerapi } from "@/util/auth";
|
||||||
|
|
||||||
export async function fetch(url, init) {
|
export async function fetch(url, init, signal) {
|
||||||
try {
|
try {
|
||||||
let res = await authfetch(url, init)
|
let res = await authfetch(url, init, signal)
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
if (res.status === 401) {
|
if (res.status === 401) {
|
||||||
router.push({ name: "login" })
|
router.push({ name: "login" })
|
||||||
|
@ -31,6 +30,9 @@ export async function fetch(url, init) {
|
||||||
return { data: await res.json(), error: null }
|
return { data: await res.json(), error: null }
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (e.name == 'AbortError') {
|
||||||
|
return { data: null, error: null, aborted: true, }
|
||||||
|
}
|
||||||
return { data: null, error: "api call failed: " + e.message }
|
return { data: null, error: "api call failed: " + e.message }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,17 +84,17 @@ export async function register(username, remotesourcename, remoteloginname, remo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchCurrentUser() {
|
export async function fetchCurrentUser(signal) {
|
||||||
let path = "/user"
|
let path = "/user"
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchOrgMembers(orgref) {
|
export async function fetchOrgMembers(orgref, signal) {
|
||||||
let path = "/orgs/" + orgref + "/members"
|
let path = "/orgs/" + orgref + "/members"
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRuns(group, startRunID, lastrun) {
|
export async function fetchRuns(group, startRunID, lastrun, signal) {
|
||||||
let u = apiurl("/runs");
|
let u = apiurl("/runs");
|
||||||
if (group) {
|
if (group) {
|
||||||
u.searchParams.append("group", group)
|
u.searchParams.append("group", group)
|
||||||
|
@ -104,49 +106,49 @@ export async function fetchRuns(group, startRunID, lastrun) {
|
||||||
u.searchParams.append("start", startRunID)
|
u.searchParams.append("start", startRunID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await fetch(u)
|
return await fetch(u, null, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRun(runid) {
|
export async function fetchRun(runid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid));
|
return await fetch(apiurl("/runs/" + runid), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchTask(runid, taskid) {
|
export async function fetchTask(runid, taskid, signal) {
|
||||||
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid))
|
return await fetch(apiurl("/runs/" + runid + "/tasks/" + taskid), signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchUser(username) {
|
export async function fetchUser(username, signal) {
|
||||||
let path = "/users/" + username
|
let path = "/users/" + username
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroup(projectgroupref) {
|
export async function fetchProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||||
|
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupSubgroups(projectgroupref) {
|
export async function fetchProjectGroupSubgroups(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||||
path += "/subgroups";
|
path += "/subgroups";
|
||||||
|
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProjectGroupProjects(projectgroupref) {
|
export async function fetchProjectGroupProjects(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||||
path += "/projects";
|
path += "/projects";
|
||||||
|
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchProject(ref) {
|
export async function fetchProject(ref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(ref)
|
let path = "/projects/" + encodeURIComponent(ref)
|
||||||
|
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchSecrets(ownertype, ref, all) {
|
export async function fetchSecrets(ownertype, ref, all, signal) {
|
||||||
let path
|
let path
|
||||||
if (ownertype == "project") {
|
if (ownertype == "project") {
|
||||||
path = "/projects/"
|
path = "/projects/"
|
||||||
|
@ -158,10 +160,10 @@ export async function fetchSecrets(ownertype, ref, all) {
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += "?tree&removeoverridden";
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchVariables(ownertype, ref, all) {
|
export async function fetchVariables(ownertype, ref, all, signal) {
|
||||||
let path
|
let path
|
||||||
if (ownertype == "project") {
|
if (ownertype == "project") {
|
||||||
path = "/projects/"
|
path = "/projects/"
|
||||||
|
@ -173,10 +175,10 @@ export async function fetchVariables(ownertype, ref, all) {
|
||||||
if (all) {
|
if (all) {
|
||||||
path += "?tree&removeoverridden";
|
path += "?tree&removeoverridden";
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createOrganization(orgname, visibility) {
|
export async function createOrganization(orgname, visibility, signal) {
|
||||||
let path = "/orgs"
|
let path = "/orgs"
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -185,10 +187,10 @@ export async function createOrganization(orgname, visibility) {
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUserToken(username, tokenname) {
|
export async function createUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens"
|
let path = "/users/" + username + "/tokens"
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -196,18 +198,18 @@ export async function createUserToken(username, tokenname) {
|
||||||
token_name: tokenname,
|
token_name: tokenname,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUserToken(username, tokenname) {
|
export async function deleteUserToken(username, tokenname, signal) {
|
||||||
let path = "/users/" + username + "/tokens/" + tokenname
|
let path = "/users/" + username + "/tokens/" + tokenname
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createUserLinkedAccount(username, remotesourcename, loginname, password) {
|
export async function createUserLinkedAccount(username, remotesourcename, loginname, password, signal) {
|
||||||
let path = "/users/" + username + "/linkedaccounts"
|
let path = "/users/" + username + "/linkedaccounts"
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -217,18 +219,18 @@ export async function createUserLinkedAccount(username, remotesourcename, loginn
|
||||||
remote_source_login_password: password,
|
remote_source_login_password: password,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteLinkedAccount(username, laid) {
|
export async function deleteLinkedAccount(username, laid, signal) {
|
||||||
let path = "/users/" + username + "/linkedaccounts/" + laid
|
let path = "/users/" + username + "/linkedaccounts/" + laid
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function restartRun(runid, fromStart) {
|
export async function restartRun(runid, fromStart, signal) {
|
||||||
let path = "/runs/" + runid + "/actions"
|
let path = "/runs/" + runid + "/actions"
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -237,10 +239,10 @@ export async function restartRun(runid, fromStart) {
|
||||||
from_start: fromStart
|
from_start: fromStart
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelRun(runid) {
|
export async function cancelRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions"
|
let path = "/runs/" + runid + "/actions"
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -248,10 +250,10 @@ export async function cancelRun(runid) {
|
||||||
action_type: "cancel"
|
action_type: "cancel"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function stopRun(runid) {
|
export async function stopRun(runid, signal) {
|
||||||
let path = "/runs/" + runid + "/actions"
|
let path = "/runs/" + runid + "/actions"
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -259,10 +261,10 @@ export async function stopRun(runid) {
|
||||||
action_type: "stop"
|
action_type: "stop"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function approveTask(runid, taskid) {
|
export async function approveTask(runid, taskid, signal) {
|
||||||
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions"
|
let path = "/runs/" + runid + "/tasks/" + taskid + "/actions"
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -270,20 +272,20 @@ export async function approveTask(runid, taskid) {
|
||||||
action_type: "approve"
|
action_type: "approve"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchRemoteSources() {
|
export async function fetchRemoteSources(signal) {
|
||||||
let path = "/remotesources"
|
let path = "/remotesources"
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path), null, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function userRemoteRepos(remotesourceid) {
|
export async function userRemoteRepos(remotesourceid, signal) {
|
||||||
let path = "/user/remoterepos/" + remotesourceid
|
let path = "/user/remoterepos/" + remotesourceid
|
||||||
return await fetch(apiurl(path));
|
return await fetch(apiurl(path, null, signal));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createProjectGroup(parentref, name, visibility) {
|
export async function createProjectGroup(parentref, name, visibility, signal) {
|
||||||
let path = "/projectgroups"
|
let path = "/projectgroups"
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -293,10 +295,10 @@ export async function createProjectGroup(parentref, name, visibility) {
|
||||||
visibility: visibility
|
visibility: visibility
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProjectGroup(projectgroupref, name, visibility) {
|
export async function updateProjectGroup(projectgroupref, name, visibility, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -305,10 +307,10 @@ export async function updateProjectGroup(projectgroupref, name, visibility) {
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createProject(parentref, name, visibility, remotesourcename, remoterepopath) {
|
export async function createProject(parentref, name, visibility, remotesourcename, remoterepopath, signal) {
|
||||||
let path = "/projects"
|
let path = "/projects"
|
||||||
let init = {
|
let init = {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -320,10 +322,10 @@ export async function createProject(parentref, name, visibility, remotesourcenam
|
||||||
repo_path: remoterepopath,
|
repo_path: remoterepopath,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProject(projectref, name, visibility) {
|
export async function updateProject(projectref, name, visibility, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(projectref)
|
let path = "/projects/" + encodeURIComponent(projectref)
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
|
@ -332,29 +334,29 @@ export async function updateProject(projectref, name, visibility) {
|
||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProject(projectref) {
|
export async function deleteProject(projectref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(projectref)
|
let path = "/projects/" + encodeURIComponent(projectref)
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function projectUpdateRepoLinkedAccount(projectref) {
|
export async function projectUpdateRepoLinkedAccount(projectref, signal) {
|
||||||
let path = "/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount"
|
let path = "/projects/" + encodeURIComponent(projectref) + "/updaterepolinkedaccount"
|
||||||
let init = {
|
let init = {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteProjectGroup(projectgroupref) {
|
export async function deleteProjectGroup(projectgroupref, signal) {
|
||||||
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
let path = "/projectgroups/" + encodeURIComponent(projectgroupref)
|
||||||
let init = {
|
let init = {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
}
|
}
|
||||||
return await fetch(apiurl(path), init)
|
return await fetch(apiurl(path), init, signal)
|
||||||
}
|
}
|
|
@ -24,7 +24,6 @@ export default {
|
||||||
error: null,
|
error: null,
|
||||||
run: null,
|
run: null,
|
||||||
code: this.$route.query.code,
|
code: this.$route.query.code,
|
||||||
polling: null,
|
|
||||||
username: null
|
username: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -168,15 +168,28 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: async function(route) {
|
$route: async function(route) {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
this.run = null;
|
this.run = null;
|
||||||
if (route.params.runid) {
|
if (route.params.runid) {
|
||||||
let { data, error } = await fetchRun(route.params.runid);
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
route.params.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -199,14 +212,27 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: async function() {
|
created: async function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
if (this.$route.params.runid) {
|
if (this.$route.params.runid) {
|
||||||
let { data, error } = await fetchRun(this.$route.params.runid);
|
let { data, error } = await fetchRun(
|
||||||
|
this.$route.params.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -164,15 +164,28 @@ export default {
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
fetchAbort: null,
|
||||||
|
|
||||||
dropdownActive: false,
|
dropdownActive: false,
|
||||||
run: null
|
run: null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: async function(route) {
|
$route: async function(route) {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
this.run = null;
|
this.run = null;
|
||||||
|
|
||||||
if (route.params.runid) {
|
if (route.params.runid) {
|
||||||
let { data, error } = await fetchRun(route.params.runid);
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
route.params.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
|
@ -204,14 +217,27 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created: async function() {
|
created: async function() {
|
||||||
|
this.fetchAbort = new AbortController();
|
||||||
|
|
||||||
if (this.$route.params.runid) {
|
if (this.$route.params.runid) {
|
||||||
let { data, error } = await fetchRun(this.$route.params.runid);
|
let { data, error, aborted } = await fetchRun(
|
||||||
|
this.$route.params.runid,
|
||||||
|
this.fetchAbort.signal
|
||||||
|
);
|
||||||
|
if (aborted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
this.$store.dispatch("setError", error);
|
this.$store.dispatch("setError", error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.run = data;
|
this.run = data;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.fetchAbort) {
|
||||||
|
this.fetchAbort.abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue