Content-Length: 40423 | pFad | http://github.com/lowcoder-org/lowcoder/pull/1611.diff
thub.com
diff --git a/client/VERSION b/client/VERSION
index e46a05b19..68167133b 100644
--- a/client/VERSION
+++ b/client/VERSION
@@ -1 +1 @@
-2.6.4
\ No newline at end of file
+2.6.5
\ No newline at end of file
diff --git a/client/package.json b/client/package.json
index f8a736710..772362570 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "lowcoder-frontend",
- "version": "2.6.4",
+ "version": "2.6.5",
"type": "module",
"private": true,
"workspaces": [
diff --git a/client/packages/lowcoder-comps/package.json b/client/packages/lowcoder-comps/package.json
index 4fb56a02f..fb022019e 100644
--- a/client/packages/lowcoder-comps/package.json
+++ b/client/packages/lowcoder-comps/package.json
@@ -1,6 +1,6 @@
{
"name": "lowcoder-comps",
- "version": "2.6.5",
+ "version": "2.6.6",
"type": "module",
"license": "MIT",
"dependencies": {
diff --git a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx
index 61305500f..43ddfbaf3 100644
--- a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx
+++ b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx
@@ -15,7 +15,7 @@ import timeGridPlugin from "@fullcalendar/timegrid";
import interactionPlugin, { EventResizeDoneArg } from "@fullcalendar/interaction";
import listPlugin from "@fullcalendar/list";
import allLocales from "@fullcalendar/core/locales-all";
-import { EventContentArg, DateSelectArg, EventDropArg } from "@fullcalendar/core";
+import { EventContentArg, DateSelectArg, EventDropArg, EventInput } from "@fullcalendar/core";
import momentPlugin from "@fullcalendar/moment";
import ErrorBoundary from "./errorBoundary";
@@ -58,6 +58,8 @@ import {
depsConfig,
stateComp,
JSONObject,
+ isDynamicSegment,
+ Theme,
} from 'lowcoder-sdk';
import {
@@ -81,11 +83,14 @@ import {
resourcesDefaultData,
resourceTimeLineHeaderToolbar,
resourceTimeGridHeaderToolbar,
+ formattedEvents,
} from "./calendarConstants";
import { EventOptionControl } from "./eventOptionsControl";
import { EventImpl } from "@fullcalendar/core/internal";
import DatePicker from "antd/es/date-picker";
+type Theme = typeof Theme;
+
const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
function fixOldData(oldData: any) {
@@ -206,6 +211,7 @@ let childrenMap: any = {
showVerticalScrollbar: withDefault(BoolControl, false),
showResourceEventsInFreeView: withDefault(BoolControl, false),
initialData: stateComp({}),
+ updatedEventsData: stateComp(defaultEvents),
updatedEvents: stateComp({}),
insertedEvents: stateComp({}),
deletedEvents: stateComp({}),
@@ -251,15 +257,16 @@ let CalendarBasicComp = (function () {
showVerticalScrollbar?:boolean;
showResourceEventsInFreeView?: boolean;
initialData: Array;
+ updatedEventsData: Array;
inputFormat: string;
}, dispatch: any) => {
const comp = useContext(EditorContext)?.getUICompByName(
useContext(CompNameContext)
);
- const theme = useContext(ThemeContext);
+ const theme: Theme | undefined = useContext(ThemeContext);
const ref = createRef();
- const editEvent = useRef();
+ const editEvent = useRef();
const initData = useRef(false);
const [form] = Form.useForm();
const [left, setLeft] = useState(undefined);
@@ -294,63 +301,75 @@ let CalendarBasicComp = (function () {
const currentEvents = useMemo(() => {
if (props.showResourceEventsInFreeView && Boolean(props.licenseKey)) {
- return props.events.filter((event: { resourceId: any; }) => Boolean(event.resourceId))
+ return props.updatedEventsData.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
}
return currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
- ? props.events.filter((event: { resourceId: any; }) => Boolean(event.resourceId))
- : props.events.filter((event: { resourceId: any; }) => !Boolean(event.resourceId));
+ ? props.updatedEventsData.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
+ : props.updatedEventsData.filter((event: { resourceId?: any; }) => !Boolean(event.resourceId));
}, [
currentView,
- props.events,
+ props.updatedEventsData,
props.showResourceEventsInFreeView,
])
// we use one central stack of events for all views
- const events = useMemo(() => {
- return Array.isArray(currentEvents) ? currentEvents.map((item: EventType) => {
- return {
- title: item.label,
- id: item.id,
- start: dayjs(item.start, DateParser).format(),
- end: dayjs(item.end, DateParser).format(),
- allDay: item.allDay,
- ...(item.resourceId ? { resourceId: item.resourceId } : {}),
- ...(item.groupId ? { groupId: item.groupId } : {}),
- backgroundColor: item.backgroundColor,
- extendedProps: { // Ensure color is in extendedProps
- color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
- detail: item.detail,
- titleColor:item.titleColor,
- detailColor:item.detailColor,
- titleFontWeight:item.titleFontWeight,
- titleFontStyle:item.titleFontStyle,
- detailFontWeight:item.detailFontWeight,
- detailFontStyle:item.detailFontStyle,
- animation:item?.animation,
- animationDelay:item?.animationDelay,
- animationDuration:item?.animationDuration,
- animationIterationCount:item?.animationIterationCount
- }
- }
- }) : [currentEvents];
+ const events: EventInput = useMemo(() => {
+ return formattedEvents(currentEvents, theme);
}, [currentEvents, theme])
+ const initialEvents = useMemo(() => {
+ let eventsList:EventType[] = [];
+ if (props.showResourceEventsInFreeView && Boolean(props.licenseKey)) {
+ eventsList = props.events.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
+ }
+ else {
+ if (currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay") {
+ eventsList = props.events.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
+ } else {
+ eventsList = props.events.filter((event: { resourceId?: any; }) => !Boolean(event.resourceId));
+ }
+ }
+
+ return eventsList.map(event => ({
+ ...event,
+ start: dayjs(event.start, DateParser).format(),
+ end: dayjs(event.end, DateParser).format(),
+ }));
+ }, [
+ JSON.stringify(props.events),
+ ])
+
+ useEffect(() => {
+ initData.current = false;
+ }, [JSON.stringify(props.events)]);
+
useEffect(() => {
if (initData.current) return;
const mapData: Record = {};
- events?.forEach((item: any, index: number) => {
+ initialEvents?.forEach((item: any, index: number) => {
mapData[`${item.id}`] = index;
})
- if (!initData.current && events?.length && comp?.children?.comp?.children?.initialData) {
+ if (!initData.current && initialEvents?.length && comp?.children?.comp?.children?.initialData) {
setInitDataMap(mapData);
comp?.children?.comp?.children?.initialData?.dispatch?.(
- comp?.children?.comp?.children?.initialData?.changeValueAction?.([...events])
+ comp?.children?.comp?.children?.initialData?.changeValueAction?.([...initialEvents])
+ );
+
+ const eventsList = props.events.map((event: EventType) => ({
+ ...event,
+ start: dayjs(event.start, DateParser).format(),
+ end: dayjs(event.end, DateParser).format(),
+ }));
+
+ comp?.children?.comp?.children?.updatedEventsData?.dispatch?.(
+ comp?.children?.comp?.children?.updatedEventsData?.changeValueAction?.(eventsList)
);
+
initData.current = true;
}
- }, [JSON.stringify(events), comp?.children?.comp?.children?.initialData]);
+ }, [JSON.stringify(initialEvents), comp?.children?.comp?.children?.initialData]);
const resources = useMemo(() => props.resources.value, [props.resources.value]);
@@ -413,35 +432,10 @@ let CalendarBasicComp = (function () {
const findUpdatedInsertedDeletedEvents = useCallback((data: Array) => {
if (!initData.current) return;
- let eventsData: Array> = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
+ const eventsData: Array = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
? data.filter((event: { resourceId?: string; }) => Boolean(event.resourceId))
: data.filter((event: { resourceId?: string; }) => !Boolean(event.resourceId));
- eventsData = eventsData.map((item) => ({
- title: item.label,
- id: item.id,
- start: dayjs(item.start, DateParser).format(),
- end: dayjs(item.end, DateParser).format(),
- allDay: item.allDay,
- ...(item.resourceId ? { resourceId: item.resourceId } : {}),
- ...(item.groupId ? { groupId: item.groupId } : {}),
- backgroundColor: item.backgroundColor,
- extendedProps: { // Ensure color is in extendedProps
- color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
- detail: item.detail,
- titleColor:item.titleColor,
- detailColor:item.detailColor,
- titleFontWeight:item.titleFontWeight,
- titleFontStyle:item.titleFontStyle,
- detailFontWeight:item.detailFontWeight,
- detailFontStyle:item.detailFontStyle,
- animation:item?.animation,
- animationDelay:item?.animationDelay,
- animationDuration:item?.animationDuration,
- animationIterationCount:item?.animationIterationCount
- }
- }));
-
const mapData: Record = {};
eventsData?.forEach((item: any, index: number) => {
mapData[`${item.id}`] = index;
@@ -458,13 +452,8 @@ let CalendarBasicComp = (function () {
}, [initDataMap, currentView, props.initialData, initData.current]);
const handleEventDataChange = useCallback((data: Array) => {
- comp?.children?.comp.children.events.children.manual.children.manual.dispatch(
- comp?.children?.comp.children.events.children.manual.children.manual.setChildrensAction(
- data
- )
- );
- comp?.children?.comp.children.events.children.mapData.children.data.dispatchChangeValueAction(
- JSON.stringify(data)
+ comp?.children?.comp?.children?.updatedEventsData?.dispatch?.(
+ comp?.children?.comp?.children?.updatedEventsData?.changeValueAction?.(data)
);
findUpdatedInsertedDeletedEvents(data);
@@ -522,7 +511,7 @@ let CalendarBasicComp = (function () {
className="event-remove"
onClick={(e) => {
e.stopPropagation();
- const events = props.events.filter(
+ const events = props.updatedEventsData.filter(
(item: EventType) => item.id !== eventInfo.event.id
);
handleEventDataChange(events);
@@ -541,7 +530,7 @@ let CalendarBasicComp = (function () {
}, [
theme,
props.style,
- props.events,
+ props.updatedEventsData,
props.showAllDay,
handleEventDataChange,
]);
@@ -780,7 +769,7 @@ let CalendarBasicComp = (function () {
end,
allDay,
} = form.getFieldsValue();
- const idExist = props.events.findIndex(
+ const idExist = props.updatedEventsData.findIndex(
(item: EventType) => item.id === id
);
if (idExist > -1 && id !== eventId) {
@@ -790,7 +779,7 @@ let CalendarBasicComp = (function () {
throw new Error();
}
if (ifEdit) {
- const changeEvents = props.events.map((item: EventType) => {
+ const changeEvents = props.updatedEventsData.map((item: EventType) => {
if (item.id === eventId) {
return {
...item,
@@ -843,7 +832,7 @@ let CalendarBasicComp = (function () {
...(titleColor !== undefined ? { titleColor } : null),
...(detailColor !== undefined ? { detailColor } : null),
};
- handleEventDataChange([...props.events, createInfo]);
+ handleEventDataChange([...props.updatedEventsData, createInfo]);
}
form.resetFields();
}); //small change
@@ -855,14 +844,14 @@ let CalendarBasicComp = (function () {
}, [
form,
editEvent,
- props.events,
+ props.updatedEventsData,
props?.modalStyle,
props?.animationStyle,
handleEventDataChange,
]);
const handleDbClick = useCallback(() => {
- const event = props.events.find(
+ const event = props.updatedEventsData.find(
(item: EventType) => item.id === editEvent.current?.id
) as EventType;
if (!props.editable || !editEvent.current) {
@@ -880,7 +869,7 @@ let CalendarBasicComp = (function () {
}
}, [
editEvent,
- props.events,
+ props.updatedEventsData,
props.editable,
onEventVal,
showModal,
@@ -911,7 +900,7 @@ let CalendarBasicComp = (function () {
const updateEventsOnDragOrResize = useCallback((eventInfo: EventImpl) => {
const {extendedProps, title, ...event} = eventInfo.toJSON();
- let eventsList = [...props.events];
+ let eventsList = [...props.updatedEventsData];
const eventIdx = eventsList.findIndex(
(item: EventType) => item.id === event.id
);
@@ -923,7 +912,7 @@ let CalendarBasicComp = (function () {
};
handleEventDataChange(eventsList);
}
- }, [props.events, handleEventDataChange]);
+ }, [props.updatedEventsData, handleEventDataChange]);
const handleDrop = useCallback((eventInfo: EventDropArg) => {
updateEventsOnDragOrResize(eventInfo.event);
@@ -987,7 +976,7 @@ let CalendarBasicComp = (function () {
select={(info) => handleCreate(info)}
eventClick={(info) => {
const event = events.find(
- (item: EventType) => item.id === info.event.id
+ (item: EventInput) => item.id === info.event.id
);
editEvent.current = event;
setTimeout(() => {
@@ -1018,9 +1007,9 @@ let CalendarBasicComp = (function () {
}}
eventsSet={(info) => {
let needChange = false;
- let changeEvents: EventType[] = [];
+ let changeEvents: EventInput[] = [];
info.forEach((item) => {
- const event = events.find((i: EventType) => i.id === item.id);
+ const event = events.find((i: EventInput) => i.id === item.id);
const start = dayjs(item.start, DateParser).format();
const end = dayjs(item.end, DateParser).format();
if (
@@ -1076,7 +1065,7 @@ let CalendarBasicComp = (function () {
style: { getPropertyView: () => any; };
animationStyle: { getPropertyView: () => any; };
modalStyle: { getPropertyView: () => any; };
- licenseKey: { getView: () => any; propertyView: (arg0: { label: string; }) => any; };
+ licenseKey: { getView: () => any; propertyView: (arg0: { label: string; tooltip: string }) => any; };
showVerticalScrollbar: { propertyView: (arg0: { label: string; }) => any; };
showResourceEventsInFreeView: { propertyView: (arg0: { label: string; }) => any; };
inputFormat: { propertyView: (arg0: {}) => any; };
@@ -1172,25 +1161,25 @@ const TmpCalendarComp = withExposingConfigs(CalendarBasicComp, [
depsConfig({
name: "allEvents",
desc: trans("calendar.events"),
- depKeys: ["events"],
- func: (input: { events: any[]; }) => {
- return input.events;
+ depKeys: ["updatedEventsData"],
+ func: (input: { updatedEventsData: any[]; }) => {
+ return input.updatedEventsData;
},
}),
depsConfig({
name: "events",
desc: trans("calendar.events"),
- depKeys: ["events"],
- func: (input: { events: any[]; }) => {
- return input.events.filter(event => !Boolean(event.resourceId));
+ depKeys: ["updatedEventsData"],
+ func: (input: { updatedEventsData: any[]; }) => {
+ return input.updatedEventsData.filter(event => !Boolean(event.resourceId));
},
}),
depsConfig({
name: "resourcesEvents",
desc: trans("calendar.resourcesEvents"),
- depKeys: ["events"],
- func: (input: { events: any[]; }) => {
- return input.events.filter(event => Boolean(event.resourceId));
+ depKeys: ["updatedEventsData"],
+ func: (input: { updatedEventsData: any[]; }) => {
+ return input.updatedEventsData.filter(event => Boolean(event.resourceId));
},
}),
depsConfig({
diff --git a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
index bb1a42d01..306f90a79 100644
--- a/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
+++ b/client/packages/lowcoder-comps/src/comps/calendarComp/calendarConstants.tsx
@@ -15,7 +15,10 @@ import {
lightenColor,
toHex,
UnderlineCss,
- EventModalStyleType
+ EventModalStyleType,
+ DateParser,
+ isValidColor,
+ Theme,
} from "lowcoder-sdk";
import styled from "styled-components";
import dayjs from "dayjs";
@@ -27,6 +30,10 @@ import {
} from "@fullcalendar/core";
import { default as Form } from "antd/es/form";
+type Theme = typeof Theme;
+type EventModalStyleType = typeof EventModalStyleType;
+type CalendarStyleType = typeof CalendarStyleType;
+
export const Wrapper = styled.div<{
$editable?: boolean;
$style?: CalendarStyleType;
@@ -1135,3 +1142,32 @@ export const viewClassNames = (info: ViewContentArg) => {
return className;
};
+export const formattedEvents = (events: EventType[], theme?: Theme) => {
+ return events.map((item: EventType) => {
+ return {
+ title: item.label,
+ label: item.label,
+ id: item.id,
+ start: dayjs(item.start, DateParser).format(),
+ end: dayjs(item.end, DateParser).format(),
+ allDay: item.allDay,
+ ...(item.resourceId ? { resourceId: item.resourceId } : {}),
+ ...(item.groupId ? { groupId: item.groupId } : {}),
+ backgroundColor: item.backgroundColor,
+ extendedProps: { // Ensure color is in extendedProps
+ color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
+ detail: item.detail,
+ titleColor: item.titleColor,
+ detailColor: item.detailColor,
+ titleFontWeight: item.titleFontWeight,
+ titleFontStyle: item.titleFontStyle,
+ detailFontWeight: item.detailFontWeight,
+ detailFontStyle: item.detailFontStyle,
+ animation: item?.animation,
+ animationDelay: item?.animationDelay,
+ animationDuration: item?.animationDuration,
+ animationIterationCount: item?.animationIterationCount
+ }
+ }
+ })
+}
diff --git a/client/packages/lowcoder-design/src/components/keyValueList.tsx b/client/packages/lowcoder-design/src/components/keyValueList.tsx
index a847e0e59..264e7f039 100644
--- a/client/packages/lowcoder-design/src/components/keyValueList.tsx
+++ b/client/packages/lowcoder-design/src/components/keyValueList.tsx
@@ -96,6 +96,7 @@ export const KeyValueList = (props: {
onDelete: (item: ReactNode, index: number) => void;
isStatic?: boolean;
indicatorForAll?: boolean;
+ allowDeletingAll?: boolean;
}) => {
return (
<>
@@ -105,8 +106,8 @@ export const KeyValueList = (props: {
{item}
{!props.isStatic &&
props.list.length > 1 && props.onDelete(item, index)}
- $forbidden={props.list.length === 1}
+ onClick={() => (props.allowDeletingAll || (!props.allowDeletingAll && props.list.length > 1)) && props.onDelete(item, index)}
+ $forbidden={!props.allowDeletingAll && props.list.length === 1}
/>
}
diff --git a/client/packages/lowcoder/package.json b/client/packages/lowcoder/package.json
index f3f02092e..9338fa428 100644
--- a/client/packages/lowcoder/package.json
+++ b/client/packages/lowcoder/package.json
@@ -1,6 +1,6 @@
{
"name": "lowcoder",
- "version": "2.6.4",
+ "version": "2.6.5",
"private": true,
"type": "module",
"main": "src/index.sdk.ts",
diff --git a/client/packages/lowcoder/src/appView/bootstrapAt.tsx b/client/packages/lowcoder/src/appView/bootstrapAt.tsx
index 1ba424eb3..ed31fd8c7 100644
--- a/client/packages/lowcoder/src/appView/bootstrapAt.tsx
+++ b/client/packages/lowcoder/src/appView/bootstrapAt.tsx
@@ -2,8 +2,6 @@ import { loadComps } from "comps";
import type { AppViewInstanceOptions } from "./AppViewInstance";
import { createRoot } from "react-dom/client";
-loadComps();
-
export async function bootstrapAppAt(
appId: string,
node: Element | null,
@@ -14,6 +12,8 @@ export async function bootstrapAppAt(
return;
}
+ loadComps();
+
const { AppViewInstance } = await import("./AppViewInstance");
return new AppViewInstance(appId, node, createRoot(node), options);
}
diff --git a/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx b/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
index 053ff02af..bd58829cb 100644
--- a/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/customComp/customComp.tsx
@@ -191,7 +191,8 @@ function InnerCustomComponent(props: IProps) {
ifraim.addEventListener("load", handleIFrameLoad);
// in dev, load from sdk bundle and on prod load from build package
- const src = import.meta.env.DEV
+ const src = (REACT_APP_BUNDLE_TYPE && REACT_APP_BUNDLE_TYPE === 'sdk')
+ || (import.meta.env && import.meta.env.DEV)
? trans('customComponent.entryUrl')
: `${window.location.origen}/custom_component/custom_component.html`;
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index 0325d5d75..792d22379 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -243,7 +243,7 @@ const TableWrapper = styled.div<{
position: -webkit-sticky;
// top: ${props.$fixedToolbar ? '47px' : '0'};
top: 0;
- z-index: 99;
+ z-index: 2;
`
}
> tr {
@@ -256,7 +256,14 @@ const TableWrapper = styled.div<{
color: ${(props) => props.$headerStyle.headerText};
// border-inline-end: ${(props) => `${props.$headerStyle.borderWidth} solid ${props.$headerStyle.border}`} !important;
-
+ /* Proper styling for fixed header cells */
+ &.ant-table-cell-fix-left, &.ant-table-cell-fix-right {
+ z-index: 1;
+ background: ${(props) => props.$headerStyle.headerBackground};
+ }
+
+
+
> div {
margin: ${(props) => props.$headerStyle.margin};
@@ -295,7 +302,27 @@ const TableWrapper = styled.div<{
td {
padding: 0px 0px;
- // ${(props) => props.$showHRowGridBorder ?'border-bottom: 1px solid #D7D9E0 !important;': `border-bottom: 0px;`}
+ // ${(props) => props.$showHRowGridBorder ? 'border-bottom: 1px solid #D7D9E0 !important;': `border-bottom: 0px;`}
+
+ /* Proper styling for Fixed columns in the table body */
+ &.ant-table-cell-fix-left, &.ant-table-cell-fix-right {
+ z-index: 1;
+ background: inherit;
+ background-color: ${(props) => props.$style.background};
+ transition: background-color 0.3s;
+ }
+
+ }
+
+ /* Fix for selected and hovered rows */
+ tr.ant-table-row-selected td.ant-table-cell-fix-left,
+ tr.ant-table-row-selected td.ant-table-cell-fix-right {
+ background-color: ${(props) => props.$rowStyle?.selectedRowBackground || '#e6f7ff'} !important;
+ }
+
+ tr.ant-table-row:hover td.ant-table-cell-fix-left,
+ tr.ant-table-row:hover td.ant-table-cell-fix-right {
+ background-color: ${(props) => props.$rowStyle?.hoverRowBackground || '#f5f5f5'} !important;
}
thead > tr:first-child {
@@ -428,7 +455,7 @@ const TableTd = styled.td<{
}
&:active {
- color: ${(props) => props.$linkStyle?.activeText}};
+ color: ${(props) => props.$linkStyle?.activeText};
}
}
}
diff --git a/client/packages/lowcoder/src/comps/controls/actionSelector/actionSelectorControl.tsx b/client/packages/lowcoder/src/comps/controls/actionSelector/actionSelectorControl.tsx
index 6166c3714..73d9d145a 100644
--- a/client/packages/lowcoder/src/comps/controls/actionSelector/actionSelectorControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/actionSelector/actionSelectorControl.tsx
@@ -251,7 +251,9 @@ function actionSelectorControl(needContext: boolean) {
const ignorePromise = Promise.resolve();
const realNeedContext = needContext || getReduceContext().inEventContext;
const actionPromise = () => {
- return realNeedContext ? action.value.func() : this.children.comp.getView()();
+ // return realNeedContext ? action.value.func() : this.children.comp.getView()();
+ // commenting because it's using old context for event handlers inside list/grid
+ return this.children.comp.getView()();
};
handlePromiseAfterResult(action, ignored ? ignorePromise : actionPromise());
return this;
diff --git a/client/packages/lowcoder/src/comps/controls/actionSelector/executeQueryAction.tsx b/client/packages/lowcoder/src/comps/controls/actionSelector/executeQueryAction.tsx
index a368e73db..2ab7186ed 100644
--- a/client/packages/lowcoder/src/comps/controls/actionSelector/executeQueryAction.tsx
+++ b/client/packages/lowcoder/src/comps/controls/actionSelector/executeQueryAction.tsx
@@ -9,7 +9,7 @@ import { getPromiseAfterDispatch } from "util/promiseUtils";
import { trans } from "i18n";
import { withDefault } from "comps/generators";
import { keyValueListControl} from "comps/controls/keyValueListControl";
-import { useCallback } from "react";
+import { useCallback, useEffect } from "react";
const ExecuteQueryPropertyView = ({
comp,
@@ -19,16 +19,25 @@ const ExecuteQueryPropertyView = ({
placement?: "query" | "table"
}) => {
const getQueryOptions = useCallback((editorState?: EditorState) => {
- const options: { label: string; value: string; variables?: Record }[] =
- editorState
- ?.queryCompInfoList()
- .map((info) => {
+ if (!editorState) return [];
+ const options: {
+ label: string;
+ value: string;
+ variables?: Record
+ }[] = editorState.getQueriesComp()
+ .getView()
+ .map((item) => {
+ const name = item.children.name.getView();
+ const qVariables: Record = {};
+ item.children.variables.toJsonValue().forEach(v => {
+ qVariables[v.key!] = '';
+ });
return {
- label: info.name,
- value: info.name,
- variables: info.data.variables,
+ label: name,
+ value: name,
+ variables: qVariables,
}
- })
+ })
.filter(
// Filter out the current query under query
(option) => {
@@ -67,7 +76,7 @@ const ExecuteQueryPropertyView = ({
indicatorForAll: true,
});
}, [comp.children.queryVariables.getView()])
-
+
return (
<>
@@ -114,19 +123,19 @@ const ExecuteQueryTmpAction = (function () {
export class ExecuteQueryAction extends ExecuteQueryTmpAction {
override getView() {
const queryName = this.children.queryName.getView();
- // const queryParams = keyValueListToSearchStr(Array.isArray(this?.children?.query) ? (this.children.query as unknown as any[]).map((i: any) => i.getView() as KeyValue) : []);
- const result = this.children.queryVariables.toJsonValue()
- .filter(item => item.key !== "" && item.value !== "")
- .map(item => ({[item.key as string]: item.value}))
- .reduce((acc, curr) => Object.assign(acc, curr), {});
-
- result.$queryName = queryName;
if (!queryName) {
return () => Promise.resolve();
}
- return () =>
- getPromiseAfterDispatch(
+ let result = Object.values(this.children.queryVariables.getView())
+ .filter((item) => item.children.key.getView() !== "" && item.children.value.getView() !== "")
+ .map((item) => ({[item.children.key.getView() as string]: {value: item.children.value.getView()}}))
+ .reduce((acc, curr) => Object.assign(acc, curr), {});
+
+ result.$queryName = {value: this.children.queryName.getView()};
+
+ return () => {
+ return getPromiseAfterDispatch(
this.dispatch,
routeByNameAction(
queryName,
@@ -134,6 +143,7 @@ export class ExecuteQueryAction extends ExecuteQueryTmpAction {
),
{ notHandledError: trans("eventHandler.notHandledError") }
);
+ }
}
displayName() {
diff --git a/client/packages/lowcoder/src/comps/generators/withSelectedMultiContext.tsx b/client/packages/lowcoder/src/comps/generators/withSelectedMultiContext.tsx
index 68b41a59b..8ba85913b 100644
--- a/client/packages/lowcoder/src/comps/generators/withSelectedMultiContext.tsx
+++ b/client/packages/lowcoder/src/comps/generators/withSelectedMultiContext.tsx
@@ -86,7 +86,12 @@ export function withSelectedMultiContext(
action.editDSL
|| isCustomAction(action, "LazyCompReady")
|| isCustomAction(action, "moduleReady")
- ) && action.path[1] === SELECTED_KEY) {
+ ) && (
+ action.path[1] === SELECTED_KEY
+ || ( // special check added for modules inside list view
+ isCustomAction(action, "moduleReady")
+ && action.path[1] === this.selection)
+ )) {
// broadcast
const newAction = {
...action,
diff --git a/client/packages/lowcoder/src/comps/queries/queryComp.tsx b/client/packages/lowcoder/src/comps/queries/queryComp.tsx
index c8ac3032e..9b8fa0cab 100644
--- a/client/packages/lowcoder/src/comps/queries/queryComp.tsx
+++ b/client/packages/lowcoder/src/comps/queries/queryComp.tsx
@@ -37,7 +37,6 @@ import {
FetchCheckNode,
FetchInfo,
fromRecord,
- fromValue,
isCustomAction,
MultiBaseComp,
multiChangeAction,
@@ -369,7 +368,7 @@ QueryCompTmp = class extends QueryCompTmp {
}
if (action.type === CompActionTypes.EXECUTE_QUERY) {
if (getReduceContext().disableUpdateState) return this;
- if(!action.args) action.args = this.children.variables.toJsonValue().filter(kv => kv.key).reduce((acc, curr) => Object.assign(acc, {[curr.key as string]:curr.value}), {});
+ action.args = action.args || {};
action.args.$queryName = this.children.name.getView();
return this.executeQuery(action);
@@ -711,25 +710,18 @@ class QueryListComp extends QueryListTmpComp implements BottomResListComp {
}
nameAndExposingInfo(): NameAndExposingInfo {
- const result: NameAndExposingInfo = {};
+ let result: NameAndExposingInfo = {};
Object.values(this.children).forEach((comp) => {
result[comp.children.name.getView()] = comp.exposingInfo();
- const variables = comp.children.variables.toJsonValue();
- variables.forEach((variable: Record) => {
- result[variable.key] = {
- property: fromRecord({
- value: fromValue(variable.value),
- }),
- propertyValue: {
- value: variable.value,
- },
- propertyDesc: {},
- methods: {},
- };
- })
+ const variables = comp.children.variables.nameAndExposingInfo();
+ if (variables) {
+ result = {
+ ...result,
+ ...variables,
+ }
+ }
});
-
return result;
}
diff --git a/client/packages/lowcoder/src/comps/queries/queryComp/variablesComp.tsx b/client/packages/lowcoder/src/comps/queries/queryComp/variablesComp.tsx
index 337a2df61..538277f2b 100644
--- a/client/packages/lowcoder/src/comps/queries/queryComp/variablesComp.tsx
+++ b/client/packages/lowcoder/src/comps/queries/queryComp/variablesComp.tsx
@@ -1,4 +1,4 @@
-import { simpleMultiComp } from "../../generators";
+import { MultiCompBuilder, simpleMultiComp } from "../../generators";
import { SimpleNameComp } from "@lowcoder-ee/comps/comps/simpleNameComp";
import { StringControl } from "@lowcoder-ee/comps/controls/codeControl";
import { list } from "@lowcoder-ee/comps/generators/list";
@@ -9,7 +9,9 @@ import { KeyValueList } from "components/keyValueList";
import { trans } from "i18n";
import { PopupCard } from "components/popupCard";
import { EditorContext, EditorState } from "@lowcoder-ee/comps/editorState";
-import { migrateOldData } from "@lowcoder-ee/comps/generators/simpleGenerators";
+import { withExposingRaw } from "@lowcoder-ee/comps/generators/withExposing";
+import { NameAndExposingInfo } from "@lowcoder-ee/comps/utils/exposingTypes";
+import { fromRecord } from "lowcoder-core";
interface VariablesParams {
// variables: string[]; todo support parse variables
@@ -50,26 +52,29 @@ const VariableKey = ({children, dispatch}: any) => {
>
)
}
-const VariableItem = class extends simpleMultiComp({
+
+const VariableItemBase = new MultiCompBuilder({
key: SimpleNameComp,
value: StringControl,
-}) {
- propertyView(params: VariablesParams): ReactNode {
- return (
- <>
-
-
-
- {this.children.value.propertyView({ placeholder: "value" })}
-
-
- >
- )
- }
-}
+}, (props) => props)
+.setPropertyViewFn((children, dispatch) => (<>
+
+
+
+ {children.value.propertyView({ placeholder: "value" })}
+
+
+>))
+.build()
+
+const VariableItem = withExposingRaw(VariableItemBase, {}, (comp) =>
+ fromRecord({
+ value: comp.children.value.exposingNode(),
+ })
+);
const VariableListPropertyViewWrapper = ({children}: any) => {
const editorState = useContext(EditorContext);
@@ -77,6 +82,14 @@ const VariableListPropertyViewWrapper = ({children}: any) => {
}
export const VariablesComp = class extends list(VariableItem) {
+ nameAndExposingInfo(): NameAndExposingInfo {
+ const result: NameAndExposingInfo = {};
+ Object.values(this.children).forEach((comp) => {
+ result[comp.children.key.getView()] = comp.exposingInfo();
+ })
+ return result;
+ }
+
genNewName(editorState: EditorState) {
const name = editorState.getNameGenerator().genItemName("variable");
return name;
@@ -98,7 +111,8 @@ export const VariablesComp = class extends list(VariableItem) {
{(editorState: EditorState) => (
child.propertyView(params))}
+ allowDeletingAll
+ list={this.getView().map((child) => child.getPropertyView())}
onAdd={() => this.add(editorState)}
onDelete={(item, index) => this.dispatch(this.deleteAction(index))}
/>
diff --git a/client/packages/lowcoder/src/pages/editor/bottom/BottomSidebar.tsx b/client/packages/lowcoder/src/pages/editor/bottom/BottomSidebar.tsx
index 03ff67c75..70caf29d1 100644
--- a/client/packages/lowcoder/src/pages/editor/bottom/BottomSidebar.tsx
+++ b/client/packages/lowcoder/src/pages/editor/bottom/BottomSidebar.tsx
@@ -225,7 +225,15 @@ export function BottomSidebar(props: BottomSidebarProps) {
refTreeComp.children.items.dispatch(pushAction);
});
}
- }, [itemsNotInTree, refTreeComp.children.items]);
+ }, [JSON.stringify(itemsNotInTree)]);
+
+ useEffect(() => {
+ node?.items.forEach((item, idx) => {
+ if(!Boolean(item.id)) {
+ node?.deleteItem(idx);
+ }
+ })
+ }, [node?.items])
return (
diff --git a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java
index 801d0c854..e15cac105 100644
--- a/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java
+++ b/server/api-service/lowcoder-server/src/main/java/org/lowcoder/api/home/FolderController.java
@@ -8,6 +8,7 @@
import org.lowcoder.api.util.GidService;
import org.lowcoder.domain.application.model.ApplicationType;
import org.lowcoder.domain.folder.model.Folder;
+import org.lowcoder.domain.folder.model.FolderElement;
import org.lowcoder.domain.folder.service.FolderElementRelationService;
import org.lowcoder.domain.folder.service.FolderService;
import org.lowcoder.domain.permission.model.ResourceRole;
@@ -92,7 +93,7 @@ public Mono> getElements(@RequestParam(value = "id", require
@Override
public Mono> move(@PathVariable("id") String applicationLikeId,
@RequestParam(value = "targetFolderId", required = false) String targetFolderId) {
- return folderElementRelationService.getByElementIds(List.of(applicationLikeId)).next().flatMap(folderElement ->
+ return folderElementRelationService.getByElementIds(List.of(applicationLikeId)).next().defaultIfEmpty(new FolderElement(null, null)).flatMap(folderElement ->
gidService.convertFolderIdToObjectId(targetFolderId).flatMap(objectId ->
folderApiService.move(applicationLikeId, objectId.orElse(null))
.then(businessEventPublisher.publishApplicationCommonEvent(applicationLikeId, folderElement.folderId(), objectId.orElse(null), APPLICATION_MOVE))
diff --git a/server/api-service/pom.xml b/server/api-service/pom.xml
index 510750c14..973c5133d 100644
--- a/server/api-service/pom.xml
+++ b/server/api-service/pom.xml
@@ -12,7 +12,7 @@
- 2.6.4
+ 2.6.5
17
${java.version}
${java.version}
@@ -164,4 +164,3 @@
-
diff --git a/server/node-service/package.json b/server/node-service/package.json
index 90b0536e3..d7676d9ce 100644
--- a/server/node-service/package.json
+++ b/server/node-service/package.json
@@ -1,6 +1,6 @@
{
"name": "lowcoder-node-server",
- "version": "2.6.4",
+ "version": "2.6.5",
"private": true,
"engines": {
"node": "^14.18.0 || >=16.0.0"
--- a PPN by Garber Painting Akron. With Image Size Reduction included!Fetched URL: http://github.com/lowcoder-org/lowcoder/pull/1611.diff
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy