2017-10-04 12:00:01 +03:00
|
|
|
/*
|
2021-06-07 17:48:55 +03:00
|
|
|
Copyright 2017-2021 The Matrix.org Foundation C.I.C.
|
2017-10-04 12:00:01 +03:00
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
import React from "react";
|
|
|
|
|
|
|
|
import { _t } from '../../../languageHandler';
|
2019-02-08 19:11:30 +03:00
|
|
|
import Field from "./Field";
|
|
|
|
import AccessibleButton from "./AccessibleButton";
|
2021-06-07 17:48:55 +03:00
|
|
|
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
interface IItemProps {
|
|
|
|
index?: number;
|
|
|
|
value?: string;
|
|
|
|
onRemove?(index: number): void;
|
|
|
|
}
|
2017-10-04 12:28:26 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
interface IItemState {
|
|
|
|
verifyRemove: boolean;
|
|
|
|
}
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
export class EditableItem extends React.Component<IItemProps, IItemState> {
|
|
|
|
public state = {
|
|
|
|
verifyRemove: false,
|
|
|
|
};
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
private onRemove = (e) => {
|
2019-02-08 19:11:30 +03:00
|
|
|
e.stopPropagation();
|
|
|
|
e.preventDefault();
|
2017-10-24 18:19:09 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
this.setState({ verifyRemove: true });
|
2019-02-08 19:11:30 +03:00
|
|
|
};
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
private onDontRemove = (e) => {
|
2019-02-08 19:11:30 +03:00
|
|
|
e.stopPropagation();
|
|
|
|
e.preventDefault();
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
this.setState({ verifyRemove: false });
|
2019-02-08 19:11:30 +03:00
|
|
|
};
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
private onActuallyRemove = (e) => {
|
2019-02-08 19:11:30 +03:00
|
|
|
e.stopPropagation();
|
|
|
|
e.preventDefault();
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2019-02-08 19:11:30 +03:00
|
|
|
if (this.props.onRemove) this.props.onRemove(this.props.index);
|
2021-06-07 17:48:55 +03:00
|
|
|
this.setState({ verifyRemove: false });
|
2019-02-08 19:11:30 +03:00
|
|
|
};
|
|
|
|
|
2019-02-22 03:15:25 +03:00
|
|
|
render() {
|
|
|
|
if (this.state.verifyRemove) {
|
|
|
|
return (
|
|
|
|
<div className="mx_EditableItem">
|
2019-02-08 19:11:30 +03:00
|
|
|
<span className="mx_EditableItem_promptText">
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("Are you sure?") }
|
2019-02-08 19:11:30 +03:00
|
|
|
</span>
|
2021-04-27 18:23:27 +03:00
|
|
|
<AccessibleButton
|
2021-06-07 17:48:55 +03:00
|
|
|
onClick={this.onActuallyRemove}
|
2021-04-27 18:23:27 +03:00
|
|
|
kind="primary_sm"
|
|
|
|
className="mx_EditableItem_confirmBtn"
|
|
|
|
>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("Yes") }
|
2019-02-22 03:15:25 +03:00
|
|
|
</AccessibleButton>
|
2021-04-27 18:23:27 +03:00
|
|
|
<AccessibleButton
|
2021-06-07 17:48:55 +03:00
|
|
|
onClick={this.onDontRemove}
|
2021-04-27 18:23:27 +03:00
|
|
|
kind="danger_sm"
|
|
|
|
className="mx_EditableItem_confirmBtn"
|
|
|
|
>
|
2021-07-20 00:43:11 +03:00
|
|
|
{ _t("No") }
|
2019-02-22 03:15:25 +03:00
|
|
|
</AccessibleButton>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2019-02-08 19:11:30 +03:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="mx_EditableItem">
|
2021-06-07 17:48:55 +03:00
|
|
|
<div onClick={this.onRemove} className="mx_EditableItem_delete" title={_t("Remove")} role="button" />
|
2021-07-20 00:43:11 +03:00
|
|
|
<span className="mx_EditableItem_item">{ this.props.value }</span>
|
2019-02-08 19:11:30 +03:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
interface IProps {
|
|
|
|
id: string;
|
|
|
|
items: string[];
|
|
|
|
itemsLabel?: string;
|
|
|
|
noItemsLabel?: string;
|
|
|
|
placeholder?: string;
|
|
|
|
newItem?: string;
|
|
|
|
canEdit?: boolean;
|
|
|
|
canRemove?: boolean;
|
|
|
|
suggestionsListId?: string;
|
|
|
|
onItemAdded?(item: string): void;
|
|
|
|
onItemRemoved?(index: number): void;
|
|
|
|
onNewItemChanged?(item: string): void;
|
|
|
|
}
|
2019-02-08 19:11:30 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
@replaceableComponent("views.elements.EditableItemList")
|
|
|
|
export default class EditableItemList<P = {}> extends React.PureComponent<IProps & P> {
|
|
|
|
protected onItemAdded = (e) => {
|
2019-02-08 19:11:30 +03:00
|
|
|
e.stopPropagation();
|
|
|
|
e.preventDefault();
|
|
|
|
|
2019-02-21 02:13:35 +03:00
|
|
|
if (this.props.onItemAdded) this.props.onItemAdded(this.props.newItem);
|
2019-02-08 19:11:30 +03:00
|
|
|
};
|
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
protected onItemRemoved = (index) => {
|
2019-02-08 19:11:30 +03:00
|
|
|
if (this.props.onItemRemoved) this.props.onItemRemoved(index);
|
|
|
|
};
|
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
protected onNewItemChanged = (e) => {
|
2019-02-21 02:13:35 +03:00
|
|
|
if (this.props.onNewItemChanged) this.props.onNewItemChanged(e.target.value);
|
|
|
|
};
|
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
protected renderNewItemField() {
|
2019-02-08 19:11:30 +03:00
|
|
|
return (
|
2021-04-29 20:57:02 +03:00
|
|
|
<form
|
2021-06-07 17:48:55 +03:00
|
|
|
onSubmit={this.onItemAdded}
|
2021-04-29 20:57:02 +03:00
|
|
|
autoComplete="off"
|
|
|
|
noValidate={true}
|
|
|
|
className="mx_EditableItemList_newItem"
|
|
|
|
>
|
2021-06-07 17:48:55 +03:00
|
|
|
<Field
|
|
|
|
label={this.props.placeholder}
|
|
|
|
type="text"
|
|
|
|
autoComplete="off"
|
|
|
|
value={this.props.newItem || ""}
|
|
|
|
onChange={this.onNewItemChanged}
|
|
|
|
list={this.props.suggestionsListId}
|
|
|
|
/>
|
|
|
|
<AccessibleButton
|
|
|
|
onClick={this.onItemAdded}
|
|
|
|
kind="primary"
|
|
|
|
type="submit"
|
|
|
|
disabled={!this.props.newItem}
|
|
|
|
>
|
|
|
|
{ _t("Add") }
|
2020-12-29 18:08:54 +03:00
|
|
|
</AccessibleButton>
|
2019-02-08 19:11:30 +03:00
|
|
|
</form>
|
2019-02-22 03:53:29 +03:00
|
|
|
);
|
2019-02-08 19:11:30 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2017-10-04 12:00:01 +03:00
|
|
|
const editableItems = this.props.items.map((item, index) => {
|
2019-02-22 03:15:25 +03:00
|
|
|
if (!this.props.canRemove) {
|
2021-07-20 00:43:11 +03:00
|
|
|
return <li key={item}>{ item }</li>;
|
2019-02-22 03:15:25 +03:00
|
|
|
}
|
|
|
|
|
2017-10-04 12:00:01 +03:00
|
|
|
return <EditableItem
|
2019-06-30 12:41:39 +03:00
|
|
|
key={item}
|
2017-10-04 12:00:01 +03:00
|
|
|
index={index}
|
2019-02-08 19:11:30 +03:00
|
|
|
value={item}
|
2021-06-07 17:48:55 +03:00
|
|
|
onRemove={this.onItemRemoved}
|
2017-10-04 12:00:01 +03:00
|
|
|
/>;
|
|
|
|
});
|
|
|
|
|
2021-07-20 00:43:11 +03:00
|
|
|
const editableItemsSection = this.props.canRemove ? editableItems : <ul>{ editableItems }</ul>;
|
2019-02-08 19:11:30 +03:00
|
|
|
const label = this.props.items.length > 0 ? this.props.itemsLabel : this.props.noItemsLabel;
|
2017-10-04 12:00:01 +03:00
|
|
|
|
2021-06-07 17:48:55 +03:00
|
|
|
return (
|
|
|
|
<div className="mx_EditableItemList">
|
|
|
|
<div className="mx_EditableItemList_label">
|
|
|
|
{ label }
|
|
|
|
</div>
|
|
|
|
{ editableItemsSection }
|
|
|
|
{ this.props.canEdit ? this.renderNewItemField() : <div /> }
|
2017-10-04 12:00:01 +03:00
|
|
|
</div>
|
2021-06-07 17:48:55 +03:00
|
|
|
);
|
2019-02-08 19:11:30 +03:00
|
|
|
}
|
|
|
|
}
|