Skip to content

Commit c8c288e

Browse files
show notification to copy api key when created
1 parent ac61742 commit c8c288e

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

Diff for: client/packages/lowcoder/src/i18n/locales/en.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3079,6 +3079,7 @@ export const en = {
30793079
"memberOfOrgs": "Workspaces Membership",
30803080
"apiKeys": "API Keys",
30813081
"createApiKey": "Create API Key",
3082+
"apiKeyInfo": "Make sure to copy your new API key now. You won't be able to see it again.",
30823083
"apiKeyName": "Name",
30833084
"apiKeyDescription": "Description",
30843085
"apiKeyCopy": "Click the Api Key to get the value in your clipboard",

Diff for: client/packages/lowcoder/src/pages/ApplicationV2/components/CreateApiKeyModal.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { validateResponse } from "api/apiUtils";
1313
import _ from "lodash";
1414
import { styled } from "styled-components";
1515
import UserApi, { ApiKeyPayload } from "api/userApi";
16+
import { ApiKeyType } from "./UserApiKeysCard";
1617

1718
const CustomModalStyled = styled(CustomModal)`
1819
button {
@@ -90,7 +91,7 @@ const FormStyled = styled(Form)`
9091
type CreateApiKeyModalProps = {
9192
modalVisible: boolean;
9293
closeModal: () => void;
93-
onConfigCreate: () => void;
94+
onConfigCreate: (apiKey?: ApiKeyType) => void;
9495
};
9596

9697
function CreateApiKeyModal(props: CreateApiKeyModalProps) {
@@ -101,6 +102,7 @@ function CreateApiKeyModal(props: CreateApiKeyModalProps) {
101102
} = props;
102103
const [form] = Form.useForm();
103104
const [saveLoading, setSaveLoading] = useState(false);
105+
const [apiKey, setApiKey] = useState<{id: string, token: string}>();
104106

105107
const handleOk = () => {
106108
form.validateFields().then(values => {
@@ -115,12 +117,15 @@ function CreateApiKeyModal(props: CreateApiKeyModalProps) {
115117
.then((resp) => {
116118
if (validateResponse(resp)) {
117119
messageInstance.success(trans("idSource.saveSuccess"));
120+
onConfigCreate(resp.data.data);
118121
}
119122
})
120-
.catch((e) => messageInstance.error(e.message))
123+
.catch((e) => {
124+
messageInstance.error(e.message);
125+
onConfigCreate();
126+
})
121127
.finally(() => {
122128
setSaveLoading(false);
123-
onConfigCreate();
124129
});
125130
}
126131

Diff for: client/packages/lowcoder/src/pages/ApplicationV2/components/UserApiKeysCard.tsx

+24-14
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import CreateApiKeyModal from "./CreateApiKeyModal";
1414
import { fetchApiKeysAction } from "redux/reduxActions/userActions";
1515
import UserApi from "@lowcoder-ee/api/userApi";
1616
import { validateResponse } from "@lowcoder-ee/api/apiUtils";
17+
import Alert from "antd/es/alert";
18+
import { CopyOutlined } from "@ant-design/icons";
1719

1820
const TableStyled = styled(Table)`
1921
.ant-table-tbody > tr > td {
@@ -37,10 +39,16 @@ const CreateButton = styled(TacoButton)`
3739
box-shadow: none;
3840
`;
3941

42+
export type ApiKeyType = {
43+
id: string;
44+
token: string;
45+
}
46+
4047
export default function UserApiKeysCard() {
4148
const dispatch = useDispatch();
4249
const apiKeys = useSelector(getApiKeys);
4350
const [modalVisible, setModalVisible] = useState(false);
51+
const [newApiKey, setNewApiKey] = useState<ApiKeyType>();
4452

4553
const handleCopy = (value: string) => {
4654
navigator.clipboard.writeText(value).then(() => {
@@ -66,13 +74,11 @@ export default function UserApiKeysCard() {
6674
{trans("profile.createApiKey")}
6775
</CreateButton>
6876
</Flex>
77+
{Boolean(newApiKey) && <Alert message={trans("profile.apiKeyInfo")} type="info" style={{marginBottom: '16px'}}/>}
6978
<TableStyled
7079
tableLayout={"auto"}
7180
scroll={{ x: "100%" }}
7281
pagination={false}
73-
onRow={(record) => ({
74-
75-
})}
7682
columns={[
7783
{
7884
title: trans("profile.apiKeyName"),
@@ -95,16 +101,19 @@ export default function UserApiKeysCard() {
95101
title: trans("profile.apiKey"),
96102
dataIndex: "token",
97103
ellipsis: true,
98-
render: (value: string) => {
99-
const startToken = value.substring(0, 6);
100-
const endToken = value.substring(value.length - 6);
101-
return (
102-
<Tooltip placement="topLeft" title={ trans("profile.apiKeyCopy")}>
103-
<div onClick={() => handleCopy(value)} style={{ cursor: 'pointer' }}>
104-
{`${startToken}********************${endToken}`}
105-
</div>
106-
</Tooltip>
107-
)
104+
render: (value: string, record: any) => {
105+
if (newApiKey?.id === record.id) {
106+
return (
107+
<Tooltip placement="topLeft" title={ trans("profile.apiKeyCopy")}>
108+
<div onClick={() => handleCopy(newApiKey?.token!)} style={{ cursor: 'pointer' }}>
109+
{value}
110+
&nbsp;
111+
<CopyOutlined />
112+
</div>
113+
</Tooltip>
114+
)
115+
}
116+
return <div>{value}</div>
108117
}
109118
},
110119
{ title: " ", dataIndex: "operation", width: "208px" },
@@ -145,8 +154,9 @@ export default function UserApiKeysCard() {
145154
<CreateApiKeyModal
146155
modalVisible={modalVisible}
147156
closeModal={() => setModalVisible(false)}
148-
onConfigCreate={() => {
157+
onConfigCreate={(apiKey?: ApiKeyType) => {
149158
setModalVisible(false);
159+
setNewApiKey(apiKey);
150160
dispatch(fetchApiKeysAction());
151161
}}
152162
/>

0 commit comments

Comments
 (0)