From c06ef8ff51abc89477aa40dfa0414c764b43e903 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 4 Dec 2023 14:43:44 +0100 Subject: [PATCH 01/67] Don't ignore the VS Code folder --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5a6fb5838..8d55aef27 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ dist/ node_modules/ storybook-static/ coverage/ -.vscode yarn-error.log cypress/screenshots/ cypress/videos/ From 69740628ccb6aaae588962dcea6d8d27c636f351 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 4 Dec 2023 14:43:49 +0100 Subject: [PATCH 02/67] Add basic Chrome debugger `launch.json` --- .vscode/launch.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..ba66beaa1 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Attach Chrome debugger", + "url": "http://localhost:8000", + "webRoot": "${workspaceFolder}" + } + ] +} From 2d6f8536b2168499e6f09a27f23d56022d1d500f Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 4 Dec 2023 15:23:35 +0100 Subject: [PATCH 03/67] Have full-stack debugging for SRR --- .vscode/launch.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index ba66beaa1..2751ea45b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,9 +4,22 @@ { "type": "chrome", "request": "launch", - "name": "Attach Chrome debugger", + "name": "Attach SPA debugging (frontend-only)", "url": "http://localhost:8000", "webRoot": "${workspaceFolder}" + }, + { + "type": "node", + "request": "launch", + "name": "SRR debugging (full-stack)", + "runtimeExecutable": "node", + "runtimeArgs": ["--inspect-brk", "${workspaceFolder}/dist/server.js"], + "env": { + "NODE_ENV": "development", + "DEBUG": "*" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "openOnSessionStart" } ] } From 40d85db139c2244c901d1bb32d20070deac9750b Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 4 Dec 2023 15:28:38 +0100 Subject: [PATCH 04/67] Add VS Code recommendations and settings Very lean and simple. --- .editorconfig | 9 +++++++++ .vscode/extensions.json | 6 ++++++ .vscode/settings.json | 3 +++ 3 files changed, 18 insertions(+) create mode 100644 .editorconfig create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..37d38bbbb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..aa9a29c8b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "editorconfig.editorconfig", + "christian-kohler.npm-intellisense" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ad92582bd --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} From f0826e065c773470a901d27ded701794cb4f7381 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 11 Dec 2023 10:37:02 +0100 Subject: [PATCH 05/67] Add explicit end of line inside VS Code settings --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ad92582bd..144a7ec7a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "editor.formatOnSave": true + "editor.formatOnSave": true, + "files.eol": "\n" } From 07e3250bfff58b7b7736f6334b7144530ba6b68e Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 18 Dec 2023 15:55:16 +0100 Subject: [PATCH 06/67] Clean, sort, remove unused imports/declarations --- .../components/Settings/ViewsSubView.tsx | 29 ++++++++----------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index d59b2b4f0..1bc3c0449 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -1,28 +1,23 @@ -import * as React from 'react'; -import { useHistory, useRouteMatch } from 'react-router'; +import { MinusCircleTwoTone, PlusCircleTwoTone } from '@ant-design/icons'; +import { NexusClient } from '@bbp/nexus-sdk'; import { AccessControl, useNexusContext } from '@bbp/react-nexus'; -import { useMutation, useQuery } from 'react-query'; -import { Table, Button, Row, Col, notification, Tooltip, Badge } from 'antd'; -import { isArray, isString, orderBy } from 'lodash'; -import { ColumnsType } from 'antd/es/table'; -import { NexusClient, View } from '@bbp/nexus-sdk'; +import * as Sentry from '@sentry/browser'; import { PromisePool } from '@supercharge/promise-pool'; +import { Badge, Button, Col, Row, Table, Tooltip, notification } from 'antd'; +import { ColumnsType } from 'antd/es/table'; +import { isArray, isString, orderBy } from 'lodash'; +import { useMutation, useQuery } from 'react-query'; import { useSelector } from 'react-redux'; -import * as Sentry from '@sentry/browser'; -import { getOrgAndProjectFromProjectId } from '../../../../shared/utils'; -import { RootState } from '../../../../shared/store/reducers'; +import { useHistory, useRouteMatch } from 'react-router'; import HasNoPermission from '../../../../shared/components/Icons/HasNoPermission'; -import './styles.less'; +import { RootState } from '../../../../shared/store/reducers'; +import { getOrgAndProjectFromProjectId } from '../../../../shared/utils'; import { IndexingErrorResults, ViewIndexingErrors, fetchIndexingErrors, } from './ViewIndexingErrors'; -import { - MinusCircleTwoTone, - PlusCircleTwoTone, - WarningOutlined, -} from '@ant-design/icons'; +import './styles.less'; type TViewType = { key: string; @@ -50,8 +45,8 @@ const aggregateFilterPredicate = (type?: string | string[]) => { const fetchViewsList = async ({ nexus, orgLabel, - projectLabel, apiEndpoint, + projectLabel, }: { nexus: NexusClient; orgLabel: string; From 58bd9b0698b11eb0127ee2d59638eb0f8632ca11 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Tue, 19 Dec 2023 16:47:57 +0100 Subject: [PATCH 07/67] Only fetch indexing errors on expand Two type errors are currently still suppressed. I need to fix them. However, the logic works already. --- .../Settings/ViewIndexingErrors.tsx | 6 +- .../components/Settings/ViewsSubView.tsx | 124 ++++++++++++------ 2 files changed, 87 insertions(+), 43 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx index 9f341f5b6..1f8cc8835 100644 --- a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx +++ b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx @@ -64,10 +64,10 @@ export const fetchIndexingErrors = async ({ }; export interface IndexingErrorResults { - '@context': string[] | string; - _next: string; - _results: IndexingError[]; + '@context': any; + _next: any; _total: number; + _results: any[]; } interface IndexingError { diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 1bc3c0449..6fe65f3f7 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -19,7 +19,7 @@ import { } from './ViewIndexingErrors'; import './styles.less'; -type TViewType = { +type SubView = { key: string; id: string; name: string; @@ -45,17 +45,15 @@ const aggregateFilterPredicate = (type?: string | string[]) => { const fetchViewsList = async ({ nexus, orgLabel, - apiEndpoint, projectLabel, }: { nexus: NexusClient; orgLabel: string; projectLabel: string; - apiEndpoint: string; }) => { try { const views = await nexus.View.list(orgLabel, projectLabel, {}); - const result: Omit[] = views._results.map( + const result: Omit[] = views._results.map( item => { const { orgLabel, projectLabel } = getOrgAndProjectFromProjectId( item._project @@ -72,17 +70,10 @@ const fetchViewsList = async ({ }; } ); + const { results, errors } = await PromisePool.withConcurrency(4) .for(result!) .process(async view => { - const indexingErrors = await fetchIndexingErrors({ - nexus, - apiEndpoint, - orgLabel, - projectLabel, - viewId: view.id, - }); - if (!view.isAggregateView) { const iViewStats = await nexus.View.statistics( orgLabel, @@ -97,15 +88,22 @@ const fetchViewsList = async ({ : 0; return { ...view, - indexingErrors, + errors: [], status: percentage ? `${(percentage * 100).toFixed(0)}%` : '0%', + indexingErrors: { + '@context': [], + _next: null, + _total: 0, + _results: [], + }, }; } return { ...view, - indexingErrors, + errors: [], status: 'N/A', + indexingErrors: { _total: 0, _results: [] }, }; }); @@ -157,13 +155,14 @@ const restartIndexOneView = async ({ }); } }; + const restartIndexingAllViews = async ({ nexus, apiEndpoint, views, }: { nexus: NexusClient; - views: TViewType[]; + views: SubView[]; apiEndpoint: string; }) => { const { results, errors } = await PromisePool.withConcurrency(4) @@ -177,6 +176,7 @@ const restartIndexingAllViews = async ({ viewId, }); }); + if (errors.length) { Sentry.captureException('Error restarting views', { extra: { @@ -184,7 +184,7 @@ const restartIndexingAllViews = async ({ }, }); // @ts-ignore - throw new Error('Error captured when reindexing the views', { + throw new Error('Error captured when re-indexing the views', { cause: errors, }); } @@ -211,8 +211,7 @@ const ViewsSubView = () => { }; const { data: views, status } = useQuery({ queryKey: [`views-${orgLabel}-${projectLabel}`], - queryFn: () => - fetchViewsList({ nexus, orgLabel, projectLabel, apiEndpoint }), + queryFn: () => fetchViewsList({ nexus, orgLabel, projectLabel }), refetchInterval: 30 * 1000, // 30s }); @@ -231,7 +230,51 @@ const ViewsSubView = () => { } ); - const columns: ColumnsType = [ + const fetchIndexingErrorsOnDemand = async ({ + nexus, + apiEndpoint, + orgLabel, + projectLabel, + viewId, + }: { + nexus: NexusClient; + apiEndpoint: string; + orgLabel: string; + projectLabel: string; + viewId: string; + }) => { + try { + // Fetch indexing errors for the specified view + const indexingErrors = await fetchIndexingErrors({ + nexus, + apiEndpoint, + orgLabel, + projectLabel, + viewId, + }); + + return indexingErrors; + } catch (error) { + console.error('Error fetching indexing errors on demand', error); + Sentry.captureException(error, { + extra: { + orgLabel, + projectLabel, + viewId, + error, + }, + }); + + return { + '@context': [], + _next: null, + _total: 0, + _results: [], + }; + } + }; + + const columns: ColumnsType = [ { key: 'name', dataIndex: 'name', @@ -375,9 +418,9 @@ const ViewsSubView = () => { handleReindexingAllViews({ nexus, apiEndpoint, - views: - views?.results.filter(item => !item.isAggregateView) || - [], + // TODO Fix this type + // @ts-ignore + views: views?.results.filter(item => !item.isAggregateView), }); }} > @@ -387,11 +430,13 @@ const ViewsSubView = () => { - + loading={status === 'loading'} className="views-table" rowClassName="view-item-row" columns={columns} + // TODO Fix this type + // @ts-ignore dataSource={views?.results} sticky={true} size="middle" @@ -399,26 +444,25 @@ const ViewsSubView = () => { rowKey={r => r.key} expandIcon={({ expanded, onExpand, record }) => expanded ? ( - onExpand(record, e)} - /> + onExpand(record, e)} /> ) : ( - - onExpand(record, e)} - style={{ fontSize: '16px' }} - /> - + { + // Fetch indexing errors when expanding the row + // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) + record.indexingErrors = await fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + }); + onExpand(record, e); + }} + /> ) } - expandedRowRender={(r: TViewType) => { + expandedRowRender={(r: SubView) => { return ( Date: Tue, 19 Dec 2023 17:01:37 +0100 Subject: [PATCH 08/67] Try to fix tests --- .../components/Settings/ViewsSubView.spec.tsx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index 8bd833b92..395dcc253 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -1,16 +1,7 @@ -import { setupServer } from 'msw/node'; -import { QueryClient, QueryClientProvider } from 'react-query'; -import { deltaPath } from '__mocks__/handlers/handlers'; -import configureStore from '../../../../shared/store'; import { createNexusClient } from '@bbp/nexus-sdk'; -import { createMemoryHistory } from 'history'; -import { Provider } from 'react-redux'; -import { Route, Router } from 'react-router-dom'; import { NexusProvider } from '@bbp/react-nexus'; -import ViewsSubView from './ViewsSubView'; -import { render, screen, waitFor } from '../../../../utils/testUtil'; -import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup'; import userEvent from '@testing-library/user-event'; +import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup'; import { aclsHandler, identitiesHandler, @@ -20,6 +11,15 @@ import { viewWithNoIndexingErrors, viewsHandler, } from '__mocks__/handlers/Settings/ViewsSubViewHandlers'; +import { deltaPath } from '__mocks__/handlers/handlers'; +import { createMemoryHistory } from 'history'; +import { setupServer } from 'msw/node'; +import { QueryClient, QueryClientProvider } from 'react-query'; +import { Provider } from 'react-redux'; +import { Route, Router } from 'react-router-dom'; +import configureStore from '../../../../shared/store'; +import { render, screen, waitFor } from '../../../../utils/testUtil'; +import ViewsSubView from './ViewsSubView'; describe('ViewsSubView', () => { const mockOrganisation = 'copies'; @@ -79,14 +79,14 @@ describe('ViewsSubView', () => { expect(getErrorBadgeContent(viewWithIndexingErrors)).toEqual('2'); }); - it('does not show error badge for views that dont have errors', async () => { + it("does not show error badge for views that don't have errors", async () => { expect(getErrorBadgeContent(viewWithNoIndexingErrors)).toBeUndefined(); }); it('shows indexing errors when view row is expanded', async () => { await expandRow(viewWithIndexingErrors); - await screen.getByText(/2 Total errors/i, { selector: 'h3' }); + screen.getByText(/2 Total errors/i, { selector: 'h3' }); const indexingErrorRows = await getErrorRows(); expect(indexingErrorRows.length).toEqual(2); From 9229f3b71b9ae5c2a90dfeed38902f62080f88e6 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 15:34:38 +0100 Subject: [PATCH 09/67] Fix one failing test Two remaining. --- .../components/Settings/ViewsSubView.spec.tsx | 6 +++- .../components/Settings/ViewsSubView.tsx | 36 +++++++++++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index 395dcc253..a7782223d 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -86,7 +86,11 @@ describe('ViewsSubView', () => { it('shows indexing errors when view row is expanded', async () => { await expandRow(viewWithIndexingErrors); - screen.getByText(/2 Total errors/i, { selector: 'h3' }); + await waitFor(() => { + expect( + screen.getByText(/2 Total errors/i, { selector: 'h3' }) + ).toBeInTheDocument(); + }); const indexingErrorRows = await getErrorRows(); expect(indexingErrorRows.length).toEqual(2); diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 6fe65f3f7..ad96effb2 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -446,20 +446,28 @@ const ViewsSubView = () => { expanded ? ( onExpand(record, e)} /> ) : ( - { - // Fetch indexing errors when expanding the row - // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) - record.indexingErrors = await fetchIndexingErrorsOnDemand({ - nexus, - apiEndpoint, - orgLabel: record.orgLabel, - projectLabel: record.projectLabel, - viewId: record.id, - }); - onExpand(record, e); - }} - /> + <> + + { + // Fetch indexing errors when expanding the row + // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) + record.indexingErrors = await fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + }); + onExpand(record, e); + }} + /> + ) } expandedRowRender={(r: SubView) => { From f0c4aac156cee145d142c6e95f15248cc307bae5 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 15:42:41 +0100 Subject: [PATCH 10/67] Anoter try to fix tests --- .../admin/components/Settings/ViewsSubView.spec.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index a7782223d..30f627ffe 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -87,11 +87,14 @@ describe('ViewsSubView', () => { await expandRow(viewWithIndexingErrors); await waitFor(() => { - expect( - screen.getByText(/2 Total errors/i, { selector: 'h3' }) - ).toBeInTheDocument(); + const errorRows = getErrorRows(); + expect(errorRows.length).toEqual(2); }); + expect( + screen.getByText(/2 Total errors/i, { selector: 'h3' }) + ).toBeInTheDocument(); + const indexingErrorRows = await getErrorRows(); expect(indexingErrorRows.length).toEqual(2); From 6bdaf88aab83d2a8c4f13658acb56714e1dac23a Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 15:53:41 +0100 Subject: [PATCH 11/67] Add data test id --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index ad96effb2..926fb2038 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -473,6 +473,7 @@ const ViewsSubView = () => { expandedRowRender={(r: SubView) => { return ( From d04b578e66689a1d03c4f5f7460bc7730af768fb Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 16:39:27 +0100 Subject: [PATCH 12/67] Remove badge overview incl. tests --- .../components/Settings/ViewsSubView.spec.tsx | 13 ------- .../components/Settings/ViewsSubView.tsx | 39 ++++++++----------- 2 files changed, 16 insertions(+), 36 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index 30f627ffe..f899ba1cc 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -75,14 +75,6 @@ describe('ViewsSubView', () => { await expectRowCountToBe(3); }); - it('shows a badge for views that have errors', async () => { - expect(getErrorBadgeContent(viewWithIndexingErrors)).toEqual('2'); - }); - - it("does not show error badge for views that don't have errors", async () => { - expect(getErrorBadgeContent(viewWithNoIndexingErrors)).toBeUndefined(); - }); - it('shows indexing errors when view row is expanded', async () => { await expandRow(viewWithIndexingErrors); @@ -151,9 +143,4 @@ describe('ViewsSubView', () => { const visibleTableRows = () => { return container.querySelectorAll('table tbody tr.view-item-row'); }; - - const getErrorBadgeContent = (rowId: string) => { - const row = getViewRowById(rowId); - return row.querySelector('sup')?.textContent; - }; }); diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 926fb2038..4f85a3e66 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -3,7 +3,7 @@ import { NexusClient } from '@bbp/nexus-sdk'; import { AccessControl, useNexusContext } from '@bbp/react-nexus'; import * as Sentry from '@sentry/browser'; import { PromisePool } from '@supercharge/promise-pool'; -import { Badge, Button, Col, Row, Table, Tooltip, notification } from 'antd'; +import { Button, Col, Row, Table, Tooltip, notification } from 'antd'; import { ColumnsType } from 'antd/es/table'; import { isArray, isString, orderBy } from 'lodash'; import { useMutation, useQuery } from 'react-query'; @@ -446,28 +446,21 @@ const ViewsSubView = () => { expanded ? ( onExpand(record, e)} /> ) : ( - <> - - { - // Fetch indexing errors when expanding the row - // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) - record.indexingErrors = await fetchIndexingErrorsOnDemand({ - nexus, - apiEndpoint, - orgLabel: record.orgLabel, - projectLabel: record.projectLabel, - viewId: record.id, - }); - onExpand(record, e); - }} - /> - + { + // Fetch indexing errors when expanding the row + // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) + record.indexingErrors = await fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + }); + onExpand(record, e); + }} + /> ) } expandedRowRender={(r: SubView) => { From 636071ea5566eb2457915b1eb3cdf11f06bea174 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 16:48:15 +0100 Subject: [PATCH 13/67] Fix unit tests Still some TODOs left to improve this sub view and its logic. --- .../components/Settings/ViewsSubView.spec.tsx | 21 +++++++------------ .../components/Settings/ViewsSubView.tsx | 4 +++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index f899ba1cc..895084016 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -8,7 +8,8 @@ import { viewErrorsHandler, viewStatsHandler, viewWithIndexingErrors, - viewWithNoIndexingErrors, + // TODO Create a test case for a view with no indexing errors + // viewWithNoIndexingErrors, viewsHandler, } from '__mocks__/handlers/Settings/ViewsSubViewHandlers'; import { deltaPath } from '__mocks__/handlers/handlers'; @@ -81,19 +82,13 @@ describe('ViewsSubView', () => { await waitFor(() => { const errorRows = getErrorRows(); expect(errorRows.length).toEqual(2); - }); - - expect( - screen.getByText(/2 Total errors/i, { selector: 'h3' }) - ).toBeInTheDocument(); - - const indexingErrorRows = await getErrorRows(); - expect(indexingErrorRows.length).toEqual(2); + screen.getByText(/2 Total errors/i, { selector: 'h3' }); - const errorRow1 = await getErrorRow('Mock Error 1'); - expect(errorRow1).toBeTruthy(); - const errorRow2 = await getErrorRow('Mock Error 2'); - expect(errorRow2).toBeTruthy(); + const errorRow1 = getErrorRow('Mock Error 1'); + expect(errorRow1).toBeTruthy(); + const errorRow2 = getErrorRow('Mock Error 2'); + expect(errorRow2).toBeTruthy(); + }); }); it('shows detailed error when error row is expanded', async () => { diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 4f85a3e66..d4bf737c2 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -90,6 +90,7 @@ const fetchViewsList = async ({ ...view, errors: [], status: percentage ? `${(percentage * 100).toFixed(0)}%` : '0%', + // TODO Don't return the empty indexing errors, we should fix this in the SDK indexingErrors: { '@context': [], _next: null, @@ -183,7 +184,7 @@ const restartIndexingAllViews = async ({ views, }, }); - // @ts-ignore + // TODO For some reason when there's a faulty view, the error results into removing the view from the list throw new Error('Error captured when re-indexing the views', { cause: errors, }); @@ -446,6 +447,7 @@ const ViewsSubView = () => { expanded ? ( onExpand(record, e)} /> ) : ( + // TODO Is there a way to show the amount of errors? { From f0d6d21cd69cf70c2025f12a7987ffd2ffa55f06 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 16:52:31 +0100 Subject: [PATCH 14/67] Fix build issue with thrown Exception --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index d4bf737c2..1b122540e 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -184,10 +184,7 @@ const restartIndexingAllViews = async ({ views, }, }); - // TODO For some reason when there's a faulty view, the error results into removing the view from the list - throw new Error('Error captured when re-indexing the views', { - cause: errors, - }); + throw new Error('Error restarting views'); } return results; }; From 71315c9ebad3215cd93e2a43731329390653a78d Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 16:55:06 +0100 Subject: [PATCH 15/67] Change error as it was before --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 1b122540e..28003076f 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -184,7 +184,10 @@ const restartIndexingAllViews = async ({ views, }, }); - throw new Error('Error restarting views'); + // @ts-ignore + throw new Error('Error captured when re-indexing the views', { + cause: errors, + }); } return results; }; From 3e95c101cd0e68026f245a830e680d5ac87625ec Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 20 Dec 2023 17:09:52 +0100 Subject: [PATCH 16/67] Clean and add additional bug TODOs --- .../components/Settings/ViewsSubView.tsx | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 28003076f..e28bd4ae7 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -80,7 +80,7 @@ const fetchViewsList = async ({ projectLabel, encodeURIComponent(view.key) ); - // TODO: we should update the type in nexus-sdk! as the response is not the same from delta! + // TODO: We should update the type in nexus-sdk! as the response is not the same from delta! // @ts-ignore const percentage = iViewStats.totalEvents ? // @ts-ignore @@ -88,23 +88,13 @@ const fetchViewsList = async ({ : 0; return { ...view, - errors: [], status: percentage ? `${(percentage * 100).toFixed(0)}%` : '0%', - // TODO Don't return the empty indexing errors, we should fix this in the SDK - indexingErrors: { - '@context': [], - _next: null, - _total: 0, - _results: [], - }, }; } return { ...view, - errors: [], status: 'N/A', - indexingErrors: { _total: 0, _results: [] }, }; }); @@ -125,6 +115,7 @@ const fetchViewsList = async ({ throw new Error('Can not fetch views', { cause: error }); } }; + const restartIndexOneView = async ({ nexus, apiEndpoint, @@ -222,7 +213,7 @@ const ViewsSubView = () => { const { mutateAsync: handleReindexingAllViews, isLoading } = useMutation( restartIndexingAllViews, { - onError: error => { + onError: () => { notification.error({ message: `Error when restarting indexing the views`, description: '', @@ -256,7 +247,13 @@ const ViewsSubView = () => { return indexingErrors; } catch (error) { + // TODO There is some issue with some views that have no indexing errors console.error('Error fetching indexing errors on demand', error); + notification.error({ + message: `Error fetching indexing errors for the selected view`, + description: '', + }); + Sentry.captureException(error, { extra: { orgLabel, From bcbcdfb1cf50d5ac75ab8aa76708abfb73dbe28b Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 3 Jan 2024 15:10:20 +0100 Subject: [PATCH 17/67] Fix issue of undefined indexing errors --- .../Settings/ViewIndexingErrors.tsx | 4 +- .../components/Settings/ViewsSubView.tsx | 38 ++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx index 1f8cc8835..6b40b4ded 100644 --- a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx +++ b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx @@ -14,9 +14,9 @@ export const ViewIndexingErrors: React.FC = ({ return (
{

{indexingErrors._total} Total errors

} - {indexingErrors._total && ( + {indexingErrors._total > 0 && ( diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index e28bd4ae7..60d34027a 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -18,6 +18,8 @@ import { fetchIndexingErrors, } from './ViewIndexingErrors'; import './styles.less'; +import { useState } from 'react'; +import { not } from 'ajv/dist/compile/codegen'; type SubView = { key: string; @@ -197,6 +199,10 @@ const ViewsSubView = () => { params: { orgLabel, projectLabel }, } = match; + const [expandedRows, setExpandedRows] = useState<{ + [key: string]: IndexingErrorResults | undefined; + }>({}); + const createNewViewHandler = () => { const queryURI = `/orgs/${orgLabel}/${projectLabel}/create`; history.push(queryURI); @@ -247,7 +253,6 @@ const ViewsSubView = () => { return indexingErrors; } catch (error) { - // TODO There is some issue with some views that have no indexing errors console.error('Error fetching indexing errors on demand', error); notification.error({ message: `Error fetching indexing errors for the selected view`, @@ -463,11 +468,40 @@ const ViewsSubView = () => { ) } expandedRowRender={(r: SubView) => { + if (!expandedRows[r.key]) { + // Fetch errors if not already fetched for this row + fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: r.orgLabel, + projectLabel: r.projectLabel, + viewId: r.id, + }) + .then(indexingErrors => { + // Update the state with the new errors + setExpandedRows(prevExpandedRows => ({ + ...prevExpandedRows, + [r.key]: indexingErrors, + })); + }) + .catch(error => { + console.error( + `Error fetching indexing errors for view ${r.key}`, + error + ); + notification.error({ + message: `Error fetching indexing errors for view ${r.key}`, + description: '', + }); + }); + return
Loading errors...
; + } + return ( ); }} From e7e9c510f44fabcf697961e52a36a6b23380d91c Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 3 Jan 2024 15:22:56 +0100 Subject: [PATCH 18/67] Fix type errors --- .../admin/components/Settings/ViewsSubView.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 60d34027a..2c018477b 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -421,9 +421,9 @@ const ViewsSubView = () => { handleReindexingAllViews({ nexus, apiEndpoint, - // TODO Fix this type - // @ts-ignore - views: views?.results.filter(item => !item.isAggregateView), + views: views?.results.filter( + item => item.isAggregateView + ) as SubView[], }); }} > @@ -438,9 +438,7 @@ const ViewsSubView = () => { className="views-table" rowClassName="view-item-row" columns={columns} - // TODO Fix this type - // @ts-ignore - dataSource={views?.results} + dataSource={views?.results as SubView[]} sticky={true} size="middle" pagination={false} @@ -449,7 +447,6 @@ const ViewsSubView = () => { expanded ? ( onExpand(record, e)} /> ) : ( - // TODO Is there a way to show the amount of errors? { From 4b6a4dfc50df19767d0b07c7f61ba40ac53e3699 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 3 Jan 2024 15:40:14 +0100 Subject: [PATCH 19/67] Pinpoint failing unit test (add TODO) --- src/subapps/admin/components/Settings/ViewsSubView.spec.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index 895084016..cd9b6aa4b 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -91,6 +91,7 @@ describe('ViewsSubView', () => { }); }); + // TODO Fix this test it('shows detailed error when error row is expanded', async () => { await expandRow(viewWithIndexingErrors); From 384e8f8564d3bfce5f2734a8970aa8fa6a92800b Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 3 Jan 2024 15:43:55 +0100 Subject: [PATCH 20/67] Fix unit test by making it async --- .../admin/components/Settings/ViewsSubView.spec.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index cd9b6aa4b..3e91baa2c 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -91,19 +91,22 @@ describe('ViewsSubView', () => { }); }); - // TODO Fix this test it('shows detailed error when error row is expanded', async () => { await expandRow(viewWithIndexingErrors); const errorRow1 = await getErrorRow('Mock Error 1'); await user.click(errorRow1); - const detailedErrorContainer = container.querySelector('.react-json-view'); - expect(detailedErrorContainer).toBeTruthy(); + await waitFor(() => { + const detailedErrorContainer = container.querySelector( + '.react-json-view' + ); + expect(detailedErrorContainer).toBeTruthy(); + }); }); const getErrorRow = async (errorMessage: string) => { - const row = await screen.getByText(new RegExp(errorMessage, 'i'), { + const row = await screen.findByText(new RegExp(errorMessage, 'i'), { selector: '.ant-collapse-header-text', }); return row; From 6b5efe8b307b77ee1a0551ab43ec7dfc0638ca7c Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:40:41 +0100 Subject: [PATCH 21/67] Change conditional based on PR feedback --- src/subapps/admin/components/Settings/ViewIndexingErrors.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx index 6b40b4ded..3ff068ee8 100644 --- a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx +++ b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx @@ -14,7 +14,7 @@ export const ViewIndexingErrors: React.FC = ({ return (
{

{indexingErrors._total} Total errors

} - {indexingErrors._total > 0 && ( + {!!indexingErrors._total && ( Date: Thu, 4 Jan 2024 11:46:47 +0100 Subject: [PATCH 22/67] Revert type changes to previous ones --- .../admin/components/Settings/ViewIndexingErrors.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx index 3ff068ee8..339d8a23a 100644 --- a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx +++ b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx @@ -64,10 +64,10 @@ export const fetchIndexingErrors = async ({ }; export interface IndexingErrorResults { - '@context': any; - _next: any; + '@context'?: string[] | string; + _next: string; _total: number; - _results: any[]; + _results: IndexingError[]; } interface IndexingError { From c87782e047ae4f94c8127cff04af4f3b92fd07c2 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:47:01 +0100 Subject: [PATCH 23/67] Fix linter issue --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 2c018477b..e223d2c50 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -30,7 +30,9 @@ type SubView = { orgLabel: string; projectLabel: string; isAggregateView: boolean; - indexingErrors: IndexingErrorResults; + indexingErrors: + | IndexingErrorResults + | { '@context': never[]; _next: null; _total: number; _results: never[] }; }; const AggregateViews = ['AggregateElasticSearchView', 'AggregateSparqlView']; @@ -478,7 +480,7 @@ const ViewsSubView = () => { // Update the state with the new errors setExpandedRows(prevExpandedRows => ({ ...prevExpandedRows, - [r.key]: indexingErrors, + [r.key]: indexingErrors as IndexingErrorResults, })); }) .catch(error => { From 2fb8441329fb1c7d22000d3fa3c17983f9d4ef57 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:54:27 +0100 Subject: [PATCH 24/67] Remove unused import --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index e223d2c50..c45680079 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -19,7 +19,6 @@ import { } from './ViewIndexingErrors'; import './styles.less'; import { useState } from 'react'; -import { not } from 'ajv/dist/compile/codegen'; type SubView = { key: string; From de5dd4b488cd1fcce0be83fbb1713db4bb36a55c Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:54:41 +0100 Subject: [PATCH 25/67] Don't return an empty object on error --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index c45680079..570650f50 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -269,12 +269,7 @@ const ViewsSubView = () => { }, }); - return { - '@context': [], - _next: null, - _total: 0, - _results: [], - }; + return null; } }; From 36a86597a5e28caac92e7ebfa76c7902ddb75956 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:54:48 +0100 Subject: [PATCH 26/67] Change types accordingly --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 570650f50..d1d8c880d 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -29,9 +29,7 @@ type SubView = { orgLabel: string; projectLabel: string; isAggregateView: boolean; - indexingErrors: - | IndexingErrorResults - | { '@context': never[]; _next: null; _total: number; _results: never[] }; + indexingErrors: IndexingErrorResults | null; }; const AggregateViews = ['AggregateElasticSearchView', 'AggregateSparqlView']; From ffa753547f46907078d9e5287f9b06e6712cc141 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Thu, 4 Jan 2024 11:54:57 +0100 Subject: [PATCH 27/67] Also send exception to Sentry --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index d1d8c880d..f9a533115 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -218,7 +218,15 @@ const ViewsSubView = () => { const { mutateAsync: handleReindexingAllViews, isLoading } = useMutation( restartIndexingAllViews, { - onError: () => { + onError: error => { + Sentry.captureException(error, { + extra: { + orgLabel, + projectLabel, + error, + }, + }); + notification.error({ message: `Error when restarting indexing the views`, description: '', From d1179fc326e6c76adbddc0a83384deb3884f124f Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Sun, 7 Jan 2024 11:08:02 +0100 Subject: [PATCH 28/67] Change display of error view --- .../components/Settings/ViewIndexingErrors.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx index 339d8a23a..43867e60b 100644 --- a/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx +++ b/src/subapps/admin/components/Settings/ViewIndexingErrors.tsx @@ -13,14 +13,17 @@ export const ViewIndexingErrors: React.FC = ({ }: Props) => { return (
- {

{indexingErrors._total} Total errors

} {!!indexingErrors._total && ( - + <> +

{indexingErrors._total} Total errors

+ + )} + Date: Sun, 7 Jan 2024 11:09:40 +0100 Subject: [PATCH 29/67] Change assertion in unit test --- src/subapps/admin/components/Settings/ViewsSubView.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index 3e91baa2c..b40344dd9 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -85,7 +85,7 @@ describe('ViewsSubView', () => { screen.getByText(/2 Total errors/i, { selector: 'h3' }); const errorRow1 = getErrorRow('Mock Error 1'); - expect(errorRow1).toBeTruthy(); + expect(errorRow1).toBeVisible(); const errorRow2 = getErrorRow('Mock Error 2'); expect(errorRow2).toBeTruthy(); }); From da84ecc01078c21a44cf261f9d36999e38f11685 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Sun, 7 Jan 2024 11:16:25 +0100 Subject: [PATCH 30/67] Remove console.log --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index f9a533115..21dffc5f8 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -484,10 +484,6 @@ const ViewsSubView = () => { })); }) .catch(error => { - console.error( - `Error fetching indexing errors for view ${r.key}`, - error - ); notification.error({ message: `Error fetching indexing errors for view ${r.key}`, description: '', From bc7b0ceab9e432839bb79d50d835b442fedbda09 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Sun, 7 Jan 2024 11:23:05 +0100 Subject: [PATCH 31/67] Remove type casting and be more explicit --- .../components/Settings/ViewsSubView.tsx | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 21dffc5f8..c28636415 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -2,7 +2,7 @@ import { MinusCircleTwoTone, PlusCircleTwoTone } from '@ant-design/icons'; import { NexusClient } from '@bbp/nexus-sdk'; import { AccessControl, useNexusContext } from '@bbp/react-nexus'; import * as Sentry from '@sentry/browser'; -import { PromisePool } from '@supercharge/promise-pool'; +import { PromisePool, PromisePoolError } from '@supercharge/promise-pool'; import { Button, Col, Row, Table, Tooltip, notification } from 'antd'; import { ColumnsType } from 'antd/es/table'; import { isArray, isString, orderBy } from 'lodash'; @@ -51,26 +51,28 @@ const fetchViewsList = async ({ nexus: NexusClient; orgLabel: string; projectLabel: string; -}) => { +}): Promise<{ + errors: PromisePoolError[]; + results: SubView[]; +}> => { try { const views = await nexus.View.list(orgLabel, projectLabel, {}); - const result: Omit[] = views._results.map( - item => { - const { orgLabel, projectLabel } = getOrgAndProjectFromProjectId( - item._project - )!; - return { - orgLabel, - projectLabel, - id: item['@id'], - key: item['@id'] as string, - name: (item['@id'] as string).split('/').pop() as string, - type: item['@type'], - isAggregateView: aggregateFilterPredicate(item['@type']), - status: '100%', - }; - } - ); + const result: SubView[] = views._results.map(item => { + const { orgLabel, projectLabel } = getOrgAndProjectFromProjectId( + item._project + )!; + return { + orgLabel, + projectLabel, + id: item['@id'], + key: item['@id'] as string, + name: (item['@id'] as string).split('/').pop() as string, + type: item['@type'], + isAggregateView: aggregateFilterPredicate(item['@type']), + status: '100%', + indexingErrors: null, + }; + }); const { results, errors } = await PromisePool.withConcurrency(4) .for(result!) @@ -423,9 +425,8 @@ const ViewsSubView = () => { handleReindexingAllViews({ nexus, apiEndpoint, - views: views?.results.filter( - item => item.isAggregateView - ) as SubView[], + views: + views?.results.filter(item => item.isAggregateView) || [], }); }} > @@ -440,7 +441,7 @@ const ViewsSubView = () => { className="views-table" rowClassName="view-item-row" columns={columns} - dataSource={views?.results as SubView[]} + dataSource={views?.results} sticky={true} size="middle" pagination={false} From 22775a4b53e3502b511609a5941887af3846354a Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Sun, 7 Jan 2024 11:25:09 +0100 Subject: [PATCH 32/67] Remove another unnecessary console.error --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index c28636415..425103955 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -262,7 +262,6 @@ const ViewsSubView = () => { return indexingErrors; } catch (error) { - console.error('Error fetching indexing errors on demand', error); notification.error({ message: `Error fetching indexing errors for the selected view`, description: '', From d0944eeb7160b0609e42825b647d7b8f5aa8c20f Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Sun, 7 Jan 2024 11:31:41 +0100 Subject: [PATCH 33/67] Add TODO for weird unfocus fetch issue --- src/subapps/admin/components/Settings/ViewsSubView.spec.tsx | 1 - src/subapps/admin/components/Settings/ViewsSubView.tsx | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index b40344dd9..b32bb494a 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -85,7 +85,6 @@ describe('ViewsSubView', () => { screen.getByText(/2 Total errors/i, { selector: 'h3' }); const errorRow1 = getErrorRow('Mock Error 1'); - expect(errorRow1).toBeVisible(); const errorRow2 = getErrorRow('Mock Error 2'); expect(errorRow2).toBeTruthy(); }); diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 425103955..1eabe7cb3 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -445,6 +445,7 @@ const ViewsSubView = () => { size="middle" pagination={false} rowKey={r => r.key} + // TODO Somehow, when window is unfocused, the expanded row function is called three times expandIcon={({ expanded, onExpand, record }) => expanded ? ( onExpand(record, e)} /> From 604947d3fbbe7aac6630a3342d28da167ad962ba Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 8 Jan 2024 10:53:37 +0100 Subject: [PATCH 34/67] Remove unused `error` argument --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 1eabe7cb3..743ef5865 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -484,7 +484,7 @@ const ViewsSubView = () => { [r.key]: indexingErrors as IndexingErrorResults, })); }) - .catch(error => { + .catch(() => { notification.error({ message: `Error fetching indexing errors for view ${r.key}`, description: '', From 4790d5202de142da582321816aae1f1c87a39cd4 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 8 Jan 2024 12:05:13 +0100 Subject: [PATCH 35/67] Pinpoint lines of errors/confusion --- src/subapps/admin/components/Settings/ViewsSubView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 743ef5865..5eef5fa76 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -445,7 +445,6 @@ const ViewsSubView = () => { size="middle" pagination={false} rowKey={r => r.key} - // TODO Somehow, when window is unfocused, the expanded row function is called three times expandIcon={({ expanded, onExpand, record }) => expanded ? ( onExpand(record, e)} /> @@ -455,6 +454,7 @@ const ViewsSubView = () => { onClick={async e => { // Fetch indexing errors when expanding the row // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) + // TODO Fix when called first time, it should not run multiple times record.indexingErrors = await fetchIndexingErrorsOnDemand({ nexus, apiEndpoint, @@ -469,6 +469,7 @@ const ViewsSubView = () => { } expandedRowRender={(r: SubView) => { if (!expandedRows[r.key]) { + // TODO Fix when called first time, it should not run multiple times // Fetch errors if not already fetched for this row fetchIndexingErrorsOnDemand({ nexus, From b9917d73ff41710fa41500f5a942abb0cb92485a Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 8 Jan 2024 13:45:05 +0100 Subject: [PATCH 36/67] Update snapshot --- .../JIRA/__tests__/__snapshots__/JIRA.spec.tsx.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shared/components/JIRA/__tests__/__snapshots__/JIRA.spec.tsx.snap b/src/shared/components/JIRA/__tests__/__snapshots__/JIRA.spec.tsx.snap index 9fc21517c..412c8a77c 100644 --- a/src/shared/components/JIRA/__tests__/__snapshots__/JIRA.spec.tsx.snap +++ b/src/shared/components/JIRA/__tests__/__snapshots__/JIRA.spec.tsx.snap @@ -275,7 +275,7 @@ exports[`JIRA renders with issues 1`] = ` - 3 years ago + 4 years ago - 3 years ago + 4 years ago Date: Mon, 8 Jan 2024 14:42:25 +0100 Subject: [PATCH 37/67] Fix over-fetching issue TODO: Remaining that it should reload in case of re-opening it again. --- .../components/Settings/ViewsSubView.tsx | 99 +++++++++---------- 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 5eef5fa76..53d8ab831 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -445,62 +445,51 @@ const ViewsSubView = () => { size="middle" pagination={false} rowKey={r => r.key} - expandIcon={({ expanded, onExpand, record }) => - expanded ? ( - onExpand(record, e)} /> - ) : ( - { - // Fetch indexing errors when expanding the row - // We do this on demand to avoid fetching all indexing errors for all views at once (which can be a lot) - // TODO Fix when called first time, it should not run multiple times - record.indexingErrors = await fetchIndexingErrorsOnDemand({ - nexus, - apiEndpoint, - orgLabel: record.orgLabel, - projectLabel: record.projectLabel, - viewId: record.id, - }); - onExpand(record, e); - }} - /> - ) - } - expandedRowRender={(r: SubView) => { - if (!expandedRows[r.key]) { - // TODO Fix when called first time, it should not run multiple times - // Fetch errors if not already fetched for this row - fetchIndexingErrorsOnDemand({ - nexus, - apiEndpoint, - orgLabel: r.orgLabel, - projectLabel: r.projectLabel, - viewId: r.id, - }) - .then(indexingErrors => { - // Update the state with the new errors - setExpandedRows(prevExpandedRows => ({ - ...prevExpandedRows, - [r.key]: indexingErrors as IndexingErrorResults, - })); - }) - .catch(() => { - notification.error({ - message: `Error fetching indexing errors for view ${r.key}`, - description: '', - }); - }); - return
Loading errors...
; + expandIcon={({ expanded, onExpand, record }) => { + if (expanded) { + return onExpand(record, e)} />; + } else { + const alreadyFetchedErrors = expandedRows[record.key]; + return ( + { + if (!alreadyFetchedErrors) { + // Only fetch errors if not already present + record.indexingErrors = await fetchIndexingErrorsOnDemand( + { + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + } + ); + setExpandedRows(prevExpandedRows => ({ + ...prevExpandedRows, + [record.key]: record.indexingErrors || undefined, + })); + } + onExpand(record, e); + }} + /> + ); + } + }} + expandedRowRender={record => { + const indexingErrors = expandedRows[record.key]; + if (!indexingErrors) { + // Fallback content in case errors haven't been set yet + return

Loading errors...

; + } else { + return ( + + ); } - - return ( - - ); }} />
From fdfc69267ebb88d1cf6cff20e4244ad541f25bee Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 8 Jan 2024 14:46:34 +0100 Subject: [PATCH 38/67] Change TODOs --- src/subapps/admin/components/Settings/ViewsSubView.spec.tsx | 2 -- src/subapps/admin/components/Settings/ViewsSubView.tsx | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx index b32bb494a..e45ea9738 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.spec.tsx @@ -8,8 +8,6 @@ import { viewErrorsHandler, viewStatsHandler, viewWithIndexingErrors, - // TODO Create a test case for a view with no indexing errors - // viewWithNoIndexingErrors, viewsHandler, } from '__mocks__/handlers/Settings/ViewsSubViewHandlers'; import { deltaPath } from '__mocks__/handlers/handlers'; diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 53d8ab831..70c4ea9db 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -449,6 +449,7 @@ const ViewsSubView = () => { if (expanded) { return onExpand(record, e)} />; } else { + // TODO In case of reopening the row, we should not fetch the errors again const alreadyFetchedErrors = expandedRows[record.key]; return ( Date: Mon, 8 Jan 2024 14:57:12 +0100 Subject: [PATCH 39/67] Remove unnecessary else statements --- .../components/Settings/ViewsSubView.tsx | 66 +++++++++---------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 70c4ea9db..3b2577614 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -448,49 +448,45 @@ const ViewsSubView = () => { expandIcon={({ expanded, onExpand, record }) => { if (expanded) { return onExpand(record, e)} />; - } else { - // TODO In case of reopening the row, we should not fetch the errors again - const alreadyFetchedErrors = expandedRows[record.key]; - return ( - { - if (!alreadyFetchedErrors) { - // Only fetch errors if not already present - record.indexingErrors = await fetchIndexingErrorsOnDemand( - { - nexus, - apiEndpoint, - orgLabel: record.orgLabel, - projectLabel: record.projectLabel, - viewId: record.id, - } - ); - setExpandedRows(prevExpandedRows => ({ - ...prevExpandedRows, - [record.key]: record.indexingErrors || undefined, - })); - } - onExpand(record, e); - }} - /> - ); } + // TODO In case of reopening the row, we should not fetch the errors again + const alreadyFetchedErrors = expandedRows[record.key]; + return ( + { + if (!alreadyFetchedErrors) { + // Only fetch errors if not already present + record.indexingErrors = await fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + }); + setExpandedRows(prevExpandedRows => ({ + ...prevExpandedRows, + [record.key]: record.indexingErrors || undefined, + })); + } + onExpand(record, e); + }} + /> + ); }} expandedRowRender={record => { const indexingErrors = expandedRows[record.key]; if (!indexingErrors) { // Fallback content in case errors haven't been set yet return

Loading errors...

; - } else { - return ( - - ); } + return ( + + ); }} />
From 4b819767eef0e59a64b7addc6ba3e10bbb4b4afb Mon Sep 17 00:00:00 2001 From: Bilal Meddah Date: Tue, 9 Jan 2024 16:39:13 +0100 Subject: [PATCH 40/67] fix: remove duplicated tag resource button --- .../ResourceViewActionsContainer.tsx | 56 ------------------- 1 file changed, 56 deletions(-) diff --git a/src/shared/containers/ResourceViewActionsContainer.tsx b/src/shared/containers/ResourceViewActionsContainer.tsx index 857786669..fdc229b22 100644 --- a/src/shared/containers/ResourceViewActionsContainer.tsx +++ b/src/shared/containers/ResourceViewActionsContainer.tsx @@ -453,62 +453,6 @@ const ResourceViewActionsContainer: React.FC<{ - - -
Tag Resource
- - The tag will be applied to revision{' '} - {resource._rev} - -
- } - content={ - - autoComplete="off" - name="tag-resource-form" - initialValues={{ tag: '' }} - onFinish={handleTagResource} - style={{ width: 300, padding: '8px 8px O' }} - > - - - - - - - - } - > - - - {view && ( From 0350fc1959ca412e949efab648af21131498c3f6 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 10 Jan 2024 11:18:53 +0100 Subject: [PATCH 41/67] Fetch errors every time the row is expanded --- .../components/Settings/ViewsSubView.tsx | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/subapps/admin/components/Settings/ViewsSubView.tsx b/src/subapps/admin/components/Settings/ViewsSubView.tsx index 3b2577614..db586d260 100644 --- a/src/subapps/admin/components/Settings/ViewsSubView.tsx +++ b/src/subapps/admin/components/Settings/ViewsSubView.tsx @@ -449,26 +449,23 @@ const ViewsSubView = () => { if (expanded) { return onExpand(record, e)} />; } - // TODO In case of reopening the row, we should not fetch the errors again - const alreadyFetchedErrors = expandedRows[record.key]; + return ( { - if (!alreadyFetchedErrors) { - // Only fetch errors if not already present - record.indexingErrors = await fetchIndexingErrorsOnDemand({ - nexus, - apiEndpoint, - orgLabel: record.orgLabel, - projectLabel: record.projectLabel, - viewId: record.id, - }); - setExpandedRows(prevExpandedRows => ({ - ...prevExpandedRows, - [record.key]: record.indexingErrors || undefined, - })); - } + // Fetch errors every time the row is expanded + record.indexingErrors = await fetchIndexingErrorsOnDemand({ + nexus, + apiEndpoint, + orgLabel: record.orgLabel, + projectLabel: record.projectLabel, + viewId: record.id, + }); + setExpandedRows(prevExpandedRows => ({ + ...prevExpandedRows, + [record.key]: record.indexingErrors || undefined, + })); onExpand(record, e); }} /> From 4802179dac7711c420e7513d83213d851cfd5698 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 10 Jan 2024 11:32:08 +0100 Subject: [PATCH 42/67] Show undo deprecation button for other types --- src/shared/containers/ResourceViewContainer.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index f520ff2b8..9b4901c94 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -772,9 +772,7 @@ const ResourceViewContainer: FC<{ {// Don't show the undo deprecated button if the resource is // of any unsupported resource. However, it needs to be shown // e.g. for custom types of resources. - !resource['@type']?.includes( - 'View' || 'Resolver' || 'Storage' || 'Schema' - ) ? ( + !resource['@type']?.includes('Resolver') ? ( <>
{// If not newest revision, then don't show the button From 123340e4e6ef66cab4768456d5d39b340367a8b1 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 10 Jan 2024 11:38:40 +0100 Subject: [PATCH 43/67] Add TODO --- src/shared/containers/ResourceViewContainer.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 9b4901c94..f3f28b4e9 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -784,6 +784,7 @@ const ResourceViewContainer: FC<{ marginBottom: '5px', }} onClick={() => { + // TODO Shows the button correctly, but the undoing of the deprecation doesn't work unDeprecateResource(); }} > From fb80f31145d59daa802ccb8cb50dd480af28a14a Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 10 Jan 2024 15:31:30 +0100 Subject: [PATCH 44/67] Make undeprecate work However, it is not a very clean implementation. I need to re-work this. --- src/shared/containers/ResourceViewContainer.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index f3f28b4e9..dad2e1db1 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -69,9 +69,16 @@ function constructUnDeprecateUrl( projectLabel: string ) { return `${apiEndpoint}/${ - resource!['@type'] === 'File' ? 'files' : 'resources' + resource!['@type']?.includes('File') + ? 'files' + : resource!['@type']?.includes('Storage') + ? 'storages' + : 'resources' }/${orgLabel}/${projectLabel}/${ - resource!['@type'] === 'File' ? '' : '_/' + resource!['@type']?.includes('Storage') || + resource!['@type']?.includes('File') + ? '' + : '_/' }${encodeURIComponent(resource!['@id'])}/undeprecate?rev=${ latestResource!._rev }`; From d350aa6f8cfa61a4efed4eb837d4124730cd8d17 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 10:31:59 +0100 Subject: [PATCH 45/67] Hide button for other types and remove TODO --- src/shared/containers/ResourceViewContainer.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index dad2e1db1..e7fb597e7 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -777,9 +777,13 @@ const ResourceViewContainer: FC<{ This resource is deprecated and not modifiable. {// Don't show the undo deprecated button if the resource is - // of any unsupported resource. However, it needs to be shown - // e.g. for custom types of resources. - !resource['@type']?.includes('Resolver') ? ( + // of any unsupported resource (e.g. Resolver). However, it needs + // to be shown e.g. for custom types of resources. + !resource['@type']?.includes( + 'Resolver' || + 'AggregateElasticSearchView' || + 'AggregateSparqlView' + ) ? ( <>
{// If not newest revision, then don't show the button @@ -791,7 +795,6 @@ const ResourceViewContainer: FC<{ marginBottom: '5px', }} onClick={() => { - // TODO Shows the button correctly, but the undoing of the deprecation doesn't work unDeprecateResource(); }} > From 18a343b532f39a9f88b9949de60c5617220df7a2 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 10:37:33 +0100 Subject: [PATCH 46/67] Make undeprecation work for all other types --- src/shared/containers/ResourceViewContainer.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index e7fb597e7..105dd8059 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -73,10 +73,16 @@ function constructUnDeprecateUrl( ? 'files' : resource!['@type']?.includes('Storage') ? 'storages' + : resource!['@type']?.includes('View') + ? 'views' + : resource!['@type']?.includes('Schema') + ? 'schemas' : 'resources' }/${orgLabel}/${projectLabel}/${ resource!['@type']?.includes('Storage') || - resource!['@type']?.includes('File') + resource!['@type']?.includes('File') || + resource!['@type']?.includes('View') || + resource!['@type']?.includes('Schema') ? '' : '_/' }${encodeURIComponent(resource!['@id'])}/undeprecate?rev=${ From c3e973b7cbeca127ebe7682b62ee4d6c9da0415c Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 10:40:52 +0100 Subject: [PATCH 47/67] Add TODOs --- src/shared/containers/ResourceViewContainer.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 105dd8059..200da4cbb 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -68,6 +68,7 @@ function constructUnDeprecateUrl( orgLabel: string, projectLabel: string ) { + // TODO Make this function more generic return `${apiEndpoint}/${ resource!['@type']?.includes('File') ? 'files' @@ -801,6 +802,7 @@ const ResourceViewContainer: FC<{ marginBottom: '5px', }} onClick={() => { + // TODO Component doesn't reload after undoing deprecation when on side-panel view unDeprecateResource(); }} > From a20ceff0d9eadca89af391063bd17f16452c8f82 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 10:55:25 +0100 Subject: [PATCH 48/67] Make construct URL function more generic However, doesn't work now if there are two resource types, such as `ElasticSearchView` and `View`. Need to fix this in the coming commit(s). --- .../containers/ResourceViewContainer.tsx | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 200da4cbb..d64cd00a8 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -67,28 +67,37 @@ function constructUnDeprecateUrl( latestResource: Resource, orgLabel: string, projectLabel: string -) { - // TODO Make this function more generic - return `${apiEndpoint}/${ - resource!['@type']?.includes('File') - ? 'files' - : resource!['@type']?.includes('Storage') - ? 'storages' - : resource!['@type']?.includes('View') - ? 'views' - : resource!['@type']?.includes('Schema') - ? 'schemas' - : 'resources' - }/${orgLabel}/${projectLabel}/${ - resource!['@type']?.includes('Storage') || - resource!['@type']?.includes('File') || - resource!['@type']?.includes('View') || - resource!['@type']?.includes('Schema') - ? '' - : '_/' - }${encodeURIComponent(resource!['@id'])}/undeprecate?rev=${ - latestResource!._rev - }`; +): string { + const typeToPathSegment = (type: string): string => { + switch (type) { + case 'File': + return 'files'; + case 'Storage': + return 'storages'; + case 'View' || 'ElasticSearchView' || 'SparqlView': + return 'views'; + case 'Schema': + return 'schemas'; + default: + return 'resources'; + } + }; + + const resourceType = Array.isArray(resource['@type']) + resource['@type'][0] + : resource['@type']; + const resourcePathSegment = resourceType + ? typeToPathSegment(resourceType) + : 'resources'; + const slashPrefix = ['Storage', 'File', 'View', 'Schema'].includes( + resourceType || '' + ) + ? '' + : '_/'; + + return `${apiEndpoint}/${resourcePathSegment}/${orgLabel}/${projectLabel}/${slashPrefix}${encodeURIComponent( + resource['@id'] + )}/undeprecate?rev=${latestResource._rev}`; } const ResourceViewContainer: FC<{ From 14868818576742039c0093f92b2f674ca658fbb7 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 15:41:52 +0100 Subject: [PATCH 49/67] Make undeprecation work for all types --- .../containers/ResourceViewContainer.tsx | 41 ++++++++++++++----- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index d64cd00a8..830292fd5 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -74,7 +74,10 @@ function constructUnDeprecateUrl( return 'files'; case 'Storage': return 'storages'; - case 'View' || 'ElasticSearchView' || 'SparqlView': + case 'ElasticSearchView': + case 'SparqlView': + case 'CompositeView': + case 'View': return 'views'; case 'Schema': return 'schemas'; @@ -83,15 +86,34 @@ function constructUnDeprecateUrl( } }; - const resourceType = Array.isArray(resource['@type']) - resource['@type'][0] - : resource['@type']; - const resourcePathSegment = resourceType - ? typeToPathSegment(resourceType) + // Determine the primary type for resource path segment + const determinePrimaryType = (types: string | string[]): string => { + if (Array.isArray(types)) { + // Prioritize specific view types over generic 'View' + const viewType = types.find(type => + ['ElasticSearchView', 'SparqlView', 'CompositeView', 'View'].includes( + type + ) + ); + return viewType || types[0]; + } + return types; + }; + + const primaryResourceType = determinePrimaryType(resource['@type'] || ''); + const resourcePathSegment = primaryResourceType + ? typeToPathSegment(primaryResourceType) : 'resources'; - const slashPrefix = ['Storage', 'File', 'View', 'Schema'].includes( - resourceType || '' - ) + + const slashPrefix = [ + 'Storage', + 'File', + 'View', + 'Schema', + 'ElasticSearchView', + 'SparqlView', + 'CompositeView', + ].includes(primaryResourceType) ? '' : '_/'; @@ -811,7 +833,6 @@ const ResourceViewContainer: FC<{ marginBottom: '5px', }} onClick={() => { - // TODO Component doesn't reload after undoing deprecation when on side-panel view unDeprecateResource(); }} > From 456e7621c06c0719432a862b227f7f081fac2998 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 16:10:16 +0100 Subject: [PATCH 50/67] Make construct URL function DRY --- .../containers/ResourceViewContainer.tsx | 70 ++++++++----------- 1 file changed, 29 insertions(+), 41 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 830292fd5..6baf3b5eb 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -68,52 +68,40 @@ function constructUnDeprecateUrl( orgLabel: string, projectLabel: string ): string { - const typeToPathSegment = (type: string): string => { - switch (type) { - case 'File': - return 'files'; - case 'Storage': - return 'storages'; - case 'ElasticSearchView': - case 'SparqlView': - case 'CompositeView': - case 'View': - return 'views'; - case 'Schema': - return 'schemas'; - default: - return 'resources'; - } + const typePathMapping: { [key: string]: string } = { + File: 'files', + Storage: 'storages', + ElasticSearchView: 'views', + SparqlView: 'views', + CompositeView: 'views', + View: 'views', + Schema: 'schemas', }; - // Determine the primary type for resource path segment - const determinePrimaryType = (types: string | string[]): string => { - if (Array.isArray(types)) { - // Prioritize specific view types over generic 'View' - const viewType = types.find(type => - ['ElasticSearchView', 'SparqlView', 'CompositeView', 'View'].includes( - type - ) - ); - return viewType || types[0]; + const determineResourcePathSegment = (types: string | string[]): string => { + if (!Array.isArray(types)) { + types = [types]; } - return types; + + // Check each type and select the most specific one that has a mapping + for (const type of types) { + if (type in typePathMapping) { + return typePathMapping[type]; + } + } + + return 'resources'; }; - const primaryResourceType = determinePrimaryType(resource['@type'] || ''); - const resourcePathSegment = primaryResourceType - ? typeToPathSegment(primaryResourceType) - : 'resources'; - - const slashPrefix = [ - 'Storage', - 'File', - 'View', - 'Schema', - 'ElasticSearchView', - 'SparqlView', - 'CompositeView', - ].includes(primaryResourceType) + const primaryResourceType = resource['@type'] || ''; + const resourcePathSegment = determineResourcePathSegment(primaryResourceType); + const slashPrefix = Array.isArray(primaryResourceType) + ? primaryResourceType.some(type => + Object.keys(typePathMapping).includes(type) + ) + ? '' + : '_/' + : Object.keys(typePathMapping).includes(primaryResourceType) ? '' : '_/'; From d3f6c5e6583ed756a0f10128387154e0fd01f0a6 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 16:12:36 +0100 Subject: [PATCH 51/67] Fix linter type issue --- src/shared/containers/ResourceViewContainer.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 6baf3b5eb..40a4a2c39 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -78,10 +78,10 @@ function constructUnDeprecateUrl( Schema: 'schemas', }; - const determineResourcePathSegment = (types: string | string[]): string => { - if (!Array.isArray(types)) { - types = [types]; - } + const determineResourcePathSegment = ( + inputTypes: string | string[] + ): string => { + const types = Array.isArray(inputTypes) ? inputTypes : [inputTypes]; // Check each type and select the most specific one that has a mapping for (const type of types) { From b6a8fedf657126b01836f9a2235d4cc10bd66207 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Fri, 12 Jan 2024 16:14:11 +0100 Subject: [PATCH 52/67] Remove incorrect leftover comment --- src/shared/containers/ResourceViewContainer.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index 40a4a2c39..c3889425f 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -83,7 +83,6 @@ function constructUnDeprecateUrl( ): string => { const types = Array.isArray(inputTypes) ? inputTypes : [inputTypes]; - // Check each type and select the most specific one that has a mapping for (const type of types) { if (type in typePathMapping) { return typePathMapping[type]; From a15e5f1d5c46159ec0688e7890b862e60d8dbabd Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Mon, 15 Jan 2024 10:07:16 +0100 Subject: [PATCH 53/67] Improve lookup from `O(n)` to `O(1)` --- src/shared/containers/ResourceViewContainer.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/shared/containers/ResourceViewContainer.tsx b/src/shared/containers/ResourceViewContainer.tsx index c3889425f..3fbb8ae65 100644 --- a/src/shared/containers/ResourceViewContainer.tsx +++ b/src/shared/containers/ResourceViewContainer.tsx @@ -95,12 +95,10 @@ function constructUnDeprecateUrl( const primaryResourceType = resource['@type'] || ''; const resourcePathSegment = determineResourcePathSegment(primaryResourceType); const slashPrefix = Array.isArray(primaryResourceType) - ? primaryResourceType.some(type => - Object.keys(typePathMapping).includes(type) - ) + ? primaryResourceType.some(type => type in typePathMapping) ? '' : '_/' - : Object.keys(typePathMapping).includes(primaryResourceType) + : primaryResourceType in typePathMapping ? '' : '_/'; From 35517fdafcb0621d162fc2349723186e20ba16bc Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 17 Jan 2024 10:55:12 +0100 Subject: [PATCH 54/67] Adjust custom linter logic for code editor Instead of disallowing the starting of all fields with an underscore, I now only allow the topmost fields to not start with an underscore. --- .../components/ResourceEditor/customLinter.ts | 59 ++++++++++++------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/src/shared/components/ResourceEditor/customLinter.ts b/src/shared/components/ResourceEditor/customLinter.ts index 7f5a20519..a7fc684e7 100644 --- a/src/shared/components/ResourceEditor/customLinter.ts +++ b/src/shared/components/ResourceEditor/customLinter.ts @@ -1,38 +1,53 @@ -/** - * Represents an issue identified by the linter. - */ export type LinterIssue = { - /** A message describing the issue. */ message: string; - /** The line number where the issue occurs. */ line: number; }; -/** - * A custom linter function that checks for issues in a given text. - * - * The function specifically looks for fields in the text that start with an underscore, - * which are considered as errors according to the linter's rules. - * - * @param text The text to be linted. - * @returns An array of LinterIssue objects, each representing a specific issue found in the text. - */ export const customLinter = (text: string): LinterIssue[] => { const linterErrors: LinterIssue[] = []; - const lines = text.split('\n'); - // Regex to match keys starting with an underscore followed by any character except a space or double quote - const regex = /"\s*_[^"\s]+"\s*:/g; + let json; + try { + json = JSON.parse(text); + } catch (error) { + // Handle JSON parsing errors if necessary + console.error('Invalid JSON:', error); + return linterErrors; + } - lines.forEach((line, index) => { - if (regex.test(line)) { + // We only iterate through top-level keys of the parsed object + for (const key in json) { + if ( + Object.prototype.hasOwnProperty.call(json, key) && + key.startsWith('_') + ) { + // Push an error for every top-level field starting with an underscore linterErrors.push({ message: - 'Fields starting with an underscore are reserved for internal use', - line: index + 1, + 'Top-level fields starting with an underscore are reserved for internal use', + line: findLineOfKey(text, key), }); } - }); + } return linterErrors; }; + +/** + * Find the line number of the first occurrence of a key in the given text. + * @param text The text to search through. + * @param key The key whose line number we want to find. + * @return The line number where the key is first found. + */ +function findLineOfKey(text: string, key: string): number { + // Create a regex to escape the key and match it in the text + const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(`"${escapedKey}"\s*:`); + const matches = text.match(regex); + + // Calculate the line number based on the position of the match + if (matches && matches.index !== undefined) { + return text.substring(0, matches.index).split('\n').length; + } + return -1; // Return -1 if the key is not found (this shouldn't happen for valid JSON) +} From 857d66c4eb116d6fe4317ca61ae2e9c712173785 Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 17 Jan 2024 11:47:00 +0100 Subject: [PATCH 55/67] Bring TSDoc comments back --- src/shared/components/ResourceEditor/customLinter.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/shared/components/ResourceEditor/customLinter.ts b/src/shared/components/ResourceEditor/customLinter.ts index a7fc684e7..f1960674b 100644 --- a/src/shared/components/ResourceEditor/customLinter.ts +++ b/src/shared/components/ResourceEditor/customLinter.ts @@ -1,5 +1,10 @@ +/** + * Represents an issue identified by the linter. + */ export type LinterIssue = { + /** A message describing the issue. */ message: string; + /** The line number where the issue occurs. */ line: number; }; From bf5ce2903583e67cd3d45ba86a2c79549982ca1f Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 17 Jan 2024 11:50:36 +0100 Subject: [PATCH 56/67] Bring back other TSDoc comment as well --- src/shared/components/ResourceEditor/customLinter.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/shared/components/ResourceEditor/customLinter.ts b/src/shared/components/ResourceEditor/customLinter.ts index f1960674b..5be74804e 100644 --- a/src/shared/components/ResourceEditor/customLinter.ts +++ b/src/shared/components/ResourceEditor/customLinter.ts @@ -8,6 +8,15 @@ export type LinterIssue = { line: number; }; +/** + * A custom linter function that checks for issues in a given text. + * + * The function specifically looks for fields in the text that start with an underscore, + * which are considered as errors according to the linter's rules. + * + * @param text The text to be linted. + * @returns An array of LinterIssue objects, each representing a specific issue found in the text. + */ export const customLinter = (text: string): LinterIssue[] => { const linterErrors: LinterIssue[] = []; From 19da337b6497ddb88f0abb5057c2b018b513eaab Mon Sep 17 00:00:00 2001 From: Daniel Burger Date: Wed, 17 Jan 2024 11:59:39 +0100 Subject: [PATCH 57/67] Remove unnecessary comment --- src/shared/components/ResourceEditor/customLinter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/shared/components/ResourceEditor/customLinter.ts b/src/shared/components/ResourceEditor/customLinter.ts index 5be74804e..e62012385 100644 --- a/src/shared/components/ResourceEditor/customLinter.ts +++ b/src/shared/components/ResourceEditor/customLinter.ts @@ -54,7 +54,6 @@ export const customLinter = (text: string): LinterIssue[] => { * @return The line number where the key is first found. */ function findLineOfKey(text: string, key: string): number { - // Create a regex to escape the key and match it in the text const escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const regex = new RegExp(`"${escapedKey}"\s*:`); const matches = text.match(regex); From f4c8ad5634e1c6a7dd7aeae303a565fdc7ceca02 Mon Sep 17 00:00:00 2001 From: Dinika Saxena Date: Wed, 17 Jan 2024 11:09:15 +0100 Subject: [PATCH 58/67] 4262 // All revisions inside the list should be accessible (atleast through scrolling) Signed-off-by: Dinika Saxena --- src/shared/containers/ResourceViewActionsContainer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/shared/containers/ResourceViewActionsContainer.tsx b/src/shared/containers/ResourceViewActionsContainer.tsx index fdc229b22..efd6fd169 100644 --- a/src/shared/containers/ResourceViewActionsContainer.tsx +++ b/src/shared/containers/ResourceViewActionsContainer.tsx @@ -281,7 +281,11 @@ const ResourceViewActionsContainer: React.FC<{ return ( - +