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

chore(pf5): upgrade Settings view to Patternfly 5 #1330

Merged
merged 31 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4cf1ad7
chore: remove unused dropdown group wrapper
tthvo Aug 19, 2024
ec36925
fix: fix broken feature level settings
tthvo Aug 19, 2024
d6a097a
fix: fix react warning about invalid child node
tthvo Aug 19, 2024
7bf86e9
chore: use cyan color
tthvo Aug 19, 2024
983fa95
fix: fix Language and AutoRefresh settings
tthvo Aug 19, 2024
50eba43
fix: fix broken notification settings
tthvo Aug 19, 2024
229a899
fix: fix broken theme select (functionality is still broken
tthvo Aug 19, 2024
d4d6d4c
chore: menu should close on click outside and escape btn clicked
tthvo Aug 19, 2024
c3959f8
chore: featureLevel should follow locale config
tthvo Aug 19, 2024
4db244a
feat: add descriptions for feature level selections
tthvo Aug 20, 2024
a978970
fix: fix broken locale selections
tthvo Aug 20, 2024
1192426
chore: use full word for units
tthvo Aug 20, 2024
5ca0f99
feat: new design for AA recording form
tthvo Aug 21, 2024
5d9fe27
feat: divider for search bar
tthvo Aug 21, 2024
916421b
fix: notification action smenu should show shadow
tthvo Aug 21, 2024
d78e519
fix: dark mode should be functional
tthvo Aug 21, 2024
6230867
feat: added theme toggle on masthead
tthvo Aug 21, 2024
dc0b6f1
fix: adjust css for darkmode
tthvo Aug 21, 2024
91ac178
chore: adjust css for topology shortcut
tthvo Aug 21, 2024
439bc8c
chore: adjust group node label
tthvo Aug 21, 2024
a5ef359
fix: escape search term
tthvo Aug 21, 2024
e7cd014
fix: ensure timezone is searched by what is displayed
tthvo Aug 21, 2024
7671e1d
chore: use plural
tthvo Aug 21, 2024
9a82b36
chore: adjust dark theme css
tthvo Aug 22, 2024
6454de6
localize
andrewazores Aug 22, 2024
f1d8773
localize
andrewazores Aug 22, 2024
f4b0c04
localize
andrewazores Aug 22, 2024
5341dbe
fixup AppLayout aria-labels
andrewazores Aug 22, 2024
6f481b5
notification overflow pluralize
andrewazores Aug 22, 2024
a50fb5c
localize
andrewazores Aug 22, 2024
8f73e06
localize
andrewazores Aug 22, 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
8 changes: 5 additions & 3 deletions locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"MAXIMUM_SIZE_UNITS_INPUT": "Maximum size units input"
},
"AUTOMATED_RULES": "Automated Rules",
"BETA": "BETA",
"BETA": "Beta",
"CANCEL": "Cancel",
"CARD_TYPE": "Card type",
"CLEAN": "Clean",
Expand All @@ -22,7 +22,7 @@
"DATE": "Date",
"DELETE": "Delete",
"DESCRIPTION": "Description",
"DEVELOPMENT": "DEVELOPMENT",
"DEVELOPMENT": "Development",
"DISABLE": "Disable",
"DONOT_ASK_AGAIN": "Don't ask me again",
"DOWNLOAD": "Download",
Expand All @@ -43,6 +43,7 @@
"MAXIMUM_SIZE_HELPER_TEXT": "The maximum size of Recording data saved to disk.",
"MERIDIEM_AM": "AM",
"MERIDIEM_PM": "PM",
"MILLISECOND_other": "Milliseconds",
"MINUTE": "Minute",
"MINUTE_one": "Minute",
"MINUTE_other": "Minutes",
Expand All @@ -51,12 +52,13 @@
"NO_DESCRIPTION": "No description",
"OK": "OK",
"PRESERVED_ARCHIVES": "Preserved Archives",
"PRODUCTION": "PRODUCTION",
"PRODUCTION": "Production",
"REFRESH": "Refresh",
"REMOVE": "Remove",
"RENAME": "Rename",
"RESET": "Reset",
"RETRY": "Retry",
"SAVE": "Save",
"SCORE": "Score",
"SECOND": "Second",
"SECOND_one": "Second",
Expand Down
51 changes: 46 additions & 5 deletions locales/en/public.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@
"GUIDED_TOUR": "Guided tour",
"HELP": "Help",
"QUICKSTARTS": "Quick starts"
},
"NOTIFICATIONS": {
"OVERFLOW_MESSAGE_one": "View one more",
"OVERFLOW_MESSAGE_other": "View {{count}} more"
},
"TOOLBAR": {
"ARIA_LABELS": {
"GLOBAL_NAVIGATION": "Global navigation",
"NAVIGATION": "Navigation",
"NOTIFICATIONS": "Notifications",
"SETTINGS": "Settings"
}
},
"USER_MENU": {
"LANGUAGE_PREFERENCE": "<Icon/> Language preference",
"LOGOUT": "Log out"
}
},
"AutomatedAnalysisCard": {
Expand Down Expand Up @@ -75,9 +91,8 @@
"CURRENT_CONFIG": "Current configuration",
"FORM_TITLE": "Profiling Recording configuration",
"FORMATTED_TEMPLATE": "Name: {{template.name}}, Type: {{template.type}}",
"MAXIMUM_AGE": "Maximum age ({{unit}})",
"MAXIMUM_SIZE": "Maximum size ({{unit}})",
"SAVE_CHANGES": "Save changes",
"MAXIMUM_AGE": "Maximum age",
"MAXIMUM_SIZE": "Maximum size",
"TEMPLATE_HELPER_TEXT": "The Event Template to be applied to automated analysis Recordings.",
"TEMPLATE_INVALID_WARNING": "WARNING: Setting a target template as a default template type configuration may not apply to all target JVMs if the JVMs do not support them."
},
Expand Down Expand Up @@ -339,7 +354,7 @@
},
"AUTOMATED_ANALYSIS_CONFIG": {
"DESCRIPTION": "Set the Recording configuration for automated analysis Recordings. You may want smaller or larger values for max-age and max-size depending on how recent you want events to be recorded from the analysis.",
"TITLE": "Automated analysis Recording configuration"
"TITLE": "Recording configuration for Automated analysis"
},
"CATEGORIES": {
"ADVANCED": "Advanced",
Expand Down Expand Up @@ -371,6 +386,7 @@
},
"DESCRIPTION": "",
"LOCALE_SELECT_DESCRIPTION": "Select current date locale.",
"SEARCH_PLACEHOLDER": "Filter by locale...",
"TIMEZONE_SELECT_DESCRIPTION": "Select current timezone.",
"TITLE": "Date & Time"
},
Expand All @@ -381,7 +397,10 @@
"TITLE": "Show deletion dialogs"
},
"FEATURE_LEVEL": {
"BETA_DESCRIPTION": "Experimental features",
"DESCRIPTION": "Control which graphical features appear in the application.",
"DEVELOPMENT_DESCRIPTION": "Under development features",
"PRODUCTION_DESCRIPTION": "Stable production-ready features",
"TITLE": "Feature level"
},
"LANGUAGE": {
Expand Down Expand Up @@ -413,6 +432,27 @@
"TITLE": "WebSocket retry interval"
}
},
"ShortCuts": {
"ARIA_LABELS": {
"TABLE": "Shortcuts table"
}
},
"TargetContextSelector": {
"CLEAR_SELECTION": "Clear selection",
"CREATE_TARGET": "Create Target",
"NO_SEARCH_MATCHES": "No Target found",
"SEARCH_PLACEHOLDER": "Filter by URL, alias, or discovery group...",
"TOGGLE_LABEL": "Select Target",
"TOGGLE_PLACEHOLDER": "Select a Target"
},
"TargetSelect": {
"ARIA_LABELS": {
"CARD_DETAILS": "Details"
},
"CARD": {
"TITLE": "Target JVM"
}
},
"TimePicker": {
"24HOUR": "24-hour",
"USE_24HR_TIME": "Use 24-hour time"
Expand All @@ -435,7 +475,8 @@
"ARIA_LABELS": {
"SELECT": "Select a timezone",
"TYPE_AHEAD": "Search a timezone"
}
},
"SEARCH_PLACEHOLDER": "Filter by timezone..."
},
"Topology": {
"GRAPH_VIEW": "Graph view",
Expand Down
91 changes: 53 additions & 38 deletions src/app/AppLayout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { useJoyride } from '@app/Joyride/JoyrideProvider';
import { GlobalQuickStartDrawer } from '@app/QuickStarts/QuickStartDrawer';
import { IAppRoute, navGroups, routes } from '@app/routes';
import { ThemeSetting, SettingTab } from '@app/Settings/types';
import { selectTab, tabAsParam } from '@app/Settings/utils';
import { DARK_THEME_CLASS, selectTab, tabAsParam } from '@app/Settings/utils';
import { DynamicFeatureFlag, FeatureFlag } from '@app/Shared/Components/FeatureFlag';
import { NotificationCategory, Notification } from '@app/Shared/Services/api.types';
import { NotificationsContext } from '@app/Shared/Services/Notifications.service';
Expand Down Expand Up @@ -64,25 +64,25 @@ import {
MenuToggleElement,
MenuToggle,
DropdownList,
DropdownGroup,
DropdownItem,
Dropdown,
} from '@patternfly/react-core';
import {
BarsIcon,
BellIcon,
CaretDownIcon,
CogIcon,
ExternalLinkAltIcon,
LanguageIcon,
PlusCircleIcon,
QuestionCircleIcon,
UserIcon,
} from '@patternfly/react-icons';
import _ from 'lodash';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';
import { Link, matchPath, NavLink, useLocation, useNavigate } from 'react-router-dom';
import { map } from 'rxjs/operators';
import { ThemeToggle } from './ThemeToggle';

export interface AppLayoutProps {
children?: React.ReactNode;
Expand Down Expand Up @@ -120,9 +120,9 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {

React.useEffect(() => {
if (theme === ThemeSetting.DARK) {
document.documentElement.classList.add('pf-theme-dark');
document.documentElement.classList.add(DARK_THEME_CLASS);
} else {
document.documentElement.classList.remove('pf-theme-dark');
document.documentElement.classList.remove(DARK_THEME_CLASS);
}
}, [theme]);

Expand Down Expand Up @@ -167,10 +167,10 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
}
const overflow = notificationsToDisplay.length - visibleNotificationsCount;
if (overflow > 0) {
return `View ${overflow} more`;
return t('AppLayout.NOTIFICATIONS.OVERFLOW_MESSAGE', { count: overflow });
}
return '';
}, [isNotificationDrawerExpanded, notificationsToDisplay, visibleNotificationsCount]);
}, [isNotificationDrawerExpanded, notificationsToDisplay, visibleNotificationsCount, t]);

React.useEffect(() => {
addSubscription(notificationsContext.unreadNotifications().subscribe((s) => setUnreadNotificationsCount(s.length)));
Expand Down Expand Up @@ -283,20 +283,20 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
const userInfoItems = React.useMemo(
() => [
<FeatureFlag level={FeatureLevel.BETA} key={'language-preferences-feature-flag'}>
<DropdownGroup key={'language-preferences'}>
<DropdownItem onClick={handleLanguagePref}>Language preference</DropdownItem>
</DropdownGroup>
<DropdownItem key={'language-preferences'} onClick={handleLanguagePref}>
<Trans t={t} components={{ Icon: <LanguageIcon /> }} i18nKey="AppLayout.USER_MENU.LANGUAGE_PREFERENCE" />
</DropdownItem>
</FeatureFlag>,
<DropdownGroup key={'log-out'}>
<DropdownItem onClick={handleLogout}>Log out</DropdownItem>
</DropdownGroup>,
<DropdownItem key={'log-out'} onClick={handleLogout}>
{t('AppLayout.USER_MENU.LOGOUT')}
</DropdownItem>,
],
[handleLogout, handleLanguagePref],
[t, handleLogout, handleLanguagePref],
);

const UserInfoToggle = React.useCallback(
const userInfoToggle = React.useCallback(
(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle variant="plainText" ref={toggleRef} onClick={handleUserInfoToggle} icon={CaretDownIcon}>
<MenuToggle variant="plainText" ref={toggleRef} onClick={handleUserInfoToggle}>
{username || (
<Icon size="sm">
<UserIcon color="white" />
Expand Down Expand Up @@ -355,17 +355,20 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
];
}, [t, handleOpenDocumentation, handleOpenGuidedTour, handleOpenDiscussion, handleOpenAboutModal]);

const levelBadge = React.useCallback((level: FeatureLevel) => {
return (
<Label
isCompact
style={{ marginLeft: '2ch', textTransform: 'capitalize', paddingTop: '0.125ch', paddingBottom: '0.125ch' }}
color={level === FeatureLevel.BETA ? 'green' : 'red'}
>
{FeatureLevel[level].toLowerCase()}
</Label>
);
}, []);
const levelBadge = React.useCallback(
(level: FeatureLevel) => {
return (
<Label
isCompact
style={{ marginLeft: '2ch', paddingTop: '0.125ch', paddingBottom: '0.125ch' }}
color={level === FeatureLevel.BETA ? 'cyan' : 'red'}
>
{t(FeatureLevel[level])}
</Label>
);
},
[t],
);

const headerToolbar = React.useMemo(
() => (
Expand All @@ -386,6 +389,11 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
/>
</ToolbarItem>
</FeatureFlag>
<ToolbarGroup variant="icon-button-group" spacer={{ default: 'spacerSm' }}>
<ToolbarItem>
<ThemeToggle />
</ToolbarItem>
</ToolbarGroup>
<ToolbarGroup variant="icon-button-group">
<ToolbarItem>
<NotificationBadge
Expand All @@ -394,7 +402,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
errorNotificationsCount > 0 ? 'attention' : unreadNotificationsCount === 0 ? 'read' : 'unread'
}
onClick={handleNotificationCenterToggle}
aria-label="Notifications"
aria-label={t('AppLayout.TOOLBAR.ARIA_LABELS.NOTIFICATIONS')}
>
<Icon>
<BellIcon />
Expand All @@ -404,7 +412,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
<ToolbarItem>
<Button
variant="plain"
aria-label="Settings"
aria-label={t('AppLayout.TOOLBAR.ARIA_LABELS.SETTINGS')}
data-tour-id="settings-link"
data-quickstart-id="settings-link"
component={(props) => <Link {...props} to="/settings" />}
Expand All @@ -431,7 +439,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
</MenuToggle>
)}
isOpen={showHelpDropdown}
onOpenChange={(v) => setShowHelpDropdown(v)}
onOpenChange={setShowHelpDropdown}
onOpenChangeKeys={['Escape']}
popperProps={{
position: 'right',
Expand All @@ -444,9 +452,9 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
<ToolbarItem visibility={{ default: 'visible' }}>
<Dropdown
onSelect={() => setShowUserInfoDropdown(false)}
toggle={UserInfoToggle}
toggle={userInfoToggle}
isOpen={showUserInfoDropdown}
onOpenChange={(v) => setShowUserInfoDropdown(v)}
onOpenChange={setShowUserInfoDropdown}
onOpenChangeKeys={['Escape']}
popperProps={{
position: 'right',
Expand All @@ -469,9 +477,10 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
setShowUserInfoDropdown,
showUserInfoDropdown,
showHelpDropdown,
UserInfoToggle,
userInfoToggle,
userInfoItems,
helpItems,
t,
],
);

Expand All @@ -482,7 +491,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
<MastheadToggle>
<PageToggleButton
variant="plain"
aria-label="Navigation"
aria-label={t('AppLayout.TOOLBAR.ARIA_LABELS.NAVIGATION')}
isSidebarOpen={isNavOpen}
onSidebarToggle={onNavToggle}
data-quickstart-id="nav-toggle-btn"
Expand All @@ -506,7 +515,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
<AboutCryostatModal isOpen={aboutModalOpen} onClose={handleCloseAboutModal} />
</>
),
[isNavOpen, aboutModalOpen, headerToolbar, handleCloseAboutModal, onNavToggle, levelBadge],
[isNavOpen, aboutModalOpen, headerToolbar, handleCloseAboutModal, onNavToggle, levelBadge, t],
);

const isActiveRoute = React.useCallback(
Expand All @@ -528,7 +537,13 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {

const Navigation = React.useMemo(
() => (
<Nav id="nav-primary-simple" theme="dark" variant="default" onSelect={mobileOnSelect} aria-label="Global nav">
<Nav
id="nav-primary-simple"
theme="dark"
variant="default"
onSelect={mobileOnSelect}
aria-label={t('AppLayout.TOOLBAR.ARIA_LABELS.GLOBAL_NAVIGATION')}
>
{navGroups.map((title) => {
return (
<NavGroup title={title} key={title}>
Expand Down Expand Up @@ -562,7 +577,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
})}
</Nav>
),
[mobileOnSelect, isActiveRoute, levelBadge, activeLevel],
[mobileOnSelect, isActiveRoute, levelBadge, activeLevel, t],
);

const Sidebar = React.useMemo(
Expand Down
3 changes: 2 additions & 1 deletion src/app/AppLayout/NotificationCenter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ export const NotificationCenter: React.FC<NotificationCenterProps> = ({ onClose
<NotificationDrawer>
<NotificationDrawerHeader count={totalUnreadNotificationsCount} onClose={onClose}>
<Dropdown
isPlain
onSelect={handleToggleDropdown}
toggle={(toggleRef: React.Ref<MenuToggleElement>) => (
<MenuToggle
Expand All @@ -164,6 +163,8 @@ export const NotificationCenter: React.FC<NotificationCenterProps> = ({ onClose
popperProps={{
position: 'right',
}}
onOpenChange={setHeaderDropdownOpen}
onOpenChangeKeys={['Escape']}
>
<DropdownList>{drawerDropdownItems}</DropdownList>
</Dropdown>
Expand Down
Loading
Loading