Skip to content

Commit 4033990

Browse files
author
FalkWolsky
committed
Icons for Number, Text & Tag Columns Types
1 parent 5e3d5a6 commit 4033990

File tree

7 files changed

+116
-20
lines changed

7 files changed

+116
-20
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ export function EditableCell<T extends JSONValue>(props: EditableCellProps<T>) {
7171
changeValue,
7272
baseValue,
7373
candidateTags,
74+
// tagColors
7475
candidateStatus,
7576
onTableEvent,
7677
} = props;

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

+20-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { ColumnTypeCompBuilder, ColumnTypeViewFn } from "../columnTypeCompBuilde
66
import { ColumnValueTooltip } from "../simpleColumnTypeComps";
77
import { withDefault } from "comps/generators";
88
import styled from "styled-components";
9+
import { IconControl } from "comps/controls/iconControl";
10+
import { hasIcon } from "comps/utils";
911

1012
const InputNumberWrapper = styled.div`
1113
.ant-input-number {
@@ -28,6 +30,8 @@ const childrenMap = {
2830
precision: RangeControl.closed(0, 20, 0),
2931
float: BoolControl,
3032
prefix: StringControl,
33+
prefixIcon: IconControl,
34+
suffixIcon: IconControl,
3135
suffix: StringControl,
3236
};
3337

@@ -46,14 +50,22 @@ export const ColumnNumberComp = (function () {
4650
childrenMap,
4751
(props, dispatch) => {
4852
float = props.float;
49-
step = props.step;
53+
step = props.step;
5054
precision = props.precision;
5155
const value = props.changeValue ?? getBaseValue(props, dispatch);
5256
let formattedValue: string | number = !float ? Math.floor(value) : value;
5357
if(float) {
5458
formattedValue = formattedValue.toFixed(precision + 1);
5559
}
56-
return props.prefix + formattedValue + props.suffix;
60+
return (
61+
<>{hasIcon(props.prefixIcon) && (
62+
<span>{props.prefixIcon}</span>
63+
)}
64+
<span>{props.prefix + formattedValue + props.suffix}</span>
65+
{hasIcon(props.suffixIcon) && (
66+
<span>{props.suffixIcon}</span>
67+
)} </>
68+
);
5769
},
5870
(nodeValue) => nodeValue.text.value,
5971
getBaseValue,
@@ -103,9 +115,15 @@ export const ColumnNumberComp = (function () {
103115
{children.prefix.propertyView({
104116
label: trans("table.prefix"),
105117
})}
118+
{children.prefixIcon.propertyView({
119+
label: trans("button.prefixIcon"),
120+
})}
106121
{children.suffix.propertyView({
107122
label: trans("table.suffix"),
108123
})}
124+
{children.suffixIcon.propertyView({
125+
label: trans("button.suffixIcon"),
126+
})}
109127
{children.float.propertyView({
110128
label: trans("table.float"),
111129
onChange: (isFloat) => {

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

+18-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { CheckboxStyle, CheckboxStyleType } from "comps/controls/styleControlCon
99
import { useStyle } from "comps/controls/styleControl";
1010
import { dropdownControl } from "comps/controls/dropdownControl";
1111
import { TableCheckedIcon, TableUnCheckedIcon } from "lowcoder-design";
12+
import { IconControl } from "comps/controls/iconControl";
13+
import { hasIcon } from "comps/utils";
1214

1315
const CheckboxStyled = styled(Checkbox)<{ $style: CheckboxStyleType }>`
1416
${(props) => props.$style && getStyle(props.$style)}
@@ -49,6 +51,9 @@ const falseValuesOptions = [
4951
const childrenMap = {
5052
text: BoolCodeControl,
5153
falseValues: dropdownControl(falseValuesOptions, ""),
54+
iconTrue: IconControl,
55+
iconFalse: IconControl,
56+
iconNull: IconControl,
5257
};
5358

5459
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, boolean, boolean> = (props) => props.text;
@@ -88,16 +93,10 @@ export const BooleanComp = (function () {
8893
const CheckBoxComp = () => {
8994
const style = useStyle(CheckboxStyle);
9095
return (
91-
<IconWrapper
92-
$style={style}
93-
$ifChecked={value}
94-
>
95-
{value ? (
96-
<TableCheckedIcon />
97-
) : props.falseValues === "x" ? (
98-
<TableUnCheckedIcon />
99-
) : (
100-
props.falseValues
96+
<IconWrapper $style={style} $ifChecked={value}>
97+
{value === true ? ( hasIcon(props.iconTrue) ? props.iconTrue : <TableCheckedIcon /> )
98+
: value === false ? ( hasIcon(props.iconFalse) ? props.iconFalse : ( props.falseValues === "x" ? <TableUnCheckedIcon /> : props.falseValues )
99+
) : ( hasIcon(props.iconNull) ? props.iconNull : "No Value"
101100
)}
102101
</IconWrapper>
103102
);
@@ -127,6 +126,15 @@ export const BooleanComp = (function () {
127126
label: trans("table.falseValues"),
128127
radioButton: true,
129128
})}
129+
{children.iconTrue.propertyView({
130+
label: trans("table.iconTrue"),
131+
})}
132+
{children.iconFalse.propertyView({
133+
label: trans("table.iconFalse"),
134+
})}
135+
{children.iconNull.propertyView({
136+
label: trans("table.iconNull"),
137+
})}
130138
</>
131139
);
132140
})

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

+30-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { toJson } from "really-relaxed-json";
1515
import { hashToNum } from "util/stringUtils";
1616
import { CustomSelect, PackUpIcon } from "lowcoder-design";
1717
import { ScrollBar } from "lowcoder-design";
18+
import { ColoredTagOptionControl } from "comps/controls/optionsControl";
1819

1920
const colors = PresetStatusColorTypes;
2021

@@ -55,13 +56,22 @@ const TagsControl = codeControl<Array<string> | string>(
5556
{ expectedType: "string | Array<string>", codeType: "JSON" }
5657
);
5758

58-
function getTagColor(text: string) {
59-
const index = Math.abs(hashToNum(text)) % colors.length;
60-
return colors[index];
59+
function getTagColor(tagText : any, tagOptions: any[]) {
60+
const foundOption = tagOptions.find((option: { label: any; }) => option.label === tagText);
61+
return foundOption ? foundOption.color : (function() {
62+
const index = Math.abs(hashToNum(tagText)) % colors.length;
63+
return colors[index];
64+
})();
65+
}
66+
67+
function getTagIcon(tagText: any, tagOptions: any[]) {
68+
const foundOption = tagOptions.find(option => option.label === tagText);
69+
return foundOption ? foundOption.icon : undefined;
6170
}
6271

6372
const childrenMap = {
6473
text: TagsControl,
74+
tagColors: ColoredTagOptionControl,
6575
};
6676

6777
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string | string[], string | string[]> = (
@@ -135,6 +145,9 @@ export const Wrapper = styled.div`
135145
}
136146
}
137147
}
148+
.ant-tag svg {
149+
margin-right: 4px;
150+
}
138151
`;
139152

140153
export const DropdownStyled = styled.div`
@@ -152,6 +165,12 @@ export const DropdownStyled = styled.div`
152165
}
153166
`;
154167

168+
export const TagStyled = styled(Tag)`
169+
svg {
170+
margin-right: 4px;
171+
}
172+
`;
173+
155174
const TagEdit = (props: TagEditPropsType) => {
156175
const defaultTags = useContext(TagsContext);
157176
const [tags, setTags] = useState(() => {
@@ -206,12 +225,12 @@ const TagEdit = (props: TagEditPropsType) => {
206225
<CustomSelect.Option value={value} key={index}>
207226
{value.split(",")[1] ? (
208227
value.split(",").map((item, i) => (
209-
<Tag color={getTagColor(item)} key={i} style={{ marginRight: "8px" }}>
228+
<Tag color={getTagColor(item, [])} key={i} style={{ marginRight: "8px" }}>
210229
{item}
211230
</Tag>
212231
))
213232
) : (
214-
<Tag color={getTagColor(value)} key={index}>
233+
<Tag color={getTagColor(value, [])} key={index}>
215234
{value}
216235
</Tag>
217236
)}
@@ -226,16 +245,17 @@ export const ColumnTagsComp = (function () {
226245
return new ColumnTypeCompBuilder(
227246
childrenMap,
228247
(props, dispatch) => {
248+
const tagOptions = props.tagColors;
229249
let value = props.changeValue ?? getBaseValue(props, dispatch);
230250
value = typeof value === "string" && value.split(",")[1] ? value.split(",") : value;
231251
const tags = _.isArray(value) ? value : [value];
232252
const view = tags.map((tag, index) => {
233253
// The actual eval value is of type number or boolean
234254
const tagText = String(tag);
235255
return (
236-
<Tag color={getTagColor(tagText)} key={index}>
256+
<TagStyled color={getTagColor(tagText, tagOptions)} icon={getTagIcon(tagText, tagOptions)} key={index} >
237257
{tagText}
238-
</Tag>
258+
</TagStyled>
239259
);
240260
});
241261
return view;
@@ -257,6 +277,9 @@ export const ColumnTagsComp = (function () {
257277
label: trans("table.columnValue"),
258278
tooltip: ColumnValueTooltip,
259279
})}
280+
{children.tagColors.propertyView({
281+
title: "test",
282+
})}
260283
</>
261284
))
262285
.build();

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import { StringOrNumberControl } from "comps/controls/codeControl";
33
import { trans } from "i18n";
44
import { ColumnTypeCompBuilder, ColumnTypeViewFn } from "../columnTypeCompBuilder";
55
import { ColumnValueTooltip } from "../simpleColumnTypeComps";
6+
import { IconControl } from "comps/controls/iconControl";
7+
import { hasIcon } from "comps/utils";
68

79
const childrenMap = {
810
text: StringOrNumberControl,
11+
prefixIcon: IconControl,
12+
suffixIcon: IconControl,
913
};
1014

1115
const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string | number, string | number> = (
@@ -17,7 +21,13 @@ export const SimpleTextComp = (function () {
1721
childrenMap,
1822
(props, dispatch) => {
1923
const value = props.changeValue ?? getBaseValue(props, dispatch);
20-
return value;
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+
)} </>;
2131
},
2232
(nodeValue) => nodeValue.text.value,
2333
getBaseValue
@@ -42,6 +52,12 @@ export const SimpleTextComp = (function () {
4252
label: trans("table.columnValue"),
4353
tooltip: ColumnValueTooltip,
4454
})}
55+
{children.prefixIcon.propertyView({
56+
label: trans("button.prefixIcon"),
57+
})}
58+
{children.suffixIcon.propertyView({
59+
label: trans("button.suffixIcon"),
60+
})}
4561
</>
4662
);
4763
})

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

+27
Original file line numberDiff line numberDiff line change
@@ -671,4 +671,31 @@ export const StepOptionControl = optionsControl(StepOption, {
671671
{ value: "4", label: "Step 4", subTitle: "Completion", description: "Process completed successfully.", status: "wait", disabled: "true" },
672672
],
673673
uniqField: "label",
674+
});
675+
676+
677+
let ColoredTagOption = new MultiCompBuilder(
678+
{
679+
label: StringControl,
680+
icon: IconControl,
681+
color: withDefault(ColorControl, ""),
682+
},
683+
(props) => props
684+
).build();
685+
686+
ColoredTagOption = class extends ColoredTagOption implements OptionCompProperty {
687+
propertyView(param: { autoMap?: boolean }) {
688+
return (
689+
<>
690+
{this.children.label.propertyView({ label: trans("coloredTagOptionControl.tag") })}
691+
{this.children.icon.propertyView({ label: trans("coloredTagOptionControl.icon") })}
692+
{this.children.color.propertyView({ label: trans("coloredTagOptionControl.color") })}
693+
</>
694+
);
695+
}
696+
};
697+
698+
export const ColoredTagOptionControl = optionsControl(ColoredTagOption, {
699+
initOptions: [{ label: "Tag1", icon: "/icon:solid/tag", color: "#f50" }, { label: "Tag2", icon: "/icon:solid/tag", color: "#2db7f5" }],
700+
uniqField: "label",
674701
});

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

+3
Original file line numberDiff line numberDiff line change
@@ -1951,6 +1951,9 @@ export const en = {
19511951
"toUpdateRowsDesc": "An Array of Objects for Rows to Be Updated in Editable Tables.",
19521952
"empty": "Empty",
19531953
"falseValues": "Text When False",
1954+
"iconTrue": "Icon When True",
1955+
"iconFalse": "Icon When False",
1956+
"iconNull": "Icon When Null",
19541957
"allColumn": "All",
19551958
"visibleColumn": "Visible",
19561959
"emptyColumns": "No Columns Are Currently Visible"

0 commit comments

Comments
 (0)