diff --git a/twake/frontend/src/app/components/search-popup/parts/channels-and-contacts.tsx b/twake/frontend/src/app/components/search-popup/parts/channels-and-contacts.tsx new file mode 100644 index 0000000000..bb9a173b83 --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/parts/channels-and-contacts.tsx @@ -0,0 +1,45 @@ +import Search from 'features/global/services/search-service'; +import ChannelsResult from 'components/search-popup/parts/channels-result'; +import UsersResult from 'components/search-popup/parts/users-result'; +import React from 'react'; +import { ChannelType } from 'app/features/channels/types/channel'; +import { UserType } from 'features/users/types/user'; + +type PropsType = { + channels: ChannelType[]; + users: UserType[]; +}; + +export default ({ channels, users }: PropsType): JSX.Element => { + return ( +
+
Channels and contacts
+ + {(channels && channels.length && ( +
+ {channels.map(channel => ( + Search.close()} + /> + ))} +
+ )) ||
} + + {(users && users.length && ( +
+ {users.map(user => ( + Search.close()} + /> + ))} +
+ )) ||
} +
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/parts/channels-result.tsx b/twake/frontend/src/app/components/search-popup/parts/channels-result.tsx index f9e079f90d..2c5865da0b 100755 --- a/twake/frontend/src/app/components/search-popup/parts/channels-result.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/channels-result.tsx @@ -4,10 +4,11 @@ import '../search-popup.scss'; import { ChannelType } from 'app/features/channels/types/channel'; import { useWorkspace } from 'features/workspaces/hooks/use-workspaces'; import assert from 'assert'; -import Emojione from 'components/emojione/emojione'; import RouterServices from 'features/router/services/router-service'; import { highlightText } from 'components/search-popup/parts/common'; import ChannelAvatar from 'components/channel-avatar/channel-avatar'; +import { WorkspaceType } from 'features/workspaces/types/workspace'; + const emoji = require('emoji-name-map'); type PropsType = { @@ -17,11 +18,23 @@ type PropsType = { }; export default ({ channel, highlight, onClick }: PropsType): JSX.Element => { - assert(channel.workspace_id, 'No workspace_id in channel object'); - assert(channel.name, 'No name in channel object'); + const info = { + workspace: { name: '' } as WorkspaceType, + }; + + try { + assert(channel.workspace_id, 'No workspace_id in channel object'); + assert(channel.name, 'No name in channel object'); + const { workspace } = useWorkspace(channel.workspace_id); + assert(workspace); + info.workspace = workspace as WorkspaceType; + const thumbnail = emoji.get(channel.icon); + } catch (e) { + console.log(channel); + console.error(e); + return
; + } // assert(channel.icon, 'No icon in channel object'); - const { workspace } = useWorkspace(channel.workspace_id); - const thumbnail = emoji.get(channel.icon); const onItemClick = async () => { assert(channel.company_id); @@ -44,7 +57,7 @@ export default ({ channel, highlight, onClick }: PropsType): JSX.Element => { className="channel-title" dangerouslySetInnerHTML={{ __html: highlightText(channel.name, highlight) }} /> -
{workspace?.name}
+
{info.workspace.name}
diff --git a/twake/frontend/src/app/components/search-popup/parts/common.tsx b/twake/frontend/src/app/components/search-popup/parts/common.tsx index ccc49965d0..3b83f4cd4a 100644 --- a/twake/frontend/src/app/components/search-popup/parts/common.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/common.tsx @@ -5,9 +5,12 @@ import DriveService from 'deprecated/Apps/Drive/Drive'; import FileUploadService from 'features/files/services/file-upload-service'; export const highlightText = (text?: string, highlight?: string) => { - if (!text || !highlight) { + if (!text) { return ''; } + if (!highlight) { + return text; + } const reg = new RegExp('(' + Strings.removeAccents(highlight) + ')', 'ig'); return Strings.removeAccents(text).replace(reg, "$1"); }; diff --git a/twake/frontend/src/app/components/search-popup/parts/discussions.tsx b/twake/frontend/src/app/components/search-popup/parts/discussions.tsx new file mode 100644 index 0000000000..8d59ead9e6 --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/parts/discussions.tsx @@ -0,0 +1,32 @@ +import Search from 'features/global/services/search-service'; +import React from 'react'; +import MessagesResult from 'components/search-popup/parts/messages-result'; +import { MessageExtended } from 'features/messages/types/message'; + +type PropsType = { + title: string; + messages: MessageExtended[]; + limit: number; +}; + +export default ({ title, messages, limit }: PropsType): JSX.Element => { + if (!messages) { + return
; + } + + return ( +
+
{title}
+
+ {messages.slice(0, limit).map(message => ( + Search.close()} + /> + ))} +
+
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/parts/files.tsx b/twake/frontend/src/app/components/search-popup/parts/files.tsx new file mode 100644 index 0000000000..3e1314c331 --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/parts/files.tsx @@ -0,0 +1,42 @@ +import PerfectScrollbar from 'react-perfect-scrollbar'; +import FilesResult from 'components/search-popup/parts/recent/files-result'; +import { onFileDownloadClick, onFilePreviewClick } from 'components/search-popup/parts/common'; +import React from 'react'; +import { FileSearchResult } from 'features/messages/types/message'; + +type PropsType = { + title: string; + files: FileSearchResult[]; + limit: number; +}; + +export default ({ files, title, limit }: PropsType): JSX.Element => { + if (!files || !files.length) { + return
; + } + + return ( +
+
{title}
+ + + {files.slice(0, limit).map(file => ( + { + onFilePreviewClick(file); + }} + onDownloadClick={() => { + onFileDownloadClick(file); + }} + /> + ))} + +
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/parts/media.tsx b/twake/frontend/src/app/components/search-popup/parts/media.tsx new file mode 100644 index 0000000000..1dd88497f1 --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/parts/media.tsx @@ -0,0 +1,39 @@ +import PerfectScrollbar from 'react-perfect-scrollbar'; +import { onFilePreviewClick } from 'components/search-popup/parts/common'; +import React from 'react'; +import MediaResult from 'components/search-popup/parts/recent/media-result'; +import { FileSearchResult } from 'features/messages/types/message'; + +type PropsType = { + title: string; + files: FileSearchResult[]; + limit: number; +}; + +export default ({ title, files, limit }: PropsType): JSX.Element => { + if (!files || !files.length) { + return
; + } + + return ( +
+
{title}
+ + + {files.slice(0, limit).map(file => ( + { + onFilePreviewClick(file); + }} + /> + ))} + +
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/parts/messages-filter.js b/twake/frontend/src/app/components/search-popup/parts/messages-filter.js index efdd939666..260122bfdc 100644 --- a/twake/frontend/src/app/components/search-popup/parts/messages-filter.js +++ b/twake/frontend/src/app/components/search-popup/parts/messages-filter.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import { ObjectModalFormTitle, diff --git a/twake/frontend/src/app/components/search-popup/parts/messages-result.tsx b/twake/frontend/src/app/components/search-popup/parts/messages-result.tsx index 144a225950..0214878989 100755 --- a/twake/frontend/src/app/components/search-popup/parts/messages-result.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/messages-result.tsx @@ -1,12 +1,10 @@ import React, { useEffect, useState } from 'react'; import '../search-popup.scss'; -import { useChannel } from 'features/channels/hooks/use-channel'; import { useUser } from 'features/users/hooks/use-user'; import { Tooltip } from 'antd'; import User from 'features/users/services/current-user-service'; import { useWorkspace } from 'features/workspaces/hooks/use-workspaces'; import RouterServices from 'features/router/services/router-service'; -import Strings from 'features/global/utils/strings'; import { highlightText } from './common'; import { MessageExtended } from 'features/messages/types/message'; import ChannelAvatar from 'components/channel-avatar/channel-avatar'; diff --git a/twake/frontend/src/app/components/search-popup/parts/quick-result.js b/twake/frontend/src/app/components/search-popup/parts/quick-result.js index 628936a1e6..0c58245296 100755 --- a/twake/frontend/src/app/components/search-popup/parts/quick-result.js +++ b/twake/frontend/src/app/components/search-popup/parts/quick-result.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import '../search-popup.scss'; import Emojione from 'components/emojione/emojione'; diff --git a/twake/frontend/src/app/components/search-popup/parts/recent-channels-and-contacts.tsx b/twake/frontend/src/app/components/search-popup/parts/recent/channels-and-contacts.tsx similarity index 100% rename from twake/frontend/src/app/components/search-popup/parts/recent-channels-and-contacts.tsx rename to twake/frontend/src/app/components/search-popup/parts/recent/channels-and-contacts.tsx diff --git a/twake/frontend/src/app/components/search-popup/parts/recent/files-result.tsx b/twake/frontend/src/app/components/search-popup/parts/recent/files-result.tsx index 425d349882..a5416a5712 100644 --- a/twake/frontend/src/app/components/search-popup/parts/recent/files-result.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/recent/files-result.tsx @@ -1,10 +1,6 @@ import React from 'react'; -import { ChannelType } from 'features/channels/types/channel'; -import { FileType } from 'features/files/types/file'; import FileUploadAPIClient from 'features/files/api/file-upload-api-client'; -import { includes } from 'lodash'; import { FileSearchResult } from 'features/messages/types/message'; -import Logger from 'features/global/framework/logger-service'; const locale = navigator.languages[0]; @@ -21,22 +17,20 @@ const iconFileByMime = (mimetype: string) => { }; export default ({ fileSearchResult, onDownloadClick, onPreviewClick }: PropsType): JSX.Element => { - let file: FileType; - try { - // @ts-ignore - file = fileSearchResult.message.files[0]; - } catch (e) { - Logger.getLogger('SearchPopup:FilesResult').error(e); - console.error(fileSearchResult); - return
; - } + const info = { + mime: fileSearchResult.metadata?.mime || '', + size: fileSearchResult.metadata?.size, + created_at: fileSearchResult.created_at, + filename: fileSearchResult.metadata?.name, + username: fileSearchResult.user.full_name, + }; - const icon = iconFileByMime(file.metadata.mime); + const icon = iconFileByMime(info.mime); let sizeStr = ''; - if (file.upload_data?.size) { - let size = file.upload_data.size; + if (info.size) { + let size = info.size; let pos = 0; while (size > 1024) { size = size / 1024; @@ -45,7 +39,7 @@ export default ({ fileSearchResult, onDownloadClick, onPreviewClick }: PropsType sizeStr = size.toFixed(2) + ' ' + ['B', 'KB', 'MB', 'GB', 'TB', 'PB'][pos]; } - let date = file.created_at + let date = info.created_at ? new Intl.DateTimeFormat(locale, { year: 'numeric', month: 'numeric', @@ -55,7 +49,7 @@ export default ({ fileSearchResult, onDownloadClick, onPreviewClick }: PropsType second: 'numeric', weekday: 'short', hour12: false, - }).format(new Date(file.created_at)) + }).format(new Date(info.created_at)) : ''; return ( @@ -64,11 +58,11 @@ export default ({ fileSearchResult, onDownloadClick, onPreviewClick }: PropsType
-
{file.metadata.name}
+
{info.filename}
{sizeStr} {date && } {date}
-
{file.user?.full_name}
+
{info.username}
diff --git a/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx b/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx index b61820c5e3..1a089e371c 100644 --- a/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/recent/media-result.tsx @@ -1,10 +1,7 @@ import React from 'react'; -import { FileType } from 'features/files/types/file'; import { FileSearchResult } from 'features/messages/types/message'; import Logger from 'features/global/framework/logger-service'; -import { - getFileMessageDownloadRoute, -} from 'components/search-popup/parts/common'; +import { getFileMessageDownloadRoute } from 'components/search-popup/parts/common'; import assert from 'assert'; type PropsType = { diff --git a/twake/frontend/src/app/components/search-popup/parts/users-result.tsx b/twake/frontend/src/app/components/search-popup/parts/users-result.tsx index 662d1b3667..8c2a7341b4 100755 --- a/twake/frontend/src/app/components/search-popup/parts/users-result.tsx +++ b/twake/frontend/src/app/components/search-popup/parts/users-result.tsx @@ -15,6 +15,8 @@ type PropsType = { export default ({ user, highlight, onClick }: PropsType): JSX.Element => { const { openDiscussion } = useDirectChannels(); + console.log(user.full_name); + const thumbnail = User.getThumbnail(user) || 'data:image/svg+xml;base64, PHN2ZyB3aWR0aD0iNTciIGhlaWdodD0iNTYiIHZpZXdCb3g9IjAgMCA1NyA1NiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMjguOTk2MSIgY3k9IjI4IiByPSIyOCIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzk1Ml82ODM4NSkiLz4KPGNpcmNsZSBjeD0iMjguOTk2MSIgY3k9IjI4IiByPSIyNy43NSIgc3Ryb2tlPSJibGFjayIgc3Ryb2tlLW9wYWNpdHk9IjAuMDgiIHN0cm9rZS13aWR0aD0iMC41IiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfOTUyXzY4Mzg1IiB4MT0iMjguOTk2MSIgeTE9IjAiIHgyPSIyOC45OTYxIiB5Mj0iNTYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzZFRDFGQiIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyNkE0RjgiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K'; diff --git a/twake/frontend/src/app/components/search-popup/search-popup.js b/twake/frontend/src/app/components/search-popup/search-popup.js index b3e04e78ae..391ffe4b6e 100755 --- a/twake/frontend/src/app/components/search-popup/search-popup.js +++ b/twake/frontend/src/app/components/search-popup/search-popup.js @@ -30,19 +30,11 @@ export default class SearchPopup extends React.Component { const tabs = [ { key: 'all', title: 'All' }, + { key: 'chats', title: 'Chats' }, { key: 'media', title: 'Media' }, { key: 'files', title: 'Files' }, ]; - const experimentalTabs = ['Chats']; - - for (let tabName of experimentalTabs) { - const tabNameLC = tabName.toLowerCase(); - if (localStorage.getItem(`search-tabs-${tabNameLC}`)) { - tabs.push({ key: tabNameLC, title: tabName }); - } - } - this.tabs = tabs; } componentDidMount() { diff --git a/twake/frontend/src/app/components/search-popup/search-popup.scss b/twake/frontend/src/app/components/search-popup/search-popup.scss index 07483a1a6e..9777244762 100755 --- a/twake/frontend/src/app/components/search-popup/search-popup.scss +++ b/twake/frontend/src/app/components/search-popup/search-popup.scss @@ -117,7 +117,7 @@ input:focus { //position: absolute; width: 100vw; - height: 100vh; + height: calc(100vh - 20px); max-width: 1000px; @@ -444,7 +444,7 @@ input:focus { } } - .recent-results { + .search-results { .result-items-channel { padding: 4px; display: flex; @@ -534,7 +534,7 @@ input:focus { .result-items-media { display: flex; flex-direction: row; - height: 130px; + height: 128px; .result-item { //box-shadow: 1px 1px 3px #ccc; padding: 4px; @@ -542,8 +542,8 @@ input:focus { img { object-fit: cover; cursor: pointer; - width: 129px; - height: 129px; + width: 120px; + height: 120px; border-radius: 8px; box-shadow: 1px 1px 3px #ccc; transition: transform 0.15s; diff --git a/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx b/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx index 0d2aa7626f..2389862188 100644 --- a/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx +++ b/twake/frontend/src/app/components/search-popup/tabs/all/recent.tsx @@ -1,72 +1,17 @@ import React, { useEffect } from 'react'; +import RecentChannelsAndContacts from 'components/search-popup/parts/recent/channels-and-contacts'; +import Files from 'components/search-popup/parts/files'; +import Media from 'components/search-popup/parts/media'; import Search from 'features/global/services/search-service'; -import FilesResult from 'components/search-popup/parts/recent/files-result'; -import MediaResult from 'components/search-popup/parts/recent/media-result'; -import PerfectScrollbar from 'react-perfect-scrollbar'; -import { FileType } from 'features/files/types/file'; -import DriveService from 'deprecated/Apps/Drive/Drive'; -import FileUploadService from 'features/files/services/file-upload-service'; -import RecentChannelsAndContacts from 'components/search-popup/parts/recent-channels-and-contacts'; -import { FileSearchResult, MessageFileType } from 'features/messages/types/message'; -import Logger from 'features/global/framework/logger-service'; -import assert from 'assert'; -import { onFileDownloadClick, onFilePreviewClick } from 'components/search-popup/parts/common'; export default (): JSX.Element => { useEffect(() => {}, []); - // let logger = Logger.getLogger('SearchPopup:TabsRecent'); - return ( -
- {} - - {(Search.recent.files.length && ( -
-
Recent files
- - - {Search.recent.files.slice(0, 8).map(file => ( - { - onFilePreviewClick(file); - }} - onDownloadClick={() => { - onFileDownloadClick(file); - }} - /> - ))} - -
- )) ||
} - - {(Search.recent.media.length && ( -
-
Recent media
- - - {Search.recent.media.slice(0, 7).map(file => ( - { - onFilePreviewClick(file); - }} - /> - ))} - -
- )) ||
} +
+ + +
); }; diff --git a/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx b/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx index 6d8f441dfd..4193c62e7a 100644 --- a/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx +++ b/twake/frontend/src/app/components/search-popup/tabs/all/search.tsx @@ -1,71 +1,37 @@ import Search from 'features/global/services/search-service'; -import ChannelsResult from 'components/search-popup/parts/channels-result'; -import UsersResult from 'components/search-popup/parts/users-result'; -import MessagesResult from 'components/search-popup/parts/messages-result'; -import React, { useEffect, useState } from 'react'; +import React, { useState } from 'react'; +import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts'; +import Discussions from 'components/search-popup/parts/discussions'; +import Files from 'components/search-popup/parts/files'; +import Media from 'components/search-popup/parts/media'; export default (): JSX.Element => { const [notFound, setNotFound] = useState(false); - useEffect(() => { - setNotFound( - Boolean(Search.value) && - !Search.searchInProgress && - !Search.results.channels.length && - !Search.results.users.length && - !Search.results.messages.length, - ); - }, [Search.searchInProgress, Search.value]); + if ( + Boolean(Search.value) && + !Search.searchInProgress && + !Search.results.channels.length && + !Search.results.users.length && + !Search.results.messages.length + ) { + return
Nothing found
; + } return (
-
{notFound &&
Nothing found
}
- - {((Search.results.channels.length || Search.results.users.length) && ( -
-
Channels and contacts
- - {(Search.results.channels.length && ( -
- {Search.results.channels.map(channel => ( - Search.close()} - /> - ))} -
- )) ||
} + {((Search.results.channels?.length || Search.results.users?.length) && ( + + )) ||
} + {(Search.results.messages?.length && ( + + )) ||
} - {(Search.results.users.length && ( -
- {Search.results.users.map(user => ( - Search.close()} - /> - ))} -
- )) ||
} -
+ {(Search.results.files?.length && ( + )) ||
} - {(Search.results.messages.length && ( -
-
Discussions
-
- {Search.results.messages.map(message => ( - Search.close()} - /> - ))} -
-
+ {(Search.results.media?.length && ( + )) ||
}
); diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx index bab8601ce9..cfe0104108 100644 --- a/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx +++ b/twake/frontend/src/app/components/search-popup/tabs/chats/index.tsx @@ -1,38 +1,27 @@ -import React, { useEffect, useState } from 'react'; +import PerfectScrollbar from 'react-perfect-scrollbar'; import Search from 'features/global/services/search-service'; -import { FileType } from 'features/files/types/file'; -import DriveService from 'deprecated/Apps/Drive/Drive'; -import FileUploadService from 'features/files/services/file-upload-service'; -import RecentChannelsAndContacts from 'components/search-popup/parts/recent-channels-and-contacts'; +import React from 'react'; +import SearchComponent from './search'; +import RecentComponent from './recent'; -export default (): JSX.Element => { - const [pageReady, setPageReady] = useState(false); - - const [searchMode, setSearchMode] = useState(false); - - useEffect(() => { - setSearchMode(Boolean(Search.value)); - setPageReady(true); - }, []); - - useEffect(() => { - const newVal = Boolean(Search.value); - if (searchMode !== newVal) { - setSearchMode(newVal); - } - }, [Search.value]); +type PropsType = { scroller: any }; +export default ({ scroller }: PropsType): JSX.Element => { return ( - (pageReady && ( -
-
- {searchMode || } - - {(searchMode && ( -
Channels and conversations
- )) ||
Recent channels and conversations
} -
-
- )) ||
+ (Search.value && ( + { + scroller = node; + }} + > + + + )) || + (Search.recentInProgress &&
loading recent...
) || ( + + ) ); }; diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx new file mode 100644 index 0000000000..dffbd6508f --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/tabs/chats/recent.tsx @@ -0,0 +1,36 @@ +import React, { useEffect } from 'react'; +import RecentChannelsAndContacts from 'components/search-popup/parts/recent/channels-and-contacts'; +import Search from 'features/global/services/search-service'; +import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts'; +import { UserType } from 'features/users/types/user'; + +export default (): JSX.Element => { + useEffect(() => {}, []); + + if (!Search.recent.channels) { + return
; + } + + const directChannels = Search.recent.channels.filter(a => a.visibility === 'direct'); + const publicChannels = Search.recent.channels.filter(a => a.visibility === 'public'); + + const users = [] as UserType[]; + const usedIds = new Set(); + + directChannels.forEach(ch => { + ch.users?.forEach(u => { + if (!usedIds.has(u.id)) { + users.push(u); + usedIds.add(u.id); + } + }); + }); + + return ( +
+ + + +
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx b/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx new file mode 100644 index 0000000000..1ffcb6e0a4 --- /dev/null +++ b/twake/frontend/src/app/components/search-popup/tabs/chats/search.tsx @@ -0,0 +1,31 @@ +import Search from 'features/global/services/search-service'; +import React, { useEffect, useState } from 'react'; +import ChannelsAndContacts from 'components/search-popup/parts/channels-and-contacts'; +import Discussions from 'components/search-popup/parts/discussions'; + +export default (): JSX.Element => { + const [notFound, setNotFound] = useState(false); + + useEffect(() => { + setNotFound( + Boolean(Search.value) && + !Search.searchInProgress && + !Search.results.channels.length && + !Search.results.users.length && + !Search.results.messages.length, + ); + }, [Search.searchInProgress, Search.value]); + + return ( +
+
{notFound &&
Nothing found
}
+ + {((Search.results.channels.length || Search.results.users.length) && ( + + )) ||
} + {(Search.results.messages.length && ) || ( +
+ )} +
+ ); +}; diff --git a/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx index f59f7a4b50..de0d6cd9ee 100644 --- a/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx +++ b/twake/frontend/src/app/components/search-popup/tabs/files/index.tsx @@ -1,65 +1,33 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import Search from 'features/global/services/search-service'; -import PerfectScrollbar from 'react-perfect-scrollbar'; -import FilesResult from 'components/search-popup/parts/recent/files-result'; -import { onFileDownloadClick, onFilePreviewClick } from 'components/search-popup/parts/common'; -import { isEmpty } from 'lodash'; +import Files from 'components/search-popup/parts/files'; export default (): JSX.Element => { - const [pageReady, setPageReady] = useState(false); - const [searchMode, setSearchMode] = useState(false); - const [notFound, setNotFound] = useState(false); + const isSearchMode = Boolean(Search.value); - useEffect(() => { - setSearchMode(Boolean(Search.value)); - setPageReady(true); - }, []); + useEffect(() => {}, [Search.searchInProgress]); - useEffect(() => { - const newVal = Boolean(Search.value); - if (searchMode !== newVal) { - setSearchMode(newVal); - } - }, [Search.value]); + if ( + isSearchMode && + !Search.searchInProgress && + (!Search.results.files || !Search.results.files.length) + ) { + return
Nothing found
; + } - useEffect(() => { - setPageReady(!Search.searchInProgress); - setNotFound(Boolean(Search.value) && !Search.searchInProgress && isEmpty(Search.results.media)); - }, [Search.searchInProgress, Search.value]); + if (Search.recent.files === undefined) { + return
; + } - useEffect(() => {}, [Search.results.files, Search.recent.files]); + const groupTitle = isSearchMode ? 'Files' : 'Recent files'; return ( - (pageReady && ( -
-
{notFound &&
Nothing found
}
- -
- {(!searchMode &&
Recent files
) || - (!notFound && !Search.searchInProgress && ( -
Files
- ))} - - - {(searchMode ? Search.results.files : Search.recent.files).map(file => ( - { - onFilePreviewClick(file); - }} - onDownloadClick={() => { - onFileDownloadClick(file); - }} - /> - ))} - -
-
- )) ||
+
+ +
); }; diff --git a/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx b/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx index 6bc8709f54..f9412d37e6 100644 --- a/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx +++ b/twake/frontend/src/app/components/search-popup/tabs/media/index.tsx @@ -1,60 +1,33 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect } from 'react'; import Search from 'features/global/services/search-service'; -import MediaResult from 'components/search-popup/parts/recent/media-result'; -import PerfectScrollbar from 'react-perfect-scrollbar'; -import { FileType } from 'features/files/types/file'; -import DriveService from 'deprecated/Apps/Drive/Drive'; -import FileUploadService from 'features/files/services/file-upload-service'; -import { onFilePreviewClick } from 'components/search-popup/parts/common'; -import { isEmpty } from 'lodash'; +import Media from 'components/search-popup/parts/media'; export default (): JSX.Element => { - const [pageReady, setPageReady] = useState(false); - const [searchMode, setSearchMode] = useState(false); - const [notFound, setNotFound] = useState(false); + useEffect(() => {}, [Search.value, Search.searchInProgress]); - useEffect(() => { - setSearchMode(Boolean(Search.value)); - setPageReady(true); - }, []); + const isSearchMode = Boolean(Search.value); - useEffect(() => { - const newVal = Boolean(Search.value); - if (searchMode !== newVal) { - setSearchMode(newVal); - } - }, [Search.value]); + if ( + isSearchMode && + !Search.searchInProgress && + (!Search.results.media || !Search.results.media.length) + ) { + return
Nothing found
; + } - useEffect(() => { - setPageReady(!Search.searchInProgress); - setNotFound(Boolean(Search.value) && !Search.searchInProgress && isEmpty(Search.results.media)); - }, [Search.searchInProgress, Search.value]); + if (Search.recent.media === undefined) { + return
; + } - return ( - (pageReady && ( -
-
{notFound &&
Nothing found
}
-
- {(!searchMode &&
Recent media
) || - (!notFound &&
Media
)} + const groupTitle = isSearchMode ? 'Media' : 'Recent media'; - - {(searchMode ? Search.results.media : Search.recent.media).map(file => ( - { - onFilePreviewClick(file); - }} - /> - ))} - -
-
- )) ||
+ return ( +
+ +
); }; diff --git a/twake/frontend/src/app/features/channels/api/channel-api-client.ts b/twake/frontend/src/app/features/channels/api/channel-api-client.ts index 179ff9fa8d..f62163acc1 100644 --- a/twake/frontend/src/app/features/channels/api/channel-api-client.ts +++ b/twake/frontend/src/app/features/channels/api/channel-api-client.ts @@ -81,7 +81,10 @@ class ChannelAPIClientService { } } - async search(searchString: string, options?: SearchOptions): Promise { + async search( + searchString: string, + options?: SearchOptions, + ): Promise<{ resources: ChannelType[] }> { const companyId = options?.company_id || Workspace.currentGroupId; let query = `/internal/services/channels/v1/companies/${companyId}/search?q=${searchString}`; let res = await Api.getWithParams<{ resources: ChannelType[] }>(query, options); diff --git a/twake/frontend/src/app/features/global/services/search-service.ts b/twake/frontend/src/app/features/global/services/search-service.ts index 9be416d7b5..4a3d62a32c 100644 --- a/twake/frontend/src/app/features/global/services/search-service.ts +++ b/twake/frontend/src/app/features/global/services/search-service.ts @@ -103,6 +103,7 @@ class SearchService extends Observable { } const res = await ChannelAPIClient.search(this.value, { limit }); this.results.channels = res.resources; + this.logger.debug('search channels, found', res.resources.length); this.notify(); } @@ -115,6 +116,7 @@ class SearchService extends Observable { companyId: Workspaces.currentGroupId, }).then(users => { this.results.users = users; + this.logger.debug('search users, found', users.length); this.notify(); }); } @@ -223,7 +225,10 @@ class SearchService extends Observable { ]; break; case 'chats': - promises = [this.searchMessages(clearResult, 100)]; + promises = [ + this.searchContacts(clearResult, 12), + this.searchMessages(clearResult, 100), + ]; break; case 'media': promises = [this.searchMedia(clearResult, 100)]; diff --git a/twake/frontend/src/app/features/messages/types/message.ts b/twake/frontend/src/app/features/messages/types/message.ts index 4b8a33411e..792408e4cb 100644 --- a/twake/frontend/src/app/features/messages/types/message.ts +++ b/twake/frontend/src/app/features/messages/types/message.ts @@ -33,6 +33,7 @@ export type MessageFileType = { }; export type FileSearchResult = MessageFileType & { + created_at: number; message: Message; user: UserType; };