From d2a57bd74ff9afbbf51b1f0f311f982068976630 Mon Sep 17 00:00:00 2001 From: TalyaNeima Date: Wed, 18 Sep 2024 12:19:00 +0300 Subject: [PATCH 1/5] adding filtering by analysis --- .../applications-table/applications-table.tsx | 193 ++++++++++-------- .../application-analysis-status.tsx | 2 +- 2 files changed, 110 insertions(+), 85 deletions(-) diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index d102d69a2a..8c58b5f7a3 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -85,10 +85,11 @@ import { import { useDeleteAssessmentMutation } from "@app/queries/assessments"; import { useDeleteReviewMutation } from "@app/queries/reviews"; import { useFetchTagsWithTagItems } from "@app/queries/tags"; +import { TaskState } from "@app/api/models"; // Relative components import { AnalysisWizard } from "../analysis-wizard/analysis-wizard"; -import { ApplicationAnalysisStatus } from "../components/application-analysis-status"; +import { ApplicationAnalysisStatus, taskStateToAnalyze } from "../components/application-analysis-status"; import { ApplicationAssessmentStatus } from "../components/application-assessment-status"; import { ApplicationBusinessService } from "../components/application-business-service"; import { ApplicationDependenciesForm } from "@app/components/ApplicationDependenciesFormContainer/ApplicationDependenciesForm"; @@ -109,6 +110,8 @@ import { DecoratedApplication, useDecoratedApplications, } from "./useDecoratedApplications"; +import { Item } from "@app/pages/migration-targets/components/dnd/item"; +import AnalysisDetails from "../analysis-details"; export const ApplicationsTable: React.FC = () => { const { t } = useTranslation(); @@ -367,7 +370,7 @@ export const ApplicationsTable: React.FC = () => { title: t("terms.archetypes"), type: FilterType.multiselect, placeholderText: - t("actions.filterBy", { + t("action s.filterBy", { what: t("terms.archetypes").toLowerCase(), }) + "...", selectOptions: referencedArchetypeRefs.map(({ name }) => ({ @@ -499,6 +502,29 @@ export const ApplicationsTable: React.FC = () => { ], getItemValue: (item) => normalizeRisk(item.risk) ?? "", }, + { + categoryKey: "analysis", + title: t("terms.analysis"), + type: FilterType.multiselect, + placeholderText: + t("actions.filterBy", { + what: t("terms.analysis").toLowerCase(), + }) + "...", + + // taskStateToAnalyze.map(state,icon)=>{ + // value: + + // } forEach.toString()} + // ApplicationAnalysisStatus.toString() + // Object.entries(Analy) + selectOptions: Array.from(taskStateToAnalyze).map(([taskState, displayStatus]) => ({ + value: taskState, // The task state will be the value + label: t(`${displayStatus}`) // The display status translated using t() + })), + + getItemValue: (item) => item?.tasks.currentAnalyzer?.state || + "No task" + }, ], initialItemsPerPage: 10, hasActionsColumn: true, @@ -547,48 +573,48 @@ export const ApplicationsTable: React.FC = () => { const importDropdownItems = importWriteAccess ? [ - setIsApplicationImportModalOpen(true)} - > - {t("actions.import")} - , - { - history.push(Paths.applicationsImports); - }} - > - {t("actions.manageImports")} - , - ] + setIsApplicationImportModalOpen(true)} + > + {t("actions.import")} + , + { + history.push(Paths.applicationsImports); + }} + > + {t("actions.manageImports")} + , + ] : []; const applicationDropdownItems = applicationWriteAccess ? [ - { - setApplicationsToDelete(selectedRows); - }} - > - {t("actions.delete")} - , - ...(credentialsReadAccess - ? [ - { - setSaveApplicationsCredentialsModalState(selectedRows); - }} - > - {t("actions.manageCredentials")} - , - ] - : []), - ] + { + setApplicationsToDelete(selectedRows); + }} + > + {t("actions.delete")} + , + ...(credentialsReadAccess + ? [ + { + setSaveApplicationsCredentialsModalState(selectedRows); + }} + > + {t("actions.manageCredentials")} + , + ] + : []), + ] : []; const dropdownItems = [...importDropdownItems, ...applicationDropdownItems]; @@ -977,58 +1003,58 @@ export const ApplicationsTable: React.FC = () => { onClick: () => assessSelectedApp(application), }, assessmentWriteAccess && - (application.assessments?.length ?? 0) > 0 && { - title: t("actions.discardAssessment"), - onClick: () => - setAssessmentToDiscard(application), - }, + (application.assessments?.length ?? 0) > 0 && { + title: t("actions.discardAssessment"), + onClick: () => + setAssessmentToDiscard(application), + }, reviewsWriteAccess && { title: t("actions.review"), onClick: () => reviewSelectedApp(application), }, reviewsWriteAccess && - application?.review && { - title: t("actions.discardReview"), - onClick: () => setReviewToDiscard(application), - }, + application?.review && { + title: t("actions.discardReview"), + onClick: () => setReviewToDiscard(application), + }, dependenciesWriteAccess && { title: t("actions.manageDependencies"), onClick: () => setApplicationDependenciesToManage(application), }, credentialsReadAccess && - applicationWriteAccess && { - title: t("actions.manageCredentials"), - onClick: () => - setSaveApplicationsCredentialsModalState([ - application, - ]), - }, + applicationWriteAccess && { + title: t("actions.manageCredentials"), + onClick: () => + setSaveApplicationsCredentialsModalState([ + application, + ]), + }, analysesReadAccess && - !!application.tasks.currentAnalyzer && { - title: t("actions.analysisDetails"), - onClick: () => { - const taskId = - application.tasks.currentAnalyzer?.id; - if (taskId && application.id) { - history.push( - formatPath( - Paths.applicationsAnalysisDetails, - { - applicationId: application.id, - taskId, - } - ) - ); - } - }, + !!application.tasks.currentAnalyzer && { + title: t("actions.analysisDetails"), + onClick: () => { + const taskId = + application.tasks.currentAnalyzer?.id; + if (taskId && application.id) { + history.push( + formatPath( + Paths.applicationsAnalysisDetails, + { + applicationId: application.id, + taskId, + } + ) + ); + } }, + }, tasksReadAccess && - tasksWriteAccess && - isTaskCancellable(application) && { - title: t("actions.cancelAnalysis"), - onClick: () => cancelAnalysis(application), - }, + tasksWriteAccess && + isTaskCancellable(application) && { + title: t("actions.cancelAnalysis"), + onClick: () => cancelAnalysis(application), + }, applicationWriteAccess && { isSeparator: true }, applicationWriteAccess && { title: t("actions.delete"), @@ -1131,11 +1157,10 @@ export const ApplicationsTable: React.FC = () => { )} titleIconVariant={"warning"} isOpen={applicationsToDelete.length > 0} - message={`${ - applicationsToDelete.length > 1 - ? t("dialog.message.applicationsBulkDelete") - : "" - } ${t("dialog.message.delete")}`} + message={`${applicationsToDelete.length > 1 + ? t("dialog.message.applicationsBulkDelete") + : "" + } ${t("dialog.message.delete")}`} aria-label="Applications bulk delete" confirmBtnVariant={ButtonVariant.danger} confirmBtnLabel={t("actions.delete")} diff --git a/client/src/app/pages/applications/components/application-analysis-status.tsx b/client/src/app/pages/applications/components/application-analysis-status.tsx index 4462aacaff..94c1e79537 100644 --- a/client/src/app/pages/applications/components/application-analysis-status.tsx +++ b/client/src/app/pages/applications/components/application-analysis-status.tsx @@ -7,7 +7,7 @@ export interface ApplicationAnalysisStatusProps { state: TaskState; } -const taskStateToAnalyze: Map = new Map([ +export const taskStateToAnalyze: Map = new Map([ ["not supported", "Canceled"], ["Canceled", "Canceled"], ["Created", "Scheduled"], From dcea9074c137b5094a4e352c192b6b4459cdc0cc Mon Sep 17 00:00:00 2001 From: TalyaNeima Date: Sun, 22 Sep 2024 10:44:16 +0300 Subject: [PATCH 2/5] sort by analysis Signed-off-by: TalyaNeima --- .../applications-table/applications-table.tsx | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index 8c58b5f7a3..b3c80a6e91 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -338,7 +338,7 @@ export const ApplicationsTable: React.FC = () => { sort: "sessionStorage", }, isLoading: isFetchingApplications, - sortableColumns: ["name", "businessService", "tags", "effort"], + sortableColumns: ["name", "businessService", "tags", "effort","analysis"], initialSort: { columnKey: "name", direction: "asc" }, initialColumns: { name: { isIdentity: true }, @@ -348,6 +348,7 @@ export const ApplicationsTable: React.FC = () => { businessService: app.businessService?.name || "", tags: app.tags?.length || 0, effort: app.effort || 0, + analysis: app.tasks.currentAnalyzer?.state || 0 }), filterCategories: [ { @@ -510,18 +511,11 @@ export const ApplicationsTable: React.FC = () => { t("actions.filterBy", { what: t("terms.analysis").toLowerCase(), }) + "...", - - // taskStateToAnalyze.map(state,icon)=>{ - // value: - - // } forEach.toString()} - // ApplicationAnalysisStatus.toString() - // Object.entries(Analy) - selectOptions: Array.from(taskStateToAnalyze).map(([taskState, displayStatus]) => ({ - value: taskState, // The task state will be the value - label: t(`${displayStatus}`) // The display status translated using t() - })), - + selectOptions: Array.from(taskStateToAnalyze).map(([taskState, displayStatus]) => ({ + value: taskState, // The task state will be the value + label: t(`${displayStatus}`) // The display status translated using t() + })), + getItemValue: (item) => item?.tasks.currentAnalyzer?.state || "No task" }, From b2201260d456fad5cf54c291c9b84b95ba215548 Mon Sep 17 00:00:00 2001 From: TalyaNaima Date: Tue, 8 Oct 2024 12:56:55 +0300 Subject: [PATCH 3/5] creating ability to filter & sort by application analysis ~ Signed-off-by: TalyaNaima --- .../applications-table/applications-table.tsx | 187 +++++++++--------- 1 file changed, 93 insertions(+), 94 deletions(-) diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index b3c80a6e91..db5246d276 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -85,11 +85,10 @@ import { import { useDeleteAssessmentMutation } from "@app/queries/assessments"; import { useDeleteReviewMutation } from "@app/queries/reviews"; import { useFetchTagsWithTagItems } from "@app/queries/tags"; -import { TaskState } from "@app/api/models"; // Relative components import { AnalysisWizard } from "../analysis-wizard/analysis-wizard"; -import { ApplicationAnalysisStatus, taskStateToAnalyze } from "../components/application-analysis-status"; +import { ApplicationAnalysisStatus } from "../components/application-analysis-status"; import { ApplicationAssessmentStatus } from "../components/application-assessment-status"; import { ApplicationBusinessService } from "../components/application-business-service"; import { ApplicationDependenciesForm } from "@app/components/ApplicationDependenciesFormContainer/ApplicationDependenciesForm"; @@ -110,8 +109,6 @@ import { DecoratedApplication, useDecoratedApplications, } from "./useDecoratedApplications"; -import { Item } from "@app/pages/migration-targets/components/dnd/item"; -import AnalysisDetails from "../analysis-details"; export const ApplicationsTable: React.FC = () => { const { t } = useTranslation(); @@ -338,7 +335,7 @@ export const ApplicationsTable: React.FC = () => { sort: "sessionStorage", }, isLoading: isFetchingApplications, - sortableColumns: ["name", "businessService", "tags", "effort","analysis"], + sortableColumns: ["name", "businessService", "tags", "effort", "analysis"], initialSort: { columnKey: "name", direction: "asc" }, initialColumns: { name: { isIdentity: true }, @@ -348,7 +345,7 @@ export const ApplicationsTable: React.FC = () => { businessService: app.businessService?.name || "", tags: app.tags?.length || 0, effort: app.effort || 0, - analysis: app.tasks.currentAnalyzer?.state || 0 + analysis: app.tasks.currentAnalyzer?.state || 0, }), filterCategories: [ { @@ -511,13 +508,14 @@ export const ApplicationsTable: React.FC = () => { t("actions.filterBy", { what: t("terms.analysis").toLowerCase(), }) + "...", - selectOptions: Array.from(taskStateToAnalyze).map(([taskState, displayStatus]) => ({ - value: taskState, // The task state will be the value - label: t(`${displayStatus}`) // The display status translated using t() - })), - - getItemValue: (item) => item?.tasks.currentAnalyzer?.state || - "No task" + selectOptions: Object.values(applications) + .map((a) => ({ + value: a?.tasks.currentAnalyzer?.state || "No Task", + label: a?.tasks.currentAnalyzer?.state || "Not Started", + })) + .filter((v, i, a) => a.findIndex((v2) => v2.label === v.label) === i) + .sort((a, b) => a.value.localeCompare(b.value)), + getItemValue: (item) => item?.tasks.currentAnalyzer?.state || "No Task", }, ], initialItemsPerPage: 10, @@ -567,48 +565,48 @@ export const ApplicationsTable: React.FC = () => { const importDropdownItems = importWriteAccess ? [ - setIsApplicationImportModalOpen(true)} - > - {t("actions.import")} - , - { - history.push(Paths.applicationsImports); - }} - > - {t("actions.manageImports")} - , - ] + setIsApplicationImportModalOpen(true)} + > + {t("actions.import")} + , + { + history.push(Paths.applicationsImports); + }} + > + {t("actions.manageImports")} + , + ] : []; const applicationDropdownItems = applicationWriteAccess ? [ - { - setApplicationsToDelete(selectedRows); - }} - > - {t("actions.delete")} - , - ...(credentialsReadAccess - ? [ - { - setSaveApplicationsCredentialsModalState(selectedRows); - }} - > - {t("actions.manageCredentials")} - , - ] - : []), - ] + { + setApplicationsToDelete(selectedRows); + }} + > + {t("actions.delete")} + , + ...(credentialsReadAccess + ? [ + { + setSaveApplicationsCredentialsModalState(selectedRows); + }} + > + {t("actions.manageCredentials")} + , + ] + : []), + ] : []; const dropdownItems = [...importDropdownItems, ...applicationDropdownItems]; @@ -997,58 +995,58 @@ export const ApplicationsTable: React.FC = () => { onClick: () => assessSelectedApp(application), }, assessmentWriteAccess && - (application.assessments?.length ?? 0) > 0 && { - title: t("actions.discardAssessment"), - onClick: () => - setAssessmentToDiscard(application), - }, + (application.assessments?.length ?? 0) > 0 && { + title: t("actions.discardAssessment"), + onClick: () => + setAssessmentToDiscard(application), + }, reviewsWriteAccess && { title: t("actions.review"), onClick: () => reviewSelectedApp(application), }, reviewsWriteAccess && - application?.review && { - title: t("actions.discardReview"), - onClick: () => setReviewToDiscard(application), - }, + application?.review && { + title: t("actions.discardReview"), + onClick: () => setReviewToDiscard(application), + }, dependenciesWriteAccess && { title: t("actions.manageDependencies"), onClick: () => setApplicationDependenciesToManage(application), }, credentialsReadAccess && - applicationWriteAccess && { - title: t("actions.manageCredentials"), - onClick: () => - setSaveApplicationsCredentialsModalState([ - application, - ]), - }, + applicationWriteAccess && { + title: t("actions.manageCredentials"), + onClick: () => + setSaveApplicationsCredentialsModalState([ + application, + ]), + }, analysesReadAccess && - !!application.tasks.currentAnalyzer && { - title: t("actions.analysisDetails"), - onClick: () => { - const taskId = - application.tasks.currentAnalyzer?.id; - if (taskId && application.id) { - history.push( - formatPath( - Paths.applicationsAnalysisDetails, - { - applicationId: application.id, - taskId, - } - ) - ); - } + !!application.tasks.currentAnalyzer && { + title: t("actions.analysisDetails"), + onClick: () => { + const taskId = + application.tasks.currentAnalyzer?.id; + if (taskId && application.id) { + history.push( + formatPath( + Paths.applicationsAnalysisDetails, + { + applicationId: application.id, + taskId, + } + ) + ); + } + }, }, - }, tasksReadAccess && - tasksWriteAccess && - isTaskCancellable(application) && { - title: t("actions.cancelAnalysis"), - onClick: () => cancelAnalysis(application), - }, + tasksWriteAccess && + isTaskCancellable(application) && { + title: t("actions.cancelAnalysis"), + onClick: () => cancelAnalysis(application), + }, applicationWriteAccess && { isSeparator: true }, applicationWriteAccess && { title: t("actions.delete"), @@ -1151,10 +1149,11 @@ export const ApplicationsTable: React.FC = () => { )} titleIconVariant={"warning"} isOpen={applicationsToDelete.length > 0} - message={`${applicationsToDelete.length > 1 - ? t("dialog.message.applicationsBulkDelete") - : "" - } ${t("dialog.message.delete")}`} + message={`${ + applicationsToDelete.length > 1 + ? t("dialog.message.applicationsBulkDelete") + : "" + } ${t("dialog.message.delete")}`} aria-label="Applications bulk delete" confirmBtnVariant={ButtonVariant.danger} confirmBtnLabel={t("actions.delete")} From cadd4b9045cd3eab9c295fb125e70fa64496e3a9 Mon Sep 17 00:00:00 2001 From: TalyaNaima Date: Tue, 8 Oct 2024 13:12:26 +0300 Subject: [PATCH 4/5] creating ability to filter & sort by application analysis Signed-off-by: TalyaNaima --- .../applications/applications-table/applications-table.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index db5246d276..d504501472 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -513,7 +513,7 @@ export const ApplicationsTable: React.FC = () => { value: a?.tasks.currentAnalyzer?.state || "No Task", label: a?.tasks.currentAnalyzer?.state || "Not Started", })) - .filter((v, i, a) => a.findIndex((v2) => v2.label === v.label) === i) + .filter((v, i, a) => a.findIndex((v3) => v3.label === v.label) === i) .sort((a, b) => a.value.localeCompare(b.value)), getItemValue: (item) => item?.tasks.currentAnalyzer?.state || "No Task", }, From 84ade6969041009834e7b2775e0c628572f9187a Mon Sep 17 00:00:00 2001 From: TalyaNaima Date: Sun, 13 Oct 2024 10:32:18 +0300 Subject: [PATCH 5/5] adding the ability to sort & filter by analysis Signed-off-by: TalyaNaima --- .../applications-table/applications-table.tsx | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/client/src/app/pages/applications/applications-table/applications-table.tsx b/client/src/app/pages/applications/applications-table/applications-table.tsx index d504501472..1259719169 100644 --- a/client/src/app/pages/applications/applications-table/applications-table.tsx +++ b/client/src/app/pages/applications/applications-table/applications-table.tsx @@ -72,7 +72,7 @@ import { useLocalTableControls } from "@app/hooks/table-controls"; // Queries import { getArchetypeById, getAssessmentsByItemId } from "@app/api/rest"; -import { Assessment, Ref } from "@app/api/models"; +import { Assessment, Ref, TaskState } from "@app/api/models"; import { useBulkDeleteApplicationMutation, useFetchApplications, @@ -88,7 +88,10 @@ import { useFetchTagsWithTagItems } from "@app/queries/tags"; // Relative components import { AnalysisWizard } from "../analysis-wizard/analysis-wizard"; -import { ApplicationAnalysisStatus } from "../components/application-analysis-status"; +import { + ApplicationAnalysisStatus, + taskStateToAnalyze, +} from "../components/application-analysis-status"; import { ApplicationAssessmentStatus } from "../components/application-assessment-status"; import { ApplicationBusinessService } from "../components/application-business-service"; import { ApplicationDependenciesForm } from "@app/components/ApplicationDependenciesFormContainer/ApplicationDependenciesForm"; @@ -509,11 +512,17 @@ export const ApplicationsTable: React.FC = () => { what: t("terms.analysis").toLowerCase(), }) + "...", selectOptions: Object.values(applications) - .map((a) => ({ - value: a?.tasks.currentAnalyzer?.state || "No Task", - label: a?.tasks.currentAnalyzer?.state || "Not Started", - })) - .filter((v, i, a) => a.findIndex((v3) => v3.label === v.label) === i) + .map((a) => { + let value = a?.tasks.currentAnalyzer?.state || "No Task"; + if (value === "No Task") { + value = "No task"; + } + let label = taskStateToAnalyze.get(value as TaskState) || value; + console.log(label + "," + value); + if (label === "NotStarted") label = "Not started"; + return { value, label }; + }) + .filter((v, i, a) => a.findIndex((v2) => v2.label === v.label) === i) .sort((a, b) => a.value.localeCompare(b.value)), getItemValue: (item) => item?.tasks.currentAnalyzer?.state || "No Task", },