Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4aa6d92

Browse files
committed
Merge branch 'dev' of github.com:lowcoder-org/lowcoder into feat/1289-customize-drawer-close
2 parents 99ce13d + ba30103 commit 4aa6d92

File tree

27 files changed

+403
-78
lines changed

27 files changed

+403
-78
lines changed

‎client/packages/lowcoder/src/comps/comps/buttonComp/scannerComp.tsx‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import React, {
3030
useState,
3131
useContext,
3232
} from "react";
33-
import { arrayStringExposingStateControl } from "comps/controls/codeStateControl";
33+
import { arrayStringExposingStateControl,stringExposingStateControl } from "comps/controls/codeStateControl";
3434
import { BoolControl } from "comps/controls/boolControl";
3535
import { RefControl } from "comps/controls/refControl";
3636
import { EditorContext } from "comps/editorState";
@@ -120,6 +120,7 @@ const BarcodeScannerComponent = React.lazy(
120120
const ScannerTmpComp = (function () {
121121
const childrenMap = {
122122
data: arrayStringExposingStateControl("data"),
123+
value: stringExposingStateControl("value"),
123124
text: withDefault(StringControl, trans("scanner.text")),
124125
continuous: BoolControl,
125126
uniqueData: withDefault(BoolControl, true),
@@ -150,17 +151,27 @@ const ScannerTmpComp = (function () {
150151
}, [success, showModal]);
151152

152153
const continuousValue = useRef<string[]>([]);
154+
const seenSetRef = useRef<Set<string>>(new Set());
153155

154156
const handleUpdate = (err: any, result: any) => {
155157
if (result) {
156158
if (props.continuous) {
157-
continuousValue.current = [...continuousValue.current, result.text];
159+
const scannedText: string = result.text;
160+
if (props.uniqueData && seenSetRef.current.has(scannedText)) {
161+
return;
162+
}
163+
continuousValue.current = [...continuousValue.current, scannedText];
164+
if (props.uniqueData) {
165+
seenSetRef.current.add(scannedText);
166+
}
158167
const val = props.uniqueData
159168
? [...new Set(continuousValue.current)]
160169
: continuousValue.current;
170+
props.value.onChange(scannedText);
161171
props.data.onChange(val);
162172
props.onEvent("success");
163173
} else {
174+
props.value.onChange(result.text);
164175
props.data.onChange([result.text]);
165176
setShowModal(false);
166177
setSuccess(true);
@@ -205,6 +216,7 @@ const ScannerTmpComp = (function () {
205216
props.onEvent("click");
206217
setShowModal(true);
207218
continuousValue.current = [];
219+
seenSetRef.current = new Set();
208220
}}
209221
>
210222
<span>{props.text}</span>
@@ -317,6 +329,7 @@ const ScannerTmpComp = (function () {
317329

318330
export const ScannerComp = withExposingConfigs(ScannerTmpComp, [
319331
new NameConfig("data", trans("data")),
332+
new NameConfig("value", trans("value")),
320333
new NameConfig("text", trans("button.textDesc")),
321334
...CommonNameConfig,
322335
]);

‎client/packages/lowcoder/src/comps/comps/formComp/formComp.tsx‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -390,15 +390,24 @@ let FormTmpComp = class extends FormBaseComp implements IForm {
390390
if (ret.children.initialData !== this.children.initialData) {
391391
// FIXME: kill setTimeout ?
392392
setTimeout(() => {
393-
this.dispatch(
394-
customAction<SetDataAction>(
395-
{
396-
type: "setData",
397-
initialData: (action.value["initialData"] as ValueAndMsg<JSONObject>).value || {},
398-
},
399-
false
400-
)
401-
);
393+
const newInitialData = (action.value["initialData"] as ValueAndMsg<JSONObject>)
394+
.value;
395+
// only setData when initialData has explicit keys.
396+
if (
397+
newInitialData &&
398+
typeof newInitialData === "object" &&
399+
Object.keys(newInitialData).length > 0
400+
) {
401+
this.dispatch(
402+
customAction<SetDataAction>(
403+
{
404+
type: "setData",
405+
initialData: newInitialData,
406+
},
407+
false
408+
)
409+
);
410+
}
402411
}, 1000);
403412
}
404413
return ret;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
2+
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
3+
import { MultiCompBuilder } from "comps/generators/multi";
4+
import { dropdownControl } from "comps/controls/dropdownControl";
5+
import { mapOptionsControl } from "comps/controls/optionsControl";
6+
import { trans } from "i18n";
7+
import { navListComp } from "../navItemComp";
8+
import { controlItem } from "lowcoder-design";
9+
import { menuPropertyView } from "./MenuItemList";
10+
11+
export function createNavItemsControl() {
12+
const OptionTypes = [
13+
{ label: trans("prop.manual"), value: "manual" },
14+
{ label: trans("prop.map"), value: "map" },
15+
] as const;
16+
17+
const NavMapOption = new MultiCompBuilder(
18+
{
19+
label: StringControl,
20+
hidden: BoolCodeControl,
21+
disabled: BoolCodeControl,
22+
active: BoolCodeControl,
23+
onEvent: eventHandlerControl([clickEvent]),
24+
},
25+
(props) => props
26+
)
27+
.setPropertyViewFn((children) => (
28+
<>
29+
{children.label.propertyView({ label: trans("label"), placeholder: "{{item}}" })}
30+
{children.active.propertyView({ label: trans("navItemComp.active") })}
31+
{children.hidden.propertyView({ label: trans("hidden") })}
32+
{children.disabled.propertyView({ label: trans("disabled") })}
33+
{children.onEvent.getPropertyView()}
34+
</>
35+
))
36+
.build();
37+
38+
const TmpNavItemsControl = new MultiCompBuilder(
39+
{
40+
optionType: dropdownControl(OptionTypes, "manual"),
41+
manual: navListComp(),
42+
mapData: mapOptionsControl(NavMapOption),
43+
},
44+
(props) => {
45+
return props.optionType === "manual" ? props.manual : props.mapData;
46+
}
47+
)
48+
.setPropertyViewFn(() => {
49+
throw new Error("Method not implemented.");
50+
})
51+
.build();
52+
53+
return class NavItemsControl extends TmpNavItemsControl {
54+
exposingNode() {
55+
return this.children.optionType.getView() === "manual"
56+
? (this.children.manual as any).exposingNode()
57+
: (this.children.mapData as any).exposingNode();
58+
}
59+
60+
propertyView() {
61+
const isManual = this.children.optionType.getView() === "manual";
62+
const content = isManual
63+
? menuPropertyView(this.children.manual as any)
64+
: this.children.mapData.getPropertyView();
65+
66+
return controlItem(
67+
{ searchChild: true },
68+
<>
69+
{this.children.optionType.propertyView({ radioButton: true, type: "oneline" })}
70+
{content}
71+
</>
72+
);
73+
}
74+
};
75+
}
76+
77+

‎client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx‎

Lines changed: 70 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { NameConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
2+
import { MultiCompBuilder } from "comps/generators/multi";
23
import { UICompBuilder, withDefault } from "comps/generators";
34
import { Section, sectionNames } from "lowcoder-design";
45
import styled from "styled-components";
56
import { clickEvent, eventHandlerControl } from "comps/controls/eventHandlerControl";
6-
import { StringControl } from "comps/controls/codeControl";
7+
import { BoolCodeControl,StringControl } from "comps/controls/codeControl";
78
import { alignWithJustifyControl } from "comps/controls/alignControl";
89
import { navListComp } from "./navItemComp";
910
import { menuPropertyView } from "./components/MenuItemList";
@@ -22,6 +23,8 @@ import { trans } from "i18n";
2223

2324
import { useContext } from "react";
2425
import { EditorContext } from "comps/editorState";
26+
import { controlItem } from "lowcoder-design";
27+
import { createNavItemsControl } from "./components/NavItemsControl";
2528

2629
type IProps = {
2730
$justify: boolean;
@@ -63,11 +66,12 @@ const Item = styled.div<{
6366
$padding: string;
6467
$textTransform:string;
6568
$textDecoration:string;
69+
$disabled?: boolean;
6670
}>`
6771
height: 30px;
6872
line-height: 30px;
6973
padding: ${(props) => props.$padding ? props.$padding : '0 16px'};
70-
color: ${(props) => (props.$active ? props.$activeColor : props.$color)};
74+
color: ${(props) => props.$disabled ? `${props.$color}80` : (props.$active ? props.$activeColor : props.$color)};
7175
font-weight: ${(props) => (props.$textWeight ? props.$textWeight : 500)};
7276
font-family:${(props) => (props.$fontFamily ? props.$fontFamily : 'sans-serif')};
7377
font-style:${(props) => (props.$fontStyle ? props.$fontStyle : 'normal')};
@@ -77,8 +81,8 @@ const Item = styled.div<{
7781
margin:${(props) => props.$margin ? props.$margin : '0px'};
7882
7983
&:hover {
80-
color: ${(props) => props.$activeColor};
81-
cursor: pointer;
84+
color: ${(props) => props.$disabled ? (props.$active ? props.$activeColor : props.$color) : props.$activeColor};
85+
cursor: ${(props)=>props.$disabled ? 'not-allowed' : 'pointer'};
8286
}
8387
8488
.anticon {
@@ -131,41 +135,74 @@ function fixOldStyleData(oldData: any) {
131135
return oldData;
132136
}
133137

138+
function fixOldItemsData(oldData: any) {
139+
if (Array.isArray(oldData)) {
140+
return {
141+
optionType: "manual",
142+
manual: oldData,
143+
};
144+
}
145+
if (oldData && !oldData.optionType && Array.isArray(oldData.manual)) {
146+
return {
147+
optionType: "manual",
148+
manual: oldData.manual,
149+
};
150+
}
151+
return oldData;
152+
}
153+
134154
const childrenMap = {
135155
logoUrl: StringControl,
136156
logoEvent: withDefault(eventHandlerControl(logoEventHandlers), [{ name: "click" }]),
137157
horizontalAlignment: alignWithJustifyControl(),
138158
style: migrateOldData(styleControl(NavigationStyle, 'style'), fixOldStyleData),
139159
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
140-
items: withDefault(navListComp(), [
141-
{
142-
label: trans("menuItem") + " 1",
143-
},
144-
]),
160+
items: withDefault(migrateOldData(createNavItemsControl(), fixOldItemsData), {
161+
optionType: "manual",
162+
manual: [
163+
{
164+
label: trans("menuItem") + " 1",
165+
},
166+
],
167+
}),
145168
};
146169

147170
const NavCompBase = new UICompBuilder(childrenMap, (props) => {
148171
const data = props.items;
149172
const items = (
150173
<>
151-
{data.map((menuItem, idx) => {
152-
const { hidden, label, items, active, onEvent } = menuItem.getView();
174+
{data.map((menuItem: any, idx: number) => {
175+
const isCompItem = typeof menuItem?.getView === "function";
176+
const view = isCompItem ? menuItem.getView() : menuItem;
177+
const hidden = !!view?.hidden;
153178
if (hidden) {
154179
return null;
155180
}
156-
const subMenuItems: Array<{ key: string; label: string }> = [];
181+
182+
const label = view?.label;
183+
const active = !!view?.active;
184+
const onEvent = view?.onEvent;
185+
const disabled = !!view?.disabled;
186+
const subItems = isCompItem ? view?.items : [];
187+
188+
const subMenuItems: Array<{ key: string; label: any; disabled?: boolean }> = [];
157189
const subMenuSelectedKeys: Array<string> = [];
158-
items.forEach((subItem, originalIndex) => {
159-
if (subItem.children.hidden.getView()) {
160-
return;
161-
}
162-
const key = originalIndex + "";
163-
subItem.children.active.getView() && subMenuSelectedKeys.push(key);
164-
subMenuItems.push({
165-
key: key,
166-
label: subItem.children.label.getView(),
190+
191+
if (Array.isArray(subItems)) {
192+
subItems.forEach((subItem: any, originalIndex: number) => {
193+
if (subItem.children.hidden.getView()) {
194+
return;
195+
}
196+
const key = originalIndex + "";
197+
subItem.children.active.getView() && subMenuSelectedKeys.push(key);
198+
subMenuItems.push({
199+
key: key,
200+
label: subItem.children.label.getView(),
201+
disabled: !!subItem.children.disabled.getView(),
202+
});
167203
});
168-
});
204+
}
205+
169206
const item = (
170207
<Item
171208
key={idx}
@@ -180,18 +217,23 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
180217
$textTransform={props.style.textTransform}
181218
$textDecoration={props.style.textDecoration}
182219
$margin={props.style.margin}
183-
onClick={() => onEvent("click")}
220+
$disabled={disabled}
221+
onClick={() => { if (!disabled && onEvent) onEvent("click"); }}
184222
>
185223
{label}
186-
{items.length > 0 && <DownOutlined />}
224+
{Array.isArray(subItems)&&subItems.length > 0 && <DownOutlined />}
187225
</Item>
188226
);
189227
if (subMenuItems.length > 0) {
190228
const subMenu = (
191229
<StyledMenu
192230
onClick={(e) => {
193-
const { onEvent: onSubEvent } = items[Number(e.key)]?.getView();
194-
onSubEvent("click");
231+
if (disabled) return;
232+
const subItem = subItems[Number(e.key)];
233+
const isSubDisabled = !!subItem?.children?.disabled?.getView?.();
234+
if (isSubDisabled) return;
235+
const onSubEvent = subItem?.getView()?.onEvent;
236+
onSubEvent && onSubEvent("click");
195237
}}
196238
selectedKeys={subMenuSelectedKeys}
197239
items={subMenuItems}
@@ -201,6 +243,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
201243
<Dropdown
202244
key={idx}
203245
popupRender={() => subMenu}
246+
disabled={disabled}
204247
>
205248
{item}
206249
</Dropdown>
@@ -237,7 +280,7 @@ const NavCompBase = new UICompBuilder(childrenMap, (props) => {
237280
return (
238281
<>
239282
<Section name={sectionNames.basic}>
240-
{menuPropertyView(children.items)}
283+
{children.items.propertyView()}
241284
</Section>
242285

243286
{(useContext(EditorContext).editorModeStatus === "logic" || useContext(EditorContext).editorModeStatus === "both") && (

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /