feat(config-ui): adjust the config-ui about cognito (#4933)
diff --git a/config-ui/src/App.tsx b/config-ui/src/App.tsx
index 5f5299c..f655349 100644
--- a/config-ui/src/App.tsx
+++ b/config-ui/src/App.tsx
@@ -37,30 +37,45 @@
function App() {
return (
<Router history={history}>
- <BaseLayout>
- <Switch>
- <Route path="/" exact component={() => <Redirect to="/projects" />} />
- <Route exact path="/login" component={() => <LoginPage />} />
- <Route exact path="/projects" component={() => <ProjectHomePage />} />
- <Route exact path="/projects/:pname" component={() => <ProjectDetailPage />} />
- <Route exact path="/projects/:pname/:bid/connection-add" component={() => <BlueprintConnectioAddPage />} />
- <Route exact path="/projects/:pname/:bid/:unique" component={() => <BlueprintConnectionDetailPage />} />
- <Route
- exact
- path="/projects/:pname/create-blueprint"
- component={() => <BlueprintCreatePage from={FromEnum.project} />}
- />
- <Route exact path="/connections" component={() => <ConnectionHomePage />} />
- <Route exact path="/connections/:plugin" component={() => <ConnectionListPage />} />
- <Route exact path="/connections/:plugin/create" component={() => <ConnectionFormPage />} />
- <Route exact path="/connections/:plugin/:cid" component={() => <ConnectionFormPage />} />
- <Route exact path="/blueprints" component={() => <BlueprintHomePage />} />
- <Route exact path="/blueprints/create" component={() => <BlueprintCreatePage from={FromEnum.blueprint} />} />
- <Route exact path="/blueprints/:id" component={() => <BlueprintDetailPage />} />
- <Route exact path="/blueprints/:bid/connection-add" component={() => <BlueprintConnectioAddPage />} />
- <Route exact path="/blueprints/:bid/:unique" component={() => <BlueprintConnectionDetailPage />} />
- </Switch>
- </BaseLayout>
+ <Switch>
+ <Route exact path="/login" component={() => <LoginPage />} />
+ <Route
+ path="/"
+ component={() => (
+ <BaseLayout>
+ <Switch>
+ <Route exact path="/" component={() => <Redirect to="/projects" />} />
+ <Route exact path="/projects" component={() => <ProjectHomePage />} />
+ <Route exact path="/projects/:pname" component={() => <ProjectDetailPage />} />
+ <Route
+ exact
+ path="/projects/:pname/:bid/connection-add"
+ component={() => <BlueprintConnectioAddPage />}
+ />
+ <Route exact path="/projects/:pname/:bid/:unique" component={() => <BlueprintConnectionDetailPage />} />
+ <Route
+ exact
+ path="/projects/:pname/create-blueprint"
+ component={() => <BlueprintCreatePage from={FromEnum.project} />}
+ />
+ <Route exact path="/connections" component={() => <ConnectionHomePage />} />
+ <Route exact path="/connections/:plugin" component={() => <ConnectionListPage />} />
+ <Route exact path="/connections/:plugin/create" component={() => <ConnectionFormPage />} />
+ <Route exact path="/connections/:plugin/:cid" component={() => <ConnectionFormPage />} />
+ <Route exact path="/blueprints" component={() => <BlueprintHomePage />} />
+ <Route
+ exact
+ path="/blueprints/create"
+ component={() => <BlueprintCreatePage from={FromEnum.blueprint} />}
+ />
+ <Route exact path="/blueprints/:id" component={() => <BlueprintDetailPage />} />
+ <Route exact path="/blueprints/:bid/connection-add" component={() => <BlueprintConnectioAddPage />} />
+ <Route exact path="/blueprints/:bid/:unique" component={() => <BlueprintConnectionDetailPage />} />
+ </Switch>
+ </BaseLayout>
+ )}
+ />
+ </Switch>
</Router>
);
}
diff --git a/config-ui/src/layouts/base/base.tsx b/config-ui/src/layouts/base/base.tsx
index 2534b8a..20044b0 100644
--- a/config-ui/src/layouts/base/base.tsx
+++ b/config-ui/src/layouts/base/base.tsx
@@ -132,7 +132,7 @@
<span>Slack</span>
</a>
<Navbar.Divider />
- <Button intent={Intent.NONE} onClick={handleSignOut}>
+ <Button small intent={Intent.NONE} onClick={handleSignOut}>
Sign Out
</Button>
</Navbar.Group>
diff --git a/config-ui/src/pages/login/api.ts b/config-ui/src/pages/login/api.ts
new file mode 100644
index 0000000..c5a7493
--- /dev/null
+++ b/config-ui/src/pages/login/api.ts
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { request } from '@/utils';
+
+type LoginPayload = {
+ username: string;
+ password: string;
+};
+
+export const login = (payload: LoginPayload) => request(`/login`, { method: 'post', data: payload });
diff --git a/config-ui/src/pages/login/login.tsx b/config-ui/src/pages/login/login.tsx
index cf4d8e9..ce097c6 100644
--- a/config-ui/src/pages/login/login.tsx
+++ b/config-ui/src/pages/login/login.tsx
@@ -16,53 +16,58 @@
*
*/
-import { request } from '@/utils';
-import React, { useState, ChangeEvent, FormEvent } from 'react';
+import { useState } from 'react';
import { useHistory } from 'react-router-dom';
+import { FormGroup, InputGroup, Button, Intent } from '@blueprintjs/core';
+
+import { operator } from '@/utils';
+
+import * as API from './api';
+import * as S from './styld';
export const LoginPage = () => {
- const [username, setUsername] = useState<string>('');
- const [password, setPassword] = useState<string>('');
+ const [username, setUsername] = useState('');
+ const [password, setPassword] = useState('');
+
const history = useHistory();
- const handleSubmit = (e: FormEvent) => {
- e.preventDefault();
- const payload = { username, password };
- try {
- login(payload).then((r) => {
- localStorage.setItem('accessToken', r.AuthenticationResult.AccessToken);
- history.push('/projects');
- });
- } catch (error) {
- console.error('Error during login:', error);
- // Handle login error here, e.g. show a message to the user
+ const handleSubmit = async () => {
+ const [success, res] = await operator(() => API.login({ username, password }), {
+ formatReason: (error) => 'Login failed',
+ });
+
+ if (success) {
+ localStorage.setItem('accessToken', res.AuthenticationResult.AccessToken);
+ history.push('/');
}
+
+ setUsername('');
+ setPassword('');
};
return (
- <div>
- <h2>"login"</h2>
- <form onSubmit={handleSubmit}>
- <div>
- <label>Username:</label>
- <input
- type="text"
+ <S.Wrapper>
+ <S.Inner>
+ <h2>DevLake Login</h2>
+ <FormGroup label="Username">
+ <InputGroup
+ placeholder="Username"
value={username}
- onChange={(e: ChangeEvent<HTMLInputElement>) => setUsername(e.target.value)}
+ onChange={(e) => setUsername((e.target as HTMLInputElement).value)}
/>
- </div>
- <div>
- <label>Password:</label>
- <input
+ </FormGroup>
+ <FormGroup label="Password">
+ <InputGroup
type="password"
+ placeholder="Password"
value={password}
- onChange={(e: ChangeEvent<HTMLInputElement>) => setPassword(e.target.value)}
+ onChange={(e) => setPassword((e.target as HTMLInputElement).value)}
/>
- </div>
- <button type="submit">login</button>
- </form>
- </div>
+ </FormGroup>
+ <Button intent={Intent.PRIMARY} onClick={handleSubmit}>
+ Login
+ </Button>
+ </S.Inner>
+ </S.Wrapper>
);
};
-
-export const login = (payload: any) => request(`/login`, { method: 'post', data: payload });
diff --git a/config-ui/src/pages/login/styld.ts b/config-ui/src/pages/login/styld.ts
new file mode 100644
index 0000000..e12cfad
--- /dev/null
+++ b/config-ui/src/pages/login/styld.ts
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import styled from 'styled-components';
+
+export const Wrapper = styled.div`
+ height: 100vh;
+ background-color: #f5f5f5;
+ overflow: hidden;
+`;
+
+export const Inner = styled.div`
+ margin: 200px auto;
+ padding: 16px 24px;
+ width: 400px;
+ background-color: #fff;
+ border-raidus: 4px;
+ box-shadow: 0px 2.4px 4.8px -0.8px rgba(0, 0, 0, 0.1), 0px 1.6px 8px rgba(0, 0, 0, 0.07);
+
+ h2 {
+ margin-bottom: 16px;
+ text-align: center;
+ }
+`;
diff --git a/config-ui/src/utils/request.ts b/config-ui/src/utils/request.ts
index 5b66b77..2fb8ba5 100644
--- a/config-ui/src/utils/request.ts
+++ b/config-ui/src/utils/request.ts
@@ -21,6 +21,7 @@
import { history } from '@/utils/history';
import { DEVLAKE_ENDPOINT } from '@/config';
+import { toast } from '@/components/toast';
const instance = axios.create({
baseURL: DEVLAKE_ENDPOINT,
@@ -55,7 +56,7 @@
(response) => response,
(error) => {
if (error.response && error.response.status === 401) {
- console.log('401 error');
+ toast.error('Please log in first');
history.push('/login');
}
},