Skip to content

Commit ff5554c

Browse files
committed
multiChanges: feat(listView): complete listView's code hint
- feat(listView): allow listView to expose data from inner comps - fix: input change triggered query exec not check dep status - feat(user) Allows admin to reset password - fix(i18n) fix bind email trans - fix(table): fix problem on pagination performance - feat: optimize message position
1 parent 105d1da commit ff5554c

File tree

29 files changed

+692
-155
lines changed

29 files changed

+692
-155
lines changed

client/packages/openblocks-design/src/components/CustomModal.tsx

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
import { ButtonProps, Modal as AntdModal } from "antd";
22
import { ModalFuncProps, ModalProps as AntdModalProps } from "antd/lib/modal";
33
import { ReactComponent as PackUpIcon } from "icons/icon-Pack-up.svg";
4-
import React, { ReactNode } from "react";
4+
import React, { ReactNode, useState } from "react";
55
import styled from "styled-components";
66
import { TacoButtonType, TacoButton } from "components/button";
77
import Draggable from "react-draggable";
88
import { DarkActiveTextColor, GreyTextColor } from "constants/style";
9-
import { CloseIcon } from "icons";
9+
import { CloseIcon, ErrorIcon, SuccessIcon, WarningIcon, WarningWhiteIcon } from "icons";
1010
import { trans } from "i18n/design";
1111

1212
type ModalWrapperProps = {
1313
width?: string | number;
1414
};
1515

16+
type Model = {
17+
destroy: () => void;
18+
update: (configUpdate: ModalFuncProps | ((prevConfig: ModalFuncProps) => ModalFuncProps)) => void;
19+
};
20+
1621
const ModalWrapper = styled.div<ModalWrapperProps>`
1722
display: flex;
1823
flex-direction: column;
@@ -39,6 +44,14 @@ const ModalHeaderTitle = styled.div`
3944
color: #222222;
4045
flex-grow: 1;
4146
min-width: 0;
47+
display: flex;
48+
align-items: center;
49+
50+
> svg {
51+
margin-right: 8px;
52+
height: 14px;
53+
width: 14px;
54+
}
4255
`;
4356

4457
const ModalCloseIcon = styled.div`
@@ -120,7 +133,8 @@ function ModalFooter(props: {
120133
showCancelButton?: boolean;
121134
showOkButton?: boolean;
122135
onCancel?: (e: React.MouseEvent<HTMLElement>) => void;
123-
onOk?: (e: React.MouseEvent<HTMLElement>) => void;
136+
onOk?: (e: React.MouseEvent<HTMLElement>) => Promise<any> | any;
137+
model?: Model;
124138
okButtonType?: TacoButtonType;
125139
autoFocusButton?: null | "ok" | "cancel";
126140
okButtonProps?: ButtonProps;
@@ -137,13 +151,16 @@ function ModalFooter(props: {
137151
autoFocusButton,
138152
okButtonProps,
139153
cancelButtonProps,
154+
model,
140155
} = props;
141156

157+
const [confirmLoading, setConfirmLoading] = useState(false);
158+
142159
return (
143160
<>
144161
{showCancelButton && (
145162
<TacoButton
146-
style={{ minWidth: "64px" }}
163+
style={{ minWidth: "66px" }}
147164
onClick={onCancel}
148165
autoFocus={autoFocusButton === "cancel"}
149166
{...cancelButtonProps}
@@ -153,10 +170,18 @@ function ModalFooter(props: {
153170
)}
154171
{showOkButton && (
155172
<TacoButton
156-
style={{ minWidth: "64px" }}
157-
onClick={onOk}
173+
style={{ minWidth: "66px" }}
174+
onClick={(e: React.MouseEvent<HTMLElement>) => {
175+
setConfirmLoading(true);
176+
const result = onOk && onOk(e);
177+
if (result && !!result.then) {
178+
return result.then(model && model.destroy).finally(() => setConfirmLoading(false));
179+
}
180+
model && model.destroy();
181+
}}
158182
autoFocus={autoFocusButton === "ok"}
159183
buttonType={okButtonType ?? "primary"}
184+
loading={confirmLoading}
160185
{...okButtonProps}
161186
>
162187
{okText ?? trans("ok")}
@@ -174,6 +199,7 @@ export type CustomModalProps = {
174199
showCancelButton?: boolean;
175200
children?: JSX.Element | React.ReactNode;
176201
okButtonType?: TacoButtonType;
202+
model?: Model;
177203
} & AntdModalProps;
178204

179205
const DEFAULT_PROPS = {
@@ -198,7 +224,7 @@ function CustomModalRender(props: CustomModalProps & ModalFuncProps) {
198224

199225
<div style={{ padding: "0 16px", ...props.bodyStyle }}>{props.children}</div>
200226

201-
{"footer" in props ? (
227+
{props.footer ? (
202228
props.footer
203229
) : (
204230
<ModalFooterWrapper>
@@ -223,15 +249,24 @@ function CustomModal(props: CustomModalProps) {
223249
);
224250
}
225251

252+
const TitleIcon = {
253+
error: <ErrorIcon />,
254+
warn: <WarningIcon />,
255+
info: <WarningWhiteIcon />,
256+
success: <SuccessIcon />,
257+
};
258+
226259
CustomModal.confirm = (props: {
227260
title?: string;
228261
content?: ReactNode;
229-
onConfirm: (e: React.MouseEvent<HTMLElement>) => Promise<any> | any;
262+
onConfirm?: (e: React.MouseEvent<HTMLElement>) => Promise<any> | any;
230263
onCancel?: () => void;
231264
confirmBtnType?: TacoButtonType;
232265
okText?: string;
233266
style?: React.CSSProperties;
234267
bodyStyle?: React.CSSProperties;
268+
footer?: ReactNode;
269+
type?: "info" | "warn" | "error" | "success";
235270
}): any => {
236271
const defaultConfirmProps: ModalFuncProps = {
237272
...DEFAULT_PROPS,
@@ -250,13 +285,20 @@ CustomModal.confirm = (props: {
250285
const model = AntdModal.confirm({
251286
width: "fit-content",
252287
style: props.style,
253-
zIndex: 2000,
254288
centered: true,
255289
onCancel: () => {
256290
model.destroy();
257291
props.onCancel?.();
258292
},
259293
});
294+
const title = props.type ? (
295+
<>
296+
{TitleIcon[props.type]}
297+
{props.title}
298+
</>
299+
) : (
300+
props.title
301+
);
260302
model.update({
261303
maskClosable: true,
262304
modalRender: () => (
@@ -267,17 +309,13 @@ CustomModal.confirm = (props: {
267309
props.onCancel?.();
268310
}}
269311
children={props.content}
270-
onOk={(e: React.MouseEvent<HTMLElement>) => {
271-
const result = props.onConfirm(e);
272-
if (result && !!result.then) {
273-
return result.then(model.destroy);
274-
}
275-
model.destroy();
276-
}}
277-
title={props.title}
312+
onOk={props.onConfirm}
313+
model={model}
314+
title={title}
278315
okButtonType={props.confirmBtnType}
279316
okText={props.okText}
280317
bodyStyle={{ ...defaultConfirmProps.bodyStyle, ...props.bodyStyle }}
318+
footer={props.footer}
281319
/>
282320
),
283321
});

client/packages/openblocks-design/src/components/button.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,14 @@ const TacoButton = forwardRef(
174174
const LoadingComp = !buttonType || buttonType === "link" ? LightLoading : Loading;
175175
return (
176176
<StyledAntdButton {...restProps} $buttonType={props.buttonType ?? "normal"} ref={ref}>
177-
{props.loading ? <LoadingComp /> : props.children}
177+
{props.loading ? (
178+
<LoadingComp
179+
backgroundColor={buttonType === "delete" ? "#fef4f4" : undefined}
180+
color={buttonType === "delete" ? "#f73131" : undefined}
181+
/>
182+
) : (
183+
props.children
184+
)}
178185
</StyledAntdButton>
179186
);
180187
}

client/packages/openblocks-design/src/components/eventHandler.tsx

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import styled from "styled-components";
2-
import { PointIcon } from "icons";
3-
import { EllipsisTextCss, labelCss } from "./Label";
4-
import { LinkButton, TacoButton } from "./button";
52
import { BluePlusIcon } from "icons";
3+
import { EllipsisTextCss, labelCss } from "./Label";
4+
import { LinkButton } from "./button";
65
import { ReactNode } from "react";
7-
import { ActiveTextColor, GreyTextColor } from "constants/style";
86
import { trans } from "i18n/design";
97

108
const InlineEventFormWrapper = styled.div`
@@ -50,14 +48,7 @@ const EventContent = styled.div`
5048
align-items: center;
5149
padding-left: 12px;
5250
`;
53-
const Icon = styled(PointIcon)`
54-
cursor: pointer;
55-
color: ${GreyTextColor};
5651

57-
&:hover {
58-
color: ${ActiveTextColor};
59-
}
60-
`;
6152
const EventTitle = styled.div`
6253
${labelCss};
6354
flex: 0 0 30%;
@@ -125,7 +116,6 @@ const AddLine = (props: { title: ReactNode; add: () => void }) => {
125116
);
126117
};
127118
export {
128-
Icon,
129119
BluePlusIcon as AddEventIcon,
130120
EventDiv,
131121
EventContent,

client/packages/openblocks-design/src/components/popover.tsx

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { SuspensionBox } from "./SuspensionBox";
22
import { Popover, PopoverProps } from "antd";
33
import { Children, cloneElement, MouseEvent, ReactNode, useState } from "react";
44
import styled from "styled-components";
5-
import { ActiveTextColor } from "constants/style";
5+
import { ActiveTextColor, GreyTextColor } from "constants/style";
66
import { trans } from "i18n/design";
7+
import { PointIcon } from "icons";
78

89
const Wedge = styled.div`
910
height: 8px;
@@ -35,6 +36,15 @@ const Handle = styled.div`
3536
}
3637
`;
3738

39+
const StyledPointIcon = styled(PointIcon)`
40+
cursor: pointer;
41+
color: ${GreyTextColor};
42+
43+
&:hover {
44+
color: ${ActiveTextColor};
45+
}
46+
`;
47+
3848
const SimplePopover = (props: {
3949
title: string;
4050
visible?: boolean;
@@ -106,7 +116,7 @@ const CustomPopover = (props: {
106116
export type EditPopoverItemType = { text: ReactNode; onClick: () => void; type?: "delete" };
107117

108118
export interface EditPopoverProps extends PopoverProps {
109-
children: React.ReactElement;
119+
children?: React.ReactElement;
110120
items?: EditPopoverItemType[]; // FIXME: refactor props below into this structure
111121
addText?: string;
112122
add?: () => void;
@@ -117,7 +127,16 @@ export interface EditPopoverProps extends PopoverProps {
117127

118128
// paste deleted popover
119129
const EditPopover = (props: EditPopoverProps) => {
120-
const { children, items, addText, add, rename, copy, del, ...popoverProps } = props;
130+
const {
131+
children = <StyledPointIcon tabIndex={-1} />,
132+
items,
133+
addText,
134+
add,
135+
rename,
136+
copy,
137+
del,
138+
...popoverProps
139+
} = props;
121140
const [visible, setVisible] = useState(false);
122141
const hide = () => {
123142
setVisible(false);

client/packages/openblocks/src/api/userApi.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class UserApi extends Api {
3636
static formLoginURL = "/auth/form/login";
3737
static markUserStatusURL = "/users/mark-status";
3838
static userDetailURL = (id: string) => `/users/userDetail/${id}`;
39+
static resetPasswordURL = `/users/reset-password`;
3940

4041
static formLogin(request: FormLoginRequest): AxiosPromise<ApiResponse> {
4142
const { invitationId, ...reqBody } = request;
@@ -85,6 +86,10 @@ class UserApi extends Api {
8586
static getUserDetail(userId: string): AxiosPromise<ApiResponse> {
8687
return Api.get(UserApi.userDetailURL(userId));
8788
}
89+
90+
static resetPassword(userId: string): AxiosPromise<ApiResponse> {
91+
return Api.post(UserApi.resetPasswordURL, { userId: userId });
92+
}
8893
}
8994

9095
export default UserApi;

client/packages/openblocks/src/components/PermissionDialog/AppPermissionDialog.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ const AppInviteView = (props: { appId: string }) => {
171171
buttonType="primary"
172172
onClick={() => {
173173
if (copy(inviteLink)) {
174-
message.success(trans("home.copySuccess"));
174+
message.success(trans("copySuccess"));
175175
} else {
176-
message.error(trans("home.copyErrorMessage"));
176+
message.error(trans("copyError"));
177177
}
178178
}}
179179
>

client/packages/openblocks/src/comps/comps/formComp/formComp.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ let FormTmpComp = class extends FormBaseComp implements IForm {
217217
}
218218
traverseFormItems(consumer: (item: GridItemComp) => boolean) {
219219
return traverseCompTree(this.getCompTree(), (item) => {
220-
return item.children.comp.children.formDataKey ? consumer(item) : true;
220+
return item.children.comp.children.formDataKey ? consumer(item as GridItemComp) : true;
221221
});
222222
}
223223
validateFormItems() {

0 commit comments

Comments
 (0)