Skip to content

Commit

Permalink
Merge pull request #1714 from ProcessMaker/FOUR-13443
Browse files Browse the repository at this point in the history
FOUR-13443 Implement Clipboard usage between pages or separate screens
  • Loading branch information
caleeli authored Sep 30, 2024
2 parents 7c903b0 + b7fad6a commit 26346b0
Show file tree
Hide file tree
Showing 8 changed files with 285 additions and 63 deletions.
5 changes: 0 additions & 5 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -626,11 +626,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
8 changes: 8 additions & 0 deletions src/components/TabsBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
</template>
</b-tab>
<b-tab
v-if="showClipboard"
class="h-100 w-100"
@click="clipboard"
>
Expand Down Expand Up @@ -123,6 +124,13 @@ export default {
isMultiPage: {
type: Boolean,
default: true
},
/**
* Show clipboard tab
*/
showClipboard: {
type: Boolean,
default: false
}
},
data() {
Expand Down
9 changes: 3 additions & 6 deletions src/components/vue-form-builder.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
ref="tabsBar"
:pages="config"
:is-multi-page="showToolbar"
:show-clipboard="true"
@tab-opened="currentPage = $event"
@clearClipboard="clearClipboard"
>
Expand Down Expand Up @@ -658,9 +659,6 @@ export default {
};
},
computed: {
pagesAndClipboard() {
return [...this.config, [{name:"Clipboard", items: []}]];
},
// Get clipboard items from Vuex store
clipboardItems() {
return this.$store.getters["clipboardModule/clipboardItems"];
Expand Down Expand Up @@ -809,9 +807,6 @@ 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: {
Expand Down Expand Up @@ -1117,6 +1112,7 @@ 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),
Expand Down Expand Up @@ -1200,6 +1196,7 @@ export default {
},
duplicateItem(index) {
const duplicate = _.cloneDeep(this.config[this.currentPage].items[index]);
this.updateUuids(duplicate);
this.config[this.currentPage].items.push(duplicate);
},
openEditPageModal(index) {
Expand Down
8 changes: 2 additions & 6 deletions src/components/vue-form-renderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,8 @@ export default {
this.containerObserver.observe(this.$refs.formRendererContainer);
ProcessMaker.EventBus.$on(
"save-clipboard",
(items) => {
this.saveClipboarToLocalStorage(items);
},
);
// Initialize the clipboard module
this.$store.dispatch('clipboardModule/initializeClipboard');
},
methods: {
...mapActions("globalErrorsModule", [
Expand Down
29 changes: 21 additions & 8 deletions src/mixins/Clipboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,26 @@ export default {
screenConfig.forEach((item) => replaceInPage(item));
},

/**
* Setup or update UUID for the item and its children.
*
* @param {*} item Control item in the screen configuration
*/
updateUuids(item) {
item.uuid = this.generateUUID();
if (item.items) {
item.items.forEach(item => {
if (item instanceof Array) {
// multi-column each item in the column
item.forEach(this.updateUuids)
} else {
// loop through children
this.updateUuids(item);
}
})
}
},

/**
* Find { component: "Clipboard" } and replace with the clipboard content.
*/
Expand All @@ -76,20 +96,13 @@ export default {
throw new Error("Expected a screen configuration array");
}

// Navigate each page and replace the clipboard component with the clipboard content
const replaceUuids = (item) => {
item.uuid = this.generateUUID();
if (item.items) {
item.items.forEach(replaceUuids);
}
}
const replaceInPage = (page) => {
page.items.forEach((item, index) => {
if (item.component === clipboardComponentName) {
// clone clipboard content to avoid modifying the original
const clipboardContent = _.cloneDeep(this.$store.getters["clipboardModule/clipboardItems"]);
// replace uuids in clipboard content
clipboardContent.forEach(replaceUuids);
clipboardContent.forEach(this.updateUuids);
page.items.splice(index, 1, ...clipboardContent);
}
if (item.items) {
Expand Down
79 changes: 79 additions & 0 deletions src/store/modules/ClipboardManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/**
* ClipboardManager class to handle saving to and loading from
* localStorage and the server.
*/
class ClipboardManager {

/**
* Callable property function that loads the clipboard from server.
*/
static loadFromServerFn = null;

/**
* Callable property function that saves the clipboard to server.
*/
static saveToServerFn = null;

/**
* Saves the clipboard items to localStorage.
* @param {Array} clipboard - The clipboard items to save.
*/
static saveToLocalStorage(clipboard) {
localStorage.setItem('clipboard', JSON.stringify(clipboard));
}

/**
* Loads the clipboard items from localStorage.
* @returns {Array} The clipboard items.
*/
static loadFromLocalStorage() {
const clipboardData = localStorage.getItem('clipboard');
if (clipboardData) {
try {
return JSON.parse(clipboardData);
} catch (e) {
console.error('Failed to parse clipboard data from localStorage:', e);
return [];
}
} else {
return [];
}
}

/**
* Saves the clipboard items to the server via POST /clipboard/create_or_update.
* @param {Array} clipboard - The clipboard items to save.
* @returns {Promise}
*/
static saveToServer(clipboard) {
// return axios.post('/clipboard/create_or_update', { clipboard });
if (!ClipboardManager.saveToServerFn) {
return Promise.resolve();
}
return ClipboardManager.saveToServerFn(clipboard);
}

/**
* Loads the clipboard items from the server via GET /clipboard/get_by_user.
* @returns {Promise<Array>} The clipboard items.
*/
static loadFromServer() {
if (!ClipboardManager.loadFromServerFn) {
return Promise.resolve([]);
}
return ClipboardManager.loadFromServerFn()
.then(clipboard => {
if (Array.isArray(clipboard)) {
return clipboard;
} else {
throw new Error('Invalid server response: Expected array for clipboard content');
}
})
.catch(error => {
console.error('Failed to load clipboard from server:', error);
return [];
});
}
}

export default ClipboardManager;
Loading

0 comments on commit 26346b0

Please sign in to comment.