Skip to content

Commit 2a08d40

Browse files
allow inline new row addition
1 parent 52e9166 commit 2a08d40

File tree

10 files changed

+198
-29
lines changed

10 files changed

+198
-29
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ export function EditableCell<T extends JSONValue>(props: EditableCellProps<T>) {
164164
width: '100%',
165165
height: '100%',
166166
}}
167-
onDoubleClick={enterEditFn}
167+
// onDoubleClick={enterEditFn}
168+
onClick={enterEditFn}
168169
>
169170
</div>
170171
</CellWrapper>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ export const ColumnTagsComp = (function () {
259259
tagOptionsList = props.tagColors;
260260
let value = props.changeValue ?? getBaseValue(props, dispatch);
261261
value = typeof value === "string" && value.split(",")[1] ? value.split(",") : value;
262-
const tags = _.isArray(value) ? value : [value];
262+
const tags = _.isArray(value) ? value : (value.length ? [value] : []);
263263
const view = tags.map((tag, index) => {
264264
// The actual eval value is of type number or boolean
265265
const tagText = String(tag);

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { ColumnValueTooltip } from "./simpleColumnTypeComps";
3232
import { SummaryColumnComp } from "./tableSummaryColumnComp";
3333
import Segmented from "antd/es/segmented";
3434
import { list } from "@lowcoder-ee/comps/generators/list";
35+
import { EMPTY_ROW_KEY } from "../tableCompView";
3536
export type Render = ReturnType<ConstructorToComp<typeof RenderComp>["getOriginalComp"]>;
3637
export const RenderComp = withSelectedMultiContext(ColumnTypeComp);
3738

@@ -385,9 +386,9 @@ export class ColumnComp extends ColumnInitComp {
385386

386387
getChangeSet() {
387388
const dataIndex = this.children.dataIndex.getView();
388-
const changeSet = _.mapValues(this.children.render.getMap(), (value) =>
389-
value.getComp().children.comp.children.changeValue.getView()
390-
);
389+
const changeSet = _.mapValues(this.children.render.getMap(), (value) =>{
390+
return value.getComp().children.comp.children.changeValue.getView()
391+
});
391392
return { [dataIndex]: changeSet };
392393
}
393394

@@ -404,6 +405,16 @@ export class ColumnComp extends ColumnInitComp {
404405
);
405406
}
406407

408+
dispatchClearInsertSet() {
409+
const renderMap = this.children.render.getMap();
410+
const insertMapKeys = Object.keys(renderMap).filter(key => key.startsWith(EMPTY_ROW_KEY));
411+
const insertMap: Record<string, any> = {};
412+
insertMapKeys.forEach(key => {
413+
const render = renderMap[key];
414+
render.getComp().children.comp.children.changeValue.dispatchChangeValueAction(null);
415+
});
416+
}
417+
407418
static setSelectionAction(key: string) {
408419
return wrapChildAction("render", RenderComp.setSelectionAction(key));
409420
}

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

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { shallowEqual } from "react-redux";
1818
import { JSONObject, JSONValue } from "util/jsonTypes";
1919
import { lastValueIfEqual } from "util/objectUtils";
2020
import { SummaryColumnComp } from "./tableSummaryColumnComp";
21+
import { EMPTY_ROW_KEY } from "../tableCompView";
2122

2223
/**
2324
* column list
@@ -72,14 +73,17 @@ export class ColumnListComp extends ColumnListTmpComp {
7273
return super.reduce(action);
7374
}
7475

75-
getChangeSet() {
76+
getChangeSet(filterNewRowsChange?: boolean) {
7677
const changeSet: Record<string, Record<string, JSONValue>> = {};
7778
const columns = this.getView();
7879
columns.forEach((column) => {
7980
const columnChangeSet = column.getChangeSet();
8081
Object.keys(columnChangeSet).forEach((dataIndex) => {
8182
Object.keys(columnChangeSet[dataIndex]).forEach((key) => {
82-
if (!_.isNil(columnChangeSet[dataIndex][key])) {
83+
const includeChange = filterNewRowsChange
84+
? key.startsWith(EMPTY_ROW_KEY)
85+
: !key.startsWith(EMPTY_ROW_KEY);
86+
if (!_.isNil(columnChangeSet[dataIndex][key]) && includeChange) {
8387
if (!changeSet[key]) changeSet[key] = {};
8488
changeSet[key][dataIndex] = columnChangeSet[dataIndex][key];
8589
}
@@ -94,6 +98,11 @@ export class ColumnListComp extends ColumnListTmpComp {
9498
columns.forEach((column) => column.dispatchClearChangeSet());
9599
}
96100

101+
dispatchClearInsertSet() {
102+
const columns = this.getView();
103+
columns.forEach((column) => column.dispatchClearInsertSet());
104+
}
105+
97106
/**
98107
* If the table data changes, call this method to trigger the action
99108
*/

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

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { tableDataRowExample } from "comps/comps/tableComp/column/tableColumnListComp";
22
import { getPageSize } from "comps/comps/tableComp/paginationControl";
3-
import { TableCompView } from "comps/comps/tableComp/tableCompView";
3+
import { EMPTY_ROW_KEY, TableCompView } from "comps/comps/tableComp/tableCompView";
44
import { TableFilter } from "comps/comps/tableComp/tableToolbarComp";
55
import {
66
columnHide,
@@ -40,7 +40,11 @@ import {
4040
deferAction,
4141
executeQueryAction,
4242
fromRecord,
43+
FunctionNode,
44+
Node,
4345
onlyEvalAction,
46+
RecordNode,
47+
RecordNodeToValue,
4448
routeByNameAction,
4549
withFunction,
4650
wrapChildAction,
@@ -53,7 +57,7 @@ import { getSelectedRowKeys } from "./selectionControl";
5357
import { compTablePropertyView } from "./tablePropertyView";
5458
import { RowColorComp, RowHeightComp, TableChildrenView, TableInitComp } from "./tableTypes";
5559

56-
import { useContext } from "react";
60+
import { useContext, useState } from "react";
5761
import { EditorContext } from "comps/editorState";
5862

5963
export class TableImplComp extends TableInitComp implements IContainer {
@@ -401,12 +405,11 @@ export class TableImplComp extends TableInitComp implements IContainer {
401405
)[0];
402406
}
403407

404-
changeSetNode() {
405-
const nodes = {
406-
dataIndexes: this.children.columns.getColumnsNode("dataIndex"),
407-
renders: this.children.columns.getColumnsNode("render"),
408-
};
409-
const resNode = withFunction(fromRecord(nodes), (input) => {
408+
private getUpsertSetResNode(
409+
nodes: Record<string, RecordNode<Record<string, Node<any>>>>,
410+
filterNewRows?: boolean,
411+
) {
412+
return withFunction(fromRecord(nodes), (input) => {
410413
// merge input.dataIndexes and input.withParams into one structure
411414
const dataIndexRenderDict = _(input.dataIndexes)
412415
.mapValues((dataIndex, idx) => input.renders[idx])
@@ -416,26 +419,45 @@ export class TableImplComp extends TableInitComp implements IContainer {
416419
_.forEach(dataIndexRenderDict, (render, dataIndex) => {
417420
_.forEach(render[MAP_KEY], (value, key) => {
418421
const changeValue = (value.comp as any).comp.changeValue;
419-
if (!_.isNil(changeValue)) {
422+
const includeRecord = (filterNewRows && key.startsWith(EMPTY_ROW_KEY)) || (!filterNewRows && !key.startsWith(EMPTY_ROW_KEY));
423+
if (!_.isNil(changeValue) && includeRecord) {
420424
if (!record[key]) record[key] = {};
421425
record[key][dataIndex] = changeValue;
422426
}
423427
});
424428
});
425429
return record;
426430
});
431+
}
432+
433+
changeSetNode() {
434+
const nodes = {
435+
dataIndexes: this.children.columns.getColumnsNode("dataIndex"),
436+
renders: this.children.columns.getColumnsNode("render"),
437+
};
438+
439+
const resNode = this.getUpsertSetResNode(nodes);
427440
return lastValueIfEqual(this, "changeSetNode", [resNode, nodes] as const, (a, b) =>
428441
shallowEqual(a[1], b[1])
429442
)[0];
430443
}
431444

432-
toUpdateRowsNode() {
445+
insertSetNode() {
433446
const nodes = {
434-
oriDisplayData: this.oriDisplayDataNode(),
435-
indexes: this.displayDataIndexesNode(),
436-
changeSet: this.changeSetNode(),
447+
dataIndexes: this.children.columns.getColumnsNode("dataIndex"),
448+
renders: this.children.columns.getColumnsNode("render"),
437449
};
438-
const resNode = withFunction(fromRecord(nodes), (input) => {
450+
451+
const resNode = this.getUpsertSetResNode(nodes, true);
452+
return lastValueIfEqual(this, "insertSetNode", [resNode, nodes] as const, (a, b) =>
453+
shallowEqual(a[1], b[1])
454+
)[0];
455+
}
456+
457+
private getToUpsertRowsResNodes(
458+
nodes: Record<string, FunctionNode<any, any>>
459+
) {
460+
return withFunction(fromRecord(nodes), (input) => {
439461
const res = _(input.changeSet)
440462
.map((changeValues, oriIndex) => {
441463
const idx = input.indexes[oriIndex];
@@ -446,11 +468,34 @@ export class TableImplComp extends TableInitComp implements IContainer {
446468
// console.info("toUpdateRowsNode. input: ", input, " res: ", res);
447469
return res;
448470
});
471+
}
472+
473+
toUpdateRowsNode() {
474+
const nodes = {
475+
oriDisplayData: this.oriDisplayDataNode(),
476+
indexes: this.displayDataIndexesNode(),
477+
changeSet: this.changeSetNode(),
478+
};
479+
480+
const resNode = this.getToUpsertRowsResNodes(nodes);
449481
return lastValueIfEqual(this, "toUpdateRowsNode", [resNode, nodes] as const, (a, b) =>
450482
shallowEqual(a[1], b[1])
451483
)[0];
452484
}
453485

486+
toInsertRowsNode() {
487+
const nodes = {
488+
oriDisplayData: this.oriDisplayDataNode(),
489+
indexes: this.displayDataIndexesNode(),
490+
changeSet: this.insertSetNode(),
491+
};
492+
493+
const resNode = this.getToUpsertRowsResNodes(nodes);
494+
return lastValueIfEqual(this, "toInsertRowsNode", [resNode, nodes] as const, (a, b) =>
495+
shallowEqual(a[1], b[1])
496+
)[0];
497+
}
498+
454499
columnAggrNode() {
455500
const nodes = {
456501
oriDisplayData: this.oriDisplayDataNode(),
@@ -473,6 +518,7 @@ export class TableImplComp extends TableInitComp implements IContainer {
473518
}
474519

475520
let TableTmpComp = withViewFn(TableImplComp, (comp) => {
521+
const [emptyRows, setEmptyRows] = useState([]);
476522
return (
477523
<HidableView hidden={comp.children.hidden.getView()}>
478524
<TableCompView
@@ -687,6 +733,14 @@ export const TableComp = withExposingConfigs(TableTmpComp, [
687733
(input) => input.changeSet,
688734
trans("table.changeSetDesc")
689735
),
736+
new CompDepsConfig(
737+
"insertSet",
738+
(comp) => ({
739+
insertSet: comp.insertSetNode(),
740+
}),
741+
(input) => input.insertSet,
742+
trans("table.changeSetDesc")
743+
),
690744
new CompDepsConfig(
691745
"toUpdateRows",
692746
(comp) => ({
@@ -697,6 +751,16 @@ export const TableComp = withExposingConfigs(TableTmpComp, [
697751
},
698752
trans("table.toUpdateRowsDesc")
699753
),
754+
new CompDepsConfig(
755+
"toInsertRows",
756+
(comp) => ({
757+
toInsertRows: comp.toInsertRowsNode(),
758+
}),
759+
(input) => {
760+
return input.toInsertRows;
761+
},
762+
trans("table.toUpdateRowsDesc")
763+
),
700764
new DepsConfig(
701765
"pageNo",
702766
(children) => {

0 commit comments

Comments
 (0)