Unverified Commit 889d6130 authored by Björn Grüning's avatar Björn Grüning Committed by GitHub
Browse files

Merge pull request #14183 from davelopez/22.05_fix_switch_history_pagination

[22.05] Switch History Modal: fix pagination
parents 09c8a0b1 a469e32e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -130,7 +130,7 @@
        <SelectorModal
            id="selector-history-modal"
            :histories="histories"
            :current-history="history"
            :current-history-id="history.id"
            @selectHistory="$emit('setCurrentHistory', $event)" />

        <CopyModal id="copy-history-modal" :history="history" />
+65 −0
Original line number Diff line number Diff line
import { mount } from "@vue/test-utils";
import flushPromises from "flush-promises";
import { getLocalVue } from "jest/helpers";
import SelectorModal from "./SelectorModal";

const localVue = getLocalVue();

const SELECTED_HISTORY_ID = "COOL_ID";
const getFakeHistorySummaries = (num, selectedIndex = 0) => {
    const result = Array.from({ length: num }, (_, index) => ({
        id: `ID-${index}`,
        name: `History-${index}`,
        tags: [],
        update_time: new Date().toISOString(),
    }));
    result[selectedIndex].id = SELECTED_HISTORY_ID;
    return result;
};
const PROPS_WITH_10_HISTORIES = {
    currentHistoryId: SELECTED_HISTORY_ID,
    histories: getFakeHistorySummaries(10),
    perPage: 3,
    static: true, // Force the modal visible for testing
};

describe("History SelectorModal.vue", () => {
    let wrapper;

    async function mountWith(props) {
        wrapper = mount(SelectorModal, {
            propsData: props,
            localVue,
        });
        await flushPromises();
    }

    it("should highlight the currently selected history", async () => {
        await mountWith(PROPS_WITH_10_HISTORIES);

        const selectedRows = wrapper.findAll(".table-success");
        expect(selectedRows.length).toBe(1);
        expect(selectedRows.at(0).attributes("data-pk")).toBe(SELECTED_HISTORY_ID);
    });

    it("paginates the histories", async () => {
        await mountWith(PROPS_WITH_10_HISTORIES);

        const displayedRows = wrapper.findAll("tbody > tr").wrappers;
        expect(displayedRows.length).toBe(3);
        expect(wrapper.vm.histories.length).toBe(10);
    });

    it("emits selectHistory with the correct history ID when a row is clicked", async () => {
        await mountWith(PROPS_WITH_10_HISTORIES);

        expect(wrapper.emitted()["selectHistory"]).toBeUndefined();

        const targetHistoryId = "ID-2";
        const targetRow = wrapper.find(`[data-pk="${targetHistoryId}"]`);
        await targetRow.trigger("click");

        expect(wrapper.emitted()["selectHistory"]).toBeDefined();
        expect(wrapper.emitted()["selectHistory"][0][0].id).toBe(targetHistoryId);
    });
});
+25 −33
Original line number Diff line number Diff line
<template>
    <b-modal ref="modal" v-bind="$attrs" :title="'Switch to History' | l" v-on="$listeners">
        <b-form-group :description="'Filter histories' | l">
            <b-input v-model="filter" :placeholder="'Search Filter' | l" />
            <b-form-input v-model="filter" type="search" :placeholder="'Search Filter' | l" />
        </b-form-group>

        <b-table
            ref="history-list"
            v-model="currentRows"
            striped
            hover
            sticky-header="50vh"
            primary-key="id"
            :fields="fields"
            :filter="filter"
            :items="histories"
            :items="formattedItems"
            :per-page="perPage"
            :current-page="currentPage"
            :selectable="true"
            select-mode="single"
            selected-variant="success"
            @row-selected="switchToHistory">
            @row-selected="switchToHistory"
            @filtered="onFiltered">
            <template v-slot:cell(tags)="row">
                <stateless-tags :value="row.item.tags" :disabled="true" />
            </template>
@@ -29,23 +28,28 @@
        </b-table>

        <template v-slot:modal-footer>
            <b-pagination v-model="currentPage" :total-rows="filteredRowCount" :per-page="perPage"></b-pagination>
            <b-pagination v-model="currentPage" :total-rows="totalRows" :per-page="perPage" />
        </template>
    </b-modal>
</template>

<script>
import { BModal, BFormGroup, BFormInput, BTable, BPagination } from "bootstrap-vue";
import { StatelessTags } from "components/Tags";
import UtcDate from "components/UtcDate";
import { debounce } from "underscore";

export default {
    components: {
        StatelessTags,
        UtcDate,
        BModal,
        BFormGroup,
        BFormInput,
        BTable,
        BPagination,
    },
    props: {
        currentHistory: { type: Object, required: true },
        currentHistoryId: { type: String, required: true },
        histories: { type: Array, default: () => [] },
        perPage: { type: Number, required: false, default: 50 },
    },
@@ -53,30 +57,22 @@ export default {
        return {
            filter: null,
            currentPage: 1,
            currentRows: [],
            totalRows: 0,
        };
    },
    computed: {
        filteredRowCount() {
            return this.currentRows.length;
        },
        selectedIndex() {
            return this.currentRows.findIndex((h) => h.id == this.currentHistory.id);
        formattedItems() {
            return this.histories.map((item) => {
                if (item.id == this.currentHistoryId) {
                    item._rowVariant = "success";
                }
                return item;
            });
        },
    },
    watch: {
        currentRows() {
            this.selectCurrentRow();
        },
        filteredRowCount(newVal, oldVal) {
            if (newVal != oldVal) {
                this.currentPage = 1;
            }
        },
        selectedIndex(idx, oldIdx) {
            if (idx != oldIdx) {
                this.debounceSelectCurrentRow();
            }
        histories(newVal) {
            this.totalRows = newVal.length;
        },
    },
    created() {
@@ -85,7 +81,6 @@ export default {
            { key: "tags", sortable: true },
            { key: "update_time", label: "Updated", sortable: true },
        ];
        this.debounceSelectCurrentRow = debounce(this.selectCurrentRow, 100);
    },
    methods: {
        switchToHistory(selected) {
@@ -93,12 +88,9 @@ export default {
                this.$emit("selectHistory", selected[0]);
            }
        },
        selectCurrentRow() {
            const idx = this.selectedIndex;
            const list = this.$refs["history-list"];
            if (list && idx > -1) {
                list.selectRow(idx);
            }
        onFiltered(filteredItems) {
            this.totalRows = filteredItems.length;
            this.currentPage = 1;
        },
    },
};