Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit90b1ac0

Browse files
committed
[Feat]: add new pending tags in suggestions for Table Tags Column
1 parent79acea5 commit90b1ac0

File tree

3 files changed

+91
-44
lines changed

3 files changed

+91
-44
lines changed

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

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ const TagsControl = codeControl<Array<string> | string>(
5757
{expectedType:"string | Array<string>",codeType:"JSON"}
5858
);
5959

60-
functiongetTagColor(tagText :any,tagOptions:any[]){
61-
constfoundOption=tagOptions.find((option:{label:any;})=>option.label===tagText);
60+
functiongetTagColor(tagText:string,tagOptions:TagOption[]):string|undefined{
61+
constfoundOption=tagOptions.find(option=>option.label===tagText);
6262
if(foundOption){
6363
if(foundOption.colorType==="preset"){
6464
returnfoundOption.presetColor;
@@ -73,10 +73,10 @@ function getTagColor(tagText : any, tagOptions: any[]) {
7373
returncolors[index];
7474
}
7575

76-
functiongetTagStyle(tagText:any,tagOptions:any[]){
77-
constfoundOption=tagOptions.find((option:{label:any;})=>option.label===tagText);
76+
functiongetTagStyle(tagText:string,tagOptions:TagOption[]):React.CSSProperties{
77+
constfoundOption=tagOptions.find(option=>option.label===tagText);
7878
if(foundOption){
79-
conststyle:any={};
79+
conststyle:React.CSSProperties={};
8080

8181
// Handle color styling
8282
if(foundOption.colorType==="custom"){
@@ -113,11 +113,23 @@ function getTagStyle(tagText: any, tagOptions: any[]) {
113113
return{};
114114
}
115115

116-
functiongetTagIcon(tagText:any,tagOptions:any[]){
116+
functiongetTagIcon(tagText:string,tagOptions:TagOption[]):React.ReactNode|undefined{
117117
constfoundOption=tagOptions.find(option=>option.label===tagText);
118118
returnfoundOption ?foundOption.icon :undefined;
119119
}
120120

121+
// Utility function to process comma-separated tags into individual tags
122+
functionprocessTagItems(tagItems:string[]):string[]{
123+
constresult:string[]=[];
124+
tagItems.forEach((item)=>{
125+
if(item.split(",")[1]){
126+
item.split(",").forEach((tag)=>result.push(tag));
127+
}
128+
result.push(item);
129+
});
130+
returnresult;
131+
}
132+
121133
constchildrenMap={
122134
text:TagsControl,
123135
tagColors:ColoredTagOptionControl,
@@ -128,11 +140,25 @@ const getBaseValue: ColumnTypeViewFn<typeof childrenMap, string | string[], stri
128140
props
129141
)=>props.text;
130142

143+
interfaceTagOption{
144+
label:string;
145+
colorType?:"preset"|"custom";
146+
presetColor?:string;
147+
color?:string;
148+
textColor?:string;
149+
border?:string;
150+
radius?:string;
151+
margin?:string;
152+
padding?:string;
153+
icon?:React.ReactNode;
154+
onEvent?:(eventType:string)=>void;
155+
}
156+
131157
typeTagEditPropsType={
132158
value:string|string[];
133159
onChange:(value:string|string[])=>void;
134160
onChangeEnd:()=>void;
135-
tagOptions:any[];
161+
tagOptions:TagOption[];
136162
};
137163

138164
exportconstWrapper=styled.div`
@@ -240,16 +266,7 @@ export const TagStyled = styled(Tag)`
240266

241267
constTagEdit=React.memo((props:TagEditPropsType)=>{
242268
constdefaultTags=useContext(TagsContext);
243-
const[tags,setTags]=useState(()=>{
244-
constresult:string[]=[];
245-
defaultTags.forEach((item)=>{
246-
if(item.split(",")[1]){
247-
item.split(",").forEach((tag)=>result.push(tag));
248-
}
249-
result.push(item);
250-
});
251-
returnresult;
252-
});
269+
const[tags,setTags]=useState(()=>processTagItems(defaultTags));
253270
const[open,setOpen]=useState(false);
254271
constmountedRef=useRef(true);
255272

@@ -268,24 +285,16 @@ const TagEdit = React.memo((props: TagEditPropsType) => {
268285
// Update tags when defaultTags changes
269286
useEffect(()=>{
270287
if(!mountedRef.current)return;
271-
272-
constresult:string[]=[];
273-
defaultTags.forEach((item)=>{
274-
if(item.split(",")[1]){
275-
item.split(",").forEach((tag)=>result.push(tag));
276-
}
277-
result.push(item);
278-
});
279-
setTags(result);
288+
setTags(processTagItems(defaultTags));
280289
},[defaultTags]);
281290

282291
consthandleSearch=useCallback((value:string)=>{
283292
if(!mountedRef.current)return;
284293

285294
if(defaultTags.findIndex((item)=>item.includes(value))<0){
286-
setTags([...defaultTags,value]);
295+
setTags([...processTagItems(defaultTags),value]);
287296
}else{
288-
setTags(defaultTags);
297+
setTags(processTagItems(defaultTags));
289298
}
290299
props.onChange(value);
291300
},[defaultTags,props.onChange]);
@@ -426,17 +435,15 @@ export const ColumnTagsComp = (function () {
426435
consttagStyle=getTagStyle(tagText,tagOptions);
427436

428437
return(
429-
<React.Fragmentkey={`${tag.split(' ').join('_')}-${index}`}>
430-
<TagStyled
431-
color={tagColor}
432-
icon={tagIcon}
433-
key={index}
434-
style={tagStyle}
435-
onClick={(e)=>handleTagClick(e,tagText)}
436-
>
437-
{tagText}
438-
</TagStyled>
439-
</React.Fragment>
438+
<TagStyled
439+
key={`${tagText.split(' ').join('_')}-${index}`}
440+
color={tagColor}
441+
icon={tagIcon}
442+
style={tagStyle}
443+
onClick={(e)=>handleTagClick(e,tagText)}
444+
>
445+
{tagText}
446+
</TagStyled>
440447
);
441448
});
442449
return(

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,6 @@ export class TableImplComp extends TableInitComp implements IContainer {
481481
return{ ...oriRow, ...changeValues};
482482
})
483483
.value();
484-
// console.info("toUpdateRowsNode. input: ", input, " res: ", res);
485484
returnres;
486485
});
487486
}
@@ -517,14 +516,25 @@ export class TableImplComp extends TableInitComp implements IContainer {
517516
oriDisplayData:this.oriDisplayDataNode(),
518517
withParams:this.children.columns.withParamsNode(),
519518
dataIndexes:this.children.columns.getColumnsNode("dataIndex"),
519+
changeSet:this.changeSetNode(),
520520
};
521521
constresNode=withFunction(fromRecord(nodes),(input)=>{
522522
constdataIndexWithParamsDict=_(input.dataIndexes)
523523
.mapValues((dataIndex,idx)=>input.withParams[idx])
524524
.mapKeys((withParams,idx)=>input.dataIndexes[idx])
525525
.value();
526-
constres=getColumnsAggr(input.oriDisplayData,dataIndexWithParamsDict);
527-
// console.info("columnAggrNode: ", res);
526+
527+
constcolumnChangeSets:Record<string,Record<string,any>>={};
528+
_.forEach(input.changeSet,(rowData,rowId)=>{
529+
_.forEach(rowData,(value,dataIndex)=>{
530+
if(!columnChangeSets[dataIndex]){
531+
columnChangeSets[dataIndex]={};
532+
}
533+
columnChangeSets[dataIndex][rowId]=value;
534+
});
535+
});
536+
537+
constres=getColumnsAggr(input.oriDisplayData,dataIndexWithParamsDict,columnChangeSets);
528538
returnres;
529539
});
530540
returnlastValueIfEqual(this,"columnAggrNode",[resNode,nodes]asconst,(a,b)=>

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,17 +230,47 @@ export function getColumnsAggr(
230230
oriDisplayData:JSONObject[],
231231
dataIndexWithParamsDict:NodeToValue<
232232
ReturnType<InstanceType<typeofColumnListComp>["withParamsNode"]>
233-
>
233+
>,
234+
columnChangeSets?:Record<string,Record<string,any>>
234235
):ColumnsAggrData{
235236
return_.mapValues(dataIndexWithParamsDict,(withParams,dataIndex)=>{
236237
constcompType=(withParams.wrap()asany).compType;
237238
constres:Record<string,JSONValue>&{compType:string}={ compType};
239+
238240
if(compType==="tag"){
239-
res.uniqueTags=_(oriDisplayData)
241+
constoriginalTags=_(oriDisplayData)
240242
.map((row)=>row[dataIndex]!)
241243
.filter((tag)=>!!tag)
244+
.value();
245+
246+
constpendingChanges=columnChangeSets?.[dataIndex]||{};
247+
constpendingTags=_(pendingChanges)
248+
.values()
249+
.filter((value)=>!!value)
250+
.value();
251+
252+
constextractTags=(value:any):string[]=>{
253+
if(!value)return[];
254+
if(_.isArray(value))returnvalue.map(String);
255+
if(typeofvalue==="string"){
256+
// Handle comma-separated tags
257+
if(value.includes(",")){
258+
returnvalue.split(",").map(tag=>tag.trim()).filter(tag=>tag);
259+
}
260+
return[value];
261+
}
262+
return[String(value)];
263+
};
264+
265+
constallTags=[
266+
...originalTags.flatMap(extractTags),
267+
...pendingTags.flatMap(extractTags)
268+
];
269+
270+
res.uniqueTags=_(allTags)
242271
.uniq()
243272
.value();
273+
244274
}elseif(compType==="badgeStatus"){
245275
res.uniqueStatus=_(oriDisplayData)
246276
.map((row)=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp