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

FOUR-13450 Reindex page index when deleted #1542

Merged
merged 10 commits into from
Feb 22, 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
6 changes: 3 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
<b-container id="screen-builder-container" class="h-100">
<b-card id="app" no-body class="h-100 bg-white border-top-0 ">
<!-- Card Header -->
<b-card-header class="bg-white">
<b-card-header class="bg-white p-0">
<b-row>
<b-col>
<b-button-group size="sm pr-2">
<b-col class="d-flex align-items-center">
<b-button-group size="sm px-2">
<b-button
:variant="displayBuilder ? 'secondary' : 'outline-secondary'"
data-cy="mode-editor"
Expand Down
35 changes: 30 additions & 5 deletions src/components/TabsBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
{{ pageNumber(index) }}
</b-badge>
<span :data-test="`tab-${n}`">
{{ pages[index].name }}
{{ pages[index]?.name }}
</span>
<span
v-if="localOpenedPages.length > 1"
Expand All @@ -50,9 +50,11 @@
<i class="fas fa-times" />
</span>
</template>
<div class="h-100 w-100" data-test="tab-content">
<slot :current-page="index" />
</div>
<template #default>
<div class="h-100 w-100" data-test="tab-content">
<slot :current-page="index" />
</div>
</template>
</b-tab>
<template #tabs-end>
<div
Expand All @@ -69,6 +71,13 @@
</div>
</div>
</template>
<template #empty>
<p class="text-center m-5 text-secondary" data-test="tab-content">
{{ $t("There are no open pages.") }}<br />
{{ $t("Open a new page above using the button") }}
<i :class="buttonIcon" />
</p>
</template>
</b-tabs>
</template>

Expand All @@ -90,6 +99,13 @@ export default {
initialOpenedPages: {
type: Array,
default: () => [0]
},
/**
* Icon to open a new tab, displayed when there are no pages opened.
*/
buttonIcon: {
type: String,
default: () => "fa fa-file"
}
},
data() {
Expand Down Expand Up @@ -167,8 +183,11 @@ export default {
this.localOpenedPages.splice(this.localOpenedPages.indexOf(pageId), 1);
this.$emit("tab-closed", this.pages[pageId], this.localOpenedPages);
},
updateTabsReferences(pageDelete) {
this.localOpenedPages = this.localOpenedPages.map((page) => page > pageDelete ? page - 1 : page);
},
async openPageByIndex(index) {
const n = this.localOpenedPages.indexOf(index);
const n = this.localOpenedPages.indexOf(index * 1);
if (n === -1) {
this.localOpenedPages.push(index);
await this.waitUpdates(this.updates + 2, 1000);
Expand All @@ -177,6 +196,12 @@ export default {
this.activeTab = n;
}
},
closePageByIndex(index) {
const n = this.localOpenedPages.indexOf(index);
if (n !== -1) {
this.localOpenedPages.splice(n, 1);
}
},
checkTabsOverflow() {
const tablist = this.$refs.tabs.$el.querySelector(".nav-tabs");
this.tabsListOverflow = tablist.scrollWidth > tablist.clientWidth;
Expand Down
123 changes: 65 additions & 58 deletions src/components/vue-form-builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,56 +101,6 @@
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">
<b-form-select
v-if="showToolbar"
v-model="currentPage"
class="form-control"
data-cy="toolbar-page"
>
<option v-for="(data, page) in config" :key="page" :value="page">
{{ data.name }}
</option>
</b-form-select>

<div v-if="showToolbar">
<b-button
size="sm"
variant="secondary"
class="ml-1"
:title="$t('Edit Page Title')"
data-cy="toolbar-edit"
@click="openEditPageModal(currentPage)"
>
<i class="far fa-edit" />
</b-button>

<b-button
size="sm"
variant="danger"
class="ml-1"
:title="$t('Delete Page')"
:disabled="!displayDelete"
data-cy="toolbar-remove"
@click="confirmDelete()"
>
<i class="far fa-trash-alt" />
</b-button>

<b-button
v-b-modal.addPageModal
size="sm"
variant="secondary"
class="ml-1 mr-1"
:title="$t('Add New Page')"
data-cy="toolbar-add"
@click="originalPageName = null"
>
<i class="fas fa-plus" />
</b-button>
</div>
</b-input-group>

<tabs-bar
ref="tabsBar"
:pages="config"
Expand Down Expand Up @@ -799,7 +749,6 @@ export default {
},
methods: {
onClick(page) {
this.currentPage = page;
this.$refs.tabsBar.openPageByIndex(page);
},
checkPageName(value) {
Expand Down Expand Up @@ -1086,8 +1035,10 @@ export default {
this.config = JSON.parse(
this.$store.getters["undoRedoModule/currentState"].config
);
this.currentPage = JSON.parse(
this.$store.getters["undoRedoModule/currentState"].currentPage
this.$refs.tabsBar.openPageByIndex(
this.config.indexOf(
this.$store.getters["undoRedoModule/currentState"].currentPage
)
);
},
redo() {
Expand All @@ -1096,8 +1047,10 @@ export default {
this.config = JSON.parse(
this.$store.getters["undoRedoModule/currentState"].config
);
this.currentPage = JSON.parse(
this.$store.getters["undoRedoModule/currentState"].currentPage
this.$refs.tabsBar.openPageByIndex(
this.config.indexOf(
this.$store.getters["undoRedoModule/currentState"].currentPage
)
);
},
updateConfig(items) {
Expand All @@ -1109,7 +1062,7 @@ export default {
},
focusInspector(validation) {
this.showConfiguration = true;
this.currentPage = this.config.indexOf(validation.page);
this.$refs.tabsBar.openPageByIndex(this.config.indexOf(validation.page));
this.$nextTick(() => {
this.inspect(validation.item);
this.$nextTick(() => {
Expand Down Expand Up @@ -1190,8 +1143,62 @@ export default {
this.addPageName = "";
this.updateState();
},
deletePage() {
this.config.splice(this.pageDelete, 1);
// This function is used to calculate the new index of the references
calcNewIndexFor(index, referencedBy) {
if (index === this.pageDelete) {
throw new Error(
`${this.$t(
"Can not delete this page, it is referenced by"
)}: ${referencedBy}`
);
}
return index > this.pageDelete ? index - 1 : index;
},
// Update Record list references
updateRecordListReferences() {
this.config.forEach((page) => {
page.items.forEach((item) => {
if (item.component === "FormRecordList") {
// eslint-disable-next-line no-param-reassign
item.config.form = this.calcNewIndexFor(
item.config.form * 1,
item.config.label
);
}
});
});
},
// Update navigation buttons references
updateNavigationButtonsReferences() {
this.config.forEach((page) => {
page.items.forEach((item) => {
if (
item.component === "FormButton" &&
item.config.event === "pageNavigate"
) {
// eslint-disable-next-line no-param-reassign
item.config.eventData = this.calcNewIndexFor(
item.config.eventData * 1,
item.config.label
);
}
});
});
},
async deletePage() {
const back = _.cloneDeep(this.config);
try {
this.updateRecordListReferences();
this.updateNavigationButtonsReferences();
this.$refs.tabsBar.closePageByIndex(this.pageDelete);
this.$refs.tabsBar.updateTabsReferences(this.pageDelete);
await this.$nextTick();
this.config.splice(this.pageDelete, 1);
} catch (error) {
this.config = back;
globalObject.ProcessMaker.alert(error.message, "danger");
return;
}
this.$store.dispatch("undoRedoModule/pushState", {
config: JSON.stringify(this.config),
currentPage: this.currentPage,
Expand Down
3 changes: 1 addition & 2 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,7 @@ window.ProcessMaker = {
}
},
alert(message, variant) {
variant;
message;
console.log(`${variant}: ${message}`);
},
screen: {
cacheEnabled: cacheEnabled ? cacheEnabled.content === "true" : false,
Expand Down
16 changes: 5 additions & 11 deletions src/stories/Configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ export const RightArrow = () => <svg
<div className='sb-section-title'>
## Introduction
</div>
<p>
Welcome to the ProcessMaker ScreenBuilder Storybook! This interactive library is designed to showcase the components used to render screens within ProcessMaker processes. Built with Vue2, our components provide a versatile and intuitive way to build dynamic forms and interfaces for your business processes.
</p>

Welcome to the ProcessMaker ScreenBuilder Storybook! This interactive library is designed to showcase the components used to render screens within ProcessMaker processes. Built with Vue2, our components provide a versatile and intuitive way to build dynamic forms and interfaces for your business processes.

<div className='sb-section-title'>
## Key Features
Expand All @@ -42,11 +41,9 @@ export const RightArrow = () => <svg
<div className='sb-section-title'>
## Getting Started
</div>
<p>
To start using the ScreenBuilder components in your ProcessMaker processes, follow these steps:
</p>

<p>
To start using the ScreenBuilder components in your ProcessMaker processes, follow these steps:

Clone the repository and `cd` into the `screen-builder` directory:

```bash
Expand All @@ -60,13 +57,10 @@ cd screen-builder
npm i
npm run serve
```
</p>
<div className='sb-section-title'>
## Explore Components
</div>
<p>
Start exploring the components by selecting them from the sidebar. Each entry provides detailed information about the component, including usage examples and customization options.
</p>
Start exploring the components by selecting them from the sidebar. Each entry provides detailed information about the component, including usage examples and customization options.
</div>

<style>
Expand Down
27 changes: 27 additions & 0 deletions src/stories/PageTabs.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,30 @@ export const TabContentFillAllTheAvailableSpace = {
});
}
};

// Without any page opened
export const WithoutAnyPageOpened = {
args: {
pages: [
{ name: "Page 1" },
{ name: "Page 2" },
{ name: "Page 3" },
{ name: "Page 4" },
{ name: "Page 5" }
],
initialOpenedPages: []
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);

// Check that there is a message when there is no page open.
await waitFor(
() => {
expect(canvas.getByTestId("tab-content")).toContainHTML(
"There are no open pages."
);
},
{ timeout: 1000 }
);
}
};
2 changes: 1 addition & 1 deletion src/stories/ScreenToolbar.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const options = [
];

export default {
title: "Components/Public/ScreenToolbar",
title: "Components/ScreenToolbar",
component: ScreenToolbar,
tags: ["autodocs"],
render: (args, { argTypes }) => ({
Expand Down
Loading