diff --git a/package.json b/package.json index c40aa61b4f..e478b5bec3 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "@monaco-editor/react": "^4.1.3", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", "@reduxjs/toolkit": "^1.8.1", - "axios": "^0.21.1", + "axios": "^0.22.0", "bfj": "^7.0.2", "browserslist": "^4.18.1", "camelcase": "^6.2.1", @@ -24,7 +24,7 @@ "final-form-arrays": "^3.0.2", "fs-extra": "^10.0.0", "identity-obj-proxy": "^3.0.0", - "iguazio.dashboard-react-controls": "1.7.1", + "iguazio.dashboard-react-controls": "1.8.0", "is-wsl": "^1.1.0", "js-base64": "^2.5.2", "js-yaml": "^3.13.1", diff --git a/src/actions/featureStore.js b/src/actions/featureStore.js index dac3e0b71d..25f45e2fb8 100644 --- a/src/actions/featureStore.js +++ b/src/actions/featureStore.js @@ -79,6 +79,7 @@ import { getFeatureVectorIdentifier } from '../utils/getUniqueIdentifier' import { parseFeatureSets } from '../utils/parseFeatureSets' +import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' const featureStoreActions = { createNewFeatureSet: (project, data) => dispatch => { @@ -180,8 +181,9 @@ const featureStoreActions = { return response.data?.feature_sets }) - .catch(err => { - dispatch(featureStoreActions.fetchFeatureSetsFailure(err.message)) + .catch(error => { + dispatch(featureStoreActions.fetchFeatureSetsFailure(error.message)) + largeResponseCatchHandler(error, 'Failed to fetch feature sets', dispatch) }) }, fetchFeatureSetsBegin: () => ({ @@ -239,7 +241,7 @@ const featureStoreActions = { type: FETCH_FEATURE_VECTOR_SUCCESS, payload: featureSets }), - fetchFeatureVectors: (project, filters, config) => dispatch => { + fetchFeatureVectors: (project, filters, config = {}, skipErrorNotification) => dispatch => { dispatch(featureStoreActions.fetchFeatureVectorsBegin()) return featureStoreApi @@ -253,8 +255,12 @@ const featureStoreActions = { return response.data.feature_vectors }) - .catch(err => { - dispatch(featureStoreActions.fetchFeatureVectorsFailure(err)) + .catch(error => { + dispatch(featureStoreActions.fetchFeatureVectorsFailure(error)) + + if (!skipErrorNotification) { + largeResponseCatchHandler(error, 'Failed to fetch feature vectors', dispatch) + } }) }, fetchFeatureVectorsBegin: () => ({ diff --git a/src/actions/functions.js b/src/actions/functions.js index e17601217c..145b4e989b 100644 --- a/src/actions/functions.js +++ b/src/actions/functions.js @@ -17,7 +17,6 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { get } from 'lodash' import functionsApi from '../api/functions-api' import yaml from 'js-yaml' import { @@ -86,7 +85,8 @@ import { } from '../constants' import { FORBIDDEN_ERROR_STATUS_CODE } from 'igz-controls/constants' import { generateCategories, generateHubCategories } from '../utils/generateTemplatesCategories' -import { setNotification } from '../reducers/notificationReducer' +import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' +import { showErrorNotification } from '../utils/notifications.util' const functionsActions = { createNewFunction: (project, data) => dispatch => { @@ -185,17 +185,8 @@ const functionsActions = { return templates }) .catch(error => { - const errorMsg = get(error, 'response.data.detail', "Function's template failed to load") - dispatch(functionsActions.fetchFunctionTemplateFailure(error)) - dispatch( - setNotification({ - status: error.response?.status || 400, - id: Math.random(), - message: errorMsg, - error - }) - ) + showErrorNotification(dispatch, error, "Function's template failed to load") }) }, fetchFunctionTemplateSuccess: selectFunction => ({ @@ -209,22 +200,21 @@ const functionsActions = { type: FETCH_FUNCTION_TEMPLATE_FAILURE, payload: err }), - fetchFunctions: - (project, filters, setLargeRequestErrorMessage) => - dispatch => { - dispatch(functionsActions.fetchFunctionsBegin()) + fetchFunctions: (project, filters, config) => dispatch => { + dispatch(functionsActions.fetchFunctionsBegin()) - return functionsApi - .getFunctions(project, filters, null, setLargeRequestErrorMessage) - .then(({ data }) => { - dispatch(functionsActions.fetchFunctionsSuccess(data.funcs)) + return functionsApi + .getFunctions(project, filters, config) + .then(({ data }) => { + dispatch(functionsActions.fetchFunctionsSuccess(data.funcs)) - return data.funcs - }) - .catch(err => { - dispatch(functionsActions.fetchFunctionsFailure(err.message)) - }) - }, + return data.funcs + }) + .catch(error => { + dispatch(functionsActions.fetchFunctionsFailure(error.message)) + largeResponseCatchHandler(error, 'Failed to fetch functions', dispatch) + }) + }, fetchFunctionsBegin: () => ({ type: FETCH_FUNCTIONS_BEGIN }), @@ -264,17 +254,8 @@ const functionsActions = { return response.data }) .catch(error => { - const errorMsg = get(error, 'response.data.detail', 'The function failed to load') dispatch(functionsActions.fetchHubFunctionTemplateFailure(error)) - - dispatch( - setNotification({ - status: error.response?.status || 400, - id: Math.random(), - message: errorMsg, - error - }) - ) + showErrorNotification(dispatch, error, 'The function failed to load') }) }, fetchHubFunctionTemplateSuccess: () => ({ @@ -300,16 +281,7 @@ const functionsActions = { return templatesData }) .catch(error => { - const errorMsg = get(error, 'response.data.detail', 'Functions failed to load') - - dispatch( - setNotification({ - status: error.response?.status || 400, - id: Math.random(), - message: errorMsg, - error - }) - ) + showErrorNotification(dispatch, error, 'Functions failed to load') }) }, diff --git a/src/actions/jobs.js b/src/actions/jobs.js index 4eac77b66d..7b08e91651 100644 --- a/src/actions/jobs.js +++ b/src/actions/jobs.js @@ -17,7 +17,6 @@ illegal under applicable law, and the grant of the foregoing license under the Apache 2.0 license is conditioned upon your compliance with such restriction. */ -import { get } from 'lodash' import jobsApi from '../api/jobs-api' import functionsApi from '../api/functions-api' import { @@ -76,7 +75,8 @@ import { SET_URL } from '../constants' import { getNewJobErrorMsg } from '../components/JobWizard/JobWizard.util' -import { setNotification } from '../reducers/notificationReducer' +import { showErrorNotification } from '../utils/notifications.util' +import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' const jobsActions = { abortJob: (project, job) => dispatch => { @@ -148,11 +148,11 @@ const jobsActions = { type: EDIT_JOB_FAILURE, payload: error }), - fetchAllJobRuns: (project, filters, jobName, setLargeRequestErrorMessage) => dispatch => { + fetchAllJobRuns: (project, filters, config, jobName) => dispatch => { dispatch(jobsActions.fetchAllJobRunsBegin()) return jobsApi - .getAllJobRuns(project, jobName, filters, setLargeRequestErrorMessage) + .getAllJobRuns(project, filters, config, jobName) .then(({ data }) => { dispatch(jobsActions.fetchAllJobRunsSuccess(data.runs || [])) @@ -160,8 +160,7 @@ const jobsActions = { }) .catch(error => { dispatch(jobsActions.fetchAllJobRunsFailure(error)) - - throw error + largeResponseCatchHandler(error, 'Failed to fetch jobs', dispatch) }) }, fetchAllJobRunsBegin: () => ({ @@ -210,17 +209,8 @@ const jobsActions = { return res.data.func }) .catch(error => { - const errorMsg = get(error, 'response.data.detail', 'Job’s function failed to load') - dispatch(jobsActions.fetchJobFunctionFailure(error)) - dispatch( - setNotification({ - status: error.response?.status || 400, - id: Math.random(), - message: errorMsg, - error - }) - ) + showErrorNotification(dispatch, error, 'Job’s function failed to load') }) }, fetchJobFunctionBegin: () => ({ @@ -280,12 +270,12 @@ const jobsActions = { fetchJobLogsSuccess: () => ({ type: FETCH_JOB_LOGS_SUCCESS }), - fetchJobs: (project, filters, scheduled, setLargeRequestErrorMessage) => dispatch => { + fetchJobs: (project, filters, config, scheduled) => dispatch => { const getJobs = scheduled ? jobsApi.getScheduledJobs : jobsApi.getJobs dispatch(jobsActions.fetchJobsBegin()) - return getJobs(project, filters, setLargeRequestErrorMessage) + return getJobs(project, filters, config) .then(({ data }) => { const newJobs = scheduled ? (data || {}).schedules @@ -298,8 +288,7 @@ const jobsActions = { }) .catch(error => { dispatch(jobsActions.fetchJobsFailure(error)) - - throw error + largeResponseCatchHandler(error, 'Failed to fetch jobs', dispatch) }) }, fetchSpecificJobs: (project, filters, jobList) => () => { diff --git a/src/actions/projects.js b/src/actions/projects.js index b8d5e1bb84..756b0f1d67 100644 --- a/src/actions/projects.js +++ b/src/actions/projects.js @@ -94,6 +94,7 @@ import { } from 'igz-controls/constants' import { parseSummaryData } from '../utils/parseSummaryData' +import { showErrorNotification } from '../utils/notifications.util' const projectsAction = { addProjectLabel: (label, labels) => ({ @@ -218,11 +219,11 @@ const projectsAction = { type: FETCH_PROJECT_DATASETS_SUCCESS, payload: datasets }), - fetchProjectFailedJobs: (project, cancelToken) => dispatch => { + fetchProjectFailedJobs: (project, signal) => dispatch => { dispatch(projectsAction.fetchProjectFailedJobsBegin()) return projectsApi - .getProjectFailedJobs(project, cancelToken) + .getProjectFailedJobs(project, signal) .then(response => { dispatch(projectsAction.fetchProjectFailedJobsSuccess(response?.data.runs)) @@ -257,11 +258,11 @@ const projectsAction = { dispatch(projectsAction.fetchProjectFilesFailure(error.message)) }) }, - fetchProjectFeatureSets: (project, cancelToken) => dispatch => { + fetchProjectFeatureSets: (project, signal) => dispatch => { dispatch(projectsAction.fetchProjectFeatureSetsBegin()) return projectsApi - .getProjectFeatureSets(project, cancelToken) + .getProjectFeatureSets(project, signal) .then(response => { dispatch(projectsAction.fetchProjectFeatureSetsSuccess(response.data?.feature_sets)) @@ -293,11 +294,11 @@ const projectsAction = { type: FETCH_PROJECT_FILES_SUCCESS, payload: files }), - fetchProjectFunctions: (project, cancelToken) => dispatch => { + fetchProjectFunctions: (project, signal) => dispatch => { dispatch(projectsAction.fetchProjectFunctionsBegin()) return projectsApi - .getProjectFunctions(project, cancelToken) + .getProjectFunctions(project, signal) .then(response => { dispatch(projectsAction.fetchProjectFunctionsSuccess(response?.data.funcs)) @@ -355,11 +356,11 @@ const projectsAction = { type: FETCH_PROJECT_JOBS_SUCCESS, payload: jobs }), - fetchProjectModels: (project, cancelToken) => dispatch => { + fetchProjectModels: (project, signal) => dispatch => { dispatch(projectsAction.fetchProjectModelsBegin()) return projectsApi - .getProjectModels(project, cancelToken) + .getProjectModels(project, signal) .then(response => { dispatch(projectsAction.fetchProjectModelsSuccess(response?.data.artifacts)) @@ -380,11 +381,11 @@ const projectsAction = { type: FETCH_PROJECT_MODELS_SUCCESS, payload: models }), - fetchProjectRunningJobs: (project, cancelToken) => dispatch => { + fetchProjectRunningJobs: (project, signal) => dispatch => { dispatch(projectsAction.fetchProjectRunningJobsBegin()) return projectsApi - .getProjectRunningJobs(project, cancelToken) + .getProjectRunningJobs(project, signal) .then(response => { dispatch(projectsAction.fetchProjectRunningJobsSuccess(response?.data.runs)) @@ -499,8 +500,9 @@ const projectsAction = { return response.data.projects }) - .catch(err => { - dispatch(projectsAction.fetchProjectsFailure(err)) + .catch(error => { + dispatch(projectsAction.fetchProjectsFailure(error), dispatch) + showErrorNotification(dispatch, error, 'Failed to fetch projects') }) }, fetchProjectsBegin: () => ({ type: FETCH_PROJECTS_BEGIN }), @@ -535,11 +537,11 @@ const projectsAction = { type: FETCH_PROJECTS_SUCCESS, payload: projectsList }), - fetchProjectsSummary: cancelToken => dispatch => { + fetchProjectsSummary: signal => dispatch => { dispatch(projectsAction.fetchProjectsSummaryBegin()) return projectsApi - .getProjectSummaries(cancelToken) + .getProjectSummaries(signal) .then(({ data: { project_summaries } }) => { dispatch(projectsAction.fetchProjectsSummarySuccess(parseSummaryData(project_summaries))) diff --git a/src/actions/workflow.js b/src/actions/workflow.js index 0e1b212639..10f0ce0498 100644 --- a/src/actions/workflow.js +++ b/src/actions/workflow.js @@ -29,6 +29,7 @@ import { } from '../constants' import { parseWorkflows } from '../utils/parseWorkflows' import { parseWorkflow } from '../components/Workflow/workflow.util' +import { largeResponseCatchHandler } from '../utils/largeResponseCatchHandler' const workflowActions = { fetchWorkflow: (project, workflowId) => dispatch => { @@ -58,15 +59,18 @@ const workflowActions = { type: FETCH_WORKFLOW_FAILURE, payload: error }), - fetchWorkflows: (project, filter, setLargeRequestErrorMessage) => dispatch => { + fetchWorkflows: (project, filter, config) => dispatch => { dispatch(workflowActions.fetchWorkflowsBegin()) return workflowApi - .getWorkflows(project, filter, setLargeRequestErrorMessage) + .getWorkflows(project, filter, config) .then(response => dispatch(workflowActions.fetchWorkflowsSuccess(parseWorkflows(response.data.runs))) ) - .catch(error => dispatch(workflowActions.fetchWorkflowsFailure(error))) + .catch(error => { + dispatch(workflowActions.fetchWorkflowsFailure(error)) + largeResponseCatchHandler(error, 'Failed to fetch workflows', dispatch) + }) }, fetchWorkflowsBegin: () => ({ type: FETCH_WORKFLOWS_BEGIN diff --git a/src/api/artifacts-api.js b/src/api/artifacts-api.js index e5f5435448..52493a737d 100644 --- a/src/api/artifacts-api.js +++ b/src/api/artifacts-api.js @@ -62,7 +62,7 @@ const artifactsApi = { }, deleteTag: (project, tag, data) => mainHttpClient.delete(`/projects/${project}/tags/${tag}`, { data }), - getArtifactPreview: (project, path, user, fileFormat, cancelToken) => { + getArtifactPreview: (project, path, user, fileFormat, signal) => { const config = { params: { path } } @@ -75,8 +75,8 @@ const artifactsApi = { config.responseType = 'blob' } - if (cancelToken) { - config.cancelToken = cancelToken + if (signal) { + config.signal = signal } return mainHttpClient.get(`projects/${project}/files`, config) @@ -107,13 +107,10 @@ const artifactsApi = { } ) }, - getDataSets: (project, filters, config, setLargeRequestErrorMessage) => { + getDataSets: (project, filters, config = {}) => { const newConfig = { ...config, - params: { category: DATASET_TYPE }, - ui: { - setLargeRequestErrorMessage - } + params: { category: DATASET_TYPE } } return fetchArtifacts(project, filters, newConfig) @@ -132,15 +129,13 @@ const artifactsApi = { } ) }, - getFiles: (project, filters, setLargeRequestErrorMessage) => { - const config = { - params: { category: ARTIFACT_OTHER_TYPE, format: 'full' }, - ui: { - setLargeRequestErrorMessage - } + getFiles: (project, filters, config = {}) => { + const newConfig = { + ...config, + params: { category: ARTIFACT_OTHER_TYPE, format: 'full' } } - return fetchArtifacts(project, filters, config) + return fetchArtifacts(project, filters, newConfig) }, getModel: (project, model, iter, tag) => { return fetchArtifacts( @@ -156,29 +151,25 @@ const artifactsApi = { } ) }, - getModelEndpoints: (project, filters, params = {}, setLargeRequestErrorMessage) => { - const config = { - params, - ui: { - setLargeRequestErrorMessage - } + getModelEndpoints: (project, filters, config = {}, params = {}) => { + const newConfig = { + ...config, + params } if (filters?.labels) { - config.params.label = filters.labels?.split(',') + newConfig.params.label = filters.labels?.split(',') } - return mainHttpClient.get(`/projects/${project}/model-endpoints`, config) + return mainHttpClient.get(`/projects/${project}/model-endpoints`, newConfig) }, - getModels: (project, filters, setLargeRequestErrorMessage) => { - const config = { - params: { category: MODEL_TYPE, format: 'full' }, - ui: { - setLargeRequestErrorMessage - } + getModels: (project, filters, config = {}) => { + const newConfig = { + ...config, + params: { category: MODEL_TYPE, format: 'full' } } - return fetchArtifacts(project, filters, config) + return fetchArtifacts(project, filters, newConfig) }, registerArtifact: (project, data) => mainHttpClient.post( diff --git a/src/api/functions-api.js b/src/api/functions-api.js index 7f9fad26a7..62a45fed9a 100644 --- a/src/api/functions-api.js +++ b/src/api/functions-api.js @@ -30,23 +30,21 @@ const functionsApi = { deleteSelectedFunction: (func, project) => mainHttpClient.delete(`/projects/${project}/functions/${func}`), deployFunction: data => mainHttpClient.post('/build/function', data), - getFunctions: (project, filters, hash, setLargeRequestErrorMessage) => { - const config = { - params: {}, - ui: { - setLargeRequestErrorMessage - } + getFunctions: (project, filters, config = {}, hash) => { + const newConfig = { + ...config, + params: {} } if (filters?.name) { - config.params.name = `~${filters.name}` + newConfig.params.name = `~${filters.name}` } if (hash) { - config.params.hash_key = hash + newConfig.params.hash_key = hash } - return mainHttpClient.get(`/projects/${project}/functions`, config) + return mainHttpClient.get(`/projects/${project}/functions`, newConfig) }, getFunction: (project, functionName, hash, tag) => { const params = {} diff --git a/src/api/jobs-api.js b/src/api/jobs-api.js index 8eef9a7c10..f9532b51c2 100644 --- a/src/api/jobs-api.js +++ b/src/api/jobs-api.js @@ -74,23 +74,18 @@ const jobsApi = { `/projects/${project}/schedules/${postData.scheduled_object.task.metadata.name}`, postData ), - getJobs: (project, filters, setLargeRequestErrorMessage, isAllJobs) => { - const config = { + getJobs: (project, filters, config = {}) => { + const newConfig = { + ...config, params: { + 'partition-by': 'name', + 'partition-sort-by': 'updated', project, ...generateRequestParams(filters) - }, - ui: { - setLargeRequestErrorMessage } } - if (!isAllJobs) { - config.params['partition-by'] = 'name' - config.params['partition-sort-by'] = 'updated' - } - - return mainHttpClient.get('/runs', config) + return mainHttpClient.get('/runs', newConfig) }, getSpecificJobs: (project, filters, jobList) => { const params = { @@ -102,19 +97,17 @@ const jobsApi = { return mainHttpClient.get(`/runs?${jobListQuery}`, { params }) }, - getAllJobRuns: (project, jobName, filters, setLargeRequestErrorMessage) => { - const config = { + getAllJobRuns: (project, filters, config = {}, jobName) => { + const newConfig = { + ...config, params: { project, name: jobName, ...generateRequestParams(filters) - }, - ui: { - setLargeRequestErrorMessage } } - return mainHttpClient.get('/runs', config) + return mainHttpClient.get('/runs', newConfig) }, getJob: (project, jobId, iter) => { const params = {} @@ -129,29 +122,27 @@ const jobsApi = { fetch(`${mainBaseUrl}/log/${project}/${id}`, { method: 'get' }), - getScheduledJobs: (project, filters, setLargeRequestErrorMessage) => { - const config = { + getScheduledJobs: (project, filters, config = {}) => { + const newConfig = { + ...config, params: { include_last_run: 'yes' - }, - ui: { - setLargeRequestErrorMessage } } if (filters?.owner) { - config.params.owner = filters.owner + newConfig.params.owner = filters.owner } if (filters?.name) { - config.params.name = `~${filters.name}` + newConfig.params.name = `~${filters.name}` } if (filters?.labels) { - config.params.labels = filters.labels?.split(',') + newConfig.params.labels = filters.labels?.split(',') } - return mainHttpClient.get(`/projects/${project}/schedules`, config) + return mainHttpClient.get(`/projects/${project}/schedules`, newConfig) }, removeScheduledJob: (project, scheduleName) => mainHttpClient.delete(`/projects/${project}/schedules/${scheduleName}`), diff --git a/src/api/projects-api.js b/src/api/projects-api.js index 9fb91ccd9b..65afdd5048 100644 --- a/src/api/projects-api.js +++ b/src/api/projects-api.js @@ -41,31 +41,31 @@ const projectsApi = { getProject: project => mainHttpClient.get(`/projects/${project}`), getProjectDataSets: project => mainHttpClient.get(`/projects/${project}/artifacts?category=dataset`), - getProjectFailedJobs: (project, cancelToken) => + getProjectFailedJobs: (project, signal) => mainHttpClient.get( `/runs?project=${project}&state=error&start_time_from=${new Date( Date.now() - 24 * 60 * 60 * 1000 ).toISOString()}`, { - cancelToken: cancelToken + signal: signal } ), - getProjectFeatureSets: (project, cancelToken) => + getProjectFeatureSets: (project, signal) => mainHttpClient.get(`/projects/${project}/feature-sets`, { - cancelToken: cancelToken + signal: signal }), getProjectFiles: project => mainHttpClient.get(`/projects/${project}/artifacts?category=other`), - getProjectFunctions: (project, cancelToken) => + getProjectFunctions: (project, signal) => mainHttpClient.get(`/projects/${project}/functions`, { - cancelToken: cancelToken + signal: signal }), - getProjectModels: (project, cancelToken) => + getProjectModels: (project, signal) => mainHttpClient.get(`/projects/${project}/artifacts?category=model`, { - cancelToken: cancelToken + signal: signal }), - getProjectRunningJobs: (project, cancelToken) => + getProjectRunningJobs: (project, signal) => mainHttpClient.get(`/runs?project=${project}&state=running`, { - cancelToken: cancelToken + signal: signal }), getProjectScheduledJobs: project => mainHttpClient.get(`/projects/${project}/schedules`), getProjectSecrets: project => @@ -74,9 +74,9 @@ const projectsApi = { mainHttpClient.get('/projects', { params }), - getProjectSummaries: cancelToken => + getProjectSummaries: signal => mainHttpClient.get('/project-summaries', { - cancelToken + signal }), getProjectSummary: project => { return mainHttpClient.get(`/project-summaries/${project}`) diff --git a/src/api/workflow-api.js b/src/api/workflow-api.js index 00177cc47b..e25d9231ff 100644 --- a/src/api/workflow-api.js +++ b/src/api/workflow-api.js @@ -76,19 +76,17 @@ const workflowsApi = { getWorkflow: (project, workflowId) => { return mainHttpClient.get(`/projects/${project}/pipelines/${workflowId}`) }, - getWorkflows: (project, filter, setLargeRequestErrorMessage) => { - const config = { - params: {}, - ui: { - setLargeRequestErrorMessage - } + getWorkflows: (project, filter, config = {}) => { + const newConfig = { + ...config, + params: {} } if (filter?.groupBy === GROUP_BY_WORKFLOW) { - config.params.filter = generateQueryParams(filter) + newConfig.params.filter = generateQueryParams(filter) } - return mainHttpClient.get(`/projects/${project}/pipelines`, config) + return mainHttpClient.get(`/projects/${project}/pipelines`, newConfig) } } diff --git a/src/common/CopyToClipboard/CopyToClipboard.js b/src/common/CopyToClipboard/CopyToClipboard.js index 528452bed5..878bd6f220 100644 --- a/src/common/CopyToClipboard/CopyToClipboard.js +++ b/src/common/CopyToClipboard/CopyToClipboard.js @@ -23,6 +23,7 @@ import { useDispatch } from 'react-redux' import { Tooltip, TextTooltipTemplate, RoundedIcon } from 'igz-controls/components' import { setNotification } from '../../reducers/notificationReducer' +import { showErrorNotification } from '../../utils/notifications.util' import { ReactComponent as Copy } from 'igz-controls/images/copy-to-clipboard-icon.svg' @@ -41,15 +42,8 @@ const CopyToClipboard = ({ children, className, disabled, textToCopy, tooltipTex }) ) }) - .catch(err => { - dispatch( - setNotification({ - error: err, - status: 400, - id: Math.random(), - message: 'Copy to clipboard failed' - }) - ) + .catch(error => { + showErrorNotification(dispatch, error, '', 'Copy to clipboard failed') }) } diff --git a/src/common/Download/DownloadItem.js b/src/common/Download/DownloadItem.js index 7afeb530a2..2b7af834ae 100644 --- a/src/common/Download/DownloadItem.js +++ b/src/common/Download/DownloadItem.js @@ -25,8 +25,9 @@ import { useParams } from 'react-router-dom' import { RoundedIcon, Tooltip, TextTooltipTemplate } from 'igz-controls/components' -import { mainHttpClient } from '../../httpClient' import downloadFile from '../../utils/downloadFile' +import { REQUEST_CANCELED } from '../../constants' +import { mainHttpClient } from '../../httpClient' import { removeDownloadItem } from '../../reducers/downloadReducer' import { ReactComponent as Close } from 'igz-controls/images/close.svg' @@ -39,8 +40,7 @@ const DownloadItem = ({ downloadItem }) => { const [isDownload, setDownload] = useState(true) const [isSuccessResponse, setIsSuccessResponse] = useState(null) const params = useParams() - - const downloadRef = useRef(null) + const downloadAbortControllerRef = useRef(null) const timeoutRef = useRef(null) const dispatch = useDispatch() @@ -54,16 +54,14 @@ const DownloadItem = ({ downloadItem }) => { const downloadCallback = useCallback(() => { if (isDownload) { + downloadAbortControllerRef.current = new AbortController() + const config = { onDownloadProgress: progressEvent => { const percentCompleted = (progressEvent.loaded * 100) / progressEvent.total setProgress(percentCompleted) }, - cancelToken: new axios.CancelToken(cancel => { - if (downloadRef.current) { - downloadRef.current.cancel = cancel - } - }), + signal: downloadAbortControllerRef.current.signal, params: { path: downloadItem.path }, responseType: 'arraybuffer' } @@ -76,7 +74,7 @@ const DownloadItem = ({ downloadItem }) => { .get(`projects/${params.projectName}/files`, config) .then(response => { downloadFile(file, response) - if (downloadRef.current) { + if (downloadAbortControllerRef.current) { setDownload(false) setIsSuccessResponse(true) } @@ -87,14 +85,14 @@ const DownloadItem = ({ downloadItem }) => { return setProgress(0) } - if (downloadRef.current) { + if (downloadAbortControllerRef.current) { setDownload(false) setProgress(0) } }) .finally(() => { - if (downloadRef.current) { - downloadRef.current.cancel = null + if (downloadAbortControllerRef.current) { + downloadAbortControllerRef.current = null } timeoutRef.current = setTimeout(() => { @@ -113,20 +111,20 @@ const DownloadItem = ({ downloadItem }) => { ]) useEffect(() => { - let cancelFetch = downloadRef.current + let cancelFetch = downloadAbortControllerRef.current setTimeout(() => { downloadCallback() }, 1000) return () => { - cancelFetch.cancel && cancelFetch.cancel() + cancelFetch && cancelFetch.abort(REQUEST_CANCELED) } - }, [downloadCallback, downloadRef]) + }, [downloadCallback, downloadAbortControllerRef]) const handleCancel = () => { - if (downloadRef.current?.cancel) { - return downloadRef.current.cancel('cancel') + if (downloadAbortControllerRef.current) { + return downloadAbortControllerRef.current.abort(REQUEST_CANCELED) } setDownload(!isDownload) @@ -141,7 +139,7 @@ const DownloadItem = ({ downloadItem }) => { } return ( -
+
}> {file} diff --git a/src/common/Input/Input.js b/src/common/Input/Input.js index aad8d34da1..a62866dc57 100644 --- a/src/common/Input/Input.js +++ b/src/common/Input/Input.js @@ -45,6 +45,7 @@ const Input = React.forwardRef( focused, iconClass, iconOnClick, + id, infoLabel, inputIcon, invalid, @@ -221,7 +222,7 @@ const Input = React.forwardRef( return (