@everymatrix/cashier-method-details 1.24.0 → 1.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everymatrix/cashier-method-details",
3
- "version": "1.24.0",
3
+ "version": "1.24.1",
4
4
  "main": "index.js",
5
5
  "svelte": "src/index.ts",
6
6
  "scripts": {
@@ -35,5 +35,5 @@
35
35
  "publishConfig": {
36
36
  "access": "public"
37
37
  },
38
- "gitHead": "88308bab2d4819ec71d025befe5d4165e8c092ca"
38
+ "gitHead": "1028027aa2cfe5775cbb4df0feb2b56d0143d3f6"
39
39
  }
@@ -1,4 +1,5 @@
1
1
  <svelte:options tag={null} />
2
+
2
3
  <script lang="ts">
3
4
  import { onMount } from "svelte";
4
5
  import { _, addNewMessages, setupI18n, setLocale } from './i18n';
@@ -9,6 +10,77 @@
9
10
  import '@everymatrix/cashier-notifications'
10
11
 
11
12
  import type {PaymentMethod} from "./CashierMethodDetails.types";
13
+ export class PaymentMethodDetails {
14
+ name: string;
15
+ label: string;
16
+ description: string;
17
+ type: number;
18
+ defaultValue: any;
19
+ format: string;
20
+ placeholder: string;
21
+ displayPlaceholder?: string;
22
+ isReadonly: boolean;
23
+ isRequired: boolean;
24
+ isPrimaryField: boolean;
25
+ demandUserInput: boolean;
26
+ autoTrim: boolean;
27
+ maxValue: string;
28
+ minValue: string;
29
+ autoUppercase: boolean;
30
+ correlationFieldName: string;
31
+ correlationFieldValue: string[];
32
+ notEqualToFieldName: string;
33
+ values: any[];
34
+ selected: Object;
35
+ useCopyButton: boolean;
36
+ inputMask: string[];
37
+ tags: string;
38
+ constructor(element: any) {
39
+ this.correlationFieldName = element.CorrelationFieldName || null;
40
+ this.correlationFieldValue = element.CorrelationFieldValue && element.CorrelationFieldValue.length > 0 ?
41
+ element.CorrelationFieldValue.split(',') : [];
42
+ this.name = element.Name || null;
43
+ this.label = element.Label || null;
44
+ this.description = element.Description || null;
45
+ this.type = element.Type || null;
46
+ this.defaultValue = this.calcDefaultValue(element);
47
+ this.format = element.Format || null;
48
+ this.placeholder = element.Placeholder || null;
49
+ this.isReadonly = element.IsReadonly || false;
50
+ this.isRequired = element.IsRequired || false;
51
+ this.maxValue = element.MaxValue || null;
52
+ this.minValue = element.MinValue || null;
53
+ this.isPrimaryField = element.IsPrimaryField || false;
54
+ this.demandUserInput = element.DemandUserInput || false;
55
+ this.autoTrim = element.AutoTrim || false;
56
+ this.autoUppercase = element.AutoUppercase || false;
57
+ this.notEqualToFieldName = element.NotEqualToFieldName || null;
58
+ this.values = element.Values;
59
+ this.useCopyButton = element.UseCopyButton || false;
60
+ this.inputMask = element.InputMask;
61
+ this.tags = element.Tags || null;
62
+ }
63
+
64
+ calcDefaultValue(element) {
65
+ if (this.type === 2) {
66
+ return element.DefaultValue === 'True';
67
+ } else {
68
+ return element.DefaultValue || null;
69
+ }
70
+ }
71
+ get descriptionWithLink(): string {
72
+ if ((FieldTypes[this.type] === 'Boolean' && this.placeholder) || (FieldTypes[this.type] === 'Link')) {
73
+ const regex = /{link}/i;
74
+ const link = this.placeholder || this.defaultValue;
75
+ const html = `<a href="${link}" target="_blank" rel="noopener noreferrer">${this.label}</a>`;
76
+ if (this.description.match(regex)) {
77
+ return this.description.replace(regex, html);
78
+ }
79
+ return `${this.description} ${html}`;
80
+ }
81
+ return this.description
82
+ }
83
+ }
12
84
 
13
85
  export enum FieldTypes {
14
86
  Unknown ='Unknown',
@@ -28,7 +100,7 @@
28
100
  Link = 'Link',
29
101
  Image = 'Image',
30
102
  Html = 'Html',
31
- QRCod = 'QRCode'
103
+ QRCode = 'QR'
32
104
  }
33
105
  export let endpoint: string;
34
106
  export let session: string;
@@ -50,7 +122,7 @@
50
122
 
51
123
  let xPaymentSessionToken: string;
52
124
  let selectedPaymentMethod: PaymentMethod = {} as PaymentMethod;
53
- let fields = [];
125
+ let fields: PaymentMethodDetails[] = [];
54
126
  let prepareFields = {};
55
127
  let isLoading:boolean = false;
56
128
  let isMethodOpen:boolean = false;
@@ -67,12 +139,31 @@
67
139
  let isTranslationLoaded: boolean;
68
140
  let openedLookup: number | null;
69
141
  let clickedElem: HTMLElement;
142
+ let qrCodeContainer: HTMLElement[] = [];
143
+ let qrCodeScriptSrc: string = 'https://cdn.rawgit.com/davidshimjs/qrcodejs/gh-pages/qrcode.min.js';
144
+ let blankPageTarget: string = '_blank';
145
+ let externalLink: string = '';
146
+
70
147
  $: endpoint && session && selectedpaymentmethodname && currency && getPaymentDetails();
71
148
  $: clientstyling && customStylingContainer && setClientStyling();
72
149
  $: clientstylingurl && customStylingContainer && setClientStylingURL();
73
150
  $: lang && setActiveLanguage();
74
151
  $: lang && translationurl && setTranslationUrl();
75
-
152
+ $: selectedpaymentmethodname && qrCodeContainer.length && generateQr();
153
+
154
+ const generateQr = () => {
155
+ qrCodeContainer.forEach(elem => {
156
+ if (elem && elem.innerText) {
157
+ const url = elem.innerText
158
+ elem.innerText = ''
159
+ new QRCode(elem, {
160
+ text: url,
161
+ width: 250,
162
+ height: 250,
163
+ });
164
+ }
165
+ })
166
+ }
76
167
  const setActiveLanguage = ():void => {
77
168
  setLocale(lang);
78
169
  }
@@ -113,7 +204,7 @@
113
204
  fetch(url, requestParams).then(res => res.json()).then(data => {
114
205
  xPaymentSessionToken = data.XPaymentSessionToken;
115
206
  selectedPaymentMethod = data.PaymentMethod;
116
- fields = selectedPaymentMethod.Fields;
207
+ fields = selectedPaymentMethod.Fields && selectedPaymentMethod.Fields.map(field => new PaymentMethodDetails(field));
117
208
  prepareFields = {};
118
209
  })
119
210
  }
@@ -238,14 +329,21 @@
238
329
  showRetryNotification = false;
239
330
  }
240
331
 
241
- const showField = (field) => {
242
- return !field.CorrelationFieldName || (field.CorrelationFieldName && prepareFields[field.CorrelationFieldName] === field.CorrelationFieldValue)
332
+ const openUrlInNewTab = (url) => {
333
+ if (!url) {
334
+ return
335
+ }
336
+ window.postMessage({ type: 'NavigateTo', path: url, target: blankPageTarget || null, externalLink: externalLink || false }, window.location.href);
243
337
  }
244
338
 
339
+ const showField = (field) => {
340
+ return !field.correlationFieldName || (field.correlationFieldName && prepareFields[field.correlationFieldName] === field.correlationFieldValue)
341
+ }
245
342
 
246
343
  </script>
247
-
248
-
344
+ <svelte:head>
345
+ <script src={qrCodeScriptSrc}></script>
346
+ </svelte:head>
249
347
  <div class="CashierMethodDetails">
250
348
  {#if isTranslationLoaded && selectedPaymentMethod.Name}
251
349
  <div class="MethodsDetails">
@@ -284,39 +382,53 @@
284
382
  </div>
285
383
  {#each fields as field, index}
286
384
  {#if showField(field)}
287
- <div class="FieldWrapper" class:Hidden={field.Type === FieldTypes.Hidden}>
385
+ <div class="FieldWrapper" class:Hidden={field.type === FieldTypes.Hidden}>
288
386
  <label>
289
- <span class:Required={field.IsRequired}>{field.Label}</span>
290
- {#if field.Description && field.Description !== field.Label}
291
- <span class="Description">{field.Description}</span>
387
+ {#if field.label && field.type !== FieldTypes.Link && field.type !== FieldTypes.Boolean}
388
+ <span class:Required={field.isRequired}>{field.label}</span>
389
+ {/if}
390
+ {#if field.description && field.description !== field.label && field.type !== FieldTypes.QRCode && field.type !== FieldTypes.Boolean && field.type !== FieldTypes.Link}
391
+ <span class="Description">{field.description}</span>
292
392
  {/if}
293
- {#if field.Type === FieldTypes.Text}
294
- <input type="text" bind:value={prepareFields[field.Name]} placeholder="{field.Placeholder}">
393
+ {#if field.type === FieldTypes.Text}
394
+ <input type="text" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
295
395
 
296
- {:else if field.Type === FieldTypes.Number || field.Type === FieldTypes.Money}
297
- <input type="number" placeholder="{field.Placeholder}" bind:value={prepareFields[field.Name]}>
396
+ {:else if field.type === FieldTypes.Number || field.type === FieldTypes.Money}
397
+ <input type="number" placeholder="{field.placeholder}" bind:value={prepareFields[field.name]}>
298
398
 
299
- {:else if field.Type === FieldTypes.Password}
300
- <input type="password" bind:value={prepareFields[field.Name]} placeholder="{field.Placeholder}">
399
+ {:else if field.type === FieldTypes.Password}
400
+ <input type="password" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
301
401
 
302
- {:else if field.Type === FieldTypes.Hidden}
303
- <input type="hidden" bind:value={prepareFields[field.Name]} placeholder="{field.Placeholder}">
402
+ {:else if field.type === FieldTypes.Hidden}
403
+ <input type="hidden" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
304
404
 
305
- {:else if field.Type === FieldTypes.Lookup}
405
+ {:else if field.type === FieldTypes.Lookup}
306
406
  <div class="CustomSelect">
307
- <div class="Selected" id="{index}" on:click="{(e) => showLookup(e,index)}">{prepareFields[field.Name] || ''}</div>
407
+ <div class="Selected" id="{index}" on:click="{(e) => showLookup(e,index)}">{prepareFields[field.name] || ''}</div>
308
408
  <div class="OptionList" class:Opened={openedLookup === index}>
309
- {#each field.Values as value}
310
- <div on:click="{() => {prepareFields[field.Name] = value.Name; fields = fields}}">
311
- <span>{value.Value}</span>
409
+ {#each field.values as value}
410
+ <div on:click="{() => {prepareFields[field.name] = value.name; fields = fields}}">
411
+ <span>{value.value}</span>
312
412
  </div>
313
413
  {/each}
314
414
  </div>
315
415
  </div>
316
- {:else if field.Type === FieldTypes.Boolean}
317
- <input type="checkbox" bind:value={prepareFields[field.Name]} placeholder="{field.Placeholder}">
416
+ {:else if field.type === FieldTypes.Boolean}
417
+ <div class="Checkbox">
418
+ <input type="checkbox" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
419
+ <span class="Checkmark"></span>
420
+ <span class="Description">{@html field.descriptionWithLink}</span>
421
+ </div>
422
+ {:else if field.type === FieldTypes.QRCode}
423
+ <div class="QRCode" on:click={() => {openUrlInNewTab(field.description)}}>
424
+ <div bind:this={qrCodeContainer[qrCodeContainer.length]}>{field.defaultValue}</div>
425
+ </div>
426
+ {:else if field.type === FieldTypes.Link}
427
+ <span>{@html field.descriptionWithLink}</span>
428
+ {:else if field.type === FieldTypes.Label}
429
+ <span class="Label"></span>
318
430
  {:else}
319
- <input type="text" bind:value={prepareFields[field.Name]} placeholder="{field.Placeholder}">
431
+ <input type="text" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
320
432
  {/if}
321
433
  </label>
322
434
  </div>
@@ -486,6 +598,10 @@
486
598
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
487
599
  padding: 0 15px 15px;
488
600
  margin-bottom: 10px;
601
+ &:has(.QRCode, .Label) {
602
+ box-shadow: none;
603
+ background: transparent;
604
+ }
489
605
  &.Hidden {
490
606
  height: 0;
491
607
  visibility: hidden;
@@ -547,6 +663,67 @@
547
663
  animation: loading-spinner 1s linear infinite
548
664
  }
549
665
  }
666
+ .QRCode {
667
+ width: 250px;
668
+ margin: auto;
669
+ }
670
+ .Checkbox {
671
+ display: flex;
672
+ position: relative;
673
+ margin-top: 12px;
674
+
675
+ .Description {
676
+ margin: 0 0 0 20px;
677
+ cursor: pointer;
678
+ line-height: var( --emw--font-size-medium, 16px);
679
+ }
680
+
681
+ .Checkmark {
682
+ position: absolute;
683
+ top: 2px;
684
+ left: 0;
685
+ height: 12px;
686
+ width: 12px;
687
+ border: 1px solid var(--emw--color-gray-100, #E8E9EB);
688
+ border-radius: var(--emw--border-radius-medium, 4px);
689
+ background-color: var(--emw--color-white, #FFF);
690
+ cursor: pointer;
691
+
692
+ &:after {
693
+ content: "";
694
+ position: absolute;
695
+ display: none;
696
+ }
697
+
698
+ &:after {
699
+ left: 4px;
700
+ top: 0;
701
+ width: 2px;
702
+ height: 8px;
703
+ border: solid var(--emw--color-white, #FFF);
704
+ border-width: 0 2px 2px 0;
705
+ -webkit-transform: rotate(45deg);
706
+ -ms-transform: rotate(45deg);
707
+ transform: rotate(45deg);
708
+ }
709
+ }
710
+ input {
711
+ position: absolute;
712
+ opacity: 0;
713
+ cursor: pointer;
714
+ height: 0;
715
+ width: 0;
716
+
717
+ &:checked ~ .Checkmark {
718
+ background-color: var(--emw--color-primary, #7EC51E);
719
+ border-color: var(--emw--color-primary, #7EC51E);
720
+ }
721
+
722
+ &:checked ~ .Checkmark:after {
723
+ display: block;
724
+ }
725
+ }
726
+ }
550
727
  .CustomSelect {
551
728
  width: 100%;
552
729
  position: relative;