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); background-color: var(--color-background-column);
border-radius: var(--border-radius); border-radius: var(--border-radius);
padding: var(--spacer-sm); 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 { .col-1 {

View File

@ -59,6 +59,9 @@ export default {
props: [ props: [
"jobData", // Job data to show. "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() { data() {
return { return {
datetime: datetime, // So that the template can access it. datetime: datetime, // So that the template can access it.
@ -105,13 +108,13 @@ export default {
methods: { methods: {
_refreshJobSettings(newJobData) { _refreshJobSettings(newJobData) {
if (objectEmpty(newJobData)) { if (objectEmpty(newJobData)) {
this.simpleSettings = null; this._clearJobSettings();
return; return;
} }
// Only fetch the job type if it's different from what's already loaded. // Only fetch the job type if it's different from what's already loaded.
if (objectEmpty(this.jobType) || this.jobType.name != newJobData.type) { 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) this.jobsApi.getJobType(newJobData.type)
.then(this.onJobTypeLoaded) .then(this.onJobTypeLoaded)
@ -136,14 +139,20 @@ export default {
} }
}, },
_clearJobSettings() {
this.simpleSettings = null;
this.$emit('reshuffled');
},
_setJobSettings(newJobSettings) { _setJobSettings(newJobSettings) {
if (objectEmpty(newJobSettings)) { if (objectEmpty(newJobSettings)) {
this.simpleSettings = null; this._clearJobSettings();
return; return;
} }
if (objectEmpty(this.jobTypeSettings)) { if (objectEmpty(this.jobTypeSettings)) {
console.warn("empty job type settings"); console.warn("empty job type settings");
this._clearJobSettings();
return; return;
} }
@ -167,6 +176,7 @@ export default {
} }
this.simpleSettings = filtered; this.simpleSettings = filtered;
this.$emit('reshuffled');
} }
} }
}; };

View File

@ -5,11 +5,12 @@
:activeStatuses="shownStatuses" :activeStatuses="shownStatuses"
@click="toggleStatusFilter" @click="toggleStatusFilter"
/> />
<div class="task-list-container"> <div class="tabulator-container">
<div class="task-list" id="flamenco_task_list"></div> <div class="task-list" id="flamenco_task_list"></div>
</div> </div>
</template> </template>
<script lang="js"> <script lang="js">
import { TabulatorFull as Tabulator } from 'tabulator-tables'; import { TabulatorFull as Tabulator } from 'tabulator-tables';
import * as datetime from "@/datetime"; import * as datetime from "@/datetime";
@ -74,7 +75,8 @@ export default {
initialSort: [ initialSort: [
{ column: "updated", dir: "desc" }, { 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. data: [], // Will be filled via a Flamenco API request.
selectable: false, // The active task is tracked by click events. 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 = new Tabulator('#flamenco_task_list', options);
this.tabulator.on("rowClick", this.onRowClick); this.tabulator.on("rowClick", this.onRowClick);
this.tabulator.on("tableBuilt", this._onTableBuilt); this.tabulator.on("tableBuilt", this._onTableBuilt);
window.addEventListener('resize', this.recalcTableHeight);
},
unmounted() {
window.removeEventListener('resize', this.recalcTableHeight);
}, },
watch: { watch: {
jobID() { jobID() {
@ -91,6 +98,12 @@ export default {
this._reformatRow(oldID); this._reformatRow(oldID);
this._reformatRow(newID); 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: { methods: {
onReconnected() { onReconnected() {
@ -124,6 +137,8 @@ export default {
// let tasks = data.tasks.map((j) => API.TaskUpdate.constructFromObject(j)); // let tasks = data.tasks.map((j) => API.TaskUpdate.constructFromObject(j));
this.tabulator.setData(data.tasks); this.tabulator.setData(data.tasks);
this._refreshAvailableStatuses(); this._refreshAvailableStatuses();
this.recalcTableHeight();
}, },
processTaskUpdate(taskUpdate) { processTaskUpdate(taskUpdate) {
// updateData() will only overwrite properties that are actually set on // updateData() will only overwrite properties that are actually set on
@ -171,7 +186,34 @@ export default {
if (!row) return if (!row) return
if (row.reformat) row.reformat(); if (row.reformat) row.reformat();
else if (row.reinitialize) row.reinitialize(true); 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> </script>

View File

@ -2,8 +2,8 @@
<div class="col col-1"> <div class="col col-1">
<jobs-table ref="jobsTable" :activeJobID="jobID" @tableRowClicked="onTableJobClicked" /> <jobs-table ref="jobsTable" :activeJobID="jobID" @tableRowClicked="onTableJobClicked" />
</div> </div>
<div class="col col-2"> <div class="col col-2" id="col-job-details">
<job-details :jobData="jobs.activeJob" /> <job-details :jobData="jobs.activeJob" @reshuffled="_recalcTasksTableHeight" />
<tasks-table v-if="hasJobData" ref="tasksTable" :jobID="jobID" :taskID="taskID" @tableRowClicked="onTableTaskClicked" /> <tasks-table v-if="hasJobData" ref="tasksTable" :jobID="jobID" :taskID="taskID" @tableRowClicked="onTableTaskClicked" />
</div> </div>
<div class="col col-3"> <div class="col col-3">
@ -226,6 +226,12 @@ export default {
}, },
onSIODisconnected(reason) { 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> </script>