update error handler
This commit is contained in:
@@ -18,6 +18,9 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
|
|||||||
|
|
||||||
return next(req).pipe(
|
return next(req).pipe(
|
||||||
catchError((error: HttpErrorResponse) => {
|
catchError((error: HttpErrorResponse) => {
|
||||||
|
console.log('error');
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
let errorMessage = 'خطای نامشخص رخ داده است';
|
let errorMessage = 'خطای نامشخص رخ داده است';
|
||||||
|
|
||||||
if (error.error instanceof ErrorEvent) {
|
if (error.error instanceof ErrorEvent) {
|
||||||
@@ -130,9 +133,13 @@ export enum ErrorType {
|
|||||||
* Helper function to determine error type
|
* Helper function to determine error type
|
||||||
*/
|
*/
|
||||||
export function getErrorType(error: HttpErrorResponse): ErrorType {
|
export function getErrorType(error: HttpErrorResponse): ErrorType {
|
||||||
|
console.log('getErrorType');
|
||||||
|
console.log(error);
|
||||||
|
|
||||||
if (error.error instanceof ErrorEvent) {
|
if (error.error instanceof ErrorEvent) {
|
||||||
return ErrorType.NETWORK;
|
return ErrorType.NETWORK;
|
||||||
}
|
}
|
||||||
|
console.log(error.status);
|
||||||
|
|
||||||
switch (error.status) {
|
switch (error.status) {
|
||||||
case 400:
|
case 400:
|
||||||
|
|||||||
@@ -140,19 +140,23 @@ export class ErrorHandlerService {
|
|||||||
* Extract user-friendly message from error
|
* Extract user-friendly message from error
|
||||||
*/
|
*/
|
||||||
private getUserMessage(error: HttpErrorResponse): string {
|
private getUserMessage(error: HttpErrorResponse): string {
|
||||||
if (error.error && typeof error.error === 'object') {
|
if (error.error) {
|
||||||
// Try different common message fields
|
if (error.error.errors && Array.isArray(error.error.errors)) {
|
||||||
return (
|
return error.error.errors[0];
|
||||||
error.error.message ||
|
}
|
||||||
error.error.error ||
|
if (typeof error.error === 'object') {
|
||||||
error.error.detail ||
|
// Try different common message fields
|
||||||
error.statusText ||
|
return (
|
||||||
'خطای نامشخص رخ داده است'
|
error.error.message ||
|
||||||
);
|
error.error.error ||
|
||||||
}
|
error.error.detail ||
|
||||||
|
error.statusText ||
|
||||||
if (typeof error.error === 'string') {
|
'خطای نامشخص رخ داده است'
|
||||||
return error.error;
|
);
|
||||||
|
}
|
||||||
|
if (typeof error.error === 'string') {
|
||||||
|
return error.error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error.statusText || 'خطای نامشخص رخ داده است';
|
return error.statusText || 'خطای نامشخص رخ داده است';
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
<p-dialog
|
||||||
|
header="شارژ لایسنس"
|
||||||
|
[(visible)]="visible"
|
||||||
|
[modal]="true"
|
||||||
|
[style]="{ width: '300px' }"
|
||||||
|
[closable]="true"
|
||||||
|
(onHide)="close()"
|
||||||
|
>
|
||||||
|
<form [formGroup]="form" (submit)="submit()" class="flex flex-col gap-4">
|
||||||
|
<app-input label="تعداد شارژ" [control]="form.controls.count" type="number" />
|
||||||
|
<app-form-footer-actions [submitLabel]="'ذخیره'" [loading]="submitLoading()" (onCancel)="close()" />
|
||||||
|
</form>
|
||||||
|
</p-dialog>
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import { AbstractFormDialog } from '@/shared/abstractClasses';
|
||||||
|
import { InputComponent } from '@/shared/components';
|
||||||
|
import { FormFooterActionsComponent } from '@/shared/components/formFooterActions/form-footer-actions.component';
|
||||||
|
import { Component, inject, Input } from '@angular/core';
|
||||||
|
import { ReactiveFormsModule, Validators } from '@angular/forms';
|
||||||
|
import { Dialog } from 'primeng/dialog';
|
||||||
|
import { ILicenseChargeRequest, ILicenseChargeResponse } from '../models';
|
||||||
|
import { PartnersService } from '../services/main.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'partner-charge-license-form-dialog',
|
||||||
|
templateUrl: './charge-license-form-dialog.component.html',
|
||||||
|
imports: [Dialog, ReactiveFormsModule, InputComponent, FormFooterActionsComponent],
|
||||||
|
})
|
||||||
|
export class PartnerChargeLicenseFormDialogComponent extends AbstractFormDialog<
|
||||||
|
ILicenseChargeRequest,
|
||||||
|
ILicenseChargeResponse
|
||||||
|
> {
|
||||||
|
@Input({ required: true }) partnerId!: string;
|
||||||
|
|
||||||
|
private readonly service = inject(PartnersService);
|
||||||
|
|
||||||
|
form = this.fb.group({
|
||||||
|
count: [0, [Validators.min(0)]],
|
||||||
|
});
|
||||||
|
|
||||||
|
submitForm(payload: ILicenseChargeRequest) {
|
||||||
|
return this.service.licenseCharge(this.partnerId, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,4 +5,5 @@ const baseUrl = '/api/v1/admin/partners';
|
|||||||
export const PARTNERS_API_ROUTES = {
|
export const PARTNERS_API_ROUTES = {
|
||||||
list: () => `${baseUrl}`,
|
list: () => `${baseUrl}`,
|
||||||
single: (id: string) => `${baseUrl}/${id}`,
|
single: (id: string) => `${baseUrl}/${id}`,
|
||||||
|
licenseCharge: (id: string) => `${baseUrl}/${id}/charge-license`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,3 +12,11 @@ export interface IPartnerRequest {
|
|||||||
code: string;
|
code: string;
|
||||||
license_quota: number;
|
license_quota: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//charge license
|
||||||
|
export interface ILicenseChargeRawResponse {}
|
||||||
|
export interface ILicenseChargeResponse extends ILicenseChargeRawResponse {}
|
||||||
|
|
||||||
|
export interface ILicenseChargeRequest {
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,14 @@ import { HttpClient } from '@angular/common/http';
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { PARTNERS_API_ROUTES } from '../constants';
|
import { PARTNERS_API_ROUTES } from '../constants';
|
||||||
import { IPartnerRawResponse, IPartnerRequest, IPartnerResponse } from '../models';
|
import {
|
||||||
|
ILicenseChargeRawResponse,
|
||||||
|
ILicenseChargeRequest,
|
||||||
|
ILicenseChargeResponse,
|
||||||
|
IPartnerRawResponse,
|
||||||
|
IPartnerRequest,
|
||||||
|
IPartnerResponse,
|
||||||
|
} from '../models';
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class PartnersService {
|
export class PartnersService {
|
||||||
@@ -14,15 +21,22 @@ export class PartnersService {
|
|||||||
getAll(): Observable<IPaginatedResponse<IPartnerResponse>> {
|
getAll(): Observable<IPaginatedResponse<IPartnerResponse>> {
|
||||||
return this.http.get<IPaginatedResponse<IPartnerRawResponse>>(this.apiRoutes.list());
|
return this.http.get<IPaginatedResponse<IPartnerRawResponse>>(this.apiRoutes.list());
|
||||||
}
|
}
|
||||||
getSingle(userId: string): Observable<IPartnerResponse> {
|
getSingle(partnerId: string): Observable<IPartnerResponse> {
|
||||||
return this.http.get<IPartnerRawResponse>(this.apiRoutes.single(userId));
|
return this.http.get<IPartnerRawResponse>(this.apiRoutes.single(partnerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
create(userData: IPartnerRequest): Observable<IPartnerResponse> {
|
create(userData: IPartnerRequest): Observable<IPartnerResponse> {
|
||||||
return this.http.post<IPartnerResponse>(this.apiRoutes.list(), userData);
|
return this.http.post<IPartnerResponse>(this.apiRoutes.list(), userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(userId: string, userData: IPartnerRequest): Observable<IPartnerResponse> {
|
update(partnerId: string, userData: IPartnerRequest): Observable<IPartnerResponse> {
|
||||||
return this.http.patch<IPartnerResponse>(this.apiRoutes.single(userId), userData);
|
return this.http.patch<IPartnerResponse>(this.apiRoutes.single(partnerId), userData);
|
||||||
|
}
|
||||||
|
|
||||||
|
licenseCharge(
|
||||||
|
partnerId: string,
|
||||||
|
data: ILicenseChargeRequest,
|
||||||
|
): Observable<ILicenseChargeResponse> {
|
||||||
|
return this.http.post<ILicenseChargeRawResponse>(this.apiRoutes.licenseCharge(partnerId), data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<div class="flex flex-col gap-6">
|
<div class="flex flex-col gap-6">
|
||||||
<app-card-data cardTitle="اطلاعات شریک تجاری" [editable]="true" [(editMode)]="editMode">
|
<app-card-data cardTitle="اطلاعات شریک تجاری" [editable]="true" [(editMode)]="editMode">
|
||||||
<ng-template #moreAction> </ng-template>
|
<ng-template #moreAction>
|
||||||
|
<p-button outlined size="small" (onClick)="openChargeDialog()"> شارژ لایسنس </p-button>
|
||||||
|
{{ visibleChargeFormDialog() }}
|
||||||
|
</ng-template>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="grid grid-cols-3 gap-4 items-center">
|
<div class="grid grid-cols-3 gap-4 items-center">
|
||||||
<app-key-value label="عنوان شریک تجاری" [value]="partner()?.name" />
|
<app-key-value label="عنوان شریک تجاری" [value]="partner()?.name" />
|
||||||
@@ -20,4 +23,10 @@
|
|||||||
[initialValues]="partner() || undefined"
|
[initialValues]="partner() || undefined"
|
||||||
(onSubmit)="getData()"
|
(onSubmit)="getData()"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<partner-charge-license-form-dialog
|
||||||
|
[(visible)]="visibleChargeFormDialog"
|
||||||
|
[partnerId]="partnerId()"
|
||||||
|
(onSubmit)="getData()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import { BreadcrumbService } from '@/core/services';
|
|||||||
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
import { AppCardComponent, KeyValueComponent } from '@/shared/components';
|
||||||
import { Component, computed, effect, inject, signal } from '@angular/core';
|
import { Component, computed, effect, inject, signal } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { Button } from 'primeng/button';
|
||||||
import { ConsumerAccountListComponent } from '../components/accounts/list.component';
|
import { ConsumerAccountListComponent } from '../components/accounts/list.component';
|
||||||
|
import { PartnerChargeLicenseFormDialogComponent } from '../components/charge-license-form-dialog.component';
|
||||||
import { GuildFormComponent } from '../components/form.component';
|
import { GuildFormComponent } from '../components/form.component';
|
||||||
import { superAdminPartnersNamedRoutes } from '../constants';
|
import { superAdminPartnersNamedRoutes } from '../constants';
|
||||||
import { PartnerStore } from '../store/partner.store';
|
import { PartnerStore } from '../store/partner.store';
|
||||||
@@ -10,7 +12,14 @@ import { PartnerStore } from '../store/partner.store';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user',
|
selector: 'app-user',
|
||||||
templateUrl: './single.component.html',
|
templateUrl: './single.component.html',
|
||||||
imports: [AppCardComponent, KeyValueComponent, GuildFormComponent, ConsumerAccountListComponent],
|
imports: [
|
||||||
|
AppCardComponent,
|
||||||
|
KeyValueComponent,
|
||||||
|
GuildFormComponent,
|
||||||
|
ConsumerAccountListComponent,
|
||||||
|
Button,
|
||||||
|
PartnerChargeLicenseFormDialogComponent,
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class PartnerComponent {
|
export class PartnerComponent {
|
||||||
private readonly store = inject(PartnerStore);
|
private readonly store = inject(PartnerStore);
|
||||||
@@ -22,6 +31,7 @@ export class PartnerComponent {
|
|||||||
|
|
||||||
readonly loading = computed(() => this.store.loading());
|
readonly loading = computed(() => this.store.loading());
|
||||||
readonly partner = computed(() => this.store.entity());
|
readonly partner = computed(() => this.store.entity());
|
||||||
|
visibleChargeFormDialog = signal(false);
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
effect(() => {
|
effect(() => {
|
||||||
@@ -46,4 +56,8 @@ export class PartnerComponent {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
openChargeDialog() {
|
||||||
|
this.visibleChargeFormDialog.set(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,13 @@
|
|||||||
[attr.maxlength]="preparedMaxLength || null"
|
[attr.maxlength]="preparedMaxLength || null"
|
||||||
[attr.type]="htmlType"
|
[attr.type]="htmlType"
|
||||||
[attr.autocomplete]="autocomplete"
|
[attr.autocomplete]="autocomplete"
|
||||||
[class]="
|
[classList]="
|
||||||
`${inputClass} w-full ${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`
|
[
|
||||||
|
inputClass,
|
||||||
|
'w-full',
|
||||||
|
`${size === 'large' ? 'p-inputtext-lg' : size === 'small' ? 'p-inputtext-sm' : ''}`,
|
||||||
|
suffixTemp || preparedSuffix() ? 'hasSuffix' : '',
|
||||||
|
].join(' ')
|
||||||
"
|
"
|
||||||
[required]="isRequired"
|
[required]="isRequired"
|
||||||
[invalid]="control.invalid && (control.touched || control.dirty)"
|
[invalid]="control.invalid && (control.touched || control.dirty)"
|
||||||
|
|||||||
@@ -224,9 +224,9 @@ export class InputComponent {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
$event.target.value = newValue;
|
$event.target.value = newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.control.setValue(newValue);
|
|
||||||
}
|
}
|
||||||
|
if (!['nationalId', 'phone', 'postalCode', 'mobile'].includes(this.type))
|
||||||
|
this.control.setValue(newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.preparedMaxLength && this.preparedMaxLength < value.length) {
|
if (this.preparedMaxLength && this.preparedMaxLength < value.length) {
|
||||||
|
|||||||
Reference in New Issue
Block a user