Skip to content

Commit 1bf4a84

Browse files
authored
Merge pull request #1083 from lowcoder-org/table-column-tooltip
Table column separator and column tooltip
2 parents a739e2e + 4e21471 commit 1bf4a84

File tree

13 files changed

+146
-41
lines changed

13 files changed

+146
-41
lines changed

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

+46-21
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import styled from "styled-components";
77
import { JSONValue } from "util/jsonTypes";
88
import ColumnTypeView from "./columnTypeView";
99
import { TableCellContext } from "comps/comps/tableComp/tableContext";
10+
import Tooltip from "antd/es/tooltip";
1011

1112
type StatusType = PresetStatusColorType | "none";
1213
export const TABLE_EDITABLE_SWITCH_ON = true;
@@ -35,6 +36,7 @@ export interface CellProps {
3536
candidateTags?: string[];
3637
candidateStatus?: { text: string; status: StatusType }[];
3738
textOverflow?: boolean;
39+
cellTooltip?: string;
3840
onTableEvent?: (eventName: any) => void;
3941
}
4042

@@ -54,6 +56,25 @@ const BorderDiv = styled.div`
5456
left: 0;
5557
`;
5658

59+
const CellWrapper = ({
60+
children,
61+
tooltipTitle,
62+
}: {
63+
children: ReactNode,
64+
tooltipTitle?: string,
65+
}) => {
66+
if (tooltipTitle) {
67+
return (
68+
<Tooltip title={tooltipTitle} placement="topLeft">
69+
{children}
70+
</Tooltip>
71+
)
72+
}
73+
return (
74+
<>{children}</>
75+
)
76+
};
77+
5778
interface EditableCellProps<T> extends CellProps {
5879
normalView: ReactNode;
5980
dispatch: DispatchType;
@@ -123,27 +144,31 @@ export function EditableCell<T extends JSONValue>(props: EditableCellProps<T>) {
123144
</>
124145
);
125146
}
126-
147+
127148
return (
128-
<ColumnTypeView
129-
textOverflow={props.textOverflow}
130-
>
131-
{status === "toSave" && !isEditing && <EditableChip />}
132-
{normalView}
133-
{/* overlay on normal view to handle double click for editing */}
134-
{editable && (
135-
<div
136-
style={{
137-
position: 'absolute',
138-
top: 0,
139-
left: 0,
140-
width: '100%',
141-
height: '100%',
142-
}}
143-
onDoubleClick={enterEditFn}
144-
>
145-
</div>
146-
)}
147-
</ColumnTypeView>
149+
<ColumnTypeView
150+
textOverflow={props.textOverflow}
151+
>
152+
{status === "toSave" && !isEditing && <EditableChip />}
153+
<CellWrapper tooltipTitle={props.cellTooltip}>
154+
{normalView}
155+
</CellWrapper>
156+
{/* overlay on normal view to handle double click for editing */}
157+
{editable && (
158+
<CellWrapper tooltipTitle={props.cellTooltip}>
159+
<div
160+
style={{
161+
position: 'absolute',
162+
top: 0,
163+
left: 0,
164+
width: '100%',
165+
height: '100%',
166+
}}
167+
onDoubleClick={enterEditFn}
168+
>
169+
</div>
170+
</CellWrapper>
171+
)}
172+
</ColumnTypeView>
148173
);
149174
}

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnBooleanComp.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ const Wrapper = styled.div`
2121
padding: 0 8px;
2222
`;
2323

24-
const IconWrapper = styled.div<{ $style: CheckboxStyleType; $ifChecked: boolean }>`
25-
pointer-events: none;
24+
const IconWrapper = styled.span<{ $style: CheckboxStyleType; $ifChecked: boolean }>`
25+
// pointer-events: none;
2626
height: 22px;
27+
display: inline-block;
2728
svg {
2829
width: 14px;
2930
height: 22px;

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/columnDropdownComp.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ export const ColumnDropdownComp = (function () {
4747
const menu = (
4848
<Menu
4949
items={items}
50-
onClick={({ key }) => items.find((o) => o.key === key)?.onEvent?.("click")}
50+
onClick={({ key }) => {
51+
items.find((o) => o.key === key)?.onEvent?.("click")
52+
}}
5153
/>
5254
);
5355

client/packages/lowcoder/src/comps/comps/tableComp/column/columnTypeComps/simpleTextComp.tsx

+11-7
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@ export const SimpleTextComp = (function () {
2121
childrenMap,
2222
(props, dispatch) => {
2323
const value = props.changeValue ?? getBaseValue(props, dispatch);
24-
return <>{hasIcon(props.prefixIcon) && (
25-
<span>{props.prefixIcon}</span>
26-
)}
27-
<span>{value}</span>
28-
{hasIcon(props.suffixIcon) && (
29-
<span>{props.suffixIcon}</span>
30-
)} </>;
24+
return(
25+
<>
26+
{hasIcon(props.prefixIcon) && (
27+
<span>{props.prefixIcon}</span>
28+
)}
29+
<span>{value}</span>
30+
{hasIcon(props.suffixIcon) && (
31+
<span>{props.suffixIcon}</span>
32+
)}
33+
</>
34+
);
3135
},
3236
(nodeValue) => nodeValue.text.value,
3337
getBaseValue

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

+43-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { JSONValue } from "util/jsonTypes";
2828
import styled from "styled-components";
2929
import { TextOverflowControl } from "comps/controls/textOverflowControl";
3030
import { default as Divider } from "antd/es/divider";
31+
import { ColumnValueTooltip } from "./simpleColumnTypeComps";
3132
export type Render = ReturnType<ConstructorToComp<typeof RenderComp>["getOriginalComp"]>;
3233
export const RenderComp = withSelectedMultiContext(ColumnTypeComp);
3334

@@ -83,11 +84,39 @@ export type CellColorViewType = (param: {
8384
currentCell: JSONValue | undefined; //number | string;
8485
}) => string;
8586

87+
const cellTooltipLabel = trans("table.columnTooltip");
88+
const CellTooltipTempComp = withContext(
89+
new MultiCompBuilder({ tooltip: StringControl }, (props) => props.tooltip)
90+
.setPropertyViewFn((children) =>
91+
children.tooltip.propertyView({
92+
label: cellTooltipLabel,
93+
tooltip: ColumnValueTooltip,
94+
})
95+
)
96+
.build(),
97+
["currentCell", "currentRow", "currentIndex"] as const
98+
);
99+
100+
// @ts-ignore
101+
export class CellTooltipComp extends CellTooltipTempComp {
102+
override getPropertyView() {
103+
return controlItem({ filterText: cellTooltipLabel }, super.getPropertyView());
104+
}
105+
}
106+
107+
// fixme, should be infer from RowColorComp, but withContext type incorrect
108+
export type CellTooltipViewType = (param: {
109+
currentRow: any;
110+
currentCell: JSONValue | undefined; //number | string;
111+
}) => string;
112+
113+
86114
export const columnChildrenMap = {
87115
// column title
88116
title: StringControl,
89-
tooltip: StringControl,
117+
titleTooltip: StringControl,
90118
showTitle: withDefault(BoolControl, true),
119+
cellTooltip: CellTooltipComp,
91120
// a custom column or a data column
92121
isCustom: valueComp<boolean>(false),
93122
// If it is a data column, it must be the name of the column and cannot be duplicated as a react key
@@ -158,6 +187,16 @@ export class ColumnComp extends ColumnInitComp {
158187
})
159188
)
160189
);
190+
comp = comp.setChild(
191+
"cellTooltip",
192+
comp.children.cellTooltip.reduce(
193+
CellTooltipComp.changeContextDataAction({
194+
currentCell: undefined,
195+
currentRow: {},
196+
currentIndex: 0,
197+
})
198+
)
199+
);
161200
}
162201
if (action.type === CompActionTypes.CHANGE_VALUE) {
163202
const title = comp.children.title.unevaledValue;
@@ -208,9 +247,10 @@ export class ColumnComp extends ColumnInitComp {
208247
label: trans("table.columnTitle"),
209248
placeholder: this.children.dataIndex.getView(),
210249
})}
211-
{this.children.tooltip.propertyView({
212-
label: trans("labelProp.tooltip"),
250+
{this.children.titleTooltip.propertyView({
251+
label: trans("table.columnTitleTooltip"),
213252
})}
253+
{this.children.cellTooltip.getPropertyView()}
214254
<Dropdown
215255
showSearch={true}
216256
defaultValue={columnValue}

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

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export class TableImplComp extends TableInitComp implements IContainer {
9797
data: (this as any).exposingValues["displayData"],
9898
filename: fileName,
9999
fileType: "csv",
100+
delimiter: this.children.toolbar.children.columnSeparator.getView(),
100101
});
101102
}
102103

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { BoolControl } from "comps/controls/boolControl";
88
import { StringControl } from "comps/controls/codeControl";
99
import { dropdownControl } from "comps/controls/dropdownControl";
1010
import { TableToolbarStyleType } from "comps/controls/styleControlConstants";
11-
import { stateComp } from "comps/generators";
11+
import { stateComp, withDefault } from "comps/generators";
1212
import { genRandomKey } from "comps/utils/idGenerator";
1313
import { ThemeContext } from "comps/utils/themeContext";
1414
import { trans } from "i18n";
@@ -560,6 +560,7 @@ export const TableToolbarComp = (function () {
560560
// searchText: StringControl,
561561
filter: stateComp<TableFilter>({ stackType: "and", filters: [] }),
562562
position: dropdownControl(positionOptions, "below"),
563+
columnSeparator: withDefault(StringControl, ','),
563564
};
564565

565566
return new ControlNodeCompBuilder(childrenMap, (props, dispatch) => {
@@ -588,6 +589,10 @@ export const TableToolbarComp = (function () {
588589
children.showFilter.propertyView({ label: trans("table.showFilter") }),
589590
children.showRefresh.propertyView({ label: trans("table.showRefresh") }),
590591
children.showDownload.propertyView({ label: trans("table.showDownload") }),
592+
children.showDownload.getView() && children.columnSeparator.propertyView({
593+
label: trans("table.columnSeparator"),
594+
tooltip: trans("table.columnSeparatorTooltip"),
595+
}),
591596
children.columnSetting.propertyView({ label: trans("table.columnSetting") }),
592597
/* children.searchText.propertyView({
593598
label: trans("table.searchText"),

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

+8-2
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ export function columnsToAntdFormat(
337337
text: string;
338338
status: StatusType;
339339
}[];
340-
const title = renderTitle({ title: column.title, tooltip: column.tooltip, editable: column.editable });
340+
const title = renderTitle({ title: column.title, tooltip: column.titleTooltip, editable: column.editable });
341341

342342
return {
343343
title: column.showTitle ? title : '',
@@ -366,11 +366,12 @@ export function columnsToAntdFormat(
366366
cellColorFn: column.cellColor,
367367
onWidthResize: column.onWidthResize,
368368
render: (value: any, record: RecordType, index: number) => {
369+
const row = _.omit(record, OB_ROW_ORI_INDEX);
369370
return column
370371
.render(
371372
{
372373
currentCell: value,
373-
currentRow: _.omit(record, OB_ROW_ORI_INDEX),
374+
currentRow: row,
374375
currentIndex: index,
375376
currentOriginalIndex: tryToNumber(record[OB_ROW_ORI_INDEX]),
376377
initialColumns,
@@ -384,6 +385,11 @@ export function columnsToAntdFormat(
384385
candidateTags: tags,
385386
candidateStatus: status,
386387
textOverflow: column.textOverflow,
388+
cellTooltip: column.cellTooltip({
389+
currentCell: value,
390+
currentRow: row,
391+
currentIndex: index,
392+
}),
387393
onTableEvent,
388394
});
389395
},

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

+5-1
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,8 @@ export const de: typeof en = {
13811381
"showFilter": "Schaltfläche Filter anzeigen",
13821382
"showRefresh": "Schaltfläche \"Aktualisieren\" anzeigen",
13831383
"showDownload": "Download-Schaltfläche anzeigen",
1384+
"columnSeparator": "Spaltentrennzeichen",
1385+
"columnSeparatorTooltip": "Spaltentrennzeichen („Trennzeichen“) in der heruntergeladenen CSV-Datei. \n\nEmpfehlungen:\n- Komma (,)\n- Semikolon (;)\n- Pipe (|)\n- Tabulator (\\t)",
13841386
"columnSetting": "Schaltfläche Spalteneinstellung anzeigen",
13851387
"searchText": "Text suchen",
13861388
"searchTextTooltip": "Suche und Filterung der in der Tabelle dargestellten Daten",
@@ -1413,10 +1415,12 @@ export const de: typeof en = {
14131415
"action": "Aktion",
14141416
"columnValue": "Spalte Wert",
14151417
"columnValueTooltip": "\\'{{currentCell}}\\': Aktuelle Zelldaten\n \\'{{currentRow}}\\': Aktuelle Zeilendaten\n \\'{{currentIndex}}\\': Aktueller Datenindex (beginnend bei 0)\n Beispiel: \\'{{currentCell * 5}}\\' Show 5 Times the Original Value Data.",
1418+
"columnTooltip": "Spalten-Tooltip",
14161419
"imageSrc": "Bildquelle",
14171420
"imageSize": "Bildgröße",
14181421
"columnTitle": "Titel anzeigen",
1419-
"showTitle": "Show Title",
1422+
"columnTitleTooltip": "Titel-Tooltip",
1423+
"showTitle": "Titel anzeigen",
14201424
"showTitleTooltip": "Spaltentitel im Tabellenkopf ein-/ausblenden",
14211425
"sortable": "Sortierbar",
14221426
"align": "Ausrichtung",

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

+4
Original file line numberDiff line numberDiff line change
@@ -1836,6 +1836,8 @@ export const en = {
18361836
"showFilter": "Show Filter Button",
18371837
"showRefresh": "Show Refresh Button",
18381838
"showDownload": "Show Download Button",
1839+
"columnSeparator": "Column Separator",
1840+
"columnSeparatorTooltip": "Column Separator (\"delimiter\") in downloaded CSV file. \n\nRecommendations:\n- Comma (,)\n- Semicolon (;)\n- Pipe (|)\n- Tab (\\t)",
18391841
"columnSetting": "Show Column Setting Button",
18401842
"searchText": "Search Text",
18411843
"searchTextTooltip": "Search and Filter the Data Presented in the Table",
@@ -1868,9 +1870,11 @@ export const en = {
18681870
"action": "Action",
18691871
"columnValue": "Column Value",
18701872
"columnValueTooltip": "'{{currentCell}}': Current Cell Data\n '{{currentRow}}': Current Row Data\n '{{currentIndex}}': Current Data Index (Starting from 0)\n Example: '{{currentCell * 5}}' Show 5 Times the Original Value Data.",
1873+
"columnTooltip": "Column Tooltip",
18711874
"imageSrc": "Image Source",
18721875
"imageSize": "Image Size",
18731876
"columnTitle": "Title",
1877+
"columnTitleTooltip": "Title Tooltip",
18741878
"showTitle": "Show Title",
18751879
"showTitleTooltip": "Show/Hide column title in table header",
18761880
"sortable": "Sortable",

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

+4
Original file line numberDiff line numberDiff line change
@@ -1903,6 +1903,8 @@ export const pt: typeof en = {
19031903
"showFilter": "Mostrar Botão de Filtro",
19041904
"showRefresh": "Mostrar Botão de Atualização",
19051905
"showDownload": "Mostrar Botão de Download",
1906+
"columnSeparator": "Separador de colunas",
1907+
"columnSeparatorTooltip": "Separador de colunas (\"delimitador\") no arquivo CSV baixado. \n\nRecomendações:\n- Vírgula (,)\n- Ponto e vírgula (;)\n- Barra vertical (|)\n- Tabulação (\\t)",
19061908
"columnSetting": "Mostrar Botão de Configuração de Coluna",
19071909
"searchText": "Texto de Busca",
19081910
"searchTextTooltip": "Pesquisar e filtrar os dados apresentados na tabela",
@@ -1935,9 +1937,11 @@ export const pt: typeof en = {
19351937
"action": "Ação",
19361938
"columnValue": "Valor da Coluna",
19371939
"columnValueTooltip": "'{{currentCell}}': Dados da Célula Atual\n '{{currentRow}}': Dados da Linha Atual\n '{{currentIndex}}': Índice de Dados Atual (Começando de 0)\n Exemplo: '{{currentCell * 5}}' Mostra 5 Vezes o Valor Original dos Dados.",
1940+
"columnTooltip": "Dica de coluna",
19381941
"imageSrc": "Fonte da Imagem",
19391942
"imageSize": "Tamanho da Imagem",
19401943
"columnTitle": "Título",
1944+
"columnTitleTooltip": "Dica de título",
19411945
"showTitle": "Mostrar Título",
19421946
"showTitleTooltip": "Mostrar/Ocultar título da coluna no cabeçalho da tabela",
19431947
"sortable": "Classificável",

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

+4
Original file line numberDiff line numberDiff line change
@@ -1403,6 +1403,8 @@ export const zh: typeof en = {
14031403
showFilter: "显示筛选按钮",
14041404
showRefresh: "显示刷新按钮",
14051405
showDownload: "显示下载按钮",
1406+
columnSeparator: "柱分离器",
1407+
columnSeparatorTooltip: "下载的 CSV 文件中的列分隔符(\“分隔符\”)。 \n\n建议:\n- 逗号 (,)\n- 分号 (;)\n- 竖线 (|)\n- 制表符 (\\t)",
14061408
columnSetting: "显示列设置按钮",
14071409
searchText: "搜索文本",
14081410
searchTextTooltip: "搜索和筛选在表格中呈现的数据",
@@ -1435,9 +1437,11 @@ export const zh: typeof en = {
14351437
action: "操作",
14361438
columnValue: "列值",
14371439
columnValueTooltip: "'{{currentCell}}': 当前单元格数据\n" + "'{{currentRow}}': 当前行数据\n" + "'{{currentIndex}}': 当前数据索引(从0开始)\n" + "示例: '{{currentCell * 5}}' 显示原始值数据的5倍.",
1440+
columnTooltip: "列工具提示",
14381441
imageSrc: "图片链接",
14391442
imageSize: "图片尺寸",
14401443
columnTitle: "标题",
1444+
columnTitleTooltip: "标题工具提示",
14411445
dataMapping: "数据映射",
14421446
showTitle: "显示标题",
14431447
showTitleTooltip: "显示/隐藏表标题中的列标题",

0 commit comments

Comments
 (0)