Skip to content

Commit 60d5f42

Browse files
Pive01HarshCasper
andauthored
prepare the 0.3.0 release (#20)
Co-authored-by: HarshCasper <erbeusgriffincasper@gmail.com>
1 parent f505d9d commit 60d5f42

27 files changed

+433
-89
lines changed

.github/images/2-configuration.png

17.6 KB
Loading

.github/images/3-logs.png

67.2 KB
Loading

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22

33
All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/).
44

5+
## [0.3.0] - 2023-01-10
6+
7+
### Added
8+
9+
- Interval of 2 seconds after which extension will refresh to check if an instance is running.
10+
- Added section to choose the LocalStack volume directory.
11+
- Added a button to change the LocalStack volume directory.
12+
- Added Card around logs to enhance their view.
13+
14+
### Changed
15+
16+
- Enhanced the **Update Images** button.
17+
- Removed the `EXTRA_CORS_ALLOWED_ORIGIN` from default configuration.
18+
519
## [0.2.0] - 2022-12-16
620

721
### Added

Dockerfile

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ LABEL org.opencontainers.image.title="LocalStack" \
2727
org.opencontainers.image.description="Extension of Localstack for Docker desktop" \
2828
org.opencontainers.image.vendor="LocalStack GmbH" \
2929
com.docker.desktop.extension.api.version=">= 0.2.3" \
30+
com.docker.extension.categories="cloud-development,testing-tools" \
3031
com.docker.desktop.extension.icon="https://avatars.githubusercontent.com/u/28732122?v=4" \
3132
com.docker.extension.screenshots="[ \
3233
{\"alt\": \"System status\", \"url\": \"https://raw.githubusercontent.com/localstack/localstack-docker-extension/main/.github/images/1-systemStatus.png\"}, \
@@ -49,21 +50,7 @@ LABEL org.opencontainers.image.title="LocalStack" \
4950
{\"title\":\"GitHub Repository\", \"url\":\"https://github.com/localstack/localstack-docker-extension\"}, \
5051
{\"title\":\"Feedback and Issues\", \"url\":\"https://github.com/localstack/localstack-docker-extension/issues\"}\
5152
]" \
52-
com.docker.extension.changelog="We have introduced a new feature:<br/> \
53-
<ul> \
54-
<li> You can now update your LocalStack images from the UI </li> \
55-
</ul> \
56-
We have made some changes in the UI: \
57-
<ul> \
58-
<li> Updates in the control section </li> \
59-
<li> Moved to a table to display saved configurations </li> \
60-
<li> Improved UI for inserting a new configuration </li> \
61-
</ul> \
62-
Bug fixes:<br/> \
63-
<ul> \
64-
<li> Made configuration persistent </li> \
65-
<li> Logs are correctly displayed </li> \
66-
</ul>"
53+
com.docker.extension.changelog="https://github.com/localstack/localstack-docker-extension/blob/main/CHANGELOG.md"
6754

6855
COPY --from=builder /backend/bin/service /
6956
COPY docker-compose.yaml .

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
IMAGE?=localstack/localstack-docker-desktop
2-
TAG?=0.2.0
2+
TAG?=0.3.0
33

44
BUILDER=buildx-multi-arch
55

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LocalStack empowers developers to use over 75+ AWS services locally while helpin
1111
You can install the LocalStack Extension for Docker Desktop via pulling our public Docker image from Docker Hub:
1212

1313
```bash
14-
docker extension install localstack/localstack-docker-desktop:0.2.0
14+
docker extension install localstack/localstack-docker-desktop:0.3.0
1515
```
1616

1717
To setup the Docker Extension by building the image locally, you can run the following commands:
@@ -20,7 +20,7 @@ To setup the Docker Extension by building the image locally, you can run the fol
2020
make install-extension
2121
```
2222

23-
It will build the Docker image and install the extension on your Docker Desktop application.
23+
It will build the Docker image and install the extension on your Docker Desktop application. After the installation, you will be prompted to select where LocalStack will be mounted. Open the drop-down and choose the username. You can additionally change this setting by navigating to the **Configurations** tab and selecting the mount point.
2424

2525
## Features
2626

ui/src/App.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import React, { useState } from 'react';
1+
import React, { ReactElement, useState } from 'react';
22
import { createStyles, makeStyles } from '@mui/styles';
3-
import { ControlledTabPanels, SystemStatus, Header, Logs, StartConfigs } from './components';
3+
import { ControlledTabPanels, Header, Logs, OnBoarding, StartConfigs, SystemStatus } from './components';
4+
import { useMountPoint } from './services/hooks';
45

56
const useStyles = makeStyles(() => createStyles({
67
sticky: {
@@ -10,12 +11,15 @@ const useStyles = makeStyles(() => createStyles({
1011
},
1112
}));
1213

13-
export function App() {
14+
export const App = (): ReactElement => {
1415
const [selected, setSelected] = useState<number>(0);
16+
const { data: mountPoint } = useMountPoint();
1517
const classes = useStyles();
18+
const shouldDialogOpen = !mountPoint || mountPoint === '';
1619

1720
return (
1821
<>
22+
{shouldDialogOpen && <OnBoarding />}
1923
<div className={classes.sticky}>
2024
<Header />
2125
</div>
@@ -39,4 +43,4 @@ export function App() {
3943
/>
4044
</>
4145
);
42-
}
46+
};

ui/src/components/Configs/ConfirmableButton.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export type BaseProps = {
2323
title: string;
2424
text?: string | JSX.Element;
2525
okText?: string;
26+
okColor?: ButtonProps['color'];
27+
cancelColor?: ButtonProps['color'];
2628
cancelText?: string;
2729
children?: ReactNode;
2830
}
@@ -39,6 +41,8 @@ export const ConfirmableButton = ({
3941
text,
4042
component = 'Button',
4143
okText,
44+
okColor,
45+
cancelColor,
4246
cancelText,
4347
children,
4448
...rest
@@ -66,14 +70,15 @@ export const ConfirmableButton = ({
6670
)}
6771
<DialogActions>
6872
<Button
73+
color= {cancelColor || 'primary'}
6974
variant="outlined"
7075
onClick={() => setShowConfirmDialog(false)}
7176
>
7277
{cancelText || 'Cancel'}
7378
</Button>
7479
<Button
7580
autoFocus
76-
color="error"
81+
color= {okColor || 'error'}
7782
variant="contained"
7883
onClick={(event: MouseEvent<HTMLButtonElement>) => {
7984
if (rest.onClick) rest.onClick(event as any); // eslint-disable-line
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
2+
import {
3+
Box,
4+
Button,
5+
CircularProgress,
6+
Dialog,
7+
DialogActions,
8+
DialogContent,
9+
FormControl,
10+
MenuItem,
11+
Select,
12+
Typography,
13+
} from '@mui/material';
14+
import React, { ReactElement, useEffect, useState } from 'react';
15+
import { useDDClient, useMountPoint } from '../../services/hooks';
16+
import { DockerImage } from '../../types';
17+
import { DownloadProgress } from '../DownloadProgress/DownloadProgress';
18+
19+
20+
export const OnBoarding = (): ReactElement => {
21+
const { setMountPointUser } = useMountPoint();
22+
const ddClient = useDDClient();
23+
const [userState, setUserState] = useState({ loading: false, selectedUser: '', users: [] });
24+
const [hasLocalImage, setHasLocalImage] = useState({ checking: true, isPresent: false });
25+
const [isPullingImage, setIsPullingImage] = useState(false);
26+
const [triggerUseEffect, setTriggerUseEffect] = useState(false);
27+
28+
const checkHomeDir = async () => {
29+
setUserState({ loading: true, selectedUser: userState.selectedUser, users: userState.users });
30+
const path = ddClient.host.platform === 'darwin' ? 'Users' : 'home';
31+
const res = await ddClient.docker.cli.exec('run',
32+
['--rm', '--entrypoint=', '-v', `/${path}:/users`, 'localstack/localstack', 'ls', '/users']);
33+
34+
if (res.stderr !== '' || res.stdout === '') {
35+
ddClient.desktopUI.toast.error(`Error while locating users: ${res.stderr}\n using /tmp as mount point`);
36+
setUserState({ loading: false, selectedUser: 'tmp', users: ['tmp'] });
37+
setMountPointUser('tmp');
38+
}
39+
const foundUsers = res.stdout.split('\n');
40+
foundUsers.pop(); // remove last '' element
41+
setUserState({ loading: false, selectedUser: foundUsers[0], users: foundUsers });
42+
};
43+
44+
const checkLocalImage = async () => {
45+
setHasLocalImage({ checking: true, isPresent: hasLocalImage.isPresent });
46+
const images = await ddClient.docker.listImages() as [DockerImage];
47+
const isPresent = images.filter(image => image.RepoTags?.at(0).split(':').at(0) === 'localstack/localstack');
48+
setHasLocalImage({ checking: false, isPresent: isPresent.length > 0 });
49+
return isPresent.length > 0;
50+
};
51+
52+
useEffect(() => {
53+
const execChecks = async () => {
54+
if (userState.users.length === 0) {
55+
const isImagePresent = await checkLocalImage();
56+
if (isImagePresent) {
57+
checkHomeDir();
58+
} else {
59+
setIsPullingImage(true);
60+
}
61+
}
62+
};
63+
64+
execChecks();
65+
}, [triggerUseEffect]);
66+
67+
const onClose = () => {
68+
setMountPointUser(userState.selectedUser);
69+
};
70+
71+
return (
72+
<Dialog open onClose={onClose}>
73+
<DialogContent>
74+
<Box >
75+
<Box marginBottom={5} display="flex" gap={5} alignItems="center">
76+
{hasLocalImage.checking &&
77+
<Typography>
78+
Checking for local LocalStack image
79+
</Typography>
80+
}
81+
{userState.loading &&
82+
<Typography>
83+
Checking for users
84+
</Typography>
85+
}
86+
{isPullingImage &&
87+
<>
88+
<Typography>
89+
Pulling localstack/localstack:latest... Please do not exit this view
90+
</Typography>
91+
<DownloadProgress callback={() => {
92+
setIsPullingImage(false);
93+
setTriggerUseEffect(!triggerUseEffect);
94+
}} />
95+
</>
96+
}
97+
{
98+
(hasLocalImage.checking || userState.loading) && <CircularProgress />
99+
}
100+
{
101+
userState.users.length > 0 &&
102+
<FormControl sx={{ minWidth: 120 }} size="small" variant='outlined'>
103+
<Select
104+
value={userState.selectedUser || userState.users[0]}
105+
onChange={({ target }) =>
106+
setUserState({ loading: userState.loading, selectedUser: target.value, users: userState.users })}
107+
>
108+
{userState.users.map(user => (
109+
<MenuItem key={user} value={user}>{user}</MenuItem>
110+
))}
111+
</Select>
112+
</FormControl>
113+
}
114+
</Box>
115+
<Typography variant='h3' gutterBottom>
116+
Select where LocalStack will be mounted
117+
</Typography>
118+
<Typography variant='subtitle2'>
119+
{`For MacOS users it will be under /Users/${userState.selectedUser || 'loading...'}/.localstack-volume`}
120+
</Typography>
121+
<Typography variant='subtitle2' gutterBottom>
122+
{`For Linux/Windows users it will be under \
123+
/home/${userState.selectedUser || 'loading...'}/.localstack-volume`}
124+
</Typography>
125+
</Box>
126+
</DialogContent>
127+
<DialogActions>
128+
<Button
129+
onClick={onClose}
130+
disabled={!userState.selectedUser || userState.selectedUser === ''}
131+
>
132+
Confirm
133+
</Button>
134+
</DialogActions>
135+
</Dialog >
136+
);
137+
};

ui/src/components/Configs/StartConfigs.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Add as AddIcon, Delete, Edit } from '@mui/icons-material';
2-
import { Box, Button, IconButton, Theme } from '@mui/material';
2+
import { Box, Button, ButtonGroup, IconButton, Theme } from '@mui/material';
33
import React, { ReactElement, useState } from 'react';
44
import { createStyles, makeStyles } from '@mui/styles';
55
import { DataGrid, GridColDef, GridRenderCellParams } from '@mui/x-data-grid';
66
import { v4 as uuid } from 'uuid';
7-
import { useRunConfig } from '../../services/hooks';
7+
import { useMountPoint, useRunConfig } from '../../services/hooks';
88
import { UpsertConfig } from './UpsertConfig';
99
import { Optional, RunConfig } from '../../types';
1010
import { DEFAULT_CONFIGURATION_ID } from '../../constants';
@@ -18,8 +18,8 @@ const useStyles = makeStyles((theme: Theme) => createStyles({
1818

1919
export const StartConfigs = (): ReactElement => {
2020

21-
const { deleteConfig } = useRunConfig();
22-
const { runConfig } = useRunConfig();
21+
const { runConfig, deleteConfig } = useRunConfig();
22+
const { setMountPointUser } = useMountPoint();
2323
const [openModal, setOpenModal] = useState<boolean>(false);
2424
const [targetConfig, setTargetConfig] = useState<RunConfig | null>(null);
2525

@@ -75,14 +75,18 @@ export const StartConfigs = (): ReactElement => {
7575
];
7676
return (
7777
<Box m={2}>
78-
<Button
79-
className={classes.addButton}
80-
endIcon={<AddIcon />}
81-
variant='contained'
82-
onClick={() => openModalSetup()}
83-
>
84-
New
85-
</Button>
78+
<ButtonGroup className={classes.addButton}>
79+
<Button
80+
endIcon={<AddIcon />}
81+
variant='contained'
82+
onClick={() => openModalSetup()}
83+
>
84+
New
85+
</Button>
86+
<Button onClick={() => setMountPointUser('')}>
87+
Change mount point
88+
</Button>
89+
</ButtonGroup>
8690
<Box sx={{ marginTop: 3 }}>
8791
<DataGrid
8892
autoHeight

0 commit comments

Comments
 (0)