Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/bim data table filter #336

Merged
merged 26 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 58 additions & 6 deletions src/BIMDataComponents/BIMDataTable/BIMDataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
textAlign: column.align || 'left',
}"
>
{{ column.id ? column.label || column.id : column }}
<div :style="{ display: 'inline-flex' }">
{{ column.id ? column.label || column.id : column }}
<slot name="header-right"></slot>
<HeaderTableFilter
NicolasRichel marked this conversation as resolved.
Show resolved Hide resolved
v-if="column.sortable"
:column="column"
@click="toggleSorting(column)"
/>
</div>
</th>
</tr>
<tr key="head-row-1">
Expand All @@ -37,7 +45,7 @@
</thead>
<tbody @dragleave="onDragleave">
<tr
v-for="{ key, data } of computedRows"
v-for="{ key, data } of sortedRows"
:key="`body-row-${key}`"
v-show="displayedRows.includes(key)"
:style="{ height: `${rowHeight}px` }"
Expand Down Expand Up @@ -117,12 +125,14 @@ import { useRowSelection } from "./table-row-selection.js";
import BIMDataButton from "../BIMDataButton/BIMDataButton.vue";
import BIMDataCheckbox from "../BIMDataCheckbox/BIMDataCheckbox.vue";
import BIMDataIconChevron from "../BIMDataIcon/BIMDataIconStandalone/BIMDataIconChevron.vue";
import HeaderTableFilter from "./header-table-filter/HeaderTableFilter.vue";

export default {
components: {
BIMDataButton,
BIMDataCheckbox,
BIMDataIconChevron,
HeaderTableFilter,
},
props: {
columns: {
Expand Down Expand Up @@ -185,7 +195,7 @@ export default {
setup(props, { emit }) {
// Compute rows keys based on props values.
const computedRows = computed(() =>
props.rows.map((row, i) => ({ key: row[props.rowKey] ?? i, data: row }))
props.rows.map((row, i) => ({ key: row[props.rowKey] ?? i, data: row })),
);

const { rowSelection, toggleRowSelection, toggleFullSelection } =
Expand All @@ -211,7 +221,7 @@ export default {
emit("all-deselected");
}
},
}
},
);

const toggleRow = row => {
Expand All @@ -236,7 +246,7 @@ export default {
() => {
pageIndex.value = 0;
},
{ immediate: true }
{ immediate: true },
);
// Compute `displayedRows` according to rows array and pagination settings.
watch(
Expand All @@ -254,7 +264,7 @@ export default {
displayedRows.value = rowKeys;
}
},
{ immediate: true }
{ immediate: true },
);

const onDrop = (data, event) => {
Expand All @@ -274,6 +284,46 @@ export default {
dragOveredRowKey.value = null;
};

const sortingColumn = ref(null);
const sortedRows = computed(() => {
if (sortingColumn.value) {
// by default, sort in ascending order
const ascendingSort =
LrxGaelle marked this conversation as resolved.
Show resolved Hide resolved
sortingColumn.value.defaultSortAs !== "desc" ? 1 : -1;
if (sortingColumn.value.sortFunction) {
const sortFunction = (a, b) => {
return (
sortingColumn.value.sortFunction(a.data, b.data) * ascendingSort
);
};
return Array.from(computedRows.value).sort(sortFunction);
} else {
return Array.from(computedRows.value).sort((a, b) => {
if (
a.data[sortingColumn.value.id] < b.data[sortingColumn.value.id]
) {
return ascendingSort;
}
if (
a.data[sortingColumn.value.id] > b.data[sortingColumn.value.id]
) {
return -ascendingSort;
}
return 0;
});
}
}
return computedRows.value;
});
const toggleSorting = column => {
if (column.defaultSortAs === "asc") {
column.defaultSortAs = "desc";
} else {
column.defaultSortAs = "asc";
}
sortingColumn.value = column;
};

return {
// References
computedRows,
Expand All @@ -289,6 +339,8 @@ export default {
onDragleave,
toggleAll,
toggleRow,
toggleSorting,
sortedRows,
};
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<span
v-if="column.sortable"
:class="[column.defaultSortAs === 'asc' ? 'asc' : 'desc', 'm-l-6']"
@mousedown.prevent
>
<BIMDataIconUp
v-if="column.defaultSortAs === 'desc'"
size="xxxs"
fill
color="default"
/>
<BIMDataIconDown
v-if="column.defaultSortAs === 'asc'"
size="xxxs"
fill
color="default"
/>
</span>
</template>

<script>
export default {
props: {
column: {
type: Object,
required: true,
},
},
};
</script>

<style scoped lang="scss">
span {
cursor: pointer;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

LrxGaelle marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 25 additions & 4 deletions src/web/views/Components/Table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
:paginated="simpleExample.paginated"
:perPage="+simpleExample.perPage"
@selection-changed="simpleExample.selection = $event"
/>
>
</BIMDataTable>
<div class="selection-box">
<div class="selection-box__label">Selection :</div>
<div
Expand Down Expand Up @@ -160,9 +161,17 @@
<Code language="javascript">
<pre>
let columns = [
{ id: "fullName", label: "Name" },
{ id: "age", label: "Age", width: "64px" },
{ id: "country", label: "Country", width: "200px", align: "center" }
{
id: "fullName",
label: "Name",
sortable: true, defaultSortAs: "desc",
sortFunction: (a, b) => {
const fullNameA = `${a.firstName} ${a.lastName}`;
const fullNameB = `${b.firstName} ${b.lastName}`;
return fullNameA &lt; fullNameB ? 1 : -1;
},
{ id: "age", label: "Age", width: "64px", sortable: true, defaultSortAs: "desc" },
{ id: "country", label: "Country", width: "200px", align: "center", sortable: true, defaultSortAs: "desc" }
];
</pre>
</Code>
Expand Down Expand Up @@ -298,17 +307,29 @@ export default {
{
id: "fullName",
label: "Name",
sortable: true,
defaultSortAs: "desc",
sortFunction: (a, b) => {
const fullNameA = `${a.firstName} ${a.lastName}`;
const fullNameB = `${b.firstName} ${b.lastName}`;

return fullNameA < fullNameB ? 1 : -1;
},
},
{
id: "age",
label: "Age",
width: "64px",
sortable: true,
defaultSortAs: "desc",
},
{
id: "country",
label: "Country",
width: "200px",
align: "center",
sortable: true,
defaultSortAs: "desc",
},
],
rows: [
Expand Down
15 changes: 15 additions & 0 deletions src/web/views/Components/Table/columns-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,19 @@ export default [
"'left' ; 'center' ; 'right'",
"Set how text is aligned in the column.",
],
[
"sortable",
"Boolean",
"If you want to sort the column, set this to true. Sortable by id value.",
],
[
"defaultSortAs",
LrxGaelle marked this conversation as resolved.
Show resolved Hide resolved
"'desc' ; 'asc'",
"Set the default sort order for the column.",
],
[
"sortFunction",
"Function",
"Set a custom sort function for the column. If not specified, the default sort function will be used.",
],
];
Loading