@servicemind.tis/tis-image-and-file-upload-and-view 1.2.33 → 1.2.34
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.
|
@@ -869,19 +869,33 @@ class TisRemoteUploadService {
|
|
|
869
869
|
this.stopHealthCheck();
|
|
870
870
|
const mobileDeviceId = this.mobileConnection$.value?.mobileDeviceId;
|
|
871
871
|
if (!mobileDeviceId || !this.deviceId) {
|
|
872
|
-
console.warn(`[${TisRemoteUploadService.COMPONENT}] Cannot start health check - missing device IDs
|
|
872
|
+
console.warn(`[${TisRemoteUploadService.COMPONENT}] Cannot start health check - missing device IDs`, {
|
|
873
|
+
mobileDeviceId,
|
|
874
|
+
desktopDeviceId: this.deviceId
|
|
875
|
+
});
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
if (!this.socketAdapter?.callApiViaSocket) {
|
|
879
|
+
console.error(`[${TisRemoteUploadService.COMPONENT}] Cannot start health check - socketAdapter.callApiViaSocket not available`);
|
|
873
880
|
return;
|
|
874
881
|
}
|
|
875
|
-
console.log(`[${TisRemoteUploadService.COMPONENT}] Starting health check (every ${HEALTH_CHECK_INTERVAL / 1000}s)
|
|
882
|
+
console.log(`[${TisRemoteUploadService.COMPONENT}] Starting health check (every ${HEALTH_CHECK_INTERVAL / 1000}s)`, {
|
|
883
|
+
mobileDeviceId,
|
|
884
|
+
desktopDeviceId: this.deviceId
|
|
885
|
+
});
|
|
876
886
|
// Set initial checking state (blinking)
|
|
877
887
|
this.isCheckingStatus$.next(true);
|
|
878
888
|
// Run first check immediately
|
|
879
|
-
this.checkDevicesOnline()
|
|
889
|
+
this.checkDevicesOnline().catch(err => {
|
|
890
|
+
console.error(`[${TisRemoteUploadService.COMPONENT}] Initial health check failed:`, err);
|
|
891
|
+
});
|
|
880
892
|
// Then run periodically
|
|
881
893
|
this.healthCheckSubscription = interval(HEALTH_CHECK_INTERVAL)
|
|
882
894
|
.pipe(takeUntil(this.destroy$))
|
|
883
895
|
.subscribe(() => {
|
|
884
|
-
this.checkDevicesOnline()
|
|
896
|
+
this.checkDevicesOnline().catch(err => {
|
|
897
|
+
console.error(`[${TisRemoteUploadService.COMPONENT}] Periodic health check failed:`, err);
|
|
898
|
+
});
|
|
885
899
|
});
|
|
886
900
|
}
|
|
887
901
|
/**
|
|
@@ -901,14 +915,22 @@ class TisRemoteUploadService {
|
|
|
901
915
|
async checkDevicesOnline() {
|
|
902
916
|
const mobileDeviceId = this.mobileConnection$.value?.mobileDeviceId;
|
|
903
917
|
if (!mobileDeviceId || !this.deviceId) {
|
|
904
|
-
console.warn(`[${TisRemoteUploadService.COMPONENT}] Cannot check devices - missing device IDs
|
|
918
|
+
console.warn(`[${TisRemoteUploadService.COMPONENT}] Cannot check devices - missing device IDs`, {
|
|
919
|
+
mobileDeviceId,
|
|
920
|
+
desktopDeviceId: this.deviceId
|
|
921
|
+
});
|
|
905
922
|
return null;
|
|
906
923
|
}
|
|
924
|
+
console.log(`[${TisRemoteUploadService.COMPONENT}] Checking devices online status...`, {
|
|
925
|
+
desktopDeviceId: this.deviceId,
|
|
926
|
+
mobileDeviceId: mobileDeviceId
|
|
927
|
+
});
|
|
907
928
|
try {
|
|
908
929
|
const response = await this.callApiWithTimeout('tis-image-mobile-uploader/check-devices-online', {
|
|
909
930
|
desktopDeviceId: this.deviceId,
|
|
910
931
|
mobileDeviceId: mobileDeviceId
|
|
911
932
|
}, 15000);
|
|
933
|
+
console.log(`[${TisRemoteUploadService.COMPONENT}] Check devices response:`, response);
|
|
912
934
|
// Response structure: { body: { data: { desktop: {...}, mobile: {...} } } }
|
|
913
935
|
const data = response?.body?.data || response?.data || response;
|
|
914
936
|
const status = {
|
|
@@ -1551,12 +1573,21 @@ class TisViewConnectionDialogComponent {
|
|
|
1551
1573
|
return `${minutesAgo}m ago`;
|
|
1552
1574
|
}
|
|
1553
1575
|
}
|
|
1576
|
+
/**
|
|
1577
|
+
* Truncate device ID to show first 8 and last 8 characters
|
|
1578
|
+
*/
|
|
1579
|
+
truncateDeviceId(deviceId) {
|
|
1580
|
+
if (!deviceId || deviceId.length <= 20) {
|
|
1581
|
+
return deviceId;
|
|
1582
|
+
}
|
|
1583
|
+
return `${deviceId.substring(0, 8)}...${deviceId.substring(deviceId.length - 8)}`;
|
|
1584
|
+
}
|
|
1554
1585
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: TisViewConnectionDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: TisRemoteUploadService }], target: i0.ɵɵFactoryTarget.Component });
|
|
1555
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: TisViewConnectionDialogComponent, isStandalone: false, selector: "tis-view-connection-dialog", ngImport: i0, template: "<div class=\"dialog-container\">\n <div class=\"dialog-header\">\n <h2 mat-dialog-title>{{ data.title || 'Mobile Connection' }}</h2>\n <button mat-icon-button class=\"close-btn\" (click)=\"close()\" tabindex=\"-1\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <mat-dialog-content class=\"dialog-content\">\n @if (mobileConnection) {\n <!-- Connection Info Card -->\n <div class=\"connection-card\">\n <div class=\"connection-header\">\n <div class=\"status-indicator\" [class.online]=\"devicesStatus?.isReadyForTransfer\" [class.blinking]=\"isCheckingStatus\">\n <mat-icon>{{ devicesStatus?.isReadyForTransfer ? 'check_circle' : 'error' }}</mat-icon>\n <span class=\"status-text\">\n {{ devicesStatus?.isReadyForTransfer ? 'Connected' : 'Connection Issue' }}\n </span>\n </div>\n <button \n mat-button \n color=\"primary\" \n class=\"refresh-btn\"\n (click)=\"refreshStatus()\"\n [disabled]=\"isCheckingStatus\">\n <mat-icon [class.spinning]=\"isCheckingStatus\">refresh</mat-icon>\n <span>Refresh</span>\n </button>\n </div>\n\n <div class=\"connection-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Mobile Device ID:</span>\n <span class=\"detail-value\">{{ mobileConnection.mobileDeviceId }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected For:</span>\n <span class=\"detail-value\">{{ getConnectionDuration() }}</span>\n </div>\n @if (mobileConnection.connectedAt) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected At:</span>\n <span class=\"detail-value\">{{ mobileConnection.connectedAt | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Devices Status Card -->\n @if (devicesStatus) {\n <div class=\"devices-status-card\">\n <h3 class=\"card-title\">Device Status</h3>\n \n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">computer</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Desktop</div>\n <div class=\"device-id\">{{ devicesStatus.desktop.deviceId }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.desktop.isOnline\">\n <mat-icon>{{ devicesStatus.desktop.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.desktop.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.desktop.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.desktop.lastPing) }}</div>\n }\n </div>\n\n <mat-divider></mat-divider>\n\n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">smartphone</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Mobile</div>\n <div class=\"device-id\">{{ devicesStatus.mobile.deviceId }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.mobile.isOnline\">\n <mat-icon>{{ devicesStatus.mobile.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.mobile.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.mobile.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.mobile.lastPing) }}</div>\n }\n </div>\n </div>\n }\n\n <!-- Warning Message -->\n @if (devicesStatus && !devicesStatus.isReadyForTransfer) {\n <div class=\"warning-message\">\n <mat-icon>warning</mat-icon>\n <span>File uploads may not work properly when devices are offline.</span>\n </div>\n }\n } @else {\n <!-- No Connection -->\n <div class=\"no-connection\">\n <mat-icon>link_off</mat-icon>\n <p>No mobile device connected</p>\n </div>\n }\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button \n mat-button \n (click)=\"close()\"\n [disabled]=\"disconnecting\">\n Close\n </button>\n @if (mobileConnection) {\n <button \n mat-raised-button \n color=\"warn\" \n (click)=\"disconnect()\"\n [disabled]=\"disconnecting\">\n <mat-icon *ngIf=\"!disconnecting\">link_off</mat-icon>\n <mat-spinner *ngIf=\"disconnecting\" diameter=\"18\"></mat-spinner>\n <span>{{ disconnecting ? 'Disconnecting...' : 'Disconnect' }}</span>\n </button>\n }\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{min-width:500px;max-width:600px}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px 0}.dialog-header h2{margin:0;font-size:20px;font-weight:500}.close-btn{margin-right:-12px}.dialog-content{padding:16px 24px!important;display:flex;flex-direction:column;gap:16px}.dialog-actions{padding:8px 16px 16px!important}.connection-card{background:#f5f5f5;border-radius:8px;padding:16px}.connection-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.status-indicator{display:flex;align-items:center;gap:8px;font-weight:500}.status-indicator mat-icon{font-size:24px;width:24px;height:24px}.status-indicator.online{color:#4caf50}.status-indicator:not(.online){color:#f44336}.status-indicator.blinking mat-icon{animation:blink 1.5s ease-in-out infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.refresh-btn{min-width:auto}.refresh-btn mat-icon{margin-right:4px}.refresh-btn mat-icon.spinning{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.connection-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:14px}.detail-label{color:#666;font-weight:500}.detail-value{color:#333;font-family:Courier New,monospace}.devices-status-card{border:1px solid #e0e0e0;border-radius:8px;padding:16px;background:#fff}.card-title{margin:0 0 16px;font-size:16px;font-weight:500;color:#333}.device-status-row{display:flex;flex-direction:column;gap:8px;padding:12px 0}.device-info{display:flex;align-items:center;gap:12px}.device-icon{font-size:32px;width:32px;height:32px;color:#666}.device-details{flex:1}.device-name{font-weight:500;font-size:14px;color:#333}.device-id{font-size:12px;color:#666;font-family:Courier New,monospace}.status-badge{display:flex;align-items:center;gap:6px;padding:4px 12px;border-radius:16px;font-size:12px;font-weight:500;background:#ffebee;color:#c62828;align-self:flex-start}.status-badge.online{background:#e8f5e9;color:#2e7d32}.status-badge mat-icon{font-size:16px;width:16px;height:16px}.last-ping{font-size:12px;color:#999;padding-left:44px}mat-divider{margin:8px 0}.warning-message{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff3e0;border-left:4px solid #ff9800;border-radius:4px;font-size:14px;color:#e65100}.warning-message mat-icon{color:#ff9800}.no-connection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;color:#999}.no-connection mat-icon{font-size:64px;width:64px;height:64px;margin-bottom:16px}.no-connection p{margin:0;font-size:16px}.dialog-actions button{margin-left:8px}.dialog-actions button mat-spinner{display:inline-block;margin-right:8px}\n"], dependencies: [{ kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i3$2.DatePipe, name: "date" }] });
|
|
1586
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.6", type: TisViewConnectionDialogComponent, isStandalone: false, selector: "tis-view-connection-dialog", ngImport: i0, template: "<div class=\"dialog-container\">\n <div class=\"dialog-header\">\n <h2 mat-dialog-title>{{ data.title || 'Mobile Connection' }}</h2>\n <button mat-icon-button class=\"close-btn\" (click)=\"close()\" tabindex=\"-1\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <mat-dialog-content class=\"dialog-content\">\n @if (mobileConnection) {\n <!-- Connection Info Card -->\n <div class=\"connection-card\">\n <div class=\"connection-header\">\n <div class=\"status-indicator\" [class.online]=\"devicesStatus?.isReadyForTransfer\" [class.blinking]=\"isCheckingStatus\">\n <mat-icon>{{ devicesStatus?.isReadyForTransfer ? 'check_circle' : 'error' }}</mat-icon>\n <span class=\"status-text\">\n {{ devicesStatus?.isReadyForTransfer ? 'Connected' : 'Connection Issue' }}\n </span>\n </div>\n <button \n mat-button \n color=\"primary\" \n class=\"refresh-btn\"\n (click)=\"refreshStatus()\"\n [disabled]=\"isCheckingStatus\">\n <mat-icon [class.spinning]=\"isCheckingStatus\">refresh</mat-icon>\n <span>Refresh</span>\n </button>\n </div>\n\n <div class=\"connection-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Mobile Device ID:</span>\n <span class=\"detail-value\">{{ truncateDeviceId(mobileConnection.mobileDeviceId) }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected For:</span>\n <span class=\"detail-value\">{{ getConnectionDuration() }}</span>\n </div>\n @if (mobileConnection.connectedAt) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected At:</span>\n <span class=\"detail-value\">{{ mobileConnection.connectedAt | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Devices Status Card -->\n @if (devicesStatus) {\n <div class=\"devices-status-card\">\n <h3 class=\"card-title\">Device Status</h3>\n \n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">computer</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Desktop</div>\n <div class=\"device-id\">{{ truncateDeviceId(devicesStatus.desktop.deviceId) }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.desktop.isOnline\">\n <mat-icon>{{ devicesStatus.desktop.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.desktop.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.desktop.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.desktop.lastPing) }}</div>\n }\n </div>\n\n <mat-divider></mat-divider>\n\n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">smartphone</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Mobile</div>\n <div class=\"device-id\">{{ truncateDeviceId(devicesStatus.mobile.deviceId) }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.mobile.isOnline\">\n <mat-icon>{{ devicesStatus.mobile.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.mobile.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.mobile.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.mobile.lastPing) }}</div>\n }\n </div>\n </div>\n }\n\n <!-- Warning Message -->\n @if (devicesStatus && !devicesStatus.isReadyForTransfer) {\n <div class=\"warning-message\">\n <mat-icon>warning</mat-icon>\n <span>File uploads may not work properly when devices are offline.</span>\n </div>\n }\n } @else {\n <!-- No Connection -->\n <div class=\"no-connection\">\n <mat-icon>link_off</mat-icon>\n <p>No mobile device connected</p>\n </div>\n }\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button \n mat-button \n (click)=\"close()\"\n [disabled]=\"disconnecting\">\n Close\n </button>\n @if (mobileConnection) {\n <button \n mat-raised-button \n color=\"warn\" \n (click)=\"disconnect()\"\n [disabled]=\"disconnecting\">\n <mat-icon *ngIf=\"!disconnecting\">link_off</mat-icon>\n <mat-spinner *ngIf=\"disconnecting\" diameter=\"18\"></mat-spinner>\n <span>{{ disconnecting ? 'Disconnecting...' : 'Disconnect' }}</span>\n </button>\n }\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{min-width:500px;max-width:600px}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px 0}.dialog-header h2{margin:0;font-size:20px;font-weight:500}.close-btn{margin-right:-12px}.dialog-content{padding:16px 24px!important;display:flex;flex-direction:column;gap:16px}.dialog-actions{padding:8px 16px 16px!important}.connection-card{background:#f5f5f5;border-radius:8px;padding:16px}.connection-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.status-indicator{display:flex;align-items:center;gap:8px;font-weight:500}.status-indicator mat-icon{font-size:24px;width:24px;height:24px}.status-indicator.online{color:#4caf50}.status-indicator:not(.online){color:#f44336}.status-indicator.blinking mat-icon{animation:blink 1.5s ease-in-out infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.refresh-btn{min-width:auto}.refresh-btn mat-icon{margin-right:4px}.refresh-btn mat-icon.spinning{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.connection-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:14px}.detail-label{color:#666;font-weight:500}.detail-value{color:#333;font-family:Courier New,monospace}.devices-status-card{border:1px solid #e0e0e0;border-radius:8px;padding:16px;background:#fff}.card-title{margin:0 0 16px;font-size:16px;font-weight:500;color:#333}.device-status-row{display:flex;flex-direction:column;gap:8px;padding:12px 0}.device-info{display:flex;align-items:center;gap:12px}.device-icon{font-size:32px;width:32px;height:32px;color:#666}.device-details{flex:1}.device-name{font-weight:500;font-size:14px;color:#333}.device-id{font-size:12px;color:#666;font-family:Courier New,monospace}.status-badge{display:flex;align-items:center;gap:6px;padding:4px 12px;border-radius:16px;font-size:12px;font-weight:500;background:#ffebee;color:#c62828;align-self:flex-start}.status-badge.online{background:#e8f5e9;color:#2e7d32}.status-badge mat-icon{font-size:16px;width:16px;height:16px}.last-ping{font-size:12px;color:#999;padding-left:44px}mat-divider{margin:8px 0}.warning-message{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff3e0;border-left:4px solid #ff9800;border-radius:4px;font-size:14px;color:#e65100}.warning-message mat-icon{color:#ff9800}.no-connection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;color:#999}.no-connection mat-icon{font-size:64px;width:64px;height:64px;margin-bottom:16px}.no-connection p{margin:0;font-size:16px}.dialog-actions button{margin-left:8px}.dialog-actions button mat-spinner{display:inline-block;margin-right:8px}\n"], dependencies: [{ kind: "directive", type: i3$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i2.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i4.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: i7.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "pipe", type: i3$2.DatePipe, name: "date" }] });
|
|
1556
1587
|
}
|
|
1557
1588
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.6", ngImport: i0, type: TisViewConnectionDialogComponent, decorators: [{
|
|
1558
1589
|
type: Component,
|
|
1559
|
-
args: [{ selector: 'tis-view-connection-dialog', standalone: false, template: "<div class=\"dialog-container\">\n <div class=\"dialog-header\">\n <h2 mat-dialog-title>{{ data.title || 'Mobile Connection' }}</h2>\n <button mat-icon-button class=\"close-btn\" (click)=\"close()\" tabindex=\"-1\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <mat-dialog-content class=\"dialog-content\">\n @if (mobileConnection) {\n <!-- Connection Info Card -->\n <div class=\"connection-card\">\n <div class=\"connection-header\">\n <div class=\"status-indicator\" [class.online]=\"devicesStatus?.isReadyForTransfer\" [class.blinking]=\"isCheckingStatus\">\n <mat-icon>{{ devicesStatus?.isReadyForTransfer ? 'check_circle' : 'error' }}</mat-icon>\n <span class=\"status-text\">\n {{ devicesStatus?.isReadyForTransfer ? 'Connected' : 'Connection Issue' }}\n </span>\n </div>\n <button \n mat-button \n color=\"primary\" \n class=\"refresh-btn\"\n (click)=\"refreshStatus()\"\n [disabled]=\"isCheckingStatus\">\n <mat-icon [class.spinning]=\"isCheckingStatus\">refresh</mat-icon>\n <span>Refresh</span>\n </button>\n </div>\n\n <div class=\"connection-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Mobile Device ID:</span>\n <span class=\"detail-value\">{{ mobileConnection.mobileDeviceId }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected For:</span>\n <span class=\"detail-value\">{{ getConnectionDuration() }}</span>\n </div>\n @if (mobileConnection.connectedAt) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected At:</span>\n <span class=\"detail-value\">{{ mobileConnection.connectedAt | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Devices Status Card -->\n @if (devicesStatus) {\n <div class=\"devices-status-card\">\n <h3 class=\"card-title\">Device Status</h3>\n \n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">computer</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Desktop</div>\n <div class=\"device-id\">{{ devicesStatus.desktop.deviceId }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.desktop.isOnline\">\n <mat-icon>{{ devicesStatus.desktop.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.desktop.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.desktop.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.desktop.lastPing) }}</div>\n }\n </div>\n\n <mat-divider></mat-divider>\n\n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">smartphone</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Mobile</div>\n <div class=\"device-id\">{{ devicesStatus.mobile.deviceId }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.mobile.isOnline\">\n <mat-icon>{{ devicesStatus.mobile.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.mobile.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.mobile.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.mobile.lastPing) }}</div>\n }\n </div>\n </div>\n }\n\n <!-- Warning Message -->\n @if (devicesStatus && !devicesStatus.isReadyForTransfer) {\n <div class=\"warning-message\">\n <mat-icon>warning</mat-icon>\n <span>File uploads may not work properly when devices are offline.</span>\n </div>\n }\n } @else {\n <!-- No Connection -->\n <div class=\"no-connection\">\n <mat-icon>link_off</mat-icon>\n <p>No mobile device connected</p>\n </div>\n }\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button \n mat-button \n (click)=\"close()\"\n [disabled]=\"disconnecting\">\n Close\n </button>\n @if (mobileConnection) {\n <button \n mat-raised-button \n color=\"warn\" \n (click)=\"disconnect()\"\n [disabled]=\"disconnecting\">\n <mat-icon *ngIf=\"!disconnecting\">link_off</mat-icon>\n <mat-spinner *ngIf=\"disconnecting\" diameter=\"18\"></mat-spinner>\n <span>{{ disconnecting ? 'Disconnecting...' : 'Disconnect' }}</span>\n </button>\n }\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{min-width:500px;max-width:600px}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px 0}.dialog-header h2{margin:0;font-size:20px;font-weight:500}.close-btn{margin-right:-12px}.dialog-content{padding:16px 24px!important;display:flex;flex-direction:column;gap:16px}.dialog-actions{padding:8px 16px 16px!important}.connection-card{background:#f5f5f5;border-radius:8px;padding:16px}.connection-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.status-indicator{display:flex;align-items:center;gap:8px;font-weight:500}.status-indicator mat-icon{font-size:24px;width:24px;height:24px}.status-indicator.online{color:#4caf50}.status-indicator:not(.online){color:#f44336}.status-indicator.blinking mat-icon{animation:blink 1.5s ease-in-out infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.refresh-btn{min-width:auto}.refresh-btn mat-icon{margin-right:4px}.refresh-btn mat-icon.spinning{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.connection-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:14px}.detail-label{color:#666;font-weight:500}.detail-value{color:#333;font-family:Courier New,monospace}.devices-status-card{border:1px solid #e0e0e0;border-radius:8px;padding:16px;background:#fff}.card-title{margin:0 0 16px;font-size:16px;font-weight:500;color:#333}.device-status-row{display:flex;flex-direction:column;gap:8px;padding:12px 0}.device-info{display:flex;align-items:center;gap:12px}.device-icon{font-size:32px;width:32px;height:32px;color:#666}.device-details{flex:1}.device-name{font-weight:500;font-size:14px;color:#333}.device-id{font-size:12px;color:#666;font-family:Courier New,monospace}.status-badge{display:flex;align-items:center;gap:6px;padding:4px 12px;border-radius:16px;font-size:12px;font-weight:500;background:#ffebee;color:#c62828;align-self:flex-start}.status-badge.online{background:#e8f5e9;color:#2e7d32}.status-badge mat-icon{font-size:16px;width:16px;height:16px}.last-ping{font-size:12px;color:#999;padding-left:44px}mat-divider{margin:8px 0}.warning-message{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff3e0;border-left:4px solid #ff9800;border-radius:4px;font-size:14px;color:#e65100}.warning-message mat-icon{color:#ff9800}.no-connection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;color:#999}.no-connection mat-icon{font-size:64px;width:64px;height:64px;margin-bottom:16px}.no-connection p{margin:0;font-size:16px}.dialog-actions button{margin-left:8px}.dialog-actions button mat-spinner{display:inline-block;margin-right:8px}\n"] }]
|
|
1590
|
+
args: [{ selector: 'tis-view-connection-dialog', standalone: false, template: "<div class=\"dialog-container\">\n <div class=\"dialog-header\">\n <h2 mat-dialog-title>{{ data.title || 'Mobile Connection' }}</h2>\n <button mat-icon-button class=\"close-btn\" (click)=\"close()\" tabindex=\"-1\">\n <mat-icon>close</mat-icon>\n </button>\n </div>\n\n <mat-dialog-content class=\"dialog-content\">\n @if (mobileConnection) {\n <!-- Connection Info Card -->\n <div class=\"connection-card\">\n <div class=\"connection-header\">\n <div class=\"status-indicator\" [class.online]=\"devicesStatus?.isReadyForTransfer\" [class.blinking]=\"isCheckingStatus\">\n <mat-icon>{{ devicesStatus?.isReadyForTransfer ? 'check_circle' : 'error' }}</mat-icon>\n <span class=\"status-text\">\n {{ devicesStatus?.isReadyForTransfer ? 'Connected' : 'Connection Issue' }}\n </span>\n </div>\n <button \n mat-button \n color=\"primary\" \n class=\"refresh-btn\"\n (click)=\"refreshStatus()\"\n [disabled]=\"isCheckingStatus\">\n <mat-icon [class.spinning]=\"isCheckingStatus\">refresh</mat-icon>\n <span>Refresh</span>\n </button>\n </div>\n\n <div class=\"connection-details\">\n <div class=\"detail-row\">\n <span class=\"detail-label\">Mobile Device ID:</span>\n <span class=\"detail-value\">{{ truncateDeviceId(mobileConnection.mobileDeviceId) }}</span>\n </div>\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected For:</span>\n <span class=\"detail-value\">{{ getConnectionDuration() }}</span>\n </div>\n @if (mobileConnection.connectedAt) {\n <div class=\"detail-row\">\n <span class=\"detail-label\">Connected At:</span>\n <span class=\"detail-value\">{{ mobileConnection.connectedAt | date:'short' }}</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Devices Status Card -->\n @if (devicesStatus) {\n <div class=\"devices-status-card\">\n <h3 class=\"card-title\">Device Status</h3>\n \n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">computer</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Desktop</div>\n <div class=\"device-id\">{{ truncateDeviceId(devicesStatus.desktop.deviceId) }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.desktop.isOnline\">\n <mat-icon>{{ devicesStatus.desktop.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.desktop.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.desktop.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.desktop.lastPing) }}</div>\n }\n </div>\n\n <mat-divider></mat-divider>\n\n <div class=\"device-status-row\">\n <div class=\"device-info\">\n <mat-icon class=\"device-icon\">smartphone</mat-icon>\n <div class=\"device-details\">\n <div class=\"device-name\">Mobile</div>\n <div class=\"device-id\">{{ truncateDeviceId(devicesStatus.mobile.deviceId) }}</div>\n </div>\n </div>\n <div class=\"status-badge\" [class.online]=\"devicesStatus.mobile.isOnline\">\n <mat-icon>{{ devicesStatus.mobile.isOnline ? 'circle' : 'cancel' }}</mat-icon>\n <span>{{ devicesStatus.mobile.isOnline ? 'Online' : 'Offline' }}</span>\n </div>\n @if (devicesStatus.mobile.lastPing) {\n <div class=\"last-ping\">Last ping: {{ getLastPing(devicesStatus.mobile.lastPing) }}</div>\n }\n </div>\n </div>\n }\n\n <!-- Warning Message -->\n @if (devicesStatus && !devicesStatus.isReadyForTransfer) {\n <div class=\"warning-message\">\n <mat-icon>warning</mat-icon>\n <span>File uploads may not work properly when devices are offline.</span>\n </div>\n }\n } @else {\n <!-- No Connection -->\n <div class=\"no-connection\">\n <mat-icon>link_off</mat-icon>\n <p>No mobile device connected</p>\n </div>\n }\n </mat-dialog-content>\n\n <mat-dialog-actions align=\"end\" class=\"dialog-actions\">\n <button \n mat-button \n (click)=\"close()\"\n [disabled]=\"disconnecting\">\n Close\n </button>\n @if (mobileConnection) {\n <button \n mat-raised-button \n color=\"warn\" \n (click)=\"disconnect()\"\n [disabled]=\"disconnecting\">\n <mat-icon *ngIf=\"!disconnecting\">link_off</mat-icon>\n <mat-spinner *ngIf=\"disconnecting\" diameter=\"18\"></mat-spinner>\n <span>{{ disconnecting ? 'Disconnecting...' : 'Disconnect' }}</span>\n </button>\n }\n </mat-dialog-actions>\n</div>\n", styles: [".dialog-container{min-width:500px;max-width:600px}.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px 0}.dialog-header h2{margin:0;font-size:20px;font-weight:500}.close-btn{margin-right:-12px}.dialog-content{padding:16px 24px!important;display:flex;flex-direction:column;gap:16px}.dialog-actions{padding:8px 16px 16px!important}.connection-card{background:#f5f5f5;border-radius:8px;padding:16px}.connection-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}.status-indicator{display:flex;align-items:center;gap:8px;font-weight:500}.status-indicator mat-icon{font-size:24px;width:24px;height:24px}.status-indicator.online{color:#4caf50}.status-indicator:not(.online){color:#f44336}.status-indicator.blinking mat-icon{animation:blink 1.5s ease-in-out infinite}@keyframes blink{0%,to{opacity:1}50%{opacity:.3}}.refresh-btn{min-width:auto}.refresh-btn mat-icon{margin-right:4px}.refresh-btn mat-icon.spinning{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.connection-details{display:flex;flex-direction:column;gap:8px}.detail-row{display:flex;justify-content:space-between;font-size:14px}.detail-label{color:#666;font-weight:500}.detail-value{color:#333;font-family:Courier New,monospace}.devices-status-card{border:1px solid #e0e0e0;border-radius:8px;padding:16px;background:#fff}.card-title{margin:0 0 16px;font-size:16px;font-weight:500;color:#333}.device-status-row{display:flex;flex-direction:column;gap:8px;padding:12px 0}.device-info{display:flex;align-items:center;gap:12px}.device-icon{font-size:32px;width:32px;height:32px;color:#666}.device-details{flex:1}.device-name{font-weight:500;font-size:14px;color:#333}.device-id{font-size:12px;color:#666;font-family:Courier New,monospace}.status-badge{display:flex;align-items:center;gap:6px;padding:4px 12px;border-radius:16px;font-size:12px;font-weight:500;background:#ffebee;color:#c62828;align-self:flex-start}.status-badge.online{background:#e8f5e9;color:#2e7d32}.status-badge mat-icon{font-size:16px;width:16px;height:16px}.last-ping{font-size:12px;color:#999;padding-left:44px}mat-divider{margin:8px 0}.warning-message{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff3e0;border-left:4px solid #ff9800;border-radius:4px;font-size:14px;color:#e65100}.warning-message mat-icon{color:#ff9800}.no-connection{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px;color:#999}.no-connection mat-icon{font-size:64px;width:64px;height:64px;margin-bottom:16px}.no-connection p{margin:0;font-size:16px}.dialog-actions button{margin-left:8px}.dialog-actions button mat-spinner{display:inline-block;margin-right:8px}\n"] }]
|
|
1560
1591
|
}], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
|
|
1561
1592
|
type: Inject,
|
|
1562
1593
|
args: [MAT_DIALOG_DATA]
|