Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ View files task attachments #1954

Merged
merged 3 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions client/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@
"assessmentQuestionnaires": "Assessment questionnaires",
"assessmentNotes": "Assessment notes",
"assessmentSummary": "Assessment summary",
"attachments": "Attachments",
"autoTagging": "Automated Tagging",
"binary": "Binary",
"branch": "Branch",
Expand Down
8 changes: 8 additions & 0 deletions client/src/app/Paths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export const DevPaths = {
applications: "/applications",
applicationsAnalysisDetails:
"/applications/:applicationId/analysis-details/:taskId",
applicationsAnalysisDetailsAttachment:
"/applications/:applicationId/analysis-details/:taskId/attachments/:attachmentId",
applicationsAnalysisTab: "/applications/analysis-tab",
applicationsAssessmentTab: "/applications/assessment-tab",
applicationsImports: "/applications/application-imports",
Expand Down Expand Up @@ -93,3 +95,9 @@ export interface AnalysisDetailsRoute {
applicationId: string;
taskId: string;
}

export interface AnalysisDetailsAttachmentRoute {
applicationId: string;
taskId: string;
attachmentId: string;
}
5 changes: 5 additions & 0 deletions client/src/app/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export const devRoutes: IRoute<DevPathValues>[] = [
{
path: Paths.applicationsAnalysisDetails,
comp: AnalysisDetails,
exact: true,
},
{
path: Paths.applicationsAnalysisDetailsAttachment,
comp: AnalysisDetails,
exact: false,
},
{
Expand Down
29 changes: 24 additions & 5 deletions client/src/app/api/rest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,13 +319,25 @@ export const getApplicationImports = (
.get(`${APP_IMPORT}?importSummary.id=${importSummaryID}&isValid=${isValid}`)
.then((response) => response.data);

export function getTaskById(
export function getTaskById(id: number): Promise<Task> {
return axios
.get(`${TASKS}/${id}`, {
headers: { ...jsonHeaders },
responseType: "json",
})
.then((response) => {
return response.data;
});
}

export function getTaskByIdAndFormat(
id: number,
format: string,
merged: boolean = false
): Promise<Task | string> {
const headers = format === "yaml" ? { ...yamlHeaders } : { ...jsonHeaders };
const responseType = format === "yaml" ? "text" : "json";
): Promise<string> {
const isYaml = format === "yaml";
const headers = isYaml ? { ...yamlHeaders } : { ...jsonHeaders };
const responseType = isYaml ? "text" : "json";

let url = `${TASKS}/${id}`;
if (merged) {
Expand All @@ -338,7 +350,9 @@ export function getTaskById(
responseType: responseType,
})
.then((response) => {
return response.data;
return isYaml
? String(response.data ?? "")
: JSON.stringify(response.data, undefined, 2);
});
}

Expand Down Expand Up @@ -439,6 +453,11 @@ export const createFile = ({
return response.data;
});

export const getTextFile = (id: number): Promise<string> =>
axios
.get(`${FILES}/${id}`, { headers: { Accept: "text/plain" } })
.then((response) => response.data);

export const getSettingById = <K extends keyof SettingTypes>(
id: K
): Promise<SettingTypes[K]> =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { FC, useState } from "react";

import {
Select,
SelectOption,
SelectList,
MenuToggleElement,
MenuToggle,
} from "@patternfly/react-core";
import { Document } from "./SimpleDocumentViewer";
import "./SimpleDocumentViewer.css";

export const AttachmentToggle: FC<{
onSelect: (docId: string | number) => void;
documents: (Document & { isSelected: boolean })[];
}> = ({ onSelect, documents }) => {
const [isOpen, setIsOpen] = useState(false);
const onToggle = () => {
setIsOpen(!isOpen);
};

return (
<div className="simple-task-viewer-attachment-toggle">
<Select
isOpen={isOpen}
onSelect={(_event, selectedId: string | number | undefined) => {
if (selectedId) {
onSelect(selectedId);
}
onToggle();
}}
onOpenChange={(isOpen) => setIsOpen(isOpen)}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle ref={toggleRef} onClick={onToggle} isExpanded={isOpen}>
{documents.find(({ isSelected }) => isSelected)?.name}
</MenuToggle>
)}
shouldFocusToggleOnSelect
>
<SelectList>
{documents.map(({ id, name, isSelected, description }) => (
<SelectOption
isSelected={isSelected}
key={id}
value={id}
description={description}
>
{name}
</SelectOption>
))}
</SelectList>
</Select>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,47 @@ import CodeIcon from "@patternfly/react-icons/dist/esm/icons/code-icon";
import "./SimpleDocumentViewer.css";

export const LanguageToggle: React.FC<{
currentLanguage: Language.yaml | Language.json;
currentLanguage: Language;
code?: string;
setCurrentLanguage: (lang: Language.yaml | Language.json) => void;
}> = ({ currentLanguage, code, setCurrentLanguage }) => (
<div
className={css(
editorStyles.codeEditorTab,
"language-toggle-group-container"
)}
key="code-language-toggle"
>
<ToggleGroup
aria-label="code content type selection"
className="language-toggle-group"
supportedLanguages: Language[];
setCurrentLanguage: (lang: Language) => void;
}> = ({ currentLanguage, code, setCurrentLanguage, supportedLanguages }) => {
if (supportedLanguages.length <= 1) {
return <></>;
}

return (
<div
className={css(
editorStyles.codeEditorTab,
"language-toggle-group-container"
)}
key="code-language-toggle"
>
<ToggleGroupItem
text={
<>
<span className={editorStyles.codeEditorTabIcon}>
<CodeIcon />
</span>
<span className={editorStyles.codeEditorTabText}>JSON</span>
</>
}
buttonId="code-language-select-json"
isSelected={currentLanguage === "json"}
isDisabled={!code && currentLanguage !== "json"}
onChange={() => setCurrentLanguage(Language.json)}
/>
<ToggleGroupItem
text={
<>
<span className={editorStyles.codeEditorTabIcon}>
<CodeIcon />
</span>
<span className={editorStyles.codeEditorTabText}>YAML</span>
</>
}
buttonId="code-language-select-yaml"
isSelected={currentLanguage === "yaml"}
isDisabled={!code && currentLanguage !== "yaml"}
onChange={() => setCurrentLanguage(Language.yaml)}
/>
</ToggleGroup>
</div>
);
<ToggleGroup
aria-label="code content type selection"
className="language-toggle-group"
>
{supportedLanguages.map((lang) => (
<ToggleGroupItem
key={lang}
text={
<>
<span className={editorStyles.codeEditorTabIcon}>
<CodeIcon />
</span>
<span className={editorStyles.codeEditorTabText}>
{lang === Language.plaintext ? "Text" : lang.toUpperCase()}
</span>
</>
}
buttonId={`code-language-select-${lang}`}
isSelected={currentLanguage === lang}
isDisabled={!code && currentLanguage !== lang}
onChange={() => setCurrentLanguage(lang)}
/>
))}
</ToggleGroup>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
.simple-task-viewer-container {
display: flex;
flex-direction: column;
height: 100%;
}

.simple-task-viewer-code {
Expand Down Expand Up @@ -53,6 +54,10 @@
flex-grow: 1;
}

.simple-task-viewer-code .pf-v5-c-code-editor__controls > * {
display: flex;
}

.simple-task-viewer-code .pf-v5-c-code-editor__header-main {
display: none;
}
Expand All @@ -67,6 +72,6 @@
--pf-v5-c-toggle-group__button--FontSize: var(--pf-v5-global--FontSize--md);
}

.merged-checkbox {
margin: auto 0.5rem;
.simple-task-viewer-attachment-toggle {
order: -1;
}
Loading
Loading