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

Remove global issues page and start using popup instead #886

Merged
merged 70 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
c520b56
removed IssuesLink from App.jsx
balsa-asanovic Nov 18, 2023
47d04f4
added class for highlighting
balsa-asanovic Nov 22, 2023
65b2ccb
added warning button to siderbar
balsa-asanovic Nov 22, 2023
8a68dcc
added className prop for styling
balsa-asanovic Nov 22, 2023
3754f47
removed title prop from ValidationErrors
balsa-asanovic Nov 22, 2023
c73c8cd
converted page to popup
balsa-asanovic Nov 23, 2023
951fe01
Removed popover, now it opens Issues popup
balsa-asanovic Nov 23, 2023
e5e85bc
typo correction in prop naming
balsa-asanovic Nov 23, 2023
dfdfd9d
changed name of comp IssuesPage to IssuesDialog
balsa-asanovic Dec 7, 2023
eff9b15
changed comp name IssuesPage to IssuesDialog
balsa-asanovic Dec 7, 2023
3195346
Merge branch 'extract-issues' of https://github.com/balsa-asanovic/ag…
balsa-asanovic Dec 7, 2023
3df181b
Reverting changes to PO files due to conflicts
balsa-asanovic Dec 7, 2023
4b92d6b
gemfile.lock reverts
balsa-asanovic Dec 7, 2023
3f011a0
changed color for highlighting
balsa-asanovic Dec 7, 2023
8223e4f
added new variable for warning icon color
balsa-asanovic Dec 7, 2023
d916474
switched to using a single ref hook
balsa-asanovic Dec 7, 2023
cd0a59e
Section component now uses forwardRef
balsa-asanovic Dec 7, 2023
ef57b49
changed the look of the issues button
balsa-asanovic Dec 7, 2023
7ae32ff
Merge remote-tracking branch 'agama/master' into extract-issues
dgdavid Dec 21, 2023
5cff43d
styling for issues dialog titles
balsa-asanovic Dec 25, 2023
12a17ef
added variable --fs-h3 for size 1rem
balsa-asanovic Dec 25, 2023
1d28178
changes prop name from sectionHighlight to openFrom
balsa-asanovic Dec 25, 2023
a68509f
sectionHighlight prop to openFrom
balsa-asanovic Dec 25, 2023
221cb19
added isOpen prop to issuesDialog
balsa-asanovic Dec 25, 2023
e27ff67
now using isOpen prop for rendering
balsa-asanovic Dec 25, 2023
fdd374d
removed IssuesLink from sidebar
balsa-asanovic Dec 26, 2023
50f5d42
removed IssuesLink from sidebar test
balsa-asanovic Dec 26, 2023
c575e28
Merge branch 'openSUSE:master' into extract-issues
balsa-asanovic Dec 26, 2023
15e0614
removed the global show issues button from Page comp
balsa-asanovic Dec 26, 2023
3dbd8e6
IssuesDialog now only shows issues from a single section
balsa-asanovic Dec 26, 2023
f9f85a8
removed warning icon from "N problems found" link
balsa-asanovic Dec 26, 2023
eb24b4c
Removed link to Issues page which no longer exists
balsa-asanovic Dec 26, 2023
6727d29
Merge branch 'openSUSE:master' into extract-issues
balsa-asanovic Dec 28, 2023
97f1343
classes no longer used
balsa-asanovic Dec 28, 2023
ae4971e
variable no longer used
balsa-asanovic Dec 28, 2023
4089b08
adjusted message text regarding the issues
balsa-asanovic Dec 28, 2023
9ff2b8f
cancel primary if there are issues, otherwise continue primary
balsa-asanovic Dec 28, 2023
2f62c18
removed the use of forward ref, added sectionId prop
balsa-asanovic Dec 30, 2023
3a6a126
adding sectionId prop value
balsa-asanovic Dec 30, 2023
bc464b2
adding sectionId prop value
balsa-asanovic Dec 30, 2023
f272ef3
adding sectionId prop value
balsa-asanovic Dec 30, 2023
bc693bd
adding sectionId prop value
balsa-asanovic Dec 30, 2023
bf745c8
adding sectionId prop value
balsa-asanovic Dec 30, 2023
afc7dae
adding sectionId prop value
balsa-asanovic Dec 30, 2023
dcfc69a
changed prop name to sectionId
balsa-asanovic Dec 30, 2023
bd4c91a
simplified issuesSection comp; no conditions, just a single section
balsa-asanovic Dec 30, 2023
6705f81
removed red color and warning icon from issueItem
balsa-asanovic Jan 3, 2024
9a6aa29
removed code for IssuesLink
balsa-asanovic Jan 3, 2024
16e6b9c
removed IssuesLink
balsa-asanovic Jan 3, 2024
d0ffa4f
changed prop name from sectionId to id
balsa-asanovic Jan 3, 2024
dc80336
prop name change from sectionId to id
balsa-asanovic Jan 3, 2024
27a0127
more simplification of IssuesDialog code
balsa-asanovic Jan 3, 2024
bd72c6e
passing title to IssuesDialog based on sectionId
balsa-asanovic Jan 3, 2024
651211f
removing the use of notificationProvider
balsa-asanovic Jan 3, 2024
f5dad31
removing the use of notificationProvider
balsa-asanovic Jan 3, 2024
5ea7aab
droping the whole notification code
balsa-asanovic Jan 3, 2024
0df8a30
removed old tests, added two basic tests
balsa-asanovic Jan 3, 2024
bddb6b8
[web] Please linters
dgdavid Jan 4, 2024
4e97140
[web] Fix InstallButton indentation and test
dgdavid Jan 4, 2024
8a45d9b
[web] Update ValidationErrors component test
dgdavid Jan 4, 2024
d4a99e1
[web] Do not use core/Section for list of issues
dgdavid Jan 4, 2024
e1b7f79
[web] Allow ValidationErrors guess the right issues key
dgdavid Jan 4, 2024
1260990
[web] Add an id to the storage actions section
dgdavid Jan 4, 2024
b67cf7d
[web] Fix loading icon size in IssuesDialog
dgdavid Jan 4, 2024
5ab2ae4
[web] Fix sectionId prop in software/PatternSelector
dgdavid Jan 4, 2024
d328700
Merge branch 'openSUSE:master' into extract-issues
balsa-asanovic Jan 4, 2024
0e84d9b
removed route for Issues Dialog
balsa-asanovic Jan 4, 2024
75d87a1
changes file update
balsa-asanovic Jan 4, 2024
a1a04a5
[web] Fix styles
dgdavid Jan 4, 2024
e443124
[web] Please ESLint
dgdavid Jan 4, 2024
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
2 changes: 0 additions & 2 deletions web/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import {
DBusError,
Disclosure,
Installation,
IssuesLink,
LogsButton,
ShowLogButton,
ShowTerminalButton,
Expand Down Expand Up @@ -106,7 +105,6 @@ function App() {
<>
<Sidebar>
<div className="flex-stack">
<IssuesLink />
<Disclosure label={_("Diagnostic tools")} data-keep-sidebar-open>
<ShowLogButton />
<LogsButton data-keep-sidebar-open="true" />
Expand Down
14 changes: 14 additions & 0 deletions web/src/assets/styles/utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,17 @@
.cursor-pointer {
cursor: pointer;
}

@keyframes fadeHighlight {
from {
background-color: yellow;
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
}

to {
background-color: transparent;
}
}

.highlighted {
animation: fadeHighlight 2s ease forwards;
}
108 changes: 80 additions & 28 deletions web/src/components/core/IssuesPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@
* find current contact information at www.suse.com.
*/

import React, { useCallback, useEffect, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";

import { HelperText, HelperTextItem } from "@patternfly/react-core";

import { partition, useCancellablePromise } from "~/utils";
import { If, Page, Section, SectionSkeleton } from "~/components/core";
import { If, Section, SectionSkeleton, Popup } from "~/components/core";
import { Icon } from "~/components/layout";
import { useInstallerClient } from "~/context/installer";
import { useNotification } from "~/context/notification";
import { _ } from "~/i18n";

/**
Expand Down Expand Up @@ -78,36 +77,82 @@ const IssueItems = ({ issues = [] }) => {
*
* @param {object} props
* @param {import ("~/client/issues").ClientsIssues} props.issues
* @param {string} [props.sectionHighlight] - A string which indicites which issues section should be highlighted.
*/
const IssuesSections = ({ issues }) => {
const IssuesSections = ({ issues, sectionHighlight = "" }) => {
const productIssues = issues.product || [];
const storageIssues = issues.storage || [];
const softwareIssues = issues.software || [];
const productSectionRef = useRef(null);
const storageSectionRef = useRef(null);
const softwareSectionRef = useRef(null);

useEffect(() => {
let selectedRef;
switch (sectionHighlight) {
case 'Product':
selectedRef = productSectionRef;
break;
case 'Storage':
selectedRef = storageSectionRef;
break;
case 'Software':
selectedRef = softwareSectionRef;
break;
default:
selectedRef = null;
}

if (selectedRef && selectedRef.current) {
selectedRef.current.scrollIntoView({ behavior: 'smooth' });
}
}, [sectionHighlight]);
dgdavid marked this conversation as resolved.
Show resolved Hide resolved

return (
<>
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
<If
condition={productIssues.length > 0}
then={
<Section key="product-issues" title={_("Product")} icon="inventory_2">
<IssueItems issues={productIssues} />
</Section>
<div ref={productSectionRef}>
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
<Section
key="product-issues"
title={_("Product")}
icon="inventory_2"
className={sectionHighlight === "Product" ? "highlighted" : ""}
>
<IssueItems issues={productIssues} />
</Section>
</div>
}
/>
<If
condition={storageIssues.length > 0}
then={
<Section key="storage-issues" title={_("Storage")} icon="hard_drive">
<IssueItems issues={storageIssues} />
</Section>
<div ref={storageSectionRef}>
<Section
key="storage-issues"
title={_("Storage")}
icon="hard_drive"
className={sectionHighlight === "Storage" ? "highlighted" : ""}
>
<IssueItems issues={storageIssues} />
</Section>
</div>
}
/>
<If
condition={softwareIssues.length > 0}
then={
<Section key="software-issues" title={_("Software")} icon="apps">
<IssueItems issues={softwareIssues} />
</Section>
<div ref={softwareSectionRef}>
<Section
key="software-issues"
title={_("Software")}
icon="apps"
className={sectionHighlight === "Software" ? "highlighted" : ""}
>
<IssueItems issues={softwareIssues} />
</Section>
</div>
}
/>
</>
Expand All @@ -120,8 +165,9 @@ const IssuesSections = ({ issues }) => {
*
* @param {object} props
* @param {import ("~/client").Issues} props.issues
* @param {string} [props.sectionHighlight] - A string which indicites which issues section should be highlighted.
*/
const IssuesContent = ({ issues }) => {
const IssuesContent = ({ issues, sectionHighlight = "" }) => {
const NoIssues = () => {
return (
<HelperText className="issue">
Expand All @@ -138,21 +184,31 @@ const IssuesContent = ({ issues }) => {
<If
condition={allIssues.length === 0}
then={<NoIssues />}
else={<IssuesSections issues={issues} />}
else={<IssuesSections issues={issues} sectionHighlight={sectionHighlight} />}
/>
);
};

/**
* Page to show all issues.
*
* It initially shows a loading state,
* then fetches and displays a list of issues grouped by categories such as 'product', 'storage', and 'software'.
*
* It uses a Popup component to display the issues, and an If component to toggle between
* a loading state and the content state.
*
* @component
*
* @param {object} props
* @param {function} props.close - A function to call when the close action is triggered.
* @param {string} [props.sectionHighlight] - A string which indicites which issues section should be highlighted.
*/
export default function IssuesPage() {
export default function IssuesPage({ close, sectionHighlight = "" }) {
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
const [isLoading, setIsLoading] = useState(true);
const [issues, setIssues] = useState();
const client = useInstallerClient();
const { cancellablePromise } = useCancellablePromise();
const [notification, updateNotification] = useNotification();

const load = useCallback(async () => {
setIsLoading(true);
Expand All @@ -163,27 +219,23 @@ export default function IssuesPage() {

const update = useCallback((issues) => {
setIssues(current => ({ ...current, ...issues }));
if (notification.issues) updateNotification({ issues: false });
}, [notification, setIssues, updateNotification]);
}, [setIssues]);

useEffect(() => {
load().then(update);
return client.onIssuesChange(update);
}, [client, load, update]);

return (
<Page
title="Issues"
icon="problem"
actionLabel="Back"
actionVariant="secondary"
navigateTo={-1}
>
<Popup isOpen title={_("Issues")}>
<If
condition={isLoading}
then={<SectionSkeleton numRows={4} />}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
else={<IssuesContent issues={issues} />}
else={<IssuesContent issues={issues} sectionHighlight={sectionHighlight} />}
/>
</Page>
<Popup.Actions>
<Popup.Confirm onClick={close} autoFocus>{_("Close")}</Popup.Confirm>
</Popup.Actions>
</Popup>
);
}
5 changes: 4 additions & 1 deletion web/src/components/core/Section.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ import { ValidationErrors } from "~/components/core";
* @property {string} [path] - Path where the section links to.
* when user clicks on the title, used for opening a dialog.
* @property {boolean} [loading] - Whether the section is busy loading its content or not.
* @property {string} [className] - Class name for section html tag.
* @property {import("~/client/mixins").ValidationError[]} [props.errors] - Validation errors to be shown before the title.
* @property {React.ReactElement} [children] - The section content.
* @property {string} [aria-label] - aria-label attribute, required if title if not given
Expand All @@ -64,6 +65,7 @@ export default function Section({
name,
path,
loading,
className,
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
errors,
children,
"aria-label": ariaLabel
Expand All @@ -89,6 +91,7 @@ export default function Section({

return (
<section
className={className}
aria-live="polite"
aria-busy={loading}
aria-label={ariaLabel || undefined}
Expand All @@ -97,7 +100,7 @@ export default function Section({
<Header />
<div className="stack content">
{errors?.length > 0 &&
<ValidationErrors errors={errors} title={`${title} errors`} />}
<ValidationErrors errors={errors} sectionName={title} />}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
{children}
</div>
</section>
Expand Down
20 changes: 15 additions & 5 deletions web/src/components/core/Sidebar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
import { Button, Text } from "@patternfly/react-core";
import { Icon, AppActions } from "~/components/layout";
import { If, NotificationMark } from "~/components/core";
import { If, IssuesPage } from "~/components/core";
import { useNotification } from "~/context/notification";
import useNodeSiblings from "~/hooks/useNodeSiblings";
import { _ } from "~/i18n";
Expand All @@ -40,6 +40,7 @@ export default function Sidebar ({ children }) {
const closeButtonRef = useRef(null);
const [notification] = useNotification();
const [addAttribute, removeAttribute] = useNodeSiblings(asideRef.current);
const [showWarningPopup, setShowWarningPopup] = useState(false);
dgdavid marked this conversation as resolved.
Show resolved Hide resolved

/**
* Set siblings as not interactive and not discoverable
Expand Down Expand Up @@ -129,21 +130,30 @@ export default function Sidebar ({ children }) {
return (
<>
<AppActions>
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
<If
condition={notification.issues}
then={
<Button
aria-label={_("Show issues popup")}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
variant="warning"
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
icon={<Icon name="warning" />}
onClick={() => setShowWarningPopup(prev => !prev)}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
/>
}
/>
<button
onClick={open}
className="plain-control"
aria-label={_("Show global options")}
aria-controls="global-options"
aria-expanded={isOpen}
>
<If
condition={notification.issues}
then={<NotificationMark data-variant="sidebar" aria-label={_("New issues found")} />}
/>
<Icon name="menu" />
</button>
</AppActions>

{showWarningPopup && <IssuesPage close={() => setShowWarningPopup(false)} />}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved

<aside
id="global-options"
ref={asideRef}
Expand Down
45 changes: 12 additions & 33 deletions web/src/components/core/ValidationErrors.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,11 @@
// @ts-check

import React, { useState } from "react";
import {
Button,
List,
ListItem,
Popover
} from "@patternfly/react-core";
import { sprintf } from "sprintf-js";

import { Icon } from '~/components/layout';
import { _, n_ } from "~/i18n";

/**
* @param {import("~/client/mixins").ValidationError[]} errors - Validation errors
* @return React.JSX
*/
const popoverContent = (errors) => {
const items = errors.map((e, i) => <ListItem key={i}>{e.message}</ListItem>);
return (
<List>{items}</List>
);
};
import { IssuesPage } from "~/components/core";
import { n_ } from "~/i18n";

/**
* Displays a list of validation errors
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -56,11 +40,11 @@ const popoverContent = (errors) => {
* @todo Improve the contents of the Popover (e.g., using a list)
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
*
* @param {object} props
* @param {string} props.title - A title for the Popover
* @param {string} [props.sectionName] - Name of the section which is displaying errors. (product, software, storage, ...)
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
* @param {import("~/client/mixins").ValidationError[]} props.errors - Validation errors
*/
const ValidationErrors = ({ title = _("Errors"), errors }) => {
const [popoverVisible, setPopoverVisible] = useState(false);
const ValidationErrors = ({ errors, sectionName = "" }) => {
const [showIssuesPopUp, setshowIssuesPopUp] = useState(false);
dgdavid marked this conversation as resolved.
Show resolved Hide resolved

if (!errors || errors.length === 0) return null;

Expand All @@ -77,7 +61,7 @@ const ValidationErrors = ({ title = _("Errors"), errors }) => {
<button
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
style={{ padding: "0", borderBottom: "1px solid" }}
className="plain-control color-warn"
onClick={() => setPopoverVisible(true)}
onClick={() => setshowIssuesPopUp(true)}
>
{ warningIcon } {
sprintf(
Expand All @@ -87,17 +71,12 @@ const ValidationErrors = ({ title = _("Errors"), errors }) => {
)
}
</button>
<Popover
isVisible={popoverVisible}
position="right"
shouldClose={() => setPopoverVisible(false)}
shouldOpen={() => setPopoverVisible(true)}
aria-label={_("Basic popover")}
headerContent={title}
bodyContent={popoverContent(errors)}
>
<Button className="hidden-popover-button" variant="link" />
</Popover>

{showIssuesPopUp &&
<IssuesPage
close={() => setshowIssuesPopUp(false)}
sectionHighlight={sectionName}
dgdavid marked this conversation as resolved.
Show resolved Hide resolved
/>}
</div>
</>
);
Expand Down
Loading
Loading