mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 08:09:27 +00:00
fix(dashboards): PromQL table footer follows the table's page size and pagination (#15877)
Co-authored-by: ktx-vaidehi <134508096+ktx-vaidehi@users.noreply.github.com>
This commit is contained in:
@@ -1113,11 +1113,9 @@ test.describe("Dashboard Table Chart Pagination Feature - PromQL Tables", () =>
|
||||
const queryEditor = pm.chartTypeSelector.queryEditor;
|
||||
await queryEditor.waitFor({ state: "visible", timeout: 10000 });
|
||||
|
||||
// Focus on the editor and enter a PromQL query using keyboard.type for reliable Monaco input
|
||||
// Fill the Monaco input directly; typing lets autocomplete corrupt the query
|
||||
await queryEditor.getByRole('code').click();
|
||||
await page.keyboard.press('Control+a');
|
||||
await page.keyboard.type('cpu_usage{}');
|
||||
await page.keyboard.press('Escape'); // Dismiss any Monaco autocomplete suggestions
|
||||
await queryEditor.locator('.inputarea').fill('cpu_usage{}');
|
||||
|
||||
// Apply
|
||||
await pm.dashboardPanelActions.applyAndWaitForPromQLQuery();
|
||||
@@ -1155,14 +1153,19 @@ test.describe("Dashboard Table Chart Pagination Feature - PromQL Tables", () =>
|
||||
const paginationInfo = pm.dashboardPanelConfigs.tableRowCount;
|
||||
await expect(paginationInfo).toHaveText(/^\s*\d+-\d+\s+of\s+\d+\s*$/, { timeout: 15000 });
|
||||
|
||||
// Only the footer's presence and range shape are checked; the page-size count is wrong today (#15544) and its fix adds the exact assertion.
|
||||
const paginationText = await paginationInfo.textContent();
|
||||
expect(paginationText.trim()).toMatch(/^\d+-\d+\s+of\s+\d+$/);
|
||||
// The page size must bound the range: "1-10 of N" with N > 10, never "1-N of N" (#15544).
|
||||
const paginationText = (await paginationInfo.textContent()).trim();
|
||||
const match = paginationText.match(/^1-(\d+)\s+of\s+(\d+)$/);
|
||||
expect(match, `unexpected footer text "${paginationText}"`).not.toBeNull();
|
||||
expect(Number(match[1])).toBe(10);
|
||||
expect(Number(match[2])).toBeGreaterThanOrEqual(12);
|
||||
|
||||
// Verify we're on the first page (starts with "1-")
|
||||
expect(paginationText.trim().startsWith('1-')).toBe(true);
|
||||
const nextPage = page.locator('[data-test="dashboard-table-pagination-next-page"]');
|
||||
await expect(nextPage).toBeVisible();
|
||||
await nextPage.click();
|
||||
await expect(paginationInfo).toHaveText(new RegExp(`^\\s*11-\\d+\\s+of\\s+${match[2]}\\s*$`));
|
||||
|
||||
testLogger.info(`Verified PromQL table pagination: ${paginationText.trim()}`);
|
||||
testLogger.info(`Verified PromQL table pagination: ${paginationText}`);
|
||||
|
||||
// Clean up - save panel first before navigating back
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
|
||||
@@ -430,6 +430,47 @@ describe("PromQLTableChart", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Legend footer pagination", () => {
|
||||
const twelveRows = Array.from({ length: 12 }, (_, i) => ({
|
||||
__legend__: "series1",
|
||||
timestamp: `2023-01-01T00:${String(i).padStart(2, "0")}:00Z`,
|
||||
value: i,
|
||||
}));
|
||||
|
||||
const mountPaginated = () =>
|
||||
createWrapper({
|
||||
data: { columns: mockTableData.columns, rows: twelveRows },
|
||||
config: { ...mockConfig, table_pagination: true, table_pagination_rows_per_page: 10 },
|
||||
});
|
||||
|
||||
it("shows the page range, page size and navigation from the table's pagination state", async () => {
|
||||
wrapper = mountPaginated();
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.find('[data-test="dashboard-table-row-count"]').text()).toBe("1-10 of 12");
|
||||
expect(wrapper.find('[data-test="dashboard-table-pagination-next-page"]').exists()).toBe(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find('[data-test="dashboard-table-pagination-last-page"]').exists()).toBe(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find('[data-test="dashboard-table-rows-per-page-select"]').text()).toContain(
|
||||
"10",
|
||||
);
|
||||
});
|
||||
|
||||
it("reaches the remaining rows on the next page", async () => {
|
||||
wrapper = mountPaginated();
|
||||
await flushPromises();
|
||||
|
||||
await wrapper.find('[data-test="dashboard-table-pagination-next-page"]').trigger("click");
|
||||
await flushPromises();
|
||||
|
||||
expect(wrapper.find('[data-test="dashboard-table-row-count"]').text()).toBe("11-12 of 12");
|
||||
expect(wrapper.findAll('tbody tr[data-test^="o2-table-row-"]').length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Event Handling", () => {
|
||||
it("should emit row-click when TableRenderer emits row-click", async () => {
|
||||
wrapper = createWrapper();
|
||||
|
||||
@@ -65,13 +65,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
<div class="flex-1" />
|
||||
<TablePaginationControls
|
||||
:show-pagination="panelConfig.table_pagination && !store.state.printMode"
|
||||
:pagination="scope.pagination"
|
||||
:pagination-options="scope.paginationOptions"
|
||||
:pagination="{ page: scope.currentPage, rowsPerPage: scope.pageSize }"
|
||||
:total-rows="scope.totalRows"
|
||||
:pages-number="scope.pagesNumber"
|
||||
:pages-number="scope.totalPages"
|
||||
:is-first-page="scope.isFirstPage"
|
||||
:is-last-page="scope.isLastPage"
|
||||
@update:rows-per-page="scope.setRowsPerPage"
|
||||
@update:rows-per-page="scope.setPageSize"
|
||||
@first-page="scope.firstPage"
|
||||
@prev-page="scope.prevPage"
|
||||
@next-page="scope.nextPage"
|
||||
@@ -217,10 +216,6 @@ export default defineComponent({
|
||||
return filtered;
|
||||
});
|
||||
|
||||
// Note: paginationOptions is now provided by TableRenderer's slot
|
||||
// and accessible via scope.paginationOptions in the template
|
||||
// This avoids code duplication
|
||||
|
||||
const pagination = ref({
|
||||
rowsPerPage: 0, // 0 = show all rows (like SQL table)
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user