Skip to content

Commit

Permalink
feat/custom contact name field (#513)
Browse files Browse the repository at this point in the history
  • Loading branch information
EduardZaydler authored May 23, 2024
1 parent 0589cf0 commit bd5de0f
Show file tree
Hide file tree
Showing 21 changed files with 134 additions and 83 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified playwright/snapshots/ContactEditForm/contacteditform--filled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 2 additions & 10 deletions src/Components/ContactEditForm/ContactEditForm.less
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
@import '~styles/variables.less';
@import '~styles/mixins.less';

.row {
margin-bottom: 10px;

&:last-child {
margin-bottom: 0;
}
}
@import "~styles/variables.less";
@import "~styles/mixins.less";

.comment {
min-height: 40px;
Expand Down
95 changes: 51 additions & 44 deletions src/Components/ContactEditForm/ContactEditForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import { ContactConfig } from "../../Domain/Config";
import { Contact } from "../../Domain/Contact";
import ContactTypeIcon from "../ContactTypeIcon/ContactTypeIcon";
import { Markdown } from "../Markdown/Markdown";
import { Gapped } from "@skbkontur/react-ui";
import { Fill, Fixed, RowStack } from "@skbkontur/react-stack-layout";
import classNames from "classnames/bind";

import styles from "./ContactEditForm.less";
import { isEmptyString } from "../../helpers/isEmptyString";

const cn = classNames.bind(styles);

Expand All @@ -21,61 +24,65 @@ type Props = {
export default class ContactEditForm extends React.Component<Props> {
render(): React.ReactElement {
const { onChange, contactInfo, contactDescriptions } = this.props;
const { value = "", type } = contactInfo || {};
const { value = "", type, name } = contactInfo || {};
const currentContactConfig = contactDescriptions.find((contact) => contact.type === type);
const contactItems: Array<[string, string]> = contactDescriptions.map((contact) => [
contact.type,
contact.label,
]);

const renderItem = (v: string, item?: string) => (
<span>
{v && <ContactTypeIcon type={v} />} {item}
</span>
);

return (
<>
<div className={cn("row")}>
<Select<string, string>
placeholder="Select channel type"
<Gapped vertical gap={10}>
<Select<string, string>
placeholder="Select channel type"
width="100%"
value={type}
renderItem={renderItem}
renderValue={renderItem}
onValueChange={(v) => {
v && onChange({ type: v });
}}
items={contactItems}
data-tid="Select channel type"
/>
<RowStack block baseline>
<Fixed width={100}>Contact value:</Fixed>
<Fill>
<ValidationWrapperV1
renderMessage={tooltip("top left")}
validationInfo={this.validateValue()}
>
<Input
width="100%"
disabled={isEmptyString(type)}
placeholder={
(currentContactConfig && currentContactConfig.placeholder) || ""
}
value={value}
onValueChange={(value) => onChange({ value })}
/>
</ValidationWrapperV1>
</Fill>
</RowStack>
<RowStack block baseline>
<Fixed width={100}>Contact name:</Fixed>
<Input
width="100%"
value={type}
renderItem={(v, item) => (
<span>
{v && <ContactTypeIcon type={v} />} {item}
</span>
)}
renderValue={(v, item) => (
<span>
{v && <ContactTypeIcon type={v} />} {item}
</span>
)}
onValueChange={(v) => {
// ToDo разобраться, почему value может отсутствовать
v && onChange({ type: v });
}}
items={contactItems}
data-tid="Select channel type"
placeholder="Type your custom contact name"
value={name}
onValueChange={(name) => onChange({ name })}
/>
</div>
<div className={cn("row")}>
<ValidationWrapperV1
renderMessage={tooltip("top left")}
validationInfo={this.validateValue()}
>
<Input
width="100%"
disabled={type == null}
placeholder={
(currentContactConfig && currentContactConfig.placeholder) || ""
}
value={value}
onValueChange={(v) => onChange({ value: v })}
/>
</ValidationWrapperV1>
</div>
</RowStack>
{currentContactConfig?.help && (
<Markdown
markdown={currentContactConfig.help}
className={cn("row", "comment")}
/>
<Markdown markdown={currentContactConfig.help} className={cn("comment")} />
)}
</>
</Gapped>
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/Components/ContactInfo/ContactInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from "react";
import { Contact } from "../../Domain/Contact";
import ContactTypeIcon from "../ContactTypeIcon/ContactTypeIcon";
import { isEmptyString } from "../../helpers/isEmptyString";

type Props = {
contact: Contact;
Expand All @@ -12,7 +13,7 @@ export default function ContactInfo({ contact, className }: Props): React.ReactE
<div className={className}>
<ContactTypeIcon type={contact.type} />
&nbsp;
<span>{contact.value}</span>
<span>{isEmptyString(contact.name) ? contact.value : contact.name}</span>
</div>
);
}
22 changes: 22 additions & 0 deletions src/Components/ContactList/Components/ContactWithCustomName.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { FC } from "react";
import Info from "@skbkontur/react-icons/Info";
import { Tooltip } from "@skbkontur/react-ui";

interface IContactWithCustomNameProps {
contactValue: string;
contactName: string | undefined;
}

export const ContactWithCustomName: FC<IContactWithCustomNameProps> = ({
contactValue,
contactName,
}) => {
return (
<>
{contactName}&nbsp;
<Tooltip render={() => `Contact value: ${contactValue}`}>
<Info style={{ verticalAlign: "text-top" }} />
</Tooltip>
</>
);
};
6 changes: 3 additions & 3 deletions src/Components/ContactList/ContactList.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import '~styles/variables.less';
@import '~styles/mixins.less';
@import "~styles/variables.less";
@import "~styles/mixins.less";

.items-cotnainer {
margin: 0 -10px;
Expand Down Expand Up @@ -57,7 +57,7 @@

td.error-icon {
width: 25px;
color: #CE0014;
color: #ce0014;
font-size: 18px;
padding-top: 8px;
}
Expand Down
21 changes: 18 additions & 3 deletions src/Components/ContactList/ContactList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { Button } from "@skbkontur/react-ui/components/Button";
import { Center } from "@skbkontur/react-ui/components/Center";
import { Gapped } from "@skbkontur/react-ui/components/Gapped";
import AddIcon from "@skbkontur/react-icons/Add";
import { ContactWithCustomName } from "./Components/ContactWithCustomName";
import WarningIcon from "@skbkontur/react-icons/Warning";
import { Contact } from "../../Domain/Contact";
import { ContactConfig } from "../../Domain/Config";
import NewContactModal from "../NewContactModal/NewContactModal";
import ContactEditModal from "../ContactEditModal/ContactEditModal";
import ContactTypeIcon from "../ContactTypeIcon/ContactTypeIcon";
import { isEmptyString } from "../../helpers/isEmptyString";
import classNames from "classnames/bind";

import styles from "./ContactList.less";
Expand Down Expand Up @@ -62,6 +64,8 @@ export default class ContactList extends React.Component<Props, State> {
(description) => description.type === contact.type
)
) {
console.log(contact.name);
const { name, value, type } = contact;
return (
<tr
key={contact.id}
Expand All @@ -71,9 +75,18 @@ export default class ContactList extends React.Component<Props, State> {
}
>
<td className={cn("icon")}>
<ContactTypeIcon type={contact.type} />
<ContactTypeIcon type={type} />
</td>
<td>
{isEmptyString(name) ? (
value
) : (
<ContactWithCustomName
contactValue={value}
contactName={name}
/>
)}
</td>
<td>{contact.value}</td>
</tr>
);
}
Expand All @@ -84,7 +97,9 @@ export default class ContactList extends React.Component<Props, State> {
<WarningIcon />
</td>
<td>
{contact.value}
{isEmptyString(contact.name)
? contact.value
: contact.name}
<span className={cn("error-message")}>
Contact type {contact.type} not more
support.{" "}
Expand Down
2 changes: 1 addition & 1 deletion src/Components/ContactSelect/ContactSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default class ContactSelect extends React.Component<Props> {
.slice(0, 10)
.map((x) => ({
value: x.id,
label: x.value,
label: x.name || x.value,
type: x.type,
}));

Expand Down
18 changes: 14 additions & 4 deletions src/Components/NotificationList/NotificationList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export default function NotificationList(props: Props): React.ReactElement {
const { timestamp, trigger, contact, throttled, send_fail: fails } = items[
key
][0];
const { type, value, user } = contact;
const { id, name } = trigger;
const { type, value, name: contactName, user } = contact;
const { id, name: triggerName } = trigger;
return (
<div key={key} className={cn("row")}>
<div className={cn("timestamp")}>
Expand All @@ -95,14 +95,24 @@ export default function NotificationList(props: Props): React.ReactElement {
</div>
<div className={cn("trigger")}>
{id ? (
<RouterLink to={getPageLink("trigger", id)}>{name}</RouterLink>
<RouterLink to={getPageLink("trigger", id)}>
{triggerName}
</RouterLink>
) : (
<span>&mdash;</span>
)}
</div>
<div className={cn("user")}>{user}</div>
<div className={cn("contact")}>
<ContactTypeIcon type={type} /> {value}
<ContactTypeIcon type={type} />
{
<>
&nbsp;
{value}
&nbsp;
{contactName && `(${contactName})`}
</>
}
</div>
<div
className={cn("throttled", { true: throttled, false: !throttled })}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@import '~styles/variables.less';
@import "~styles/variables.less";

.item {
cursor: pointer;
&:hover, &.enabled-cell:hover{
&:hover,
&.enabled-cell:hover {
background-color: #f8f8f8;
}

Expand All @@ -21,15 +22,15 @@
&::after {
content: "";
position: absolute;
top: 0;
right: calc(100% - 80px);
bottom: 0;
top: 0;
right: calc(100% - 80px);
bottom: 0;
background-color: #f8f8f8;
opacity: 0;
opacity: 0;
}

&:hover::after {
opacity: 1;
opacity: 1;
}
}

Expand All @@ -49,6 +50,7 @@
.contacts-content {
width: 100%;
margin-right: -500px;
margin-top: 4px;
display: inline-block;
}

Expand All @@ -65,7 +67,7 @@
}

.contacts-cell {
width: 80%;
width: 80%;
}

.enabled-cell {
Expand All @@ -75,7 +77,7 @@

.disabled-label {
overflow: hidden;
color: #D43517;
color: #d43517;
font-weight: 700;
}

Expand Down Expand Up @@ -112,7 +114,7 @@
max-height: 100%;
}

.contact {
.contact {
margin: 0;
display: block;
}
Expand Down
3 changes: 3 additions & 0 deletions src/Components/TagListItem/TagListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ export const TagListItem: FC<ItemProps> = ({
/>
&nbsp;
{contact.value}
&nbsp;
{contact.name &&
`(${contact.name})`}
</div>
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/Containers/SettingsContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ const SettingsContainer: FC<ISettingsContainerProps> = ({ moiraApi, match, histo
};

const handleAddContact = async (contact: Partial<Contact>): Promise<Contact | undefined> => {
const contactType = contact.type;
const { type: contactType, name: contactName } = contact;

if (settings === undefined || contactType === undefined || login === undefined) {
throw new Error("InvalidProgramState");
Expand All @@ -101,6 +101,7 @@ const SettingsContainer: FC<ISettingsContainerProps> = ({ moiraApi, match, histo
value: normalizeContactValueForApi(contactType, contact.value ?? ""),
type: contactType,
user: team ? undefined : login,
name: contactName,
};

const newContact = team
Expand Down
Loading

0 comments on commit bd5de0f

Please sign in to comment.