Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1605] Fix Tags Flow #1619

Merged
merged 8 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ const ConversationMetadata = (props: ConnectedProps<typeof connector>) => {
const [tagName, setTagName] = useState('');

useEffect(() => {
if (tags.length == 0) {
listTags();
}
listTags();
}, []);

const showAddTags = () => {
Expand Down Expand Up @@ -117,9 +115,9 @@ const ConversationMetadata = (props: ConnectedProps<typeof connector>) => {
return (
<Dialog close={() => setShowTagsDialog(false)}>
<form className={styles.addTags} onSubmit={submitForm}>
<div className={styles.addTagHeadline}>Add a tag</div>
<Input
type="text"
label="Add a tag"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setTagName(e.target.value);
}}
Expand All @@ -129,7 +127,7 @@ const ConversationMetadata = (props: ConnectedProps<typeof connector>) => {
placeholder="Please enter a tag name"
autoComplete="off"
autoFocus
fontClass="font-s"
fontClass="font-base"
minLength={1}
maxLength={50}
validation={checkIfExists}
Expand All @@ -149,9 +147,7 @@ const ConversationMetadata = (props: ConnectedProps<typeof connector>) => {
})
) : (
<div>
<div>
<Tag tag={{id: '', color: color, name: tagName}} />
</div>
{tagName.length > 0 && <Tag tag={{id: '', color: color, name: tagName}} />}
<p className={styles.addTagsDescription}>Pick a color</p>
<ColorSelector
handleUpdate={(e: React.ChangeEvent<HTMLInputElement>) => setColor(e.target.value as TagColor)}
Expand Down
13 changes: 6 additions & 7 deletions frontend/ui/src/pages/Tags/EmptyStateTags.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import React, {useState} from 'react';
import React from 'react';
import {Button} from 'components';
import {ReactComponent as EmptyImage} from 'assets/images/empty-state/tags-empty-state.svg';

import SimpleTagForm from './SimpleTagForm';
import styles from './EmptyStateTags.module.scss';

const EmptyStateTags: React.FC = (): JSX.Element => {
const [show, setShow] = useState(false);
interface EmptyStateTagsProps {
removeEmptyState(): void;
}

const EmptyStateTags = (props: EmptyStateTagsProps) => {
return (
<div className={styles.cardRaised}>
<div className={styles.emptyStateTitle}>
<h1>You don&#39;t have tags yet.</h1>
<p>Tags provide a useful way to group related conversations together and to quickly filter and search them.</p>
<EmptyImage />
<Button onClick={() => setShow(true)}>Create a Tag</Button>
{show && <SimpleTagForm onClose={() => setShow(false)} />}
<Button onClick={props.removeEmptyState}>Create a Tag</Button>
</div>
</div>
);
Expand Down
8 changes: 5 additions & 3 deletions frontend/ui/src/pages/Tags/SimpleTagForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const SimpleTagForm = ({errorMessage, createTag, errorTag, onClose, tags}: Simpl
const [name, setName] = useState('');
const [color, setColor] = useState<TagColor>('tag-blue');
const [showError, setShowError] = useState(true);

const handleCreate = () => {
if (name.trim().length) {
createTag({name: name.trim(), color}).then((success: boolean) => {
Expand All @@ -51,10 +52,10 @@ const SimpleTagForm = ({errorMessage, createTag, errorTag, onClose, tags}: Simpl
};

return (
<DialogCustomizable close={onClose} style={tags.length ? {right: 0, top: '32px'} : {top: '200px'}}>
<DialogCustomizable close={onClose} style={tags.length ? {right: 0, top: '32px'} : {top: '50px', right: '0px'}}>
<div className={styles.tagCreate}>
<h4 className={styles.headline}>Add a tag</h4>
<Input
label="Add a tag"
type="text"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setName(e.target.value);
Expand All @@ -67,7 +68,8 @@ const SimpleTagForm = ({errorMessage, createTag, errorTag, onClose, tags}: Simpl
placeholder="Please enter a tag name"
autoComplete="off"
autoFocus={true}
fontClass="font-m"
fontClass="font-base"
minLength={1}
maxLength={50}
/>
<p className={styles.errorMessage}>{(!name.length || showError) && errorMessage}</p>
Expand Down
11 changes: 9 additions & 2 deletions frontend/ui/src/pages/Tags/TableRow.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
border-radius: 50%;
line-height: 44px;
margin-top: 6px;
margin-left: 12px;
}

.editInput {
Expand Down Expand Up @@ -57,8 +58,8 @@
}

.actionSVG {
width: 16px;
height: 16px;
width: 20px;
height: 18px;
path {
fill: var(--color-dark-elements-gray);
}
Expand All @@ -69,7 +70,13 @@
}
}

.actionSVGEdit {
@extend .actionSVG;
height: 24px;
}

.actionButton {
outline: none;
cursor: pointer;
border: none;
background: none;
Expand Down
12 changes: 8 additions & 4 deletions frontend/ui/src/pages/Tags/TableRow.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import React, {useState, useCallback} from 'react';
import _, {connect, ConnectedProps} from 'react-redux';

import styles from './TableRow.module.scss';
import {updateTag} from '../../actions/tags';

import {Button, LinkButton} from 'components';
import {ReactComponent as EditIcon} from 'assets/images/icons/edit.svg';
import {ReactComponent as TrashIcon} from 'assets/images/icons/trash.svg';
import ColorSelector from '../../components/ColorSelector';
import Tag from '../../components/Tag';
import {Tag as TagModel, TagColor} from 'model';
import {Settings} from '../../reducers/data/settings';
import {StateModel} from '../../reducers';

import {ReactComponent as EditIcon} from 'assets/images/icons/edit-pencil.svg';
AitorAlgorta marked this conversation as resolved.
Show resolved Hide resolved
import {ReactComponent as TrashIcon} from 'assets/images/icons/trash.svg';

import styles from './TableRow.module.scss';

import {cyTagsTableRowDisplayDeleteModal} from 'handles';

type TableRowProps = {
Expand Down Expand Up @@ -135,7 +139,7 @@ const TableRowComponent = (props: TableRowProps) => {
<td style={{width: '25%'}}>
<div className={styles.actions}>
<button type="button" className={styles.actionButton} onClick={() => setTagState({...tag, edit: true})}>
<EditIcon className={styles.actionSVG} title="Edit tag" />
<EditIcon className={styles.actionSVGEdit} title="Edit tag" />
</button>
<button
type="button"
Expand Down
17 changes: 5 additions & 12 deletions frontend/ui/src/pages/Tags/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
.organizationSectionHeadline {
@include font-l;
font-weight: bold;
margin-bottom: 48px;
margin-bottom: 24px;
}

.organizationContainer {
Expand Down Expand Up @@ -91,13 +91,10 @@
}

.addButton {
@include font-base;
display: flex;
flex-direction: row;
margin-left: 8px;
margin-top: 6px;
padding-top: 4px;
padding-bottom: 6px;
position: relative;
height: 38px;
align-items: center;
color: var(--color-airy-blue);
cursor: pointer;
background: white;
Expand All @@ -112,11 +109,7 @@
}

.plusButton {
display: inherit;
margin-left: 4px;
width: 12px;
position: relative;
top: 1px;
}
}

Expand Down Expand Up @@ -149,7 +142,7 @@
@include font-m;
font-weight: 700;
text-align: left;
padding-bottom: 41px;
padding-bottom: 0px;
padding-left: 2px;
}

Expand Down
24 changes: 22 additions & 2 deletions frontend/ui/src/pages/Tags/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ import _, {connect, ConnectedProps} from 'react-redux';

import {SettingsModal, LinkButton, Button, SearchField, Input} from 'components';
import {cyTagsSearchField, cyTagsTable} from 'handles';

import {ReactComponent as Plus} from 'assets/images/icons/plus.svg';

import {listTags, deleteTag, filterTags, errorTag} from '../../actions/tags';
import {filteredTags} from '../../selectors/tags';

import {Tag} from 'model';
import {ModalType} from '../../types';

import styles from './index.module.scss';
import {TableRow} from './TableRow';
import SimpleTagForm from './SimpleTagForm';
import EmptyStateTags from './EmptyStateTags';
import {StateModel} from '../../reducers';
import {setPageTitle} from '../../services/pageTitle';

import styles from './index.module.scss';

import {cyTagsTableRowDisplayDeleteModalInput, cyTagsTableRowDisplayDeleteModalButton} from 'handles';

const initialState = {
Expand All @@ -28,6 +32,7 @@ const initialState = {
},
tagQuery: '',
createDrawer: false,
emptyState: true,
};

class Tags extends Component<ConnectedProps<typeof connector>, typeof initialState> {
Expand Down Expand Up @@ -65,6 +70,13 @@ class Tags extends Component<ConnectedProps<typeof connector>, typeof initialSta
this.props.errorTag('');
};

removeEmptyStateAndCreateTag = () => {
this.setState({
emptyState: false,
});
this.handleTagDrawer();
};

keyPressed = (e: React.KeyboardEvent<HTMLInputElement>) => {
const code = e.keyCode || e.which;
if (code === 13) {
Expand Down Expand Up @@ -210,7 +222,15 @@ class Tags extends Component<ConnectedProps<typeof connector>, typeof initialSta

render() {
const {allTagsCount} = this.props;
return <div className={styles.tagsWrapper}>{allTagsCount == 0 ? <EmptyStateTags /> : this.renderTagList()}</div>;
return (
<div className={styles.tagsWrapper}>
{allTagsCount == 0 && this.state.emptyState ? (
<EmptyStateTags removeEmptyState={this.removeEmptyStateAndCreateTag} />
) : (
this.renderTagList()
)}
</div>
);
}
}

Expand Down
3 changes: 3 additions & 0 deletions lib/typescript/assets/images/icons/edit-pencil.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion lib/typescript/assets/images/icons/edit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion lib/typescript/assets/images/icons/trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions lib/typescript/httpclient/src/endpoints/createTag.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
import {Tag} from 'model';

const tagMapper = {
BLUE: 'tag-blue',
RED: 'tag-red',
GREEN: 'tag-green',
PURPLE: 'tag-purple',
};

export const createTagDef = {
endpoint: 'tags.create',
mapResponse: (response: Tag) => ({
id: response.id,
name: response.name,
color: tagMapper[response.color] || 'tag-blue',
}),
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const listConversationsDef = {
},
mapResponse: response => {
const conversationData = (response as PaginatedPayload<any>).data.map(messagePayload => ({
...camelcaseKeys(messagePayload, {deep: true, stopPaths: ['metadata.user_data']}),
...camelcaseKeys(messagePayload, {deep: true, stopPaths: ['metadata.user_data', 'metadata.tags']}),
AitorAlgorta marked this conversation as resolved.
Show resolved Hide resolved
createdAt: new Date(messagePayload.created_at),
lastMessage: mapMessage(messagePayload.last_message),
}));
Expand Down
5 changes: 4 additions & 1 deletion lib/typescript/httpclient/src/endpoints/listTags.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {Tag} from 'model';

const tagMapper = {
BLUE: 'tag-blue',
RED: 'tag-red',
Expand All @@ -7,5 +9,6 @@ const tagMapper = {

export const listTagsDef = {
endpoint: 'tags.list',
mapResponse: response => response.data.map(t => ({id: t.id, name: t.name, color: tagMapper[t.color] || 'tag-blue'})),
mapResponse: response =>
response.data.map((t: Tag) => ({id: t.id, name: t.name, color: tagMapper[t.color] || 'tag-blue'})),
};