inviton-powerduck 0.0.136 → 0.0.138

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.
Files changed (39) hide show
  1. package/app/powerduck-system-resources.ts +2 -0
  2. package/common/css/ladda-themeless-zoomin.min.css +89 -89
  3. package/common/dialog-utils.ts +1 -1
  4. package/common/external-barcode-scanner.ts +0 -1
  5. package/common/utils/array-extend.ts +32 -29
  6. package/common/utils/broswer-image-compression.ts +1 -1
  7. package/common/utils/language-utils.ts +3 -1
  8. package/components/app/vue-plugin-jsxtransform.ts +1 -1
  9. package/components/bootstrap-toggle/index.tsx +6 -1
  10. package/components/chart-js/pie-chart.tsx +1 -1
  11. package/components/chart-js/thirdparty/flot/jquery.flot.categories.min.js +93 -93
  12. package/components/chart-js/thirdparty/flot/jquery.flot.crosshair.min.js +83 -83
  13. package/components/chart-js/thirdparty/flot/jquery.flot.navigate.min.js +270 -270
  14. package/components/chart-js/thirdparty/flot/jquery.flot.pie.min.js +507 -507
  15. package/components/chart-js/thirdparty/flot/jquery.flot.resize.min.js +147 -147
  16. package/components/chart-js/thirdparty/flot/jquery.flot.stack.min.js +104 -104
  17. package/components/datatable/datatable-static.tsx +5 -5
  18. package/components/datatable/datatable.tsx +1 -1
  19. package/components/datatable/ts/reorder.ts +0 -2
  20. package/components/dropdown/currency-code-picker.tsx +42 -39
  21. package/components/dropdown/index.tsx +2 -1
  22. package/components/fullcalendar/timegrid-calendar.tsx +1 -1
  23. package/components/image-crop/image-cropping-modal.tsx +54 -15
  24. package/components/image-crop/upload-and-crop.tsx +21 -13
  25. package/components/image-crop/vendor/jquery.Jcrop.min.css +344 -344
  26. package/components/import/import-mapper.tsx +231 -231
  27. package/components/input/localized-info-input.tsx +9 -0
  28. package/components/input/localized-string-input.tsx +21 -0
  29. package/components/input/localized-string-textarea.tsx +16 -0
  30. package/components/input/localized-string-wysiwyg.tsx +16 -0
  31. package/components/input/plugins/daterangepicker/daterangepicker.min.css +400 -400
  32. package/components/input/plugins/daterangepicker/jquery.daterangepicker.min.js +1903 -1903
  33. package/components/input/translate.tsx +100 -0
  34. package/components/modal/modal.tsx +1 -1
  35. package/components/photos/photo-manager.tsx +7 -11
  36. package/components/share/share-modal.tsx +1 -1
  37. package/components/share/share.tsx +1 -1
  38. package/components/svg/skilift-svg.tsx +6 -6
  39. package/package.json +2 -1
@@ -329,7 +329,7 @@ class TimegridCalendarComponent extends TsxComponent<TimegridCalendarArgs> imple
329
329
  resourceGroupField: 'building',
330
330
  events: this.getEvents(),
331
331
  eventRender: (args) => {
332
- console.log('rendering');
332
+ // console.log('rendering');
333
333
  args.el.classList.add('tg-has-menu');
334
334
  args.el.setAttribute('data-uuid', args.event.extendedProps.uuid);
335
335
  args.el.setAttribute('data-event-id', args.event.id);
@@ -99,7 +99,7 @@ class ImageCropModalComponent extends TsxComponent<ImageCropModalBindingArgs> im
99
99
  const start = new Date().getTime();
100
100
  const img = new Image();
101
101
  img.onload = function () {
102
- const waitForLoad = function (callback) {
102
+ const waitForLoad = (callback) => {
103
103
  if (new Date().getTime() - start > 700) {
104
104
  callback();
105
105
  } else {
@@ -150,18 +150,6 @@ class ImageCropModalComponent extends TsxComponent<ImageCropModalBindingArgs> im
150
150
  (this.$refs.imageCropModal as typeof Modal.prototype).hide();
151
151
  }
152
152
 
153
- private getImageFormat(dataUrl): string {
154
- if (dataUrl.length > 100) {
155
- dataUrl = dataUrl.substring(0, 100);
156
- }
157
-
158
- if (dataUrl.contains('image/png')) {
159
- return 'image/png';
160
- } else {
161
- return 'image/jpeg';
162
- }
163
- }
164
-
165
153
  private handleSaveButtonClicked() {
166
154
  this.blocked = true;
167
155
 
@@ -169,7 +157,6 @@ class ImageCropModalComponent extends TsxComponent<ImageCropModalBindingArgs> im
169
157
  const canvas = this.$refs.imageCropCanvas as HTMLCanvasElement;
170
158
  const ctx = canvas.getContext('2d');
171
159
  const selection = this.getCurrentSelection();
172
-
173
160
  image.src = this.getFileName();
174
161
  image.onload = async () => {
175
162
  this.drawCroppedImageOnCanvas(
@@ -196,7 +183,7 @@ class ImageCropModalComponent extends TsxComponent<ImageCropModalBindingArgs> im
196
183
  this.blocked = false;
197
184
  }, 500);
198
185
  },
199
- this.getImageFormat(image.src),
186
+ await this.getImageFormat(image.src),
200
187
  0.9,
201
188
  );
202
189
  };
@@ -272,6 +259,58 @@ class ImageCropModalComponent extends TsxComponent<ImageCropModalBindingArgs> im
272
259
  }
273
260
  }
274
261
 
262
+ private async getImageFormat(url: string): Promise<string | null> {
263
+ const response = await fetch(url, { mode: 'cors' });
264
+ if (!response.ok) {
265
+ throw new Error('Failed to fetch image');
266
+ }
267
+
268
+ const buffer = await response.arrayBuffer();
269
+ const bytes = new Uint8Array(buffer);
270
+
271
+ if (
272
+ bytes[0] === 0x89
273
+ && bytes[1] === 0x50
274
+ && bytes[2] === 0x4E
275
+ && bytes[3] === 0x47
276
+ ) {
277
+ return 'image/png';
278
+ }
279
+
280
+ if (
281
+ bytes[0] === 0xFF
282
+ && bytes[1] === 0xD8
283
+ && bytes[bytes.length - 2] === 0xFF
284
+ && bytes[bytes.length - 1] === 0xD9
285
+ ) {
286
+ return 'image/jpeg';
287
+ }
288
+
289
+ if (
290
+ bytes[0] === 0x47
291
+ && bytes[1] === 0x49
292
+ && bytes[2] === 0x46
293
+ && bytes[3] === 0x38
294
+ ) {
295
+ return 'image/gif';
296
+ }
297
+
298
+ if (
299
+ bytes[0] === 0x52
300
+ && bytes[1] === 0x49
301
+ && bytes[2] === 0x46
302
+ && bytes[3] === 0x46
303
+ && bytes[8] === 0x57
304
+ && bytes[9] === 0x45
305
+ && bytes[10] === 0x42
306
+ && bytes[11] === 0x50
307
+ ) {
308
+ return 'image/webp';
309
+ }
310
+
311
+ return null;
312
+ }
313
+
275
314
  private getCurrentSelection(): ImageCropSelection {
276
315
  const img = $(this.getImageElement()).first();
277
316
  const cropHolder = $(this.$refs.imageCroppingContainer).find('.jcrop-active').first();
@@ -2,8 +2,11 @@ import type { _ButtonArgsBase, ButtonLayout, ButtonSize } from '../button/button
2
2
  import type { UploadButtonFileObtainedArgs } from '../button/upload-button';
3
3
  import type { ImageCroppedUploadArgs } from './image-cropping-modal';
4
4
  import { Prop, toNative } from 'vue-facing-decorator';
5
+ import PowerduckState from '../../app/powerduck-state';
5
6
  import TsxComponent, { Component } from '../../app/vuetsx';
6
7
  import { BrowserImageCompression } from '../../common/utils/broswer-image-compression';
8
+ import { formatString } from '../../common/utils/format-string';
9
+ import { PortalUtils } from '../../common/utils/utils';
7
10
  import UploadButton from '../button/upload-button';
8
11
  import LoadingIndicator from '../loading-indicator';
9
12
  import NotificationProvider from '../ui/notification';
@@ -27,6 +30,7 @@ interface UploadImageAndCropButtonArgs extends _ButtonArgsBase {
27
30
  uploadComplete: (args: any) => void;
28
31
  autoCommit?: boolean;
29
32
  disableCompression?: boolean;
33
+ allowedTypes?: string[];
30
34
  compressionMaxSizeMb?: number;
31
35
  isLoading?: boolean;
32
36
  }
@@ -54,6 +58,7 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
54
58
  @Prop() uploadComplete: (args: any) => void;
55
59
  @Prop() autoCommit: boolean;
56
60
  @Prop() disableCompression: boolean;
61
+ @Prop() allowedTypes: string[];
57
62
  @Prop() compressionMaxSizeMb?: number;
58
63
  isInternalLoading: boolean = false;
59
64
 
@@ -61,6 +66,11 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
61
66
  const urlCreator = window.URL || window.webkitURL;
62
67
  const imgUrl = urlCreator.createObjectURL(e.file);
63
68
 
69
+ if (this.allowedTypes?.length > 0 && !this.allowedTypes.includes(e.file.type)) {
70
+ NotificationProvider.showErrorMessage(formatString(PowerduckState.getResourceValue('uploadImageInvalidFileType'), PortalUtils.htmlEscape(this.allowedTypes.join(', '))));
71
+ return;
72
+ }
73
+
64
74
  if (this.useCropper != false) {
65
75
  (this.$refs.imgCrop as typeof ImageCropModal.prototype).show({
66
76
  fileName: e.file.name,
@@ -78,9 +88,9 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
78
88
  file: e.file,
79
89
  fileName: e.file.name,
80
90
  dataUrl: null,
81
- }).then((resp) => {
91
+ }).then(() => {
82
92
  this.isInternalLoading = false;
83
- }).catch((err) => {
93
+ }).catch((_err) => {
84
94
  this.isInternalLoading = false;
85
95
  });
86
96
  }
@@ -91,8 +101,6 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
91
101
  }
92
102
 
93
103
  async getUploadPromise(args: ImageCroppedUploadArgs): Promise<any> {
94
- const self = this;
95
-
96
104
  if (!(this.disableCompression || args.file.type == 'image/svg+xml')) {
97
105
  args.file = await BrowserImageCompression.compress(args.file, {
98
106
  maxSizeMB: this.compressionMaxSizeMb,
@@ -101,8 +109,8 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
101
109
 
102
110
  return new Promise((resolve, reject) => {
103
111
  const formData = new FormData();
104
- if (self.uploadArgs != null) {
105
- const argsVal = self.uploadArgs(args);
112
+ if (this.uploadArgs != null) {
113
+ const argsVal = this.uploadArgs(args);
106
114
  if (argsVal != null) {
107
115
  for (const key in argsVal) {
108
116
  formData.append(key, argsVal[key]);
@@ -110,10 +118,10 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
110
118
  }
111
119
  }
112
120
 
113
- if (self.autoCommit === true) {
121
+ if (this.autoCommit === true) {
114
122
  const request = new XMLHttpRequest();
115
- request.open('POST', self.uploadUrl);
116
- request.onreadystatechange = function () {
123
+ request.open('POST', this.uploadUrl);
124
+ request.onreadystatechange = () => {
117
125
  if (request.readyState == 4) {
118
126
  let response;
119
127
  try {
@@ -123,8 +131,8 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
123
131
  }
124
132
 
125
133
  if (request.status == 200) {
126
- if (self.uploadComplete) {
127
- self.uploadComplete(response);
134
+ if (this.uploadComplete) {
135
+ this.uploadComplete(response);
128
136
  }
129
137
 
130
138
  resolve(response);
@@ -144,8 +152,8 @@ class UploadImageAndCropButtonComponent extends TsxComponent<UploadImageAndCropB
144
152
 
145
153
  request.send(formData);
146
154
  } else {
147
- const argsVal = self.uploadArgs(args);
148
- self.uploadComplete(argsVal);
155
+ const argsVal = this.uploadArgs(args);
156
+ this.uploadComplete(argsVal);
149
157
  resolve(formData);
150
158
  }
151
159
  });