Skip to content

Commit 7655fbe

Browse files
authored
Merge pull request #212 from kgonella/feature/copy-paste-all-contents
Add toolbox on top of each richeditor widget
2 parents 1830e2e + 9eba035 commit 7655fbe

File tree

7 files changed

+143
-10
lines changed

7 files changed

+143
-10
lines changed

assets/css/app.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ html.is-disabled body {
209209
align-items: center !important;
210210
}
211211

212+
.uie-flex-cross-right {
213+
justify-content: flex-end !important;
214+
}
215+
212216
.uie-flex-main-between {
213217
justify-content: space-between !important;
214218
}

assets/js/app.js

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ global.MonsieurBizRichEditorManager = class {
218218
initInterface() {
219219
this.initUiElementsInterface();
220220
this.initUiPanelsInterface();
221+
this.initUiToolsInterface();
222+
221223
document.dispatchEvent(new CustomEvent('mbiz:rich-editor:init-interface-complete', {
222224
'detail': {'editorManager': this}
223225
}));
@@ -226,6 +228,30 @@ global.MonsieurBizRichEditorManager = class {
226228
action.classList.remove('disabled');
227229
}.bind(this));
228230
}.bind(this));
231+
232+
document.addEventListener('mbiz:rich-editor:uielements:copied', function (e) {
233+
this.container.querySelectorAll('.js-uie-tools-paste-all').forEach(function (action) {
234+
action.removeAttribute('disabled');
235+
}.bind(this));
236+
}.bind(this));
237+
}
238+
239+
initUiToolsInterface() {
240+
const copyAllButton = this.container.querySelector('.js-uie-tools-copy-all');
241+
const pasteAllButton = this.container.querySelector('.js-uie-tools-paste-all');
242+
const trashAllButton = this.container.querySelector('.js-uie-tools-trash-all');
243+
244+
copyAllButton && copyAllButton.addEventListener('click', e => {
245+
this.saveUiElementsToClipboard(e.currentTarget);
246+
});
247+
248+
pasteAllButton && pasteAllButton.addEventListener('click', e => {
249+
this.pasteUiElementsFromClipboard();
250+
});
251+
252+
trashAllButton && trashAllButton.addEventListener('click', e => {
253+
this.resetUiElements();
254+
});
229255
}
230256

231257
initUiPanelsInterface() {
@@ -300,7 +326,7 @@ global.MonsieurBizRichEditorManager = class {
300326
);
301327
});
302328
// Disabled?
303-
if (!this.isClipboardEmpty()) {
329+
if (!this.isClipboardEmpty('monsieurBizRichEditorElementClipboard')) {
304330
actions.querySelector('.js-uie-paste').classList.remove('disabled');
305331
}
306332

@@ -617,19 +643,65 @@ global.MonsieurBizRichEditorManager = class {
617643
req.send(data);
618644
}
619645

620-
isClipboardEmpty() {
621-
const clipboard = window.localStorage.getItem('monsieurBizRichEditorClipboard');
646+
isClipboardEmpty(clipboardKey) {
647+
const clipboard = window.localStorage.getItem(clipboardKey);
622648
return null === clipboard || '' === clipboard;
623649
}
624650

651+
resetUiElements() {
652+
if (this.uiElements.length === 0) {
653+
return;
654+
}
655+
656+
this.loadUiConfirmationModal(() => { this.initUiElements([], () => { this.write(); }) })
657+
}
658+
659+
loadUiConfirmationModal(callback) {
660+
const modal = document.querySelector('#monsieurbiz-rich-editor-confirmation-modal');
661+
const confirmButton = modal.querySelector('#monsieurbiz-rich-editor-confirmation-button');
662+
663+
const clonedConfirmButtom = confirmButton.cloneNode(true);
664+
confirmButton.parentNode.replaceChild(clonedConfirmButtom, confirmButton);
665+
clonedConfirmButtom.addEventListener('click', () => {
666+
callback();
667+
})
668+
669+
$(modal).modal('show');
670+
}
671+
672+
saveUiElementsToClipboard(button) {
673+
window.localStorage.setItem('monsieurBizRichEditorElementsClipboard', JSON.stringify(this.uiElements));
674+
675+
const originalText = button.dataset.tooltip;
676+
button.dataset.tooltip = button.dataset.alternateText;
677+
window.setTimeout(function () {
678+
button.dataset.tooltip = originalText;
679+
}, 1000);
680+
681+
document.dispatchEvent(new CustomEvent('mbiz:rich-editor:uielements:copied', {}));
682+
}
683+
684+
pasteUiElementsFromClipboard() {
685+
const clipboard = window.localStorage.getItem('monsieurBizRichEditorElementsClipboard');
686+
if (clipboard !== null) {
687+
const pastedUiElement = JSON.parse(clipboard);
688+
689+
if (this.uiElements.length > 0) {
690+
this.loadUiConfirmationModal(() => { this.initUiElements(pastedUiElement, () => { this.write(); }) })
691+
} else {
692+
this.initUiElements(pastedUiElement, () => { this.write(); });
693+
}
694+
}
695+
}
696+
625697
saveUiElementToClipboard(uiElement, callback) {
626-
window.localStorage.setItem('monsieurBizRichEditorClipboard', JSON.stringify(uiElement));
698+
window.localStorage.setItem('monsieurBizRichEditorElementClipboard', JSON.stringify(uiElement));
627699
callback();
628700
document.dispatchEvent(new CustomEvent('mbiz:rich-editor:uielement:copied', {}));
629701
}
630702

631703
pasteUiElementFromClipboard(futurePosition) {
632-
const clipboard = window.localStorage.getItem('monsieurBizRichEditorClipboard');
704+
const clipboard = window.localStorage.getItem('monsieurBizRichEditorElementClipboard');
633705
if (null !== clipboard) {
634706
const pastedUiElement = JSON.parse(clipboard);
635707
const manager = this;

src/Resources/public/css/rich-editor.css

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Resources/public/js/rich-editor.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Resources/translations/messages.en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ monsieurbiz_richeditor_plugin:
126126
justify: 'Justify'
127127
clipboard: 'Clipboard'
128128
paste_from_clipboard: 'Paste from clipboard'
129+
paste_all_from_clipboard: 'Paste all elements'
130+
copy_all_from_clipboard: 'Copy all elements'
131+
trash_all: 'Remove all elements'
129132
copied: 'Copied!'
130133
copy: 'Copy'
131134
action:

src/Resources/translations/messages.fr.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ monsieurbiz_richeditor_plugin:
126126
justify: 'Justifié'
127127
clipboard: 'Presse-papier'
128128
paste_from_clipboard: 'Coller depuis le presse-papier'
129+
paste_all_from_clipboard: 'Coller tous les éléments'
130+
copy_all_from_clipboard: 'Copier tous les éléments'
131+
trash_all: 'Supprimer tous les éléments'
129132
copied: 'Copié !'
130133
copy: 'Copier'
131134
action:

src/Resources/views/Admin/app.html.twig

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,46 @@
11
{% include '@SyliusUi/_javascripts.html.twig' with {'path': 'bundles/monsieurbizsyliusricheditorplugin/js/rich-editor.js'} %}
22
{% include '@SyliusUi/_stylesheets.html.twig' with {'path': 'bundles/monsieurbizsyliusricheditorplugin/css/rich-editor.css'} %}
33

4+
<div class="ui small basic modal" id="monsieurbiz-rich-editor-confirmation-modal">
5+
<div class="ui icon header">
6+
<i class="warning sign icon"></i>
7+
{{ 'sylius.ui.confirm_your_action'|trans }}
8+
</div>
9+
<div class="content">
10+
<p>{{ 'sylius.ui.are_your_sure_you_want_to_perform_this_action'|trans }}</p>
11+
</div>
12+
<div class="actions">
13+
<div class="ui red basic cancel inverted button">
14+
<i class="remove icon"></i>
15+
{{ 'sylius.ui.no_label'|trans }}
16+
</div>
17+
<div class="ui green ok inverted button" id="monsieurbiz-rich-editor-confirmation-button">
18+
<i class="checkmark icon"></i>
19+
{{ 'sylius.ui.yes_label'|trans }}
20+
</div>
21+
</div>
22+
</div>
23+
24+
<div class="ui small basic modal" id="monsieurbiz-rich-editor-confirmation-modal">
25+
<div class="ui icon header">
26+
<i class="warning sign icon"></i>
27+
{{ 'sylius.ui.confirm_your_action'|trans }}
28+
</div>
29+
<div class="content">
30+
<p>{{ 'sylius.ui.are_your_sure_you_want_to_perform_this_action'|trans }}</p>
31+
</div>
32+
<div class="actions">
33+
<div class="ui red basic cancel inverted button">
34+
<i class="remove icon"></i>
35+
{{ 'sylius.ui.no_label'|trans }}
36+
</div>
37+
<div class="ui green ok inverted button" id="monsieurbiz-rich-editor-confirmation-button">
38+
<i class="checkmark icon"></i>
39+
{{ 'sylius.ui.yes_label'|trans }}
40+
</div>
41+
</div>
42+
</div>
43+
444
<script id="monsieurbiz-rich-editor-actions" type="x-tmpl-mustache">
545
{% verbatim %}
646
<div class="ui horizontal divider">
@@ -52,12 +92,23 @@
5292
</script>
5393

5494
<script id="monsieurbiz-rich-editor-ui-elements-container" type="x-tmpl-mustache">
55-
{% verbatim %}
56-
<div class="ui container">
95+
<div class="ui">
96+
<div class="uie-flex uie-flex-cross-right">
97+
<div class="ui buttons">
98+
<button class="ui icon button js-uie-tools-copy-all" type="button" data-alternate-text="{{ 'monsieurbiz_richeditor_plugin.form.copied'|trans }}" data-tooltip="{{ "monsieurbiz_richeditor_plugin.form.copy_all_from_clipboard"|trans }}">
99+
<i class="copy icon"></i>
100+
</button>
101+
<button class="ui icon button js-uie-tools-paste-all" type="button" disabled data-tooltip="{{ "monsieurbiz_richeditor_plugin.form.paste_all_from_clipboard"|trans }}">
102+
<i class="paste icon"></i>
103+
</button>
104+
<button class="ui icon button js-uie-tools-trash-all" type="button" data-tooltip="{{ "monsieurbiz_richeditor_plugin.form.trash_all"|trans }}">
105+
<i class="trash icon"></i>
106+
</button>
107+
</div>
108+
</div>
57109
<div class="ui segment js-uie-container">
58110
</div>
59111
</div>
60-
{% endverbatim %}
61112
</script>
62113

63114
<script id="monsieurbiz-rich-editor-ui-element-card" type="x-tmpl-mustache">

0 commit comments

Comments
 (0)