Merge branch 'temp-fix-tabulator-height' into main

This commit is contained in:
Sybren A. Stüvel 2022-05-30 15:48:27 +02:00
commit 9e22cda793
4 changed files with 74 additions and 8 deletions

View File

@ -101,6 +101,14 @@ body {
background-color: var(--color-background-column);
border-radius: var(--border-radius);
padding: var(--spacer-sm);
/* These two are necessary for the automatic resizing of the tasks table: */
/* Ensures that the table cannot push down the bottom of the column element,
* and thus the column height is a stable reference. */
overflow-y: auto;
/* Ensures the offsetParent of the table is the column itself; without this,
* offsetParent would be <body>. */
position: relative;
}
.col-1 {

View File

@ -59,6 +59,9 @@ export default {
props: [
"jobData", // Job data to show.
],
emits: [
"reshuffled", // Emitted when the size of this component may have changed. Used to resize other components in response.
],
data() {
return {
datetime: datetime, // So that the template can access it.
@ -105,13 +108,13 @@ export default {
methods: {
_refreshJobSettings(newJobData) {
if (objectEmpty(newJobData)) {
this.simpleSettings = null;
this._clearJobSettings();
return;
}
// Only fetch the job type if it's different from what's already loaded.
if (objectEmpty(this.jobType) || this.jobType.name != newJobData.type) {
this.simpleSettings = null; // They should only be shown when the type info is known.
this._clearJobSettings(); // They should only be shown when the type info is known.
this.jobsApi.getJobType(newJobData.type)
.then(this.onJobTypeLoaded)
@ -136,14 +139,20 @@ export default {
}
},
_clearJobSettings() {
this.simpleSettings = null;
this.$emit('reshuffled');
},
_setJobSettings(newJobSettings) {
if (objectEmpty(newJobSettings)) {
this.simpleSettings = null;
this._clearJobSettings();
return;
}
if (objectEmpty(this.jobTypeSettings)) {
console.warn("empty job type settings");
this._clearJobSettings();
return;
}
@ -167,6 +176,7 @@ export default {
}
this.simpleSettings = filtered;
this.$emit('reshuffled');
}
}
};

View File

@ -5,11 +5,12 @@
:activeStatuses="shownStatuses"
@click="toggleStatusFilter"
/>
<div class="task-list-container">
<div class="tabulator-container">
<div class="task-list" id="flamenco_task_list"></div>
</div>
</template>
<script lang="js">
import { TabulatorFull as Tabulator } from 'tabulator-tables';
import * as datetime from "@/datetime";
@ -74,7 +75,8 @@ export default {
initialSort: [
{ column: "updated", dir: "desc" },
],
height: "300px", // Must be set in order for the virtual DOM to function correctly.
height: "100%", // Must be set in order for the virtual DOM to function correctly.
maxHeight: "100%",
data: [], // Will be filled via a Flamenco API request.
selectable: false, // The active task is tracked by click events.
};
@ -82,6 +84,11 @@ export default {
this.tabulator = new Tabulator('#flamenco_task_list', options);
this.tabulator.on("rowClick", this.onRowClick);
this.tabulator.on("tableBuilt", this._onTableBuilt);
window.addEventListener('resize', this.recalcTableHeight);
},
unmounted() {
window.removeEventListener('resize', this.recalcTableHeight);
},
watch: {
jobID() {
@ -91,6 +98,12 @@ export default {
this._reformatRow(oldID);
this._reformatRow(newID);
},
availableStatuses() {
// Statuses changed, so the filter bar could have gone from "no statuses"
// to "any statuses" (or one row of filtering stuff to two, I don't know)
// and changed height.
this.$nextTick(this.recalcTableHeight);
},
},
methods: {
onReconnected() {
@ -124,6 +137,8 @@ export default {
// let tasks = data.tasks.map((j) => API.TaskUpdate.constructFromObject(j));
this.tabulator.setData(data.tasks);
this._refreshAvailableStatuses();
this.recalcTableHeight();
},
processTaskUpdate(taskUpdate) {
// updateData() will only overwrite properties that are actually set on
@ -171,7 +186,34 @@ export default {
if (!row) return
if (row.reformat) row.reformat();
else if (row.reinitialize) row.reinitialize(true);
}
},
/**
* Recalculate the appropriate table height to fit in the column without making that scroll.
*/
recalcTableHeight() {
if (!this.tabulator.initialized) {
// Sometimes this function is called too early, before the table was initialised.
// After the table is initialised it gets resized anyway, so this call can be ignored.
return;
}
const table = this.tabulator.element;
const tableContainer = table.parentElement;
const outerContainer = tableContainer.parentElement;
const availableHeight = outerContainer.clientHeight - 12; // TODO: figure out where the -12 comes from.
if (tableContainer.offsetParent != tableContainer.parentElement) {
// `offsetParent` is assumed to be the actual column in the 3-column
// view. To ensure this, it's given `position: relative` in the CSS
// styling.
console.warn("TaskTable.recalcTableHeight() only works when the offset parent is the real parent of the element.");
return;
}
const tableHeight = availableHeight - tableContainer.offsetTop;
this.tabulator.setHeight(tableHeight);
},
}
};
</script>

View File

@ -2,8 +2,8 @@
<div class="col col-1">
<jobs-table ref="jobsTable" :activeJobID="jobID" @tableRowClicked="onTableJobClicked" />
</div>
<div class="col col-2">
<job-details :jobData="jobs.activeJob" />
<div class="col col-2" id="col-job-details">
<job-details :jobData="jobs.activeJob" @reshuffled="_recalcTasksTableHeight" />
<tasks-table v-if="hasJobData" ref="tasksTable" :jobID="jobID" :taskID="taskID" @tableRowClicked="onTableTaskClicked" />
</div>
<div class="col col-3">
@ -226,6 +226,12 @@ export default {
},
onSIODisconnected(reason) {
},
_recalcTasksTableHeight() {
if (!this.$refs.tasksTable) return;
// Any recalculation should be done after the DOM has updated.
this.$nextTick(this.$refs.tasksTable.recalcTableHeight);
},
},
}
</script>