@servicemind.tis/tis-image-and-file-upload-and-view 1.2.16 → 1.2.19
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/fesm2022/servicemind.tis-tis-image-and-file-upload-and-view.mjs +794 -14
- package/fesm2022/servicemind.tis-tis-image-and-file-upload-and-view.mjs.map +1 -1
- package/lib/interfaces/index.d.ts +2 -0
- package/lib/interfaces/socket-adapter.interface.d.ts +258 -0
- package/lib/services/tis-remote-upload.service.d.ts +116 -0
- package/lib/tis-image-and-file-upload-and-view/tis-image-and-file-upload-and-view.component.d.ts +37 -6
- package/lib/tis-image-and-file-upload-and-view.module.d.ts +14 -12
- package/lib/tis-qr-code-dialog/tis-qr-code-dialog.component.d.ts +50 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
/**
|
|
3
|
+
* Interface that the host application must implement to enable
|
|
4
|
+
* remote upload functionality via WebSocket.
|
|
5
|
+
*
|
|
6
|
+
* This allows the library to leverage an existing WebSocket connection
|
|
7
|
+
* from the host application instead of creating its own.
|
|
8
|
+
*/
|
|
9
|
+
export interface TisSocketAdapter {
|
|
10
|
+
/**
|
|
11
|
+
* Subscribe to a channel and return an Observable of messages
|
|
12
|
+
* @param channelName - The channel name to subscribe to
|
|
13
|
+
* @returns Observable that emits messages received on the channel
|
|
14
|
+
*/
|
|
15
|
+
subscribeToChannel(channelName: string): Observable<any>;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to channels matching a prefix (optional)
|
|
18
|
+
* @param prefix - The prefix to match channel names
|
|
19
|
+
* @returns Observable that emits messages from matching channels
|
|
20
|
+
*/
|
|
21
|
+
subscribeToChannelPrefix?(prefix: string): Observable<any>;
|
|
22
|
+
/**
|
|
23
|
+
* Unsubscribe from a channel
|
|
24
|
+
* @param channelName - The channel name to unsubscribe from
|
|
25
|
+
*/
|
|
26
|
+
unsubscribeFromChannel?(channelName: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Send a message via the socket connection
|
|
29
|
+
* @param action - The action/route to call
|
|
30
|
+
* @param data - The data payload to send
|
|
31
|
+
* @returns Observable of the response (optional)
|
|
32
|
+
*/
|
|
33
|
+
callApi?(action: string, data: any): Observable<any>;
|
|
34
|
+
/**
|
|
35
|
+
* Get unique device/browser ID for pairing
|
|
36
|
+
* @returns Device ID string or Promise that resolves to device ID
|
|
37
|
+
*/
|
|
38
|
+
getDeviceId(): string | Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Check if socket is currently connected
|
|
41
|
+
* @returns true if connected, false otherwise
|
|
42
|
+
*/
|
|
43
|
+
isConnected(): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Observable that emits connection status changes
|
|
46
|
+
*/
|
|
47
|
+
connectionStatus$: Observable<boolean>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Configuration for remote upload feature
|
|
51
|
+
*/
|
|
52
|
+
export interface TisRemoteUploadConfig {
|
|
53
|
+
/**
|
|
54
|
+
* Enable/disable remote upload feature
|
|
55
|
+
*/
|
|
56
|
+
enabled: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Socket adapter implementation from host app
|
|
59
|
+
*/
|
|
60
|
+
socketAdapter?: TisSocketAdapter;
|
|
61
|
+
/**
|
|
62
|
+
* API endpoints for remote upload operations
|
|
63
|
+
*/
|
|
64
|
+
apiEndpoints?: TisRemoteUploadApiEndpoints;
|
|
65
|
+
/**
|
|
66
|
+
* QR code configuration
|
|
67
|
+
*/
|
|
68
|
+
qrCode?: TisQrCodeConfig;
|
|
69
|
+
/**
|
|
70
|
+
* Pairing configuration
|
|
71
|
+
*/
|
|
72
|
+
pairing?: TisPairingConfig;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* API endpoints configuration for remote upload
|
|
76
|
+
*/
|
|
77
|
+
export interface TisRemoteUploadApiEndpoints {
|
|
78
|
+
/**
|
|
79
|
+
* Endpoint to generate a pairing code
|
|
80
|
+
* POST request with deviceId, returns { pairingCode, channel, expiresAt }
|
|
81
|
+
*/
|
|
82
|
+
generatePairingCode: string;
|
|
83
|
+
/**
|
|
84
|
+
* Endpoint to validate a pairing code (used by mobile)
|
|
85
|
+
* POST request with pairingCode, returns { valid, deviceId, channel }
|
|
86
|
+
*/
|
|
87
|
+
validatePairingCode: string;
|
|
88
|
+
/**
|
|
89
|
+
* Endpoint called by mobile after uploading to notify desktop
|
|
90
|
+
* POST request with { channel, uploadedFile }
|
|
91
|
+
*/
|
|
92
|
+
notifyUpload?: string;
|
|
93
|
+
/**
|
|
94
|
+
* Channel prefix for receiving upload notifications
|
|
95
|
+
* Desktop subscribes to: {prefix}{deviceId}
|
|
96
|
+
*/
|
|
97
|
+
uploadChannelPrefix: string;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* QR code display configuration
|
|
101
|
+
*/
|
|
102
|
+
export interface TisQrCodeConfig {
|
|
103
|
+
/**
|
|
104
|
+
* Base URL for the mobile upload page
|
|
105
|
+
* The full URL will be: {mobileUploadUrl}?code={pairingCode}&deviceId={deviceId}
|
|
106
|
+
*/
|
|
107
|
+
mobileUploadUrl: string;
|
|
108
|
+
/**
|
|
109
|
+
* QR code expiry time in seconds (default: 300 = 5 minutes)
|
|
110
|
+
*/
|
|
111
|
+
expirySeconds?: number;
|
|
112
|
+
/**
|
|
113
|
+
* Size of the QR code in pixels (default: 200)
|
|
114
|
+
*/
|
|
115
|
+
size?: number;
|
|
116
|
+
/**
|
|
117
|
+
* Logo URL to display in the center of QR code (optional)
|
|
118
|
+
*/
|
|
119
|
+
logoUrl?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Pairing persistence configuration
|
|
123
|
+
*/
|
|
124
|
+
export interface TisPairingConfig {
|
|
125
|
+
/**
|
|
126
|
+
* Whether to persist pairing in localStorage (default: true)
|
|
127
|
+
*/
|
|
128
|
+
persistInStorage?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Storage key for pairing data (default: 'tis-remote-upload-pairing')
|
|
131
|
+
*/
|
|
132
|
+
storageKey?: string;
|
|
133
|
+
/**
|
|
134
|
+
* How long pairing remains valid in milliseconds (default: 24 hours)
|
|
135
|
+
* Set to 0 for session-only pairing
|
|
136
|
+
*/
|
|
137
|
+
pairingTTL?: number;
|
|
138
|
+
/**
|
|
139
|
+
* Whether to auto-reconnect on page reload if pairing exists
|
|
140
|
+
*/
|
|
141
|
+
autoReconnect?: boolean;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Pairing session data stored in localStorage
|
|
145
|
+
*/
|
|
146
|
+
export interface TisPairingSession {
|
|
147
|
+
/**
|
|
148
|
+
* Unique pairing code
|
|
149
|
+
*/
|
|
150
|
+
pairingCode: string;
|
|
151
|
+
/**
|
|
152
|
+
* Desktop device ID
|
|
153
|
+
*/
|
|
154
|
+
desktopDeviceId: string;
|
|
155
|
+
/**
|
|
156
|
+
* Mobile device ID (set after mobile connects)
|
|
157
|
+
*/
|
|
158
|
+
mobileDeviceId?: string;
|
|
159
|
+
/**
|
|
160
|
+
* WebSocket channel for communication
|
|
161
|
+
*/
|
|
162
|
+
channel: string;
|
|
163
|
+
/**
|
|
164
|
+
* When the pairing was created
|
|
165
|
+
*/
|
|
166
|
+
createdAt: number;
|
|
167
|
+
/**
|
|
168
|
+
* When the pairing expires
|
|
169
|
+
*/
|
|
170
|
+
expiresAt: number;
|
|
171
|
+
/**
|
|
172
|
+
* Current pairing status
|
|
173
|
+
*/
|
|
174
|
+
status: 'pending' | 'connected' | 'disconnected' | 'expired';
|
|
175
|
+
/**
|
|
176
|
+
* Last activity timestamp
|
|
177
|
+
*/
|
|
178
|
+
lastActivity?: number;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Event emitted when a remote upload is received
|
|
182
|
+
*/
|
|
183
|
+
export interface TisRemoteUploadEvent {
|
|
184
|
+
/**
|
|
185
|
+
* The uploaded file data
|
|
186
|
+
*/
|
|
187
|
+
file: TisRemoteUploadedFile;
|
|
188
|
+
/**
|
|
189
|
+
* Mobile device ID that uploaded the file
|
|
190
|
+
*/
|
|
191
|
+
mobileDeviceId: string;
|
|
192
|
+
/**
|
|
193
|
+
* Timestamp of the upload
|
|
194
|
+
*/
|
|
195
|
+
timestamp: number;
|
|
196
|
+
/**
|
|
197
|
+
* Session ID for grouping multiple uploads
|
|
198
|
+
*/
|
|
199
|
+
sessionId?: string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* File data received from remote upload
|
|
203
|
+
*/
|
|
204
|
+
export interface TisRemoteUploadedFile {
|
|
205
|
+
/**
|
|
206
|
+
* S3 or cloud storage URL of the uploaded file
|
|
207
|
+
*/
|
|
208
|
+
s3Url: string;
|
|
209
|
+
/**
|
|
210
|
+
* Original filename
|
|
211
|
+
*/
|
|
212
|
+
fileName: string;
|
|
213
|
+
/**
|
|
214
|
+
* File MIME type
|
|
215
|
+
*/
|
|
216
|
+
mimeType: string;
|
|
217
|
+
/**
|
|
218
|
+
* File size in bytes
|
|
219
|
+
*/
|
|
220
|
+
size: number;
|
|
221
|
+
/**
|
|
222
|
+
* Thumbnail URL (for images)
|
|
223
|
+
*/
|
|
224
|
+
thumbnailUrl?: string;
|
|
225
|
+
/**
|
|
226
|
+
* Additional metadata from the upload
|
|
227
|
+
*/
|
|
228
|
+
metadata?: Record<string, any>;
|
|
229
|
+
/**
|
|
230
|
+
* Upload data from presigned URL response
|
|
231
|
+
*/
|
|
232
|
+
uploadData?: any;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Message format for WebSocket communication
|
|
236
|
+
*/
|
|
237
|
+
export interface TisRemoteUploadMessage {
|
|
238
|
+
/**
|
|
239
|
+
* Message type
|
|
240
|
+
*/
|
|
241
|
+
type: 'pairing_request' | 'pairing_accepted' | 'upload_started' | 'upload_progress' | 'upload_complete' | 'upload_error' | 'disconnect';
|
|
242
|
+
/**
|
|
243
|
+
* Channel name
|
|
244
|
+
*/
|
|
245
|
+
channel: string;
|
|
246
|
+
/**
|
|
247
|
+
* Message payload
|
|
248
|
+
*/
|
|
249
|
+
payload: any;
|
|
250
|
+
/**
|
|
251
|
+
* Sender device ID
|
|
252
|
+
*/
|
|
253
|
+
senderId: string;
|
|
254
|
+
/**
|
|
255
|
+
* Timestamp
|
|
256
|
+
*/
|
|
257
|
+
timestamp: number;
|
|
258
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { OnDestroy } from '@angular/core';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
|
+
import { TisRemoteUploadConfig, TisPairingSession, TisRemoteUploadEvent, TisRemoteUploadedFile } from '../interfaces/socket-adapter.interface';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export declare class TisRemoteUploadService implements OnDestroy {
|
|
7
|
+
private http;
|
|
8
|
+
private destroy$;
|
|
9
|
+
private channelSubscription;
|
|
10
|
+
private config;
|
|
11
|
+
private socketAdapter;
|
|
12
|
+
private pairingSession$;
|
|
13
|
+
private connectionStatus$;
|
|
14
|
+
private remoteUpload$;
|
|
15
|
+
private error$;
|
|
16
|
+
constructor(http: HttpClient);
|
|
17
|
+
/**
|
|
18
|
+
* Configure the remote upload service
|
|
19
|
+
*/
|
|
20
|
+
configure(config: TisRemoteUploadConfig): void;
|
|
21
|
+
/**
|
|
22
|
+
* Get current pairing session
|
|
23
|
+
*/
|
|
24
|
+
getPairingSession(): Observable<TisPairingSession | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Get connection status
|
|
27
|
+
*/
|
|
28
|
+
getConnectionStatus(): Observable<'disconnected' | 'pending' | 'connected'>;
|
|
29
|
+
/**
|
|
30
|
+
* Get remote upload events
|
|
31
|
+
*/
|
|
32
|
+
getRemoteUploads(): Observable<TisRemoteUploadEvent>;
|
|
33
|
+
/**
|
|
34
|
+
* Get error events
|
|
35
|
+
*/
|
|
36
|
+
getErrors(): Observable<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if remote upload is available (configured and socket connected)
|
|
39
|
+
*/
|
|
40
|
+
isAvailable(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Check if currently paired with a mobile device
|
|
43
|
+
*/
|
|
44
|
+
isPaired(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Generate a new pairing code and QR data
|
|
47
|
+
*/
|
|
48
|
+
generatePairingCode(): Promise<{
|
|
49
|
+
qrData: string;
|
|
50
|
+
pairingCode: string;
|
|
51
|
+
expiresAt: number;
|
|
52
|
+
}>;
|
|
53
|
+
/**
|
|
54
|
+
* Validate a pairing code (used by mobile app)
|
|
55
|
+
*/
|
|
56
|
+
validatePairingCode(pairingCode: string): Promise<{
|
|
57
|
+
valid: boolean;
|
|
58
|
+
desktopDeviceId?: string;
|
|
59
|
+
channel?: string;
|
|
60
|
+
}>;
|
|
61
|
+
/**
|
|
62
|
+
* Disconnect and clear pairing
|
|
63
|
+
*/
|
|
64
|
+
disconnect(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Notify desktop about uploaded file (called by mobile)
|
|
67
|
+
*/
|
|
68
|
+
notifyUpload(channel: string, uploadedFile: TisRemoteUploadedFile, sessionId?: string): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Get device ID from socket adapter
|
|
71
|
+
*/
|
|
72
|
+
private getDeviceId;
|
|
73
|
+
/**
|
|
74
|
+
* Subscribe to a channel for receiving remote upload messages
|
|
75
|
+
*/
|
|
76
|
+
private subscribeToChannel;
|
|
77
|
+
/**
|
|
78
|
+
* Handle incoming channel messages
|
|
79
|
+
*/
|
|
80
|
+
private handleChannelMessage;
|
|
81
|
+
/**
|
|
82
|
+
* Handle pairing accepted from mobile
|
|
83
|
+
*/
|
|
84
|
+
private handlePairingAccepted;
|
|
85
|
+
/**
|
|
86
|
+
* Handle upload complete from mobile
|
|
87
|
+
*/
|
|
88
|
+
private handleUploadComplete;
|
|
89
|
+
/**
|
|
90
|
+
* Handle mobile disconnect
|
|
91
|
+
*/
|
|
92
|
+
private handleMobileDisconnect;
|
|
93
|
+
/**
|
|
94
|
+
* Call API endpoint
|
|
95
|
+
*/
|
|
96
|
+
private callApi;
|
|
97
|
+
/**
|
|
98
|
+
* Check if session is expired
|
|
99
|
+
*/
|
|
100
|
+
private isSessionExpired;
|
|
101
|
+
/**
|
|
102
|
+
* Save session to localStorage
|
|
103
|
+
*/
|
|
104
|
+
private saveSession;
|
|
105
|
+
/**
|
|
106
|
+
* Restore session from localStorage
|
|
107
|
+
*/
|
|
108
|
+
private restoreSession;
|
|
109
|
+
/**
|
|
110
|
+
* Clear stored session
|
|
111
|
+
*/
|
|
112
|
+
private clearStoredSession;
|
|
113
|
+
ngOnDestroy(): void;
|
|
114
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TisRemoteUploadService, never>;
|
|
115
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<TisRemoteUploadService>;
|
|
116
|
+
}
|
package/lib/tis-image-and-file-upload-and-view/tis-image-and-file-upload-and-view.component.d.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { EventEmitter, SimpleChanges } from '@angular/core';
|
|
2
|
-
import type { DialogConfig, FileViewerFileType, OptionConfig, UrlConfig } from '../interfaces';
|
|
1
|
+
import { EventEmitter, SimpleChanges, OnDestroy } from '@angular/core';
|
|
2
|
+
import type { DialogConfig, FileViewerFileType, OptionConfig, UrlConfig, TisRemoteUploadConfig, TisRemoteUploadEvent } from '../interfaces';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
4
|
import { MatDialog } from '@angular/material/dialog';
|
|
5
5
|
import { BreakpointObserver } from '@angular/cdk/layout';
|
|
6
6
|
import { TisHelperService } from '../services/tis-helper.service';
|
|
7
|
+
import { TisRemoteUploadService } from '../services/tis-remote-upload.service';
|
|
7
8
|
import { Config } from '../interfaces/config.type';
|
|
8
9
|
import { CdkDragDrop } from '@angular/cdk/drag-drop';
|
|
9
10
|
import * as i0 from "@angular/core";
|
|
10
|
-
export declare class TisImageAndFileUploadAndViewComponent {
|
|
11
|
+
export declare class TisImageAndFileUploadAndViewComponent implements OnDestroy {
|
|
11
12
|
dialog: MatDialog;
|
|
12
13
|
private helper;
|
|
13
14
|
private breakpointObserver;
|
|
15
|
+
private remoteUploadService;
|
|
14
16
|
private changeSubject;
|
|
17
|
+
private destroy$;
|
|
15
18
|
urlConfig: UrlConfig;
|
|
16
19
|
entityType: string;
|
|
17
20
|
entityId: any;
|
|
18
|
-
viewType: 'card' | 'list';
|
|
21
|
+
viewType: 'card' | 'list' | 'compact';
|
|
19
22
|
type: 'image' | 'file';
|
|
20
23
|
label: string | null;
|
|
21
24
|
disabled: boolean;
|
|
@@ -34,11 +37,13 @@ export declare class TisImageAndFileUploadAndViewComponent {
|
|
|
34
37
|
isEnableCapture: boolean;
|
|
35
38
|
deleteConfirmationMsg: string;
|
|
36
39
|
dialogConfig: DialogConfig;
|
|
40
|
+
remoteUploadConfig: TisRemoteUploadConfig | null;
|
|
37
41
|
uploadInProgress: EventEmitter<any>;
|
|
38
42
|
onUploaded: EventEmitter<any>;
|
|
39
43
|
onFileSelect: EventEmitter<any>;
|
|
40
44
|
onFileRemoved: EventEmitter<any>;
|
|
41
45
|
onError: EventEmitter<any>;
|
|
46
|
+
onRemoteUpload: EventEmitter<TisRemoteUploadEvent>;
|
|
42
47
|
isShowImageSequence: boolean;
|
|
43
48
|
enableDragNDrop: boolean;
|
|
44
49
|
dataSequenceChange: EventEmitter<any>;
|
|
@@ -54,7 +59,7 @@ export declare class TisImageAndFileUploadAndViewComponent {
|
|
|
54
59
|
images: never[];
|
|
55
60
|
loading: boolean;
|
|
56
61
|
status: boolean;
|
|
57
|
-
constructor(dialog: MatDialog, helper: TisHelperService, breakpointObserver: BreakpointObserver);
|
|
62
|
+
constructor(dialog: MatDialog, helper: TisHelperService, breakpointObserver: BreakpointObserver, remoteUploadService: TisRemoteUploadService);
|
|
58
63
|
ngOnInit(): void;
|
|
59
64
|
ngAfterViewInit(): void;
|
|
60
65
|
ngOnChanges(changes: SimpleChanges): void;
|
|
@@ -100,6 +105,32 @@ export declare class TisImageAndFileUploadAndViewComponent {
|
|
|
100
105
|
drop(event: CdkDragDrop<any[]>): void;
|
|
101
106
|
updateSequence(isShowMessage?: boolean): void;
|
|
102
107
|
getTagsArray(tags: string): any[];
|
|
108
|
+
/**
|
|
109
|
+
* Check if remote upload is available and configured
|
|
110
|
+
*/
|
|
111
|
+
isRemoteUploadAvailable(): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Initialize remote upload configuration
|
|
114
|
+
* Call this in ngOnInit or when config changes
|
|
115
|
+
*/
|
|
116
|
+
private initRemoteUpload;
|
|
117
|
+
/**
|
|
118
|
+
* Handle a remote upload event
|
|
119
|
+
*/
|
|
120
|
+
private handleRemoteUpload;
|
|
121
|
+
/**
|
|
122
|
+
* Open the QR code dialog for mobile upload
|
|
123
|
+
*/
|
|
124
|
+
openRemoteUploadDialog(): void;
|
|
125
|
+
/**
|
|
126
|
+
* Check if currently paired with a mobile device
|
|
127
|
+
*/
|
|
128
|
+
isRemotePaired(): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Disconnect from paired mobile device
|
|
131
|
+
*/
|
|
132
|
+
disconnectRemote(): void;
|
|
133
|
+
ngOnDestroy(): void;
|
|
103
134
|
static ɵfac: i0.ɵɵFactoryDeclaration<TisImageAndFileUploadAndViewComponent, never>;
|
|
104
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<TisImageAndFileUploadAndViewComponent, "tis-image-and-file-upload-and-view", never, { "urlConfig": { "alias": "urlConfig"; "required": true; }; "entityType": { "alias": "entityType"; "required": false; }; "entityId": { "alias": "entityId"; "required": false; }; "viewType": { "alias": "viewType"; "required": false; }; "type": { "alias": "type"; "required": false; }; "label": { "alias": "label"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "data": { "alias": "data"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "isValidateMimeType": { "alias": "isValidateMimeType"; "required": false; }; "selectedId": { "alias": "selectedId"; "required": false; }; "options": { "alias": "options"; "required": false; }; "required": { "alias": "required"; "required": false; }; "previewOnly": { "alias": "previewOnly"; "required": false; }; "previewInFlex": { "alias": "previewInFlex"; "required": false; }; "imageItemClass": { "alias": "imageItemClass"; "required": false; }; "isAddUploadedFileInLastNode": { "alias": "isAddUploadedFileInLastNode"; "required": false; }; "isEnableDeleteConfirmation": { "alias": "isEnableDeleteConfirmation"; "required": false; }; "isEnableCapture": { "alias": "isEnableCapture"; "required": false; }; "deleteConfirmationMsg": { "alias": "deleteConfirmationMsg"; "required": false; }; "dialogConfig": { "alias": "dialogConfig"; "required": false; }; "isShowImageSequence": { "alias": "isShowImageSequence"; "required": false; }; "enableDragNDrop": { "alias": "enableDragNDrop"; "required": false; }; }, { "uploadInProgress": "uploadInProgress"; "onUploaded": "onUploaded"; "onFileSelect": "onFileSelect"; "onFileRemoved": "onFileRemoved"; "onError": "onError"; "dataSequenceChange": "dataSequenceChange"; }, never, never, false, never>;
|
|
135
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TisImageAndFileUploadAndViewComponent, "tis-image-and-file-upload-and-view", never, { "urlConfig": { "alias": "urlConfig"; "required": true; }; "entityType": { "alias": "entityType"; "required": false; }; "entityId": { "alias": "entityId"; "required": false; }; "viewType": { "alias": "viewType"; "required": false; }; "type": { "alias": "type"; "required": false; }; "label": { "alias": "label"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "data": { "alias": "data"; "required": false; }; "hint": { "alias": "hint"; "required": false; }; "accept": { "alias": "accept"; "required": false; }; "isValidateMimeType": { "alias": "isValidateMimeType"; "required": false; }; "selectedId": { "alias": "selectedId"; "required": false; }; "options": { "alias": "options"; "required": false; }; "required": { "alias": "required"; "required": false; }; "previewOnly": { "alias": "previewOnly"; "required": false; }; "previewInFlex": { "alias": "previewInFlex"; "required": false; }; "imageItemClass": { "alias": "imageItemClass"; "required": false; }; "isAddUploadedFileInLastNode": { "alias": "isAddUploadedFileInLastNode"; "required": false; }; "isEnableDeleteConfirmation": { "alias": "isEnableDeleteConfirmation"; "required": false; }; "isEnableCapture": { "alias": "isEnableCapture"; "required": false; }; "deleteConfirmationMsg": { "alias": "deleteConfirmationMsg"; "required": false; }; "dialogConfig": { "alias": "dialogConfig"; "required": false; }; "remoteUploadConfig": { "alias": "remoteUploadConfig"; "required": false; }; "isShowImageSequence": { "alias": "isShowImageSequence"; "required": false; }; "enableDragNDrop": { "alias": "enableDragNDrop"; "required": false; }; }, { "uploadInProgress": "uploadInProgress"; "onUploaded": "onUploaded"; "onFileSelect": "onFileSelect"; "onFileRemoved": "onFileRemoved"; "onError": "onError"; "onRemoteUpload": "onRemoteUpload"; "dataSequenceChange": "dataSequenceChange"; }, never, never, false, never>;
|
|
105
136
|
}
|
|
@@ -7,19 +7,21 @@ import * as i5 from "./tis-file-viewer/tis-pdf-viewer/tis-pdf-viewer.component";
|
|
|
7
7
|
import * as i6 from "./tis-file-viewer/tis-video/tis-video.component";
|
|
8
8
|
import * as i7 from "./tis-error-dialog/tis-error-dialog.component";
|
|
9
9
|
import * as i8 from "./tis-confirmation-dialog/tis-confirmation-dialog.component";
|
|
10
|
-
import * as i9 from "
|
|
11
|
-
import * as i10 from "
|
|
12
|
-
import * as i11 from "@angular/
|
|
13
|
-
import * as i12 from "
|
|
14
|
-
import * as i13 from "@angular/
|
|
15
|
-
import * as i14 from "@angular/material/
|
|
16
|
-
import * as i15 from "@angular/material/
|
|
17
|
-
import * as i16 from "@angular/material/
|
|
18
|
-
import * as i17 from "@angular/material/
|
|
19
|
-
import * as i18 from "@angular/material/
|
|
20
|
-
import * as i19 from "@angular/
|
|
10
|
+
import * as i9 from "./tis-qr-code-dialog/tis-qr-code-dialog.component";
|
|
11
|
+
import * as i10 from "@angular/common";
|
|
12
|
+
import * as i11 from "@angular/common/http";
|
|
13
|
+
import * as i12 from "ngx-extended-pdf-viewer";
|
|
14
|
+
import * as i13 from "@angular/forms";
|
|
15
|
+
import * as i14 from "@angular/material/tooltip";
|
|
16
|
+
import * as i15 from "@angular/material/icon";
|
|
17
|
+
import * as i16 from "@angular/material/snack-bar";
|
|
18
|
+
import * as i17 from "@angular/material/progress-spinner";
|
|
19
|
+
import * as i18 from "@angular/material/input";
|
|
20
|
+
import * as i19 from "@angular/material/button";
|
|
21
|
+
import * as i20 from "@angular/material/dialog";
|
|
22
|
+
import * as i21 from "@angular/cdk/drag-drop";
|
|
21
23
|
export declare class TisImageAndFileUploadAndViewModule {
|
|
22
24
|
static ɵfac: i0.ɵɵFactoryDeclaration<TisImageAndFileUploadAndViewModule, never>;
|
|
23
|
-
static ɵmod: i0.ɵɵNgModuleDeclaration<TisImageAndFileUploadAndViewModule, [typeof i1.TisImageAndFileUploadAndViewComponent, typeof i2.TisPreviewImageComponent, typeof i3.TisFileViewerComponent, typeof i4.TisExcelFileViewerComponent, typeof i5.TisPdfViewerComponent, typeof i6.TisVideoComponent, typeof i7.TisErrorDialogComponent, typeof i8.TisConfirmationDialogComponent], [typeof
|
|
25
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<TisImageAndFileUploadAndViewModule, [typeof i1.TisImageAndFileUploadAndViewComponent, typeof i2.TisPreviewImageComponent, typeof i3.TisFileViewerComponent, typeof i4.TisExcelFileViewerComponent, typeof i5.TisPdfViewerComponent, typeof i6.TisVideoComponent, typeof i7.TisErrorDialogComponent, typeof i8.TisConfirmationDialogComponent, typeof i9.TisQrCodeDialogComponent], [typeof i10.CommonModule, typeof i11.HttpClientModule, typeof i12.NgxExtendedPdfViewerModule, typeof i13.FormsModule, typeof i13.ReactiveFormsModule, typeof i14.MatTooltipModule, typeof i15.MatIconModule, typeof i16.MatSnackBarModule, typeof i17.MatProgressSpinnerModule, typeof i18.MatInputModule, typeof i19.MatButtonModule, typeof i20.MatDialogModule, typeof i21.DragDropModule], [typeof i1.TisImageAndFileUploadAndViewComponent, typeof i9.TisQrCodeDialogComponent]>;
|
|
24
26
|
static ɵinj: i0.ɵɵInjectorDeclaration<TisImageAndFileUploadAndViewModule>;
|
|
25
27
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { OnInit, OnDestroy, ElementRef } from '@angular/core';
|
|
2
|
+
import { MatDialogRef } from '@angular/material/dialog';
|
|
3
|
+
import { TisRemoteUploadService } from '../services/tis-remote-upload.service';
|
|
4
|
+
import { TisRemoteUploadEvent } from '../interfaces/socket-adapter.interface';
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
export interface TisQrCodeDialogData {
|
|
7
|
+
title?: string;
|
|
8
|
+
subtitle?: string;
|
|
9
|
+
qrSize?: number;
|
|
10
|
+
showCountdown?: boolean;
|
|
11
|
+
autoCloseOnUpload?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare class TisQrCodeDialogComponent implements OnInit, OnDestroy {
|
|
14
|
+
dialogRef: MatDialogRef<TisQrCodeDialogComponent>;
|
|
15
|
+
data: TisQrCodeDialogData;
|
|
16
|
+
private remoteUploadService;
|
|
17
|
+
qrCanvas: ElementRef<HTMLCanvasElement>;
|
|
18
|
+
qrData: string;
|
|
19
|
+
pairingCode: string;
|
|
20
|
+
expiresAt: number;
|
|
21
|
+
remainingTime: string;
|
|
22
|
+
isLoading: boolean;
|
|
23
|
+
isExpired: boolean;
|
|
24
|
+
isConnected: boolean;
|
|
25
|
+
errorMessage: string | null;
|
|
26
|
+
connectionStatus: 'disconnected' | 'pending' | 'connected';
|
|
27
|
+
uploadedFiles: TisRemoteUploadEvent[];
|
|
28
|
+
private destroy$;
|
|
29
|
+
private countdownSubscription;
|
|
30
|
+
constructor(dialogRef: MatDialogRef<TisQrCodeDialogComponent>, data: TisQrCodeDialogData, remoteUploadService: TisRemoteUploadService);
|
|
31
|
+
ngOnInit(): void;
|
|
32
|
+
ngOnDestroy(): void;
|
|
33
|
+
private generateQrCode;
|
|
34
|
+
private subscribeToEvents;
|
|
35
|
+
private startCountdown;
|
|
36
|
+
private renderQrCode;
|
|
37
|
+
/**
|
|
38
|
+
* Simple QR code generator using canvas
|
|
39
|
+
* In production, you'd use a library like qrcode or qrcode-generator
|
|
40
|
+
*/
|
|
41
|
+
private generateQrCodeOnCanvas;
|
|
42
|
+
private generatePattern;
|
|
43
|
+
private drawFinderPattern;
|
|
44
|
+
refreshQrCode(): void;
|
|
45
|
+
disconnect(): void;
|
|
46
|
+
close(): void;
|
|
47
|
+
copyPairingCode(): void;
|
|
48
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TisQrCodeDialogComponent, never>;
|
|
49
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<TisQrCodeDialogComponent, "tis-qr-code-dialog", never, {}, {}, never, never, false, never>;
|
|
50
|
+
}
|
package/package.json
CHANGED
package/public-api.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export * from './lib/tis-image-and-file-upload-and-view.service';
|
|
|
2
2
|
export * from './lib/tis-image-and-file-upload-and-view/tis-image-and-file-upload-and-view.component';
|
|
3
3
|
export * from './lib/tis-image-and-file-upload-and-view.module';
|
|
4
4
|
export * from './lib/interfaces';
|
|
5
|
+
export * from './lib/services/tis-remote-upload.service';
|
|
6
|
+
export * from './lib/tis-qr-code-dialog/tis-qr-code-dialog.component';
|