@webitel/ui-sdk 26.2.96 → 26.2.98

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": "@webitel/ui-sdk",
3
- "version": "26.2.96",
3
+ "version": "26.2.98",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "make-all": "npm version patch --git-tag-version false && npm run build && (npm run build:types || true) && (npm run biome:format:all || true) && npm run publish-lib",
@@ -305,6 +305,10 @@
305
305
  "types": "./types/modules*",
306
306
  "import": "./src/modules*"
307
307
  },
308
+ "./modules/FilesExport": {
309
+ "types": "./types/modules/FilesExport/v2/index.d.ts",
310
+ "import": "./src/modules/FilesExport/v2/index.ts"
311
+ },
308
312
  "./modules/CallSession": {
309
313
  "types": "./types/modules/CallSession/index.d.ts",
310
314
  "import": "./src/modules/CallSession/index.ts"
@@ -0,0 +1,132 @@
1
+ import JSZip from 'jszip';
2
+ import { ref } from 'vue';
3
+ import { _wtUiLog } from '../../../../scripts/logger';
4
+ import { UseFilesExportOptions, UseFilesExportReturn } from '../types/types';
5
+ import { fetchFileBinary, handleMimeType, saveZip } from '../utils/utils';
6
+
7
+ export const useFilesExportProgress = () => {
8
+ const isLoading = ref(false);
9
+ const downloadStatus = ref<{
10
+ count: number;
11
+ }>({
12
+ count: 0,
13
+ });
14
+ const zippingStatus = ref<{
15
+ percent: number;
16
+ }>({
17
+ percent: 0,
18
+ });
19
+
20
+ const updateDownloadStatus = (count: number) => {
21
+ downloadStatus.value = {
22
+ count,
23
+ };
24
+ };
25
+ const updateZippingStatus = (percent: number) => {
26
+ zippingStatus.value = {
27
+ percent,
28
+ };
29
+ };
30
+
31
+ const start = () => {
32
+ isLoading.value = true;
33
+ };
34
+
35
+ const reset = () => {
36
+ isLoading.value = false;
37
+ downloadStatus.value = {
38
+ count: 0,
39
+ };
40
+ zippingStatus.value = {
41
+ percent: 0,
42
+ };
43
+ };
44
+
45
+ return {
46
+ isLoading,
47
+ downloadStatus,
48
+ zippingStatus,
49
+
50
+ start,
51
+ updateDownloadStatus,
52
+ updateZippingStatus,
53
+ reset,
54
+ };
55
+ };
56
+
57
+ export const useFilesExport = ({
58
+ getFileURL,
59
+ fetch,
60
+ filename,
61
+ skipFilesWithError,
62
+ }: UseFilesExportOptions): UseFilesExportReturn => {
63
+ const {
64
+ isLoading,
65
+ downloadStatus,
66
+ zippingStatus,
67
+ start: startProgress,
68
+ updateDownloadStatus,
69
+ updateZippingStatus,
70
+ reset: resetProgress,
71
+ } = useFilesExportProgress();
72
+
73
+ const fillZip = async (zip: JSZip) => {
74
+ let page = 1;
75
+ let hasNext = true;
76
+ do {
77
+ const { items, next } = await fetch({
78
+ page,
79
+ size: 1000,
80
+ });
81
+ for (const item of items) {
82
+ try {
83
+ const binary = await fetchFileBinary(getFileURL(item));
84
+ const itemFilename = handleMimeType(item);
85
+ zip.file(itemFilename, binary);
86
+ updateDownloadStatus(downloadStatus.value.count + 1);
87
+ } catch (err) {
88
+ _wtUiLog.warn({
89
+ entity: 'script',
90
+ module: 'FilesExport',
91
+ })(`An error occurred while downloading a file id=${item.id}`, err);
92
+ if (!skipFilesWithError) {
93
+ throw err;
94
+ }
95
+ }
96
+ }
97
+ hasNext = next;
98
+ page++;
99
+ } while (hasNext);
100
+ };
101
+
102
+ const generateZip = async (zip: JSZip): Promise<Blob> => {
103
+ return zip.generateAsync(
104
+ {
105
+ type: 'blob',
106
+ },
107
+ (progress) => {
108
+ updateZippingStatus(progress.percent);
109
+ },
110
+ );
111
+ };
112
+
113
+ const exportFiles = async () => {
114
+ startProgress();
115
+ try {
116
+ const zip = new JSZip();
117
+ await fillZip(zip);
118
+ const blob = await generateZip(zip);
119
+ saveZip(blob, filename);
120
+ } finally {
121
+ resetProgress();
122
+ }
123
+ };
124
+
125
+ return {
126
+ isLoading,
127
+ downloadStatus,
128
+ zippingStatus,
129
+
130
+ exportFiles,
131
+ };
132
+ };
@@ -0,0 +1 @@
1
+ export { useFilesExport } from './composables/useFilesExport';
@@ -0,0 +1,30 @@
1
+ import { Ref } from 'vue';
2
+
3
+ export type ExportedItem = {
4
+ name: string; // file name inside zip
5
+ mimeType?: string;
6
+ } & Record<string, unknown>;
7
+
8
+ export type UseFilesExportOptions = {
9
+ getFileURL: (item: ExportedItem) => string;
10
+ fetch: ({ page, size }: { page: number; size?: number }) => Promise<{
11
+ items: ExportedItem[];
12
+ next: boolean;
13
+ }>;
14
+ filename?: string;
15
+ skipFilesWithError?: boolean;
16
+ };
17
+
18
+ export type FilesExportProgressStatus = {
19
+ isLoading: Ref<boolean>;
20
+ downloadStatus: Ref<{
21
+ count: number;
22
+ }>;
23
+ zippingStatus: Ref<{
24
+ percent: number;
25
+ }>;
26
+ };
27
+
28
+ export type UseFilesExportReturn = {
29
+ exportFiles: () => Promise<void>;
30
+ } & FilesExportProgressStatus;
@@ -0,0 +1,31 @@
1
+ import { saveAs } from 'file-saver-es';
2
+ import jszipUtils from 'jszip-utils';
3
+
4
+ import type { ExportedItem } from '../types/types';
5
+
6
+ export function saveZip(blob: Blob, filename: string) {
7
+ saveAs(blob, `${filename}.zip`);
8
+ }
9
+
10
+ export function fetchFileBinary(url: string): Promise<string | ArrayBuffer> {
11
+ return new Promise((resolve, reject) => {
12
+ jszipUtils.getBinaryContent(url, (err, data) => {
13
+ if (err) reject(err);
14
+ else resolve(data);
15
+ });
16
+ });
17
+ }
18
+
19
+ export function handleMimeType(item: ExportedItem): string {
20
+ const assertedExt = item.name.split('.').pop();
21
+ const nameWithoutExt = assertedExt
22
+ ? item.name.split('.').slice(0, -1).join('.')
23
+ : item.name;
24
+ const mimeExt = item.mimeType?.split('/').pop();
25
+ if (assertedExt) {
26
+ return `${nameWithoutExt}.${assertedExt}`;
27
+ } else if (mimeExt) {
28
+ return `${nameWithoutExt}.${mimeExt}`;
29
+ }
30
+ return nameWithoutExt;
31
+ }
@@ -0,0 +1,23 @@
1
+ import { UseFilesExportOptions, UseFilesExportReturn } from '../types/types';
2
+ export declare const useFilesExportProgress: () => {
3
+ isLoading: import("vue").Ref<boolean, boolean>;
4
+ downloadStatus: import("vue").Ref<{
5
+ count: number;
6
+ }, {
7
+ count: number;
8
+ } | {
9
+ count: number;
10
+ }>;
11
+ zippingStatus: import("vue").Ref<{
12
+ percent: number;
13
+ }, {
14
+ percent: number;
15
+ } | {
16
+ percent: number;
17
+ }>;
18
+ start: () => void;
19
+ updateDownloadStatus: (count: number) => void;
20
+ updateZippingStatus: (percent: number) => void;
21
+ reset: () => void;
22
+ };
23
+ export declare const useFilesExport: ({ getFileURL, fetch, filename, skipFilesWithError, }: UseFilesExportOptions) => UseFilesExportReturn;
@@ -0,0 +1 @@
1
+ export { useFilesExport } from './composables/useFilesExport';
@@ -0,0 +1,29 @@
1
+ import { Ref } from 'vue';
2
+ export type ExportedItem = {
3
+ name: string;
4
+ mimeType?: string;
5
+ } & Record<string, unknown>;
6
+ export type UseFilesExportOptions = {
7
+ getFileURL: (item: ExportedItem) => string;
8
+ fetch: ({ page, size }: {
9
+ page: number;
10
+ size?: number;
11
+ }) => Promise<{
12
+ items: ExportedItem[];
13
+ next: boolean;
14
+ }>;
15
+ filename?: string;
16
+ skipFilesWithError?: boolean;
17
+ };
18
+ export type FilesExportProgressStatus = {
19
+ isLoading: Ref<boolean>;
20
+ downloadStatus: Ref<{
21
+ count: number;
22
+ }>;
23
+ zippingStatus: Ref<{
24
+ percent: number;
25
+ }>;
26
+ };
27
+ export type UseFilesExportReturn = {
28
+ exportFiles: () => Promise<void>;
29
+ } & FilesExportProgressStatus;
@@ -0,0 +1,4 @@
1
+ import type { ExportedItem } from '../types/types';
2
+ export declare function saveZip(blob: Blob, filename: string): void;
3
+ export declare function fetchFileBinary(url: string): Promise<string | ArrayBuffer>;
4
+ export declare function handleMimeType(item: ExportedItem): string;