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-18059 Clipboard Tab #1715

Merged
merged 12 commits into from
Oct 4, 2024
6 changes: 1 addition & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

<b-col v-if="displayBuilder && !displayPreview" class="text-right">
<screen-toolbar
:disabled="$refs.builder?.isCurrentPageClipboard"
@undo="$refs.builder.undo()"
@redo="$refs.builder.redo()"
@open-calc="openComputedProperties"
Expand Down Expand Up @@ -626,11 +627,6 @@ export default {
if (computed) {
this.computed = JSON.parse(computed);
}
if(savedClipboard) {
const clipboardsItems = JSON.parse(savedClipboard);

this.$store.dispatch("clipboardModule/addToClipboard", clipboardsItems);
}
},
saveToLocalStorage() {
localStorage.setItem("savedConfig", JSON.stringify(this.config));
Expand Down
17 changes: 15 additions & 2 deletions src/components/ScreenToolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<b-button
class="screen-toolbar-button"
variant="link"
:disabled="!canUndo"
:disabled="!canUndo || disabled"
data-cy="toolbar-undo"
@click="$emit('undo')"
>
Expand All @@ -14,7 +14,7 @@
<b-button
class="screen-toolbar-button"
variant="link"
:disabled="!canRedo"
:disabled="!canRedo || disabled"
data-cy="toolbar-redo"
@click="$emit('redo')"
>
Expand All @@ -25,6 +25,7 @@
type="button"
class="screen-toolbar-button"
variant="link"
:disabled="disabled"
:title="$t('Calculated Properties')"
data-cy="topbar-calcs"
@click="$emit('open-calc')"
Expand All @@ -36,6 +37,7 @@
type="button"
class="screen-toolbar-button"
variant="link"
:disabled="disabled"
:title="$t('Custom CSS')"
data-cy="topbar-css"
@click="$emit('open-customCss')"
Expand All @@ -47,6 +49,7 @@
type="button"
class="screen-toolbar-button"
variant="link"
:disabled="disabled"
:title="$t('Watchers')"
data-cy="topbar-watchers"
@click="$emit('open-watchers')"
Expand All @@ -58,6 +61,7 @@
type="button"
class="screen-toolbar-button"
variant="outlined-secondary"
:disabled="disabled"
:popper-opts="{ placement: 'bottom-end' }"
data-cy="topbar-options"
>
Expand All @@ -77,6 +81,15 @@

<script>
export default {
props: {
/**
* Whether the toolbar is disabled or not
*/
disabled: {
type: Boolean,
default: false
}
},
data() {
return {
showToolbar: true
Expand Down
45 changes: 40 additions & 5 deletions src/components/TabsBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,26 @@
</template>
</b-tab>
<b-tab
v-if="showClipboard"
ref="clipboard"
class="h-100 w-100"
@click="clipboard"
name="clipboard"
>
<template #title>
{{ $t('Clear Clipboard') }}
{{ $t('Clipboard') }}
<span
:data-test="`close-clipboard-tab`"
class="close-tab"
role="link"
@click.stop="closeClipboard"
>
<i class="fas fa-times" />
</span>
</template>
<template #default>
<div class="h-100 w-100" data-test="tab-content">
<slot :current-page="clipboardPageIndex" />
</div>
</template>
</b-tab>
<template #tabs-end>
Expand Down Expand Up @@ -123,6 +138,13 @@ export default {
isMultiPage: {
type: Boolean,
default: true
},
/**
* Show clipboard tab
*/
showClipboard: {
type: Boolean,
default: false
}
},
data() {
Expand All @@ -136,6 +158,9 @@ export default {
};
},
computed: {
clipboardPageIndex() {
return this.pages.length;
},
validLocalOpenedPages() {
return this.localOpenedPages.filter((page) => this.pages[page]);
}
Expand Down Expand Up @@ -178,12 +203,22 @@ export default {
this.checkTabsOverflow();
},
methods: {
clipboard() {
this.$emit('clearClipboard');
openClipboard() {
if (this.$refs.clipboard) {
this.$refs.clipboard.activate();
}
},
closeClipboard() {
this.$emit('close-clipboard');
},
tabOpened() {
const pageIndex = this.localOpenedPages[this.activeTab];
this.$emit("tab-opened", pageIndex);
const isInClipboard = (this.activeTab === this.$refs.tabs.tabs.length - 1) && this.showClipboard;
if (isInClipboard) {
this.$emit("tab-opened", this.clipboardPageIndex);
} else {
this.$emit("tab-opened", pageIndex);
}
},
pageNumber(index) {
return index + 1;
Expand Down
86 changes: 65 additions & 21 deletions src/components/vue-form-builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
no-body
class="h-100 rounded-0 border-top-0 border-bottom-0 border-left-0"
>
<b-input-group size="sm" style="height: 42px">
<b-input-group size="sm" style="height: 42px">
<b-input-group-prepend>
<span
class="input-group-text rounded-0 border-left-0 border-top-0 border-bottom-0"
Expand Down Expand Up @@ -76,6 +76,8 @@
:boundary="'viewport'"
:data-cy="`controls-${element.component}`"
class="gray-text"
:disabled="!canDragControl(element)"
@mousedown="disableEnableDragControl(element, $event)"
>
<i
v-if="element.config && element.config.icon"
Expand Down Expand Up @@ -106,8 +108,9 @@
ref="tabsBar"
:pages="config"
:is-multi-page="showToolbar"
:show-clipboard="showClipboard"
@tab-opened="currentPage = $event"
@clearClipboard="clearClipboard"
@close-clipboard="closeClipboard"
>
<template #tabs-start>
<pages-dropdown
Expand All @@ -120,6 +123,13 @@
/>
</template>
<template #default="{ currentPage: tabPage }">
<b-button
v-if="isClipboardPage(tabPage)"
variant="link"
@click="clearClipboard"
>
{{ $t('Clear All') }}
</b-button>
<div
v-if="isCurrentPageEmpty(tabPage)"
data-cy="screen-drop-zone"
Expand Down Expand Up @@ -154,15 +164,15 @@
data-cy="editor-content"
class="h-100"
ghost-class="form-control-ghost"
:value="config[tabPage].items"
:value="extendedPages[tabPage].items"
v-bind="{
group: { name: 'controls' },
swapThreshold: 0.5
}"
@input="updateConfig"
>
<div
v-for="(element, index) in config[tabPage].items"
v-for="(element, index) in extendedPages[tabPage].items"
:key="index"
class="control-item mt-4 mb-4"
:class="{
Expand Down Expand Up @@ -193,13 +203,14 @@
{{ element.config.name || element.label || $t("Field Name") }}
<div class="ml-auto">
<clipboard-button
v-if="!isClipboardPage(tabPage)"
:index="index"
:config="element.config"
:isInClipboard="isInClipboard(config[currentPage].items[index])"
:isInClipboard="isInClipboard(extendedPages[tabPage].items[index])"
:addTitle="$t('Add to clipboard')"
:removeTitle="$t('Remove from clipboard')"
@addToClipboard="addToClipboard(config[currentPage].items[index])"
@removeFromClipboard="removeFromClipboard(config[currentPage].items[index])"
@addToClipboard="addToClipboard(extendedPages[tabPage].items[index])"
@removeFromClipboard="removeFromClipboard(extendedPages[tabPage].items[index])"
/>
<button
v-if="isAiSection(element) && aiPreview(element)"
Expand Down Expand Up @@ -257,13 +268,14 @@
{{ element.config.name || $t("Variable Name") }}
<div class="ml-auto">
<clipboard-button
v-if="!isClipboardPage(tabPage)"
:index="index"
:config="element.config"
:isInClipboard="isInClipboard(config[currentPage].items[index])"
:isInClipboard="isInClipboard(extendedPages[tabPage].items[index])"
:addTitle="$t('Add to clipboard')"
:removeTitle="$t('Remove from clipboard')"
@addToClipboard="addToClipboard(config[currentPage].items[index])"
@removeFromClipboard="removeFromClipboard(config[currentPage].items[index])"
@addToClipboard="addToClipboard(extendedPages[tabPage].items[index])"
@removeFromClipboard="removeFromClipboard(extendedPages[tabPage].items[index])"
/>
<button
class="btn btn-sm btn-secondary mr-2"
Expand Down Expand Up @@ -363,7 +375,7 @@
''
)}`"
:builder="builder"
:form-config="config"
:form-config="extendedPages"
:screen-type="screenType"
:current-page="currentPage"
:selected-control="selected"
Expand Down Expand Up @@ -616,7 +628,13 @@ export default {
config[0].name = this.title;
}

const clipboardPage = {
name: this.$t("Clipboard"),
items: this.$store.getters["clipboardModule/clipboardItems"],
};

return {
clipboardPage,
showAddPageValidations: false,
openedPages: [0],
currentPage: 0,
Expand Down Expand Up @@ -658,10 +676,15 @@ export default {
};
},
computed: {
pagesAndClipboard() {
return [...this.config, [{name:"Clipboard", items: []}]];
isCurrentPageClipboard() {
return this.isClipboardPage(this.currentPage);
},
extendedPages() {
return [
...this.config,
this.clipboardPage,
];
},
// Get clipboard items from Vuex store
clipboardItems() {
return this.$store.getters["clipboardModule/clipboardItems"];
},
Expand Down Expand Up @@ -809,14 +832,26 @@ export default {
this.$root.$on("ai-form-progress-updated", (progress, nonce) => {
this.updateProgress(progress, nonce);
});
this.$root.$on("update-clipboard", () => {
ProcessMaker.EventBus.$emit("save-clipboard", this.clipboardItems);
});
this.setGroupOrder(defaultGroupOrder);
},
methods: {
isClipboardPage(page) {
return page === this.config.length;
},
disableEnableDragControl(control, event) {
if (!this.canDragControl(control)) {
event.preventDefault();
}
},
canDragControl(control) {
const isDragAndPaste = control.component === "Clipboard";
return !(isDragAndPaste && this.isClipboardPage(this.currentPage));
},
openClipboard() {
this.$refs.tabsBar.openPageByIndex(-1);
this.showClipboard = true;
this.$nextTick(() => {
this.$refs.tabsBar.openClipboard();
});
},
isCurrentPageEmpty(currentPage) {
return this.config[currentPage]?.items?.length === 0;
Expand Down Expand Up @@ -1117,11 +1152,14 @@ export default {
});
},
updateState() {
// paste the clipboard items into the current page
this.replaceClipboardContent(this.config);
this.$store.dispatch("undoRedoModule/pushState", {
config: JSON.stringify(this.config),
currentPage: this.currentPage
});
this.replaceClipboardContent([this.clipboardPage]);
this.$store.dispatch("clipboardModule/pushState", this.clipboardPage.items);
},
async undo() {
this.inspect();
Expand All @@ -1146,7 +1184,7 @@ export default {
);
},
updateConfig(items) {
this.config[this.currentPage].items = items;
this.extendedPages[this.currentPage].items = items;
this.updateState();
},
hasError(element) {
Expand Down Expand Up @@ -1194,13 +1232,14 @@ export default {
},
deleteItem(index) {
// Remove the item from the array in currentPage
this.config[this.currentPage].items.splice(index, 1);
this.extendedPages[this.currentPage].items.splice(index, 1);
this.inspection.inspector.splice(0, this.inspection.inspector.length);
this.updateState();
},
duplicateItem(index) {
const duplicate = _.cloneDeep(this.config[this.currentPage].items[index]);
this.config[this.currentPage].items.push(duplicate);
this.updateUuids(duplicate);
this.extendedPages[this.currentPage].items.push(duplicate);
},
openEditPageModal(index) {
this.editPageIndex = index;
Expand Down Expand Up @@ -1303,6 +1342,7 @@ export default {
currentPage: this.currentPage,
deletedPage: true
});
this.$store.dispatch("clipboardModule/pushState", this.clipboardPage.items);
},
inspect(element = {}) {
this.inspection = element;
Expand Down Expand Up @@ -1609,4 +1649,8 @@ $side-bar-font-size: 0.875rem;
font-size: 15px;
font-weight: normal;
}
.gray-text.disabled {
cursor: not-allowed; /* Cambia el cursor cuando se pasa por encima */
pointer-events: all; /* Permite que el pseudo-elemento reciba eventos del ratón */
}
</style>
Loading
Loading