Skip to content

Commit

Permalink
Merge pull request #1540 from ProcessMaker/feature/FOUR-13447_B
Browse files Browse the repository at this point in the history
FOUR-13447: Page Dropdown
  • Loading branch information
caleeli authored Feb 21, 2024
2 parents 20a51df + b88948e commit dfc2e69
Show file tree
Hide file tree
Showing 9 changed files with 448 additions and 20 deletions.
1 change: 1 addition & 0 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,7 @@ export default {
<style lang="scss">
@import "bootstrap/dist/css/bootstrap";
@import "bootstrap-vue/dist/bootstrap-vue";
@import "assets/css/custom";
$validation-panel-bottom: 3.5rem;
$validation-panel-right: 0;
Expand Down
4 changes: 4 additions & 0 deletions src/assets/css/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.btn-platform {
background-color: #ffff;
color: #6a7888;
}
2 changes: 1 addition & 1 deletion src/bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import "bootstrap-vue/dist/bootstrap-vue.css";
import "@fortawesome/fontawesome-free/css/all.min.css";
import "@processmaker/vue-form-elements/dist/vue-form-elements.css";
import "@processmaker/vue-multiselect/dist/vue-multiselect.min.css";

import "@/assets/css/custom.css";
// For QA: Set default testIdAttribute to "data-test"
configure({ testIdAttribute: "data-test" });

Expand Down
26 changes: 13 additions & 13 deletions src/components/TabsBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@
@input="tabOpened"
>
<template #tabs-start>
<div class="tabs-sticky d-flex flex-row tabs-start">
<div>
<slot name="tabs-start" />
</div>
<div
v-show="tabsListOverflow && showLeftScroll"
class="position-relative overflow-visible"
>
<div>
<slot name="tabs-start" />
<div class="tabs-sticky d-flex flex-row tabs-start">
<div
role="link"
class="nav-scroll nav-scroll-left"
data-test="scroll-left"
@click="scrollTabsLeft"
v-show="tabsListOverflow && showLeftScroll"
class="position-relative overflow-visible"
>
<i class="fas fa-chevron-left" />
<div
role="link"
class="nav-scroll nav-scroll-left"
data-test="scroll-left"
@click="scrollTabsLeft"
>
<i class="fas fa-chevron-left" />
</div>
</div>
</div>
</div>
Expand Down
118 changes: 118 additions & 0 deletions src/components/editor/pagesDropdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<template>
<!--
Dropdown component to display options related to pages.
Provides options to add a new page, see all pages, and select individual pages.
-->
<b-dropdown data-test="page-dropdown" variant="platform" :boundary="boundary">
<!-- Dropdown button content -->
<template #button-content>
<!-- Icon representing a file -->
<i class="fa fa-file"></i>
</template>

<!-- Option to add a new page -->
<b-dropdown-item data-test="add-page" @click="onAddPage">
<!-- Icon for adding a new page -->
<i class="fa fa-plus platform-dropdown-item-icon"></i>
<!-- Text for adding a new page -->
{{ $t("Create Page") }}
</b-dropdown-item>

<!-- Option to see all pages -->
<b-dropdown-item data-test="see-all-pages" @click="onSeeAllPages">
<!-- Icon for seeing all pages -->
<i class="fa fa-eye platform-dropdown-item-icon"></i>
<!-- Text for seeing all pages -->
{{ $t("See all pages") }}
</b-dropdown-item>

<!-- Divider between adding and viewing options -->
<b-dropdown-divider></b-dropdown-divider>

<!-- Dropdown items for selecting individual pages -->
<b-dropdown-item
v-for="(item, page) in data"
:key="page"
:data-test="'page-' + item.name"
@click="onClickPage(page)"
>
<!-- Display the name of the page -->
{{ item.name }}
</b-dropdown-item>
</b-dropdown>
</template>

<script>
/**
* Vue component for managing pages through a dropdown menu.
* @component
* @prop {Props} props - The component's props object.
*/
export default {
/**
* The name of the component.
* @type {string}
*/
name: "PagesDropdown",
/**
* The props that the component accepts.
* @type {Object}
* @property {PageItem[]} data - The array of page items to be displayed in the dropdown.
* Defaults to null.
*/
props: {
data: {
type: Array,
default: null
},
boundary: {
type: String,
default: "viewport"
}
},
/**
* The methods available within the component.
*/
methods: {
/**
* Handler for when the "Add Page" option is clicked.
* Emits the "addPage" event.
*/
onAddPage() {
this.$emit("addPage");
},
/**
* Handler for when the "See All Pages" option is clicked.
* Emits the "seeAllPages" event.
*/
onSeeAllPages() {
this.$emit("seeAllPages");
},
/**
* Handler for when a specific page is clicked.
* Emits the "clickPage" event with the selected page.
* @param {PageItem} page - The selected page item.
*/
onClickPage(page) {
this.$emit("clickPage", page);
}
}
};
</script>

<style lang="scss" scoped>
// Platform btn style
.btn-platform {
background-color: #ffff;
color: #6a7888;
}
.platform-dropdown-item-icon {
// Style for the icons in dropdown items.
color: #1572c2;
}
</style>
28 changes: 22 additions & 6 deletions src/components/vue-form-builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<!-- Renderer -->
<b-col
id="screen-container"
ref="screen-container"
class="overflow-auto mh-100 p-0 d-flex flex-column position-relative"
>
<b-input-group size="sm" class="bg-white p-2">
Expand Down Expand Up @@ -158,16 +159,19 @@
}}</b-button>
</b-button-group>
</b-input-group>

<tabs-bar
ref="tabsBar"
:pages="config"
@tab-opened="currentPage = $event"
>
<template #tabs-start>
<b-form-select
:options="config.map((v, k) => k)"
data-test="open-page"
@change="$refs.tabsBar.openPageByIndex($event)"
<pages-dropdown
v-if="showToolbar"
:data="config"
@addPage="$bvModal.show('addPageModal')"
@clickPage="onClick"
@seeAllPages="onSeeAllPages"
/>
</template>
<template #default>
Expand Down Expand Up @@ -410,6 +414,7 @@
<!-- Modals -->
<b-modal
id="addPageModal"
ref="addPageModal"
:ok-title="$t('Save')"
:cancel-title="$t('Cancel')"
cancel-variant="btn btn-outline-secondary"
Expand Down Expand Up @@ -497,6 +502,7 @@ import "@processmaker/vue-form-elements/dist/vue-form-elements.css";
import accordions from "./accordions";
import { keyNameProperty } from "../form-control-common-properties";
import VariableNameGenerator from "@/components/VariableNameGenerator";
import PagesDropdown from "@/components/editor/pagesDropdown";
import testing from "@/mixins/testing";
import defaultValueEditor from "./inspector/default-value-editor";
import RequiredCheckbox from "./utils/required-checkbox";
Expand Down Expand Up @@ -567,7 +573,8 @@ export default {
MultipleUploadsCheckbox,
defaultValueEditor,
...inspector,
...renderer
...renderer,
PagesDropdown
},
mixins: [HasColorProperty, testing],
props: {
Expand Down Expand Up @@ -784,11 +791,20 @@ export default {
this.setGroupOrder(defaultGroupOrder);
},
methods: {
onSeeAllPages() {
// TODO open the all pages modal
console.log("onSeeAllPages");
},
onClick(page) {
this.currentPage = page;
this.$refs.tabsBar.openPageByIndex(page);
},
checkPageName(value) {
const pageNames = this.config
.map((config) => config.name)
.filter((name) => name !== this.originalPageName);
return pageNames.includes(value) ? this.$t("Must be unique.") : "";

},
getGroupOrder(groupName) {
let order = _.get(this.groupOrder, groupName, Number.POSITIVE_INFINITY);
Expand Down Expand Up @@ -1303,7 +1319,7 @@ export default {
};
</script>

<style scoped>
<style>
.custom-popover {
margin-right: -400px;
padding: 16px;
Expand Down
112 changes: 112 additions & 0 deletions src/stories/DropdownAndPages.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* eslint-disable import/no-extraneous-dependencies */
import { within, userEvent, expect, waitFor } from "@storybook/test";
import "../bootstrap";
// b-tabs from bootstrap-vue
import TabsBar from "../components/TabsBar.vue";
import PagesDropdown from "../components/editor/pagesDropdown.vue";

export default {
title: "Components/DropdownAndPages",
component: [TabsBar, PagesDropdown],
tags: ["autodocs"],
render: (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { TabsBar, PagesDropdown },
template: `
<tabs-bar ref="tabsBar" v-bind="$props">
<template v-slot:tabs-start>
<pages-dropdown
:data="pages"
@addPage="onAddPage"
@clickPage="onClick"
@seeAllPages="onSeeAllPages"
/>
</template>
<template v-slot="{ currentPage }">
Here comes content of {{pages[currentPage].name}} (#{{currentPage}})
</template>
</tabs-bar>
`,
data() {
return {};
},
methods: {
onAddPage() {
console.log("Add page clicked");
},
onSeeAllPages() {
console.log("See all pages clicked");
},
onClick(index) {
this.$refs.tabsBar.openPageByIndex(index);
}
}
})
};

/**
* Stories of the component
*/
// Preview the component
export const Preview = {
args: {
pages: [
{ name: "Page 1" },
{ name: "Page 2" },
{ name: "Page 3" },
{ name: "Page 4" },
{ name: "Page 5" }
],
initialOpenedPages: [0]
}
};

// Open a page using the PageDropdown(index)
export const OpenPageUsingDropdown = {
args: {
pages: [
{ name: "Page1" },
{ name: "Page2" },
{ name: "Page3" },
{ name: "Page4" },
{ name: "Page5" }
],
initialOpenedPages: [0]
},
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const selector = canvasElement.querySelector(
"[data-test=page-dropdown] button"
);
let selectorAddPage = canvasElement.querySelector("[data-test=page-Page3]");
console.log(selectorAddPage);
await selector.click(selector);
await selectorAddPage.click(selectorAddPage);
// Open Page 3 (index=2)
await step("Open Page 3 (index=2)", async () => {
await waitFor(
() => {
expect(canvas.getByTestId("tab-content")).toContainHTML(
"Here comes content of Page3 (#2)"
);
},
{ timeout: 1000 }
);
});

// Open Page 2 (index=1)
await selector.click(selector);
selectorAddPage = canvasElement.querySelector("[data-test=page-Page2]");
await selectorAddPage.click(selectorAddPage);
await step("Open Page 2 (index=1)", async () => {
await waitFor(
() => {
expect(canvas.getByTestId("tab-content")).toContainHTML(
"Here comes content of Page2 (#1)"
);
},
{ timeout: 1000 }
);
});
}
};
Loading

0 comments on commit dfc2e69

Please sign in to comment.