diff --git a/.devcontainer/setupEnv.sh b/.devcontainer/setupEnv.sh index c0d8ee98..08a87bbc 100644 --- a/.devcontainer/setupEnv.sh +++ b/.devcontainer/setupEnv.sh @@ -1,5 +1,9 @@ #!/bin/sh +echo "Pull latest code for the current branch" +git fetch +git pull + set -e # Exit on error echo "Setting up ContentProcessor..." @@ -7,16 +11,20 @@ cd ./src/ContentProcessor uv sync --frozen cd ../../ -pwd - echo "Setting up ContentProcessorApi..." cd ./src/ContentProcessorAPI uv sync --frozen cd ../../ -pwd echo "Installing dependencies for ContentProcessorWeb..." cd ./src/ContentProcessorWeb yarn install +cd ../../ + +echo "Setting up executable permission for shell scripts" +sudo chmod +x ./infra/scripts/docker-build.sh +sudo chmod +x ./src/ContentProcessorAPI/samples/upload_files.sh +sudo chmod +x ./src/ContentProcessorAPI/samples/schemas/register_schema.sh + echo "Setup complete! 🎉" diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml new file mode 100644 index 00000000..23b8355c --- /dev/null +++ b/.github/workflows/build-docker-image.yml @@ -0,0 +1,87 @@ +name: Build and Push Docker Images + +on: + push: + branches: [main, dev, demo, hotfix] + pull_request: + branches: [main, dev, demo, hotfix] + types: [opened, ready_for_review, reopened, synchronize] + workflow_dispatch: + +jobs: + build-and-push: + runs-on: ubuntu-latest + env: + ACR_LOGIN_SERVER: ${{ secrets.ACR_LOGIN_SERVER }} + ACR_USERNAME: ${{ secrets.ACR_USERNAME }} + ACR_PASSWORD: ${{ secrets.ACR_PASSWORD }} + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Get current date + id: date + run: echo "date=$(date +'%Y-%m-%d')" >> $GITHUB_OUTPUT + + - name: Log in to Azure Container Registry + if: ${{ github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo' || github.ref_name == 'hotfix' }} + uses: azure/docker-login@v2 + with: + login-server: ${{ env.ACR_LOGIN_SERVER }} + username: ${{ env.ACR_USERNAME }} + password: ${{ env.ACR_PASSWORD }} + + - name: Set Docker image tags + id: tag + run: | + BRANCH="${{ github.ref_name }}" + DATE="${{ steps.date.outputs.date }}" + if [[ "$BRANCH" == "main" ]]; then + BASE_TAG="latest" + elif [[ "$BRANCH" == "dev" ]]; then + BASE_TAG="dev" + elif [[ "$BRANCH" == "demo" ]]; then + BASE_TAG="demo" + elif [[ "$BRANCH" == "hotfix" ]]; then + BASE_TAG="hotfix" + else + BASE_TAG="pullrequest-ignore" + fi + DATE_TAG="${BASE_TAG}-${DATE}" + echo "BASE_TAG=${BASE_TAG}" >> $GITHUB_ENV + echo "DATE_TAG=${DATE_TAG}" >> $GITHUB_ENV + echo "Base tag: $BASE_TAG, Date tag: $DATE_TAG" + + - name: Build and Push ContentProcessor Docker image + uses: docker/build-push-action@v6 + with: + context: ./src/ContentProcessor + file: ./src/ContentProcessor/Dockerfile + push: ${{ github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo' || github.ref_name == 'hotfix' }} + tags: | + ${{ env.ACR_LOGIN_SERVER }}/contentprocessor:${{ env.BASE_TAG }} + ${{ env.ACR_LOGIN_SERVER }}/contentprocessor:${{ env.DATE_TAG }} + + - name: Build and Push ContentProcessorAPI Docker image + uses: docker/build-push-action@v6 + with: + context: ./src/ContentProcessorAPI + file: ./src/ContentProcessorAPI/Dockerfile + push: ${{ github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo' || github.ref_name == 'hotfix' }} + tags: | + ${{ env.ACR_LOGIN_SERVER }}/contentprocessorapi:${{ env.BASE_TAG }} + ${{ env.ACR_LOGIN_SERVER }}/contentprocessorapi:${{ env.DATE_TAG }} + + - name: Build and Push ContentProcessorWeb Docker image + uses: docker/build-push-action@v6 + with: + context: ./src/ContentProcessorWeb + file: ./src/ContentProcessorWeb/Dockerfile + push: ${{ github.ref_name == 'main' || github.ref_name == 'dev' || github.ref_name == 'demo' || github.ref_name == 'hotfix' }} + tags: | + ${{ env.ACR_LOGIN_SERVER }}/contentprocessorweb:${{ env.BASE_TAG }} + ${{ env.ACR_LOGIN_SERVER }}/contentprocessorweb:${{ env.DATE_TAG }} diff --git a/infra/deploy_ai_foundry.bicep b/infra/deploy_ai_foundry.bicep index 232fc86d..62d6a480 100644 --- a/infra/deploy_ai_foundry.bicep +++ b/infra/deploy_ai_foundry.bicep @@ -245,225 +245,6 @@ resource aiHubProject 'Microsoft.MachineLearningServices/workspaces@2024-01-01-p } } -// var phiModelRegions = ['East US', 'East US 2', 'North Central US', 'South Central US', 'Sweden Central', 'West US', 'West US 3', 'eastus','eastus2','northcentralus','southcentralus','swedencentral','westus','westus3'] - -// var isInPhiList = contains(phiModelRegions, location) - -// var serverlessModelName = 'Phi-4' //'Phi-3-medium-4k-instruct' -// var phiserverlessName = '${solutionName}-${serverlessModelName}' -// resource phiserverless 'Microsoft.MachineLearningServices/workspaces/serverlessEndpoints@2024-10-01' = if (isInPhiList) { -// parent: aiHubProject -// location: location -// name: phiserverlessName -// properties: { -// authMode: 'Key' -// contentSafety: { -// contentSafetyStatus: 'Enabled' -// } -// modelSettings: { -// modelId: 'azureml://registries/azureml/models/${serverlessModelName}' -// } -// } -// sku: { -// name: 'Consumption' -// tier: 'Free' -// } -// } - -resource tenantIdEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'TENANT-ID' - properties: { - value: subscription().tenantId - } -} - -// resource adlsAccountNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'ADLS-ACCOUNT-NAME' -// properties: { -// value: storageName -// } -// } - -// resource adlsAccountContainerEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'ADLS-ACCOUNT-CONTAINER' -// properties: { -// value: 'data' -// } -// } - -// resource adlsAccountKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'ADLS-ACCOUNT-KEY' -// properties: { -// value: storage.listKeys().keys[0].value -// } -// } - -// resource azureOpenAIInferenceEndpoint 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-OPENAI-INFERENCE-ENDPOINT' -// properties: { -// value: phiserverless != null ? phiserverless.properties.inferenceEndpoint.uri : '' -// // value: phiserverless.properties.inferenceEndpoint.uri -// } -// } - -// resource azureOpenAIInferenceKey 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-OPENAI-INFERENCE-KEY' -// properties: { -// value: phiserverless != null ? listKeys(phiserverless.id, '2024-10-01').primaryKey : '' -// // listKeys(phiserverless.id, '2024-10-01').primaryKey -// } -// } - -resource azureOpenAIApiKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-KEY' - properties: { - value: aiServices.listKeys().key1 //aiServices_m.listKeys().key1 - } -} - -resource azureOpenAIDeploymentModel 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPEN-AI-DEPLOYMENT-MODEL' - properties: { - value: gptModelName - } -} - -resource gptModelVersionEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-PREVIEW-API-VERSION' - properties: { - value: gptModelVersion //'2024-02-15-preview' - } -} - -resource azureOpenAIEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-ENDPOINT' - properties: { - value: aiServices.properties.endpoint //aiServices_m.properties.endpoint - } -} - -resource azureAIProjectConnectionStringEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-AI-PROJECT-CONN-STRING' - properties: { - value: '${split(aiHubProject.properties.discoveryUrl, '/')[2]};${subscription().subscriptionId};${resourceGroup().name};${aiHubProject.name}' - } -} - -resource azureOpenAICUEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-CU-ENDPOINT' - properties: { - value: aiServices_CU.properties.endpoint - } -} - -resource azureOpenAICUApiKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-CU-KEY' - properties: { - value: aiServices_CU.listKeys().key1 - } -} - -resource azureOpenAICUApiVersionEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-OPENAI-CU-VERSION' - properties: { - value: '?api-version=2024-12-01-preview' - } -} - -// resource azureSearchAdminKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-SEARCH-KEY' -// properties: { -// value: aiSearch.listAdminKeys().primaryKey -// } -// } - -// resource azureSearchServiceEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-SEARCH-ENDPOINT' -// properties: { -// value: 'https://${aiSearch.name}.search.windows.net' -// } -// } - -// resource azureSearchServiceEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-SEARCH-SERVICE' -// properties: { -// value: aiSearch.name -// } -// } - -// resource azureSearchIndexEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { -// parent: keyVault -// name: 'AZURE-SEARCH-INDEX' -// properties: { -// value: 'transcripts_index' -// } -// } - -resource cogServiceEndpointEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'COG-SERVICES-ENDPOINT' - properties: { - value: aiServices.properties.endpoint - } -} - -resource cogServiceKeyEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'COG-SERVICES-KEY' - properties: { - value: aiServices.listKeys().key1 - } -} - -resource cogServiceNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'COG-SERVICES-NAME' - properties: { - value: aiServicesName - } -} - -resource azureSubscriptionIdEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-SUBSCRIPTION-ID' - properties: { - value: subscription().subscriptionId - } -} - -resource resourceGroupNameEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-RESOURCE-GROUP' - properties: { - value: resourceGroup().name - } -} - -resource azureLocatioEntry 'Microsoft.KeyVault/vaults/secrets@2021-11-01-preview' = { - parent: keyVault - name: 'AZURE-LOCATION' - properties: { - value: solutionLocation - } -} - output aiServicesTarget string = aiServices.properties.endpoint //aiServices_m.properties.endpoint output aiServicesCUEndpoint string = aiServices_CU.properties.endpoint //aiServices_m.properties.endpoint output aiServicesName string = aiServicesName //aiServicesName_m diff --git a/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.styles.scss b/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.styles.scss index a1d00b9b..8a89b6ac 100644 --- a/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.styles.scss +++ b/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.styles.scss @@ -4,3 +4,44 @@ border: 1px solid rgb(219, 219, 219) } +.imageErrorContainer{ + background: rgba(0, 0, 0, 0.3); + /* margin: auto; */ + display: flex; + align-items: center; + justify-content: center; +} + +.invalidImagePopup{ + width: 100%; + padding: auto; + margin: auto; + z-index: 99999; + /* background: white; */ + padding: 35px; + box-sizing: content-box; + margin: 30px; + border-radius: 6px; + border: 1px solid #c0c0c0; + /* font-size: 21px; */ + /* font-weight: 600; */ + box-shadow: azure; + /* transform: translate(-50%, -50%); */ + /* top: 50%; */ + /* left: 50%; */ + background: white; + /* display: flex +; */ + background-color: white; + border: 1px solid #ddd; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + + .imgEH{ + font-size: 24px; + font-weight: 600; + } + +} + + + diff --git a/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.tsx b/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.tsx index 26a0887c..40bd4055 100644 --- a/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.tsx +++ b/src/ContentProcessorWeb/src/Components/DocumentViewer/DocumentViewer.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { Document } from "./DocumentViewer.types"; import { TIFFViewer } from 'react-tiff'; @@ -17,10 +17,18 @@ interface IIFrameComponentProps { const DocumentViewer = ({ className, metadata, urlWithSasToken, iframeKey }: IIFrameComponentProps) => { const { t } = useTranslation(); + const [imgError, setImageError] = useState(false); + + useEffect(() => { + setImageError(false) + }, [urlWithSasToken]) + + // Ref for the container div where the Dialog will be rendered + const containerRef = React.useRef(null); const getContentComponent = () => { if (!metadata || !urlWithSasToken) { - return
{t("components.document.none", "No document available")}
; + return
{t("components.document.none", "No document available")}
; } switch (metadata.mimeType) { @@ -50,7 +58,7 @@ const DocumentViewer = ({ className, metadata, urlWithSasToken, iframeKey }: IIF case "image/svg+xml": { return
- {"Document"} + {"Document"} setImageError(true)} width="100%" height="100%" className="document-image" />
; } @@ -94,7 +102,17 @@ const DocumentViewer = ({ className, metadata, urlWithSasToken, iframeKey }: IIF } }; - return
{getContentComponent()}
; + return <>
+ {imgError ? +
+ We can't open this file +

Something went wrong.

+
+ : getContentComponent() + } +
+ + ; } export default DocumentViewer; \ No newline at end of file diff --git a/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPageContent.tsx b/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPageContent.tsx index a278bb96..c93c9626 100644 --- a/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPageContent.tsx +++ b/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPageContent.tsx @@ -26,7 +26,7 @@ import { createAsyncThunk } from "@reduxjs/toolkit"; import httpUtility from "../../Services/httpUtility.ts"; import { JsonEditor } from "json-edit-react"; import { CheckmarkCircleFilled } from "@fluentui/react-icons"; -import { fetchContentJsonData } from '../../store/slices/centerPanelSlice'; +import { fetchContentJsonData , setActiveProcessId } from '../../store/slices/centerPanelSlice'; interface ContentProps { @@ -113,7 +113,7 @@ const ContentDevelopers: React.FC = ({ const styles = useStyles(); const dispatch = useDispatch(); const [comment, setComment] = React.useState(""); - const [selectedProcessId, setSelectedProcessId] = React.useState(null); + //const [selectedProcessId, setSelectedProcessId] = React.useState(null); const [selectedTab, setSelectedTab] = React.useState("extracted-results"); const [ApiLoader ,setApiLoader] = useState(false); const status = ['extract','processing','map','evaluate']; @@ -125,12 +125,14 @@ const ContentDevelopers: React.FC = ({ modified_result: state.centerPanel.modified_result, isSavingInProgress: state.centerPanel.isSavingInProgress, processStepsData: state.centerPanel.processStepsData, - selectedItem : state.leftPanel.selectedItem + selectedItem : state.leftPanel.selectedItem, + activeProcessId : state.centerPanel.activeProcessId }), shallowEqual ); useEffect(() => { - setSelectedProcessId(store.processId) + //setSelectedProcessId(store.processId); + dispatch(setActiveProcessId(store.processId)) setComment(''); }, [store.processId]) @@ -144,8 +146,8 @@ const ContentDevelopers: React.FC = ({ try { setApiLoader(true); await Promise.allSettled([ - dispatch(fetchContentJsonData({ processId: selectedProcessId })), - dispatch(fetchProcessSteps({ processId: selectedProcessId })) + dispatch(fetchContentJsonData({ processId: store.activeProcessId })), + dispatch(fetchProcessSteps({ processId: store.activeProcessId })) ]); } catch (error) { console.error("Error fetching data:", error); @@ -153,10 +155,10 @@ const ContentDevelopers: React.FC = ({ setApiLoader(false); } } - if ((selectedProcessId != null || selectedProcessId != '') && !status.includes(store.selectedItem.status) && store.selectedItem?.process_id === selectedProcessId ) { + if ((store.activeProcessId != null || store.activeProcessId != '') && !status.includes(store.selectedItem.status) && store.selectedItem?.process_id === store.activeProcessId ) { fetchContent(); } - }, [selectedProcessId, store.selectedItem]) + }, [store.activeProcessId, store.selectedItem]) const renderProcessTimeInSeconds = (timeString: string) => { if (!timeString) { @@ -176,13 +178,13 @@ const ContentDevelopers: React.FC = ({ const ExtractedResults = React.useCallback(() => (
- {selectedProcessId && !status.includes(store.selectedItem.status) ? ( + {store.activeProcessId && !status.includes(store.selectedItem.status) ? ( ) :

No data available

}
- ), [selectedProcessId,store.selectedItem]); + ), [store.activeProcessId,store.selectedItem]); const ProcessHistory = useCallback(() => (
@@ -220,7 +222,7 @@ const ContentDevelopers: React.FC = ({ {ApiLoader ?

Loading...

: (store.processStepsData?.length == 0 || status.includes(store.selectedItem.status)) &&

No data available

}
- ), [store.processStepsData, selectedProcessId, styles.tabItemCotnent, ApiLoader]); + ), [store.processStepsData, store.activeProcessId, styles.tabItemCotnent, ApiLoader]); const onTabSelect = (event: SelectTabEvent, data: SelectTabData) => { setSelectedTab(data.value); @@ -230,7 +232,7 @@ const ContentDevelopers: React.FC = ({ try { dispatch(startLoader("1")); dispatch(setUpdateComments(comment)) - await dispatch(saveContentJson({ 'processId': selectedProcessId, 'contentJson': store.modified_result.extracted_result, 'comments': comment , 'savedComments': store.comments })) + await dispatch(saveContentJson({ 'processId': store.activeProcessId, 'contentJson': store.modified_result.extracted_result, 'comments': comment , 'savedComments': store.comments })) } catch (error) { console.error('API Error:', error); } finally { diff --git a/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPagePanelRight.tsx b/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPagePanelRight.tsx index db450c7f..29046f7c 100644 --- a/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPagePanelRight.tsx +++ b/src/ContentProcessorWeb/src/Pages/DefaultPage/DefaultPagePanelRight.tsx @@ -18,21 +18,33 @@ const PanelRight: React.FC = () => { processId: state.leftPanel.processId, fileHeaders: state.rightPanel.fileHeaders, blobURL : state.rightPanel.blobURL, - rLoader: state.rightPanel.rLoader + rLoader: state.rightPanel.rLoader, + fileResponse : state.rightPanel.fileResponse }),shallowEqual ); + const isBlobExists = ()=>{ + const isfileExists = store.fileResponse.find(i =>i.processId == store.processId) + return isfileExists; + } useEffect(() => { - if (store.processId != null && store.processId != '') { + if (store.processId != null && store.processId != '' && !isBlobExists()) { dispatch(fetchContentFileData({ processId: store.processId })) } }, [store.processId]) - useEffect(() => { - if (Object.keys(store.fileHeaders).length > 0) { - //const fileURL = `${process.env.REACT_APP_API_BASE_URL}/contentprocessor/processed/files/${store.processId}`; - setFileData({ 'urlWithSasToken': store.blobURL, 'mimeType': store.fileHeaders['content-type'] }) + // useEffect(() => { + // if (Object.keys(store.fileHeaders).length > 0) { + // //const fileURL = `${process.env.REACT_APP_API_BASE_URL}/contentprocessor/processed/files/${store.processId}`; + // setFileData({ 'urlWithSasToken': store.blobURL, 'mimeType': store.fileHeaders['content-type'] }) + // } + // }, [store.fileHeaders]) + + useEffect(()=>{ + const isExists = isBlobExists(); + if(store.fileResponse.length > 0 && isExists && isExists.processId == store.processId){ + setFileData({ 'urlWithSasToken': isExists.blobURL, 'mimeType': isExists.headers['content-type'] }) } - }, [store.fileHeaders]) + },[store.processId, store.fileResponse]) return ( diff --git a/src/ContentProcessorWeb/src/store/slices/centerPanelSlice.ts b/src/ContentProcessorWeb/src/store/slices/centerPanelSlice.ts index a921e55c..6bd44b63 100644 --- a/src/ContentProcessorWeb/src/store/slices/centerPanelSlice.ts +++ b/src/ContentProcessorWeb/src/store/slices/centerPanelSlice.ts @@ -10,7 +10,7 @@ interface CenterPanelState { modified_result: any; comments: string; isSavingInProgress: boolean; - + activeProcessId : string, processStepsData: any[]; } @@ -78,7 +78,7 @@ const initialState: CenterPanelState = { modified_result: {}, comments: '', isSavingInProgress: false, - + activeProcessId : '', processStepsData: [], }; @@ -91,7 +91,10 @@ const centerPanelSlice = createSlice({ }, setUpdateComments : (state, action) => { state.comments = action.payload - } + }, + setActiveProcessId :(state,action) =>{ + state.activeProcessId = action.payload + } }, extraReducers: (builder) => { //Fetch Dropdown values @@ -103,9 +106,11 @@ const centerPanelSlice = createSlice({ state.comments = ''; }) .addCase(fetchContentJsonData.fulfilled, (state, action) => { // Adjust `any` to the response data type - state.contentData = action.payload; - state.comments = action.payload.comment?? "" ; - state.cLoader = false; + if(state.activeProcessId == action.payload.process_id){ + state.contentData = action.payload; + state.comments = action.payload.comment?? "" ; + state.cLoader = false; + } }) .addCase(fetchContentJsonData.rejected, (state, action) => { state.cError = action.error.message || 'An error occurred'; @@ -146,5 +151,5 @@ const centerPanelSlice = createSlice({ }, }); -export const { setModifiedResult ,setUpdateComments} = centerPanelSlice.actions; +export const { setModifiedResult ,setUpdateComments, setActiveProcessId} = centerPanelSlice.actions; export default centerPanelSlice.reducer; diff --git a/src/ContentProcessorWeb/src/store/slices/rightPanelSlice.ts b/src/ContentProcessorWeb/src/store/slices/rightPanelSlice.ts index 0e3dd0df..fb47ad44 100644 --- a/src/ContentProcessorWeb/src/store/slices/rightPanelSlice.ts +++ b/src/ContentProcessorWeb/src/store/slices/rightPanelSlice.ts @@ -3,12 +3,18 @@ import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'; import httpUtility from '../../Services/httpUtility'; import { toast } from "react-toastify"; +interface T { + headers:any, + blobURL:string, + processId : string +} interface RightPanelState { fileHeaders: any; rLoader: boolean; blobURL: string; rError: string | null; + fileResponse : Array } export const fetchContentFileData = createAsyncThunk('/contentprocessor/processed/files/', async ({ processId }, { rejectWithValue }): Promise => { @@ -24,7 +30,7 @@ export const fetchContentFileData = createAsyncThunki.processId === action.payload.processId) + if(!isItemExists ) + state.fileResponse.push(action.payload) }) .addCase(fetchContentFileData.rejected, (state, action) => { //console.log('Error : ', action.error.message)