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

update datatables to v2 #197

Merged
merged 5 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion app/assets/stylesheets/layout.scss
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ though the color below doesn't improve much.
right: 27px;
}
}
div.dataTables_wrapper {
.dataTables_wrapper {
table {
tbody {
a {
Expand All @@ -395,6 +395,7 @@ though the color below doesn't improve much.
}
}
}
.dt-length,
.dataTables_length {
display: none;
}
Expand Down
8 changes: 5 additions & 3 deletions app/javascript/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
/* Data Tables */
.datatable input[type="search"],
.dataTables_wrapper input[type="search"],
.dt-container input[type="search"],
.data-table tfoot input {
font-size: 16px;
border: 0;
Expand All @@ -49,13 +50,14 @@

.datatable,
.dataTables_wrapper,
.dt-container,
.data-table.table-bordered th {
border-left: 0;
border-right: 0;
}

/* right align search on vue pages */
[data-behavior="vue"] div.dataTables_wrapper div.dataTables_filter {
[data-behavior="vue"] .dt-container .dt-search {
text-align: right;
}

Expand All @@ -66,12 +68,12 @@

/* center datatable search on mobile */
@media (max-width: 640px) {
[data-behavior="vue"] div.dataTables_wrapper div.dataTables_filter label {
[data-behavior="vue"] .dt-container .dt-search label {
display: block;
width: 100%;
}

[data-behavior="vue"] div.dataTables_wrapper div.dataTables_filter input {
[data-behavior="vue"] .dt-container .dt-search input {
margin: 0;
width: 100%;
}
Expand Down
58 changes: 30 additions & 28 deletions app/javascript/components/DataTables/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import "datatables.net-select";
import "datatables.net-buttons";
import "datatables.net-bs4";
import debounce from "lodash/debounce";
import "datatables.net-bs4/css/dataTables.bootstrap4.min.css";

DataTable.use(DataTablesLib);

Expand All @@ -85,8 +86,8 @@ const emit = defineEmits<{
}>();

const table = ref<typeof DataTable | null>(null);
const dt = ref<DataTableApi<object> | null>(null);
const selectAllCheckbox = ref<HTMLInputElement | null>(null);
let dt: DataTableApi<object> | null = null;

function setAllCheckboxes(checked: boolean) {
const checkboxes = document.querySelectorAll(".select-checkbox");
Expand All @@ -96,37 +97,33 @@ function setAllCheckboxes(checked: boolean) {
}

function selectAllRows() {
if (!dt.value) throw new Error("No datatable api found");
dt.value
.rows({
page: "current",
})
.select();
if (!dt) throw new Error("No datatable api found");
dt.rows({
page: "current",
}).select();

setAllCheckboxes(true);
}

function deselectAllRows() {
if (!dt.value) throw new Error("No datatable api found");
dt.value
.rows({
page: "current",
})
.deselect();
if (!dt) throw new Error("No datatable api found");
dt.rows({
page: "current",
}).deselect();

setAllCheckboxes(false);
}

function handleSelectAllClick(e: MouseEvent) {
if (!dt.value) throw new Error("No datatable api found");
if (!dt) throw new Error("No datatable api found");
const checked = (e.target as HTMLInputElement).checked;
checked ? selectAllRows() : deselectAllRows();
}

function setSelectAllCheckboxState() {
if (!dt.value) throw new Error("No datatable api found");
const selectedRows = dt.value.rows({ selected: true } as any);
const allRows = dt.value.rows();
if (!dt) throw new Error("No datatable api found");
const selectedRows = dt.rows({ selected: true } as any);
const allRows = dt.rows();
const isAllSelected = selectedRows.count() === allRows.count();

selectAllCheckbox.value!.checked = isAllSelected;
Expand All @@ -141,33 +138,33 @@ function emitSelectedRows(e: Event, dt: DataTableApi<any>) {
}

function handleFilterInput(e: Event, colIndex: number) {
if (!dt.value) throw new Error("No datatable api found");
if (!dt) throw new Error("No datatable api found");
const input = e.target as HTMLInputElement;
console.log("filteringInput", input.value);
dt.value.column(colIndex).search(input.value).draw();
dt.column(colIndex).search(input.value).draw();
}

const debouncedFilterInput = debounce(handleFilterInput, 250);

onMounted(() => {
if (!table.value) throw new Error("No dataTableRef found");
dt.value = table.value.dt() as DataTableApi<object>;
dt = table.value.dt as DataTableApi<object>;

selectAllCheckbox.value?.addEventListener("click", handleSelectAllClick);
dt.value.on("select", setSelectAllCheckboxState);
dt.value.on("deselect", setSelectAllCheckboxState);
dt.on("select", setSelectAllCheckboxState);
dt.on("deselect", setSelectAllCheckboxState);

dt.value.on("select", emitSelectedRows);
dt.value.on("deselect", emitSelectedRows);
dt.on("select", emitSelectedRows);
dt.on("deselect", emitSelectedRows);

emit("mounted", dt.value);
emit("mounted", dt);
});

// passes both the event and the datatable instance's
// api to the listener
function handleDataTableClick(event: MouseEvent) {
if (!dt.value) throw new Error("No datatable api found");
emit("click", event, dt.value);
if (!dt) throw new Error("No datatable api found");
emit("click", event, dt);
}

const defaultOptions: DataTableOptions = {
Expand Down Expand Up @@ -203,7 +200,7 @@ const mergedCols = props.selectable
: props.columns;
</script>
<style>
div.dataTables_wrapper div.dataTables_processing {
.dt-container .dt-processing {
position: absolute;
margin: 0;
width: 100%;
Expand All @@ -215,4 +212,9 @@ div.dataTables_wrapper div.dataTables_processing {
align-items: center;
justify-content: center;
}

/* prevent cells with long urls from overflowing */
.dt-container tbody td {
overflow-wrap: break-word;
}
</style>
12 changes: 5 additions & 7 deletions cypress/e2e/adminGroups.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ describe("admin groups index page", () => {
const collectionNamesDesc = [...collectionNamesAsc].reverse();

// check that it begins in acending order
cy.get("[data-cy='groups-table'] tbody > tr td:first-child").each(
cy.get("[data-cy='groups-table'] tbody > tr:first-child .sorting_1").each(
($el, index) => {
const expectedCollectionName = collectionNamesAsc[index];
cy.wrap($el).should("contain", expectedCollectionName);
Expand Down Expand Up @@ -191,13 +191,11 @@ describe("admin groups index page", () => {
});

it("searches collections by name", () => {
cy.get("[data-cy='groups-table']").within(() => {
cy.contains("Search").type("collection2");
cy.get("#dt-search-0").type("collection2");

cy.get("tbody > tr")
.should("have.length", 1)
.should("contain", "collection2");
});
cy.get("tbody > tr")
.should("have.length", 1)
.should("contain", "collection2");
});
});
});
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"@headlessui/vue": "^1.7.23",
"@umn-latis/cla-vue-template": "^1.2.1",
"axios": "^1.7.9",
"datatables.net": "^1.13.2",
"datatables.net-bs4": "^1.13.3",
"datatables.net-buttons": "^2.3.5",
"datatables.net-select": "^1.6.1",
"datatables.net-vue3": "^2.0.0",
"datatables.net": "^2.1.8",
"datatables.net-bs4": "^2.1.8",
"datatables.net-buttons": "^3.2.0",
"datatables.net-select": "^2.1.0",
"datatables.net-vue3": "^3.0.2",
"dayjs": "^1.11.13",
"deepmerge-ts": "^7.1.3",
"p-debounce": "^4.0.0",
Expand Down
51 changes: 24 additions & 27 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1832,42 +1832,39 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"

datatables.net-bs4@^1.13.3:
version "1.13.3"
resolved "https://registry.yarnpkg.com/datatables.net-bs4/-/datatables.net-bs4-1.13.3.tgz#888f002b343c1e0f9874aa697485bd7abfc702a8"
integrity sha512-LtySVYRv8I8FE4+Y8t3IQZYoIQOoKygWvhcUX0qZtdqaEr55MnUTcHzeXVUVNEiycsG62lrCPf/Uurl7Rw6kKA==
datatables.net-bs4@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/datatables.net-bs4/-/datatables.net-bs4-2.1.8.tgz#bf90a2729bfdff18ac71526f5b9171c43070adcd"
integrity sha512-2mFfyD6KdeFaq5qlOWggcjLPblZTuoOFv1fHN3WzquYNiWe8BuSEEARvl7OQ+53/sEY3HOkHsbZ5+Pat0faG9Q==
dependencies:
datatables.net ">=1.12.1"
datatables.net "2.1.8"
jquery ">=1.7"

datatables.net-buttons@^2.3.5:
version "2.3.5"
resolved "https://registry.yarnpkg.com/datatables.net-buttons/-/datatables.net-buttons-2.3.5.tgz#70bbcdf529035b735da3be58da6cee0829a7cd26"
integrity sha512-iY4BC10zNWuyzgdiPQ4b8n9Cz74oEk4OzO8FTDeg0yytmsZVT/JncIS2mBt08JW4DLWaB6a0+6UPd+0UHwvIUA==
datatables.net-buttons@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/datatables.net-buttons/-/datatables.net-buttons-3.2.0.tgz#591238e488ed18d1c8830b2e3cbb649ab3773790"
integrity sha512-u51/KUvxMJz7ZsmhEUMU3nAh++wU0IYtU/U9TaH5rZR3zVHj+OBepApLIMz/uLjcXpNeIb7kjcKKNkVtxk9kbw==
dependencies:
datatables.net ">=1.12.1"
datatables.net "^2"
jquery ">=1.7"

datatables.net-select@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/datatables.net-select/-/datatables.net-select-1.6.1.tgz#dc322112802cb36007e5f6429cdbd586a368e558"
integrity sha512-0Ghr0fPFwUYFVcQRU7njnms0e12iIkhuC8cv6nDjsoby2w/JK+xgBlmW+7fEcqF8pxwZzFZb8bHdK9f4p4s9ag==
datatables.net-select@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/datatables.net-select/-/datatables.net-select-2.1.0.tgz#d50f13cd4c18d50c06b24efd8ca5371ed0bbe59d"
integrity sha512-6B1sI5pfvBen+8kySl1T0hkGoUmrw+5YGqaW4NCg+1srMw+48YV5SdWPiyCQDoev2ajBdKzHuG/wzD2INMbmJw==
dependencies:
datatables.net ">=1.12.1"
datatables.net "^2"
jquery ">=1.7"

datatables.net-vue3@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/datatables.net-vue3/-/datatables.net-vue3-2.0.0.tgz#01b20c68201f49f57920dea62a5f742b7119880b"
integrity sha512-auwLfwqebGZ0gFnU8C/HWQYpkVtU64x8T+gYs5i7/Jqyo3YNTDU2M/lWwp7rJ+VSlolkDICrKpfmmo/Rz6ZBFw==
dependencies:
datatables.net "^1.13.1"
jquery "^3.6.0"
datatables.net-vue3@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/datatables.net-vue3/-/datatables.net-vue3-3.0.2.tgz#7da2cd2b980bab8607fe6529f3fa176ff69ec178"
integrity sha512-UJs3IrKS+gsaPSy3CeL5ny/hGWm8xs77DZLYSW8QXPpDhMS7ZZfC4AGKNvXa2C9J1OllWhiR20dScpi0lKdCvQ==

datatables.net@>=1.12.1, datatables.net@^1.13.1, datatables.net@^1.13.2:
version "1.13.2"
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-1.13.2.tgz#48f7035b1696a29cb70909db1f2e0ebd5f946f3e"
integrity sha512-u5nOU+C9SBp1SyPmd6G+niozZtrBwo1E8xzdOk3JJaAkFYgX/KxF3Gd79R8YLbUfmIs2OLnLe5gaz/qs5U8UDA==
datatables.net@2.1.8, datatables.net@^2, datatables.net@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/datatables.net/-/datatables.net-2.1.8.tgz#9b020f18e927cc924d72411f62dc595cc688669b"
integrity sha512-47ULt+U4bcjbuGTpTlT6SnCuSFVRBxxdWa6X3NfvTObBJ2BZU0o+JUIl05wQ6cABNIavjbAV51gpgvFsMHL9zA==
dependencies:
jquery ">=1.7"

Expand Down Expand Up @@ -2781,7 +2778,7 @@ jiti@^1.21.6:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9"
integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==

jquery@>=1.7, jquery@^3.6.0:
jquery@>=1.7:
version "3.6.3"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.3.tgz#23ed2ffed8a19e048814f13391a19afcdba160e6"
integrity sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg==
Expand Down
Loading