Skip to content

Commit

Permalink
feat(layout): add button to the footer to update images
Browse files Browse the repository at this point in the history
  • Loading branch information
jamaljsr committed Aug 3, 2022
1 parent 43cf188 commit d3e98f4
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 22 deletions.
File renamed without changes.
5 changes: 2 additions & 3 deletions src/components/designer/default/DefaultSidebar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,11 @@ describe('DefaultSidebar Component', () => {
mockRepoService.checkForUpdates.mockResolvedValue({
state: defaultRepoState,
});
const { getByText, findByText, getByRole } = renderComponent();
const { getByText, getByRole, store } = renderComponent();
fireEvent.click(getByRole('switch'));
expect(getByText('Check for new Node Versions')).toBeInTheDocument();
fireEvent.click(getByText('Check for new Node Versions'));
expect(await findByText('You are up to date!')).toBeInTheDocument();
fireEvent.click(getByText('Close'));
expect(store.getState().modals.imageUpdates.visible).toBe(true);
});

it('should not display c-lightning nodes on Windows', () => {
Expand Down
26 changes: 11 additions & 15 deletions src/components/designer/default/DefaultSidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React from 'react';
import { CloudSyncOutlined } from '@ant-design/icons';
import styled from '@emotion/styled';
import { Button, Switch } from 'antd';
Expand All @@ -11,7 +11,6 @@ import { getPolarPlatform } from 'utils/system';
import SidebarCard from '../SidebarCard';
import SyncButton from '../SyncButton';
import DraggableNode from './DraggableNode';
import ImageUpdatesModal from './ImageUpdatesModal';

const Styled = {
AddNodes: styled.h3`
Expand All @@ -38,14 +37,14 @@ interface Props {
const DefaultSidebar: React.FC<Props> = ({ network }) => {
const { l } = usePrefixedTranslation('cmps.designer.default.DefaultSidebar');

const [showUpdatesModal, setShowUpdatesModal] = useState(false);
const { updateSettings } = useStoreActions(s => s.app);
const { showImageUpdates } = useStoreActions(s => s.modals);
const { settings, dockerRepoState } = useStoreState(s => s.app);
const showAll = settings.showAllNodeVersions;
const currPlatform = getPolarPlatform();

const toggleVersions = () => updateSettings({ showAllNodeVersions: !showAll });
const toggleModal = () => setShowUpdatesModal(!showUpdatesModal);
const toggleModal = () => showImageUpdates();

const nodes: {
label: string;
Expand Down Expand Up @@ -101,17 +100,14 @@ const DefaultSidebar: React.FC<Props> = ({ network }) => {
visible={showAll || latest}
/>
))}
{showAll && (
<Styled.UpdatesButton
type="link"
block
icon={<CloudSyncOutlined />}
onClick={toggleModal}
>
{l('checkUpdates')}
</Styled.UpdatesButton>
)}
{showUpdatesModal && <ImageUpdatesModal onClose={toggleModal} />}
<Styled.UpdatesButton
type="link"
block
icon={<CloudSyncOutlined />}
onClick={toggleModal}
>
{l('checkUpdates')}
</Styled.UpdatesButton>
</SidebarCard>
);
};
Expand Down
15 changes: 15 additions & 0 deletions src/components/home/GetStarted.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { CloudSyncOutlined } from '@ant-design/icons';
import styled from '@emotion/styled';
import { Button } from 'antd';
import { usePrefixedTranslation } from 'hooks';
import { useStoreActions } from 'store';
import { NETWORK_NEW } from 'components/routing';
import logobw from 'resources/logo_bw.png';

Expand All @@ -27,10 +29,15 @@ const Styled = {
ImportLink: styled(Link)`
margin-top: 15px;
`,
UpdatesButton: styled(Button)`
margin-top: 30px;
`,
};

const GetStarted: React.FC = () => {
const { l } = usePrefixedTranslation('cmps.home.GetStarted');
const { showImageUpdates } = useStoreActions(s => s.modals);
const toggleModal = () => showImageUpdates();

return (
<Styled.GetStarted>
Expand All @@ -40,6 +47,14 @@ const GetStarted: React.FC = () => {
{l('createBtn')}
</Button>
</Link>
<Styled.UpdatesButton
type="link"
block
icon={<CloudSyncOutlined />}
onClick={toggleModal}
>
{l('checkUpdates')}
</Styled.UpdatesButton>
</Styled.GetStarted>
);
};
Expand Down
11 changes: 10 additions & 1 deletion src/components/home/Home.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import { Network } from 'types';
import { getNetwork, injections, renderWithProviders } from 'utils/tests';
import Home from './Home';

describe('Home component', () => {
const renderComponent = (initialNetworks?: Network[]) => {
const renderComponent = (initialNetworks?: Network[], initialized?: boolean) => {
const initialState = {
app: {
initialized,
dockerVersions: {
docker: '1.2.3',
compose: '4.5.6',
Expand Down Expand Up @@ -36,6 +38,13 @@ describe('Home component', () => {
expect(await findByText('Create a Lightning Network')).toBeInTheDocument();
});

it('should display node updates modal', async () => {
const { findByText, getByText, store } = renderComponent([], true);
expect(await findByText('Check for new Node Versions')).toBeInTheDocument();
fireEvent.click(getByText('Check for new Node Versions'));
expect(store.getState().modals.imageUpdates.visible).toBe(true);
});

it('should display a list of networks', async () => {
const { findByText } = renderComponent();
expect(await findByText('my network 1')).toBeInTheDocument();
Expand Down
2 changes: 1 addition & 1 deletion src/components/home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const Home: React.FC = () => {
try {
await initialize();
} catch (error: any) {
notify({ message: l('loadError'), error });
notify({ message: l('initError'), error });
}
},
[],
Expand Down
21 changes: 20 additions & 1 deletion src/components/layouts/AppLayout.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react';
import { getI18n, useTranslation } from 'react-i18next';
import { fireEvent } from '@testing-library/react';
import { renderWithProviders } from 'utils/tests';
import { defaultRepoState } from 'utils/constants';
import { injections, renderWithProviders } from 'utils/tests';
import AppLayout from './AppLayout';

const mockRepoService = injections.repoService as jest.Mocked<
typeof injections.repoService
>;

describe('AppLayout component', () => {
const renderComponent = (route?: string) => {
const initialState = {
Expand Down Expand Up @@ -44,6 +49,20 @@ describe('AppLayout component', () => {
expect(history.location.pathname).toEqual('/');
});

describe('Updates Button', () => {
it('should display the Image Updates Modal', async () => {
mockRepoService.checkForUpdates.mockResolvedValue({
state: defaultRepoState,
});
const { getByText, findByText } = renderComponent();
fireEvent.click(getByText('Update'));
expect(getByText('Check for new Node Versions')).toBeInTheDocument();
fireEvent.click(getByText('Check for new Node Versions'));
expect(await findByText('You are up to date!')).toBeInTheDocument();
fireEvent.click(getByText('Close'));
});
});

describe('Language Switcher', () => {
it('should set language to English', async () => {
const { getByText, findByText } = renderComponent();
Expand Down
8 changes: 7 additions & 1 deletion src/components/layouts/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import { css, Global } from '@emotion/react';
import styled from '@emotion/styled';
import { Layout } from 'antd';
import { useTheme } from 'hooks/useTheme';
import { useStoreState } from 'store';
import { useStoreActions, useStoreState } from 'store';
import { ThemeColors } from 'theme/colors';
import { NavMenu } from 'components/common';
import ImageUpdatesModal from 'components/common/ImageUpdatesModal';
import { HOME } from 'components/routing';
import logo from 'resources/logo.png';
import { DockerStatus, LocaleSwitch, ThemeSwitch } from './';
import CheckForUpdatesButton from './CheckForUpdatesButton';

const { Header, Content, Footer } = Layout;

Expand Down Expand Up @@ -89,6 +91,8 @@ const AntdOverrides: React.FC = () => {

const AppLayout: React.FC<Props> = (props: Props) => {
const { initialized } = useStoreState(s => s.app);
const { imageUpdates } = useStoreState(s => s.modals);
const { hideImageUpdates } = useStoreActions(s => s.modals);
const theme = useTheme();
return (
<Styled.Layout>
Expand All @@ -109,10 +113,12 @@ const AppLayout: React.FC<Props> = (props: Props) => {
<Styled.Footer colors={theme.footer}>
<DockerStatus />
<Styled.FooterToggles>
<CheckForUpdatesButton />
<LocaleSwitch />
<ThemeSwitch />
</Styled.FooterToggles>
</Styled.Footer>
{imageUpdates.visible && <ImageUpdatesModal onClose={hideImageUpdates} />}
</Styled.Layout>
);
};
Expand Down
33 changes: 33 additions & 0 deletions src/components/layouts/CheckForUpdatesButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React, { useCallback } from 'react';
import { CloudSyncOutlined } from '@ant-design/icons';
import styled from '@emotion/styled';
import { Button } from 'antd';
import { usePrefixedTranslation } from 'hooks';
import { useStoreActions } from 'store';

const Styled = {
Button: styled(Button)`
color: inherit;
padding: 0 10px 0 0;
&:focus,
&:active {
color: inherit;
}
`,
};

const CheckForUpdatesButton: React.FC = () => {
const { l } = usePrefixedTranslation('cmps.layouts.CheckForUpdatesButton');
const { showImageUpdates } = useStoreActions(s => s.modals);

const handleClick = useCallback(() => showImageUpdates(), []);

return (
<Styled.Button type="link" onClick={handleClick}>
<CloudSyncOutlined />
{l('updates')}
</Styled.Button>
);
};

export default CheckForUpdatesButton;
2 changes: 2 additions & 0 deletions src/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -245,11 +245,13 @@
"cmps.home.DetectDockerModal.checkAgain": "Check Again",
"cmps.home.GetStarted.title": "Let's get started!",
"cmps.home.GetStarted.createBtn": "Create a Lightning Network",
"cmps.home.GetStarted.checkUpdates": "Check for new Node Versions",
"cmps.home.Home.initError": "Unable to initialize the application state",
"cmps.home.NetworkCard.lightningNodes": "Lightning Nodes",
"cmps.home.NetworkCard.bitcoinNodes": "Bitcoin Nodes",
"cmps.layouts.ThemeSwitch.light": "Light",
"cmps.layouts.ThemeSwitch.dark": "Dark",
"cmps.layouts.CheckForUpdatesButton.updates": "Update",
"cmps.network.NetworkActions.menuExport": "Export",
"cmps.network.NetworkActions.menuRename": "Rename",
"cmps.network.NetworkActions.menuDelete": "Delete",
Expand Down
21 changes: 21 additions & 0 deletions src/store/models/modals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,17 @@ interface AdvancedOptionsModel {
defaultCommand?: string;
}

interface ImageUpdatesModel {
visible: boolean;
}

export interface ModalsModel {
openChannel: OpenChannelModel;
changeBackend: ChangeBackendModel;
createInvoice: CreateInvoiceModel;
payInvoice: PayInvoiceModel;
advancedOptions: AdvancedOptionsModel;
imageUpdates: ImageUpdatesModel;
setOpenChannel: Action<ModalsModel, OpenChannelModel>;
showOpenChannel: Thunk<ModalsModel, Partial<OpenChannelModel>, StoreInjections>;
hideOpenChannel: Thunk<ModalsModel, void, StoreInjections, RootModel>;
Expand All @@ -56,6 +61,9 @@ export interface ModalsModel {
setAdvancedOptions: Action<ModalsModel, AdvancedOptionsModel>;
showAdvancedOptions: Thunk<ModalsModel, Partial<AdvancedOptionsModel>, StoreInjections>;
hideAdvancedOptions: Thunk<ModalsModel, void, StoreInjections, RootModel>;
setImageUpdates: Action<ModalsModel, ImageUpdatesModel>;
showImageUpdates: Thunk<ModalsModel, void, StoreInjections>;
hideImageUpdates: Thunk<ModalsModel, void, StoreInjections, RootModel>;
}

const modalsModel: ModalsModel = {
Expand All @@ -64,6 +72,7 @@ const modalsModel: ModalsModel = {
createInvoice: { visible: false },
payInvoice: { visible: false },
advancedOptions: { visible: false },
imageUpdates: { visible: false },
setOpenChannel: action((state, payload) => {
state.openChannel = {
...state.openChannel,
Expand Down Expand Up @@ -157,6 +166,18 @@ const modalsModel: ModalsModel = {
defaultCommand: undefined,
});
}),
setImageUpdates: action((state, payload) => {
state.imageUpdates = {
...state.imageUpdates,
...payload,
};
}),
showImageUpdates: thunk(actions => {
actions.setImageUpdates({ visible: true });
}),
hideImageUpdates: thunk(actions => {
actions.setImageUpdates({ visible: false });
}),
};

export default modalsModel;

0 comments on commit d3e98f4

Please sign in to comment.