diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 9f67f3322488..fb72e3853e64 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -62,7 +62,7 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} run: | case "$TARGET_BRANCH" in - release_[[:digit:]][[:digit:]].[[:digit:]][[:digit:]]|master) + release_[[:digit:]][[:digit:]].[[:digit:]][[:digit:]] | release_[[:digit:]][[:digit:]].[[:digit:]] | master) UPLOAD_DIR=$TARGET_BRANCH ;; dev) diff --git a/client/src/components/Form/Elements/FormData/FormData.test.js b/client/src/components/Form/Elements/FormData/FormData.test.js index 9b97ed3296ab..578bf4f8b321 100644 --- a/client/src/components/Form/Elements/FormData/FormData.test.js +++ b/client/src/components/Form/Elements/FormData/FormData.test.js @@ -186,6 +186,61 @@ describe("FormData", () => { expect(wrapper.emitted().input[1][0]).toEqual(value_sorted); }); + it("sorts mixed dces and hdas", async () => { + const sortOptions = { + hda: [ + { id: "hda1", hid: 1, name: "hdaName1", src: "hda", tags: ["tag1"] }, + { id: "hda2", hid: 2, name: "hdaName2", src: "hda", tags: ["tag1", "tag2"] }, + { id: "hda3", hid: 3, name: "hdaName3", src: "hda", tags: ["tag2", "tag3"] }, + { id: "hda4", hid: 4, name: "hdaName4", src: "hda" }, + ], + dce: [ + { id: "dce1", name: "dceName1", src: "dce", is_dataset: true }, + { id: "dce2", name: "dceName2", src: "dce", is_dataset: true }, + { id: "dce3", name: "dceName3", src: "dce", is_dataset: true }, + { id: "dce4", name: "dceName4", src: "dce", is_dataset: true }, + ], + }; + const wrapper = createTarget({ + //intermix hdas and dces in the selected options + value: { + values: [ + { id: "hda1", src: "hda" }, + { id: "dce4", src: "dce" }, + { id: "dce2", src: "dce" }, + { id: "hda2", src: "hda" }, + { id: "dce3", src: "dce" }, + ], + }, + multiple: true, + optional: true, + options: sortOptions, + }); + const selectedValues = wrapper.findAll(SELECTED_VALUE); + expect(selectedValues.length).toBe(5); + // when dces are mixed in their values are shown first and are + // ordered by id descending + expect(selectedValues.at(0).text()).toBe("dceName4 (as dataset)"); + expect(selectedValues.at(1).text()).toBe("dceName3 (as dataset)"); + expect(selectedValues.at(2).text()).toBe("dceName2 (as dataset)"); + expect(selectedValues.at(3).text()).toBe("2: hdaName2"); + expect(selectedValues.at(4).text()).toBe("1: hdaName1"); + await selectedValues.at(0).trigger("click"); + const value_sorted = { + batch: false, + product: false, + values: [ + // when dces are mixed in, they are emitted first + // and are sorted by id descending + { id: "dce3", map_over_type: null, src: "dce" }, + { id: "dce2", map_over_type: null, src: "dce" }, + { id: "hda1", map_over_type: null, src: "hda" }, + { id: "hda2", map_over_type: null, src: "hda" }, + ], + }; + expect(wrapper.emitted().input[1][0]).toEqual(value_sorted); + }); + it("dataset collection as hda", async () => { const wrapper = createTarget({ value: { values: [{ id: "dce1", src: "dce" }] }, diff --git a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.test.js b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.test.js index 7cb65453957c..a0ace176ad53 100644 --- a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.test.js +++ b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.test.js @@ -84,20 +84,33 @@ describe("History Selection Operations", () => { expect(wrapper.find(option).exists()).toBe(false); }); - it("should display 'unhide' option only on hidden items", async () => { + it("should display 'unhide' option on hidden items", async () => { const option = '[data-description="unhide option"]'; expect(wrapper.find(option).exists()).toBe(false); await wrapper.setProps({ filterText: "visible:false" }); expect(wrapper.find(option).exists()).toBe(true); }); - it("should display 'delete' option only on non-deleted items", async () => { + it("should display 'unhide' option when hidden and visible items are mixed", async () => { + const option = '[data-description="unhide option"]'; + expect(wrapper.find(option).exists()).toBe(false); + await wrapper.setProps({ filterText: "visible:any" }); + expect(wrapper.find(option).exists()).toBe(true); + }); + + it("should display 'delete' option on non-deleted items", async () => { const option = '[data-description="delete option"]'; expect(wrapper.find(option).exists()).toBe(true); await wrapper.setProps({ filterText: "deleted:true" }); expect(wrapper.find(option).exists()).toBe(false); }); + it("should display 'delete' option when non-deleted and deleted items are mixed", async () => { + const option = '[data-description="delete option"]'; + await wrapper.setProps({ filterText: "deleted:any" }); + expect(wrapper.find(option).exists()).toBe(true); + }); + it("should display 'permanently delete' option always", async () => { const option = '[data-description="purge option"]'; expect(wrapper.find(option).exists()).toBe(true); @@ -105,7 +118,7 @@ describe("History Selection Operations", () => { expect(wrapper.find(option).exists()).toBe(true); }); - it("should display 'undelete' option only on deleted and non-purged items", async () => { + it("should display 'undelete' option on deleted and non-purged items", async () => { const option = '[data-description="undelete option"]'; expect(wrapper.find(option).exists()).toBe(false); await wrapper.setProps({ @@ -115,6 +128,15 @@ describe("History Selection Operations", () => { expect(wrapper.find(option).exists()).toBe(true); }); + it("should display 'undelete' option when non-purged items (deleted or not) are mixed", async () => { + const option = '[data-description="undelete option"]'; + await wrapper.setProps({ + filterText: "deleted:any", + contentSelection: getNonPurgedContentSelection(), + }); + expect(wrapper.find(option).exists()).toBe(true); + }); + it("should not display 'undelete' when is manual selection mode and all selected items are purged", async () => { const option = '[data-description="undelete option"]'; await wrapper.setProps({ @@ -136,6 +158,17 @@ describe("History Selection Operations", () => { expect(wrapper.find(option).exists()).toBe(true); }); + it("should display 'undelete' option when is query selection mode and filtering by any deleted state", async () => { + const option = '[data-description="undelete option"]'; + // In query selection mode we don't know if some items may not be purged, so we allow to undelete + await wrapper.setProps({ + filterText: "deleted:any", + contentSelection: getPurgedContentSelection(), + isQuerySelection: true, + }); + expect(wrapper.find(option).exists()).toBe(true); + }); + it("should display collection building options only on visible and non-deleted items", async () => { const buildListOption = '[data-description="build list"]'; const buildPairOption = '[data-description="build pair"]'; @@ -151,6 +184,14 @@ describe("History Selection Operations", () => { expect(wrapper.find(buildListOption).exists()).toBe(false); expect(wrapper.find(buildPairOption).exists()).toBe(false); expect(wrapper.find(buildListOfPairsOption).exists()).toBe(false); + await wrapper.setProps({ filterText: "visible:any" }); + expect(wrapper.find(buildListOption).exists()).toBe(false); + expect(wrapper.find(buildPairOption).exists()).toBe(false); + expect(wrapper.find(buildListOfPairsOption).exists()).toBe(false); + await wrapper.setProps({ filterText: "deleted:any" }); + expect(wrapper.find(buildListOption).exists()).toBe(false); + expect(wrapper.find(buildPairOption).exists()).toBe(false); + expect(wrapper.find(buildListOfPairsOption).exists()).toBe(false); }); it("should display list building option when all are selected", async () => { diff --git a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue index 9b70de885019..ed42dd945bbd 100644 --- a/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue +++ b/client/src/components/History/CurrentHistory/HistoryOperations/SelectionOperations.vue @@ -24,7 +24,10 @@ data-description="undelete option"> Undelete - + Delete @@ -191,10 +194,14 @@ export default { computed: { /** @returns {Boolean} */ showHidden() { - return HistoryFilters.checkFilter(this.filterText, "visible", false); + return !HistoryFilters.checkFilter(this.filterText, "visible", true); }, /** @returns {Boolean} */ showDeleted() { + return !HistoryFilters.checkFilter(this.filterText, "deleted", false); + }, + /** @returns {Boolean} */ + showStrictDeleted() { return HistoryFilters.checkFilter(this.filterText, "deleted", true); }, /** @returns {Boolean} */ diff --git a/client/src/components/Markdown/MarkdownSelector.vue b/client/src/components/Markdown/MarkdownSelector.vue index fc032f15b411..0ff5e0b296b6 100644 --- a/client/src/components/Markdown/MarkdownSelector.vue +++ b/client/src/components/Markdown/MarkdownSelector.vue @@ -1,6 +1,12 @@