From da92005bc4e1950dd9ba901cf541bdb2a9e0096b Mon Sep 17 00:00:00 2001 From: Ian Bolton Date: Mon, 18 Dec 2023 16:47:12 -0500 Subject: [PATCH] :bug: Add conditional tooltip and update template (#1637) https://issues.redhat.com/browse/MTA-1350 --------- Signed-off-by: ibolton336 --- client/public/locales/en/translation.json | 7 + .../templates/questionnaire-template.yaml | 22 ++-- .../components/answer-table/answer-table.tsx | 124 ++++++++++-------- .../questions-table/questions-table.tsx | 39 +++++- 4 files changed, 126 insertions(+), 66 deletions(-) diff --git a/client/public/locales/en/translation.json b/client/public/locales/en/translation.json index d6bd70c3ee..6d37a49256 100644 --- a/client/public/locales/en/translation.json +++ b/client/public/locales/en/translation.json @@ -165,8 +165,11 @@ "archetypeNoApplications": "No applications currently match the criteria tags.", "archetypeAlreadyAssessed": "An assessment for one or more of the archetypes this application is associated with exists.", "archetypeAlreadyReviewed": "A review for one or more of the archetypes this application is associated with exists. Open the details drawer to view the review(s).", + "autoSelectTagsLabel": "Automatically select tags based on the answers to the questionnaire. ", "appNotAssesedTitle": "Assessment has not been completed", "appNotAssessedBody": "In order to review an application it must be assessed first. Assess the application and try again.", + "autoSelectTooltip": "Automatically select this answer based on tags associated with the application(s) or archetype.", + "autoTagTooltip": "Automatically tag this application or archetype with these tags based on this answer to the questionnaire.", "assessmentStakeholderHeader": "Select the stakeholder(s) or stakeholder group(s) associated with this assessment.", "binaryPackaging": "Packaging will default to JAR if left empty.", "blockedDeleteTracker": "Cannot delete {{what}} because it is associated with a tracker.", @@ -188,6 +191,7 @@ "inheritedReviewTooltip_plural": "This application is inheriting reviews from {{count}} archetypes.", "inheritedAssessmentTooltip": "This application is inheriting an assessment from an archetype.", "inheritedAssessmentTooltip_plural": "This application is inheriting assessments from {{count}} archetypes.", + "dependentQuestionTooltip": "This question is conditionally included or excluded based on tags:", "jiraInstanceNotConnected": "Jira instance {{name}} is not connected.", "manageDependenciesInstructions": "Add northbound and southbound dependencies for the selected application here. Note that any selections made will be saved automatically. To undo any changes, you must manually delete the applications from the dropdowns.", "noDataAvailableBody": "No data available to be shown here.", @@ -302,6 +306,7 @@ "date": "Date", "decision": "Decision", "dependencies": "Dependencies", + "dependentQuestion": "Dependent question", "description": "Description", "details": "Details", "displayName": "Display name", @@ -310,6 +315,7 @@ "email": "Email", "error": "Error", "errorReport": "Error report", + "exclude": "Exclude", "exportToIssue": "Export to Issue Manager", "facts": "Facts", "failed": "Failed", @@ -327,6 +333,7 @@ "impactfulButNotAdvisableToMove": "Impactful but not advisable to move", "image": "Image", "imports": "Imports", + "include": "Include", "importSummary": "Import summary", "importSummaryDeleted": "Import summary deleted", "inadvisable": "Inadvisable", diff --git a/client/public/templates/questionnaire-template.yaml b/client/public/templates/questionnaire-template.yaml index 1e82596de5..4163e6edc5 100644 --- a/client/public/templates/questionnaire-template.yaml +++ b/client/public/templates/questionnaire-template.yaml @@ -8,6 +8,9 @@ sections: - order: 1 text: What is the main technology in your application? explanation: Identify the main framework or technology used in your application. + includeFor: + - category: Language + tag: Java answers: - order: 1 text: Quarkus @@ -15,7 +18,10 @@ sections: rationale: Quarkus is a modern, container-friendly framework. mitigation: No mitigation needed. applyTags: - - category: Technology + - category: Runtime + tag: Quarkus + autoAnswerFor: + - category: Runtime tag: Quarkus - order: 2 text: Spring Boot @@ -23,16 +29,16 @@ sections: rationale: Spring Boot is versatile and widely used. mitigation: Ensure container compatibility. applyTags: - - category: Technology + - category: Runtime + tag: Spring Boot + autoAnswerFor: + - category: Runtime tag: Spring Boot - order: 3 text: Legacy Monolithic Application risk: red rationale: Legacy monoliths are challenging for cloud adaptation. mitigation: Consider refactoring into microservices. - applyTags: - - category: Architecture - tag: Monolith - order: 2 text: Does your application use a microservices architecture? explanation: Assess if the application is built using a microservices architecture. @@ -42,9 +48,6 @@ sections: risk: green rationale: Microservices are well-suited for cloud environments. mitigation: Continue monitoring service dependencies. - applyTags: - - category: Architecture - tag: Microservices - order: 2 text: No risk: yellow @@ -59,6 +62,9 @@ sections: - order: 3 text: Is your application's data storage cloud-optimized? explanation: Evaluate if the data storage solution is optimized for cloud usage. + includeFor: + - category: Language + tag: Java answers: - order: 1 text: Cloud-Native Storage Solution diff --git a/client/src/app/components/answer-table/answer-table.tsx b/client/src/app/components/answer-table/answer-table.tsx index b473bb3829..c8d56e4c3a 100644 --- a/client/src/app/components/answer-table/answer-table.tsx +++ b/client/src/app/components/answer-table/answer-table.tsx @@ -10,13 +10,14 @@ import { } from "@app/components/TableControls"; import { NoDataEmptyState } from "@app/components/NoDataEmptyState"; import { Answer } from "@app/api/models"; -import { Label, Text } from "@patternfly/react-core"; +import { Label, Text, Tooltip } from "@patternfly/react-core"; import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing"; import { IconedStatus } from "@app/components/IconedStatus"; import { TimesCircleIcon } from "@patternfly/react-icons"; import { WarningTriangleIcon } from "@patternfly/react-icons"; import { List, ListItem } from "@patternfly/react-core"; import RiskIcon from "../risk-icon/risk-icon"; +import { InfoCircleIcon } from "@patternfly/react-icons"; export interface IAnswerTableProps { answers: Answer[]; @@ -101,63 +102,74 @@ const AnswerTable: React.FC = ({ } > - {currentPageItems?.map((answer, rowIndex) => { - return ( - - - - - {answer.text} - - - - - - - - {!!answer?.autoAnswerFor?.length && ( - <> -
- - Auto answer if the following tags are present: - - {answer?.autoAnswerFor?.map((tag, index) => { - return ( -
- + {currentPageItems?.map((answer, rowIndex) => ( + + + + +
+ {answer.text} + {(!!answer?.autoAnswerFor?.length || + !!answer?.applyTags?.length) && ( + + {!!answer?.autoAnswerFor?.length && ( + <> + + {t("message.autoSelectTooltip")} + + + {answer.autoAnswerFor.map( + (tag, index) => ( + + + + ) + )} + + + )} + {!!answer?.applyTags?.length && ( + <> + {t("message.autoTagTooltip")} + + {answer.applyTags.map((tag, index) => ( + + + + ))} + + + )}
- ); - })} -
- - )} - - - {!!answer?.applyTags?.length && ( -
- - Apply Tags for this answer choice: - - {answer?.applyTags?.map((tag, index) => { - return ( -
- -
- ); - })} + } + > + + + + + )}
- )} - - - ); - })} + + + + + + + + {/* ... other rows ... */} + + ))} diff --git a/client/src/app/components/questions-table/questions-table.tsx b/client/src/app/components/questions-table/questions-table.tsx index 81a6f9a101..40f8e7da54 100644 --- a/client/src/app/components/questions-table/questions-table.tsx +++ b/client/src/app/components/questions-table/questions-table.tsx @@ -17,7 +17,7 @@ import { useTranslation } from "react-i18next"; import spacing from "@patternfly/react-styles/css/utilities/Spacing/spacing"; import { Assessment, Question, Questionnaire } from "@app/api/models"; import { useLocalTableControls } from "@app/hooks/table-controls"; -import { Label } from "@patternfly/react-core"; +import { Label, Tooltip } from "@patternfly/react-core"; import { NoDataEmptyState } from "@app/components/NoDataEmptyState"; import AnswerTable from "@app/components/answer-table/answer-table"; import { AxiosError } from "axios"; @@ -99,6 +99,35 @@ const QuestionsTable: React.FC<{ data?.sections.find((section) => section.questions.includes(question) )?.name || ""; + + const getConditionalTooltipContent = (question: Question) => { + const includeTags = question?.includeFor + ?.map((tag) => tag.tag) + .join(", "); + const excludeTags = question?.excludeFor + ?.map((tag) => tag.tag) + .join(", "); + + return ( +
+
{t("message.dependentQuestionTooltip")}
+ {includeTags && ( +
+ {t("terms.include")}: {includeTags} +
+ )} + {excludeTags && ( +
+ {t("terms.exclude")}: {excludeTags} +
+ )} +
+ ); + }; + return ( @@ -113,7 +142,13 @@ const QuestionsTable: React.FC<{ > {(!!question?.includeFor?.length || !!question?.excludeFor?.length) && ( - + + + )} {question.text}