Fix: Tag Interface Delete Button #104256

Manually merged
Sybren A. Stüvel merged 39 commits from Evelinealy/flamenco:tag-interface into main 2023-11-02 16:13:14 +01:00
Showing only changes of commit 77a08c4254 - Show all commits

View File

@ -2,11 +2,11 @@
<div class="col col-workers-list">
<h2 class="column-title">Tag Details</h2>
<div class="action-buttons">
<button @click="fetchTags">Refresh</button>
<button @click="deleteTag" :disabled="tags.length === 0">
Delete Tag
</button>
<div class="action-buttons btn-bar-group">
<div class="btn-bar">
<button @click="fetchTags">Refresh</button>
<button @click="deleteTag" :disabled="!selectedTag">Delete Tag</button>
</div>
</div>
<div class="action-buttons">
@ -21,103 +21,17 @@
</form>
</div>
<!-- Table to display tags -->
<table v-if="tags.length > 0" class="tag-table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr
v-for="tag in tags"
:key="tag.name"
@click="onTagClick(tag)"
:class="{ selected: isSelected(tag) }"
>
<td>{{ tag.name }}</td>
<td>{{ tag.description }}</td>
<!-- Name editing field -->
<td>
<input
type="text"
v-if="isSelected(tag)"
v-model="tag.name"
@blur="updateTagName(tag)"
/>
<span v-else>{{ tag.name }}</span>
</td>
</tr>
</tbody>
</table>
<div v-else class="dl-no-data">
<span>No tags found.</span>
</div>
<div id="tag-table-container"></div>
</div>
<footer class="app-footer"></footer>
</template>
<style scoped>
.action-buttons {
margin-bottom: 10px;
margin-top: 10px;
}
.action-buttons button {
margin-right: 10px;
}
/* Add some basic styling to the table */
.tag-table {
background-color: var(--table-color-background-row-odd);
border-radius: var(--border-radius);
color: var(--color-text-muted);
font-family: var(--font-family-mono);
font-size: var(--font-size-sm);
text-align: left;
width: 100%;
border-collapse: collapse;
margin-top: 20px;
overflow: hidden;
position: relative;
text-align: left;
transform: translateZ(0);
}
.tag-table th {
height: 24px;
white-space: nowrap;
}
.tag-table td {
border: 1px solid #ccc;
padding: 8px;
text-align: left;
}
.tag-table th {
background-color: #f0f0f0;
}
.tag-table tbody tr:hover {
background-color: #f5f5f5;
}
/* Style for selected row */
.tag-table tbody tr.selected {
background-color: rgb(137, 130, 201);
font-weight: bold;
}
.selected {
background-color: #f0f0f0;
}
@import "@/assets/base.css";
</style>
<script>
import { TabulatorFull as Tabulator } from "tabulator-tables";
import { useWorkers } from "@/stores/workers";
import { useNotifs } from "@/stores/notifications";
import { WorkerMgtApi } from "@/manager-api";
@ -137,22 +51,56 @@ export default {
selectedTag: null,
newTagName: "",
workers: useWorkers(),
activeRowIndex: -1,
};
},
mounted() {
this.fetchTags();
const vueComponent = this;
const api = new WorkerMgtApi(getAPIClient());
window.api = api;
const tag_options = {
columns: [
{ title: "Name", field: "name", sorter: "string" },
{ title: "Description", field: "description", sorter: "string" },
],
rowFormatter(row) {
const data = row.getData();
const isActive = data.id === vueComponent.activeTagID;
const classList = row.getElement().classList;
classList.toggle("active-row", isActive);
classList.toggle("deletion-requested", !!data.delete_requested_at);
},
layout: "fitData",
layoutColumnsOnNewData: true,
height: "525px", // Must be set in order for the virtual DOM to function correctly.
selectable: true, // The active worker is tracked by click events, not row selection.
};
this.tabulator = new Tabulator("#tag-table-container", tag_options);
this.tabulator.on("rowClick", this.onRowClick);
this.tabulator.on("tableBuilt", () => {
this.fetchTags();
});
},
methods: {
sortData() {
const tab = this.tabulator;
tab.setSort(tab.getSorters()); // This triggers re-sorting.
},
_onTableBuilt() {
this.fetchTags();
},
fetchTags() {
this.workers
.refreshTags()
.then(() => {
this.tags = this.workers.tags;
this.tabulator.setData(this.tags);
})
.catch((error) => {
const errorMsg = JSON.stringify(error);
@ -168,7 +116,9 @@ export default {
api
.createWorkerTag(newTag)
.then(this.fetchTags)
.then(() => {
this.fetchTags(); // Refresh table data
})
.catch((error) => {
const errorMsg = JSON.stringify(error);
useNotifs().add(`Error: ${errorMsg}`);
@ -176,34 +126,40 @@ export default {
},
deleteTag() {
if (this.tags.length === 0) {
return;
}
if (!this.selectedTag) {
return;
}
// Find the index of the selected tag in the tags array
const index = this.tags.findIndex(
(tag) => tag.id === this.selectedTag.id
);
if (index !== -1) {
const api = new WorkerMgtApi(getAPIClient());
api
.deleteWorkerTag(this.selectedTag.id)
.then(() => {
const api = new WorkerMgtApi(getAPIClient());
api
.deleteWorkerTag(this.selectedTag.id)
.then(() => {
const index = this.tags.findIndex(
dr.sybren marked this conversation as resolved Outdated

Add this column to the end, so that it has the same layout as the job blocklist (there the is on the right as well).

Add this column to the end, so that it has the same layout as the job blocklist (there the ❌ is on the right as well).
(tag) => tag.id === this.selectedTag.id
);
if (index !== -1) {
this.tags.splice(index, 1);
this.selectedTag = null;
})
.catch((error) => {
const errorMsg = JSON.stringify(error);
useNotifs().add(`Error: ${errorMsg}`);
});
}
}
this.selectedTag = null;
this.tabulator.setData(this.tags);
})
.catch((error) => {
const errorMsg = JSON.stringify(error);
useNotifs().add(`Error: ${errorMsg}`);
});
},
onTagClick(tag) {
this.selectedTag = tag;
onRowClick(event, row) {
const tag = row.getData();
this.onTagClick(tag, row.getIndex());
},
onTagClick(tag, rowIndex) {
console.log("Clicked Tag:", tag);
console.log("Selected Tag:", this.selectedTag);
this.selectedTag = this.selectedTag === tag ? null : tag;
this.activeRowIndex = rowIndex;
},
},