From 03c8f8d3fc894700b182883c0a52f7d5309e1b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 19 Jul 2021 16:18:34 +0500 Subject: [PATCH 01/32] update rest client --- src/services/api/index.ts | 9 ++ src/services/api/models/ClusterAnalysisDto.ts | 7 ++ src/services/api/models/ClusterDto.ts | 11 +++ src/services/api/models/DepositDto.ts | 11 +++ .../api/models/OperationDurationDto.ts | 8 ++ src/services/api/models/WellDepthToDayDto.ts | 9 ++ .../api/models/WellDepthToIntervalDto.ts | 8 ++ src/services/api/models/WellDto.ts | 2 + src/services/api/services/AnalyticsService.ts | 99 +++++++++++++++++++ src/services/api/services/ClusterService.ts | 42 ++++++++ src/services/api/services/DepositService.ts | 39 ++++++++ 11 files changed, 245 insertions(+) create mode 100644 src/services/api/models/ClusterAnalysisDto.ts create mode 100644 src/services/api/models/ClusterDto.ts create mode 100644 src/services/api/models/DepositDto.ts create mode 100644 src/services/api/models/OperationDurationDto.ts create mode 100644 src/services/api/models/WellDepthToDayDto.ts create mode 100644 src/services/api/models/WellDepthToIntervalDto.ts create mode 100644 src/services/api/services/AnalyticsService.ts create mode 100644 src/services/api/services/ClusterService.ts create mode 100644 src/services/api/services/DepositService.ts diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 52c5279..6af8497 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -5,19 +5,28 @@ export { ApiError } from './core/ApiError'; export { OpenAPI } from './core/OpenAPI'; export type { AuthDto } from './models/AuthDto'; +export type { ClusterAnalysisDto } from './models/ClusterAnalysisDto'; +export type { ClusterDto } from './models/ClusterDto'; export type { DataSaubBaseDto } from './models/DataSaubBaseDto'; export type { DatesRangeDto } from './models/DatesRangeDto'; +export type { DepositDto } from './models/DepositDto'; export type { EventDto } from './models/EventDto'; export type { MessageDto } from './models/MessageDto'; export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer'; +export type { OperationDurationDto } from './models/OperationDurationDto'; export type { TelemetryInfoDto } from './models/TelemetryInfoDto'; export type { TelemetryMessageDto } from './models/TelemetryMessageDto'; export type { TelemetryUserDto } from './models/TelemetryUserDto'; export type { UserTokenDto } from './models/UserTokenDto'; +export type { WellDepthToDayDto } from './models/WellDepthToDayDto'; +export type { WellDepthToIntervalDto } from './models/WellDepthToIntervalDto'; export type { WellDto } from './models/WellDto'; +export { AnalyticsService } from './services/AnalyticsService'; export { AuthService } from './services/AuthService'; +export { ClusterService } from './services/ClusterService'; export { DataService } from './services/DataService'; +export { DepositService } from './services/DepositService'; export { MessageService } from './services/MessageService'; export { ReportService } from './services/ReportService'; export { TelemetryService } from './services/TelemetryService'; diff --git a/src/services/api/models/ClusterAnalysisDto.ts b/src/services/api/models/ClusterAnalysisDto.ts new file mode 100644 index 0000000..82c311d --- /dev/null +++ b/src/services/api/models/ClusterAnalysisDto.ts @@ -0,0 +1,7 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ClusterAnalysisDto = { + id?: number; +} \ No newline at end of file diff --git a/src/services/api/models/ClusterDto.ts b/src/services/api/models/ClusterDto.ts new file mode 100644 index 0000000..f4270a6 --- /dev/null +++ b/src/services/api/models/ClusterDto.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type ClusterDto = { + id?: number; + name?: string | null; + description?: string | null; + latitude?: number; + longitude?: number; +} \ No newline at end of file diff --git a/src/services/api/models/DepositDto.ts b/src/services/api/models/DepositDto.ts new file mode 100644 index 0000000..a605887 --- /dev/null +++ b/src/services/api/models/DepositDto.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type DepositDto = { + id?: number; + name?: string | null; + description?: string | null; + latitude?: number; + longitude?: number; +} \ No newline at end of file diff --git a/src/services/api/models/OperationDurationDto.ts b/src/services/api/models/OperationDurationDto.ts new file mode 100644 index 0000000..7f061a0 --- /dev/null +++ b/src/services/api/models/OperationDurationDto.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type OperationDurationDto = { + processName?: string | null; + duration?: number; +} \ No newline at end of file diff --git a/src/services/api/models/WellDepthToDayDto.ts b/src/services/api/models/WellDepthToDayDto.ts new file mode 100644 index 0000000..51cef5f --- /dev/null +++ b/src/services/api/models/WellDepthToDayDto.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type WellDepthToDayDto = { + wellDepth?: number; + bitDepth?: number; + date?: string; +} \ No newline at end of file diff --git a/src/services/api/models/WellDepthToIntervalDto.ts b/src/services/api/models/WellDepthToIntervalDto.ts new file mode 100644 index 0000000..a92c110 --- /dev/null +++ b/src/services/api/models/WellDepthToIntervalDto.ts @@ -0,0 +1,8 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type WellDepthToIntervalDto = { + intervalStartDate?: string; + intervalDepthProgress?: number; +} \ No newline at end of file diff --git a/src/services/api/models/WellDto.ts b/src/services/api/models/WellDto.ts index c161219..17e0645 100644 --- a/src/services/api/models/WellDto.ts +++ b/src/services/api/models/WellDto.ts @@ -8,4 +8,6 @@ export type WellDto = { deposit?: string | null; id?: number; lastData?: any; + latitude?: number; + longitude?: number; } \ No newline at end of file diff --git a/src/services/api/services/AnalyticsService.ts b/src/services/api/services/AnalyticsService.ts new file mode 100644 index 0000000..e9d0d87 --- /dev/null +++ b/src/services/api/services/AnalyticsService.ts @@ -0,0 +1,99 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { OperationDurationDto } from '../models/OperationDurationDto'; +import type { WellDepthToDayDto } from '../models/WellDepthToDayDto'; +import type { WellDepthToIntervalDto } from '../models/WellDepthToIntervalDto'; +import { request as __request } from '../core/request'; + +export class AnalyticsService { + + /** + * Возвращает данные по скважине "глубина-день" + * @param wellId id скважины + * @returns WellDepthToDayDto Success + * @throws ApiError + */ + public static async getWellDepthToDay( +wellId: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/wellDepthToDay`, + }); + return result.body; + } + + /** + * Возвращает данные по глубине скважины за период + * @param wellId id скважины + * @param intervalHoursTimestamp количество секунд в необходимом интервале времени + * @param workBeginTimestamp количество секунд в времени начала смены + * @returns WellDepthToIntervalDto Success + * @throws ApiError + */ + public static async getWellDepthToInterval( +wellId: number, +intervalHoursTimestamp?: number, +workBeginTimestamp?: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/wellDepthToInterval`, + query: { + 'intervalHoursTimestamp': intervalHoursTimestamp, + 'workBeginTimestamp': workBeginTimestamp, + }, + }); + return result.body; + } + + /** + * Возвращает данные по операциям на скважине "операции-время" + * @param wellId id скважины + * @param begin дата начала интервала + * @param end дата окончания интервала + * @returns OperationDurationDto Success + * @throws ApiError + */ + public static async getOperationsSummary( +wellId: number, +begin?: string, +end?: string, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/operationsSummary`, + query: { + 'begin': begin, + 'end': end, + }, + }); + return result.body; + } + + /** + * Возвращает детальные данные по операциям на скважине за период + * @param wellId id скважины + * @param intervalHoursTimestamp количество секунд в необходимом интервале времени + * @param workBeginTimestamp количество секунд в времени начала смены + * @returns OperationDurationDto Success + * @throws ApiError + */ + public static async getOperationsToInterval( +wellId: number, +intervalHoursTimestamp?: number, +workBeginTimestamp?: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/operationsToInterval`, + query: { + 'intervalHoursTimestamp': intervalHoursTimestamp, + 'workBeginTimestamp': workBeginTimestamp, + }, + }); + return result.body; + } + +} \ No newline at end of file diff --git a/src/services/api/services/ClusterService.ts b/src/services/api/services/ClusterService.ts new file mode 100644 index 0000000..b31f270 --- /dev/null +++ b/src/services/api/services/ClusterService.ts @@ -0,0 +1,42 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ClusterAnalysisDto } from '../models/ClusterAnalysisDto'; +import type { WellDto } from '../models/WellDto'; +import { request as __request } from '../core/request'; + +export class ClusterService { + + /** + * Получение доступных пользователю скважин + * @param clusterId + * @returns WellDto Success + * @throws ApiError + */ + public static async getWells( +clusterId: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/Cluster/${clusterId}`, + }); + return result.body; + } + + /** + * Получение обопщенной аналитики по кусту (лучшая/худшая скважина) + * @param clusterId + * @returns ClusterAnalysisDto Success + * @throws ApiError + */ + public static async getAnalysis( +clusterId: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/Cluster/${clusterId}/Analysis`, + }); + return result.body; + } + +} \ No newline at end of file diff --git a/src/services/api/services/DepositService.ts b/src/services/api/services/DepositService.ts new file mode 100644 index 0000000..ff64c74 --- /dev/null +++ b/src/services/api/services/DepositService.ts @@ -0,0 +1,39 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ClusterDto } from '../models/ClusterDto'; +import type { DepositDto } from '../models/DepositDto'; +import { request as __request } from '../core/request'; + +export class DepositService { + + /** + * Получает список доступных пользователю месторождений + * @returns DepositDto Success + * @throws ApiError + */ + public static async getDeposits(): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/Deposit`, + }); + return result.body; + } + + /** + * Получает список доступных пользователю кустов месторождения + * @param depositId + * @returns ClusterDto Success + * @throws ApiError + */ + public static async getClusters( +depositId: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/Deposit/${depositId}`, + }); + return result.body; + } + +} \ No newline at end of file From 5c7029dd978f567d64c3aca73b3046ba79bd52e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 19 Jul 2021 16:19:01 +0500 Subject: [PATCH 02/32] fix report warnings --- src/pages/Report.jsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/Report.jsx b/src/pages/Report.jsx index f3b30c0..c7574d3 100644 --- a/src/pages/Report.jsx +++ b/src/pages/Report.jsx @@ -67,7 +67,7 @@ export default function Report(props) { title: 'Название отчета', dataIndex: 'reportName', key: 'reportName', - render: name => getReportFile(event, name)} download={name}>{name} + render: name => getReportFile(event, name)} download={name}>{name} }, ]; @@ -80,7 +80,7 @@ export default function Report(props) {
{ progressData.operation }
- {getReportFile(event, progressData.reportName)}} + {getReportFile(event, progressData.reportName)}} download={progressData.reportName}> { progressData.reportName } @@ -172,7 +172,7 @@ export default function Report(props) { } getRepostSizeAsync() - },[rangeDate, step, format]) + },[rangeDate, step, format, wellId]) useEffect(()=>{ async function getSuitableReportsAsync() { @@ -204,7 +204,7 @@ export default function Report(props) { } getSuitableReportsAsync() - },[rangeDate, step, format]) + },[rangeDate, step, format, wellId]) useEffect(()=>{ async function getDatesRange() { @@ -214,7 +214,7 @@ export default function Report(props) { } getDatesRange() - },[]) + },[wellId]) return (<>
From c279efa64ebcd6306980cc91c70cdc4ea5c4f000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 19 Jul 2021 16:43:04 +0500 Subject: [PATCH 03/32] nit. design. treeSelector width --- src/styles/App.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/styles/App.less b/src/styles/App.less index 89df32a..8f7e2cc 100644 --- a/src/styles/App.less +++ b/src/styles/App.less @@ -160,6 +160,7 @@ tr.table_row_size { } .header-tree-select{ + width: 300px; border: 1px solid rgba(255, 255, 255, 0.2); background-color: rgba(0, 0, 0, 0.3); } From bf7663987ab45b49e946f93fa1472624b3e88947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 19 Jul 2021 17:38:31 +0500 Subject: [PATCH 04/32] add pigeon-maps --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index fcc367b..5d3a0a0 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "craco-less": "^1.17.1", "date-fns": "^2.20.0", "moment": "^2.29.1", + "pigeon-maps": "^0.19.7", "react": "^17.0.2", "react-datepicker": "^3.8.0", "react-dom": "^17.0.2", From d23287918f08424576c1fc0c7b68c68bc44bd325 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 20 Jul 2021 09:15:11 +0500 Subject: [PATCH 05/32] api client update --- src/services/api/services/ClusterService.ts | 18 ++++++++++++++++-- src/services/api/services/DepositService.ts | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/services/api/services/ClusterService.ts b/src/services/api/services/ClusterService.ts index b31f270..e839088 100644 --- a/src/services/api/services/ClusterService.ts +++ b/src/services/api/services/ClusterService.ts @@ -2,11 +2,25 @@ /* tslint:disable */ /* eslint-disable */ import type { ClusterAnalysisDto } from '../models/ClusterAnalysisDto'; +import type { ClusterDto } from '../models/ClusterDto'; import type { WellDto } from '../models/WellDto'; import { request as __request } from '../core/request'; export class ClusterService { + /** + * Получает список доступных пользователю кустов + * @returns ClusterDto Success + * @throws ApiError + */ + public static async getClusters(): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/cluster`, + }); + return result.body; + } + /** * Получение доступных пользователю скважин * @param clusterId @@ -18,7 +32,7 @@ clusterId: number, ): Promise> { const result = await __request({ method: 'GET', - path: `/api/Cluster/${clusterId}`, + path: `/api/cluster/${clusterId}`, }); return result.body; } @@ -34,7 +48,7 @@ clusterId: number, ): Promise> { const result = await __request({ method: 'GET', - path: `/api/Cluster/${clusterId}/Analysis`, + path: `/api/cluster/${clusterId}/Analysis`, }); return result.body; } diff --git a/src/services/api/services/DepositService.ts b/src/services/api/services/DepositService.ts index ff64c74..ca61820 100644 --- a/src/services/api/services/DepositService.ts +++ b/src/services/api/services/DepositService.ts @@ -15,7 +15,7 @@ export class DepositService { public static async getDeposits(): Promise> { const result = await __request({ method: 'GET', - path: `/api/Deposit`, + path: `/api/deposit`, }); return result.body; } @@ -31,7 +31,7 @@ depositId: number, ): Promise> { const result = await __request({ method: 'GET', - path: `/api/Deposit/${depositId}`, + path: `/api/deposit/${depositId}`, }); return result.body; } From 732e793527d30e795b7140876e6edb675100bfd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 20 Jul 2021 14:10:01 +0500 Subject: [PATCH 06/32] stash --- package-lock.json | 55 ++++++--------- package.json | 2 +- src/images/las.png | Bin 0 -> 965 bytes src/images/{logoSmaill.svg => logoSmall.svg} | 0 src/images/pdf.png | Bin 0 -> 36295 bytes src/images/pointer.svg | 12 ++++ src/images/xlsx.png | Bin 0 -> 5708 bytes src/pages/Cluster.jsx | 8 +++ src/pages/Deposit.jsx | 69 +++++++++++++++++++ src/pages/Main.jsx | 42 ++++++----- src/{components => pages}/Well.jsx | 12 ++-- src/pages/Wells.jsx | 65 ----------------- 12 files changed, 140 insertions(+), 125 deletions(-) create mode 100644 src/images/las.png rename src/images/{logoSmaill.svg => logoSmall.svg} (100%) create mode 100644 src/images/pdf.png create mode 100644 src/images/pointer.svg create mode 100644 src/images/xlsx.png create mode 100644 src/pages/Cluster.jsx create mode 100644 src/pages/Deposit.jsx rename src/{components => pages}/Well.jsx (88%) delete mode 100644 src/pages/Wells.jsx diff --git a/package-lock.json b/package-lock.json index eb6f624..1533101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10473,8 +10473,7 @@ "dependencies": { "hosted-git-info": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "resolved": "", "dev": true }, "normalize-package-data": { @@ -11657,6 +11656,11 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, + "pigeon-maps": { + "version": "0.19.7", + "resolved": "https://registry.npmjs.org/pigeon-maps/-/pigeon-maps-0.19.7.tgz", + "integrity": "sha512-8yS5o7lr3mr5674Cfkxrk3EqPiV6WjGBrpVKNn6/40bTdH5qq2NNXK2Iu0fQcDRRZ6mTtXHX0tJAO1tp8ZKBNg==" + }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", @@ -11797,9 +11801,9 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -14137,9 +14141,9 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, "resolve-url-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz", - "integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz", + "integrity": "sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg==", "requires": { "adjust-sourcemap-loader": "3.0.0", "camelcase": "5.3.1", @@ -14147,7 +14151,7 @@ "convert-source-map": "1.7.0", "es6-iterator": "2.0.3", "loader-utils": "1.2.3", - "postcss": "7.0.21", + "postcss": "7.0.36", "rework": "1.0.1", "rework-visit": "1.0.0", "source-map": "0.6.1" @@ -14181,28 +14185,10 @@ "json5": "^1.0.1" } }, - "postcss": { - "version": "7.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", - "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -15905,9 +15891,9 @@ } }, "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "tryer": { @@ -16862,8 +16848,7 @@ }, "ssri": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "resolved": "", "requires": { "figgy-pudding": "^3.5.1" } @@ -17804,9 +17789,9 @@ } }, "ws": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", - "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==" + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==" }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index 5d3a0a0..709c113 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "react_test": "react-scripts test", "eject": "react-scripts eject" }, - "proxy": "http://192.168.1.70:5000", + "proxy": "http://127.0.0.1:5000", "eslintConfig": { "extends": [ "react-app", diff --git a/src/images/las.png b/src/images/las.png new file mode 100644 index 0000000000000000000000000000000000000000..1348d4b4661332e87050c314e558d0d3968c2e06 GIT binary patch literal 965 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&O$hJ_aRt(ko<4`81IJFo*+52k zZXF!`2LqtshV6T|?moEx=&6(EF5SNWaMRBHXD?pecjV-?+xJghya807TG`Pteeso> zcaqB6^BX5DSiLp7uJ81v8)q)xx^&~-naejHJbnr^?7)e0(-yD0dh1?Jec!7$?^bWy z*En$=@4vNYfNl~f3GxeOP^sJe{2)W#*R4{^pTA~cShCbQje&vbil>WXNX4ADw@-)N zHV|NYaL0>j%ksR&AcHLd3#OJ9-uwSn>wc2;G!v_d=~G(&F>{~p{%Nymi$TW6s}rAQ z?LFytW_fG+o2UBQb_cJ1UGrJ=#_M>tDc2d|8$~zpu3FDHkLmTF_AmPxe{kkBghu?8 zdZ4<2@meuM4U5@pw467S>5`-@>>M%JqL^^O9aCtDQG3p*rIKWi%T{M9)Pp6@ifx94^S%!N9L%F>T zYed7Fdt4IS7Z`5(+cU~3?EXHB)y1K#yqbBvn~%fPcK6~F3}%e72b2_8X0T3SSll3z zAasF=hbiemhy(8ojuVW>nW_#0p%LT*T1UWYN&5AhbaI2$KxUMTWTwatlOV zSWKE`G(-uA25>%N+M-~jP~E|MLg)bxWBB#?#Y=2#|2Hv)$8R_l{?k^_hvE8+ub=-& zvMl(z|D-U-fwl9Wb539YApw?zo?dn?+aQ^BI|6(e-}jTSR@VeTk9x;jtx$?q!dfOF-Ab`2@Dzb3^n zN*}CYuw&p!tK-jU{mgiTLE%@T<<0dQ8QRZnSN+~}`kAlGTZieZuHG%~uHx3>`#$G& zf|i+K=6hw$ka+xm i?#(sfryYMDt>3}W_Rv6>O%Ry&89ZJ6T-G@yGywoZ`L?Y9 literal 0 HcmV?d00001 diff --git a/src/images/logoSmaill.svg b/src/images/logoSmall.svg similarity index 100% rename from src/images/logoSmaill.svg rename to src/images/logoSmall.svg diff --git a/src/images/pdf.png b/src/images/pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..e47094f7c2fc8c47d117ea319703a326c6bcb3c3 GIT binary patch literal 36295 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 literal 0 HcmV?d00001 diff --git a/src/images/pointer.svg b/src/images/pointer.svg new file mode 100644 index 0000000..62cc064 --- /dev/null +++ b/src/images/pointer.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/images/xlsx.png b/src/images/xlsx.png new file mode 100644 index 0000000000000000000000000000000000000000..8e68f30a6997e8852a92b702b408b2916f1f0e6b GIT binary patch literal 5708 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 F{ST0LBWVBt literal 0 HcmV?d00001 diff --git a/src/pages/Cluster.jsx b/src/pages/Cluster.jsx new file mode 100644 index 0000000..d8743b3 --- /dev/null +++ b/src/pages/Cluster.jsx @@ -0,0 +1,8 @@ +import {useParams} from "react-router-dom"; + +export default function Cluster() { + + let { id } = useParams() + + return(
Куст {id}
) +} \ No newline at end of file diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx new file mode 100644 index 0000000..17b7c9c --- /dev/null +++ b/src/pages/Deposit.jsx @@ -0,0 +1,69 @@ +import { Map, Overlay } from "pigeon-maps" +import pointer from '../images/pointer.svg' +import {Link} from "react-router-dom"; +import LoaderPortal from '../components/LoaderPortal' +import { useState, useEffect } from "react"; +import {ClusterService} from '../services/api' + +const calcViewParams = (clusters) => { + if (clusters.length === 0) + return {center:[60.81226, 70.0562], zoom: 5} + + const center = clusters.reduce((sum, cluster) => { + sum[0] += (cluster.latitude / clusters.length) + sum[1] += (cluster.longitude / clusters.length) + return sum + }, [0, 0]) + + const maxDeg = clusters.reduce((max, cluster) => { + const dLatitude = Math.abs(center[0] - cluster.latitude) + const dLongitude = Math.abs(center[1] - cluster.longitude) + const d = dLatitude > dLongitude ? dLatitude : dLongitude + return d > max ? d : max + }, 0) + + return {center, zoom: maxDeg*25} +} + +export default function Deposit() { + const [clustersData, setClustersData] = useState([]) + const [showLoader, setShowLoader] = useState(false) + + const updateClusters = async()=>{ + setShowLoader(true) + try{ + const data = await ClusterService.getClusters() + setClustersData(data) + }catch{ + //ignore + } + setShowLoader(false) + } + + useEffect(()=>{updateClusters()}, []) + + const viewParams = calcViewParams(clustersData) + + return ( + + + {clustersData.map(cluster => + + + + + {cluster.name} + + + )} + + + ); +} diff --git a/src/pages/Main.jsx b/src/pages/Main.jsx index adf515f..cd5246b 100644 --- a/src/pages/Main.jsx +++ b/src/pages/Main.jsx @@ -1,25 +1,31 @@ -import Wells from './Wells' -import Well from "../components/Well"; +import Deposit from './Deposit' +import Cluster from './Cluster' +import Well from "./Well"; import LayoutPortal from './LayoutPortal' import {Redirect, Route, Switch} from "react-router-dom"; export default function Main() { - return ( - - - - - - - - - - - - - - - + return ( + + + + + + + + + + + + + + + + + + + + ) } diff --git a/src/components/Well.jsx b/src/pages/Well.jsx similarity index 88% rename from src/components/Well.jsx rename to src/pages/Well.jsx index 64e6ecc..5dfadd7 100644 --- a/src/components/Well.jsx +++ b/src/pages/Well.jsx @@ -1,12 +1,12 @@ import {Layout, Menu} from "antd"; import {FolderOutlined, FundViewOutlined} from "@ant-design/icons"; import {Link, Redirect, Route, Switch, useParams} from "react-router-dom"; -import Files from "../pages/Files"; -import Archive from "../pages/Archive"; -import Messages from "../pages/Messages"; -import Report from "../pages/Report"; -import Analysis from "../pages/Analysis"; -import TelemetryView from "../pages/TelemetryView"; +import Files from "./Files"; +import Archive from "./Archive"; +import Messages from "./Messages"; +import Report from "./Report"; +import Analysis from "./Analysis"; +import TelemetryView from "./TelemetryView"; const { Content } = Layout diff --git a/src/pages/Wells.jsx b/src/pages/Wells.jsx deleted file mode 100644 index 4bf4e9a..0000000 --- a/src/pages/Wells.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import { useState, useEffect } from 'react' -import { WellService } from '../services/api' -import LoaderPortal from '../components/LoaderPortal' -import { Table } from 'antd' // TreeSelect -import { useHistory } from 'react-router-dom' -import notify from '../components/notify' - -const columns = [ - { - title: 'Месторождение', - dataIndex: 'deposit', - key: 'deposit', - }, - { - title: 'Куст', - dataIndex: 'cluster', - key: 'cluster', - }, - { - title: 'Скважина', - dataIndex: 'caption', - key: 'caption', - }, - { - title: 'Данные', - dataIndex: 'lastData', - key: 'lastData', - }, -]; - -export default function Wells(props){ - const [wells, setWells] = useState([]) - const [loader, setLoader] = useState(false) - const history = useHistory() - - const updateWellsList = async () => { - setLoader(true) - try{ - let newWells = (await WellService.getWells()).map(w =>{return {key:w.id, ...w}}) - console.log(newWells) - setWells( newWells ) - } - catch(e){ - notify('Не удалось загрузить список скважин', 'error') - console.error(`${e}`); - } - setLoader(false) - } - - useEffect(()=>updateWellsList(), []) - - return(<> -

Скважины

- - { - return { - onClick: event => {history.push(`/well/${record.id}/`)}, - }; - }}/> - - ) -} \ No newline at end of file From 396e94e334b7d62c9be3f165509b4faeb2876bd7 Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Wed, 21 Jul 2021 16:53:33 +0500 Subject: [PATCH 07/32] =?UTF-8?q?CF2-29:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D1=81=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=D0=BC=D0=B8=20=D0=BF=D0=BE=20=D1=81=D0=BA=D0=B2=D0=B0?= =?UTF-8?q?=D0=B6=D0=B8=D0=BD=D0=B5=20+=20openApi=20=D0=B0=D0=B2=D1=82?= =?UTF-8?q?=D0=BE=D1=81=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Well.jsx | 9 +- src/pages/WellAnalysis.jsx | 159 ++++++++++++++++++ src/services/api/index.ts | 2 + src/services/api/models/DataSaubBaseDto.ts | 2 + src/services/api/models/OperationDto.ts | 12 ++ .../models/OperationDtoPaginationContainer.ts | 12 ++ .../api/models/OperationDurationDto.ts | 2 +- src/services/api/services/AnalyticsService.ts | 58 +++++-- 8 files changed, 242 insertions(+), 14 deletions(-) create mode 100644 src/pages/WellAnalysis.jsx create mode 100644 src/services/api/models/OperationDto.ts create mode 100644 src/services/api/models/OperationDtoPaginationContainer.ts diff --git a/src/components/Well.jsx b/src/components/Well.jsx index 64e6ecc..66fc623 100644 --- a/src/components/Well.jsx +++ b/src/components/Well.jsx @@ -6,6 +6,7 @@ import Archive from "../pages/Archive"; import Messages from "../pages/Messages"; import Report from "../pages/Report"; import Analysis from "../pages/Analysis"; +import WellAnalysis from "../pages/WellAnalysis"; import TelemetryView from "../pages/TelemetryView"; const { Content } = Layout @@ -33,9 +34,12 @@ export default function Well() { Анализ }> - Файлы + Операции по скважине }> + Файлы + + }> Архив @@ -58,6 +62,9 @@ export default function Well() { + + + diff --git a/src/pages/WellAnalysis.jsx b/src/pages/WellAnalysis.jsx new file mode 100644 index 0000000..f0f5b6f --- /dev/null +++ b/src/pages/WellAnalysis.jsx @@ -0,0 +1,159 @@ +import {Table, Select, DatePicker, ConfigProvider} from 'antd'; +import {AnalyticsService} from '../services/api' +import {useState, useEffect} from 'react' +import {useParams} from 'react-router-dom' +import notify from '../components/notify' +import LoaderPortal from '../components/LoaderPortal' +import locale from "antd/lib/locale/ru_RU"; +import moment from 'moment' +import '../styles/message.css' + +const {Option} = Select +const pageSize = 26 +const {RangePicker} = DatePicker; + +const columns = [ + { + title: 'Название операции', + key: 'name', + dataIndex: 'name', + }, + { + title: 'Дата начала операции', + key: 'beginDate', + dataIndex: 'beginDate', + render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss') + }, + { + title: 'Дата окончания операции', + key: 'endDate', + dataIndex: 'endDate', + render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss') + }, + { + title: 'Глубина скважины в начале операции', + key: 'beginWellDepth', + dataIndex: 'startWellDepth', + }, + { + title: 'Глубина скважины в конце операции', + key: 'endWellDepth', + dataIndex: 'endWellDepth', + } +]; + +const filterOptions = [ + {label: 'Невозможно определить операцию', value: 1}, + {label: 'Роторное бурение', value: 2}, + {label: 'Слайдирование', value: 3}, + {label: 'Подъем с проработкой', value: 4}, + {label: 'Спуск с проработкой', value: 5}, + {label: 'Подъем с промывкой', value: 6}, + {label: 'Спуск с промывкой', value: 7}, + {label: 'Спуск в скважину', value: 8}, + {label: 'Спуск с вращением', value: 9}, + {label: 'Подъем из скважины', value: 10}, + {label: 'Подъем с вращением', value: 11}, + {label: 'Промывка в покое', value: 12}, + {label: 'Промывка с вращением', value: 13}, + {label: 'Удержание в клиньях', value: 14}, + {label: 'Неподвижное состояние', value: 15}, + {label: 'Вращение без циркуляции', value: 16}, + {label: 'На поверхности', value: 17} +] + +export default function WellAnalysis() { + let {id} = useParams() + + const [page, setPage] = useState(1) + const [range, setRange] = useState([]) + const [categories, setCategories] = useState([]) + const [pagination, setPagination] = useState(null) + const [operations, setOperations] = useState([]) + + const [loader, setLoader] = useState(false) + + const children = filterOptions.map((line) => ) + + const onChangeRange = (range) => { + setRange(range) + } + + useEffect(() => { + const GetOperations = async () => { + setLoader(true) + try { + let begin = null + let end = null + if (range?.length > 1) { + begin = range[0].toISOString() + end = range[1].toISOString() + } + + await AnalyticsService.getOperationsByWell( + `${id}`, + (page-1) * pageSize, + pageSize, + categories, + begin, + end).then((paginatedOperations) => { + setOperations(paginatedOperations?.items.map(o => { + return { + key: o.id, + begin: o.date, + ...o + } + })) + + setPagination({ + total: paginatedOperations?.count, + current: Math.floor(paginatedOperations?.skip / pageSize), + }) + } + ) + } catch (ex) { + notify(`Не удалось загрузить операции по скважине "${id}"`, 'error') + console.log(ex) + } + setLoader(false) + } + GetOperations() + }, [id, categories, range]) + + return(<> +
+

Фильтр операций

+ + + + +
+ +
setPage(page) + }} + rowKey={(record) => record.id} + /> + + ) + } \ No newline at end of file diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 6af8497..c10cc8c 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -13,6 +13,8 @@ export type { DepositDto } from './models/DepositDto'; export type { EventDto } from './models/EventDto'; export type { MessageDto } from './models/MessageDto'; export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer'; +export type { OperationDto } from './models/OperationDto'; +export type { OperationDtoPaginationContainer } from './models/OperationDtoPaginationContainer'; export type { OperationDurationDto } from './models/OperationDurationDto'; export type { TelemetryInfoDto } from './models/TelemetryInfoDto'; export type { TelemetryMessageDto } from './models/TelemetryMessageDto'; diff --git a/src/services/api/models/DataSaubBaseDto.ts b/src/services/api/models/DataSaubBaseDto.ts index 0a9e94f..e12e1c5 100644 --- a/src/services/api/models/DataSaubBaseDto.ts +++ b/src/services/api/models/DataSaubBaseDto.ts @@ -38,4 +38,6 @@ export type DataSaubBaseDto = { flow?: number | null; flowIdle?: number | null; flowDeltaLimitMax?: number | null; + idFeedRegulator?: number | null; + mseState?: number | null; } \ No newline at end of file diff --git a/src/services/api/models/OperationDto.ts b/src/services/api/models/OperationDto.ts new file mode 100644 index 0000000..9481988 --- /dev/null +++ b/src/services/api/models/OperationDto.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type OperationDto = { + id?: number; + name?: string | null; + beginDate?: string; + endDate?: string; + startWellDepth?: number; + endWellDepth?: number; +} \ No newline at end of file diff --git a/src/services/api/models/OperationDtoPaginationContainer.ts b/src/services/api/models/OperationDtoPaginationContainer.ts new file mode 100644 index 0000000..64fcf00 --- /dev/null +++ b/src/services/api/models/OperationDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { OperationDto } from './OperationDto'; + +export type OperationDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} \ No newline at end of file diff --git a/src/services/api/models/OperationDurationDto.ts b/src/services/api/models/OperationDurationDto.ts index 7f061a0..5be7a04 100644 --- a/src/services/api/models/OperationDurationDto.ts +++ b/src/services/api/models/OperationDurationDto.ts @@ -3,6 +3,6 @@ /* eslint-disable */ export type OperationDurationDto = { - processName?: string | null; + operationName?: string | null; duration?: number; } \ No newline at end of file diff --git a/src/services/api/services/AnalyticsService.ts b/src/services/api/services/AnalyticsService.ts index e9d0d87..a3913d0 100644 --- a/src/services/api/services/AnalyticsService.ts +++ b/src/services/api/services/AnalyticsService.ts @@ -1,6 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { OperationDtoPaginationContainer } from '../models/OperationDtoPaginationContainer'; import type { OperationDurationDto } from '../models/OperationDurationDto'; import type { WellDepthToDayDto } from '../models/WellDepthToDayDto'; import type { WellDepthToIntervalDto } from '../models/WellDepthToIntervalDto'; @@ -8,6 +9,39 @@ import { request as __request } from '../core/request'; export class AnalyticsService { + /** + * Возвращает список операций на скважине за все время + * @param wellId id скважины + * @param skip для пагинации кол-во записей пропустить + * @param take для пагинации кол-во записей + * @param categoryids + * @param begin + * @param end + * @returns OperationDtoPaginationContainer Success + * @throws ApiError + */ + public static async getOperationsByWell( +wellId: number, +skip: number, +take: number = 32, +categoryids?: Array, +begin?: string, +end?: string, +): Promise { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/operationsByWell`, + query: { + 'skip': skip, + 'take': take, + 'categoryids': categoryids, + 'begin': begin, + 'end': end, + }, + }); + return result.body; + } + /** * Возвращает данные по скважине "глубина-день" * @param wellId id скважины @@ -27,22 +61,22 @@ wellId: number, /** * Возвращает данные по глубине скважины за период * @param wellId id скважины - * @param intervalHoursTimestamp количество секунд в необходимом интервале времени - * @param workBeginTimestamp количество секунд в времени начала смены + * @param intervalSeconds количество секунд в необходимом интервале времени + * @param workBeginSeconds количество секунд в времени начала смены * @returns WellDepthToIntervalDto Success * @throws ApiError */ public static async getWellDepthToInterval( wellId: number, -intervalHoursTimestamp?: number, -workBeginTimestamp?: number, +intervalSeconds?: number, +workBeginSeconds?: number, ): Promise> { const result = await __request({ method: 'GET', path: `/api/analytics/${wellId}/wellDepthToInterval`, query: { - 'intervalHoursTimestamp': intervalHoursTimestamp, - 'workBeginTimestamp': workBeginTimestamp, + 'intervalSeconds': intervalSeconds, + 'workBeginSeconds': workBeginSeconds, }, }); return result.body; @@ -75,22 +109,22 @@ end?: string, /** * Возвращает детальные данные по операциям на скважине за период * @param wellId id скважины - * @param intervalHoursTimestamp количество секунд в необходимом интервале времени - * @param workBeginTimestamp количество секунд в времени начала смены + * @param intervalSeconds количество секунд в необходимом интервале времени + * @param workBeginSeconds количество секунд в времени начала смены * @returns OperationDurationDto Success * @throws ApiError */ public static async getOperationsToInterval( wellId: number, -intervalHoursTimestamp?: number, -workBeginTimestamp?: number, +intervalSeconds?: number, +workBeginSeconds?: number, ): Promise> { const result = await __request({ method: 'GET', path: `/api/analytics/${wellId}/operationsToInterval`, query: { - 'intervalHoursTimestamp': intervalHoursTimestamp, - 'workBeginTimestamp': workBeginTimestamp, + 'intervalSeconds': intervalSeconds, + 'workBeginSeconds': workBeginSeconds, }, }); return result.body; From 13f56cda573233cab7d6f2210b24e963377c5089 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 22 Jul 2021 10:16:55 +0500 Subject: [PATCH 08/32] api client update --- src/services/api/index.ts | 7 ++- src/services/api/models/ClusterAnalysisDto.ts | 7 --- src/services/api/models/ClusterDto.ts | 6 +- src/services/api/models/ClusterStatDto.ts | 14 +++++ src/services/api/models/CompanyDto.ts | 9 +++ src/services/api/models/DataSaubBaseDto.ts | 2 + src/services/api/models/DepositDto.ts | 4 +- src/services/api/models/OperationDto.ts | 12 ++++ .../models/OperationDtoPaginationContainer.ts | 12 ++++ .../api/models/OperationDurationDto.ts | 2 +- src/services/api/models/UserTokenDto.ts | 2 +- src/services/api/models/WellDto.ts | 5 +- src/services/api/models/WellSectionDto.ts | 21 +++++++ src/services/api/models/WellStatDto.ts | 28 +++++++++ src/services/api/services/AnalyticsService.ts | 58 +++++++++++++++---- src/services/api/services/ClusterService.ts | 22 +++---- 16 files changed, 171 insertions(+), 40 deletions(-) delete mode 100644 src/services/api/models/ClusterAnalysisDto.ts create mode 100644 src/services/api/models/ClusterStatDto.ts create mode 100644 src/services/api/models/CompanyDto.ts create mode 100644 src/services/api/models/OperationDto.ts create mode 100644 src/services/api/models/OperationDtoPaginationContainer.ts create mode 100644 src/services/api/models/WellSectionDto.ts create mode 100644 src/services/api/models/WellStatDto.ts diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 6af8497..9371e5f 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -5,14 +5,17 @@ export { ApiError } from './core/ApiError'; export { OpenAPI } from './core/OpenAPI'; export type { AuthDto } from './models/AuthDto'; -export type { ClusterAnalysisDto } from './models/ClusterAnalysisDto'; export type { ClusterDto } from './models/ClusterDto'; +export type { ClusterStatDto } from './models/ClusterStatDto'; +export type { CompanyDto } from './models/CompanyDto'; export type { DataSaubBaseDto } from './models/DataSaubBaseDto'; export type { DatesRangeDto } from './models/DatesRangeDto'; export type { DepositDto } from './models/DepositDto'; export type { EventDto } from './models/EventDto'; export type { MessageDto } from './models/MessageDto'; export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer'; +export type { OperationDto } from './models/OperationDto'; +export type { OperationDtoPaginationContainer } from './models/OperationDtoPaginationContainer'; export type { OperationDurationDto } from './models/OperationDurationDto'; export type { TelemetryInfoDto } from './models/TelemetryInfoDto'; export type { TelemetryMessageDto } from './models/TelemetryMessageDto'; @@ -21,6 +24,8 @@ export type { UserTokenDto } from './models/UserTokenDto'; export type { WellDepthToDayDto } from './models/WellDepthToDayDto'; export type { WellDepthToIntervalDto } from './models/WellDepthToIntervalDto'; export type { WellDto } from './models/WellDto'; +export type { WellSectionDto } from './models/WellSectionDto'; +export type { WellStatDto } from './models/WellStatDto'; export { AnalyticsService } from './services/AnalyticsService'; export { AuthService } from './services/AuthService'; diff --git a/src/services/api/models/ClusterAnalysisDto.ts b/src/services/api/models/ClusterAnalysisDto.ts deleted file mode 100644 index 82c311d..0000000 --- a/src/services/api/models/ClusterAnalysisDto.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* istanbul ignore file */ -/* tslint:disable */ -/* eslint-disable */ - -export type ClusterAnalysisDto = { - id?: number; -} \ No newline at end of file diff --git a/src/services/api/models/ClusterDto.ts b/src/services/api/models/ClusterDto.ts index f4270a6..82b801d 100644 --- a/src/services/api/models/ClusterDto.ts +++ b/src/services/api/models/ClusterDto.ts @@ -4,8 +4,8 @@ export type ClusterDto = { id?: number; - name?: string | null; + caption?: string | null; description?: string | null; - latitude?: number; - longitude?: number; + latitude?: number | null; + longitude?: number | null; } \ No newline at end of file diff --git a/src/services/api/models/ClusterStatDto.ts b/src/services/api/models/ClusterStatDto.ts new file mode 100644 index 0000000..dc711bb --- /dev/null +++ b/src/services/api/models/ClusterStatDto.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { WellStatDto } from './WellStatDto'; + +export type ClusterStatDto = { + id?: number; + caption?: string | null; + description?: string | null; + latitude?: number | null; + longitude?: number | null; + wellsStat?: Array | null; +} \ No newline at end of file diff --git a/src/services/api/models/CompanyDto.ts b/src/services/api/models/CompanyDto.ts new file mode 100644 index 0000000..fcd415a --- /dev/null +++ b/src/services/api/models/CompanyDto.ts @@ -0,0 +1,9 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type CompanyDto = { + id?: number; + caption?: string | null; + companyType?: string | null; +} \ No newline at end of file diff --git a/src/services/api/models/DataSaubBaseDto.ts b/src/services/api/models/DataSaubBaseDto.ts index 0a9e94f..e12e1c5 100644 --- a/src/services/api/models/DataSaubBaseDto.ts +++ b/src/services/api/models/DataSaubBaseDto.ts @@ -38,4 +38,6 @@ export type DataSaubBaseDto = { flow?: number | null; flowIdle?: number | null; flowDeltaLimitMax?: number | null; + idFeedRegulator?: number | null; + mseState?: number | null; } \ No newline at end of file diff --git a/src/services/api/models/DepositDto.ts b/src/services/api/models/DepositDto.ts index a605887..0cbaeec 100644 --- a/src/services/api/models/DepositDto.ts +++ b/src/services/api/models/DepositDto.ts @@ -6,6 +6,6 @@ export type DepositDto = { id?: number; name?: string | null; description?: string | null; - latitude?: number; - longitude?: number; + latitude?: number | null; + longitude?: number | null; } \ No newline at end of file diff --git a/src/services/api/models/OperationDto.ts b/src/services/api/models/OperationDto.ts new file mode 100644 index 0000000..9481988 --- /dev/null +++ b/src/services/api/models/OperationDto.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type OperationDto = { + id?: number; + name?: string | null; + beginDate?: string; + endDate?: string; + startWellDepth?: number; + endWellDepth?: number; +} \ No newline at end of file diff --git a/src/services/api/models/OperationDtoPaginationContainer.ts b/src/services/api/models/OperationDtoPaginationContainer.ts new file mode 100644 index 0000000..64fcf00 --- /dev/null +++ b/src/services/api/models/OperationDtoPaginationContainer.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { OperationDto } from './OperationDto'; + +export type OperationDtoPaginationContainer = { + skip?: number; + take?: number; + count?: number; + items?: Array | null; +} \ No newline at end of file diff --git a/src/services/api/models/OperationDurationDto.ts b/src/services/api/models/OperationDurationDto.ts index 7f061a0..5be7a04 100644 --- a/src/services/api/models/OperationDurationDto.ts +++ b/src/services/api/models/OperationDurationDto.ts @@ -3,6 +3,6 @@ /* eslint-disable */ export type OperationDurationDto = { - processName?: string | null; + operationName?: string | null; duration?: number; } \ No newline at end of file diff --git a/src/services/api/models/UserTokenDto.ts b/src/services/api/models/UserTokenDto.ts index 9b4db8f..1439c28 100644 --- a/src/services/api/models/UserTokenDto.ts +++ b/src/services/api/models/UserTokenDto.ts @@ -9,7 +9,7 @@ export type UserTokenDto = { surname?: string | null; patronymic?: string | null; id?: number; - customerName?: string | null; + companyName?: string | null; roleName?: string | null; token?: string | null; } \ No newline at end of file diff --git a/src/services/api/models/WellDto.ts b/src/services/api/models/WellDto.ts index 17e0645..e33d86b 100644 --- a/src/services/api/models/WellDto.ts +++ b/src/services/api/models/WellDto.ts @@ -8,6 +8,7 @@ export type WellDto = { deposit?: string | null; id?: number; lastData?: any; - latitude?: number; - longitude?: number; + latitude?: number | null; + longitude?: number | null; + wellType?: string | null; } \ No newline at end of file diff --git a/src/services/api/models/WellSectionDto.ts b/src/services/api/models/WellSectionDto.ts new file mode 100644 index 0000000..684e7e5 --- /dev/null +++ b/src/services/api/models/WellSectionDto.ts @@ -0,0 +1,21 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type WellSectionDto = { + sectionType?: string | null; + wellDepthPlan?: number; + wellDepthFact?: number; + buildDaysPlan?: number; + buildDaysFact?: number; + rateOfPenetrationPlan?: number; + rateOfPenetrationFact?: number; + routeSpeedPlan?: number; + routeSpeedFact?: number; + bhaUpSpeedPlan?: number; + bhaUpSpeedFact?: number; + bhaDownSpeedPlan?: number; + bhaDownSpeedFact?: number; + casingDownSpeedPlan?: number; + casingDownSpeedFact?: number; +} \ No newline at end of file diff --git a/src/services/api/models/WellStatDto.ts b/src/services/api/models/WellStatDto.ts new file mode 100644 index 0000000..18176e6 --- /dev/null +++ b/src/services/api/models/WellStatDto.ts @@ -0,0 +1,28 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { CompanyDto } from './CompanyDto'; +import type { WellSectionDto } from './WellSectionDto'; + +export type WellStatDto = { + caption?: string | null; + cluster?: string | null; + deposit?: string | null; + id?: number; + lastData?: any; + latitude?: number | null; + longitude?: number | null; + wellType?: string | null; + planStart?: string | null; + planEnd?: string | null; + factStart?: string | null; + factEnd?: string | null; + unProductiveDays?: number | null; + rateOfPenetrationPlan?: number | null; + rateOfPenetrationFact?: number | null; + routeSpeedPlan?: number | null; + routeSpeedFact?: number | null; + sections?: Array | null; + companies?: Array | null; +} \ No newline at end of file diff --git a/src/services/api/services/AnalyticsService.ts b/src/services/api/services/AnalyticsService.ts index e9d0d87..8c52822 100644 --- a/src/services/api/services/AnalyticsService.ts +++ b/src/services/api/services/AnalyticsService.ts @@ -1,6 +1,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { OperationDtoPaginationContainer } from '../models/OperationDtoPaginationContainer'; import type { OperationDurationDto } from '../models/OperationDurationDto'; import type { WellDepthToDayDto } from '../models/WellDepthToDayDto'; import type { WellDepthToIntervalDto } from '../models/WellDepthToIntervalDto'; @@ -8,6 +9,39 @@ import { request as __request } from '../core/request'; export class AnalyticsService { + /** + * Возвращает список операций на скважине за все время + * @param wellId id скважины + * @param skip для пагинации кол-во записей пропустить + * @param take для пагинации кол-во записей + * @param categoryIds список категорий + * @param begin дата начала + * @param end окончание + * @returns OperationDtoPaginationContainer Success + * @throws ApiError + */ + public static async getOperationsByWell( +wellId: number, +skip: number, +take: number = 32, +categoryIds?: Array, +begin?: string, +end?: string, +): Promise { + const result = await __request({ + method: 'GET', + path: `/api/analytics/${wellId}/operationsByWell`, + query: { + 'skip': skip, + 'take': take, + 'categoryIds': categoryIds, + 'begin': begin, + 'end': end, + }, + }); + return result.body; + } + /** * Возвращает данные по скважине "глубина-день" * @param wellId id скважины @@ -27,22 +61,22 @@ wellId: number, /** * Возвращает данные по глубине скважины за период * @param wellId id скважины - * @param intervalHoursTimestamp количество секунд в необходимом интервале времени - * @param workBeginTimestamp количество секунд в времени начала смены + * @param intervalSeconds количество секунд в необходимом интервале времени + * @param workBeginSeconds количество секунд в времени начала смены * @returns WellDepthToIntervalDto Success * @throws ApiError */ public static async getWellDepthToInterval( wellId: number, -intervalHoursTimestamp?: number, -workBeginTimestamp?: number, +intervalSeconds?: number, +workBeginSeconds?: number, ): Promise> { const result = await __request({ method: 'GET', path: `/api/analytics/${wellId}/wellDepthToInterval`, query: { - 'intervalHoursTimestamp': intervalHoursTimestamp, - 'workBeginTimestamp': workBeginTimestamp, + 'intervalSeconds': intervalSeconds, + 'workBeginSeconds': workBeginSeconds, }, }); return result.body; @@ -75,22 +109,22 @@ end?: string, /** * Возвращает детальные данные по операциям на скважине за период * @param wellId id скважины - * @param intervalHoursTimestamp количество секунд в необходимом интервале времени - * @param workBeginTimestamp количество секунд в времени начала смены + * @param intervalSeconds количество секунд в необходимом интервале времени + * @param workBeginSeconds количество секунд в времени начала смены * @returns OperationDurationDto Success * @throws ApiError */ public static async getOperationsToInterval( wellId: number, -intervalHoursTimestamp?: number, -workBeginTimestamp?: number, +intervalSeconds?: number, +workBeginSeconds?: number, ): Promise> { const result = await __request({ method: 'GET', path: `/api/analytics/${wellId}/operationsToInterval`, query: { - 'intervalHoursTimestamp': intervalHoursTimestamp, - 'workBeginTimestamp': workBeginTimestamp, + 'intervalSeconds': intervalSeconds, + 'workBeginSeconds': workBeginSeconds, }, }); return result.body; diff --git a/src/services/api/services/ClusterService.ts b/src/services/api/services/ClusterService.ts index e839088..da970cc 100644 --- a/src/services/api/services/ClusterService.ts +++ b/src/services/api/services/ClusterService.ts @@ -1,8 +1,8 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ -import type { ClusterAnalysisDto } from '../models/ClusterAnalysisDto'; import type { ClusterDto } from '../models/ClusterDto'; +import type { ClusterStatDto } from '../models/ClusterStatDto'; import type { WellDto } from '../models/WellDto'; import { request as __request } from '../core/request'; @@ -23,32 +23,32 @@ export class ClusterService { /** * Получение доступных пользователю скважин - * @param clusterId + * @param idCluster * @returns WellDto Success * @throws ApiError */ public static async getWells( -clusterId: number, +idCluster: number, ): Promise> { const result = await __request({ method: 'GET', - path: `/api/cluster/${clusterId}`, + path: `/api/cluster/${idCluster}`, }); return result.body; } /** - * Получение обопщенной аналитики по кусту (лучшая/худшая скважина) - * @param clusterId - * @returns ClusterAnalysisDto Success + * Получение обопщенной статистики по кусту (лучшая/худшая скважина) + * @param idCluster + * @returns ClusterStatDto Success * @throws ApiError */ - public static async getAnalysis( -clusterId: number, -): Promise> { + public static async getStat( +idCluster: number, +): Promise { const result = await __request({ method: 'GET', - path: `/api/cluster/${clusterId}/Analysis`, + path: `/api/cluster/${idCluster}/Stat`, }); return result.body; } From a90f34a0afc80375507b99aff7e06369c1e784a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 22 Jul 2021 10:17:39 +0500 Subject: [PATCH 09/32] =?UTF-8?q?CF2-27=20=D0=9D=D0=B0=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=83=20=D0=B2=D1=8B=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=D0=B0=20=D0=BA=D1=83=D1=81=D1=82=D0=B0=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=B5=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Deposit.jsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx index 17b7c9c..038ad3c 100644 --- a/src/pages/Deposit.jsx +++ b/src/pages/Deposit.jsx @@ -4,6 +4,7 @@ import {Link} from "react-router-dom"; import LoaderPortal from '../components/LoaderPortal' import { useState, useEffect } from "react"; import {ClusterService} from '../services/api' +import notify from '../components/notify' const calcViewParams = (clusters) => { if (clusters.length === 0) @@ -34,8 +35,10 @@ export default function Deposit() { try{ const data = await ClusterService.getClusters() setClustersData(data) - }catch{ - //ignore + } + catch(ex) { + notify(`Не удалось загрузить список кустов`, 'error') + console.log(ex) } setShowLoader(false) } @@ -59,7 +62,7 @@ export default function Deposit() { > + - {cluster.name} + {cluster.caption} )} From e972a660f1bd749be0498b1cf6d635f3f29b0d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 22 Jul 2021 10:18:00 +0500 Subject: [PATCH 10/32] =?UTF-8?q?CF2-28=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D1=82=D1=8C=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D1=83?= =?UTF-8?q?=20=D0=B4=D0=B5=D1=82=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20=D0=BA=D1=83=D1=81=D1=82=D0=B0(Cluster).=20=D0=9F?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BD=D0=B5=D1=81=D1=82=D0=B8=20=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B5=20=D0=B2=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA?= =?UTF-8?q?=D1=83=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=20(=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D1=88=D0=B0=D1=8F/=D1=85=D1=83=D0=B4=D1=88=D0=B0=D1=8F?= =?UTF-8?q?=20=D1=81=D0=BA=D0=B2=D0=B0=D0=B6=D0=B8=D0=BD=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Cluster.jsx | 141 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 3 deletions(-) diff --git a/src/pages/Cluster.jsx b/src/pages/Cluster.jsx index d8743b3..74855b2 100644 --- a/src/pages/Cluster.jsx +++ b/src/pages/Cluster.jsx @@ -1,8 +1,143 @@ import {useParams} from "react-router-dom"; +import {Link} from "react-router-dom"; +import LoaderPortal from '../components/LoaderPortal' +import { useState, useEffect } from "react"; +import {ClusterService} from '../services/api' +import notify from '../components/notify' +import {Table, Tag, Button} from 'antd'; -export default function Cluster() { - +const columns = [ + { + title: 'скв №', + key: 'caption', + dataIndex: 'caption', + render: (_, item) => {item.caption} + }, + { + title: 'Тип скв.', + key: 'wellType', + dataIndex: 'wellType', + }, + { + title: 'Фактические сроки бурения', + children: [ + { + title: 'начало', + key: 'factStart', + dataIndex: 'factStart', + }, + { + title: 'окончание', + key: 'factEnd', + dataIndex: 'factEnd', + }, + ] + }, + { + title: 'Продолжительность бурения', + children: [ + { + title: 'план', + key: 'periodPlan', + dataIndex: 'periodPlan', + }, + { + title: 'факт', + key: 'periodFact', + dataIndex: 'periodFact', + }, + ] + }, + { + title: 'МСП за скв', + children: [ + { + title: 'план', + key: 'rateOfPenetrationPlan', + dataIndex: 'rateOfPenetrationPlan', + }, + { + title: 'факт', + key: 'rateOfPenetrationFact', + dataIndex: 'rateOfPenetrationFact', + }, + ], + }, + { + title: 'Рейсовая скорость за скв', + children: [ + { + title: 'план', + key: 'routeSpeedPlan', + dataIndex: 'routeSpeedPlan', + }, + { + title: 'факт', + key: 'routeSpeedFact', + dataIndex: 'routeSpeedFact', + }, + ], + }, + { + title: 'Секции', + key: 'sections', + dataIndex: 'sections', + render: (item) => (таблица по секциям) + }, + { + title: 'График глубина-день', + render: _ => () + }, + { + title: 'Таблица по операциям', + render: _ => () + }, + { + title: 'Подрядчики', + key: 'companies', + dataIndex: 'companies', + render: (item) => item.map(company => {company.caption}) + }, +]; + +export default function Cluster() { let { id } = useParams() + const [clusterTitle, setClusterTitle] = useState("") + const [wellsStat, setWellsStat] = useState(null) + const [showLoader, setShowLoader] = useState(false) - return(
Куст {id}
) + useEffect(()=>{ + const updateWellsStat = async() => { + setShowLoader(true) + try{ + const msInDay = 1000*60*60*24 + const data = await ClusterService.getStat(id) + const wellsStat = data.wellsStat.map(w=>({...w, + periodPlan: (new Date(w.planEnd) - new Date(w.planStart))/msInDay, + periodFact: (new Date(w.factEnd) - new Date(w.factStart))/msInDay, + })) + setWellsStat(wellsStat) + setClusterTitle(data.caption) + } + catch(ex) { + notify(`Не удалось загрузить статистику по скважинам куста "${id}"`, 'error') + console.log(ex) + } + setShowLoader(false) + } + updateWellsStat() + },[id]) + + return( + +

{clusterTitle}

+
record.id} + /> + ) } \ No newline at end of file From dd9fc2514d38ff9ea7bc57fa047a58e290c76389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Thu, 22 Jul 2021 11:43:58 +0500 Subject: [PATCH 11/32] =?UTF-8?q?=D1=81=D0=BE=D1=80=D1=82=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=20=D0=B8=20=D1=81=D1=82=D1=80=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/{pages => components}/LayoutPortal.jsx | 2 +- src/{pages/Header.jsx => components/PageHeader.jsx} | 8 +++++--- src/pages/Main.jsx | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) rename src/{pages => components}/LayoutPortal.jsx (89%) rename src/{pages/Header.jsx => components/PageHeader.jsx} (79%) diff --git a/src/pages/LayoutPortal.jsx b/src/components/LayoutPortal.jsx similarity index 89% rename from src/pages/LayoutPortal.jsx rename to src/components/LayoutPortal.jsx index b1ff72e..ce89995 100644 --- a/src/pages/LayoutPortal.jsx +++ b/src/components/LayoutPortal.jsx @@ -1,5 +1,5 @@ import {Layout} from 'antd' -import PageHeader from './Header' +import PageHeader from './PageHeader' const {Content} = Layout diff --git a/src/pages/Header.jsx b/src/components/PageHeader.jsx similarity index 79% rename from src/pages/Header.jsx rename to src/components/PageHeader.jsx index ab1de4a..f8b82cc 100644 --- a/src/pages/Header.jsx +++ b/src/components/PageHeader.jsx @@ -2,7 +2,7 @@ import { Layout, Button } from 'antd' import { UserOutlined } from '@ant-design/icons' import logo from '../images/logo_32.png' import { Link } from "react-router-dom" -import WellTreeSelector from '../components/WellTreeSelector' +import WellTreeSelector from './WellTreeSelector' const { Header } = Layout @@ -17,9 +17,11 @@ export default function PageHeader({title='Мониторинг', wellsList}){ return(
- АСБ + + АСБ + -

{title}

+

{title}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ НаименованиеТемпература, °CПлотность, г/см³Усл. вязкость, секR300R600R3/R6ДНС, дПаПластич. вязкость, сПзСНС, дПаR3/R6 49СДНС 49С, дПаПластич. вязкость 49С, сПзСНС 49С, дПаМВТ, кг/м³Песок, %Фильтрация, см³/30минКорка, ммКТКрНЖесткость, мг/лХлориды, мг/лPfMfPmТвердая фаза раствора, %Смазка, %Карбонат кальция, кг/м³
План                           
Факт                           
+
 
+

{date}

+ + ) +} \ No newline at end of file diff --git a/src/components/Disposition.jsx b/src/components/Disposition.jsx new file mode 100644 index 0000000..b40e30b --- /dev/null +++ b/src/components/Disposition.jsx @@ -0,0 +1,19 @@ +let date = new Date().toLocaleString() + + +export default function Disposition() { + return ( + <> +

Распоряжение

+ +

+ Текст +

+ +

Ф.И.О.

+

Должность

+

Компания

+

{date}

+ + ) +} \ No newline at end of file diff --git a/src/components/Documents.jsx b/src/components/Documents.jsx new file mode 100644 index 0000000..db405b0 --- /dev/null +++ b/src/components/Documents.jsx @@ -0,0 +1,170 @@ +import {Table, DatePicker, Form, Button, Upload, ConfigProvider} from 'antd'; +import { UploadOutlined } from '@ant-design/icons'; +import MenuDocuments from "./MenuDocuments"; +import {useState, useEffect} from "react"; +import {useParams} from 'react-router-dom' +import notify from './notify' +import LoaderPortal from './LoaderPortal' +import locale from "antd/lib/locale/ru_RU"; +import moment from 'moment' + +const pageSize = 26 +const {RangePicker} = DatePicker; + +const columns = [ + { + title: 'Документ', + key: 'document', + dataIndex: 'name', + }, + { + title: 'Дата загрузки', + key: 'uploadDate', + dataIndex: 'uploadDate', + render: (item) => moment.utc(item).local().format('DD MMM YYYY, HH:mm:ss') + }, + { + title: 'Ф.И.О.', + key: 'name', + dataIndex: 'name', + } +]; + +export default function Documents() { + let {id} = useParams() + + const [page, setPage] = useState(1) + const [range, setRange] = useState([]) + const [pagination, setPagination] = useState(null) + const [files, setFiles] = useState([]) + + const [loader, setLoader] = useState(false) + + const submitFileFormProps = { + //action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', + onChange({ file, fileList }) { + if (file.status !== 'uploading') { + console.log(file, fileList); + } + } + } + + const onChangeRange = (range) => { + setRange(range) + } + + const onFinish = (values) => { + console.log('Success:', values); + } + + const onFinishFailed = (errorInfo) => { + console.log('Failed:', errorInfo); + } + + const fileList = [] + + useEffect(() => { + const GetDocuments = async () => { + setLoader(true) + + try { + let begin = null + let end = null + if (range?.length > 1) { + begin = range[0].toISOString() + end = range[1].toISOString() + } + // await AnalyticsService.getOperationsByWell( + // `${id}`, + // (page-1) * pageSize, + // pageSize, + // begin, + // end).then((paginatedFiles) => { + // setFiles(paginatedFiles?.items.map(f => { + // return { + // key: f.id, + // begin: f.date, + // ...f + // } + // })) + + // setPagination({ + // total: paginatedFiles?.count, + // current: Math.floor(paginatedFiles?.skip / pageSize), + // }) + // } + //) + } catch (ex) { + notify(`Не удалось загрузить файлы по скважине "${id}"`, 'error') + console.log(ex) + } + setLoader(false) + } + GetDocuments() + }, [id, range]) + + return ( +
+ +
+

Фильтр документов:

+ + + +
+ +
 
+
+
+ + {/* { + setFile(e.target.value) + files.push(e.target.value) + localStorage.setItem(e.target.value, file) + setFiles(files) + console.log(e.target.value) + } + }/> */} + + + + + + + +
+
+
 
+ setPage(page) + }} + rowKey={(record) => record.id} + /> + ); +} \ No newline at end of file diff --git a/src/components/MenuDocuments.jsx b/src/components/MenuDocuments.jsx new file mode 100644 index 0000000..d3b73ce --- /dev/null +++ b/src/components/MenuDocuments.jsx @@ -0,0 +1,40 @@ +import {Menu} from "antd"; +import {FolderOutlined} from "@ant-design/icons"; +import {Link} from "react-router-dom"; + + +export default function MenuDocuments() { + return( + <> + + }> + Растворный сервис + + }> + Цементирование + + }> + ННБ + + }> + ГТИ + + }> + Документы по скважине + + }> + Супервайзер + + }> + Мастер + + }> + Последние данные + + + ) +} diff --git a/src/components/NnbTable.jsx b/src/components/NnbTable.jsx new file mode 100644 index 0000000..978e7c6 --- /dev/null +++ b/src/components/NnbTable.jsx @@ -0,0 +1,250 @@ +let date = new Date().toLocaleString() + +export function NnbTable() { + return (<> +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Глубина по + стволу, мЗенитный + угол, градАзимут + магнитный, градАзимут + истинный, градАзимут + дирекц., градГлубина по + вертикали, мАбсолютная + отметка, мЛок. + смещение к северу, мЛок. + смещение к востоку, мОтклонение + от устья, мАзимут + смещения, градОтклонение + от устья, мПространст. + интенсивность, град/10 мУгол + установки отклон., градИнтенсив. + по зениту, град/10 мКомментарийРазница вертикальных глубин + между ХХХ (план) и ХХХ (факт)Расстояние в пространстве между + ХХХ (план) и ХХХ (факт)


















+
 
+

{date}

+ ) +} \ No newline at end of file diff --git a/src/components/Sludge.jsx b/src/components/Sludge.jsx new file mode 100644 index 0000000..4705892 --- /dev/null +++ b/src/components/Sludge.jsx @@ -0,0 +1,383 @@ +let date = new Date().toLocaleString() + +export function Sludge() { + return (<> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
N пробы + Глубина + отбора пробыЛитологияКраткое + описаниеЛБА + бурового раствора ЛБА + (шлама)Газопоказания + Мех. + скоростьПредварительное заключение о насыщении по ГК
Песчаник + (%) Алевролит + (%)Аргиллит + (%)Аргиллит + бит. (%)Уголь + (%)Песок + (%)Глина + (%)Известняк + (%)Цемент + (%)Сумма + УВ мах. (абс%) С1 + метан (отн%)С2 этан + (отн%)С3 + пропан (отн%)С4 + бутан (отн%)С5 + пентан (отн%)






















+
 
+

{date}

+ + ) +} \ No newline at end of file diff --git a/src/pages/Cementing.jsx b/src/pages/Cementing.jsx new file mode 100644 index 0000000..b46fee5 --- /dev/null +++ b/src/pages/Cementing.jsx @@ -0,0 +1,8 @@ +import Documents from "../components/Documents" + +export default function Cementing() { + + return( + + ) +} \ No newline at end of file diff --git a/src/pages/DocumentForWell.jsx b/src/pages/DocumentForWell.jsx new file mode 100644 index 0000000..cdbf72e --- /dev/null +++ b/src/pages/DocumentForWell.jsx @@ -0,0 +1,8 @@ +import Documents from "../components/Documents" + +export default function DocumentsForWell() { + + return( + + ) +} \ No newline at end of file diff --git a/src/pages/FluidService.jsx b/src/pages/FluidService.jsx new file mode 100644 index 0000000..fa8e795 --- /dev/null +++ b/src/pages/FluidService.jsx @@ -0,0 +1,8 @@ +import Documents from "../components/Documents" + +export default function FluidService() { + + return( + + ) +} \ No newline at end of file diff --git a/src/pages/Gti.jsx b/src/pages/Gti.jsx new file mode 100644 index 0000000..4f37cf5 --- /dev/null +++ b/src/pages/Gti.jsx @@ -0,0 +1,8 @@ +import Documents from "../components/Documents" + +export default function Gti() { + + return( + + ) +} \ No newline at end of file diff --git a/src/pages/LastData.jsx b/src/pages/LastData.jsx new file mode 100644 index 0000000..a331594 --- /dev/null +++ b/src/pages/LastData.jsx @@ -0,0 +1,94 @@ +import {Button, Modal, Checkbox } from "antd"; +import {CementFluid} from "../components/CementFluid"; +import React, {useState} from "react"; +import {Sludge} from "../components/Sludge"; +import {NnbTable} from "../components/NnbTable" +import Disposition from "../components/Disposition"; +import MenuDocuments from "../components/MenuDocuments"; + + +export default function LastData() { + const [tableVisible, setTableVisible] = useState(false) + const [tableSludgeVisible, setTableSludgeVisible] = useState(false) + const [tableNNBVisible, setTableNNBVisible] = useState(false) + const [dispositionVisible, setDispositionVisible] = useState(false) + + return ( + <> +
+ +
+
 
+ + setTableVisible(false)} + onCancel={() => setTableVisible(false)} + width={1800} + okText='Ок' + cancelText='Отмена' + > + + + + setTableSludgeVisible(false)} + onCancel={() => setTableSludgeVisible(false)} + width={1600} + okText='Ок' + cancelText='Отмена' + > + + + + setTableNNBVisible(false)} + onCancel={() => setTableNNBVisible(false)} + width={1400} + okText='Ок' + cancelText='Отмена' + > + + + + setDispositionVisible(false)} + onCancel={() => setDispositionVisible(false)} + width={850} + okText='Ок' + cancelText='Отмена' + footer={[ + Принять распоряжение, + , + + ]} + > + + + ) +} \ No newline at end of file diff --git a/src/pages/Master.jsx b/src/pages/Master.jsx new file mode 100644 index 0000000..56da051 --- /dev/null +++ b/src/pages/Master.jsx @@ -0,0 +1,8 @@ +import Documents from "../components/Documents" + +export default function Master() { + + return( + + ) +} \ No newline at end of file diff --git a/src/pages/Messages.jsx b/src/pages/Messages.jsx index 0b410c6..2f9e92e 100644 --- a/src/pages/Messages.jsx +++ b/src/pages/Messages.jsx @@ -110,7 +110,7 @@ export default function Messages() { <>
-

Фильтр сообщений

+

Фильтр сообщений

record.id} /> - + ) } \ No newline at end of file diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts index 02aad65..1e4a66a 100644 --- a/src/services/signalr/index.ts +++ b/src/services/signalr/index.ts @@ -14,12 +14,12 @@ type ConnectionsDict = { const Connections: ConnectionsDict = { 'hubs/telemetry': new HubConnectionBuilder() - .withUrl(`http://192.168.1.70:5000/hubs/telemetry`, ConnectionOptions) + .withUrl(`http://localhost:5000/hubs/telemetry`, ConnectionOptions) .withAutomaticReconnect() .build(), 'hubs/reports': new HubConnectionBuilder() - .withUrl(`http://192.168.1.70:5000/hubs/reports`, ConnectionOptions) + .withUrl(`http://localhost:5000/hubs/reports`, ConnectionOptions) .withAutomaticReconnect() .build() } diff --git a/src/styles/index.css b/src/styles/index.css index 8d31ab7..9a60f46 100644 --- a/src/styles/index.css +++ b/src/styles/index.css @@ -48,3 +48,11 @@ code { monospace; } +.linkDocuments { + color: #000; +} + +.linkDocuments:hover { + color: #c32828; +} + diff --git a/src/styles/message.css b/src/styles/message.css index fb003b0..cd0e395 100644 --- a/src/styles/message.css +++ b/src/styles/message.css @@ -33,7 +33,7 @@ margin: 0 0 5px 0; } -.filter-group__heading { +.filter-group-heading { margin: 5px auto; align-items: center; } From 8c00b0568ceb47e0f607b49f1be3ff8aa2551b58 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jul 2021 16:16:10 +0500 Subject: [PATCH 15/32] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=D0=B5=D0=BD=D0=B0=20=D0=BC=D0=BD=D0=B5=D0=BC=D0=BE=D1=81?= =?UTF-8?q?=D1=85=D0=B5=D0=BC=D0=B0=20=D0=B8=D0=B7=20=D0=B2=D0=B5=D1=82?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=B4=D0=B5=D0=BC=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/CustomColumn.jsx | 14 ++- src/components/RigMnemo.jsx | 184 ++++++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+), 5 deletions(-) create mode 100644 src/components/RigMnemo.jsx diff --git a/src/components/CustomColumn.jsx b/src/components/CustomColumn.jsx index c8d5da3..02aa7e5 100644 --- a/src/components/CustomColumn.jsx +++ b/src/components/CustomColumn.jsx @@ -1,4 +1,5 @@ import {Display} from './Display' +import RigMnemo from '../components/RigMnemo' export const CustomColumn = ({data}) => { const dataLast = data[data.length -1] @@ -17,10 +18,13 @@ export const CustomColumn = ({data}) => { lines.forEach(line => line.value = '-' ) return (<> - {lines.map(line => )} + {lines.map(line => )} + ) } \ No newline at end of file diff --git a/src/components/RigMnemo.jsx b/src/components/RigMnemo.jsx new file mode 100644 index 0000000..3a9a58f --- /dev/null +++ b/src/components/RigMnemo.jsx @@ -0,0 +1,184 @@ +const styleBase = { + stroke: "none", + strokeLinecap: "butt", + strokeLinejoin: "miter", +} + +const styleCasing = { + ...styleBase, + fill: "#808080", +}; +const styleGround = { + ...styleBase, + fill: "#deaa87", +}; + +const styleTower = { + ...styleBase, + fill: "#999999", +}; + +const styleWell = { + ...styleBase, + fill: "#37abc8", +}; + +const styleBitDrive = { + ...styleBase, + fill: "#ff8080", +}; + +const styleBitTool = { + ...styleBase, + fill: "#f9f9f9", +}; + +const styleBlock = { + ...styleBase, + fill: "#ffdd55", +}; + +const stylePump1 = { + ...styleBase, + fill: "#5fd35f", +}; + +const stylePump2 = { + ...styleBase, + fill: "#b3b3b3", +}; + +export default function RigMnemo({ + blockPosition, + bitPosition, +}) { + + let blockPositionLocal = +blockPosition + blockPositionLocal = blockPositionLocal ? blockPositionLocal : 0 + const blockTranslate = `translate(-75, ${-35 + (50 * (30 - blockPositionLocal) / 30)})` + + let bitPositionLocal = +bitPosition + bitPositionLocal = bitPositionLocal ? bitPositionLocal : 0 + //const bitTranslate = `translate(0, ${-41 + 41 * (3426 - bitPosition)/(3426 - 3200)})` + const bitTranslate = `translate(0, 0)` + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} From 47ebddeb3faab6f66552a8ad596c5642e257a9e1 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jul 2021 17:15:33 +0500 Subject: [PATCH 16/32] =?UTF-8?q?=D0=9D=D0=BE=D1=80=D0=BC=D0=B0=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D1=8B=D0=B5=20=D1=81=D1=82=D0=B8=D0=BB=D0=B8=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=9C=D0=BD=D0=B5=D0=BC=D0=BE=D1=81=D1=85?= =?UTF-8?q?=D0=B5=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/images/DempherOff.png | Bin 0 -> 974 bytes src/images/DempherOn.png | Bin 0 -> 1223 bytes src/images/SpinDisabled.png | Bin 0 -> 1566 bytes src/images/SpinEnabled.png | Bin 0 -> 1903 bytes src/pages/TelemetryView.jsx | 66 ++++++++++----- src/services/api/index.ts | 2 + src/services/api/models/ClusterDto.ts | 3 + src/services/api/models/ClusterStatDto.ts | 2 + src/services/api/models/DepositDto.ts | 5 +- src/services/api/models/FilePropertiesDto.ts | 11 +++ src/services/api/models/WellDto.ts | 1 - src/services/api/models/WellStatDto.ts | 1 - src/services/api/services/AnalyticsService.ts | 10 +-- src/services/api/services/FileService.ts | 80 ++++++++++++++++++ 15 files changed, 154 insertions(+), 29 deletions(-) create mode 100644 src/images/DempherOff.png create mode 100644 src/images/DempherOn.png create mode 100644 src/images/SpinDisabled.png create mode 100644 src/images/SpinEnabled.png create mode 100644 src/services/api/models/FilePropertiesDto.ts create mode 100644 src/services/api/services/FileService.ts diff --git a/package.json b/package.json index 709c113..5d3a0a0 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "react_test": "react-scripts test", "eject": "react-scripts eject" }, - "proxy": "http://127.0.0.1:5000", + "proxy": "http://192.168.1.70:5000", "eslintConfig": { "extends": [ "react-app", diff --git a/src/images/DempherOff.png b/src/images/DempherOff.png new file mode 100644 index 0000000000000000000000000000000000000000..c179c94db2f5f82497894cee5f2e9c22ad78c14c GIT binary patch literal 974 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 literal 0 HcmV?d00001 diff --git a/src/images/SpinDisabled.png b/src/images/SpinDisabled.png new file mode 100644 index 0000000000000000000000000000000000000000..c19ce753eff8c51396d5aed589ff23e789e0313d GIT binary patch literal 1566 zcmV+(2I2XMP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9 za%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00oXoL_t(oN6nXcR~kta#UCIjilXAKF{nr5 zL``%u-~S6FQ}r zW%jqWB-Gq2k%k6|G&V|@dpHu2U^pxi3OQB|bgFz_3dN%2b2%xLN>bo{dv_;80|OFj zX>knwQIpJRDkZ6OT0%iY#MBsb&$H;<#DqjTI*gs%-^NhOoXN1Ga`N#^19)=c_@ zdlpl%yWYNi9B?6s8p&9eau=B}Wr3ALFST$w)XdB8s9f}cRQmFaMQ-h zid;c7&SG7Oghbh~W{jr#`T4n=qEv_}C&{3S_jzxAeqQ3Zd~AB!87!lM%nHU4cJuDz zM`y$Vi!H9MG9NXAOsZJu3G94xds{NtPoYqY+pQq|>z8~#K9*0^s1UK_h9_pS>?{kn zLHuoFbA8A1hL^E^ZVjLf*8iA6>elm z@eKZdr?J2y^=MDoWWC32V+W z89n;Bl`QERRVfJO>pbi{V6J;&NBbW)N{s28LA>EcnG9&c!1kk1pc>iPIhpoSTsrTx zSuV~x8*8$X#X}}Wlxs%W=p}g1I9K${dI|Qa=FM!dfqC7ya;mg;kZyR$w8!I;y`iBlJ}=p9k6Js{BZ2*}V9Y%eW626`2o zLS*;%ZyBIWv{=>pmT|4}Jw8?3Lq>yY0CkR38LJ>gdHFrZ#3h6lIKR%c)Vtk=3RhI> zjpb$8VZnaVdWgQp#x6aQMv6^RQQ1O}cJs6l+Eh*0hb6eDqV7=Q(~u27UXxSPx5#gW zCcy{|SgfbVJiC#G$al^p-;MxOk^$EQ-WqMhFoD-kV`P9LY1BxJj+#eRkz#psc`0!YMnwVJ#c$uFn+!^FZu!BNjN*_MF-6pm(zA5ao9HLYF0u3v zeTZLUWMh4C(eycg(V!I|wM_6g5qncrK3Se6qu7Jc0fdG)WiL>mgbTvBQ5UF&W88Si zdnN|SniOQB6uK#GsH*hORmmvS&nW`Zd;>ALo+o{{qi<}?vG79Ou?(3Ai>keTRkq{8 z5e;UZtHGO1K1gV=xh4rgYM-6vo$6|1(?!JWlWSyTq$UwXO)@up+TJjs%BP*4UP@?9 z3!rtj{Gct(v#1`fCG7N_0PacgrBM%Rx@qh4XDK0bBfAZA>BqnMbmeyofgHwV1`xZz zojRTQ=;v9R^a7WD_|MX=25Ph+)ye2zb;w&6>X@shGJg^^W9Cod6_FA74`m#wm`U_c Qy#N3J07*qoM6N<$g2U15asU7T literal 0 HcmV?d00001 diff --git a/src/images/SpinEnabled.png b/src/images/SpinEnabled.png new file mode 100644 index 0000000000000000000000000000000000000000..d888ddc4f0f58ba6d79553496596e272b4e17823 GIT binary patch literal 1903 zcmV-#2ax!QP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9 za%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00!SlL_t(oN6nXea8%VD$G^MTO?Hzd7zl>E zz@TO0`amRPfJn;}(T>_;c?(Vp{i9A%Yf(pJY#s11I@5w3(4o|EkYou3Q7H*dLv|3! z0tp}qLIA0Gun9>vFY?%Avzy)h_1t@Zc=wWIH%>bpJ~O#Dzwi0od%ycT=bm$qjs&$3G zi_O#5A;FTwNy8J>%-_Dr$8#6AA<>wCP$+~TLI{L{7!VJ0J>fv+?RRn}FrhFHoq9ja z`dGy1^w5jH0EKW*Y%0nZ?&GYH8P%9c-#;I*Mw5JV3AgV$wprI=&HXFo_y%527seJX zK!&KCPN$Q#c7Hc2=I%gt%H47tiKt^H(C@)GW1^^t;<-QQ!>sr_hZvDCTW-V7`(Ab0jZmYLl`0CXVaXbr{wsBvQ31-Y2>VP%5g*jM3z0XC}rP1jh4ICArE*Eny3Vi?hA98^&wnY} zvnlW3Q?#pkA62!Sr|On!I#lDJ-+cM1XuF5v>@%pU;cLD~i)nWbEiQSMBP~PB+_7%~ z%_~~PQ5b_nN&mP1dA&9)t|^ermM@%ii*a}<(7*g(MC?! zNmf*H4=feGY9^7-&q`z-KD1ig>plv3y{xF{><`eNDzqItDgS*$3O z)*Z#E-t#ESdmm!L3RkL`px#*C+(8(2~Kb^4>&b@dQODjGA6mI^#RL2E?f%?p3W z42umplXF=a9e=T{MPYLZFer^=mB-TNz~yTK27Ih2Xv|dg{2MvrZ5*kTb)CaAKU%`k z=y^Kpaq$E_N*a%{qHuqbRUGxW*juXzjA}-_;9l|}E#Y<+6q>I$iWN+UX-QLA89j-K z$>JD;%e_|>fk`n*I?(D;zX5>nSVAN~J#6ZX|pJNSi^7#itI{3wM5)K6h<+ILU zkk2bn~h;fLT4ibDXC5+*7!{&~YI1U<@`t-t zps=X~V$NV?bgcho8*Jt&NKQ&+Md7IXG)($IR)#XH8HqPeY!(+!rR|j;%klPe`SQ&q6Qkh)(H%JlmdO7% zwO^H2YTIW&m*bI$xK(-4`4--*E5L>+YjCi=939k;G~F0{z3@}c7@qge?7+tQ-SXDv zjmazV`)@x$wmB1*o-DrU{nZlDjD%hE^V&;WkrbNWU8Ki$k3BNNq(#6v|Z;RnY@1i z$Y}gNw@vJ!dKZ?7#ZB4NMIu7c6i#0|gH!!AV$T#rUvNOYHC|W@W>^m|=fzcJ+2QAL zE!YijK;#9y@**oOyw6t*o%n_$YGvkqwhY~dAhOJ 14, dash}, + lineMax: {label: "blockSpeedMax", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#38C3FF', calc:(v) => 23, dash}, } const pressureGroup = { @@ -60,7 +66,7 @@ const axialLoadGroup = { } const hookWeightGroup = { - label: "Ввес на крюке", + label: "Вес на крюке", yDisplay: false, linePv: {label: "hookWeight", units: 'т', xAccessorName: "hookWeight", yAccessorName: "date", color: '#0aa'}, lineIdle: { @@ -114,7 +120,7 @@ const rotorTorqueGroup = { const paramsGroups = [blockHeightGroup, blockSpeedGroup, pressureGroup, axialLoadGroup, hookWeightGroup, rotorTorqueGroup] -export const Column = ({lineGroup, data, interval}) => { +export const Column = ({lineGroup, data, interval, showBorder}) => { let lines = [lineGroup.linePv] if (lineGroup.lineSp) @@ -123,6 +129,12 @@ export const Column = ({lineGroup, data, interval}) => { if (lineGroup.lineOther) lines.push(lineGroup.lineOther) + if (lineGroup.lineAvg) + lines.push(lineGroup.lineAvg) + + if (lineGroup.lineMax) + lines.push(lineGroup.lineMax) + let dataLast = null let pv = null if (data?.length > 0) { @@ -133,10 +145,12 @@ export const Column = ({lineGroup, data, interval}) => { return ( <> - +
+ +
{ // Словарь категорий для строк таблицы const categoryDictionary = { - 1: {title: 'Авария'}, + 1: {title: 'Важное'}, 2: {title: 'Предупреждение'}, 3: {title: 'Информация'}, } @@ -183,13 +197,26 @@ const columns = [ }, ]; +const intervalSteps = [ + {label: '10 минут', value: 600}, + {label: '30 минут', value: 1800}, + {label: '1 час', value: 3600}, + {label: '6 часов', value: 21600}, + {label: '12 часов', value: 43200}, + {label: '1 день', value: 86400}, +] + +const defaultInterval = intervalSteps[0]["value"] // поменять тут TODO + export default function TelemetryView(props) { let {id} = useParams() const [saubData, setSaubData] = useState([]) - const [chartInterval, setChartInterval] = useState(600) + const [chartInterval, setChartInterval] = useState(defaultInterval) const [messages, setMessages] = useState([]) - const [loader, setLoader] = useState(false) // , setLoader + const [loader, setLoader] = useState(false) + + const periods = intervalSteps.map((line) => ) const handleReceiveDataSaub = (data) => { if (data) { @@ -247,28 +274,27 @@ export default function TelemetryView(props) {   Интервал:  - + {periods}   + + +

MSE

- + - + - {paramsGroups.map(group => + {paramsGroups.map((group, index) => - + )} diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 9371e5f..fae9c9d 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -12,6 +12,7 @@ export type { DataSaubBaseDto } from './models/DataSaubBaseDto'; export type { DatesRangeDto } from './models/DatesRangeDto'; export type { DepositDto } from './models/DepositDto'; export type { EventDto } from './models/EventDto'; +export type { FilePropertiesDto } from './models/FilePropertiesDto'; export type { MessageDto } from './models/MessageDto'; export type { MessageDtoPaginationContainer } from './models/MessageDtoPaginationContainer'; export type { OperationDto } from './models/OperationDto'; @@ -32,6 +33,7 @@ export { AuthService } from './services/AuthService'; export { ClusterService } from './services/ClusterService'; export { DataService } from './services/DataService'; export { DepositService } from './services/DepositService'; +export { FileService } from './services/FileService'; export { MessageService } from './services/MessageService'; export { ReportService } from './services/ReportService'; export { TelemetryService } from './services/TelemetryService'; diff --git a/src/services/api/models/ClusterDto.ts b/src/services/api/models/ClusterDto.ts index 82b801d..ec20834 100644 --- a/src/services/api/models/ClusterDto.ts +++ b/src/services/api/models/ClusterDto.ts @@ -2,10 +2,13 @@ /* tslint:disable */ /* eslint-disable */ +import type { WellDto } from './WellDto'; + export type ClusterDto = { id?: number; caption?: string | null; description?: string | null; latitude?: number | null; longitude?: number | null; + wells?: Array | null; } \ No newline at end of file diff --git a/src/services/api/models/ClusterStatDto.ts b/src/services/api/models/ClusterStatDto.ts index dc711bb..911a264 100644 --- a/src/services/api/models/ClusterStatDto.ts +++ b/src/services/api/models/ClusterStatDto.ts @@ -2,6 +2,7 @@ /* tslint:disable */ /* eslint-disable */ +import type { WellDto } from './WellDto'; import type { WellStatDto } from './WellStatDto'; export type ClusterStatDto = { @@ -10,5 +11,6 @@ export type ClusterStatDto = { description?: string | null; latitude?: number | null; longitude?: number | null; + wells?: Array | null; wellsStat?: Array | null; } \ No newline at end of file diff --git a/src/services/api/models/DepositDto.ts b/src/services/api/models/DepositDto.ts index 0cbaeec..c142448 100644 --- a/src/services/api/models/DepositDto.ts +++ b/src/services/api/models/DepositDto.ts @@ -2,10 +2,13 @@ /* tslint:disable */ /* eslint-disable */ +import type { ClusterDto } from './ClusterDto'; + export type DepositDto = { id?: number; - name?: string | null; + caption?: string | null; description?: string | null; latitude?: number | null; longitude?: number | null; + clusters?: Array | null; } \ No newline at end of file diff --git a/src/services/api/models/FilePropertiesDto.ts b/src/services/api/models/FilePropertiesDto.ts new file mode 100644 index 0000000..59ed185 --- /dev/null +++ b/src/services/api/models/FilePropertiesDto.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type FilePropertiesDto = { + id?: number; + name?: string | null; + idCategory?: number; + uploadDate?: string; + userName?: string | null; +} \ No newline at end of file diff --git a/src/services/api/models/WellDto.ts b/src/services/api/models/WellDto.ts index e33d86b..d681ec5 100644 --- a/src/services/api/models/WellDto.ts +++ b/src/services/api/models/WellDto.ts @@ -7,7 +7,6 @@ export type WellDto = { cluster?: string | null; deposit?: string | null; id?: number; - lastData?: any; latitude?: number | null; longitude?: number | null; wellType?: string | null; diff --git a/src/services/api/models/WellStatDto.ts b/src/services/api/models/WellStatDto.ts index 18176e6..7293b43 100644 --- a/src/services/api/models/WellStatDto.ts +++ b/src/services/api/models/WellStatDto.ts @@ -10,7 +10,6 @@ export type WellStatDto = { cluster?: string | null; deposit?: string | null; id?: number; - lastData?: any; latitude?: number | null; longitude?: number | null; wellType?: string | null; diff --git a/src/services/api/services/AnalyticsService.ts b/src/services/api/services/AnalyticsService.ts index a3913d0..8c52822 100644 --- a/src/services/api/services/AnalyticsService.ts +++ b/src/services/api/services/AnalyticsService.ts @@ -14,9 +14,9 @@ export class AnalyticsService { * @param wellId id скважины * @param skip для пагинации кол-во записей пропустить * @param take для пагинации кол-во записей - * @param categoryids - * @param begin - * @param end + * @param categoryIds список категорий + * @param begin дата начала + * @param end окончание * @returns OperationDtoPaginationContainer Success * @throws ApiError */ @@ -24,7 +24,7 @@ export class AnalyticsService { wellId: number, skip: number, take: number = 32, -categoryids?: Array, +categoryIds?: Array, begin?: string, end?: string, ): Promise { @@ -34,7 +34,7 @@ end?: string, query: { 'skip': skip, 'take': take, - 'categoryids': categoryids, + 'categoryIds': categoryIds, 'begin': begin, 'end': end, }, diff --git a/src/services/api/services/FileService.ts b/src/services/api/services/FileService.ts new file mode 100644 index 0000000..bcfade8 --- /dev/null +++ b/src/services/api/services/FileService.ts @@ -0,0 +1,80 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { FilePropertiesDto } from '../models/FilePropertiesDto'; +import { request as __request } from '../core/request'; + +export class FileService { + + /** + * Сохраняет переданные файлы и информацию о них + * @param wellId id скважины + * @param idCategory id категории файла + * @param idUser id отправившего файл пользователя + * @param requestBody + * @returns number Success + * @throws ApiError + */ + public static async saveFiles( +wellId: number, +idCategory?: number, +idUser?: number, +requestBody?: any, +): Promise { + const result = await __request({ + method: 'POST', + path: `/api/files/${wellId}/files`, + query: { + 'idCategory': idCategory, + 'idUser': idUser, + }, + body: requestBody, + }); + return result.body; + } + + /** + * Возвращает информацию о файлах для скважины в выбраной категории + * @param wellId id скважины + * @param idCategory id категории файла + * @returns FilePropertiesDto Success + * @throws ApiError + */ + public static async getFilesInfo( +wellId: number, +idCategory?: number, +): Promise> { + const result = await __request({ + method: 'GET', + path: `/api/files/${wellId}/filesInfo`, + query: { + 'idCategory': idCategory, + }, + }); + return result.body; + } + + /** + * Возвращает файл с диска на сервере + * @param wellId id скважины + * @param fileName + * @param fileId id запрашиваемого файла + * @returns string Success + * @throws ApiError + */ + public static async getFile( +wellId: number, +fileName: string, +fileId?: number, +): Promise { + const result = await __request({ + method: 'GET', + path: `/api/files/${wellId}/${fileName}`, + query: { + 'fileId': fileId, + }, + }); + return result.body; + } + +} \ No newline at end of file From a56ca1671a4b31d9e1112b8c8d1f3686efdc6e89 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jul 2021 17:39:40 +0500 Subject: [PATCH 17/32] =?UTF-8?q?=D0=9E=D1=82=D0=BC=D0=B5=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=D0=B4=D0=BD=D0=B8?= =?UTF-8?q?=D1=85=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=BD=D1=8B?= =?UTF-8?q?=D1=85=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/CustomColumn.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/CustomColumn.jsx b/src/components/CustomColumn.jsx index 02aa7e5..5d23414 100644 --- a/src/components/CustomColumn.jsx +++ b/src/components/CustomColumn.jsx @@ -10,6 +10,7 @@ export const CustomColumn = ({data}) => { {label:'Забой, м', accessorName:'wellDepth'}, {label:'Расход, м³/ч', accessorName:'flow'}, {label:'Расход х.х., м³/ч', accessorName:'flowIdle'}, + {label: 'Отметка времени данных', accessorName: 'date'}, ] if(dataLast) From fba38ed02315be481967df9d1fd2ad7d50b42066 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 26 Jul 2021 09:44:54 +0500 Subject: [PATCH 18/32] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BA?= =?UTF-8?q?=D0=B0=D1=80=D1=82=D0=B8=D0=BD=D0=BA=D0=B8=20=D0=B8=20=D0=B7?= =?UTF-8?q?=D0=B0=D1=85=D0=B0=D1=80=D0=B4=D0=BA=D0=BE=D0=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/TelemetryView.jsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/pages/TelemetryView.jsx b/src/pages/TelemetryView.jsx index 9273b09..f4a4761 100644 --- a/src/pages/TelemetryView.jsx +++ b/src/pages/TelemetryView.jsx @@ -8,10 +8,6 @@ import {CustomColumn} from '../components/CustomColumn' import {UserOfWells} from '../components/UserOfWells' import {ModeDisplay} from '../components/ModeDisplay' import {Display} from '../components/Display' -import SpinPicEnabled from "../images/SpinEnabled.png" -import SpinPicDisabled from "../images/SpinDisabled.png" -import MomentStabPicEnabled from "../images/DempherOn.png" -import MomentStabPicDisabled from "../images/DempherOff.png" import moment from 'moment' import {Subscribe} from '../services/signalr' import {DataService, MessageService} from '../services/api' @@ -34,8 +30,6 @@ const blockSpeedGroup = { yDisplay: false, linePv: {label: "blockSpeed", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#0a0'}, lineSp: {label: "blockSpeedSp", units: 'м/ч', xAccessorName: "blockSpeedSp", yAccessorName: "date", color: '#0a0'}, - lineAvg: {label: "blockSpeedAvg", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#38C3FF', calc:(v) => 14, dash}, - lineMax: {label: "blockSpeedMax", units: 'м/ч', xAccessorName: "blockSpeed", yAccessorName: "date", color: '#38C3FF', calc:(v) => 23, dash}, } const pressureGroup = { @@ -279,9 +273,6 @@ export default function TelemetryView(props) {   - - -

MSE

From 4638e46a9379db64d57d4beee78ec75c78b4df5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 26 Jul 2021 10:16:20 +0500 Subject: [PATCH 19/32] nit fix warnings and client update --- src/components/RigMnemo.jsx | 4 ++-- src/components/WellTreeSelector.jsx | 2 +- src/pages/Deposit.jsx | 2 +- src/pages/Report.jsx | 6 +++--- src/pages/WellAnalysis.jsx | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/RigMnemo.jsx b/src/components/RigMnemo.jsx index 3a9a58f..0d7c18e 100644 --- a/src/components/RigMnemo.jsx +++ b/src/components/RigMnemo.jsx @@ -57,8 +57,8 @@ export default function RigMnemo({ blockPositionLocal = blockPositionLocal ? blockPositionLocal : 0 const blockTranslate = `translate(-75, ${-35 + (50 * (30 - blockPositionLocal) / 30)})` - let bitPositionLocal = +bitPosition - bitPositionLocal = bitPositionLocal ? bitPositionLocal : 0 + //let bitPositionLocal = +bitPosition + //bitPositionLocal = bitPositionLocal ? bitPositionLocal : 0 //const bitTranslate = `translate(0, ${-41 + 41 * (3426 - bitPosition)/(3426 - 3200)})` const bitTranslate = `translate(0, 0)` diff --git a/src/components/WellTreeSelector.jsx b/src/components/WellTreeSelector.jsx index fde7017..26ade5c 100644 --- a/src/components/WellTreeSelector.jsx +++ b/src/components/WellTreeSelector.jsx @@ -6,7 +6,7 @@ import { TreeSelect } from 'antd' import { useHistory } from 'react-router-dom' import notify from './notify' -export default function WellTreeSelector({}) { +export default function WellTreeSelector() { const [wellsTree, setWellsTree] = useState([]) const [showLoader, setShowLoader] = useState(false) const history = useHistory() diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx index 038ad3c..249802a 100644 --- a/src/pages/Deposit.jsx +++ b/src/pages/Deposit.jsx @@ -7,7 +7,7 @@ import {ClusterService} from '../services/api' import notify from '../components/notify' const calcViewParams = (clusters) => { - if (clusters.length === 0) + if (clusters && clusters.length === 0) return {center:[60.81226, 70.0562], zoom: 5} const center = clusters.reduce((sum, cluster) => { diff --git a/src/pages/Report.jsx b/src/pages/Report.jsx index c7574d3..aa7c23e 100644 --- a/src/pages/Report.jsx +++ b/src/pages/Report.jsx @@ -67,7 +67,7 @@ export default function Report(props) { title: 'Название отчета', dataIndex: 'reportName', key: 'reportName', - render: name => getReportFile(event, name)} download={name}>{name} + render: name => }, ]; @@ -80,10 +80,10 @@ export default function Report(props) {
{ progressData.operation }
- {getReportFile(event, progressData.reportName)}} + ) } diff --git a/src/pages/WellAnalysis.jsx b/src/pages/WellAnalysis.jsx index f0f5b6f..f83d8b7 100644 --- a/src/pages/WellAnalysis.jsx +++ b/src/pages/WellAnalysis.jsx @@ -118,7 +118,7 @@ export default function WellAnalysis() { setLoader(false) } GetOperations() - }, [id, categories, range]) + }, [id, categories, range, page]) return(<>
From 87a7faa17f60bb9c9fd9e0ee5f84e189a9fae39e Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Mon, 26 Jul 2021 11:12:20 +0500 Subject: [PATCH 20/32] =?UTF-8?q?CF2-33:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BD=D0=BE=D0=B2=D0=BE=D0=B9=20=D0=B2?= =?UTF-8?q?=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8=20'=D0=94=D0=BE=D0=BA?= =?UTF-8?q?=D1=83=D0=BC=D0=B5=D0=BD=D1=8B'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Documents.jsx | 101 +++++++++++++---------- src/pages/Cementing.jsx | 4 +- src/pages/DocumentForWell.jsx | 4 +- src/pages/FluidService.jsx | 4 +- src/pages/Gti.jsx | 4 +- src/pages/Login.jsx | 1 + src/pages/Master.jsx | 4 +- src/pages/Nnb.jsx | 4 +- src/pages/Supervisor.jsx | 4 +- src/pages/Well.jsx | 14 ++-- src/services/api/index.ts | 3 + src/services/api/services/FileService.ts | 92 +++++++++++++++++++++ 12 files changed, 174 insertions(+), 65 deletions(-) create mode 100644 src/services/api/services/FileService.ts diff --git a/src/components/Documents.jsx b/src/components/Documents.jsx index db405b0..c758f90 100644 --- a/src/components/Documents.jsx +++ b/src/components/Documents.jsx @@ -1,11 +1,12 @@ -import {Table, DatePicker, Form, Button, Upload, ConfigProvider} from 'antd'; -import { UploadOutlined } from '@ant-design/icons'; -import MenuDocuments from "./MenuDocuments"; -import {useState, useEffect} from "react"; +import {Table, DatePicker, Form, Button, Upload, ConfigProvider} from 'antd' +import { UploadOutlined } from '@ant-design/icons' +import MenuDocuments from "./MenuDocuments" +import { FileService } from '../services/api' +import {useState, useEffect} from "react" import {useParams} from 'react-router-dom' import notify from './notify' import LoaderPortal from './LoaderPortal' -import locale from "antd/lib/locale/ru_RU"; +import locale from "antd/lib/locale/ru_RU" import moment from 'moment' const pageSize = 26 @@ -25,26 +26,26 @@ const columns = [ }, { title: 'Ф.И.О.', - key: 'name', - dataIndex: 'name', + key: 'userName', + dataIndex: 'userName', } ]; -export default function Documents() { +export default function Documents({selectedFileCategory}) { let {id} = useParams() const [page, setPage] = useState(1) const [range, setRange] = useState([]) const [pagination, setPagination] = useState(null) const [files, setFiles] = useState([]) + const [selectedFiles, setSelectedFiles] = useState([]) const [loader, setLoader] = useState(false) const submitFileFormProps = { - //action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', onChange({ file, fileList }) { if (file.status !== 'uploading') { - console.log(file, fileList); + setSelectedFiles(fileList) } } } @@ -54,15 +55,33 @@ export default function Documents() { } const onFinish = (values) => { - console.log('Success:', values); + var fileList = values.fileInput.fileList + + if (fileList.length > 0) + { + const formData = new FormData(); + + fileList.forEach(val => { + formData.append('files', val.originFileObj) + }) + + fetch(`/api/files/${id}/files?idCategory=${selectedFileCategory}&idUser=${localStorage['userId']}`, { + headers: { + Authorization: 'Bearer ' + localStorage['token'] + }, + method: 'POST', + body: formData + }) + .then(async (response) => { + // refresh component to upload new files в зависимоть useEffect какую-то переменную, чтоб дергался снова запрос на всю инфу о файлах + }); + } } const onFinishFailed = (errorInfo) => { - console.log('Failed:', errorInfo); + notify(`Не удалось отправить файлы по скважине "${id}".`, 'error') } - const fileList = [] - useEffect(() => { const GetDocuments = async () => { setLoader(true) @@ -74,26 +93,29 @@ export default function Documents() { begin = range[0].toISOString() end = range[1].toISOString() } - // await AnalyticsService.getOperationsByWell( - // `${id}`, - // (page-1) * pageSize, - // pageSize, - // begin, - // end).then((paginatedFiles) => { - // setFiles(paginatedFiles?.items.map(f => { - // return { - // key: f.id, - // begin: f.date, - // ...f - // } - // })) + console.log(id) + await FileService.getFilesInfo( + `${id}`, + (page - 1) * pageSize, + pageSize, + selectedFileCategory, + begin, + end + ).then((paginatedFiles) => { + setFiles(paginatedFiles?.items.map(f => { + return { + key: f.id, + begin: f.date, + ...f + } + })) - // setPagination({ - // total: paginatedFiles?.count, - // current: Math.floor(paginatedFiles?.skip / pageSize), - // }) - // } - //) + setPagination({ + total: paginatedFiles?.count, + current: Math.floor(paginatedFiles?.skip / pageSize), + }) + } + ) } catch (ex) { notify(`Не удалось загрузить файлы по скважине "${id}"`, 'error') console.log(ex) @@ -101,7 +123,7 @@ export default function Documents() { setLoader(false) } GetDocuments() - }, [id, range]) + }, [id, selectedFileCategory, range]) return (
@@ -127,15 +149,6 @@ export default function Documents() { name="fileInput" rules={[{ required: true, message: 'Выберите файл' }]} > - {/* { - setFile(e.target.value) - files.push(e.target.value) - localStorage.setItem(e.target.value, file) - setFiles(files) - console.log(e.target.value) - } - }/> */} @@ -144,7 +157,7 @@ export default function Documents() { - -
- + +
 
{ + setSelectedItem({ current: e.key }); + }; + return( <> }> Растворный сервис diff --git a/src/pages/Cementing.jsx b/src/pages/Cementing.jsx index 72c3f99..2f08b27 100644 --- a/src/pages/Cementing.jsx +++ b/src/pages/Cementing.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function Cementing(id) { +export default function Cementing({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/DocumentForWell.jsx b/src/pages/DocumentForWell.jsx index bab1b6a..62255c3 100644 --- a/src/pages/DocumentForWell.jsx +++ b/src/pages/DocumentForWell.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function DocumentsForWell(id) { +export default function DocumentsForWell({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/FluidService.jsx b/src/pages/FluidService.jsx index 4f2135c..2022289 100644 --- a/src/pages/FluidService.jsx +++ b/src/pages/FluidService.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function FluidService(id) { +export default function FluidService({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/Gti.jsx b/src/pages/Gti.jsx index a822c5f..c51aa47 100644 --- a/src/pages/Gti.jsx +++ b/src/pages/Gti.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function Gti(id) { +export default function Gti({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/Master.jsx b/src/pages/Master.jsx index 9ec37c7..6c15e0c 100644 --- a/src/pages/Master.jsx +++ b/src/pages/Master.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function Master(id) { +export default function Master({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/Nnb.jsx b/src/pages/Nnb.jsx index c3b674c..c5d1227 100644 --- a/src/pages/Nnb.jsx +++ b/src/pages/Nnb.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function Nnb(id) { +export default function Nnb({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/Supervisor.jsx b/src/pages/Supervisor.jsx index 5a670a4..52bf0b8 100644 --- a/src/pages/Supervisor.jsx +++ b/src/pages/Supervisor.jsx @@ -1,8 +1,8 @@ import Documents from "../components/Documents" -export default function Supervisor(id) { +export default function Supervisor({selectedFileCategory}) { return( - + ) } \ No newline at end of file diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index df55594..293b95f 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -113,22 +113,22 @@ export default function Well() { - + - + - + - + - + - + diff --git a/src/services/api/services/FileService.ts b/src/services/api/services/FileService.ts index 5ba7110..8200338 100644 --- a/src/services/api/services/FileService.ts +++ b/src/services/api/services/FileService.ts @@ -69,22 +69,17 @@ end?: string, /** * Возвращает файл с диска на сервере * @param wellId id скважины - * @param fileName * @param fileId id запрашиваемого файла * @returns string Success * @throws ApiError */ public static async getFile( wellId: number, -fileName: string, -fileId?: number, +fileId: number, ): Promise { const result = await __request({ method: 'GET', - path: `/api/files/${wellId}/${fileName}`, - query: { - 'fileId': fileId, - }, + path: `/api/files/${wellId}/${fileId}`, }); return result.body; } From b6bfce38de21e013643d337307d3a87c8c18ce5b Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Mon, 26 Jul 2021 16:07:05 +0500 Subject: [PATCH 25/32] =?UTF-8?q?CF2-33:=20=D0=9F=D1=83=D1=81=D1=82=D1=8B?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BF=D0=BE=D0=BD=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D1=8B,=20=D0=B2=D1=8B=D0=B7=D1=8B=D0=B2=D0=B0=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D0=B5=20Documents,=20=D0=B7=D0=B0=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D1=81=D1=80=D0=B0=D0=B7=D1=83=20=D0=BD?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D0=B7=D0=BE=D0=B2=20Documents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Documents.jsx | 2 +- src/pages/Cementing.jsx | 8 -------- src/pages/DocumentForWell.jsx | 8 -------- src/pages/Gti.jsx | 8 -------- src/pages/Master.jsx | 8 -------- src/pages/Nnb.jsx | 8 -------- src/pages/Supervisor.jsx | 8 -------- src/pages/Well.jsx | 24 +++++++++--------------- 8 files changed, 10 insertions(+), 64 deletions(-) delete mode 100644 src/pages/Cementing.jsx delete mode 100644 src/pages/DocumentForWell.jsx delete mode 100644 src/pages/Gti.jsx delete mode 100644 src/pages/Master.jsx delete mode 100644 src/pages/Nnb.jsx delete mode 100644 src/pages/Supervisor.jsx diff --git a/src/components/Documents.jsx b/src/components/Documents.jsx index e3bbda3..b7cb274 100644 --- a/src/components/Documents.jsx +++ b/src/components/Documents.jsx @@ -171,7 +171,7 @@ export default function Documents({selectedFileCategory}) { } } GetDocuments() - }, [id, range, selectedFileCategory, isTableUpdating]) + }, [id, range,page, selectedFileCategory, isTableUpdating]) return (
diff --git a/src/pages/Cementing.jsx b/src/pages/Cementing.jsx deleted file mode 100644 index 2f08b27..0000000 --- a/src/pages/Cementing.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function Cementing({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/DocumentForWell.jsx b/src/pages/DocumentForWell.jsx deleted file mode 100644 index 62255c3..0000000 --- a/src/pages/DocumentForWell.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function DocumentsForWell({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/Gti.jsx b/src/pages/Gti.jsx deleted file mode 100644 index c51aa47..0000000 --- a/src/pages/Gti.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function Gti({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/Master.jsx b/src/pages/Master.jsx deleted file mode 100644 index 6c15e0c..0000000 --- a/src/pages/Master.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function Master({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/Nnb.jsx b/src/pages/Nnb.jsx deleted file mode 100644 index c5d1227..0000000 --- a/src/pages/Nnb.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function Nnb({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/Supervisor.jsx b/src/pages/Supervisor.jsx deleted file mode 100644 index 52bf0b8..0000000 --- a/src/pages/Supervisor.jsx +++ /dev/null @@ -1,8 +0,0 @@ -import Documents from "../components/Documents" - -export default function Supervisor({selectedFileCategory}) { - - return( - - ) -} \ No newline at end of file diff --git a/src/pages/Well.jsx b/src/pages/Well.jsx index 293b95f..3845f4d 100644 --- a/src/pages/Well.jsx +++ b/src/pages/Well.jsx @@ -7,13 +7,7 @@ import Messages from "../pages/Messages"; import Report from "../pages/Report"; import Analysis from "../pages/Analysis"; import WellAnalysis from "../pages/WellAnalysis"; -import FluidService from "../components/Documents"; -import Cementing from "../pages/Cementing"; -import Nnb from "../pages/Nnb"; -import Gti from "../pages/Gti"; -import DocumentForWell from "../pages/DocumentForWell"; -import Supervisor from "../pages/Supervisor"; -import Master from "../pages/Master"; +import Documents from "../components/Documents"; import LastData from '../pages/LastData' import TelemetryView from "../pages/TelemetryView"; @@ -110,31 +104,31 @@ export default function Well() { - + - + - + - + - + - + - + - + From 90801ff31b5c8218e735b748840262480c254c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 26 Jul 2021 16:54:48 +0500 Subject: [PATCH 26/32] websocket development config --- src/services/signalr/index.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts index 91d7082..449cd65 100644 --- a/src/services/signalr/index.ts +++ b/src/services/signalr/index.ts @@ -12,14 +12,19 @@ type ConnectionsDict = { [route: string]: HubConnection; }; +//var baseUrl = `http://192.168.1.70:5000` +var baseUrl = process.env.NODE_ENV === 'development' + ?'http://192.168.1.70:5000' + :'' + const Connections: ConnectionsDict = { 'hubs/telemetry': new HubConnectionBuilder() - .withUrl(`http://192.168.1.70:5000/hubs/telemetry`, ConnectionOptions)// + .withUrl(`${baseUrl}/hubs/telemetry`, ConnectionOptions)// .withAutomaticReconnect() .build(), 'hubs/reports': new HubConnectionBuilder() - .withUrl(`http://192.168.1.70:5000/hubs/reports`, ConnectionOptions) + .withUrl(`${baseUrl}/hubs/reports`, ConnectionOptions) .withAutomaticReconnect() .build() } From 899698223e909c059d132b0f9db6e40a6760012b Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Mon, 26 Jul 2021 17:29:38 +0500 Subject: [PATCH 27/32] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BF=D1=83?= =?UTF-8?q?=D1=82=D0=B8=20=D0=B4=D0=BE=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=D0=B5=D1=80=D0=B0=20=D1=84=D0=B0=D0=B9=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/services/api/services/FileService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/api/services/FileService.ts b/src/services/api/services/FileService.ts index 8200338..187193b 100644 --- a/src/services/api/services/FileService.ts +++ b/src/services/api/services/FileService.ts @@ -54,7 +54,7 @@ end?: string, ): Promise { const result = await __request({ method: 'GET', - path: `/api/files/${wellId}/filesInfo`, + path: `/api/files/${wellId}`, query: { 'skip': skip, 'take': take, From f34aee8adade4e83820369e671a36ca90a99c3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Mon, 26 Jul 2021 17:42:10 +0500 Subject: [PATCH 28/32] api client update --- src/services/api/services/DataService.ts | 2 +- src/services/api/services/FileService.ts | 4 ++-- src/services/api/services/ReportService.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/services/api/services/DataService.ts b/src/services/api/services/DataService.ts index fa8fc17..38d648a 100644 --- a/src/services/api/services/DataService.ts +++ b/src/services/api/services/DataService.ts @@ -13,7 +13,7 @@ export class DataService { * @param wellId id скважины * @param begin дата начала выборки. По умолчанию: текущее время - intervalSec * @param intervalSec интервал времени даты начала выборки, секунды - * @param approxPointsCount желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. + * @param approxPointsCount жела��мое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. * @returns DataSaubBaseDto Success * @throws ApiError */ diff --git a/src/services/api/services/FileService.ts b/src/services/api/services/FileService.ts index 8200338..60af0b4 100644 --- a/src/services/api/services/FileService.ts +++ b/src/services/api/services/FileService.ts @@ -34,7 +34,7 @@ requestBody?: any, } /** - * Возвращает информацию о файлах для скважины в выбраной категории + * Возвращает информацию о файлах для сква��ины в выбраной категории * @param wellId id скважины * @param skip для пагинации кол-во записей пропустить * @param take для пагинации кол-во записей взять @@ -54,7 +54,7 @@ end?: string, ): Promise { const result = await __request({ method: 'GET', - path: `/api/files/${wellId}/filesInfo`, + path: `/api/files/${wellId}`, query: { 'skip': skip, 'take': take, diff --git a/src/services/api/services/ReportService.ts b/src/services/api/services/ReportService.ts index e63a83e..e02c282 100644 --- a/src/services/api/services/ReportService.ts +++ b/src/services/api/services/ReportService.ts @@ -116,7 +116,7 @@ end?: string, } /** - * Возвращает даты самого старого и самого свежего отчетов в БД + * Возвра��ает даты самого старого и самого свежего отчетов в БД * @param wellId id скважины * @returns DatesRangeDto Success * @throws ApiError From 4fc4dd5995514dad5d96e0b1be05fcd541649162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 27 Jul 2021 10:18:33 +0500 Subject: [PATCH 29/32] remove unused packadges --- package-lock.json | 94 +++----------------------------------------- package.json | 5 +-- src/___setupProxy_js | 20 ---------- 3 files changed, 7 insertions(+), 112 deletions(-) delete mode 100644 src/___setupProxy_js diff --git a/package-lock.json b/package-lock.json index e8fc82f..0f273be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1329,15 +1329,6 @@ "@hapi/hoek": "^8.3.0" } }, - "@hypnosphi/create-react-context": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@hypnosphi/create-react-context/-/create-react-context-0.3.1.tgz", - "integrity": "sha512-V1klUed202XahrWJLLOT3EXNeCpFHCcJntdFGI15ntCwau+jfT386w7OFTMaCqOgXUH1fa0w/I1oZs+i/Rfr0A==", - "requires": { - "gud": "^1.0.0", - "warning": "^4.0.3" - } - }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1895,9 +1886,9 @@ }, "dependencies": { "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "requires": { "async-limiter": "~1.0.0" } @@ -2379,14 +2370,6 @@ "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==" }, - "@types/http-proxy": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.7.tgz", - "integrity": "sha512-9hdj6iXH64tHSLTY+Vt2eYOGzSogC+JQ2H7bdPWkuh7KXP5qLllWx++t+K9Wk556c3dkDdPws/SpMRi0sdCT1w==", - "requires": { - "@types/node": "*" - } - }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -7353,11 +7336,6 @@ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", "optional": true }, - "gud": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", - "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" - }, "gzip-size": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", @@ -7751,25 +7729,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-middleware": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.1.tgz", - "integrity": "sha512-cfaXRVoZxSed/BmkA7SwBVNI9Kj7HFltaE5rqYOub5kWzWZ+gofV2koVN1j2rMW7pEfSSlCHGJ31xmuyFyfLOg==", - "requires": { - "@types/http-proxy": "^1.17.5", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "dependencies": { - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - } - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -11690,11 +11649,6 @@ "ts-pnp": "^1.1.6" } }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" - }, "portfinder": { "version": "1.0.28", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", @@ -13401,18 +13355,6 @@ "whatwg-fetch": "^3.4.1" } }, - "react-datepicker": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-3.8.0.tgz", - "integrity": "sha512-iFVNEp8DJoX5yEvEiciM7sJKmLGrvE70U38KhpG13XrulNSijeHw1RZkhd/0UmuXR71dcZB/kdfjiidifstZjw==", - "requires": { - "classnames": "^2.2.6", - "date-fns": "^2.0.1", - "prop-types": "^15.7.2", - "react-onclickoutside": "^6.10.0", - "react-popper": "^1.3.8" - } - }, "react-dev-utils": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.4.tgz", @@ -13539,25 +13481,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, - "react-onclickoutside": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/react-onclickoutside/-/react-onclickoutside-6.10.0.tgz", - "integrity": "sha512-7i2L3ef+0ILXpL6P+Hg304eCQswh4jl3ynwR71BSlMU49PE2uk31k8B2GkP6yE9s2D4jTGKnzuSpzWxu4YxfQQ==" - }, - "react-popper": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.11.tgz", - "integrity": "sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==", - "requires": { - "@babel/runtime": "^7.1.2", - "@hypnosphi/create-react-context": "^0.3.1", - "deep-equal": "^1.1.1", - "popper.js": "^1.14.4", - "prop-types": "^15.6.1", - "typed-styles": "^0.0.7", - "warning": "^4.0.2" - } - }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", @@ -15910,11 +15833,6 @@ "mime-types": "~2.1.24" } }, - "typed-styles": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", - "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" - }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -17263,9 +17181,9 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "requires": { "async-limiter": "~1.0.0" } diff --git a/package.json b/package.json index c042595..3514b06 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,9 @@ "chartjs-adapter-moment": "^1.0.0", "chartjs-plugin-datalabels": "^2.0.0-rc.1", "craco-less": "^1.17.1", - "date-fns": "^2.20.0", - "http-proxy-middleware": "^2.0.1", "moment": "^2.29.1", "pigeon-maps": "^0.19.7", "react": "^17.0.2", - "react-datepicker": "^3.8.0", "react-dom": "^17.0.2", "react-router-dom": "^5.2.0", "react-scripts": "4.0.3", @@ -34,7 +31,7 @@ "react_test": "react-scripts test", "eject": "react-scripts eject" }, - "proxy":"http://192.168.1.70:5000", + "proxy": "http://192.168.1.70:5000", "eslintConfig": { "extends": [ "react-app", diff --git a/src/___setupProxy_js b/src/___setupProxy_js deleted file mode 100644 index 18b7b0e..0000000 --- a/src/___setupProxy_js +++ /dev/null @@ -1,20 +0,0 @@ -// const { createProxyMiddleware } = require('http-proxy-middleware'); - -// module.exports = function(app) { -// app.use( -// '/api', -// createProxyMiddleware({ -// target: 'http://192.168.1.70:5000', -// changeOrigin: true, -// ws:true, -// }) -// ); -// app.use( -// '/hubs', -// createProxyMiddleware({ -// target: 'http://192.168.1.70:5000', -// changeOrigin: true, -// ws:true, -// }) -// ); -// }; \ No newline at end of file From 79127d3beb8d6f5b0d25e07b4a327cb37ef35727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 27 Jul 2021 10:20:53 +0500 Subject: [PATCH 30/32] Deposit page zoom bugfix --- src/pages/Deposit.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Deposit.jsx b/src/pages/Deposit.jsx index 9988fc6..26818fb 100644 --- a/src/pages/Deposit.jsx +++ b/src/pages/Deposit.jsx @@ -7,7 +7,7 @@ import {ClusterService} from '../services/api' import notify from '../components/notify' const calcViewParams = (clusters) => { - if (clusters || clusters.length === 0) + if ((!clusters) || clusters.length === 0) return {center:[60.81226, 70.0562], zoom: 5} const center = clusters.reduce((sum, cluster) => { From 639ab50482cebfed232ad2cd5b3ed79ab6e6a263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 27 Jul 2021 10:39:03 +0500 Subject: [PATCH 31/32] update favicon manifest --- public/manifest.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/public/manifest.json b/public/manifest.json index 080d6c7..1f2f141 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -6,16 +6,6 @@ "src": "favicon.ico", "sizes": "64x64 32x32 24x24 16x16", "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" } ], "start_url": ".", From 5dc042d7be520aea5731f14de81b48682bc2565d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A4=D1=80=D0=BE=D0=BB=D0=BE=D0=B2?= Date: Tue, 27 Jul 2021 11:10:03 +0500 Subject: [PATCH 32/32] improve signalR unsubscribe --- src/services/signalr/index.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/services/signalr/index.ts b/src/services/signalr/index.ts index 449cd65..72ed2fb 100644 --- a/src/services/signalr/index.ts +++ b/src/services/signalr/index.ts @@ -48,6 +48,21 @@ type handlerFunction = (...args: any[]) => void; type cleanFunction = (...args: any[]) => void; +const MakeUnsubscribeFunction = ( + connection: HubConnection, + methodName: string, + groupName: (string|null)):cleanFunction => { + return async() => { + if(connection.state === HubConnectionState.Connected) + { + if(groupName) + await connection.send('RemoveFromGroup', groupName) + connection.off(methodName) + } + connection.stop() + } +} + /** Subscribe on some SignalR method (topic). * @example useEffect(() => Subscribe('methodName', `${id}`, handleNewData), [id]); * @param {string} methodName name of the method @@ -66,12 +81,7 @@ const Subscribe = ( connection.on(methodName, handler) }) - if(groupName) - return () => { - Connections[hubUrl].send('RemoveFromGroup', groupName) - .finally(()=>Connections[hubUrl].off(methodName)) - } - return () => Connections[hubUrl].off(methodName) + return MakeUnsubscribeFunction(Connections[hubUrl],methodName,groupName) } /** Invokes some SignalR method.