Skip to content

Commit 9752906

Browse files
committed
[Feat]: Add event handlers on more column types
1 parent 2dedc8f commit 9752906

File tree

9 files changed

+163
-28
lines changed

9 files changed

+163
-28
lines changed

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/ColumnNumberComp.tsx

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { withDefault } from "comps/generators";
99
import styled from "styled-components";
1010
import { IconControl } from "comps/controls/iconControl";
1111
import { hasIcon } from "comps/utils";
12+
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
1213

1314
const InputNumberWrapper = styled.div`
1415
.ant-input-number {
@@ -25,6 +26,15 @@ const InputNumberWrapper = styled.div`
2526
}
2627
`;
2728

29+
const NumberViewWrapper = styled.div`
30+
cursor: pointer;
31+
display: flex;
32+
align-items: center;
33+
gap: 4px;
34+
`;
35+
36+
const NumberEventOptions = [clickEvent] as const;
37+
2838
const childrenMap = {
2939
text: NumberControl,
3040
step: withDefault(NumberControl, 1),
@@ -34,6 +44,7 @@ const childrenMap = {
3444
prefixIcon: IconControl,
3545
suffixIcon: IconControl,
3646
suffix: StringControl,
47+
onEvent: eventHandlerControl(NumberEventOptions),
3748
};
3849

3950
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, number, number> = (props) => props.text;
@@ -46,6 +57,7 @@ type NumberViewProps = {
4657
suffixIcon: ReactNode;
4758
float: boolean;
4859
precision: number;
60+
onEvent?: (eventName: string) => void;
4961
};
5062

5163
type NumberEditProps = {
@@ -66,16 +78,22 @@ const ColumnNumberView = React.memo((props: NumberViewProps) => {
6678
return result;
6779
}, [props.value, props.float, props.precision]);
6880

81+
const handleClick = useCallback(() => {
82+
if (props.onEvent) {
83+
props.onEvent("click");
84+
}
85+
}, [props.onEvent]);
86+
6987
return (
70-
<>
88+
<NumberViewWrapper onClick={handleClick}>
7189
{hasIcon(props.prefixIcon) && (
7290
<span>{props.prefixIcon}</span>
7391
)}
7492
<span>{props.prefix + formattedValue + props.suffix}</span>
7593
{hasIcon(props.suffixIcon) && (
7694
<span>{props.suffixIcon}</span>
7795
)}
78-
</>
96+
</NumberViewWrapper>
7997
);
8098
});
8199

@@ -197,6 +215,7 @@ export const ColumnNumberComp = (function () {
197215
children.step.dispatchChangeValueAction(String(newValue));
198216
}
199217
})}
218+
{children.onEvent.propertyView()}
200219
</>
201220
);
202221
})

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnAvatarsComp.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const Container = styled.div<{ $style: AvatarGroupStyleType | undefined, alignme
3838
cursor: pointer;
3939
`;
4040

41+
const AvatarEventOptions = [clickEvent, refreshEvent] as const;
42+
4143
const DropdownOption = new MultiCompBuilder(
4244
{
4345
src: StringControl,
@@ -46,6 +48,7 @@ const DropdownOption = new MultiCompBuilder(
4648
color: ColorControl,
4749
backgroundColor: ColorControl,
4850
Tooltip: StringControl,
51+
onEvent: eventHandlerControl(AvatarEventOptions),
4952
},
5053
(props) => props
5154
)
@@ -63,6 +66,7 @@ const DropdownOption = new MultiCompBuilder(
6366
{children.color.propertyView({ label: trans("style.fill") })}
6467
{children.backgroundColor.propertyView({ label: trans("style.background") })}
6568
{children.Tooltip.propertyView({ label: trans("badge.tooltip") })}
69+
{children.onEvent.propertyView()}
6670
</>
6771
);
6872
})
@@ -83,14 +87,16 @@ const MemoizedAvatar = React.memo(({
8387
style,
8488
autoColor,
8589
avatarSize,
86-
onEvent
90+
onEvent,
91+
onItemEvent
8792
}: {
8893
item: any;
8994
index: number;
9095
style: any;
9196
autoColor: boolean;
9297
avatarSize: number;
93-
onEvent: (event: string) => void;
98+
onEvent: (event: string) => void;
99+
onItemEvent?: (event: string) => void;
94100
}) => {
95101
const mountedRef = useRef(true);
96102

@@ -103,8 +109,15 @@ const MemoizedAvatar = React.memo(({
103109

104110
const handleClick = useCallback(() => {
105111
if (!mountedRef.current) return;
112+
113+
// Trigger individual avatar event first
114+
if (onItemEvent) {
115+
onItemEvent("click");
116+
}
117+
118+
// Then trigger main component event
106119
onEvent("click");
107-
}, [onEvent]);
120+
}, [onEvent, onItemEvent]);
108121

109122
return (
110123
<Tooltip title={item.Tooltip} key={index}>
@@ -114,6 +127,7 @@ const MemoizedAvatar = React.memo(({
114127
style={{
115128
color: item.color ? item.color : (style.fill !== '#FFFFFF' ? style.fill : '#FFFFFF'),
116129
backgroundColor: item.backgroundColor ? item.backgroundColor : (autoColor ? MacaroneList[index % MacaroneList.length] : style.background),
130+
cursor: 'pointer',
117131
}}
118132
size={avatarSize}
119133
onClick={handleClick}
@@ -162,6 +176,7 @@ const MemoizedAvatarGroup = React.memo(({
162176
autoColor={autoColor}
163177
avatarSize={avatarSize}
164178
onEvent={onEvent}
179+
onItemEvent={item.onEvent}
165180
/>
166181
))}
167182
</Avatar.Group>

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnImgComp.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,28 @@ import { withDefault } from "comps/generators";
1010
import { TacoImage } from "lowcoder-design";
1111
import styled from "styled-components";
1212
import { DEFAULT_IMG_URL } from "@lowcoder-ee/util/stringUtils";
13+
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
1314

1415
export const ColumnValueTooltip = trans("table.columnValueTooltip");
1516

1617
const childrenMap = {
1718
src: withDefault(StringControl, "{{currentCell}}"),
1819
size: withDefault(NumberControl, "50"),
20+
onEvent: eventHandlerControl([clickEvent]),
1921
};
2022

2123
const StyledTacoImage = styled(TacoImage)`
22-
pointer-events: auto;
24+
pointer-events: auto !important;
25+
cursor: pointer !important;
26+
27+
&:hover {
28+
opacity: 0.8;
29+
transition: opacity 0.2s ease;
30+
}
2331
`;
2432

2533
// Memoized image component
26-
const ImageView = React.memo(({ src, size }: { src: string; size: number }) => {
34+
const ImageView = React.memo(({ src, size, onEvent }: { src: string; size: number; onEvent?: (eventName: string) => void }) => {
2735
const mountedRef = useRef(true);
2836

2937
// Cleanup on unmount
@@ -33,10 +41,19 @@ const ImageView = React.memo(({ src, size }: { src: string; size: number }) => {
3341
};
3442
}, []);
3543

44+
const handleClick = useCallback(() => {
45+
console.log("Image clicked!", { src, onEvent: !!onEvent }); // Debug log
46+
if (mountedRef.current && onEvent) {
47+
onEvent("click");
48+
}
49+
}, [onEvent, src]);
50+
3651
return (
3752
<StyledTacoImage
3853
src={src || DEFAULT_IMG_URL}
3954
width={size}
55+
onClick={handleClick}
56+
style={{ cursor: 'pointer' }} // Inline style as backup
4057
/>
4158
);
4259
});
@@ -96,7 +113,7 @@ export const ImageComp = (function () {
96113
childrenMap,
97114
(props, dispatch) => {
98115
const value = props.changeValue ?? getBaseValue(props, dispatch);
99-
return <ImageView src={value} size={props.size} />;
116+
return <ImageView src={value} size={props.size} onEvent={props.onEvent} />;
100117
},
101118
(nodeValue) => nodeValue.src.value,
102119
getBaseValue
@@ -118,6 +135,7 @@ export const ImageComp = (function () {
118135
{children.size.propertyView({
119136
label: trans("table.imageSize"),
120137
})}
138+
{children.onEvent.propertyView()}
121139
</>
122140
);
123141
})

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnLinksComp.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const OptionItem = new MultiCompBuilder(
7070
.build();
7171

7272
// Memoized menu item component
73-
const MenuItem = React.memo(({ option, index }: { option: any; index: number }) => {
73+
const MenuItem = React.memo(({ option, index, onMainEvent }: { option: any; index: number; onMainEvent?: (eventName: string) => void }) => {
7474
const handleClick = useCallback(() => {
7575
if (!option.disabled) {
7676
if (option.onClick) {
@@ -79,8 +79,12 @@ const MenuItem = React.memo(({ option, index }: { option: any; index: number })
7979
if (option.onEvent) {
8080
option.onEvent("click");
8181
}
82+
// Trigger the main component's event handler
83+
if (onMainEvent) {
84+
onMainEvent("click");
85+
}
8286
}
83-
}, [option.disabled, option.onClick, option.onEvent]);
87+
}, [option.disabled, option.onClick, option.onEvent, onMainEvent]);
8488

8589
return (
8690
<MenuLinkWrapper>
@@ -96,7 +100,7 @@ const MenuItem = React.memo(({ option, index }: { option: any; index: number })
96100
MenuItem.displayName = 'MenuItem';
97101

98102
// Memoized menu component
99-
const LinksMenu = React.memo(({ options }: { options: any[] }) => {
103+
const LinksMenu = React.memo(({ options, onEvent }: { options: any[]; onEvent?: (eventName: string) => void }) => {
100104
const mountedRef = useRef(true);
101105

102106
// Cleanup on unmount
@@ -111,9 +115,9 @@ const LinksMenu = React.memo(({ options }: { options: any[] }) => {
111115
.filter((o) => !o.hidden)
112116
.map((option, index) => ({
113117
key: index,
114-
label: <MenuItem option={option} index={index} />
118+
label: <MenuItem option={option} index={index} onMainEvent={onEvent} />
115119
})),
116-
[options]
120+
[options, onEvent]
117121
);
118122

119123
return (
@@ -130,11 +134,12 @@ export const ColumnLinksComp = (function () {
130134
options: manualOptionsControl(OptionItem, {
131135
initOptions: [{ label: trans("table.option1") }],
132136
}),
137+
onEvent: eventHandlerControl(LinksEventOptions),
133138
};
134139
return new ColumnTypeCompBuilder(
135140
childrenMap,
136141
(props) => {
137-
return <LinksMenu options={props.options} />;
142+
return <LinksMenu options={props.options} onEvent={props.onEvent} />;
138143
},
139144
() => ""
140145
)
@@ -144,6 +149,7 @@ export const ColumnLinksComp = (function () {
144149
newOptionLabel: trans("table.option"),
145150
title: trans("table.optionList"),
146151
})}
152+
{children.onEvent.propertyView()}
147153
</>
148154
))
149155
.build();

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnMarkdownComp.tsx

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import { StringControl } from "comps/controls/codeControl";
99
import { trans } from "i18n";
1010
import { markdownCompCss, TacoMarkDown } from "lowcoder-design";
1111
import styled from "styled-components";
12+
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
1213

1314
const Wrapper = styled.div`
1415
${markdownCompCss};
1516
max-height: 32px;
17+
cursor: pointer;
1618
1719
> .markdown-body {
1820
margin: 0;
@@ -22,16 +24,25 @@ const Wrapper = styled.div`
2224
}
2325
`;
2426

27+
const MarkdownEventOptions = [clickEvent] as const;
28+
2529
const childrenMap = {
2630
text: StringControl,
31+
onEvent: eventHandlerControl(MarkdownEventOptions),
2732
};
2833

2934
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string, string> = (props) => props.text;
3035

3136
// Memoized markdown view component
32-
const MarkdownView = React.memo(({ value }: { value: string }) => {
37+
const MarkdownView = React.memo(({ value, onEvent }: { value: string; onEvent?: (eventName: string) => void }) => {
38+
const handleClick = useCallback(() => {
39+
if (onEvent) {
40+
onEvent("click");
41+
}
42+
}, [onEvent]);
43+
3344
return (
34-
<Wrapper>
45+
<Wrapper onClick={handleClick}>
3546
<TacoMarkDown>{value}</TacoMarkDown>
3647
</Wrapper>
3748
);
@@ -92,7 +103,7 @@ export const ColumnMarkdownComp = (function () {
92103
childrenMap,
93104
(props, dispatch) => {
94105
const value = props.changeValue ?? getBaseValue(props, dispatch);
95-
return <MarkdownView value={value} />;
106+
return <MarkdownView value={value} onEvent={props.onEvent} />;
96107
},
97108
(nodeValue) => nodeValue.text.value,
98109
getBaseValue
@@ -110,6 +121,7 @@ export const ColumnMarkdownComp = (function () {
110121
label: trans("table.columnValue"),
111122
tooltip: ColumnValueTooltip,
112123
})}
124+
{children.onEvent.propertyView()}
113125
</>
114126
))
115127
.build();

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnSelectComp.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ const SelectOptionWithEventsControl = optionsControl(SelectOptionWithEvents, {
116116
const childrenMap = {
117117
text: StringControl,
118118
options: SelectOptionWithEventsControl,
119+
onEvent: eventHandlerControl(SelectOptionEventOptions),
119120
};
120121

121122
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string, string> = (props) => props.text;
@@ -125,6 +126,7 @@ type SelectEditProps = {
125126
onChange: (value: string) => void;
126127
onChangeEnd: () => void;
127128
options: any[];
129+
onMainEvent?: (eventName: string) => void;
128130
};
129131

130132
const SelectEdit = React.memo((props: SelectEditProps) => {
@@ -150,7 +152,12 @@ const SelectEdit = React.memo((props: SelectEditProps) => {
150152
if (selectedOption && selectedOption.onEvent) {
151153
selectedOption.onEvent("click");
152154
}
153-
}, [props.onChange, props.options]);
155+
156+
// Also trigger the main component's event handler
157+
if (props.onMainEvent) {
158+
props.onMainEvent("click");
159+
}
160+
}, [props.onChange, props.options, props.onMainEvent]);
154161

155162
const handleEvent = useCallback(async (eventName: string) => {
156163
if (!mountedRef.current) return [] as unknown[];
@@ -203,6 +210,7 @@ export const ColumnSelectComp = (function () {
203210
options={props.otherProps?.options || []}
204211
onChange={props.onChange}
205212
onChangeEnd={props.onChangeEnd}
213+
onMainEvent={props.otherProps?.onEvent}
206214
/>
207215
</Wrapper>
208216
)
@@ -217,6 +225,7 @@ export const ColumnSelectComp = (function () {
217225
{children.options.propertyView({
218226
title: trans("optionsControl.optionList"),
219227
})}
228+
{children.onEvent.propertyView()}
220229
</>
221230
);
222231
})

0 commit comments

Comments
 (0)