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 b4afd6a

Browse files
authored
Merge branch 'dev' into pwa-icon-support
2 parents 0b9741b + 1671585 commit b4afd6a

File tree

49 files changed

+526
-232
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+526
-232
lines changed

‎client/packages/lowcoder-comps/src/comps/barChartComp/barChartComp.tsx

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ BarChartTmpComp = withViewFn(BarChartTmpComp, (comp) => {
6161
const [chartSize, setChartSize] = useState<ChartSize>();
6262
const firstResize = useRef(true);
6363
const theme = useContext(ThemeContext);
64+
const [chartKey, setChartKey] = useState(0);
65+
const prevRaceMode = useRef<boolean>();
6466
const defaultChartTheme = {
6567
color: chartColorPalette,
6668
backgroundColor: "#fff",
@@ -73,6 +75,16 @@ BarChartTmpComp = withViewFn(BarChartTmpComp, (comp) => {
7375
log.error('theme chart error: ', error);
7476
}
7577

78+
// Detect race mode changes and force chart recreation
79+
const currentRaceMode = comp.children.chartConfig?.children?.comp?.children?.race?.getView();
80+
useEffect(() => {
81+
if (prevRaceMode.current !== undefined && prevRaceMode.current !== currentRaceMode) {
82+
// Force chart recreation when race mode changes
83+
setChartKey(prev => prev + 1);
84+
}
85+
prevRaceMode.current = currentRaceMode;
86+
}, [currentRaceMode]);
87+
7688
const triggerClickEvent = async (dispatch: any, action: CompAction<JSONValue>) => {
7789
await getPromiseAfterDispatch(
7890
dispatch,
@@ -176,10 +188,11 @@ BarChartTmpComp = withViewFn(BarChartTmpComp, (comp) => {
176188
return (
177189
<div ref={containerRef} style={{height: '100%'}}>
178190
<ReactECharts
191+
key={chartKey}
179192
ref={(e) => (echartsCompRef.current = e)}
180193
style={{ height: "100%" }}
181-
notMerge
182-
lazyUpdate
194+
notMerge={!currentRaceMode}
195+
lazyUpdate={!currentRaceMode}
183196
opts={{ locale: getEchartsLocale() }}
184197
option={option}
185198
mode={mode}

‎client/packages/lowcoder-comps/src/comps/barChartComp/barChartUtils.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,15 @@ export function getEchartsConfig(
201201
animationEasing: 'linear',
202202
animationEasingUpdate: 'linear',
203203
}
204+
} else {
205+
// Ensure proper animation settings when race is disabled
206+
config = {
207+
...config,
208+
animationDuration: 1000,
209+
animationDurationUpdate: 1000,
210+
animationEasing: 'cubicOut',
211+
animationEasingUpdate: 'cubicOut',
212+
}
204213
}
205214
if (props.data.length <= 0) {
206215
// no data
@@ -333,6 +342,21 @@ export function getEchartsConfig(
333342
animationDurationUpdate: 300
334343
},
335344
}
345+
} else {
346+
// Reset axis animations when race is disabled
347+
config = {
348+
...config,
349+
xAxis: {
350+
...config.xAxis,
351+
animationDuration: undefined,
352+
animationDurationUpdate: undefined
353+
},
354+
yAxis: {
355+
...config.yAxis,
356+
animationDuration: undefined,
357+
animationDurationUpdate: undefined
358+
},
359+
}
336360
}
337361
}
338362
// console.log("Echarts transformedData and config", transformedData, config);

‎client/packages/lowcoder-comps/src/comps/basicChartComp/chartConfigs/barChartConfig.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export const BarChartConfig = (function () {
5353
type: "bar",
5454
subtype: props.type,
5555
realtimeSort: props.race,
56-
seriesLayoutBy: props.race?'column':undefined,
56+
seriesLayoutBy: props.race?'column':'row',
5757
label: {
5858
show: props.showLabel,
5959
position: "top",

‎client/packages/lowcoder-core/lib/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,11 +1692,12 @@ class CodeNode extends AbstractNode {
16921692
// if query is dependent on itself, mark as ready
16931693
if (pathsArr?.[0] === options?.queryName)
16941694
return;
1695+
// TODO: check if this is needed after removing lazy load
16951696
// wait for lazy loaded comps to load before executing query on page load
1696-
if (value && !Object.keys(value).length && paths.size) {
1697-
isFetching = true;
1698-
ready = false;
1699-
}
1697+
// if (value && !Object.keys(value).length && paths.size) {
1698+
// isFetching = true;
1699+
// ready = false;
1700+
// }
17001701
if (_.has(value, IS_FETCHING_FIELD)) {
17011702
isFetching = isFetching || value.isFetching === true;
17021703
}

‎client/packages/lowcoder-core/src/eval/codeNode.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,12 @@ export class CodeNode extends AbstractNode<ValueAndMsg<unknown>> {
176176
// if query is dependent on itself, mark as ready
177177
if (pathsArr?.[0] === options?.queryName) return;
178178

179+
// TODO: check if this is needed after removing lazy load
179180
// wait for lazy loaded comps to load before executing query on page load
180-
if (value && !Object.keys(value).length && paths.size) {
181-
isFetching = true;
182-
ready = false;
183-
}
181+
// if (value && !Object.keys(value).length && paths.size) {
182+
// isFetching = true;
183+
// ready = false;
184+
// }
184185
if (_.has(value, IS_FETCHING_FIELD)) {
185186
isFetching = isFetching || value.isFetching === true;
186187
}

‎client/packages/lowcoder/src/components/DraggableTree/DroppableMenuItem.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ export default function DraggableMenuItem(props: IDraggableMenuItemProps) {
6767
const canDropBefore = checkDroppableFlag(item.canDropBefore, activeNode?.data);
6868
const canDropAfter = checkDroppableFlag(item.canDropAfter, activeNode?.data);
6969

70+
const lastChildNode = items[items.length - 1];
71+
const canDropAfterLastChild = checkDroppableFlag(lastChildNode?.canDropAfter, activeNode?.data);
72+
7073
const dropData: IDropData = {
7174
targetListSize: items.length,
7275
targetPath: dropInAsSub ? [...path, 0] : [...path.slice(0, -1), path[path.length - 1] + 1],
@@ -136,6 +139,15 @@ export default function DraggableMenuItem(props: IDraggableMenuItemProps) {
136139
/>
137140
</Fragment>
138141
))}
142+
{activeNode && canDropAfterLastChild && (
143+
<div style={{ position: "relative" }}>
144+
<DroppablePlaceholder
145+
targetListSize={-1}
146+
path={[...path, items.length]}
147+
disabled={isDragging || disabled}
148+
/>
149+
</div>
150+
)}
139151
</div>
140152
)}
141153
</>

‎client/packages/lowcoder/src/components/PermissionDialog/DatasourcePermissionDialog.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { DatasourceRole } from "../../api/datasourcePermissionApi";
1313
import { getDataSourcePermissionInfo } from "../../redux/selectors/datasourceSelectors";
1414
import { StyledLoading } from "./commonComponents";
1515
import { PermissionRole } from "./Permission";
16+
import { getUser } from "../../redux/selectors/usersSelectors";
1617

1718
export const DatasourcePermissionDialog = (props: {
1819
datasourceId: string;
@@ -22,6 +23,7 @@ export const DatasourcePermissionDialog = (props: {
2223
const { datasourceId } = props;
2324
const dispatch = useDispatch();
2425
const permissionInfo = useSelector(getDataSourcePermissionInfo)[datasourceId];
26+
const user = useSelector(getUser);
2527

2628
useEffect(() => {
2729
dispatch(fetchDatasourcePermissions({ datasourceId: datasourceId }));
@@ -75,6 +77,8 @@ export const DatasourcePermissionDialog = (props: {
7577
{ label: trans("share.datasourceOwner"), value: PermissionRole.Owner },
7678
]}
7779
permissionItems={permissions}
80+
contextType="organization"
81+
organizationId={user.currentOrgId}
7882
viewBodyRender={(list) => {
7983
if (!permissionInfo) {
8084
return <StyledLoading size={18} />;

‎client/packages/lowcoder/src/components/PermissionDialog/Permission.tsx

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { EmptyContent } from "pages/common/styledComponent";
2727
import { trans } from "i18n";
2828
import { PermissionItem } from "./PermissionList";
2929
import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSelector";
30-
import { fetchAvailableGroupsMembers } from "@lowcoder-ee/util/pagination/axios";
30+
import { fetchAvailableGroupsMembers,fetchAvailableOrgGroupsMembers } from "@lowcoder-ee/util/pagination/axios";
3131

3232
const AddAppUserContent = styled.div`
3333
display: flex;
@@ -186,6 +186,13 @@ const AddRoleSelect = styled(StyledRoleSelect)<{ $isVisible: boolean }>`
186186
display: ${(props) => (props.$isVisible ? "unset" : "none")};
187187
`;
188188

189+
type PermissionContextType = "application" | "organization";
190+
191+
type PermissionContextProps = {
192+
contextType: PermissionContextType;
193+
organizationId?: string;
194+
};
195+
189196
type AddAppOptionView = {
190197
type: ApplicationPermissionType;
191198
id: string;
@@ -294,8 +301,10 @@ const PermissionSelector = (props: {
294301
user: User;
295302
filterItems: PermissionItem[];
296303
supportRoles: { label: string; value: PermissionRole }[];
304+
contextType: PermissionContextType;
305+
organizationId?: string;
297306
}) => {
298-
const { selectedItems, setSelectRole, setSelectedItems, user } = props;
307+
const { selectedItems, setSelectRole, setSelectedItems, user, contextType, organizationId } = props;
299308
const [roleSelectVisible, setRoleSelectVisible] = useState(false);
300309
const selectRef = useRef<HTMLDivElement>(null);
301310
const [optionViews, setOptionViews] = useState<AddAppOptionView[]>()
@@ -305,42 +314,41 @@ const PermissionSelector = (props: {
305314

306315
const debouncedUserSearch = useCallback(
307316
debounce((searchTerm: string) => {
308-
if (!application) return;
309-
310317
setIsLoading(true);
311-
fetchAvailableGroupsMembers(application.applicationId, searchTerm).then(res => {
312-
if(res.success) {
313-
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
314-
}
315-
setIsLoading(false);
316-
}).catch(() => {
318+
319+
if (contextType === "application" && application) {
320+
fetchAvailableGroupsMembers(application.applicationId, searchTerm).then(res => {
321+
if(res.success) {
322+
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
323+
}
324+
setIsLoading(false);
325+
}).catch(() => {
326+
setIsLoading(false);
327+
});
328+
} else if (contextType === "organization" && organizationId) {
329+
fetchAvailableOrgGroupsMembers(organizationId, searchTerm).then(res => {
330+
if(res.success) {
331+
setOptionViews(getPermissionOptionView(res.data || [], props.filterItems))
332+
}
333+
setIsLoading(false);
334+
}).catch(() => {
335+
setIsLoading(false);
336+
});
337+
} else {
317338
setIsLoading(false);
318-
});
339+
}
319340
}, 500),
320-
[application, props.filterItems]
341+
[application, props.filterItems,contextType,organizationId]
321342
);
322343

323344
useEffect(() => {
324345
debouncedUserSearch(searchValue);
325-
326346
return () => {
327347
debouncedUserSearch.cancel();
328348
};
329349
}, [searchValue, debouncedUserSearch]);
330350

331-
useEffect(() => {
332-
if (!application) return;
333-
334-
setIsLoading(true);
335-
fetchAvailableGroupsMembers(application.applicationId, "").then(res => {
336-
if(res.success) {
337-
setOptionViews(getPermissionOptionView(res.data, props.filterItems))
338-
}
339-
setIsLoading(false);
340-
}).catch(() => {
341-
setIsLoading(false);
342-
});
343-
}, [application, props.filterItems]);
351+
344352

345353
useEffect(() => {
346354
setRoleSelectVisible(selectedItems.length > 0);
@@ -425,8 +433,8 @@ export const Permission = (props: {
425433
supportRoles: { label: string; value: PermissionRole }[];
426434
onCancel: () => void;
427435
addPermission: (userIds: string[], groupIds: string[], role: string) => void;
428-
}) => {
429-
const { onCancel } = props;
436+
}&PermissionContextProps) => {
437+
const { onCancel, contextType ="application", organizationId } = props;
430438
const user = useSelector(getUser);
431439
const [selectRole, setSelectRole] = useState<ApplicationRoleType>("viewer");
432440
const [selectedItems, setSelectedItems] = useState<PermissionAddEntity[]>([]);
@@ -443,6 +451,8 @@ export const Permission = (props: {
443451
user={user}
444452
filterItems={props.filterItems}
445453
supportRoles={props.supportRoles}
454+
contextType={contextType}
455+
organizationId={organizationId}
446456
/>
447457
<BottomButton>
448458
<TacoButton style={{ marginRight: "8px" }} onClick={onCancel}>

‎client/packages/lowcoder/src/components/PermissionDialog/PermissionDialog.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,10 @@ export const PermissionDialog = (props: {
5757
) => void;
5858
updatePermission: (permissionId: string, role: string) => void;
5959
deletePermission: (permissionId: string) => void;
60+
contextType?: "application" | "organization";
61+
organizationId?: string;
6062
}) => {
61-
const { supportRoles, permissionItems, visible, onVisibleChange, addPermission, viewBodyRender } =
63+
const { supportRoles, permissionItems, visible, onVisibleChange, addPermission, viewBodyRender, contextType, organizationId } =
6264
props;
6365
const [activeStepKey, setActiveStepKey] = useState("view");
6466

@@ -117,6 +119,8 @@ export const PermissionDialog = (props: {
117119
addPermission={(userIds, groupIds, role) =>
118120
addPermission(userIds, groupIds, role, props.back)
119121
}
122+
contextType={contextType || "application"}
123+
organizationId={organizationId}
120124
/>
121125
),
122126
footerRender: (props) => null,

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
1+
import { BoolCodeControl, StringControl,NumberControl } from "comps/controls/codeControl";
22
import { dropdownControl } from "comps/controls/dropdownControl";
33
import { ButtonEventHandlerControl } from "comps/controls/eventHandlerControl";
44
import { IconControl } from "comps/controls/iconControl";
@@ -137,7 +137,8 @@ const childrenMap = {
137137
disabledStyle: DisabledButtonStyleControl,
138138
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
139139
viewRef: RefControl<HTMLElement>,
140-
tooltip: StringControl
140+
tooltip: StringControl,
141+
tabIndex: NumberControl
141142
};
142143

143144
type ChildrenType = NewChildren<RecordConstructorToComp<typeof childrenMap>>;
@@ -162,8 +163,12 @@ const ButtonPropertyView = React.memo((props: {
162163
disabledPropertyView(props.children),
163164
hiddenPropertyView(props.children),
164165
loadingPropertyView(props.children),
166+
props.children.tabIndex.propertyView({ label: trans("prop.tabIndex") }),
165167
]
166-
: props.children.form.getPropertyView()}
168+
: [
169+
props.children.form.getPropertyView(),
170+
props.children.tabIndex.propertyView({ label: trans("prop.tabIndex") }),
171+
]}
167172
</Section>
168173
</>
169174
)}
@@ -222,6 +227,7 @@ const ButtonView = React.memo((props: ToViewReturn<ChildrenType>) => {
222227
(!isDefault(props.type) && getForm(editorState, props.form)?.disableSubmit())
223228
}
224229
onClick={handleClick}
230+
tabIndex={typeof props.tabIndex === 'number' ? props.tabIndex : undefined}
225231
>
226232
{props.prefixIcon && <IconWrapper>{props.prefixIcon}</IconWrapper>}
227233
{

0 commit comments

Comments
(0)

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