190 lines
6.3 KiB
TypeScript
190 lines
6.3 KiB
TypeScript
import { Component, ReactNode, createRef } from "react";
|
|
import { Icon } from "@fluentui/react";
|
|
import { Behavior } from "@Model/Behavior";
|
|
import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting";
|
|
import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status";
|
|
import { DetailsList } from "@Component/DetailsList/DetailsList";
|
|
import { Localization } from "@Component/Localization/Localization";
|
|
import { PickerList } from "@Input/PickerList/PickerList";
|
|
import "./BehaviorPicker.scss";
|
|
|
|
interface IBehaviorPickerProps {
|
|
behavior: Behavior[];
|
|
focusBehavior?: Behavior;
|
|
click?: (behavior: Behavior) => void;
|
|
delete?: (behavior: Behavior) => void;
|
|
action?: (behavior: Behavior) => void;
|
|
add?: (behavior: Behavior) => void;
|
|
}
|
|
|
|
interface IBehaviorPickerState {
|
|
isPickerListOpen: boolean;
|
|
}
|
|
|
|
@useStatusWithEvent("behaviorChange")
|
|
@useSettingWithEvent("language")
|
|
class BehaviorPicker extends Component<IBehaviorPickerProps & IMixinSettingProps & IMixinStatusProps> {
|
|
|
|
public state = {
|
|
isPickerListOpen: false
|
|
}
|
|
|
|
private isInnerClick: boolean = false;
|
|
private clickLineRef = createRef<HTMLDivElement>();
|
|
|
|
private getData() {
|
|
let data: Array<{select: boolean, key: string, behavior: Behavior | undefined}> = [];
|
|
for (let i = 0; i < this.props.behavior.length; i++) {
|
|
data.push({
|
|
key: this.props.behavior[i].id,
|
|
behavior: this.props.behavior[i],
|
|
select: this.props.behavior[i].id === this.props.focusBehavior?.id
|
|
})
|
|
}
|
|
data.push({
|
|
key: "@@AddButton_List_Key",
|
|
behavior: undefined,
|
|
select: false
|
|
})
|
|
return data;
|
|
}
|
|
|
|
private renderLine = (behavior?: Behavior): ReactNode => {
|
|
if (behavior) {
|
|
|
|
const titleClassList: string[] = ["behavior-picker-title"];
|
|
if (this.props.setting) {
|
|
titleClassList.push(this.props.setting.language);
|
|
}
|
|
if (behavior.isDeleted()) {
|
|
titleClassList.push("is-deleted");
|
|
}
|
|
|
|
return <>
|
|
<div className="behavior-picker-line-color-view">
|
|
<div style={{ borderLeft: `10px solid rgb(${behavior.color.join(",")})` }}/>
|
|
</div>
|
|
<div
|
|
className="behavior-picker-line-icon-view"
|
|
onClick={() => {
|
|
this.isInnerClick = true;
|
|
this.props.action && this.props.action(behavior);
|
|
}}
|
|
>
|
|
{
|
|
behavior.isDeleted() ?
|
|
<Icon iconName={behavior.iconName}/>:
|
|
<>
|
|
<Icon iconName={behavior.iconName} className="behavior-icon"/>
|
|
<Icon iconName="EditCreate" className="view-icon"/>
|
|
</>
|
|
}
|
|
</div>
|
|
<div className={titleClassList.join(" ")}>
|
|
<div>{behavior.name}</div>
|
|
</div>
|
|
<div
|
|
className="behavior-picker-line-delete-view"
|
|
onClick={() => {
|
|
this.isInnerClick = true;
|
|
this.props.delete && this.props.delete(behavior);
|
|
}}
|
|
>
|
|
<Icon iconName="Delete"/>
|
|
</div>
|
|
</>;
|
|
} else {
|
|
|
|
const openPicker = () => {
|
|
this.isInnerClick = true;
|
|
this.setState({
|
|
isPickerListOpen: true
|
|
});
|
|
}
|
|
|
|
return <>
|
|
<div
|
|
className="behavior-picker-line-icon-view"
|
|
onClick={openPicker}
|
|
>
|
|
<Icon iconName="Add" className="add-icon"/>
|
|
</div>
|
|
<div
|
|
className="behavior-picker-title behavior-add-line"
|
|
onClick={openPicker}
|
|
ref={this.clickLineRef}
|
|
>
|
|
<Localization i18nKey="Behavior.Picker.Add.Button"/>
|
|
</div>
|
|
</>;
|
|
}
|
|
}
|
|
|
|
private getAllData = (): Behavior[] => {
|
|
if (this.props.status) {
|
|
let res: Behavior[] = [];
|
|
for (let i = 0; i < this.props.status.model.behaviorPool.length; i++) {
|
|
|
|
let isAdded = false;
|
|
for (let j = 0; j < this.props.behavior.length; j++) {
|
|
if (this.props.status.model.behaviorPool[i].id === this.props.behavior[j].id) {
|
|
isAdded = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!isAdded) {
|
|
res.push(this.props.status.model.behaviorPool[i]);
|
|
}
|
|
}
|
|
return res;
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
private renderPickerList(): ReactNode {
|
|
return <PickerList
|
|
item={this.getAllData()}
|
|
noData="Behavior.Picker.Add.Nodata"
|
|
target={this.clickLineRef}
|
|
click={((item) => {
|
|
if (item instanceof Behavior && this.props.add) {
|
|
this.props.add(item);
|
|
}
|
|
this.setState({
|
|
isPickerListOpen: false
|
|
})
|
|
})}
|
|
dismiss={() => {
|
|
this.setState({
|
|
isPickerListOpen: false
|
|
});
|
|
}}
|
|
/>
|
|
}
|
|
|
|
public render(): ReactNode {
|
|
return <>
|
|
<DetailsList
|
|
hideCheckBox
|
|
className="behavior-picker-list"
|
|
items={this.getData()}
|
|
clickLine={(item) => {
|
|
if (!this.isInnerClick && this.props.click && item.behavior) {
|
|
this.props.click(item.behavior);
|
|
}
|
|
this.isInnerClick = false;
|
|
}}
|
|
columns={[{
|
|
className: "behavior-picker-line",
|
|
key: "behavior",
|
|
render: this.renderLine
|
|
}]}
|
|
/>
|
|
{this.state.isPickerListOpen ? this.renderPickerList() : null}
|
|
</>
|
|
}
|
|
}
|
|
|
|
export { BehaviorPicker }; |