feat: a lot of a lot
This commit is contained in:
@@ -44,6 +44,8 @@ export type { CreateBarcodeTemplateAttributeRequest } from './models/CreateBarco
|
|||||||
export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse';
|
export type { CreateBarcodeTemplateAttributeResponse } from './models/CreateBarcodeTemplateAttributeResponse';
|
||||||
export type { CreateDealBillRequest } from './models/CreateDealBillRequest';
|
export type { CreateDealBillRequest } from './models/CreateDealBillRequest';
|
||||||
export type { CreateDealBillResponse } from './models/CreateDealBillResponse';
|
export type { CreateDealBillResponse } from './models/CreateDealBillResponse';
|
||||||
|
export type { CreateMarketplaceRequest } from './models/CreateMarketplaceRequest';
|
||||||
|
export type { CreateMarketplaceResponse } from './models/CreateMarketplaceResponse';
|
||||||
export type { CreatePaymentRecordRequest } from './models/CreatePaymentRecordRequest';
|
export type { CreatePaymentRecordRequest } from './models/CreatePaymentRecordRequest';
|
||||||
export type { CreatePaymentRecordResponse } from './models/CreatePaymentRecordResponse';
|
export type { CreatePaymentRecordResponse } from './models/CreatePaymentRecordResponse';
|
||||||
export type { CreatePayRateRequest } from './models/CreatePayRateRequest';
|
export type { CreatePayRateRequest } from './models/CreatePayRateRequest';
|
||||||
@@ -55,6 +57,7 @@ export type { CreateServicesKitRequest } from './models/CreateServicesKitRequest
|
|||||||
export type { CreateServicesKitResponse } from './models/CreateServicesKitResponse';
|
export type { CreateServicesKitResponse } from './models/CreateServicesKitResponse';
|
||||||
export type { CreateShippingWarehouseRequest } from './models/CreateShippingWarehouseRequest';
|
export type { CreateShippingWarehouseRequest } from './models/CreateShippingWarehouseRequest';
|
||||||
export type { CreateShippingWarehouseResponse } from './models/CreateShippingWarehouseResponse';
|
export type { CreateShippingWarehouseResponse } from './models/CreateShippingWarehouseResponse';
|
||||||
|
export type { CreateTaskResponse } from './models/CreateTaskResponse';
|
||||||
export type { CreateUserRequest } from './models/CreateUserRequest';
|
export type { CreateUserRequest } from './models/CreateUserRequest';
|
||||||
export type { CreateUserResponse } from './models/CreateUserResponse';
|
export type { CreateUserResponse } from './models/CreateUserResponse';
|
||||||
export type { DealAddKitRequest } from './models/DealAddKitRequest';
|
export type { DealAddKitRequest } from './models/DealAddKitRequest';
|
||||||
@@ -107,6 +110,8 @@ export type { DealUpdateServiceQuantityRequest } from './models/DealUpdateServic
|
|||||||
export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse';
|
export type { DealUpdateServiceQuantityResponse } from './models/DealUpdateServiceQuantityResponse';
|
||||||
export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest';
|
export type { DealUpdateServiceRequest } from './models/DealUpdateServiceRequest';
|
||||||
export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse';
|
export type { DealUpdateServiceResponse } from './models/DealUpdateServiceResponse';
|
||||||
|
export type { DeleteMarketplaceRequest } from './models/DeleteMarketplaceRequest';
|
||||||
|
export type { DeleteMarketplaceResponse } from './models/DeleteMarketplaceResponse';
|
||||||
export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest';
|
export type { DeletePaymentRecordRequest } from './models/DeletePaymentRecordRequest';
|
||||||
export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse';
|
export type { DeletePaymentRecordResponse } from './models/DeletePaymentRecordResponse';
|
||||||
export type { DeletePayRateRequest } from './models/DeletePayRateRequest';
|
export type { DeletePayRateRequest } from './models/DeletePayRateRequest';
|
||||||
@@ -128,6 +133,8 @@ export type { GetAllShippingWarehousesResponse } from './models/GetAllShippingWa
|
|||||||
export type { GetAllUsersResponse } from './models/GetAllUsersResponse';
|
export type { GetAllUsersResponse } from './models/GetAllUsersResponse';
|
||||||
export type { GetBarcodeTemplateByIdRequest } from './models/GetBarcodeTemplateByIdRequest';
|
export type { GetBarcodeTemplateByIdRequest } from './models/GetBarcodeTemplateByIdRequest';
|
||||||
export type { GetBarcodeTemplateByIdResponse } from './models/GetBarcodeTemplateByIdResponse';
|
export type { GetBarcodeTemplateByIdResponse } from './models/GetBarcodeTemplateByIdResponse';
|
||||||
|
export type { GetClientMarketplacesRequest } from './models/GetClientMarketplacesRequest';
|
||||||
|
export type { GetClientMarketplacesResponse } from './models/GetClientMarketplacesResponse';
|
||||||
export type { GetDealBillById } from './models/GetDealBillById';
|
export type { GetDealBillById } from './models/GetDealBillById';
|
||||||
export type { GetPaymentRecordsResponse } from './models/GetPaymentRecordsResponse';
|
export type { GetPaymentRecordsResponse } from './models/GetPaymentRecordsResponse';
|
||||||
export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest';
|
export type { GetProductBarcodePdfRequest } from './models/GetProductBarcodePdfRequest';
|
||||||
@@ -138,6 +145,8 @@ export type { GetServiceKitSchema } from './models/GetServiceKitSchema';
|
|||||||
export type { GetTimeTrackingRecordsRequest } from './models/GetTimeTrackingRecordsRequest';
|
export type { GetTimeTrackingRecordsRequest } from './models/GetTimeTrackingRecordsRequest';
|
||||||
export type { GetTimeTrackingRecordsResponse } from './models/GetTimeTrackingRecordsResponse';
|
export type { GetTimeTrackingRecordsResponse } from './models/GetTimeTrackingRecordsResponse';
|
||||||
export type { HTTPValidationError } from './models/HTTPValidationError';
|
export type { HTTPValidationError } from './models/HTTPValidationError';
|
||||||
|
export type { MarketplaceCreateSchema } from './models/MarketplaceCreateSchema';
|
||||||
|
export type { MarketplaceSchema } from './models/MarketplaceSchema';
|
||||||
export type { NotificationChannel } from './models/NotificationChannel';
|
export type { NotificationChannel } from './models/NotificationChannel';
|
||||||
export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
|
export type { PaginationInfoSchema } from './models/PaginationInfoSchema';
|
||||||
export type { PaymentRecordCreateSchema } from './models/PaymentRecordCreateSchema';
|
export type { PaymentRecordCreateSchema } from './models/PaymentRecordCreateSchema';
|
||||||
@@ -177,8 +186,12 @@ export type { ServiceSchema } from './models/ServiceSchema';
|
|||||||
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
export type { ServiceUpdateRequest } from './models/ServiceUpdateRequest';
|
||||||
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
export type { ServiceUpdateResponse } from './models/ServiceUpdateResponse';
|
||||||
export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema';
|
export type { ShippingWarehouseSchema } from './models/ShippingWarehouseSchema';
|
||||||
|
export type { SynchronizeMarketplaceRequest } from './models/SynchronizeMarketplaceRequest';
|
||||||
|
export type { TaskInfoResponse } from './models/TaskInfoResponse';
|
||||||
export type { TimeTrackingData } from './models/TimeTrackingData';
|
export type { TimeTrackingData } from './models/TimeTrackingData';
|
||||||
export type { TimeTrackingRecord } from './models/TimeTrackingRecord';
|
export type { TimeTrackingRecord } from './models/TimeTrackingRecord';
|
||||||
|
export type { UpdateMarketplaceRequest } from './models/UpdateMarketplaceRequest';
|
||||||
|
export type { UpdateMarketplaceResponse } from './models/UpdateMarketplaceResponse';
|
||||||
export type { UpdatePayRateRequest } from './models/UpdatePayRateRequest';
|
export type { UpdatePayRateRequest } from './models/UpdatePayRateRequest';
|
||||||
export type { UpdatePayRateResponse } from './models/UpdatePayRateResponse';
|
export type { UpdatePayRateResponse } from './models/UpdatePayRateResponse';
|
||||||
export type { UpdateServiceKitSchema } from './models/UpdateServiceKitSchema';
|
export type { UpdateServiceKitSchema } from './models/UpdateServiceKitSchema';
|
||||||
@@ -207,5 +220,6 @@ export { ProductService } from './services/ProductService';
|
|||||||
export { RoleService } from './services/RoleService';
|
export { RoleService } from './services/RoleService';
|
||||||
export { ServiceService } from './services/ServiceService';
|
export { ServiceService } from './services/ServiceService';
|
||||||
export { ShippingWarehouseService } from './services/ShippingWarehouseService';
|
export { ShippingWarehouseService } from './services/ShippingWarehouseService';
|
||||||
|
export { TaskService } from './services/TaskService';
|
||||||
export { TimeTrackingService } from './services/TimeTrackingService';
|
export { TimeTrackingService } from './services/TimeTrackingService';
|
||||||
export { UserService } from './services/UserService';
|
export { UserService } from './services/UserService';
|
||||||
|
|||||||
9
src/client/models/CreateMarketplaceRequest.ts
Normal file
9
src/client/models/CreateMarketplaceRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { MarketplaceCreateSchema } from './MarketplaceCreateSchema';
|
||||||
|
export type CreateMarketplaceRequest = {
|
||||||
|
marketplace: MarketplaceCreateSchema;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/CreateMarketplaceResponse.ts
Normal file
9
src/client/models/CreateMarketplaceResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type CreateMarketplaceResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/CreateTaskResponse.ts
Normal file
8
src/client/models/CreateTaskResponse.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type CreateTaskResponse = {
|
||||||
|
taskId: string;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/DeleteMarketplaceRequest.ts
Normal file
8
src/client/models/DeleteMarketplaceRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeleteMarketplaceRequest = {
|
||||||
|
marketplaceId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/DeleteMarketplaceResponse.ts
Normal file
9
src/client/models/DeleteMarketplaceResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type DeleteMarketplaceResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/GetClientMarketplacesRequest.ts
Normal file
8
src/client/models/GetClientMarketplacesRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type GetClientMarketplacesRequest = {
|
||||||
|
clientId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/GetClientMarketplacesResponse.ts
Normal file
9
src/client/models/GetClientMarketplacesResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { MarketplaceSchema } from './MarketplaceSchema';
|
||||||
|
export type GetClientMarketplacesResponse = {
|
||||||
|
marketplaces: Array<MarketplaceSchema>;
|
||||||
|
};
|
||||||
|
|
||||||
11
src/client/models/MarketplaceCreateSchema.ts
Normal file
11
src/client/models/MarketplaceCreateSchema.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type MarketplaceCreateSchema = {
|
||||||
|
name: string;
|
||||||
|
clientId: number;
|
||||||
|
baseMarketplaceKey: string;
|
||||||
|
authData: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
14
src/client/models/MarketplaceSchema.ts
Normal file
14
src/client/models/MarketplaceSchema.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { BaseMarketplaceSchema } from './BaseMarketplaceSchema';
|
||||||
|
import type { ClientSchema } from './ClientSchema';
|
||||||
|
export type MarketplaceSchema = {
|
||||||
|
name: string;
|
||||||
|
baseMarketplace: BaseMarketplaceSchema;
|
||||||
|
client: ClientSchema;
|
||||||
|
authData: Record<string, any>;
|
||||||
|
id: number;
|
||||||
|
};
|
||||||
|
|
||||||
8
src/client/models/SynchronizeMarketplaceRequest.ts
Normal file
8
src/client/models/SynchronizeMarketplaceRequest.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type SynchronizeMarketplaceRequest = {
|
||||||
|
marketplaceId: number;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/TaskInfoResponse.ts
Normal file
9
src/client/models/TaskInfoResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type TaskInfoResponse = {
|
||||||
|
taskId: string;
|
||||||
|
status: string;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/UpdateMarketplaceRequest.ts
Normal file
9
src/client/models/UpdateMarketplaceRequest.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { MarketplaceSchema } from './MarketplaceSchema';
|
||||||
|
export type UpdateMarketplaceRequest = {
|
||||||
|
marketplace: MarketplaceSchema;
|
||||||
|
};
|
||||||
|
|
||||||
9
src/client/models/UpdateMarketplaceResponse.ts
Normal file
9
src/client/models/UpdateMarketplaceResponse.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export type UpdateMarketplaceResponse = {
|
||||||
|
ok: boolean;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
@@ -28,4 +28,15 @@ export class AuthService {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Test
|
||||||
|
* @returns any Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static testAuthTestPost(): CancelablePromise<any> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/auth/test',
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export class ClientService {
|
|||||||
* @returns ClientCreateResponse Successful Response
|
* @returns ClientCreateResponse Successful Response
|
||||||
* @throws ApiError
|
* @throws ApiError
|
||||||
*/
|
*/
|
||||||
public static createClient({
|
public static createClientApi({
|
||||||
requestBody,
|
requestBody,
|
||||||
}: {
|
}: {
|
||||||
requestBody: ClientCreateRequest,
|
requestBody: ClientCreateRequest,
|
||||||
|
|||||||
@@ -2,7 +2,15 @@
|
|||||||
/* istanbul ignore file */
|
/* istanbul ignore file */
|
||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
import type { CreateMarketplaceRequest } from '../models/CreateMarketplaceRequest';
|
||||||
|
import type { CreateMarketplaceResponse } from '../models/CreateMarketplaceResponse';
|
||||||
|
import type { DeleteMarketplaceRequest } from '../models/DeleteMarketplaceRequest';
|
||||||
|
import type { DeleteMarketplaceResponse } from '../models/DeleteMarketplaceResponse';
|
||||||
import type { GetAllBaseMarketplacesResponse } from '../models/GetAllBaseMarketplacesResponse';
|
import type { GetAllBaseMarketplacesResponse } from '../models/GetAllBaseMarketplacesResponse';
|
||||||
|
import type { GetClientMarketplacesRequest } from '../models/GetClientMarketplacesRequest';
|
||||||
|
import type { GetClientMarketplacesResponse } from '../models/GetClientMarketplacesResponse';
|
||||||
|
import type { UpdateMarketplaceRequest } from '../models/UpdateMarketplaceRequest';
|
||||||
|
import type { UpdateMarketplaceResponse } from '../models/UpdateMarketplaceResponse';
|
||||||
import type { CancelablePromise } from '../core/CancelablePromise';
|
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||||
import { OpenAPI } from '../core/OpenAPI';
|
import { OpenAPI } from '../core/OpenAPI';
|
||||||
import { request as __request } from '../core/request';
|
import { request as __request } from '../core/request';
|
||||||
@@ -18,4 +26,84 @@ export class MarketplaceService {
|
|||||||
url: '/marketplace/base/get-all',
|
url: '/marketplace/base/get-all',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Get
|
||||||
|
* @returns GetClientMarketplacesResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getClientMarketplaces({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: GetClientMarketplacesRequest,
|
||||||
|
}): CancelablePromise<GetClientMarketplacesResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/marketplace/get',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create
|
||||||
|
* @returns CreateMarketplaceResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static createMarketplace({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: CreateMarketplaceRequest,
|
||||||
|
}): CancelablePromise<CreateMarketplaceResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/marketplace/create',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Delete
|
||||||
|
* @returns DeleteMarketplaceResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static deleteMarketplace({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: DeleteMarketplaceRequest,
|
||||||
|
}): CancelablePromise<DeleteMarketplaceResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/marketplace/delete',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Update
|
||||||
|
* @returns UpdateMarketplaceResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static updateMarketplace({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: UpdateMarketplaceRequest,
|
||||||
|
}): CancelablePromise<UpdateMarketplaceResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/marketplace/update',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
src/client/services/TaskService.ts
Normal file
53
src/client/services/TaskService.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/* generated using openapi-typescript-codegen -- do not edit */
|
||||||
|
/* istanbul ignore file */
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
import type { CreateTaskResponse } from '../models/CreateTaskResponse';
|
||||||
|
import type { SynchronizeMarketplaceRequest } from '../models/SynchronizeMarketplaceRequest';
|
||||||
|
import type { TaskInfoResponse } from '../models/TaskInfoResponse';
|
||||||
|
import type { CancelablePromise } from '../core/CancelablePromise';
|
||||||
|
import { OpenAPI } from '../core/OpenAPI';
|
||||||
|
import { request as __request } from '../core/request';
|
||||||
|
export class TaskService {
|
||||||
|
/**
|
||||||
|
* Synchronize Marketplace
|
||||||
|
* @returns CreateTaskResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static createSynchronizeMarketplaceTask({
|
||||||
|
requestBody,
|
||||||
|
}: {
|
||||||
|
requestBody: SynchronizeMarketplaceRequest,
|
||||||
|
}): CancelablePromise<CreateTaskResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/task/synchronize-marketplace',
|
||||||
|
body: requestBody,
|
||||||
|
mediaType: 'application/json',
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Task Info
|
||||||
|
* @returns TaskInfoResponse Successful Response
|
||||||
|
* @throws ApiError
|
||||||
|
*/
|
||||||
|
public static getTaskInfo({
|
||||||
|
taskId,
|
||||||
|
}: {
|
||||||
|
taskId: string,
|
||||||
|
}): CancelablePromise<TaskInfoResponse> {
|
||||||
|
return __request(OpenAPI, {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/task/info/{task_id}',
|
||||||
|
path: {
|
||||||
|
'task_id': taskId,
|
||||||
|
},
|
||||||
|
errors: {
|
||||||
|
422: `Validation Error`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
IconHome2,
|
IconHome2,
|
||||||
IconLogout,
|
IconLogout,
|
||||||
IconMan,
|
IconMan,
|
||||||
IconMoon,
|
IconMoon, IconShoppingCart,
|
||||||
IconSun,
|
IconSun,
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import classes from './Navbar.module.css';
|
import classes from './Navbar.module.css';
|
||||||
@@ -76,6 +76,11 @@ const mockdata = [
|
|||||||
icon: IconBuildingWarehouse,
|
icon: IconBuildingWarehouse,
|
||||||
label: 'Склады отгрузки',
|
label: 'Склады отгрузки',
|
||||||
href: '/shipping_warehouses'
|
href: '/shipping_warehouses'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon:IconShoppingCart,
|
||||||
|
label: 'Маркетплейсы',
|
||||||
|
href: '/marketplaces'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const ClientSelectNew: FC<Props> = (props) => {
|
|||||||
const {clients} = useClientsList();
|
const {clients} = useClientsList();
|
||||||
return (
|
return (
|
||||||
<ObjectSelect
|
<ObjectSelect
|
||||||
|
searchable
|
||||||
data={clients}
|
data={clients}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
|||||||
101
src/features/tasksSlice.tsx
Normal file
101
src/features/tasksSlice.tsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import {createSlice, PayloadAction} from "@reduxjs/toolkit";
|
||||||
|
import {notifications} from "../shared/lib/notifications.ts";
|
||||||
|
import {IconCheck, IconX} from "@tabler/icons-react";
|
||||||
|
import {rem} from "@mantine/core";
|
||||||
|
|
||||||
|
export type TaskData = {
|
||||||
|
title: string;
|
||||||
|
message: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TaskConfig = {
|
||||||
|
onSuccessData: TaskData;
|
||||||
|
onErrorData: TaskData;
|
||||||
|
onLoadingData: TaskData;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Task = {
|
||||||
|
id: string;
|
||||||
|
config: TaskConfig;
|
||||||
|
info: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface TasksState {
|
||||||
|
tasks: Task[];
|
||||||
|
notificationTaskMap: { [key: string]: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: TasksState = {
|
||||||
|
tasks: [],
|
||||||
|
notificationTaskMap: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const tasksSlice = createSlice({
|
||||||
|
name: "tasks",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
addTask: (state, action: PayloadAction<Task>) => {
|
||||||
|
const task = action.payload;
|
||||||
|
state.notificationTaskMap[task.id] = notifications.show({
|
||||||
|
loading: true,
|
||||||
|
title: task.config.onLoadingData.title,
|
||||||
|
message: task.config.onLoadingData.message,
|
||||||
|
autoClose: false,
|
||||||
|
withCloseButton: false,
|
||||||
|
withBorder: true,
|
||||||
|
radius: "sm"
|
||||||
|
});
|
||||||
|
state.tasks.push(task);
|
||||||
|
localStorage.setItem("tasks", JSON.stringify(state.tasks));
|
||||||
|
},
|
||||||
|
removeTask: (state, action: PayloadAction<string>) => {
|
||||||
|
state.tasks = state.tasks.filter((task) => task.id !== action.payload);
|
||||||
|
localStorage.setItem("tasks", JSON.stringify(state.tasks));
|
||||||
|
},
|
||||||
|
failTask: (state, action: PayloadAction<Task>) => {
|
||||||
|
const task = action.payload;
|
||||||
|
const notificationId = state.notificationTaskMap[task.id];
|
||||||
|
|
||||||
|
if (!notificationId) return;
|
||||||
|
notifications.update({
|
||||||
|
id: notificationId,
|
||||||
|
color: 'red',
|
||||||
|
title: task.config.onErrorData.title,
|
||||||
|
message: task.config.onErrorData.message,
|
||||||
|
icon: <IconX style={{width: rem(18), height: rem(18)}}/>,
|
||||||
|
loading: false,
|
||||||
|
autoClose: 2000,
|
||||||
|
})
|
||||||
|
state.tasks = state.tasks.filter((task) => task.id !== action.payload.id);
|
||||||
|
state.notificationTaskMap = Object.fromEntries(
|
||||||
|
Object.entries(state.notificationTaskMap).filter(([taskId]) => taskId !== task.id)
|
||||||
|
);
|
||||||
|
localStorage.setItem("tasks", JSON.stringify(state.tasks));
|
||||||
|
},
|
||||||
|
successTask: (state, action: PayloadAction<Task>) => {
|
||||||
|
const task = action.payload;
|
||||||
|
const notificationId = state.notificationTaskMap[task.id];
|
||||||
|
|
||||||
|
if (!notificationId) return;
|
||||||
|
notifications.update({
|
||||||
|
id: notificationId,
|
||||||
|
color: 'teal',
|
||||||
|
title: task.config.onSuccessData.title,
|
||||||
|
message: task.config.onSuccessData.message,
|
||||||
|
icon: <IconCheck style={{width: rem(18), height: rem(18)}}/>,
|
||||||
|
loading: false,
|
||||||
|
autoClose: 2000,
|
||||||
|
})
|
||||||
|
state.tasks = state.tasks.filter((task) => task.id !== action.payload.id);
|
||||||
|
state.notificationTaskMap = Object.fromEntries(
|
||||||
|
Object.entries(state.notificationTaskMap).filter(([taskId]) => taskId !== task.id)
|
||||||
|
);
|
||||||
|
|
||||||
|
localStorage.setItem("tasks", JSON.stringify(state.tasks));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {addTask, removeTask, successTask, failTask} = tasksSlice.actions;
|
||||||
|
|
||||||
|
export default tasksSlice.reducer;
|
||||||
54
src/hooks/usePollingEffect.tsx
Normal file
54
src/hooks/usePollingEffect.tsx
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import {useEffect, useRef, DependencyList} from 'react';
|
||||||
|
|
||||||
|
type UsePollingEffectOptions = {
|
||||||
|
interval?: number;
|
||||||
|
isActive?: boolean;
|
||||||
|
onCleanUp?: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
function usePollingEffect(
|
||||||
|
asyncCallback: () => Promise<void>,
|
||||||
|
dependencies: DependencyList = [],
|
||||||
|
options: UsePollingEffectOptions = {}
|
||||||
|
): void {
|
||||||
|
const {
|
||||||
|
interval = 3000,
|
||||||
|
isActive = true,
|
||||||
|
onCleanUp = () => {
|
||||||
|
}
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const timeoutIdRef = useRef<number | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isActive) { // If not active, don't do anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stopped = false;
|
||||||
|
|
||||||
|
const pollingCallback = async () => {
|
||||||
|
try {
|
||||||
|
await asyncCallback();
|
||||||
|
} finally {
|
||||||
|
if (!stopped) {
|
||||||
|
timeoutIdRef.current = setTimeout(pollingCallback, interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Immediately invoke the polling callback when the effect runs
|
||||||
|
pollingCallback();
|
||||||
|
|
||||||
|
// Clean up function to clear the timeout if the component unmounts or dependencies change
|
||||||
|
return () => {
|
||||||
|
stopped = true; // This will prevent new timeouts from being scheduled
|
||||||
|
if (timeoutIdRef.current) {
|
||||||
|
clearTimeout(timeoutIdRef.current);
|
||||||
|
}
|
||||||
|
onCleanUp();
|
||||||
|
};
|
||||||
|
}, [...dependencies, interval, isActive]); // dependencies array spread with interval
|
||||||
|
}
|
||||||
|
|
||||||
|
export default usePollingEffect;
|
||||||
@@ -19,6 +19,7 @@ import {ModalsProvider} from "@mantine/modals";
|
|||||||
import {OpenAPI} from "./client";
|
import {OpenAPI} from "./client";
|
||||||
import {DatesProvider} from "@mantine/dates";
|
import {DatesProvider} from "@mantine/dates";
|
||||||
import {modals} from "./modals/modals.ts";
|
import {modals} from "./modals/modals.ts";
|
||||||
|
import TasksProvider from "./providers/TasksProvider/TasksProvider.tsx";
|
||||||
|
|
||||||
// Configuring router
|
// Configuring router
|
||||||
const router = createRouter({routeTree})
|
const router = createRouter({routeTree})
|
||||||
@@ -46,8 +47,12 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|||||||
<MantineProvider defaultColorScheme={"dark"}>
|
<MantineProvider defaultColorScheme={"dark"}>
|
||||||
<ModalsProvider modals={modals}>
|
<ModalsProvider modals={modals}>
|
||||||
<DatesProvider settings={{locale: 'ru'}}>
|
<DatesProvider settings={{locale: 'ru'}}>
|
||||||
<RouterProvider router={router}/>
|
<TasksProvider>
|
||||||
<Notifications/>
|
|
||||||
|
<RouterProvider router={router}/>
|
||||||
|
<Notifications/>
|
||||||
|
</TasksProvider>
|
||||||
|
|
||||||
</DatesProvider>
|
</DatesProvider>
|
||||||
</ModalsProvider>
|
</ModalsProvider>
|
||||||
</MantineProvider>
|
</MantineProvider>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import ServiceKitModalForm from "../pages/ServicesPage/modals/ServicesKitModalFo
|
|||||||
import ServicesKitSelectModal from "./ServicesKitSelectModal/ServicesKitSelectModal.tsx";
|
import ServicesKitSelectModal from "./ServicesKitSelectModal/ServicesKitSelectModal.tsx";
|
||||||
import SelectDealProductsModal from "../pages/LeadsPage/modals/SelectDealProductsModal.tsx";
|
import SelectDealProductsModal from "../pages/LeadsPage/modals/SelectDealProductsModal.tsx";
|
||||||
import ShippingWarehouseForm from "../pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx";
|
import ShippingWarehouseForm from "../pages/ShippingWarehousesPage/modals/ShippingWarehouseForm.tsx";
|
||||||
|
import MarketplaceFormModal from "../pages/MarketplacesPage/modals/MarketplaceFormModal/MarketplaceFormModal.tsx";
|
||||||
|
|
||||||
export const modals = {
|
export const modals = {
|
||||||
enterDeadline: EnterDeadlineModal,
|
enterDeadline: EnterDeadlineModal,
|
||||||
@@ -42,5 +43,6 @@ export const modals = {
|
|||||||
serviceKitModalForm: ServiceKitModalForm,
|
serviceKitModalForm: ServiceKitModalForm,
|
||||||
servicesKitSelectModal: ServicesKitSelectModal,
|
servicesKitSelectModal: ServicesKitSelectModal,
|
||||||
selectDealProductsModal: SelectDealProductsModal,
|
selectDealProductsModal: SelectDealProductsModal,
|
||||||
shippingWarehouseForm: ShippingWarehouseForm
|
shippingWarehouseForm: ShippingWarehouseForm,
|
||||||
|
marketplaceFormModal: MarketplaceFormModal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import {CRUDTableProps} from "../../../../types/CRUDTable.tsx";
|
||||||
|
import {ClientSchema, MarketplaceSchema} from "../../../../client";
|
||||||
|
import {FC} from "react";
|
||||||
|
import {BaseTable} from "../../../../components/BaseTable/BaseTable.tsx";
|
||||||
|
import useMarketplacesTableColumns from "./columns.tsx";
|
||||||
|
import {MRT_TableOptions} from "mantine-react-table";
|
||||||
|
import {ActionIcon, Button, Flex, rem, Text, Tooltip} from "@mantine/core";
|
||||||
|
import {modals} from "@mantine/modals";
|
||||||
|
import {IconEdit, IconRefresh, IconTrash} from "@tabler/icons-react";
|
||||||
|
|
||||||
|
type RestProps = {
|
||||||
|
client?: ClientSchema;
|
||||||
|
onSynchronize?: (marketplace: MarketplaceSchema) => void;
|
||||||
|
|
||||||
|
}
|
||||||
|
type Props = CRUDTableProps<MarketplaceSchema> & RestProps;
|
||||||
|
|
||||||
|
const MarketplacesTable: FC<Props> = ({onDelete, onChange, onCreate, items, client, onSynchronize}) => {
|
||||||
|
const columns = useMarketplacesTableColumns();
|
||||||
|
const onDeleteClick = (marketplace: MarketplaceSchema) => {
|
||||||
|
if (!onDelete) return;
|
||||||
|
modals.openConfirmModal({
|
||||||
|
title: 'Удаление маркетплейса',
|
||||||
|
children: (
|
||||||
|
<Text size="sm">
|
||||||
|
Вы уверены что хотите удалить маркетплейс {marketplace.name}
|
||||||
|
</Text>
|
||||||
|
),
|
||||||
|
labels: {confirm: 'Да', cancel: "Нет"},
|
||||||
|
confirmProps: {color: 'red'},
|
||||||
|
onConfirm: () => onDelete(marketplace)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const onEditClick = (marketplace: MarketplaceSchema) => {
|
||||||
|
if (!onChange) return;
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "marketplaceFormModal",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onChange: (event) => onChange(event),
|
||||||
|
element: marketplace
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onCreateClick = () => {
|
||||||
|
if (!onCreate || !client) return;
|
||||||
|
modals.openContextModal({
|
||||||
|
modal: "marketplaceFormModal",
|
||||||
|
withCloseButton: false,
|
||||||
|
innerProps: {
|
||||||
|
onCreate: (event) => onCreate({...event, client: client})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<BaseTable
|
||||||
|
data={items}
|
||||||
|
columns={columns}
|
||||||
|
restProps={{
|
||||||
|
enableSorting: false,
|
||||||
|
enableColumnActions: false,
|
||||||
|
enableTopToolbar: true,
|
||||||
|
renderTopToolbar: (
|
||||||
|
<Flex p={rem(10)} justify="end">
|
||||||
|
<Button
|
||||||
|
disabled={!client}
|
||||||
|
variant={"default"}
|
||||||
|
onClick={() => onCreateClick()}>
|
||||||
|
Добавить
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
),
|
||||||
|
enableRowActions: true,
|
||||||
|
renderRowActions: ({row}) => (
|
||||||
|
<Flex gap="md">
|
||||||
|
<Tooltip label="Редактировать">
|
||||||
|
<ActionIcon
|
||||||
|
onClick={() => onEditClick(row.original)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconEdit/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Удалить">
|
||||||
|
<ActionIcon onClick={() => onDeleteClick(row.original)} variant={"default"}>
|
||||||
|
<IconTrash/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip label="Синхронизировать">
|
||||||
|
<ActionIcon onClick={() => onSynchronize && onSynchronize(row.original)}
|
||||||
|
variant={"default"}>
|
||||||
|
<IconRefresh/>
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
} as MRT_TableOptions<MarketplaceSchema>}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default MarketplacesTable;
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import {MarketplaceSchema} from "../../../../client";
|
||||||
|
import {MRT_ColumnDef} from "mantine-react-table";
|
||||||
|
import {useMemo} from "react";
|
||||||
|
import {ActionIcon, Image} from "@mantine/core";
|
||||||
|
|
||||||
|
const useMarketplacesTableColumns = () => {
|
||||||
|
return useMemo<MRT_ColumnDef<MarketplaceSchema>[]>(() => [
|
||||||
|
{
|
||||||
|
header: "Маркетплейс",
|
||||||
|
size: 10,
|
||||||
|
Cell: ({row}) => (
|
||||||
|
<ActionIcon variant={"transparent"}>
|
||||||
|
<Image src={row.original.baseMarketplace?.iconUrl || ""}/>
|
||||||
|
</ActionIcon>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "name",
|
||||||
|
header: "Название",
|
||||||
|
enableSorting: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: "client.name",
|
||||||
|
header: "Клиент",
|
||||||
|
enableSorting: false,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// accessorKey: "authData",
|
||||||
|
// header: "Данные авторизации",
|
||||||
|
// enableSorting: false,
|
||||||
|
// },
|
||||||
|
], []);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useMarketplacesTableColumns;
|
||||||
115
src/pages/MarketplacesPage/hooks/useMarketplacesPageState.tsx
Normal file
115
src/pages/MarketplacesPage/hooks/useMarketplacesPageState.tsx
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {ClientSchema, MarketplaceSchema, MarketplaceService, TaskService} from "../../../client";
|
||||||
|
import {notifications} from "../../../shared/lib/notifications.ts";
|
||||||
|
import {RootState, useAppDispatch} from "../../../redux/store.ts";
|
||||||
|
import {addTask} from "../../../features/tasksSlice.tsx";
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
|
||||||
|
const useMarketplacesPageState = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const tasks = useSelector((state: RootState) => state.tasks.tasks);
|
||||||
|
const [client, setClient] = useState<ClientSchema | undefined>();
|
||||||
|
const [items, setItems] = useState<MarketplaceSchema[]>([]);
|
||||||
|
const fetchMarketplaces = async () => {
|
||||||
|
if (!client) return;
|
||||||
|
MarketplaceService.getClientMarketplaces({
|
||||||
|
requestBody: {
|
||||||
|
clientId: client.id
|
||||||
|
}
|
||||||
|
}).then((response) => {
|
||||||
|
setItems(response.marketplaces);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCreate = (marketplace: MarketplaceSchema) => {
|
||||||
|
MarketplaceService.createMarketplace({
|
||||||
|
requestBody: {
|
||||||
|
marketplace: {
|
||||||
|
...marketplace,
|
||||||
|
clientId: marketplace.client.id,
|
||||||
|
baseMarketplaceKey: marketplace.baseMarketplace.key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await fetchMarketplaces();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onDelete = (marketplace: MarketplaceSchema) => {
|
||||||
|
MarketplaceService.deleteMarketplace({
|
||||||
|
requestBody: {
|
||||||
|
marketplaceId: marketplace.id
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await fetchMarketplaces();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const onChange = (marketplace: MarketplaceSchema) => {
|
||||||
|
MarketplaceService.updateMarketplace({
|
||||||
|
requestBody: {
|
||||||
|
marketplace: marketplace
|
||||||
|
}
|
||||||
|
}).then(async ({ok, message}) => {
|
||||||
|
notifications.guess(ok, {message});
|
||||||
|
if (!ok) return;
|
||||||
|
await fetchMarketplaces();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSynchronize = (marketplace: MarketplaceSchema) => {
|
||||||
|
|
||||||
|
// If there is already synchronization task for this marketplace show notifications.error()
|
||||||
|
const task = tasks.find(task => task.info.marketplaceId === marketplace.id);
|
||||||
|
if (task) {
|
||||||
|
notifications.error({
|
||||||
|
title: 'Ошибка',
|
||||||
|
message: `Синхронизация маркетплейса ${marketplace.name} уже запущена`
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
TaskService.createSynchronizeMarketplaceTask({
|
||||||
|
requestBody: {
|
||||||
|
marketplaceId:
|
||||||
|
marketplace.id
|
||||||
|
}
|
||||||
|
}).then(({taskId}) => {
|
||||||
|
dispatch(addTask({
|
||||||
|
id: taskId,
|
||||||
|
config: {
|
||||||
|
onErrorData: {
|
||||||
|
title: 'Ошибка',
|
||||||
|
message: `Ошибка синхронизации маркетплейса: ${marketplace.name}`
|
||||||
|
},
|
||||||
|
onLoadingData: {
|
||||||
|
title: 'Синхронизация',
|
||||||
|
message: `Синхронизация маркетплейса: ${marketplace.name}`
|
||||||
|
},
|
||||||
|
onSuccessData: {
|
||||||
|
title: 'Успех',
|
||||||
|
message: `Маркетплейс ${marketplace.name} успешно синхронизирован`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
marketplaceId: marketplace.id
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
fetchMarketplaces();
|
||||||
|
}, [client]);
|
||||||
|
return {
|
||||||
|
client,
|
||||||
|
setClient,
|
||||||
|
items,
|
||||||
|
onDelete,
|
||||||
|
onChange,
|
||||||
|
onCreate,
|
||||||
|
onSynchronize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default useMarketplacesPageState;
|
||||||
1
src/pages/MarketplacesPage/index.ts
Normal file
1
src/pages/MarketplacesPage/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {MarketplacesPage} from './ui/MarketplacesPage.tsx';
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import {TextInput} from "@mantine/core";
|
||||||
|
import {BaseFormInputProps} from "../../../../types/utils.ts";
|
||||||
|
import {FC} from "react";
|
||||||
|
import {BaseMarketplaceSchema} from "../../../../client";
|
||||||
|
import {BaseMarketplaceType} from "../../../../shared/enums/BaseMarketplaceType.ts";
|
||||||
|
|
||||||
|
type RestProps = {
|
||||||
|
baseMarketplace: BaseMarketplaceSchema;
|
||||||
|
}
|
||||||
|
type Props = BaseFormInputProps<Record<string, string>> & RestProps;
|
||||||
|
|
||||||
|
const MarketplaceAuthDataInput: FC<Props> = (props: Props) => {
|
||||||
|
console.log(props.baseMarketplace);
|
||||||
|
const getWildberriesInputs = () => {
|
||||||
|
// return input that sets record "Authorization" to value
|
||||||
|
return <TextInput
|
||||||
|
{...props}
|
||||||
|
label={"Ключ авторизации"}
|
||||||
|
placeholder={"Введите ключ авторизации"}
|
||||||
|
value={props.value["Authorization"] || ""}
|
||||||
|
onChange={(value) => props.onChange({...props.value, Authorization: value.target.value})}
|
||||||
|
/>
|
||||||
|
|
||||||
|
}
|
||||||
|
const getOzonInputs = () => {
|
||||||
|
// return input that sets record "Client-Id" and "Api-Key" to value
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<TextInput
|
||||||
|
{...props}
|
||||||
|
label={"Client-Id"}
|
||||||
|
placeholder={"Введите Client-Id"}
|
||||||
|
value={props.value["Client-Id"] || ""}
|
||||||
|
onChange={(value) => props.onChange({...props.value, "Client-Id": value.target.value})}
|
||||||
|
/>
|
||||||
|
<TextInput
|
||||||
|
{...props}
|
||||||
|
label={"Api-Key"}
|
||||||
|
placeholder={"Введите Api-Key"}
|
||||||
|
value={props.value["Api-Key"] || ""}
|
||||||
|
onChange={(value) => props.onChange({...props.value, "Api-Key": value.target.value})}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
const getYandexMarketInputs = () => {
|
||||||
|
}
|
||||||
|
|
||||||
|
const getInputs = () => {
|
||||||
|
if (props.baseMarketplace.key === BaseMarketplaceType.WILDBERRIES) {
|
||||||
|
return getWildberriesInputs();
|
||||||
|
}
|
||||||
|
if (props.baseMarketplace.key === BaseMarketplaceType.OZON) {
|
||||||
|
return getOzonInputs();
|
||||||
|
}
|
||||||
|
if (props.baseMarketplace.key === BaseMarketplaceType.YANDEX_MARKET) {
|
||||||
|
return getYandexMarketInputs();
|
||||||
|
}
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{getInputs()}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MarketplaceAuthDataInput;
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import {ContextModalProps} from "@mantine/modals";
|
||||||
|
import BaseFormModal, {CreateEditFormProps} from "../../../ClientsPage/modals/BaseFormModal/BaseFormModal.tsx";
|
||||||
|
import {MarketplaceSchema} from "../../../../client";
|
||||||
|
import {useForm} from "@mantine/form";
|
||||||
|
import {Fieldset, Flex, rem, TextInput} from "@mantine/core";
|
||||||
|
import BaseMarketplaceSelect from "../../../../components/Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
|
||||||
|
import MarketplaceAuthDataInput from "./MarketplaceAuthDataInput.tsx";
|
||||||
|
|
||||||
|
type Props = CreateEditFormProps<MarketplaceSchema>
|
||||||
|
const MarketplaceFormModal = ({
|
||||||
|
context,
|
||||||
|
id,
|
||||||
|
innerProps
|
||||||
|
}: ContextModalProps<Props>) => {
|
||||||
|
const isEditing = 'element' in innerProps;
|
||||||
|
const initialValue: Partial<MarketplaceSchema> = isEditing ? innerProps.element : {
|
||||||
|
authData: {
|
||||||
|
Authorization: '',
|
||||||
|
"Client-Id": '',
|
||||||
|
"Api-Key": ''
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const form = useForm<Partial<MarketplaceSchema>>({
|
||||||
|
initialValues: initialValue,
|
||||||
|
validate: {
|
||||||
|
baseMarketplace: (baseMarketplace) => !baseMarketplace && "Необходимо указать базовый маркетплейс",
|
||||||
|
name: (name) => !name && "Необходимо указать название маркетплейса",
|
||||||
|
authData: (authData) => !authData && "Необходимо указать данные авторизации"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<BaseFormModal
|
||||||
|
form={form}
|
||||||
|
closeOnSubmit
|
||||||
|
onClose={() => context.closeContextModal(id)}
|
||||||
|
{...innerProps}
|
||||||
|
>
|
||||||
|
<BaseFormModal.Body>
|
||||||
|
<>
|
||||||
|
<Fieldset legend={"Общие параметры"}>
|
||||||
|
<Flex direction={"column"} gap={rem(10)}>
|
||||||
|
<TextInput
|
||||||
|
label={"Название"}
|
||||||
|
placeholder={"Введите название маркетплейса"}
|
||||||
|
{...form.getInputProps("name")}
|
||||||
|
/>
|
||||||
|
<BaseMarketplaceSelect
|
||||||
|
label={"Базовый маркетплейс"}
|
||||||
|
placeholder={"Выберите базовый маркетплейс"}
|
||||||
|
{...form.getInputProps("baseMarketplace")}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{form.values.baseMarketplace &&
|
||||||
|
<MarketplaceAuthDataInput
|
||||||
|
baseMarketplace={form.values.baseMarketplace}
|
||||||
|
value={form.values.authData as Record<string, string>}
|
||||||
|
onChange={(value) => form.setFieldValue("authData", value)}
|
||||||
|
error={form.getInputProps("authData").error}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
</Flex>
|
||||||
|
</Fieldset>
|
||||||
|
</>
|
||||||
|
</BaseFormModal.Body>
|
||||||
|
</BaseFormModal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default MarketplaceFormModal;
|
||||||
17
src/pages/MarketplacesPage/ui/MarketplacesPage.module.css
Normal file
17
src/pages/MarketplacesPage/ui/MarketplacesPage.module.css
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1;
|
||||||
|
gap: rem(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-panel {
|
||||||
|
padding: rem(5);
|
||||||
|
gap: rem(10);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-panel-last-item {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
29
src/pages/MarketplacesPage/ui/MarketplacesPage.tsx
Normal file
29
src/pages/MarketplacesPage/ui/MarketplacesPage.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import styles from './MarketplacesPage.module.css';
|
||||||
|
import PageBlock from "../../../components/PageBlock/PageBlock.tsx";
|
||||||
|
import ClientSelectNew from "../../../components/Selects/ClientSelectNew/ClientSelectNew.tsx";
|
||||||
|
import useMarketplacesPageState from "../hooks/useMarketplacesPageState.tsx";
|
||||||
|
import MarketplacesTable from "../components/MarketplacesTable/MarketplacesTable.tsx";
|
||||||
|
|
||||||
|
export const MarketplacesPage = () => {
|
||||||
|
const state = useMarketplacesPageState();
|
||||||
|
return (
|
||||||
|
<div className={styles['container']}>
|
||||||
|
<PageBlock>
|
||||||
|
<div className={styles['top-panel']}>
|
||||||
|
<ClientSelectNew
|
||||||
|
placeholder={'Выберите клиента'}
|
||||||
|
onChange={state.setClient}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</PageBlock>
|
||||||
|
<PageBlock>
|
||||||
|
<>
|
||||||
|
<MarketplacesTable
|
||||||
|
{...state}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</>
|
||||||
|
</PageBlock>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
63
src/providers/TasksProvider/TasksProvider.tsx
Normal file
63
src/providers/TasksProvider/TasksProvider.tsx
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import {FC, ReactNode, useEffect, useState} from "react";
|
||||||
|
import {TaskStatus} from "../../shared/enums/TaskStatus";
|
||||||
|
import usePollingEffect from "../../hooks/usePollingEffect.tsx";
|
||||||
|
import {RootState, useAppDispatch} from "../../redux/store.ts";
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {TaskService} from "../../client";
|
||||||
|
import {addTask, failTask, successTask, Task} from "../../features/tasksSlice.tsx";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
|
||||||
|
const POLLING_STATUSES = [
|
||||||
|
TaskStatus.RETRY,
|
||||||
|
TaskStatus.STARTED,
|
||||||
|
TaskStatus.PENDING,
|
||||||
|
] as string[];
|
||||||
|
|
||||||
|
const TasksProvider: FC<Props> = ({children}) => {
|
||||||
|
const [isPooling, setIsPooling] = useState(false);
|
||||||
|
const tasks = useSelector((state: RootState) => state.tasks.tasks);
|
||||||
|
const notificationTaskMap = useSelector((state: RootState) => state.tasks.notificationTaskMap);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const poolTasks = async () => {
|
||||||
|
// get statuses of all tasks
|
||||||
|
const taskInfos = await Promise.all(
|
||||||
|
tasks.map((task) => TaskService.getTaskInfo({taskId: task.id}))
|
||||||
|
);
|
||||||
|
taskInfos.forEach(({taskId, status}) => {
|
||||||
|
if (POLLING_STATUSES.includes(status)) return;
|
||||||
|
const task = tasks.find((task) => task.id === taskId);
|
||||||
|
if (!task) return;
|
||||||
|
if (status === TaskStatus.FAILURE) {
|
||||||
|
dispatch(failTask(task));
|
||||||
|
} else if (status === TaskStatus.SUCCESS) {
|
||||||
|
dispatch(successTask(task));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
usePollingEffect(
|
||||||
|
poolTasks,
|
||||||
|
[tasks, notificationTaskMap, isPooling],
|
||||||
|
{interval: 1000, isActive: isPooling && tasks.length > 0}
|
||||||
|
)
|
||||||
|
useEffect(() => {
|
||||||
|
if (tasks.length === 0) {
|
||||||
|
setIsPooling(false);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setIsPooling(true);
|
||||||
|
}, [tasks]);
|
||||||
|
useEffect(() => {
|
||||||
|
// loading from localstorage
|
||||||
|
const tasks = JSON.parse(localStorage.getItem("tasks") || "[]");
|
||||||
|
tasks.forEach((task: Task) => {
|
||||||
|
dispatch(addTask(task));
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
return <>{children}</>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TasksProvider;
|
||||||
@@ -2,11 +2,13 @@ import {configureStore} from "@reduxjs/toolkit";
|
|||||||
import {useDispatch} from "react-redux";
|
import {useDispatch} from "react-redux";
|
||||||
import authReducer from '../features/authSlice';
|
import authReducer from '../features/authSlice';
|
||||||
import uiReducer from '../features/uiSlice';
|
import uiReducer from '../features/uiSlice';
|
||||||
|
import tasksReducer from '../features/tasksSlice.tsx';
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
ui: uiReducer
|
ui: uiReducer,
|
||||||
|
tasks: tasksReducer
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ const TestLazyImport = createFileRoute('/test')()
|
|||||||
const ShippingwarehousesLazyImport = createFileRoute('/shipping_warehouses')()
|
const ShippingwarehousesLazyImport = createFileRoute('/shipping_warehouses')()
|
||||||
const ServicesLazyImport = createFileRoute('/services')()
|
const ServicesLazyImport = createFileRoute('/services')()
|
||||||
const ProductsLazyImport = createFileRoute('/products')()
|
const ProductsLazyImport = createFileRoute('/products')()
|
||||||
|
const MarketplacesLazyImport = createFileRoute('/marketplaces')()
|
||||||
const LoginLazyImport = createFileRoute('/login')()
|
const LoginLazyImport = createFileRoute('/login')()
|
||||||
const LeadsLazyImport = createFileRoute('/leads')()
|
const LeadsLazyImport = createFileRoute('/leads')()
|
||||||
const ClientsLazyImport = createFileRoute('/clients')()
|
const ClientsLazyImport = createFileRoute('/clients')()
|
||||||
@@ -52,6 +53,11 @@ const ProductsLazyRoute = ProductsLazyImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() => import('./routes/products.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/products.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
|
const MarketplacesLazyRoute = MarketplacesLazyImport.update({
|
||||||
|
path: '/marketplaces',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any).lazy(() => import('./routes/marketplaces.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
const LoginLazyRoute = LoginLazyImport.update({
|
const LoginLazyRoute = LoginLazyImport.update({
|
||||||
path: '/login',
|
path: '/login',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
@@ -133,6 +139,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof LoginLazyImport
|
preLoaderRoute: typeof LoginLazyImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/marketplaces': {
|
||||||
|
id: '/marketplaces'
|
||||||
|
path: '/marketplaces'
|
||||||
|
fullPath: '/marketplaces'
|
||||||
|
preLoaderRoute: typeof MarketplacesLazyImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/products': {
|
'/products': {
|
||||||
id: '/products'
|
id: '/products'
|
||||||
path: '/products'
|
path: '/products'
|
||||||
@@ -180,6 +193,7 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
ClientsLazyRoute,
|
ClientsLazyRoute,
|
||||||
LeadsLazyRoute,
|
LeadsLazyRoute,
|
||||||
LoginLazyRoute,
|
LoginLazyRoute,
|
||||||
|
MarketplacesLazyRoute,
|
||||||
ProductsLazyRoute,
|
ProductsLazyRoute,
|
||||||
ServicesLazyRoute,
|
ServicesLazyRoute,
|
||||||
ShippingwarehousesLazyRoute,
|
ShippingwarehousesLazyRoute,
|
||||||
@@ -201,6 +215,7 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
"/clients",
|
"/clients",
|
||||||
"/leads",
|
"/leads",
|
||||||
"/login",
|
"/login",
|
||||||
|
"/marketplaces",
|
||||||
"/products",
|
"/products",
|
||||||
"/services",
|
"/services",
|
||||||
"/shipping_warehouses",
|
"/shipping_warehouses",
|
||||||
@@ -226,6 +241,9 @@ export const routeTree = rootRoute.addChildren({
|
|||||||
"/login": {
|
"/login": {
|
||||||
"filePath": "login.lazy.tsx"
|
"filePath": "login.lazy.tsx"
|
||||||
},
|
},
|
||||||
|
"/marketplaces": {
|
||||||
|
"filePath": "marketplaces.lazy.tsx"
|
||||||
|
},
|
||||||
"/products": {
|
"/products": {
|
||||||
"filePath": "products.lazy.tsx"
|
"filePath": "products.lazy.tsx"
|
||||||
},
|
},
|
||||||
|
|||||||
6
src/routes/marketplaces.lazy.tsx
Normal file
6
src/routes/marketplaces.lazy.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import {createLazyFileRoute} from '@tanstack/react-router'
|
||||||
|
import {MarketplacesPage} from "../pages/MarketplacesPage";
|
||||||
|
|
||||||
|
export const Route = createLazyFileRoute('/marketplaces')({
|
||||||
|
component: MarketplacesPage
|
||||||
|
})
|
||||||
6
src/shared/enums/BaseMarketplaceType.ts
Normal file
6
src/shared/enums/BaseMarketplaceType.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export enum BaseMarketplaceType {
|
||||||
|
WILDBERRIES = 'wb',
|
||||||
|
OZON = 'ozon',
|
||||||
|
YANDEX_MARKET = 'ym'
|
||||||
|
|
||||||
|
}
|
||||||
7
src/shared/enums/TaskStatus.ts
Normal file
7
src/shared/enums/TaskStatus.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export enum TaskStatus {
|
||||||
|
PENDING = "PENDING",
|
||||||
|
STARTED = "STARTED",
|
||||||
|
RETRY = "RETRY",
|
||||||
|
FAILURE = "FAILURE",
|
||||||
|
SUCCESS = "SUCCESS",
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user