@everymatrix/cashier-method-details 1.24.0 → 1.24.4

Sign up to get free protection for your applications and to get access to all the features.
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.4",
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": "6b5a6d6584217df74f6dfeed6858faa39a7f971d"
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;