Skip to content

Commit

Permalink
fix: modify usages of Vue-tabulator to use Tabulator-table
Browse files Browse the repository at this point in the history
OpenSILEX/opensilex-dev!1202
  • Loading branch information
ROUX YVAN committed Apr 5, 2024
1 parent ed2a6c1 commit 74d7159
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 138 deletions.
187 changes: 90 additions & 97 deletions opensilex-front/front/src/components/common/forms/AttributesTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@
</b-row>
<b-row>
<b-col cols="10">
<VueTabulator
ref="tabulatorRef"
class="table-light table-bordered"
v-model="attributesArray"
:options="options"
@cell-click="removeRow"
/>
<div ref="table" class="tab"> </div>
</b-col>
</b-row>
</b-col>
Expand All @@ -31,129 +25,112 @@


<script lang="ts">
import { Component, Prop, Ref, PropSync } from "vue-property-decorator";
type Attribute = {
attribute: string,
value: string
}
import {Component, Prop, Ref, Watch} from "vue-property-decorator";
import Vue from "vue";
import {CellComponent, ColumnDefinition, TabulatorFull as Tabulator} from 'tabulator-tables';
// @ts-ignore
@Component
export default class AttributesTable extends Vue {
$opensilex: any;
$store: any;
$i18n: any;
langs: any = {
fr: {
//French language definition
columns: {
attribute: 'Attribut<span class="required">*</span>',
value: "Valeur",
actions: "Supprimer",
}
},
en: {
columns: {
attribute: 'Attribute<span class="required">*</span>',
value: "Value",
actions: "Delete",
}
},
};
@Ref("tabulatorRef") readonly tabulatorRef!: any;
@Ref("langInput") readonly langInput!: any;
@Ref("table") readonly table!: any;
@Prop()
editMode: boolean;
@Prop()
attributesArray;
tableColumns: any[] = [
{
title: 'attribute<span class="required">*</span>',
field: "attribute",
formater: "string",
editor: "input",
validator: ["required", "unique"],
widthGrow: 0.5,
},
{
title: "Value",
field: "value",
formater: "string",
editor: "input",
validator: ["required", "unique"],
widthGrow: 0.5
},
{
title: "Delete",
field: "actions",
widthGrow: 0.3,
formatter: function(cell, formatterParams, onRendered) {
attributesArray: Array<Attribute>;
private tabulatorData: Array<Attribute> = [];
// defined as computed to set titles reactive to lang switch
private get tableColumns(): ColumnDefinition[] {
return [
{
title: this.$t("AttributesTable.attribute") + '<span class="required">*</span>',
field: "attribute",
editor: "input",
validator: ["required", "unique"],
widthGrow: 0.5,
},
{
title: this.$t("AttributesTable.value").toString(),
field: "value",
editor: "input",
validator: ["required", "unique"],
widthGrow: 0.5
},
{
title: this.$t("AttributesTable.delete").toString(),
field: "actions",
widthGrow: 0.3,
formatter: function (cell, formatterParams, onRendered) {
return '<span style="color:red"><!----><svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="trash-alt" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-trash-alt fa-w-14 fa-sm"><path data-v-0514f944="" fill="currentColor" d="M32 464a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48V128H32zm272-256a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zm-96 0a16 16 0 0 1 32 0v224a16 16 0 0 1-32 0zM432 32H312l-9.4-18.7A24 24 0 0 0 281.1 0H166.8a23.72 23.72 0 0 0-21.4 13.3L136 32H16A16 16 0 0 0 0 48v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z" class=""></path></svg></span>';
}
}
}
];
created() {
]
}
private tabulator: Tabulator= null;
private langUnwatcher;
@Watch("tabulatorData")
newData(value: Array<Attribute>) {
this.tabulator.replaceData(value);
}
mounted() {
this.langUnwatcher = this.$store.watch(
() => this.$store.getters.language,
(lang) => {
this.changeTableLang(lang);
() => {
//change columns translation on lang change
this.instanciateTabulator()
}
);
this.tabulatorData = this.attributesArray;
this.instanciateTabulator()
}
beforeDestroy() {
this.langUnwatcher();
}
options: any = {
layout: "fitColumns",
cellHozAlign: "center",
clipboard: true,
columns: this.tableColumns,
maxHeight: "100%", //do not let table get bigger than the height of its parent element
langs: this.langs
};
resetTable() {
this.attributesArray = [];
public resetTable() {
this.tabulatorData = this.attributesArray ?? [];
this.instanciateTabulator()
}
addEmptyRow() {
console.debug("add row");
let tabulatorInstance = this.tabulatorRef.getInstance();
tabulatorInstance.addRow({
attribute: null,
value: null
let emptyRows = this.tabulatorData.filter( rowData => {
return rowData.attribute === undefined;
});
}
addRow(row) {
console.debug("add row", row);
if (row.attribute != undefined && row.attribute != null && row.attribute != "") {
this.attributesArray.unshift(row);
if (emptyRows.length === 0) {
this.tabulatorData = this.tabulatorData.concat([{attribute: undefined, value: undefined}])
}
}
removeRow(evt, clickedCell) {
let columnName = clickedCell.getField();
console.debug(columnName);
if (columnName == "actions") {
let row = clickedCell.getRow();
row.delete();
}
removeRow(attribute: string) {
this.tabulatorData = this.tabulatorData.filter( rowData => {
return rowData.attribute !== attribute;
});
}
pushAttributes(): { [key: string]: string; } {
let attributes = {};
let data = this.tabulatorRef.getInstance().getData();
let data = this.tabulatorData;
for (let y = 0; y < data.length; y++) {
if (data[y].attribute !== null) {
Expand All @@ -170,9 +147,7 @@ export default class AttributesTable extends Vue {
* @param metadata input metadata
* @param attributes output metadata. Attributes is reset and updated inside this function
*/
static readAttributes(
metadata: { [key: string]: string; },
attributes: Array<{ attribute: string, value: string }>) {
static readAttributes(metadata: { [key: string]: string; } ): Array<{ attribute: string, value: string }> {
let attributesArray = [];
if (metadata) {
Expand All @@ -185,20 +160,34 @@ export default class AttributesTable extends Vue {
}
}
// use splice() and push() method to ensure Vue reactivity
attributes.splice(0);
attributes.push(... attributesArray);
return attributesArray;
}
changeTableLang(lang: string) {
let tabulatorInstance = this.tabulatorRef.getInstance();
tabulatorInstance.setLocale(lang);
private instanciateTabulator() {
this.tabulator = new Tabulator(this.table, {
data: this.tabulatorData, //link data to table
reactiveData: true, //enable data reactivity
columns: this.tableColumns, //define table columns
layout: "fitColumns",
layoutColumnsOnNewData: true,
index: "attribute",
});
this.tabulator.on("cellClick", (e, cell) => {
if (cell.getField() === "actions") {
this.removeRow(cell.getRow().getData().attribute);
}
});
}
}
</script>

<style scoped lang="scss">
<style lang="scss">
.tabulator-row > .tabulator-cell {
text-align: center;
padding: 1%;
}
</style>

<i18n>
Expand All @@ -208,12 +197,16 @@ en:
title: Additional attributes
add: Add an attribute
attribute: Attribute
value: Value
delete: Delete


fr:
AttributesTable:
title: Attributs supplémentaires
add: Ajouter un attribut
attribute: Attribut
value: Valeur
delete: Supprimer

</i18n>
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export default class DeviceForm extends Vue {
reset() {
this.uriGenerated = true;
this.attTable.resetTable();
}
create(form: DeviceCreationDTO){
Expand All @@ -192,7 +193,7 @@ export default class DeviceForm extends Vue {
attributesArray = [];
readAttributes(metadata: { [key: string]: string; }) {
AttributesTable.readAttributes(metadata,this.attributesArray);
this.attributesArray = AttributesTable.readAttributes(metadata);
}
typeSwitch(type: string, initialLoad: boolean) {
Expand Down
Loading

0 comments on commit 74d7159

Please sign in to comment.