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

feat: tag search by clicking on tag #81

Merged
merged 8 commits into from
May 9, 2022
29 changes: 26 additions & 3 deletions src/hooks/use-get-tags-accordions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
import React, { ReactElement, useMemo } from 'react';
import { useTags, ZIMBRA_STANDARD_COLORS } from '@zextras/carbonio-shell-ui';
import React, { ReactElement, useCallback, useMemo } from 'react';
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { useTags, ZIMBRA_STANDARD_COLORS, runSearch } from '@zextras/carbonio-shell-ui';
import {
AccordionItem,
Dropdown,
Expand Down Expand Up @@ -36,14 +38,35 @@ const CustomComp = (props: ItemProps): ReactElement => {
const [t] = useTranslation();
const actions = useGetTagsActions({ tag: props?.item, t });

const triggerSearch = useCallback(
() =>
runSearch(
[
{
avatarBackground: ZIMBRA_STANDARD_COLORS[props?.item?.color || 0].hex,
avatarIcon: 'Tag',
background: 'gray2',
hasAvatar: true,
isGeneric: false,
isQueryFilter: true,
label: `tag:${props?.item?.name}`,
value: `tag:"${props?.item?.name}"`
}
],
'mails'
),
[props?.item?.color, props?.item?.name]
);

return (
<Dropdown contextMenu items={actions} display="block" width="fit">
<Dropdown contextMenu items={actions} display="block" width="fit" onClick={triggerSearch}>
<Row mainAlignment="flex-start" height="fit" padding={{ left: 'large' }} takeAvailableSpace>
<Icon
size="large"
icon="Tag"
customColor={ZIMBRA_STANDARD_COLORS[props?.item?.color].hex}
/>

<Padding right="large" />
<Tooltip label={props?.item?.name} placement="right" maxWidth="100%">
<AccordionItem {...props} height={40} />
Expand Down
44 changes: 31 additions & 13 deletions src/ui-actions/mail-message-preview-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,17 @@ import React, {
useCallback,
useContext
} from 'react';
import { Row, IconButton, Tooltip, Dropdown, ThemeContext } from '@zextras/carbonio-design-system';
import {
Row,
IconButton,
Tooltip,
Dropdown,
ThemeContext,
Padding
} from '@zextras/carbonio-design-system';
import { difference, map, slice } from 'lodash';
import { useParams } from 'react-router-dom';

import { useVisibleActionsCount } from '../hooks/use-visible-actions-count';

type MailMsgPreviewActionsType = {
Expand Down Expand Up @@ -108,18 +116,28 @@ const MailMsgPreviewActions: FC<MailMsgPreviewActionsType> = ({
}}
>
{firstActions?.length > 0 &&
map(firstActions, (action) => (
<Tooltip key={`${action.icon}`} label={action.label}>
<IconButton
size="small"
icon={action.icon}
onClick={(ev: React.MouseEvent<HTMLButtonElement>): void => {
if (ev) ev.preventDefault();
action.click();
}}
/>
</Tooltip>
))}
map(firstActions, (action) =>
action.items ? (
<Padding right="small">
<Tooltip label={action.label}>
<Dropdown items={action.items}>
<IconButton icon={action.icon} size="small" />
</Dropdown>
</Tooltip>
</Padding>
) : (
<Tooltip key={`${action.icon}`} label={action.label}>
<IconButton
size="small"
icon={action.icon}
onClick={(ev: React.MouseEvent<HTMLButtonElement>): void => {
if (ev) ev.preventDefault();
action.click();
}}
/>
</Tooltip>
)
)}
{secondActions?.length > 0 && (
<Dropdown items={secondActions} forceOpen={open} onClose={onDropdownClose}>
<IconButton size="small" icon="MoreVertical" onClick={onIconClick} />
Expand Down
10 changes: 9 additions & 1 deletion src/ui-actions/tag-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,13 @@ export const applyTag = ({
conversation: any;
tags: TagsFromStoreType;
isMessage?: boolean;
}): { id: string; items: TagType[]; customComponent: ReactElement } => {
}): {
id: string;
items: TagType[];
customComponent: ReactElement;
label?: 'string';
icon?: string;
} => {
const tagItem = reduce(
tags,
(acc, v) => {
Expand All @@ -412,6 +418,8 @@ export const applyTag = ({
return {
id: TagsActionsType.Apply,
items: tagItem,
label: t('label.tag', 'Tag'),
icon: 'TagsMoreOutline',
customComponent: (
<Row takeAvailableSpace mainAlignment="flex-start">
<Padding right="small">
Expand Down
3 changes: 1 addition & 2 deletions src/views/app/detail-panel/edit/edit-view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -663,8 +663,7 @@ export default function EditView({ mailId, folderId, setHeader, toggleAppBoard }
messages,
saveDraftCb,
settings,
t,
throttledSaveToDraft
t
]);

useEffect(() => {
Expand Down
6 changes: 3 additions & 3 deletions src/views/app/detail-panel/preview/attachments-block.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function Attachment({ filename, size, link, message, part, iconColors, att }) {
[att.name, createSnackbar, message.id, t]
);

const isAValidDestination = useMemo((node) => node.permissions?.can_write_file, []);
const isAValidDestination = useMemo((node) => node?.permissions?.can_write_file, []);

const actionTarget = useMemo(
() => ({
Expand Down Expand Up @@ -265,7 +265,7 @@ const copyToFiles = (att, message, nodes) =>
_jsns: 'urn:zimbraMail',
mid: message.id,
part: att.name,
destinationFolderId: nodes[0].id
destinationFolderId: nodes?.[0]?.id
});

export default function AttachmentsBlock({ message }) {
Expand Down Expand Up @@ -343,7 +343,7 @@ export default function AttachmentsBlock({ message }) {
[attachments, createSnackbar, message, t]
);

const isAValidDestination = useMemo((node) => node.permissions?.can_write_file, []);
const isAValidDestination = useMemo((node) => node?.permissions?.can_write_file, []);

const actionTarget = useMemo(
() => ({
Expand Down
29 changes: 28 additions & 1 deletion src/views/app/detail-panel/preview/parts/preview-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ import {
} from '@zextras/carbonio-design-system';
import { capitalize, every, find, includes, isEmpty, map, reduce } from 'lodash';
import { useTranslation } from 'react-i18next';
import { useTags, useUserAccounts, ZIMBRA_STANDARD_COLORS } from '@zextras/carbonio-shell-ui';
import {
useTags,
useUserAccounts,
ZIMBRA_STANDARD_COLORS,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
runSearch
} from '@zextras/carbonio-shell-ui';
import { useParams } from 'react-router-dom';
import OnBehalfOfDisplayer from './on-behalf-of-displayer';
import MailMsgPreviewActions from '../../../../../ui-actions/mail-message-preview-actions';
Expand Down Expand Up @@ -162,6 +169,25 @@ const PreviewHeader: FC<PreviewHeaderProps> = ({ compProps }): ReactElement => {
every(message.tags, (tn) => tn !== ''),
[isTagInStore, message.tags, showMultiTagIcon]
);
const triggerSearch = useCallback(
(tagToSearch) =>
runSearch(
[
{
avatarBackground: tagToSearch?.color,
avatarIcon: 'Tag',
background: 'gray2',
hasAvatar: true,
isGeneric: false,
isQueryFilter: true,
label: `tag:${tagToSearch?.name}`,
value: `tag:"${tagToSearch?.name}"`
}
],
'mails'
),
[]
);

return (
<HoverContainer
Expand Down Expand Up @@ -294,6 +320,7 @@ const PreviewHeader: FC<PreviewHeaderProps> = ({ compProps }): ReactElement => {
background="gray2"
hasAvatar
avatarIcon="Tag"
onClick={(): void => triggerSearch(tag)}
/>
))}
</Text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export default function PreviewPanelActions({ item, folderId, isMessageView, con
{map(primaryActions, (action) => (
<Padding left="extrasmall" key={action.label}>
<IconButton
key={action.id}
size="medium"
icon={action.icon}
onClick={(ev) => {
Expand All @@ -137,6 +138,7 @@ export default function PreviewPanelActions({ item, folderId, isMessageView, con
/>
</Padding>
))}

<Padding left="extrasmall">
<Dropdown
placement="right-end"
Expand Down
42 changes: 21 additions & 21 deletions src/views/search/advance-filter-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,77 +107,77 @@ const AdvancedFilterModal: FC<AdvancedFilterModalProps> = ({
query,
(v) =>
!includes(queryArray, v.label) &&
!/^Subject:*/.test(v.label) &&
!/^Attachment:*/.test(v.label) &&
!/^Is:*/.test(v.label) &&
!/^Smaller:*/.test(v.label) &&
!/^Larger:*/.test(v.label) &&
!/^subject:*/.test(v.label) &&
!/^in:*/.test(v.label) &&
!/^before:*/.test(v.label) &&
!/^after:*/.test(v.label) &&
!/^date:*/.test(v.label) &&
!/^tag:*/.test(v.label) &&
!/^Subject:/.test(v.label) &&
!/^Attachment:/.test(v.label) &&
!/^Is:/.test(v.label) &&
!/^Smaller:/.test(v.label) &&
!/^Larger:/.test(v.label) &&
!/^subject:/.test(v.label) &&
!/^in:/.test(v.label) &&
!/^before:/.test(v.label) &&
!/^after:/.test(v.label) &&
!/^date:/.test(v.label) &&
!/^tag:/.test(v.label) &&
!v.isQueryFilter
),
(q) => ({ ...q, hasAvatar: false })
);

const subjectsFromQuery = map(
filter(query, (v) => /^Subject:*/.test(v.label)),
filter(query, (v) => /^Subject:/.test(v.label)),
(q) => ({ ...q, hasAvatar: false })
);
setSubject(subjectsFromQuery);

const attachmentTypeFromQuery = map(
filter(query, (v) => /^Attachment:*/.test(v.label)),
filter(query, (v) => /^Attachment:/.test(v.label)),
(q) => ({ ...q })
);
setAttachmentType(attachmentTypeFromQuery);

const emailStatusFromQuery = map(
filter(query, (v) => /^Is:*/.test(v.label)),
filter(query, (v) => /^Is:/.test(v.label)),
(q) => ({ ...q })
);
setEmailStatus(emailStatusFromQuery);

const sizeSmallerFromQuery = map(
filter(query, (v) => /^Smaller:*/.test(v.label)),
filter(query, (v) => /^Smaller:/.test(v.label)),
(q) => ({ ...q })
);
setSizeSmaller(sizeSmallerFromQuery);

const sizeLargerFromQuery = map(
filter(query, (v) => /^Larger:*/.test(v.label)),
filter(query, (v) => /^Larger:/.test(v.label)),
(q) => ({ ...q })
);
setSizeLarger(sizeLargerFromQuery);
const sentBeforeFromQuery = map(
filter(query, (v) => /^before:*/.test(v.label)),
filter(query, (v) => /^before:/.test(v.label)),
(q) => ({ ...q, hasAvatar: true, icon: 'CalendarOutline' })
);
setSentBefore(sentBeforeFromQuery);

const sentAfterFromQuery = map(
filter(query, (v) => /^after:*/.test(v.label)),
filter(query, (v) => /^after:/.test(v.label)),
(q) => ({ ...q, hasAvatar: true, icon: 'CalendarOutline' })
);
setSentAfter(sentAfterFromQuery);

const tagFromQuery = map(
filter(query, (v) => /^tag:*/.test(v.label)),
filter(query, (v) => /^tag:/.test(v.label)),
(q) => ({ ...q, hasAvatar: true, icon: 'TagOutline' })
);
setTag(tagFromQuery);

const sentOnFromQuery = map(
filter(query, (v) => /^date:*/.test(v.label)),
filter(query, (v) => /^date:/.test(v.label)),
(q) => ({ ...q, hasAvatar: true, icon: 'CalendarOutline' })
);
setSentOn(sentOnFromQuery);

const folderFromQuery = map(
filter(query, (v) => /^in:*/.test(v.label)),
filter(query, (v) => /^in:/.test(v.label)),
(q) => ({
...q,
hasAvatar: true,
Expand Down
12 changes: 6 additions & 6 deletions src/views/search/search-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ const SearchView: FC<SearchProps> = ({ useDisableSearch, useQuery, ResultsHeader
const modifiedQuery = map(query, (q) => {
if (
(includes(queryArray, q.label) ||
/^subject:*/.test(q.label) ||
/^in:*/.test(q.label) ||
/^before:*/.test(q.label) ||
/^after:*/.test(q.label) ||
/^tag:*/.test(q.label) ||
/^date:*/.test(q.label)) &&
/^subject:/.test(q.label) ||
/^in:/.test(q.label) ||
/^before:/.test(q.label) ||
/^after:/.test(q.label) ||
/^tag:/.test(q.label) ||
/^date:/.test(q.label)) &&
!includes(Object.keys(q), 'isGeneric') &&
!includes(Object.keys(q), 'isQueryFilter')
) {
Expand Down
4 changes: 2 additions & 2 deletions translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,9 @@
"sending_mail_to_self": "It looks like you're about to send an e-mail to yourself",
"snackbar": {
"all_att_added": "Attachments added successfully",
"att_err_adding": "There seems to be a problem when adding attachments, please try again",
"all_att_saved": "Attachments successfully saved in the selected folder",
"att_err": "There seems to be a problem when saving, please try again",
"att_err_adding": "There seems to be a problem when adding attachments, please try again",
"att_saved": "Attachment saved in the selected folder",
"calendar_edits_saved": "Edits saved correctly",
"settings_saved": "Edits saved correctly",
Expand Down Expand Up @@ -409,7 +409,7 @@
"tag_not_updated": "Something went wrong, tag not updated. Please try again.",
"tag_updated": "Tag successfully updated"
},
"something_went_wrong": "SOMETHING WENT WRONG"
"something_went_wrong": "SOMETHING WENT WRONG"
},
"notification": {
"new_message": "New Message",
Expand Down