Add group details gen & recode input with text field component #22
| @ -8,6 +8,7 @@ div.combo-input { | |||||||
|         width: 100%; |         width: 100%; | ||||||
|         height: 100%; |         height: 100%; | ||||||
|         min-height: $line-min-height; |         min-height: $line-min-height; | ||||||
|  |         max-width: calc( 100% - 32px ); | ||||||
|         display: flex; |         display: flex; | ||||||
|         align-items: center; |         align-items: center; | ||||||
|         padding-left: 8px; |         padding-left: 8px; | ||||||
| @ -17,7 +18,12 @@ div.combo-input { | |||||||
|         overflow: hidden; |         overflow: hidden; | ||||||
| 
 | 
 | ||||||
|         span { |         span { | ||||||
|  |             word-break: keep-all; | ||||||
|  |             overflow: hidden; | ||||||
|  |             white-space: nowrap; | ||||||
|  |             text-overflow: ellipsis; | ||||||
|             display: block; |             display: block; | ||||||
|  |             max-width: 100%; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,19 +4,32 @@ $line-min-height: 24px; | |||||||
| 
 | 
 | ||||||
| div.object-picker { | div.object-picker { | ||||||
| 
 | 
 | ||||||
|  |     div.list-color { | ||||||
|  |         width: 3px; | ||||||
|  |         height: $line-min-height; | ||||||
|  |         border-radius: 1000px; | ||||||
|  |         flex-shrink: 0; | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     div.value-view { |     div.value-view { | ||||||
|  |         flex-shrink: 1; | ||||||
|         width: 100%; |         width: 100%; | ||||||
|         height: 100%; |         height: 100%; | ||||||
|  |         max-width: calc( 100% - 51px ); | ||||||
|         min-height: $line-min-height; |         min-height: $line-min-height; | ||||||
|         display: flex; |         display: flex; | ||||||
|         align-items: center; |         align-items: center; | ||||||
|         white-space: nowrap; |  | ||||||
|         word-break: keep-all; |  | ||||||
|         text-overflow: ellipsis; |  | ||||||
|         overflow: hidden; |  | ||||||
| 
 | 
 | ||||||
|         span { |         span { | ||||||
|  |             word-break: keep-all; | ||||||
|  |             overflow: hidden; | ||||||
|  |             white-space: nowrap; | ||||||
|  |             text-overflow: ellipsis; | ||||||
|             display: block; |             display: block; | ||||||
|  |             max-width: 100%; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -28,4 +41,17 @@ div.object-picker { | |||||||
|         justify-content: center; |         justify-content: center; | ||||||
|         align-items: center; |         align-items: center; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     div.list-empty { | ||||||
|  |         width: $line-min-height; | ||||||
|  |         height: $line-min-height; | ||||||
|  |         flex-shrink: 0; | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     div.list-empty:hover { | ||||||
|  |         color: $lt-red; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -4,10 +4,10 @@ import { Group } from "@Model/Group"; | |||||||
| import { Range } from "@Model/Range"; | import { Range } from "@Model/Range"; | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; | import { TextField, ITextFieldProps } from "../TextField/TextField"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { PickerList, IDisplayItem } from "../PickerList/PickerList"; | import { PickerList, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "../PickerList/PickerList"; | ||||||
| import { Localization } from "@Component/Localization/Localization"; | import { Localization } from "@Component/Localization/Localization"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import CtrlObject from "@Model/CtrlObject"; | import { CtrlObject } from "@Model/CtrlObject"; | ||||||
| import "./ObjectPicker.scss"; | import "./ObjectPicker.scss"; | ||||||
| 
 | 
 | ||||||
| type IObjectType = Label | Group | Range | CtrlObject; | type IObjectType = Label | Group | Range | CtrlObject; | ||||||
| @ -16,6 +16,7 @@ interface IObjectPickerProps extends ITextFieldProps { | |||||||
|     type: Array<"L" | "G" | "R">; |     type: Array<"L" | "G" | "R">; | ||||||
|     value?: IObjectType; |     value?: IObjectType; | ||||||
|     valueChange?: (value: IObjectType) => any; |     valueChange?: (value: IObjectType) => any; | ||||||
|  |     cleanValue?: () => any; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| interface IObjectPickerState { | interface IObjectPickerState { | ||||||
| @ -57,6 +58,8 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | |||||||
|         return option; |         return option; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private isClean: boolean = false; | ||||||
|  | 
 | ||||||
|     public constructor(props: IObjectPickerProps) { |     public constructor(props: IObjectPickerProps) { | ||||||
|         super(props); |         super(props); | ||||||
|         this.state = { |         this.state = { | ||||||
| @ -68,6 +71,7 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | |||||||
| 
 | 
 | ||||||
|     private renderPicker() { |     private renderPicker() { | ||||||
|         return <PickerList |         return <PickerList | ||||||
|  |             noData="Object.Picker.List.No.Data" | ||||||
|             target={this.pickerTarget} |             target={this.pickerTarget} | ||||||
|             objectList={this.getAllOption()} |             objectList={this.getAllOption()} | ||||||
|             clickObjectItems={((item) => { |             clickObjectItems={((item) => { | ||||||
| @ -88,22 +92,18 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | |||||||
| 
 | 
 | ||||||
|     public render(): ReactNode { |     public render(): ReactNode { | ||||||
| 
 | 
 | ||||||
|         let name = ""; |         let disPlayInfo: IDisplayInfo; | ||||||
|         let icon = "Label"; |         let isDelete: boolean = false; | ||||||
|         if (this.props.value instanceof CtrlObject) { |  | ||||||
|             name = this.props.value.displayName; |  | ||||||
| 
 | 
 | ||||||
|             if (this.props.value instanceof Range) { |         if (this.props.value) { | ||||||
|                 icon = "CubeShape" |             disPlayInfo = getObjectDisplayInfo(this.props.value); | ||||||
|  |             isDelete = this.props.value.isDeleted(); | ||||||
|  |         } else { | ||||||
|  |             disPlayInfo = { | ||||||
|  |                 name: "", | ||||||
|  |                 icon: "Label", | ||||||
|  |                 color: "rgba(0,0,0,0)" | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             if (this.props.value instanceof Group) { |  | ||||||
|                 icon = "WebAppBuilderFragment" |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         if (this.props.value instanceof Label) { |  | ||||||
|             name = this.props.value.name; |  | ||||||
|             icon = "tag"; |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         return <> |         return <> | ||||||
| @ -113,21 +113,52 @@ class ObjectPicker extends Component<IObjectPickerProps & IMixinStatusProps, IOb | |||||||
|                 keyI18n={this.props.keyI18n} |                 keyI18n={this.props.keyI18n} | ||||||
|                 targetRef={this.pickerTarget} |                 targetRef={this.pickerTarget} | ||||||
|                 onClick={() => { |                 onClick={() => { | ||||||
|                     this.setState({ |                     if (this.isClean) { | ||||||
|                         isPickerVisible: true |                         this.isClean = false; | ||||||
|                     }) |                     } else { | ||||||
|  |                         this.setState({ | ||||||
|  |                             isPickerVisible: true | ||||||
|  |                         }) | ||||||
|  |                     } | ||||||
|                 }} |                 }} | ||||||
|             > |             > | ||||||
|  |                 <div | ||||||
|  |                     className="list-color" | ||||||
|  |                     style={{ | ||||||
|  |                             backgroundColor: disPlayInfo.color | ||||||
|  |                     }} | ||||||
|  |                 /> | ||||||
|                 <div className="list-button"> |                 <div className="list-button"> | ||||||
|                     <Icon iconName={icon}/> |                     <Icon iconName={disPlayInfo.icon}/> | ||||||
|                 </div> |                 </div> | ||||||
|                 <div className="value-view"> |                 <div | ||||||
|  |                     className="value-view" | ||||||
|  |                     style={{ | ||||||
|  |                         textDecoration: isDelete ? "line-through" : undefined, | ||||||
|  |                         opacity: isDelete ? ".6" : undefined | ||||||
|  |                     }} | ||||||
|  |                 > | ||||||
|                     {    |                     {    | ||||||
|                         name ?  |                         disPlayInfo.name ?  | ||||||
|                             <span>{name}</span> : |                             <span>{disPlayInfo.name}</span> : | ||||||
|                             <Localization i18nKey="Input.Error.Select"/> |                             <Localization i18nKey="Input.Error.Select"/> | ||||||
|                     } |                     } | ||||||
|                 </div> |                 </div> | ||||||
|  |                 <div | ||||||
|  |                     className="list-empty" | ||||||
|  |                     onClick={() => { | ||||||
|  |                         if (this.props.cleanValue && disPlayInfo.name) { | ||||||
|  |                             this.isClean = true; | ||||||
|  |                             this.props.cleanValue(); | ||||||
|  |                         } | ||||||
|  |                     }} | ||||||
|  |                 > | ||||||
|  |                     {    | ||||||
|  |                         disPlayInfo.name ?  | ||||||
|  |                             <Icon iconName="delete"/> : | ||||||
|  |                             null | ||||||
|  |                     } | ||||||
|  |                 </div> | ||||||
|             </TextField> |             </TextField> | ||||||
| 
 | 
 | ||||||
|             {this.state.isPickerVisible ?  this.renderPicker(): null} |             {this.state.isPickerVisible ?  this.renderPicker(): null} | ||||||
|  | |||||||
| @ -1,12 +1,13 @@ | |||||||
| div.picker-list-root { | div.picker-list-root { | ||||||
| 	max-width: 200px; | 	min-width: 200px; | ||||||
| 	height: 100%; | 	height: 100%; | ||||||
| 	padding: 0px; | 	padding: 0px; | ||||||
| 	margin: 0px; | 	margin: 0px; | ||||||
| 	overflow-y: auto; | 	overflow-y: auto; | ||||||
| 
 | 
 | ||||||
| 	div.picker-list-item { | 	div.picker-list-item { | ||||||
| 		width: 200px; | 		min-width: 200px; | ||||||
|  | 		padding-right: 10px; | ||||||
| 		height: 36px; | 		height: 36px; | ||||||
| 		display: flex; | 		display: flex; | ||||||
| 		justify-content: center; | 		justify-content: center; | ||||||
| @ -37,6 +38,7 @@ div.picker-list-root { | |||||||
| 
 | 
 | ||||||
| 		div.list-item-name { | 		div.list-item-name { | ||||||
| 			width: 100%; | 			width: 100%; | ||||||
|  | 			white-space: nowrap; | ||||||
|             box-sizing: border-box; |             box-sizing: border-box; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -7,13 +7,45 @@ import { Range } from "@Model/Range"; | |||||||
| import { Component, ReactNode, RefObject } from "react"; | import { Component, ReactNode, RefObject } from "react"; | ||||||
| import "./PickerList.scss"; | import "./PickerList.scss"; | ||||||
| 
 | 
 | ||||||
| type IPickerListItem = CtrlObject | Label; | type IDisplayInfo = Record<"color" | "icon" | "name", string>; | ||||||
|  | type IPickerListItem = CtrlObject | Label | Range | Group; | ||||||
| type IDisplayItem = { | type IDisplayItem = { | ||||||
|     nameKey: AllI18nKeys; |     nameKey: AllI18nKeys; | ||||||
|     key: string; |     key: string; | ||||||
| 	mark?: boolean; | 	mark?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | function getObjectDisplayInfo(item: IPickerListItem): IDisplayInfo { | ||||||
|  | 
 | ||||||
|  | 	let color: number[] = []; | ||||||
|  | 	let icon: string = "tag"; | ||||||
|  | 	let name: string = ""; | ||||||
|  | 
 | ||||||
|  | 	if (item instanceof Range) { | ||||||
|  | 		icon = "CubeShape" | ||||||
|  | 	} | ||||||
|  | 	if (item instanceof Group) { | ||||||
|  | 		icon = "WebAppBuilderFragment" | ||||||
|  | 	} | ||||||
|  | 	if (item instanceof CtrlObject) { | ||||||
|  | 		color[0] = Math.round(item.color[0] * 255); | ||||||
|  | 		color[1] = Math.round(item.color[1] * 255); | ||||||
|  | 		color[2] = Math.round(item.color[2] * 255); | ||||||
|  | 		name = item.displayName; | ||||||
|  | 	} | ||||||
|  | 	if (item instanceof Label) { | ||||||
|  | 		icon = "tag"; | ||||||
|  | 		color = item.color.concat([]); | ||||||
|  | 		name = item.name; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return { | ||||||
|  | 		color: `rgb(${color[0]},${color[1]},${color[2]})`, | ||||||
|  | 		icon: icon, | ||||||
|  | 		name: name | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| interface IPickerListProps { | interface IPickerListProps { | ||||||
|     displayItems?: IDisplayItem[]; |     displayItems?: IDisplayItem[]; | ||||||
| 	objectList?: IPickerListItem[]; | 	objectList?: IPickerListItem[]; | ||||||
| @ -27,28 +59,7 @@ interface IPickerListProps { | |||||||
| class PickerList extends Component<IPickerListProps> { | class PickerList extends Component<IPickerListProps> { | ||||||
| 
 | 
 | ||||||
| 	private renderItem(item: IPickerListItem) { | 	private renderItem(item: IPickerListItem) { | ||||||
| 
 | 		const displayInfo = getObjectDisplayInfo(item); | ||||||
| 		let color: number[] = []; |  | ||||||
| 		let icon: string = "tag"; |  | ||||||
| 		let name: string = ""; |  | ||||||
| 
 |  | ||||||
| 		if (item instanceof Range) { |  | ||||||
| 			icon = "CubeShape" |  | ||||||
| 		} |  | ||||||
| 		if (item instanceof Group) { |  | ||||||
| 			icon = "WebAppBuilderFragment" |  | ||||||
| 		} |  | ||||||
| 		if (item instanceof CtrlObject) { |  | ||||||
| 			color[0] = Math.round(item.color[0] * 255); |  | ||||||
| 			color[1] = Math.round(item.color[1] * 255); |  | ||||||
| 			color[2] = Math.round(item.color[2] * 255); |  | ||||||
| 			name = item.displayName; |  | ||||||
| 		} |  | ||||||
| 		if (item instanceof Label) { |  | ||||||
| 			icon = "tag"; |  | ||||||
| 			color = item.color.concat([]); |  | ||||||
| 			name = item.name; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		return <div | 		return <div | ||||||
| 			className="picker-list-item" | 			className="picker-list-item" | ||||||
| @ -61,14 +72,14 @@ class PickerList extends Component<IPickerListProps> { | |||||||
| 		> | 		> | ||||||
| 			<div className="list-item-color" | 			<div className="list-item-color" | ||||||
| 				style={{ | 				style={{ | ||||||
| 					backgroundColor: `rgb(${color[0]},${color[1]},${color[2]})` | 					backgroundColor: displayInfo.color | ||||||
| 				}} | 				}} | ||||||
| 			></div> | 			></div> | ||||||
| 			<div className="list-item-icon"> | 			<div className="list-item-icon"> | ||||||
| 				<Icon iconName={icon}/> | 				<Icon iconName={displayInfo.icon}/> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div className="list-item-name"> | 			<div className="list-item-name"> | ||||||
| 				{name} | 				{displayInfo.name} | ||||||
| 			</div> | 			</div> | ||||||
| 		</div>; | 		</div>; | ||||||
| 	} | 	} | ||||||
| @ -124,4 +135,4 @@ class PickerList extends Component<IPickerListProps> { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export { PickerList, IDisplayItem } | export { PickerList, IDisplayItem, IDisplayInfo, getObjectDisplayInfo } | ||||||
| @ -29,6 +29,7 @@ const EN_US = { | |||||||
|     "Object.List.New.Range": "Range object {id}", |     "Object.List.New.Range": "Range object {id}", | ||||||
|     "Object.List.New.Label": "Label {id}", |     "Object.List.New.Label": "Label {id}", | ||||||
|     "Object.List.No.Data": "There are no objects in the model, click the button to create it", |     "Object.List.No.Data": "There are no objects in the model, click the button to create it", | ||||||
|  |     "Object.Picker.List.No.Data": "There is no model in the model for this option", | ||||||
|     "Panel.Title.Notfound": "{id}", |     "Panel.Title.Notfound": "{id}", | ||||||
|     "Panel.Info.Notfound": "This panel with id {id} can not found!", |     "Panel.Info.Notfound": "This panel with id {id} can not found!", | ||||||
|     "Panel.Title.Render.View": "Live preview", |     "Panel.Title.Render.View": "Live preview", | ||||||
|  | |||||||
| @ -29,6 +29,7 @@ const ZH_CN = { | |||||||
|     "Object.List.New.Range": "范围对象 {id}", |     "Object.List.New.Range": "范围对象 {id}", | ||||||
|     "Object.List.New.Label": "标签 {id}", |     "Object.List.New.Label": "标签 {id}", | ||||||
|     "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", |     "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", | ||||||
|  |     "Object.Picker.List.No.Data": "模型中没有合适此选项的模型", | ||||||
|     "Panel.Title.Notfound": "{id}", |     "Panel.Title.Notfound": "{id}", | ||||||
|     "Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!", |     "Panel.Info.Notfound": "这个编号为 {id} 的面板无法找到!", | ||||||
|     "Panel.Title.Render.View": "实时预览", |     "Panel.Title.Render.View": "实时预览", | ||||||
|  | |||||||
| @ -52,6 +52,31 @@ class CtrlObject extends LabelObject { | |||||||
|     public delete() { |     public delete() { | ||||||
|         this.model.deleteObject([this]); |         this.model.deleteObject([this]); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 判断是否为相同对象 | ||||||
|  |      */ | ||||||
|  |     public equal(obj: CtrlObject): boolean { | ||||||
|  |         return this === obj || this.id === obj.id; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 删除标记 | ||||||
|  |      */ | ||||||
|  |     private deleteFlag: boolean = false; | ||||||
|  | 
 | ||||||
|  |      /** | ||||||
|  |       * 是否被删除 | ||||||
|  |       */ | ||||||
|  |     public isDeleted(): boolean { | ||||||
|  |         if (this.deleteFlag) return true; | ||||||
|  |         for (let i = 0; i < this.model.objectPool.length; i++) { | ||||||
|  |             if (this.model.objectPool[i].equal(this)) return false; | ||||||
|  |         } | ||||||
|  |         this.deleteFlag = true; | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export default CtrlObject; | export default CtrlObject; | ||||||
|  | |||||||
| @ -44,13 +44,20 @@ class Label { | |||||||
|         return this === label || this.id === label.id; |         return this === label || this.id === label.id; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 删除标记 | ||||||
|  |      */ | ||||||
|  |     private deleteFlag: boolean = false; | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 是否被删除 |      * 是否被删除 | ||||||
|      */ |      */ | ||||||
|     public isDeleted(): boolean { |     public isDeleted(): boolean { | ||||||
|  |         if (this.deleteFlag) return true; | ||||||
|         for (let i = 0; i < this.model.labelPool.length; i++) { |         for (let i = 0; i < this.model.labelPool.length; i++) { | ||||||
|             if (this.model.labelPool[i].equal(this)) return false; |             if (this.model.labelPool[i].equal(this)) return false; | ||||||
|         } |         } | ||||||
|  |         this.deleteFlag = true; | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -126,13 +126,19 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | |||||||
| 
 | 
 | ||||||
|             {group.genMethod === GenMod.Range ? this.renderRangeGenOption(group) : null} |             {group.genMethod === GenMod.Range ? this.renderRangeGenOption(group) : null} | ||||||
| 
 | 
 | ||||||
|  |             <TogglesInput | ||||||
|  | 				keyI18n="Common.Attr.Key.Generation" | ||||||
|  | 				onIconName="BuildDefinition" offIconName="BuildDefinition" | ||||||
|  | 				valueChange={() => { | ||||||
|  | 					console.log("gen"); | ||||||
|  | 				}} | ||||||
|  | 			/> | ||||||
|  | 
 | ||||||
| 		</> | 		</> | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|     private renderPointGenOption(group: Group) { |     private renderPointGenOption(group: Group) { | ||||||
| 
 |  | ||||||
|         return <> |         return <> | ||||||
| 
 |  | ||||||
|             <AttrInput |             <AttrInput | ||||||
|                 id={group.id} isNumber={true} step={0.1} keyI18n="Common.Attr.Key.Generation.Point.X" |                 id={group.id} isNumber={true} step={0.1} keyI18n="Common.Attr.Key.Generation.Point.X" | ||||||
|                 value={group.genPoint[0] ?? 0} |                 value={group.genPoint[0] ?? 0} | ||||||
| @ -163,12 +169,17 @@ class GroupDetails extends Component<IGroupDetailsProps & IMixinStatusProps> { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private renderRangeGenOption(group: Group) { |     private renderRangeGenOption(group: Group) { | ||||||
| 
 |  | ||||||
|         return <> |         return <> | ||||||
| 
 |  | ||||||
|             <ObjectPicker |             <ObjectPicker | ||||||
|                 keyI18n="Common.Attr.Key.Generation.Use.Range" |                 keyI18n="Common.Attr.Key.Generation.Use.Range" | ||||||
|                 type={["L", "G", "R"]} |                 type={["L", "R"]} | ||||||
|  |                 value={group.genRange} | ||||||
|  |                 valueChange={(value) => { | ||||||
|  |                     this.props.status?.changeGroupAttrib(group.id, "genRange", value); | ||||||
|  |                 }} | ||||||
|  |                 cleanValue={() => { | ||||||
|  |                     this.props.status?.changeGroupAttrib(group.id, "genRange", undefined); | ||||||
|  |                 }} | ||||||
|             /> |             /> | ||||||
|         </> |         </> | ||||||
|     } |     } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user