Skip to content

Commit

Permalink
UI improvements (#1658)
Browse files Browse the repository at this point in the history
  • Loading branch information
olgenn authored Sep 4, 2024
1 parent b4a5a76 commit e4d467d
Show file tree
Hide file tree
Showing 27 changed files with 373 additions and 145 deletions.
28 changes: 6 additions & 22 deletions frontend/src/App/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const getInitialState = (): IAppState => {
let authData = null;
let storageData = null;
let activeMode = getThemeMode();
let selectedMode: IAppState['systemMode'] = 'system';

try {
storageData = localStorage.getItem(AUTH_DATA_STORAGE_KEY);
Expand All @@ -22,9 +21,8 @@ const getInitialState = (): IAppState => {
try {
const modeStorageData = localStorage.getItem(MODE_STORAGE_KEY);

if (modeStorageData) {
if (modeStorageData && JSON.parse(modeStorageData)) {
activeMode = modeStorageData as Mode;
selectedMode = modeStorageData as Mode;
}
} catch (e) {
console.log(e);
Expand All @@ -38,7 +36,7 @@ const getInitialState = (): IAppState => {
authData,
userData: null,
breadcrumbs: null,
systemMode: selectedMode,
systemMode: activeMode,

toolsPanelState: {
isOpen: false,
Expand Down Expand Up @@ -75,17 +73,11 @@ export const appSlice = createSlice({
}
},

setSystemMode: (state, action: PayloadAction<Mode | null>) => {
state.systemMode = action.payload ?? 'system';

applyMode(action.payload ?? getThemeMode());

setSystemMode: (state, action: PayloadAction<Mode>) => {
state.systemMode = action.payload;
applyMode(action.payload);
try {
if (action.payload) {
localStorage.setItem(MODE_STORAGE_KEY, action.payload);
} else {
localStorage.removeItem(MODE_STORAGE_KEY);
}
localStorage.setItem(MODE_STORAGE_KEY, action.payload);
} catch (e) {
console.log(e);
}
Expand Down Expand Up @@ -168,12 +160,4 @@ export const selectToolsPanelState = (state: RootState) => state.app.toolsPanelS
export const selectHelpPanelContent = (state: RootState) => state.app.helpPanel.content;
export const selectTutorialPanel = (state: RootState) => state.app.tutorialPanel;
export const selectSystemMode = (state: RootState) => state.app.systemMode;

export const selectAppliedThemeMode = (state: RootState): Mode => {
if (state.app.systemMode === 'system') {
return getThemeMode();
}

return state.app.systemMode;
};
export default appSlice.reducer;
2 changes: 1 addition & 1 deletion frontend/src/App/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface IAppState {
userData: IUser | null;
authData: IUserAuthData | null;
breadcrumbs: TBreadcrumb[] | null;
systemMode: Mode | 'system';
systemMode: Mode;
toolsPanelState: {
isOpen: boolean;
tab: ToolsTabs;
Expand Down
3 changes: 0 additions & 3 deletions frontend/src/assets/icons/dark-theme.svg

This file was deleted.

3 changes: 0 additions & 3 deletions frontend/src/assets/icons/light-theme.svg

This file was deleted.

3 changes: 0 additions & 3 deletions frontend/src/assets/icons/system-theme.svg

This file was deleted.

3 changes: 3 additions & 0 deletions frontend/src/assets/icons/theme.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions frontend/src/layouts/AppLayout/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import { GlobalUserRole } from 'types';
import { selectUserName } from 'App/slice';
import { useCheckAvailableProjectPermission } from 'pages/Project/hooks/useCheckAvailableProjectPermission';

import { DISCORD_URL, DOCS_URL } from '../../consts';
import { goToUrl } from '../../libs';

export const useSideNavigation = () => {
const { t } = useTranslation();
const userName = useAppSelector(selectUserName) ?? '';
Expand Down Expand Up @@ -83,6 +86,29 @@ export const useSideNavigation = () => {
title: t('navigation.account'),
items: userSettingsLinks,
},

{ type: 'divider' },

{
type: 'section-group',
title: t('navigation.resources'),
items: [
{
type: 'link',
text: t('common.docs'),
external: true,
href: DOCS_URL,
// onClick: () => goToUrl(DOCS_URL, true),
},
{
type: 'link',
text: t('common.discord'),
external: true,
href: DISCORD_URL,
onClick: () => goToUrl(DISCORD_URL, true),
},
],
},
].filter(Boolean) as SideNavigationProps['items'];

const activeHref = useMemo(() => {
Expand Down
50 changes: 45 additions & 5 deletions frontend/src/layouts/AppLayout/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
.b-page-header {
.awsui-context-top-navigation {
border-bottom: 1px solid awsui.$color-border-divider-default;

[class*="awsui_utility-type-button"] {
[class*="awsui_link"][href="theme-button"] {
[class^="awsui_icon"] {
width: 48px !important;
}
}
}
}
}
}
Expand Down Expand Up @@ -38,10 +46,42 @@
}

.themeIcon {
stroke: none !important;
fill: currentColor !important;
transform: scale(1.5);
path {
stroke: none !important;
display: flex;
align-items: center;
width: 48px;
gap: 6px;

.switcher {
position: relative;
flex-shrink: 0;
width: 24px;
height: 16px;
border-radius: 8px;
background-color: awsui.$color-background-layout-toggle-default;
transition: background-color .2s ease;

&::before {
content: "";
position: absolute;
top: 2px;
left: 0;
transform: translateX(2px);
width: 12px;
height: 12px;
border-radius: 50%;
background-color: awsui.$color-foreground-control-default;
transition: transform .2s ease;
}

&.on {
background-color: awsui.$color-background-control-checked;
&::before {
transform: translateX(10px);
}
}
}

.icon {
flex-shrink: 0;
}
}
37 changes: 12 additions & 25 deletions frontend/src/layouts/AppLayout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,11 @@ import {
import { AnnotationContext } from './AnnotationContext';
import { useProjectDropdown, useSideNavigation } from './hooks';
import { TallyComponent } from './Tally';
import { DarkThemeIcon, LightThemeIcon } from './themeIcons';
import { TutorialPanel } from './TutorialPanel';

import { ToolsTabs } from 'App/types';

import { ReactComponent as DarkThemeIcon } from 'assets/icons/dark-theme.svg';
import { ReactComponent as LightThemeIcon } from 'assets/icons/light-theme.svg';
import { ReactComponent as SystemThemeIcon } from 'assets/icons/system-theme.svg';
import logo from 'assets/images/logo.svg';
import styles from './index.module.scss';

Expand All @@ -55,10 +53,9 @@ const HeaderPortal = ({ children }: PortalProps) => {
return null;
};

const THEME_ICON_MAP: Record<Mode | 'system', React.ReactElement> = {
const THEME_ICON_MAP: Record<Mode, React.FC> = {
[Mode.Dark]: DarkThemeIcon,
[Mode.Light]: LightThemeIcon,
system: SystemThemeIcon,
};

const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
Expand All @@ -76,7 +73,12 @@ const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {

const onFollowHandler: SideNavigationProps['onFollow'] = (event) => {
event.preventDefault();
navigate(event.detail.href);

if (event.detail.external) {
goToUrl(event.detail.href, true);
} else {
navigate(event.detail.href);
}
};

const renderBreadcrumbs = () => {
Expand Down Expand Up @@ -124,14 +126,11 @@ const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
event.preventDefault();

switch (systemMode) {
case 'system':
dispatch(setSystemMode(Mode.Light));
return;
case Mode.Light:
dispatch(setSystemMode(Mode.Dark));
return;
default:
dispatch(setSystemMode(null));
dispatch(setSystemMode(Mode.Light));
}
};

Expand All @@ -155,16 +154,10 @@ const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
onClick: toggleTutorialPanel,
},
{
href: 'theme-button',
type: 'button',
text: t('common.docs'),
external: true,
onClick: () => goToUrl(DOCS_URL, true),
},
{
type: 'button',
text: t('common.discord'),
external: true,
onClick: () => goToUrl(DISCORD_URL, true),
iconSvg: <ThemeIcon />,
onClick: onChangeSystemModeToggle,
},
isAvailableProjectDropdown && {
type: 'menu-dropdown',
Expand All @@ -173,12 +166,6 @@ const AppLayout: React.FC<{ children: React.ReactNode }> = ({ children }) => {
items: projectsDropdownList,
onItemFollow: onFollowProject,
},
{
type: 'button',
iconSvg: <ThemeIcon className={styles.themeIcon} />,
onClick: onChangeSystemModeToggle,
},

{
'data-class': 'user-menu',
type: 'menu-dropdown',
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/layouts/AppLayout/themeIcons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import cn from 'classnames';

import { ReactComponent as ThemeIcon } from 'assets/icons/theme.svg';
import styles from './index.module.scss';

export const DarkThemeIcon: React.FC = () => {
return (
<div className={styles.themeIcon}>
<div className={cn(styles.switcher, styles.on)} />
<ThemeIcon className={styles.icon} />
</div>
);
};

export const LightThemeIcon: React.FC = () => {
return (
<div className={styles.themeIcon}>
<div className={cn(styles.switcher, styles.of)} />
<ThemeIcon className={styles.icon} />
</div>
);
};
9 changes: 4 additions & 5 deletions frontend/src/libs/fleet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ import { StatusIndicatorProps } from '@cloudscape-design/components';
export const getStatusIconType = (status: IInstance['status']): StatusIndicatorProps['type'] => {
switch (status) {
case 'pending':
case 'creating':
return 'pending';
case 'terminated':
return 'stopped';
case 'creating':
case 'starting':
case 'provisioning':
case 'terminating':
return 'loading';
case 'provisioning':
case 'starting':
case 'busy':
return 'in-progress';
case 'idle':
return 'success';
default:
return 'stopped';
console.error(new Error('Undefined fleet status'));
}
};
10 changes: 5 additions & 5 deletions frontend/src/libs/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ export const getStatusIconType = (status: IRun['status']): StatusIndicatorProps[
return 'error';
case 'aborted':
case 'terminated':
return 'stopped';
case 'done':
return 'success';
return 'stopped';
case 'running':
return 'success';
case 'terminating':
case 'pulling':
case 'provisioning':
return 'in-progress';
case 'submitted':
case 'pending':
case 'pulling':
case 'provisioning':
return 'pending';
default:
return 'stopped';
console.error(new Error('Undefined run status'));
}
};

Expand Down
12 changes: 7 additions & 5 deletions frontend/src/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@
"administration": "Administration",
"users": "Users",
"user_settings": "User settings",
"account": "Account",
"billing": "Billing"
"account": "User",
"billing": "Billing",
"resources": "Resources"
},

"backend": {
Expand Down Expand Up @@ -409,6 +410,7 @@

"fleets": {
"fleet": "Fleet",
"fleet_placeholder": "Filtering by fleet",
"fleet_name": "Fleet name",
"total_instances": "Number of instances",
"default": "Default pool",
Expand All @@ -417,7 +419,7 @@
"nomatch_message_title": "No matches",
"nomatch_message_text": "We can't find a match.",
"nomatch_message_button_label": "Clear filter",
"active_only": "Active Fleets",
"active_only": "Active Instances",
"instances": {
"title": "Instances",
"empty_message_title": "No instances",
Expand Down Expand Up @@ -457,8 +459,8 @@
"token_description": "Specify use your personal access token",
"global_role": "Global role",
"email": "Email",
"account": "Account",
"account_settings": "Account settings",
"account": "User",
"account_settings": "User settings",
"settings": "Settings",
"create": {
"page_title": "Create user",
Expand Down
Loading

0 comments on commit e4d467d

Please sign in to comment.