Skip to content
Merged

Stage #9197

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@
"soundshot",
"soundshots",
"runtimes",
"localtime"
"localtime",
"Behaviour"
],
"useGitignore": true,
"ignorePaths": [
Expand Down
10 changes: 10 additions & 0 deletions apps/desktop-timer/src/assets/styles/_overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -735,3 +735,13 @@ angular2-smart-table > div {
angular2-smart-table a:hover {
text-decoration: auto !important;
}

nb-toastr-container {
position: absolute !important;
top: 20px !important; /* change this value to what you want */
right: 0px !important; /* keep consistent with your toast position */
}

nb-toast {
width: 21rem !important;
}
2 changes: 1 addition & 1 deletion apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"sound-play": "1.1.0",
"squirrelly": "^8.0.8",
"twing": "^5.0.2",
"typeorm": "^0.3.24",
"typeorm": "^0.3.27",
"undici": "^6.10.2",
"custom-electron-titlebar": "^4.2.8"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/server-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"rxjs": "^7.8.2",
"squirrelly": "^8.0.8",
"twing": "^5.0.2",
"typeorm": "^0.3.24",
"typeorm": "^0.3.27",
"undici": "^6.10.2",
"custom-electron-titlebar": "^4.2.8"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"rxjs": "^7.8.2",
"squirrelly": "^8.0.8",
"twing": "^5.0.2",
"typeorm": "^0.3.24",
"typeorm": "^0.3.27",
"undici": "^6.10.2",
"custom-electron-titlebar": "^4.2.8"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"graphql": "^16.11.0",
"nest-knexjs": "^0.0.26",
"slugify": "^1.6.6",
"typeorm": "^0.3.24",
"typeorm": "^0.3.27",
"tslib": "^2.6.2"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion packages/config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"mikro-orm-soft-delete": "^1.0.0-alpha.1",
"nest-knexjs": "^0.0.26",
"tslib": "^2.6.2",
"typeorm": "^0.3.24"
"typeorm": "^0.3.27"
},
"devDependencies": {
"@types/jest": "29.5.14",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@
"sql.js": "^1.5.0",
"streamifier": "^0.1.1",
"swagger-ui-express": "^5.0.0",
"typeorm": "^0.3.24",
"typeorm": "^0.3.27",
"underscore": "^1.13.3",
"unleash-client": "^3.16.1",
"unzipper": "^0.10.11",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import { catchError } from 'rxjs/operators';
import { AuthStrategy } from '../auth';
import { ElectronService } from '../electron/services';
import { Router } from '@angular/router';
import { Store } from '../services';
import { Store, ErrorMapping } from '../services';

@Injectable()
export class UnauthorizedInterceptor implements HttpInterceptor {
constructor(
private authStrategy: AuthStrategy,
private electronService: ElectronService,
private router: Router,
private store: Store
) {}
private store: Store,
private _errorMapping: ErrorMapping
) { }

intercept(
request: HttpRequest<any>,
Expand All @@ -24,7 +25,10 @@ export class UnauthorizedInterceptor implements HttpInterceptor {
catchError((error) => {
// Early return if offline is triggered.
if (this.store.isOffline) {
return;
return throwError(() => {
const message = this._errorMapping.mapErrorMessage(error);
return new Error(message);
});
}
// Unauthorized error occurred
if (error.status === HttpStatusCode.Unauthorized) {
Expand All @@ -39,7 +43,8 @@ export class UnauthorizedInterceptor implements HttpInterceptor {
})
);
}
return throwError(() => error);

return throwError(() => new Error(this._errorMapping.mapErrorMessage(error)));
})
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,22 @@ export class SequenceQueue extends OfflineQueue<ISequence> {

let latest = null;

if (timer.isStartedOffline) {
if (timer.isStartedOffline && timer.timelogId) {
latest = await this._timeTrackerService.getTimeLogById(timer.timelogId);
} else if (timer.isStartedOffline && !timer.stoppedAt) {
console.log('⏱ - Silent start');
latest = await this._timeTrackerService.toggleApiStart({
...timer,
...params
});
} else if (timer.isStartedOffline && !timer.timelogId && timer.startedAt && timer.stoppedAt) {
latest = await this._timeTrackerService.addTimeLog({
startedAt: timer.startedAt,
stoppedAt: timer.stoppedAt,
taskId: timer.taskId,
projectId: timer.projectId,
description: timer.description
});
}

console.log('🛠 - Create queue');
Expand All @@ -78,10 +88,31 @@ export class SequenceQueue extends OfflineQueue<ISequence> {

if (timer.isStoppedOffline) {
console.log('⏱ - Silent stop');
latest = await this._timeTrackerService.toggleApiStop({
...timer,
...params
});
if (!latest && timer.timelogId) {
const currentTimeLog = await this._timeTrackerService.getTimeLogById(timer.timelogId);
if (currentTimeLog.id && currentTimeLog.isRunning) {
latest = await this._timeTrackerService.toggleApiStop({
...timer,
...params
});
} else if (currentTimeLog.id && timer.stoppedAt) {
latest = await this._timeTrackerService.updateTimeLog(
timer.timelogId,
{
startedAt: timer.startedAt || currentTimeLog.startedAt,
stoppedAt: timer.stoppedAt,
description: timer.description,
projectId: timer.projectId,
taskId: timer.taskId
}
)
}
} else if (latest && latest.id && latest.isRunning) {
latest = await this._timeTrackerService.toggleApiStop({
...timer,
...params
});
}
}

const status = await this._timeTrackerStatusService.status();
Expand All @@ -92,9 +123,9 @@ export class SequenceQueue extends OfflineQueue<ISequence> {
lastTimer: latest
? latest
: {
...timer,
id: status?.lastLog?.id
},
...timer,
id: status?.lastLog?.id
},
...timer
});
console.log('⏱ - local database updated');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class TimeSlotQueue extends OfflineQueue<ITimeSlot> {
)
await this._electronService.ipcRenderer.invoke('UPDATE_SYNCED_TIMER', {
id: interval.timerId,
startedAt: interval.startedAt,
timeSlotId
});
this._timeSlotQueueService.updater = { ...interval, timeSlotId };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ToastrNotificationService } from './toastr-notification.service';
import { ErrorClientService } from './error-client.service';
import { ErrorServerService } from './error-server.service';
import { LoggerService } from '../electron/services';
import { ErrorMapping } from './error-mapping.service';

@Injectable({
providedIn: 'root',
Expand All @@ -13,7 +14,8 @@ export class ErrorHandlerService implements ErrorHandler {
private readonly _toastrNotifierService: ToastrNotificationService,
private readonly _errorClientService: ErrorClientService,
private readonly _errorServerService: ErrorServerService,
private readonly _loggerService: LoggerService
private readonly _loggerService: LoggerService,
private readonly _errorMapping: ErrorMapping
) {
console.error = _loggerService.log.error;
Object.assign(console, _loggerService.log.functions);
Expand All @@ -22,8 +24,7 @@ export class ErrorHandlerService implements ErrorHandler {
public handleError(error: Error | HttpErrorResponse): void {
let message: string;
if (error instanceof HttpErrorResponse) {
this._errorServerService.message = error;
message = this._errorServerService.message;
message = this._errorMapping.mapErrorMessage(error);
} else {
this._errorClientService.message = error;
message = this._errorClientService.message;
Expand Down
46 changes: 46 additions & 0 deletions packages/desktop-ui-lib/src/lib/services/error-mapping.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Injectable({
providedIn: 'root',
})
export class ErrorMapping {
constructor(
private readonly _translateService: TranslateService
) {}
public mapErrorMessage(error: HttpErrorResponse): string {
if (error.error instanceof ErrorEvent) {
return this._translateService.instant('TIMER_TRACKER.TOASTR.NETWORK_ERROR', { message: error.error.message });
}

switch (error.status) {
case 0:
return this._translateService.instant('TIMER_TRACKER.TOASTR.NO_INTERNET_CONNECTION');
case 400:
return this.extractMessage(error, this._translateService.instant('TIMER_TRACKER.TOASTR.BAD_REQUEST'));
case 401:
return this._translateService.instant('TIMER_TRACKER.TOASTR.UNAUTHORIZED');
case 403:
return this._translateService.instant('TIMER_TRACKER.TOASTR.ACCESS_DENIED');
case 404:
return this._translateService.instant('TIMER_TRACKER.TOASTR.NOT_FOUND');
case 408:
return this._translateService.instant('TIMER_TRACKER.TOASTR.TIMEOUT');
case 500:
return this._translateService.instant('TIMER_TRACKER.TOASTR.SERVER_ERROR');
case 413:
return this._translateService.instant('TIMER_TRACKER.TOASTR.LARGE_FILE');
case 503:
return this._translateService.instant('TIMER_TRACKER.TOASTR.SERVICE_UNAVAILABLE');
default:
return this.extractMessage(error, this._translateService.instant('TIMER_TRACKER.TOASTR.UNEXPECTED_ERROR'));
}
}


private extractMessage(error: HttpErrorResponse, fallback: string): string {
if (error.error?.message) return error.error.message;
if (typeof error.error === 'string') return error.error;
return fallback;
}
}
1 change: 1 addition & 0 deletions packages/desktop-ui-lib/src/lib/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export * from './time-tracker-date.manager';
export * from './time-zone-manager';
export * from './toastr-notification.service';
export * from './user-organization-cache.service';
export * from './error-mapping.service';
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,26 @@ export class ToastrNotificationService extends NotificationService {

public success(message: string): void {
this._toastrService.success(message, this._notification.title, {
toastClass: 'toast-top-custom-title-bar'
toastClass: 'toast-top-custom-title-bar',
preventDuplicates: true
});
}

public error(message: string): void {
this._toastrService.danger(message, this._notification.title);
this._toastrService.danger(message, this._notification.title, {
preventDuplicates: true
});
}

public warn(message: string): void {
this._toastrService.warning(message, this._notification.title);
this._toastrService.warning(message, this._notification.title, {
preventDuplicates: true
});
}

public info(message: string): void {
this._toastrService.info(message, this._notification.title);
this._toastrService.info(message, this._notification.title, {
preventDuplicates: true
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1069,7 +1069,7 @@ export class SettingsComponent implements OnInit, AfterViewInit, OnDestroy {
default:
break;
}
this.toastrService.show(this._translateService.instant(message), `Success`, { status: arg?.status });
this._notifier.success(this._translateService.instant(message));
this._isRestart$.next(false);
}

Expand Down
Loading
Loading