PluginProbe
MailerLite – WooCommerce integration / 3.1.20
MailerLite – WooCommerce integration v3.1.20
3.1.25 3.1.26 3.1.24 3.1.23 3.1.22 3.1.21 3.1.20 3.1.19 3.1.18 3.1.17 3.1.16 3.1.15 1.8.7 1.8.8 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 All 147 releases
woo-mailerlite / admin / assets / js / components / Modals / Modals.js

Modals.js in MailerLite – WooCommerce integration 3.1.20, at admin/assets/js/components/Modals/Modals.js

279 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import eventBus from "../eventBus.js";
2 import ApiMixin from '../Api/ApiMixin.js';
3 import {validate} from "../Plugins/Validation.js";
4 import {loadStart, loadEnd} from "../Plugins/Loader.js";
5 const template = `
6 <!-- Create Group Modal -->
7 <div v-if="openCreateGroupModal" class="woo-ml-wizard-modal" id="wooMlWizardCreateGroupModal" role="dialog" data-testid="create-group-modal">
8 <div class="woo-ml-wizard-modal-parent">
9 <div class="woo-ml-wizard-modal-container">
10 <div class="woo-ml-wizard-modal-content">
11 <div class="woo-ml-wizard-modal-header">
12 <h2>Create new group</h2>
13 <span @click="openCreateGroupModal = false" class="close"></span>
14 </div>
15 <div class="woo-ml-wizard-modal-body">
16 <div class="create-group-input">
17 <input ref="wooMlCreateGroup" type="text" name="createGroup" placeholder="Enter group name" v-model="createGroupName" class="" data-testid="create-group-name-input">
18 </div>
19 <div class="modal-button-ml">
20 <button @click="openCreateGroupModal = false" type="button" class="btn-secondary-ml woo-ml-close" style="margin-right: 12px;">Close</button>
21 <button @click="createGroup" ref="createGroup" type="button" class="btn-primary-ml" data-testid="create-group-submit-btn"><span class="woo-ml-button-text">Create group</span></button>
22 </div>
23 </div>
24 </div>
25 </div>
26 </div>
27 </div>
28 <!-- Create Group Modal -->
29
30 <!-- Sync Resources Modal -->
31 <div v-if="openSyncModal" class="woo-ml-wizard-modal" id="wooMlSyncModal" role="dialog">
32 <div class="woo-ml-wizard-modal-parent">
33 <div class="woo-ml-wizard-modal-container">
34 <div class="woo-ml-wizard-modal-content woo-ml-text-center">
35 <div class="woo-ml-wizard-modal-header">
36 <h2>Synchronizing subscribers</h2>
37 </div>
38 <p style="line-height: 1.75rem; font-size: 14px; text-align: left; margin-bottom: 24px;">
39 This initial import will send product details, product categories, and customer data to MailerLite. It will also enable real-time synchronization on future updates. Please note that only subscribers who opt-in to receive email marketing will be added.
40 </p>
41 <div class="progress-box">
42 <div class="progress">
43 <div id="wooMlWizardProgress" :style="{ width: progressPercentage + '%' }"></div>
44 </div>
45 <div style=" text-align: center; "><span id="progressPercentage">{{ progressPercentage }}%</span></div>
46 </div>
47 <h4>Total resources to sync: {{ remainingUntrackedResources }}</h4>
48 <div class="woo-ml-wizard-modal-body">
49 <div class="modal-button-ml">
50 <button @click="openSyncModal = false" type="button" class="btn-secondary-ml">Cancel</button>
51 </div>
52 </div>
53 </div>
54 </div>
55 </div>
56 </div>
57 <!-- Sync Resources Modal -->
58
59 <!-- Cancel Sync Resources Modal -->
60 <div v-if="openCancelSyncModal" class="woo-ml-wizard-modal" id="wooMlCancelSyncModal" role="dialog">
61 <div class="woo-ml-wizard-modal-parent">
62 <div class="woo-ml-wizard-modal-container">
63 <div class="woo-ml-wizard-modal-content woo-ml-text-center">
64 <div class="woo-ml-wizard-modal-header">
65 <h2>Terminate import</h2>
66 </div>
67 <p style="line-height: 1.75rem; font-size: 14px; text-align: left; margin-bottom: 0;">
68 Are you sure you want to stop the import process? The import will be reset, and the progress made so far will be lost. Click 'Terminate' if you wish to continue.
69 </p>
70 <div class="woo-ml-wizard-modal-body">
71 <div class="modal-button-ml">
72 <button @click="openCancelSyncModal = false" type="button" class="btn-secondary-ml" style="margin-right: 12px;">Close</button>
73 <button id="confirmCancelSync" type="button" class="btn-danger-ml" style="margin-right: 12px;"><span class="woo-ml-button-text">Terminate</span></button>
74 </div>
75 </div>
76 </div>
77 </div>
78 </div>
79 </div>
80 <!-- Cancel Sync Resources Modal -->
81
82 <!-- Reset Integration Modal -->
83 <div v-if="openResetModal" class="woo-ml-wizard-modal" id="wooMlResetIntegrationModal" role="dialog">
84 <div class="woo-ml-wizard-modal-parent">
85 <div class="woo-ml-wizard-modal-container">
86 <div class="woo-ml-wizard-modal-content woo-ml-text-center">
87 <div class="woo-ml-wizard-modal-header">
88 <h2>Reset integration</h2>
89 </div>
90 <p style="line-height: 1.75rem; font-size: 14px; text-align: left; margin-bottom: 0;">
91 Are you sure you want to reset the integration? Click 'Reset' if you wish to continue.
92 </p>
93 <div class="woo-ml-wizard-modal-body">
94 <div class="modal-button-ml">
95 <form id="resetIntegration" method="post">
96 <!-- wp_nonce_field('ml_reset_integration'); -->
97 <input type="hidden" name="resetIntegration"/>
98 <button @click="openResetModal = false" type="button" class="btn-secondary-ml" style="margin-right: 12px;">Close</button>
99 <button @click.prevent="resetIntegration" ref="resetIntegration" id="resetIntegrationBtn" class="btn-danger-ml" style="margin-right: 12px;"><span class="woo-ml-button-text">Reset</span></button>
100 </form>
101 </div>
102 </div>
103 </div>
104 </div>
105 </div>
106 </div>
107 <!-- Reset Integration Modal -->
108
109 <!-- Reset Integration Modal -->
110 <div v-if="openDebugLogModal" class="woo-ml-wizard-modal" id="openDebugLogModal" role="dialog">
111 <div class="woo-ml-wizard-modal-parent">
112 <div class="woo-ml-wizard-modal-container">
113 <div class="woo-ml-wizard-modal-content woo-ml-text-center">
114 <div class="woo-ml-wizard-modal-header">
115 <h2>Debug logs</h2>
116 <p style="line-height: 1.75rem; font-size: 14px; text-align: left; margin-bottom: 0;">
117 In case you have problems with our application's performance, please click 'Copy to clipboard' and share the logs with our support team using <a href="https://www.mailerlite.com/contact-us?category=integrations-api" target="_blank" class="settings-label-medium">this contact form</a>.
118 </p>
119 </div>
120 <div class="woo-ml-wizard-modal-body">
121 <input type="text" v-model="searchLogs" @input="highlightSearch" placeholder="Search logs..." />
122 <pre class="woo-mailerlite-log-container" ref="debugLogLines">
123 <div v-for="(line, index) in filteredLogs" :key="index" v-html="highlightSearch(line)"></div>
124 </pre>
125 <div class="modal-button-ml">
126 <button @click="openDebugLogModal = false" type="button" class="btn-secondary-ml" style="margin-right: 12px;">Close</button>
127 <button @click="copyDebugLogToClipboard" type="button" class="btn-primary-ml no-icon-tooltip-ml" style="margin-right: 12px;"><span class="no-icon-tooltip-ml-text">Copied</span><span class="woo-ml-button-text">{{this.copyMessage !== '' ? this.copyMessage : 'Copy to clipboard'}}</span></button>
128 </div>
129 </div>
130 </div>
131 </div>
132 </div>
133 </div>
134 <!-- Reset Integration Modal -->
135 `;
136
137 const Modals = {
138 template,
139 mixins: [ApiMixin],
140 data() {
141 return {
142 totalTrackedResources: 0,
143 totalUntrackedResources: 100,
144 openCreateGroupModal: false,
145 openSyncModal: false,
146 openCancelSyncModal: false,
147 openResetModal: false,
148 openDebugLogModal: false,
149 progressPercentage: 0,
150 intervalId: null,
151 createGroupName: "",
152 filteredLogs: [],
153 searchLogs: "",
154 copyMessage: "",
155 resetSyncButtonRef: null,
156 }
157 },
158 computed: {
159 remainingUntrackedResources() {
160 return this.totalUntrackedResources - this.totalTrackedResources;
161 },
162 },
163 mounted() {
164 eventBus.on('show-create-group-modal', (data) => {
165 this.openCreateGroupModal = true
166 });
167 eventBus.on('show-sync-modal', (data) => {
168 this.openSyncModal = true
169
170 // TODO - send sync to background and continue setup
171 this.simProgress()
172 });
173 eventBus.on('show-cancel-sync-modal', (data) => {
174 this.openCancelSyncModal = true
175 });
176 eventBus.on('show-reset-modal', (ref) => {
177 this.openResetModal = true
178 });
179 eventBus.on('show-debug-modal', async (ref) => {
180 try {
181 loadStart(ref);
182 const data = await this.getDebugLog()
183 if (data.success) {
184 this.debugLogs = data.log ? data.log.split('\n') : "No Logs Found"
185 this.filteredLogs = [...this.debugLogs];
186 this.openDebugLogModal = true
187 } else {
188 eventBus.emit('alert-event', { error: 'An error occurred' });
189 }
190 loadEnd(ref);
191 } catch (err) {
192 this.isLoading = false
193 eventBus.emit('alert-event', { error: 'An error occurred' });
194 loadEnd(ref);
195 }
196 });
197 },
198 methods: {
199 simProgress() {
200 if (this.intervalId) return;
201 this.progressPercentage = 0;
202 this.totalTrackedResources = 0;
203
204 this.intervalId = setInterval(() => {
205 if (this.totalTrackedResources < this.totalUntrackedResources) {
206 this.totalTrackedResources += 10;
207
208 this.progressPercentage = Math.round(
209 (this.totalTrackedResources / this.totalUntrackedResources) * 100
210 );
211 } else {
212 clearInterval(this.intervalId); // stop once it reaches 100
213 this.intervalId = null;
214
215 // move to settings and close modal
216 eventBus.emit('wizard-step-event', 2)
217 this.openSyncModal = false
218 }
219 }, 500);
220 },
221 async createGroup() {
222 loadStart(this.$refs.createGroup);
223 const groupNameValid = validate(this.$refs.wooMlCreateGroup, ['required', 'minLength:3'], {
224 required: 'Group name is required.',
225 });
226 if (groupNameValid) {
227 const response = await this.createGroupApi(this.createGroupName)
228 if (response.success) {
229 eventBus.emit('trigger-group-created', response.data)
230 }
231 }
232 loadEnd(this.$refs.createGroup);
233 this.openCreateGroupModal = false
234 },
235 resetIntegration() {
236 eventBus.emit('reset-integration');
237 },
238 filterLogs() {
239 const term = this.searchLogs.toLowerCase();
240 this.filteredLogs = this.debugLogs.filter(line =>
241 line.toLowerCase().includes(term)
242 );
243 },
244 // Highlight search term in logs
245 highlightSearch(line) {
246 if (!this.searchLogs) return line;
247 if (typeof line !== 'string') return line;
248 const term = this.searchLogs.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); // Escape special characters
249 const regex = new RegExp(`(${term})`, 'gi');
250 return line.replace(regex, '<span class="woo-mailerlite-log-highlight">$1</span>');
251 },
252 copyDebugLogToClipboard() {
253 if (navigator.clipboard && window.isSecureContext) {
254 // Modern method (HTTPS only)
255 navigator.clipboard.writeText(this.filteredLogs.join('\n')).then(() => {
256 this.copyMessage = 'Copied!';
257 setTimeout(() => {
258 this.copyMessage = "";
259 }, 2000);
260 }).catch(err => {
261 });
262 } else {
263 const textarea = document.createElement("textarea");
264 textarea.value = this.filteredLogs.join('\n');
265 document.body.appendChild(textarea);
266 textarea.select();
267 document.execCommand("copy");
268 document.body.removeChild(textarea);
269 this.copyMessage = 'Copied!';
270 setTimeout(() => {
271 this.copyMessage = "";
272 }, 2000);
273 }
274 },
275 }
276 };
277
278 export default Modals;
279