Skip to content

Commit 931fd16

Browse files
authored
Merge pull request #1304 from lowcoder-org/fixes/table
Table fixes related to sorting and text overflow visibility + added destroyInactiveTabPane in tab comp
2 parents e11e951 + a381ff7 commit 931fd16

File tree

9 files changed

+65
-16
lines changed

9 files changed

+65
-16
lines changed

client/packages/lowcoder/src/components/table/columnTypeView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const ColumnTypeHoverView = styled.div<{
3838
max-height: 150px;
3939
max-width: 300px;
4040
overflow: auto;
41-
background: inherit;
41+
background: #fafafa;
4242
z-index: 3;
4343
padding: ${(props) => props.$padding};
4444
top: ${(props) => `${props.$adjustTop || 0}px`};

client/packages/lowcoder/src/comps/comps/moduleComp/moduleComp.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ const childrenMap = {
8585
events: eventHandlerControl(),
8686
autoHeight: AutoHeightControl,
8787
scrollbars: withDefault(BoolControl, false),
88+
loadModuleInDomWhenHide: withDefault(BoolControl, true),
8889
};
8990

9091
type DataType = ToDataType<ToInstanceType<typeof childrenMap>>;
@@ -127,6 +128,9 @@ class ModuleTmpComp extends ModuleCompBase {
127128
label: trans("prop.scrollbar"),
128129
})}
129130
{hiddenPropertyView(this.children)}
131+
{this.children.hidden.getView() && this.children.loadModuleInDomWhenHide.propertyView({
132+
label: "Load module in DOM when hidden",
133+
})}
130134
</Section>
131135
</>
132136
);
@@ -525,6 +529,9 @@ const ModuleCompWithView = withViewFn(ModuleTmpComp, (comp) => {
525529
if (error) {
526530
return <Placeholder>{error}</Placeholder>;
527531
}
532+
if (comp.children.hidden.getView() && !comp.children.loadModuleInDomWhenHide.getView()) {
533+
return null;
534+
}
528535

529536
let content: ReactNode = appId ? <ModuleLoading /> : <Placeholder />;
530537
if (comp.moduleRootComp && comp.isReady) {

client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
RecordNode,
4747
RecordNodeToValue,
4848
routeByNameAction,
49+
ValueAndMsg,
4950
withFunction,
5051
wrapChildAction,
5152
} from "lowcoder-core";
@@ -55,7 +56,7 @@ import { lastValueIfEqual, shallowEqual } from "util/objectUtils";
5556
import { IContainer } from "../containerBase";
5657
import { getSelectedRowKeys } from "./selectionControl";
5758
import { compTablePropertyView } from "./tablePropertyView";
58-
import { RowColorComp, RowHeightComp, TableChildrenView, TableInitComp } from "./tableTypes";
59+
import { RowColorComp, RowHeightComp, SortValue, TableChildrenView, TableInitComp } from "./tableTypes";
5960

6061
import { useContext, useState } from "react";
6162
import { EditorContext } from "comps/editorState";
@@ -295,19 +296,37 @@ export class TableImplComp extends TableInitComp implements IContainer {
295296

296297
// handle sort: data -> sortedData
297298
sortDataNode() {
298-
const nodes = {
299+
const nodes: {
300+
data: Node<JSONObject[]>;
301+
sort: Node<SortValue[]>;
302+
dataIndexes: RecordNode<Record<string, Node<string>>>;
303+
sortables: RecordNode<Record<string, Node<ValueAndMsg<boolean>>>>;
304+
withParams: RecordNode<_.Dictionary<any>>,
305+
} = {
299306
data: this.children.data.exposingNode(),
300307
sort: this.children.sort.node(),
301308
dataIndexes: this.children.columns.getColumnsNode("dataIndex"),
302309
sortables: this.children.columns.getColumnsNode("sortable"),
310+
withParams: this.children.columns.withParamsNode(),
303311
};
304312
const sortedDataNode = withFunction(fromRecord(nodes), (input) => {
305313
const { data, sort, dataIndexes, sortables } = input;
306-
const columns = _(dataIndexes)
314+
const sortColumns = _(dataIndexes)
307315
.mapValues((dataIndex, idx) => ({ sortable: !!sortables[idx] }))
308316
.mapKeys((sortable, idx) => dataIndexes[idx])
309317
.value();
310-
const sortedData = sortData(data, columns, sort);
318+
const dataColumns = _(dataIndexes)
319+
.mapValues((dataIndex, idx) => ({
320+
dataIndex,
321+
render: input.withParams[idx] as any,
322+
}))
323+
.value();
324+
const updatedData: Array<RecordType> = data.map((row, index) => ({
325+
...row,
326+
[OB_ROW_ORI_INDEX]: index + "",
327+
}));
328+
const originalData = getOriDisplayData(updatedData, 1000, Object.values(dataColumns))
329+
const sortedData = sortData(originalData, sortColumns, sort);
311330
// console.info( "sortNode. data: ", data, " sort: ", sort, " columns: ", columns, " sortedData: ", sortedData);
312331
return sortedData;
313332
});

client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ export function columnsToAntdFormat(
340340
status: StatusType;
341341
}[];
342342
const title = renderTitle({ title: column.title, tooltip: column.titleTooltip, editable: column.editable });
343-
343+
344344
return {
345345
key: `${column.dataIndex}-${mIndex}`,
346346
title: column.showTitle ? title : '',
@@ -399,7 +399,7 @@ export function columnsToAntdFormat(
399399
},
400400
...(column.sortable
401401
? {
402-
sorter: true,
402+
sorter: { multiple: (sortedColumns.length - mIndex) + 1 },
403403
sortOrder: sortMap.get(column.dataIndex),
404404
showSorterTooltip: false,
405405
}

client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ const childrenMap = {
6161
onEvent: eventHandlerControl(EVENT_OPTIONS),
6262
disabled: BoolCodeControl,
6363
showHeader: withDefault(BoolControl, true),
64+
destroyInactiveTab: withDefault(BoolControl, false),
6465
style: styleControl(TabContainerStyle , 'style'),
6566
headerStyle: styleControl(ContainerHeaderStyle , 'headerStyle'),
6667
bodyStyle: styleControl(TabBodyStyle , 'bodyStyle'),
@@ -196,6 +197,7 @@ const TabbedContainer = (props: TabbedContainerProps) => {
196197
headerStyle,
197198
bodyStyle,
198199
horizontalGridCells,
200+
destroyInactiveTab,
199201
} = props;
200202

201203
const visibleTabs = tabs.filter((tab) => !tab.hidden);
@@ -242,7 +244,8 @@ const TabbedContainer = (props: TabbedContainerProps) => {
242244
return {
243245
label,
244246
key: tab.key,
245-
forceRender: true,
247+
forceRender: !destroyInactiveTab,
248+
destroyInactiveTabPane: destroyInactiveTab,
246249
children: (
247250
<BackgroundColorContext.Provider value={bodyStyle.background}>
248251
<ScrollBar style={{ height: props.autoHeight ? "auto" : "100%", margin: "0px", padding: "0px" }} hideScrollbar={!props.showVerticalScrollbar} overflow={props.autoHeight ? 'hidden':'scroll'}>
@@ -315,8 +318,9 @@ export const TabbedContainerBaseComp = (function () {
315318
<Section name={sectionNames.interaction}>
316319
{children.onEvent.getPropertyView()}
317320
{disabledPropertyView(children)}
318-
{children.showHeader.propertyView({ label: trans("tabbedContainer.showTabs") })}
319321
{hiddenPropertyView(children)}
322+
{children.showHeader.propertyView({ label: trans("tabbedContainer.showTabs") })}
323+
{children.destroyInactiveTab.propertyView({ label: trans("tabbedContainer.destroyInactiveTab") })}
320324
</Section>
321325
)}
322326

client/packages/lowcoder/src/comps/controls/iconControl.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ import {
2626
useIcon,
2727
wrapperToControlItem,
2828
} from "lowcoder-design";
29-
import { ReactNode, useCallback, useState } from "react";
29+
import { memo, ReactNode, useCallback, useMemo, useState } from "react";
3030
import styled from "styled-components";
3131
import { setFieldsNoTypeCheck } from "util/objectUtils";
3232
import { StringControl } from "./codeControl";
3333
import { ControlParams } from "./controlParams";
34+
import { IconDictionary } from "@lowcoder-ee/constants/iconConstants";
3435

3536
const ButtonWrapper = styled.div`
3637
width: 100%;
@@ -208,14 +209,24 @@ type ChangeModeAction = {
208209
useCodeEditor: boolean;
209210
};
210211

211-
export function IconControlView(props: { value: string }) {
212+
export const IconControlView = memo((props: { value: string }) => {
212213
const { value } = props;
213214
const icon = useIcon(value);
214-
if (icon) {
215-
return icon.getView();
216-
}
217-
return <StyledImage src={value} alt="" />;
218-
}
215+
216+
return useMemo(() => {
217+
if (value && IconDictionary[value] && IconDictionary[value]?.title === icon?.title) {
218+
return IconDictionary[value];
219+
}
220+
221+
if (value && icon) {
222+
const renderIcon = icon.getView();
223+
IconDictionary[value] = renderIcon;
224+
return renderIcon;
225+
}
226+
227+
return <StyledImage src={value} alt="" />;
228+
}, [icon, value, IconDictionary[value]])
229+
});
219230

220231
export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMsg<string>>> {
221232
private readonly useCodeEditor: boolean;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export let IconDictionary: Record<string, any> = {};
2+
3+
export const resetIconDictionary = () => {
4+
IconDictionary = {};
5+
}

client/packages/lowcoder/src/i18n/locales/en.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2344,6 +2344,7 @@ export const en = {
23442344
"gutter" : "Gap",
23452345
"gutterTooltip" : "The distance between tabs in px",
23462346
"tabsCentered" : "Centered Tabs",
2347+
"destroyInactiveTab": "Destroy Inactive TabPane"
23472348
},
23482349
"formComp": {
23492350
"containerPlaceholder": "Drag Components from the Right Pane or",

client/packages/lowcoder/src/pages/editor/AppEditor.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import dayjs from "dayjs";
3636
import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSelector";
3737
import { notificationInstance } from "components/GlobalInstances";
3838
import { AppState } from "@lowcoder-ee/redux/reducers";
39+
import { resetIconDictionary } from "@lowcoder-ee/constants/iconConstants";
3940

4041
const AppSnapshot = lazy(() => {
4142
return import("pages/editor/appSnapshot")
@@ -188,6 +189,7 @@ const AppEditor = React.memo(() => {
188189
useEffect(() => {
189190
if(!isLowcoderCompLoading) {
190191
fetchApplication();
192+
resetIconDictionary();
191193
}
192194
}, [isLowcoderCompLoading, fetchApplication]);
193195

0 commit comments

Comments
 (0)