Skip to content

Commit

Permalink
Merge pull request #1304 from lowcoder-org/fixes/table
Browse files Browse the repository at this point in the history
Table fixes related to sorting and text overflow visibility + added destroyInactiveTabPane in tab comp
  • Loading branch information
FalkWolsky authored Nov 14, 2024
2 parents e11e951 + a381ff7 commit 931fd16
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const ColumnTypeHoverView = styled.div<{
max-height: 150px;
max-width: 300px;
overflow: auto;
background: inherit;
background: #fafafa;
z-index: 3;
padding: ${(props) => props.$padding};
top: ${(props) => `${props.$adjustTop || 0}px`};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const childrenMap = {
events: eventHandlerControl(),
autoHeight: AutoHeightControl,
scrollbars: withDefault(BoolControl, false),
loadModuleInDomWhenHide: withDefault(BoolControl, true),
};

type DataType = ToDataType<ToInstanceType<typeof childrenMap>>;
Expand Down Expand Up @@ -127,6 +128,9 @@ class ModuleTmpComp extends ModuleCompBase {
label: trans("prop.scrollbar"),
})}
{hiddenPropertyView(this.children)}
{this.children.hidden.getView() && this.children.loadModuleInDomWhenHide.propertyView({
label: "Load module in DOM when hidden",
})}
</Section>
</>
);
Expand Down Expand Up @@ -525,6 +529,9 @@ const ModuleCompWithView = withViewFn(ModuleTmpComp, (comp) => {
if (error) {
return <Placeholder>{error}</Placeholder>;
}
if (comp.children.hidden.getView() && !comp.children.loadModuleInDomWhenHide.getView()) {
return null;
}

let content: ReactNode = appId ? <ModuleLoading /> : <Placeholder />;
if (comp.moduleRootComp && comp.isReady) {
Expand Down
27 changes: 23 additions & 4 deletions client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
RecordNode,
RecordNodeToValue,
routeByNameAction,
ValueAndMsg,
withFunction,
wrapChildAction,
} from "lowcoder-core";
Expand All @@ -55,7 +56,7 @@ import { lastValueIfEqual, shallowEqual } from "util/objectUtils";
import { IContainer } from "../containerBase";
import { getSelectedRowKeys } from "./selectionControl";
import { compTablePropertyView } from "./tablePropertyView";
import { RowColorComp, RowHeightComp, TableChildrenView, TableInitComp } from "./tableTypes";
import { RowColorComp, RowHeightComp, SortValue, TableChildrenView, TableInitComp } from "./tableTypes";

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

// handle sort: data -> sortedData
sortDataNode() {
const nodes = {
const nodes: {
data: Node<JSONObject[]>;
sort: Node<SortValue[]>;
dataIndexes: RecordNode<Record<string, Node<string>>>;
sortables: RecordNode<Record<string, Node<ValueAndMsg<boolean>>>>;
withParams: RecordNode<_.Dictionary<any>>,
} = {
data: this.children.data.exposingNode(),
sort: this.children.sort.node(),
dataIndexes: this.children.columns.getColumnsNode("dataIndex"),
sortables: this.children.columns.getColumnsNode("sortable"),
withParams: this.children.columns.withParamsNode(),
};
const sortedDataNode = withFunction(fromRecord(nodes), (input) => {
const { data, sort, dataIndexes, sortables } = input;
const columns = _(dataIndexes)
const sortColumns = _(dataIndexes)
.mapValues((dataIndex, idx) => ({ sortable: !!sortables[idx] }))
.mapKeys((sortable, idx) => dataIndexes[idx])
.value();
const sortedData = sortData(data, columns, sort);
const dataColumns = _(dataIndexes)
.mapValues((dataIndex, idx) => ({
dataIndex,
render: input.withParams[idx] as any,
}))
.value();
const updatedData: Array<RecordType> = data.map((row, index) => ({
...row,
[OB_ROW_ORI_INDEX]: index + "",
}));
const originalData = getOriDisplayData(updatedData, 1000, Object.values(dataColumns))
const sortedData = sortData(originalData, sortColumns, sort);
// console.info( "sortNode. data: ", data, " sort: ", sort, " columns: ", columns, " sortedData: ", sortedData);
return sortedData;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ export function columnsToAntdFormat(
status: StatusType;
}[];
const title = renderTitle({ title: column.title, tooltip: column.titleTooltip, editable: column.editable });

return {
key: `${column.dataIndex}-${mIndex}`,
title: column.showTitle ? title : '',
Expand Down Expand Up @@ -399,7 +399,7 @@ export function columnsToAntdFormat(
},
...(column.sortable
? {
sorter: true,
sorter: { multiple: (sortedColumns.length - mIndex) + 1 },
sortOrder: sortMap.get(column.dataIndex),
showSorterTooltip: false,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const childrenMap = {
onEvent: eventHandlerControl(EVENT_OPTIONS),
disabled: BoolCodeControl,
showHeader: withDefault(BoolControl, true),
destroyInactiveTab: withDefault(BoolControl, false),
style: styleControl(TabContainerStyle , 'style'),
headerStyle: styleControl(ContainerHeaderStyle , 'headerStyle'),
bodyStyle: styleControl(TabBodyStyle , 'bodyStyle'),
Expand Down Expand Up @@ -196,6 +197,7 @@ const TabbedContainer = (props: TabbedContainerProps) => {
headerStyle,
bodyStyle,
horizontalGridCells,
destroyInactiveTab,
} = props;

const visibleTabs = tabs.filter((tab) => !tab.hidden);
Expand Down Expand Up @@ -242,7 +244,8 @@ const TabbedContainer = (props: TabbedContainerProps) => {
return {
label,
key: tab.key,
forceRender: true,
forceRender: !destroyInactiveTab,
destroyInactiveTabPane: destroyInactiveTab,
children: (
<BackgroundColorContext.Provider value={bodyStyle.background}>
<ScrollBar style={{ height: props.autoHeight ? "auto" : "100%", margin: "0px", padding: "0px" }} hideScrollbar={!props.showVerticalScrollbar} overflow={props.autoHeight ? 'hidden':'scroll'}>
Expand Down Expand Up @@ -315,8 +318,9 @@ export const TabbedContainerBaseComp = (function () {
<Section name={sectionNames.interaction}>
{children.onEvent.getPropertyView()}
{disabledPropertyView(children)}
{children.showHeader.propertyView({ label: trans("tabbedContainer.showTabs") })}
{hiddenPropertyView(children)}
{children.showHeader.propertyView({ label: trans("tabbedContainer.showTabs") })}
{children.destroyInactiveTab.propertyView({ label: trans("tabbedContainer.destroyInactiveTab") })}
</Section>
)}

Expand Down
25 changes: 18 additions & 7 deletions client/packages/lowcoder/src/comps/controls/iconControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ import {
useIcon,
wrapperToControlItem,
} from "lowcoder-design";
import { ReactNode, useCallback, useState } from "react";
import { memo, ReactNode, useCallback, useMemo, useState } from "react";
import styled from "styled-components";
import { setFieldsNoTypeCheck } from "util/objectUtils";
import { StringControl } from "./codeControl";
import { ControlParams } from "./controlParams";
import { IconDictionary } from "@lowcoder-ee/constants/iconConstants";

const ButtonWrapper = styled.div`
width: 100%;
Expand Down Expand Up @@ -208,14 +209,24 @@ type ChangeModeAction = {
useCodeEditor: boolean;
};

export function IconControlView(props: { value: string }) {
export const IconControlView = memo((props: { value: string }) => {
const { value } = props;
const icon = useIcon(value);
if (icon) {
return icon.getView();
}
return <StyledImage src={value} alt="" />;
}

return useMemo(() => {
if (value && IconDictionary[value] && IconDictionary[value]?.title === icon?.title) {
return IconDictionary[value];
}

if (value && icon) {
const renderIcon = icon.getView();
IconDictionary[value] = renderIcon;
return renderIcon;
}

return <StyledImage src={value} alt="" />;
}, [icon, value, IconDictionary[value]])
});

export class IconControl extends AbstractComp<ReactNode, string, Node<ValueAndMsg<string>>> {
private readonly useCodeEditor: boolean;
Expand Down
5 changes: 5 additions & 0 deletions client/packages/lowcoder/src/constants/iconConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export let IconDictionary: Record<string, any> = {};

export const resetIconDictionary = () => {
IconDictionary = {};
}
1 change: 1 addition & 0 deletions client/packages/lowcoder/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2344,6 +2344,7 @@ export const en = {
"gutter" : "Gap",
"gutterTooltip" : "The distance between tabs in px",
"tabsCentered" : "Centered Tabs",
"destroyInactiveTab": "Destroy Inactive TabPane"
},
"formComp": {
"containerPlaceholder": "Drag Components from the Right Pane or",
Expand Down
2 changes: 2 additions & 0 deletions client/packages/lowcoder/src/pages/editor/AppEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import dayjs from "dayjs";
import { currentApplication } from "@lowcoder-ee/redux/selectors/applicationSelector";
import { notificationInstance } from "components/GlobalInstances";
import { AppState } from "@lowcoder-ee/redux/reducers";
import { resetIconDictionary } from "@lowcoder-ee/constants/iconConstants";

const AppSnapshot = lazy(() => {
return import("pages/editor/appSnapshot")
Expand Down Expand Up @@ -188,6 +189,7 @@ const AppEditor = React.memo(() => {
useEffect(() => {
if(!isLowcoderCompLoading) {
fetchApplication();
resetIconDictionary();
}
}, [isLowcoderCompLoading, fetchApplication]);

Expand Down

0 comments on commit 931fd16

Please sign in to comment.