From d07a20d8fec142e54150c1c3ca9142f6e7b917cd Mon Sep 17 00:00:00 2001 From: MrKBear Date: Tue, 15 Mar 2022 11:29:46 +0800 Subject: [PATCH] Add object picker component --- .../Component/ObjectPicker/ObjectPicker.scss | 86 ++++++++++ .../Component/ObjectPicker/ObjectPicker.tsx | 147 +++++++++++++++++- source/Localization/EN-US.ts | 2 + source/Localization/ZH-CN.ts | 2 + source/Panel/GroupDetails/GroupDetails.tsx | 6 + 5 files changed, 235 insertions(+), 8 deletions(-) create mode 100644 source/Component/ObjectPicker/ObjectPicker.scss diff --git a/source/Component/ObjectPicker/ObjectPicker.scss b/source/Component/ObjectPicker/ObjectPicker.scss new file mode 100644 index 0000000..757f005 --- /dev/null +++ b/source/Component/ObjectPicker/ObjectPicker.scss @@ -0,0 +1,86 @@ +@import "../Theme/Theme.scss"; + +$line-min-height: 26px; + +div.object-picker-root { + width: 100%; + display: flex; + min-height: $line-min-height; + padding: 5px 0; + + div.input-intro { + width: 50%; + height: 100%; + max-width: 220px; + min-height: $line-min-height; + display: flex; + align-items: center; + padding-right: 5px; + box-sizing: border-box; + } + + div.root-content { + width: 50%; + height: 100%; + max-width: 180px; + min-height: $line-min-height; + border-radius: 3px; + overflow: hidden; + display: flex; + cursor: pointer; + + div.value-view { + width: 100%; + height: 100%; + min-height: $line-min-height; + display: flex; + align-items: center; + white-space: nowrap; + word-break: keep-all; + text-overflow: ellipsis; + overflow: hidden; + + span { + display: block; + } + } + + div.list-button { + width: $line-min-height; + height: $line-min-height; + flex-shrink: 0; + display: flex; + justify-content: center; + align-items: center; + } + } +} + +div.dark.object-picker-root { + + div.root-content { + background-color: $lt-bg-color-lvl3-dark; + color: $lt-font-color-normal-dark; + } + + div.root-content:hover { + background-color: $lt-bg-color-lvl2-dark; + } +} + +div.light.object-picker-root { + + div.root-content { + background-color: $lt-bg-color-lvl3-light; + color: $lt-font-color-normal-light; + } + + div.root-content:hover { + background-color: $lt-bg-color-lvl2-light; + } +} + +div.combo-picker-root { + width: 300px; + height: 340px; +} \ No newline at end of file diff --git a/source/Component/ObjectPicker/ObjectPicker.tsx b/source/Component/ObjectPicker/ObjectPicker.tsx index 63f649f..6423bb0 100644 --- a/source/Component/ObjectPicker/ObjectPicker.tsx +++ b/source/Component/ObjectPicker/ObjectPicker.tsx @@ -1,12 +1,143 @@ -import { Component, ReactNode } from "react"; +import { Component, createRef, ReactNode } from "react"; +import { Label } from "@Model/Label"; +import { Group } from "@Model/Group"; +import { Range } from "@Model/Range"; +import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; +import { FontLevel, Theme } from "@Component/Theme/Theme"; +import { PickerList, IDisplayItem } from "../PickerList/PickerList"; +import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; +import { Icon } from "@fluentui/react"; +import CtrlObject from "@Model/CtrlObject"; +import "./ObjectPicker.scss"; -interface IObjectPickerProps {} +type IObjectType = Label | Group | Range | CtrlObject; -class ObjectPicker extends Component { - - public render(): ReactNode { - return
- } +interface IObjectPickerProps { + keyI18n: AllI18nKeys; + infoI18n?: AllI18nKeys; + type: Array<"L" | "G" | "R">; + value?: IObjectType; + valueChange?: (value: IObjectType) => any; } -export { ObjectPicker } \ No newline at end of file +interface IObjectPickerState { + isPickerVisible: boolean; +} + +@useStatusWithEvent("objectChange", "labelChange") +class ObjectPicker extends Component { + + private getAllOption() { + let option: Array = []; + if (this.props.status) { + + for (let i = 0; i < this.props.type.length; i++) { + + if (this.props.type[i] === "L") { + for (let j = 0; j < this.props.status.model.labelPool.length; j++) { + option.push(this.props.status.model.labelPool[j]); + } + } + + if (this.props.type[i] === "R") { + for (let j = 0; j < this.props.status.model.objectPool.length; j++) { + if (this.props.status.model.objectPool[j] instanceof Range) { + option.push(this.props.status.model.objectPool[j]); + } + } + } + + if (this.props.type[i] === "G") { + for (let j = 0; j < this.props.status.model.objectPool.length; j++) { + if (this.props.status.model.objectPool[j] instanceof Group) { + option.push(this.props.status.model.objectPool[j]); + } + } + } + } + } + return option; + } + + public constructor(props: IObjectPickerProps) { + super(props); + this.state = { + isPickerVisible: false + } + } + + private pickerTarget = createRef(); + + private renderPicker() { + return { + if (this.props.valueChange) { + this.props.valueChange(item); + } + this.setState({ + isPickerVisible: false + }) + })} + dismiss={() => { + this.setState({ + isPickerVisible: false + }) + }} + /> + } + + public render(): ReactNode { + + let name = ""; + let icon = "Label"; + if (this.props.value instanceof CtrlObject) { + name = this.props.value.displayName; + + if (this.props.value instanceof Range) { + icon = "CubeShape" + } + + if (this.props.value instanceof Group) { + icon = "WebAppBuilderFragment" + } + } + if (this.props.value instanceof Label) { + name = this.props.value.name; + icon = "tag"; + } + + return <> + +
+ +
+
{ + this.setState({ + isPickerVisible: true + }) + }} + > +
+ +
+
+ { + name ? + {name} : + + } +
+
+
+ + {this.state.isPickerVisible ? this.renderPicker(): null} + + } +} + +export { ObjectPicker, IDisplayItem }; \ No newline at end of file diff --git a/source/Localization/EN-US.ts b/source/Localization/EN-US.ts index d341593..b722ed6 100644 --- a/source/Localization/EN-US.ts +++ b/source/Localization/EN-US.ts @@ -24,6 +24,7 @@ const EN_US = { "Input.Error.Min": "Enter value must be greater than {num}", "Input.Error.Length": "The length of the input content must be less than {num}", "Input.Error.Length.Less": "The length of the input content must be greater than {num}", + "Input.Error.Select": "Select object ...", "Object.List.New.Group": "Group object {id}", "Object.List.New.Range": "Range object {id}", "Object.List.New.Label": "Label {id}", @@ -65,6 +66,7 @@ const EN_US = { "Common.Attr.Key.Generation.Mod": "Generation model", "Common.Attr.Key.Generation.Mod.Point": "Point model", "Common.Attr.Key.Generation.Mod.Range": "Range model", + "Common.Attr.Key.Generation.Use.Range": "Generation range", "Panel.Info.Range.Details.Attr.Error.Not.Range": "Object is not a Range", "Panel.Info.Range.Details.Attr.Error.Unspecified": "Unspecified range object", "Panel.Info.Group.Details.Attr.Error.Not.Group": "Object is not a Group", diff --git a/source/Localization/ZH-CN.ts b/source/Localization/ZH-CN.ts index 67c770c..991e55c 100644 --- a/source/Localization/ZH-CN.ts +++ b/source/Localization/ZH-CN.ts @@ -24,6 +24,7 @@ const ZH_CN = { "Input.Error.Min": "输入数值须大于 {number}", "Input.Error.Length": "输入内容长度须小于 {number}", "Input.Error.Length.Less": "输入内容长度须大于 {number}", + "Input.Error.Select": "选择对象 ...", "Object.List.New.Group": "组对象 {id}", "Object.List.New.Range": "范围对象 {id}", "Object.List.New.Label": "标签 {id}", @@ -65,6 +66,7 @@ const ZH_CN = { "Common.Attr.Key.Generation.Mod": "生成模式", "Common.Attr.Key.Generation.Mod.Point": "点生成", "Common.Attr.Key.Generation.Mod.Range": "范围生成", + "Common.Attr.Key.Generation.Use.Range": "生成范围", "Panel.Info.Range.Details.Attr.Error.Not.Range": "对象不是一个范围", "Panel.Info.Range.Details.Attr.Error.Unspecified": "未指定范围对象", "Panel.Info.Group.Details.Attr.Error.Not.Group": "对象不是一个群", diff --git a/source/Panel/GroupDetails/GroupDetails.tsx b/source/Panel/GroupDetails/GroupDetails.tsx index 3606c0b..ff2be79 100644 --- a/source/Panel/GroupDetails/GroupDetails.tsx +++ b/source/Panel/GroupDetails/GroupDetails.tsx @@ -9,6 +9,7 @@ import { LabelPicker } from "@Component/LabelPicker/LabelPicker"; import { Group, GenMod } from "@Model/Group"; import { AllI18nKeys } from "@Component/Localization/Localization"; import { ComboInput, IDisplayItem } from "@Component/ComboInput/ComboInput"; +import { ObjectPicker } from "@Component/ObjectPicker/ObjectPicker"; import "./GroupDetails.scss"; interface IGroupDetailsProps {} @@ -137,6 +138,11 @@ class GroupDetails extends Component { } }} /> + + }