Skip to content

Commit 61018b5

Browse files
committed
Update more of the UI to use new design elements
1 parent 2824db7 commit 61018b5

File tree

14 files changed

+100
-109
lines changed

14 files changed

+100
-109
lines changed

resources/scripts/components/elements/Code.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import classNames from 'classnames';
33

44
interface CodeProps {
55
dark?: boolean | undefined;
6+
className?: string;
67
children: React.ReactChild | React.ReactFragment | React.ReactPortal;
78
}
89

9-
export default ({ dark, children }: CodeProps) => (
10+
export default ({ dark, className, children }: CodeProps) => (
1011
<code
11-
className={classNames('font-mono text-sm px-2 py-1 rounded', {
12+
className={classNames('font-mono text-sm px-2 py-1 inline-block rounded', className, {
1213
'bg-neutral-700': !dark,
1314
'bg-neutral-900 text-gray-100': dark,
1415
})}

resources/scripts/components/elements/button/style.module.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
/* Sizing Controls */
77
&.small {
8-
@apply px-4 py-1 font-normal text-sm focus:ring-2;
8+
@apply px-4 py-0 h-8 font-normal text-sm focus:ring-2;
99
}
1010

1111
&.large {

resources/scripts/components/server/network/AllocationRow.tsx

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ import { faNetworkWired } from '@fortawesome/free-solid-svg-icons';
66
import InputSpinner from '@/components/elements/InputSpinner';
77
import { Textarea } from '@/components/elements/Input';
88
import Can from '@/components/elements/Can';
9-
import Button from '@/components/elements/Button';
9+
import { Button } from '@/components/elements/button/index';
1010
import GreyRowBox from '@/components/elements/GreyRowBox';
1111
import { Allocation } from '@/api/server/getServer';
1212
import styled from 'styled-components/macro';
1313
import { debounce } from 'debounce';
1414
import setServerAllocationNotes from '@/api/server/network/setServerAllocationNotes';
15-
import useFlash from '@/plugins/useFlash';
15+
import { useFlashKey } from '@/plugins/useFlash';
1616
import { ServerContext } from '@/state/server';
1717
import CopyOnClick from '@/components/elements/CopyOnClick';
1818
import DeleteAllocationButton from '@/components/server/network/DeleteAllocationButton';
1919
import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation';
2020
import getServerAllocations from '@/api/swr/getServerAllocations';
2121
import { formatIp } from '@/helpers';
22+
import Code from '@/components/elements/Code';
2223

23-
const Code = styled.code`${tw`font-mono py-1 px-2 bg-neutral-900 rounded text-sm inline-block`}`;
2424
const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`;
2525

2626
interface Props {
@@ -29,7 +29,7 @@ interface Props {
2929

3030
const AllocationRow = ({ allocation }: Props) => {
3131
const [ loading, setLoading ] = useState(false);
32-
const { clearFlashes, clearAndAddHttpError } = useFlash();
32+
const { clearFlashes, clearAndAddHttpError } = useFlashKey('server:network');
3333
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
3434
const { mutate } = getServerAllocations();
3535

@@ -39,69 +39,64 @@ const AllocationRow = ({ allocation }: Props) => {
3939

4040
const setAllocationNotes = debounce((notes: string) => {
4141
setLoading(true);
42-
clearFlashes('server:network');
42+
clearFlashes();
4343

4444
setServerAllocationNotes(uuid, allocation.id, notes)
4545
.then(() => onNotesChanged(allocation.id, notes))
46-
.catch(error => clearAndAddHttpError({ key: 'server:network', error }))
46+
.catch(error => clearAndAddHttpError(error))
4747
.then(() => setLoading(false));
4848
}, 750);
4949

5050
const setPrimaryAllocation = () => {
51-
clearFlashes('server:network');
51+
clearFlashes();
5252
mutate(data => data?.map(a => ({ ...a, isDefault: a.id === allocation.id })), false);
5353

5454
setPrimaryServerAllocation(uuid, allocation.id)
5555
.catch(error => {
56-
clearAndAddHttpError({ key: 'server:network', error });
56+
clearAndAddHttpError(error);
5757
mutate();
5858
});
5959
};
6060

6161
return (
62-
<GreyRowBox $hoverable={false} css={tw`flex-wrap md:flex-nowrap mt-2`}>
63-
<div css={tw`flex items-center w-full md:w-auto`}>
64-
<div css={tw`pl-4 pr-6 text-neutral-400`}>
62+
<GreyRowBox $hoverable={false} className={'flex-wrap md:flex-nowrap mt-2'}>
63+
<div className={'flex items-center w-full md:w-auto'}>
64+
<div className={'pl-4 pr-6 text-neutral-400'}>
6565
<FontAwesomeIcon icon={faNetworkWired}/>
6666
</div>
67-
<div css={tw`mr-4 flex-1 md:w-40`}>
67+
<div className={'mr-4 flex-1 md:w-40'}>
6868
{allocation.alias ?
69-
<CopyOnClick text={allocation.alias}><Code css={tw`w-40 truncate`}>{allocation.alias}</Code></CopyOnClick> :
70-
<CopyOnClick text={formatIp(allocation.ip)}><Code>{formatIp(allocation.ip)}</Code></CopyOnClick>}
69+
<CopyOnClick text={allocation.alias}><Code dark className={'w-40 truncate'}>{allocation.alias}</Code></CopyOnClick> :
70+
<CopyOnClick text={formatIp(allocation.ip)}><Code dark>{formatIp(allocation.ip)}</Code></CopyOnClick>}
7171
<Label>{allocation.alias ? 'Hostname' : 'IP Address'}</Label>
7272
</div>
73-
<div css={tw`w-16 md:w-24 overflow-hidden`}>
74-
<Code>{allocation.port}</Code>
73+
<div className={'w-16 md:w-24 overflow-hidden'}>
74+
<Code dark>{allocation.port}</Code>
7575
<Label>Port</Label>
7676
</div>
7777
</div>
78-
<div css={tw`mt-4 w-full md:mt-0 md:flex-1 md:w-auto`}>
78+
<div className={'mt-4 w-full md:mt-0 md:flex-1 md:w-auto'}>
7979
<InputSpinner visible={loading}>
8080
<Textarea
81-
css={tw`bg-neutral-800 hover:border-neutral-600 border-transparent`}
81+
className={'bg-neutral-800 hover:border-neutral-600 border-transparent'}
8282
placeholder={'Notes'}
8383
defaultValue={allocation.notes || undefined}
8484
onChange={e => setAllocationNotes(e.currentTarget.value)}
8585
/>
8686
</InputSpinner>
8787
</div>
88-
<div css={tw`w-full md:flex-none md:w-40 md:text-center mt-4 md:mt-0 ml-4 flex items-center justify-end`}>
88+
<div className={'flex justify-end space-x-4 mt-4 w-full md:mt-0 md:w-48'}>
8989
{allocation.isDefault ?
90-
<span css={tw`bg-green-500 py-1 px-2 rounded text-green-50 text-xs`}>Primary</span>
90+
<Button size={Button.Sizes.Small} className={'!text-gray-50 !bg-blue-600'} disabled>Primary</Button>
9191
:
9292
<>
9393
<Can action={'allocation.delete'}>
9494
<DeleteAllocationButton allocation={allocation.id}/>
9595
</Can>
9696
<Can action={'allocation.update'}>
97-
<Button
98-
isSecondary
99-
size={'xsmall'}
100-
color={'primary'}
101-
onClick={setPrimaryAllocation}
102-
>
97+
<Button.Text size={Button.Sizes.Small} onClick={setPrimaryAllocation}>
10398
Make Primary
104-
</Button>
99+
</Button.Text>
105100
</Can>
106101
</>
107102
}

resources/scripts/components/server/network/DeleteAllocationButton.tsx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import React, { useState } from 'react';
22
import { faTrashAlt } from '@fortawesome/free-solid-svg-icons';
33
import tw from 'twin.macro';
44
import Icon from '@/components/elements/Icon';
5-
import ConfirmationModal from '@/components/elements/ConfirmationModal';
65
import { ServerContext } from '@/state/server';
76
import deleteServerAllocation from '@/api/server/network/deleteServerAllocation';
87
import getServerAllocations from '@/api/swr/getServerAllocations';
9-
import useFlash from '@/plugins/useFlash';
8+
import { useFlashKey } from '@/plugins/useFlash';
9+
import { Dialog } from '@/components/elements/dialog';
10+
import { Button } from '@/components/elements/button/index';
1011

1112
interface Props {
1213
allocation: number;
@@ -19,36 +20,41 @@ const DeleteAllocationButton = ({ allocation }: Props) => {
1920
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
2021

2122
const { mutate } = getServerAllocations();
22-
const { clearFlashes, clearAndAddHttpError } = useFlash();
23+
const { clearFlashes, clearAndAddHttpError } = useFlashKey('server:network');
2324

2425
const deleteAllocation = () => {
25-
clearFlashes('server:network');
26+
clearFlashes();
2627

2728
mutate(data => data?.filter(a => a.id !== allocation), false);
2829
setServerFromState(s => ({ ...s, allocations: s.allocations.filter(a => a.id !== allocation) }));
2930

3031
deleteServerAllocation(uuid, allocation)
31-
.catch(error => clearAndAddHttpError({ key: 'server:network', error }));
32+
.catch(error => {
33+
clearAndAddHttpError(error);
34+
mutate();
35+
});
3236
};
3337

3438
return (
3539
<>
36-
<ConfirmationModal
37-
visible={confirm}
38-
title={'Remove this allocation?'}
39-
buttonText={'Delete'}
40+
<Dialog.Confirm
41+
open={confirm}
42+
onClose={() => setConfirm(false)}
43+
title={'Remove Allocation'}
44+
confirm={'Delete'}
4045
onConfirmed={deleteAllocation}
41-
onModalDismissed={() => setConfirm(false)}
4246
>
43-
This allocation will be immediately removed from your server. Are you sure you want to continue?
44-
</ConfirmationModal>
45-
<button
46-
css={tw`text-neutral-400 px-2 py-1 mr-2 transition-colors duration-150 hover:text-red-400`}
47+
This allocation will be immediately removed from your server.
48+
</Dialog.Confirm>
49+
<Button.Danger
50+
variant={Button.Variants.Secondary}
51+
size={Button.Sizes.Small}
52+
shape={Button.Shapes.IconSquare}
4753
type={'button'}
4854
onClick={() => setConfirm(true)}
4955
>
5056
<Icon icon={faTrashAlt} css={tw`w-3 h-auto`}/>
51-
</button>
57+
</Button.Danger>
5258
</>
5359
);
5460
};

resources/scripts/components/server/network/NetworkContainer.tsx

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { useEffect, useState } from 'react';
22
import Spinner from '@/components/elements/Spinner';
3-
import useFlash from '@/plugins/useFlash';
3+
import { useFlashKey } from '@/plugins/useFlash';
44
import ServerContentBlock from '@/components/elements/ServerContentBlock';
55
import { ServerContext } from '@/state/server';
66
import AllocationRow from '@/components/server/network/AllocationRow';
@@ -20,17 +20,15 @@ const NetworkContainer = () => {
2020
const allocations = ServerContext.useStoreState(state => state.server.data!.allocations, isEqual);
2121
const setServerFromState = ServerContext.useStoreActions(actions => actions.server.setServerFromState);
2222

23-
const { clearFlashes, clearAndAddHttpError } = useFlash();
23+
const { clearFlashes, clearAndAddHttpError } = useFlashKey('server:network');
2424
const { data, error, mutate } = getServerAllocations();
2525

2626
useEffect(() => {
2727
mutate(allocations);
2828
}, []);
2929

3030
useEffect(() => {
31-
if (error) {
32-
clearAndAddHttpError({ key: 'server:network', error });
33-
}
31+
clearAndAddHttpError(error);
3432
}, [ error ]);
3533

3634
useDeepCompareEffect(() => {
@@ -40,15 +38,15 @@ const NetworkContainer = () => {
4038
}, [ data ]);
4139

4240
const onCreateAllocation = () => {
43-
clearFlashes('server:network');
41+
clearFlashes();
4442

4543
setLoading(true);
4644
createServerAllocation(uuid)
4745
.then(allocation => {
4846
setServerFromState(s => ({ ...s, allocations: s.allocations.concat(allocation) }));
4947
return mutate(data?.concat(allocation), false);
5048
})
51-
.catch(error => clearAndAddHttpError({ key: 'server:network', error }))
49+
.catch(error => clearAndAddHttpError(error))
5250
.then(() => setLoading(false));
5351
};
5452

resources/scripts/components/server/schedules/DeleteScheduleButton.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { ServerContext } from '@/state/server';
44
import { Actions, useStoreActions } from 'easy-peasy';
55
import { ApplicationStore } from '@/state';
66
import { httpErrorToHuman } from '@/api/http';
7-
import tw from 'twin.macro';
8-
import Button from '@/components/elements/Button';
9-
import ConfirmationModal from '@/components/elements/ConfirmationModal';
7+
import { Button } from '@/components/elements/button/index';
8+
import { Dialog } from '@/components/elements/dialog';
9+
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
1010

1111
interface Props {
1212
scheduleId: number;
@@ -38,20 +38,23 @@ export default ({ scheduleId, onDeleted }: Props) => {
3838

3939
return (
4040
<>
41-
<ConfirmationModal
42-
visible={visible}
43-
title={'Delete schedule?'}
44-
buttonText={'Yes, delete schedule'}
41+
<Dialog.Confirm
42+
open={visible}
43+
onClose={() => setVisible(false)}
44+
title={'Delete Schedule'}
45+
confirm={'Delete'}
4546
onConfirmed={onDelete}
46-
showSpinnerOverlay={isLoading}
47-
onModalDismissed={() => setVisible(false)}
4847
>
49-
Are you sure you want to delete this schedule? All tasks will be removed and any running processes
50-
will be terminated.
51-
</ConfirmationModal>
52-
<Button css={tw`flex-1 sm:flex-none mr-4 border-transparent`} color={'red'} isSecondary onClick={() => setVisible(true)}>
48+
<SpinnerOverlay visible={isLoading} />
49+
All tasks will be removed and any running processes will be terminated.
50+
</Dialog.Confirm>
51+
<Button.Danger
52+
variant={Button.Variants.Secondary}
53+
className={'flex-1 sm:flex-none mr-4 border-transparent'}
54+
onClick={() => setVisible(true)}
55+
>
5356
Delete
54-
</Button>
57+
</Button.Danger>
5558
</>
5659
);
5760
};

resources/scripts/components/server/schedules/EditScheduleModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { httpErrorToHuman } from '@/api/http';
99
import FlashMessageRender from '@/components/FlashMessageRender';
1010
import useFlash from '@/plugins/useFlash';
1111
import tw from 'twin.macro';
12-
import Button from '@/components/elements/Button';
12+
import { Button } from '@/components/elements/button/index';
1313
import ModalContext from '@/context/ModalContext';
1414
import asModal from '@/hoc/asModal';
1515
import Switch from '@/components/elements/Switch';
@@ -135,7 +135,7 @@ const EditScheduleModal = ({ schedule }: Props) => {
135135
/>
136136
</div>
137137
<div css={tw`mt-6 text-right`}>
138-
<Button css={tw`w-full sm:w-auto`} type={'submit'} disabled={isSubmitting}>
138+
<Button className={'w-full sm:w-auto'} type={'submit'} disabled={isSubmitting}>
139139
{schedule ? 'Save changes' : 'Create schedule'}
140140
</Button>
141141
</div>

resources/scripts/components/server/schedules/NewTaskButton.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import React, { useState } from 'react';
22
import { Schedule } from '@/api/server/schedules/getServerSchedules';
33
import TaskDetailsModal from '@/components/server/schedules/TaskDetailsModal';
4-
import Button from '@/components/elements/Button';
5-
import tw from 'twin.macro';
4+
import { Button } from '@/components/elements/button/index';
65

76
interface Props {
87
schedule: Schedule;
@@ -14,7 +13,7 @@ export default ({ schedule }: Props) => {
1413
return (
1514
<>
1615
<TaskDetailsModal schedule={schedule} visible={visible} onModalDismissed={() => setVisible(false)}/>
17-
<Button onClick={() => setVisible(true)} css={tw`flex-1`}>
16+
<Button onClick={() => setVisible(true)} className={'flex-1'}>
1817
New Task
1918
</Button>
2019
</>

resources/scripts/components/server/schedules/RunScheduleButton.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { useCallback, useState } from 'react';
22
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
3-
import tw from 'twin.macro';
4-
import Button from '@/components/elements/Button';
3+
import { Button } from '@/components/elements/button/index';
54
import triggerScheduleExecution from '@/api/server/schedules/triggerScheduleExecution';
65
import { ServerContext } from '@/state/server';
76
import useFlash from '@/plugins/useFlash';
@@ -33,9 +32,8 @@ const RunScheduleButton = ({ schedule }: { schedule: Schedule }) => {
3332
<>
3433
<SpinnerOverlay visible={loading} size={'large'}/>
3534
<Button
36-
isSecondary
37-
color={'grey'}
38-
css={tw`flex-1 sm:flex-none border-transparent`}
35+
variant={Button.Variants.Secondary}
36+
className={'flex-1 sm:flex-none'}
3937
disabled={schedule.isProcessing}
4038
onClick={onTriggerExecute}
4139
>

resources/scripts/components/server/schedules/ScheduleContainer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Can from '@/components/elements/Can';
1111
import useFlash from '@/plugins/useFlash';
1212
import tw from 'twin.macro';
1313
import GreyRowBox from '@/components/elements/GreyRowBox';
14-
import Button from '@/components/elements/Button';
14+
import { Button } from '@/components/elements/button/index';
1515
import ServerContentBlock from '@/components/elements/ServerContentBlock';
1616

1717
export default () => {

0 commit comments

Comments
 (0)