Skip to content

Commit

Permalink
linagora#1960 Allow mentions to use user list state
Browse files Browse the repository at this point in the history
  • Loading branch information
Stéphane VIEIRA committed Mar 11, 2022
1 parent e9966be commit fda0c03
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import DepreciatedCollections from 'app/deprecated/CollectionsV1/Collections/Col
import { UserType } from 'app/features/users/types/user';
import UserService from 'app/features/users/services/current-user-service';
import RouterService from 'app/features/router/services/router-service';
import UserAPIClient from 'app/features/users/api/user-api-client';
import { WorkspaceUserType } from 'app/features/workspaces/types/workspace';
import Strings from 'app/features/global/utils/strings';
import ChannelMembersAPIClient from 'app/features/channel-members/api/channel-members-api-client';
import { ChannelMemberType } from 'app/features/channel-members/types/channel-member-types';
import { searchBackend, searchFrontend } from 'app/features/users/hooks/use-search-user-list';

import './style.scss';

Expand Down Expand Up @@ -63,23 +61,34 @@ const resolver = async (

callback(result);
} else {
UserAPIClient.search<WorkspaceUserType>(
Strings.removeAccents(text),
{
scope: 'workspace',
if (companyId && workspaceId) {
const resultFrontend = searchFrontend(text, {
companyId,
workspaceId,
},
wsUsers => {
const users = wsUsers.map(wsUser => wsUser.user);

for (let j = 0; j < Math.min(max, users.length); j++) {
result[j] = { ...users[j], ...{ autocomplete_id: j } };
}
scope: 'workspace',
});

callback(result);
},
);
searchBackend(text, {
companyId,
workspaceId,
scope: 'workspace',
callback: () => {
const resultFrontend = searchFrontend(text, {
companyId,
workspaceId,
scope: 'workspace',
});

callback([...resultFrontend]);
},
});

for (let j = 0; j < Math.min(max, resultFrontend.length); j++) {
result[j] = { ...resultFrontend[j], ...{ autocomplete_id: j } };
}

callback(result);
}
}
};

Expand Down
133 changes: 92 additions & 41 deletions twake/frontend/src/app/features/users/hooks/use-search-user-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,72 @@ import { useEffect, useState } from 'react';

import useRouterCompany from 'app/features/router/hooks/use-router-company';
import { UserType } from 'app/features/users/types/user';
import { useSetUserList, useUserList } from './use-user-list';
import { getCurrentUserList, setUserList, useSetUserList, useUserList } from './use-user-list';
import UserAPIClient, { SearchContextType } from '../api/user-api-client';
import { delayRequest } from 'app/features/global/utils/managedSearchRequest';
import Strings from 'app/features/global/utils/strings';
import useRouterWorkspace from 'app/features/router/hooks/use-router-workspace';
import { WorkspaceUserType } from 'app/features/workspaces/types/workspace';

export const useSearchUserList = ({
scope,
}: {
scope: SearchContextType['scope'];
}): {
search: (str?: string) => void;
result: UserType[];
} => {
const { set: setUserList } = useSetUserList('use-search-user-list');
const [query, setQuery] = useState<string | undefined>();
const { userList } = useUserList();
const companyId = useRouterCompany();
const workspaceId = useRouterWorkspace();
let result = userList || [];
const search = async (str?: string) => {
setQuery(str);
};
export const searchBackend = async (
query: string | undefined,
{
workspaceId,
companyId,
scope,
callback,
}: {
workspaceId: string;
companyId: string;
scope: SearchContextType['scope'];
callback?: () => void;
},
) => {
delayRequest('useSearchUserList', async () => {
await UserAPIClient.search<any>(
query,
{
companyId,
workspaceId: scope === 'workspace' ? workspaceId : undefined,
scope,
},
result => {
let final: UserType[] = [];
if (result && scope === 'workspace') {
final = result.map(wsUser => ({
...wsUser.user,
workspaces: [{ id: workspaceId, company_id: companyId }],
}));
}

useEffect(() => {
delayRequest('useSearchUserList', async () => {
await UserAPIClient.search<WorkspaceUserType>(
query,
{
companyId,
workspaceId: scope === 'workspace' ? workspaceId : undefined,
scope,
},
list => {
if (list && scope === 'workspace') {
setUserList(
list.map(wsUser => ({
...wsUser.user,
workspaces: [{ id: workspaceId, company_id: companyId }],
})),
);
}
},
);
});
}, [companyId, query, scope, setUserList, workspaceId]);
if (result && scope === 'company') {
final = result.map(user => ({
...user,
workspaces: [{ id: workspaceId, company_id: companyId }],
}));
}

callback && callback();
setUserList && setUserList(final);
},
);
});
};

export const searchFrontend = (
query: string | undefined,
{
workspaceId,
companyId,
scope,
userList,
}: {
workspaceId: string;
companyId: string;
scope: SearchContextType['scope'];
userList?: UserType[];
},
) => {
let result = userList || getCurrentUserList() || [];

if (query) {
result = result
Expand All @@ -61,6 +80,12 @@ export const useSearchUserList = ({
.sort((a, b) => a.username.length - b.username.length);
}

if (!query) {
// TODO return list with users sorted by favorite
// eslint-disable-next-line no-self-assign
result = result;
}

if (scope === 'company') {
result = result?.filter(u => u.companies?.map(obj => obj.company.id).includes(companyId));
}
Expand All @@ -69,5 +94,31 @@ export const useSearchUserList = ({
result = result.filter(u => u.workspaces?.map(ws => ws.id).includes(workspaceId));
}

return result;
};

export const useSearchUserList = ({
scope,
}: {
scope: SearchContextType['scope'];
}): {
search: (str?: string) => void;
result: UserType[];
} => {
const { set: setUserList } = useSetUserList('use-search-user-list');
const [query, setQuery] = useState<string | undefined>();
const { userList } = useUserList();
const companyId = useRouterCompany();
const workspaceId = useRouterWorkspace();
const search = async (str?: string) => {
setQuery(str);
};

useEffect(() => {
searchBackend(query, { workspaceId, scope, companyId });
}, [companyId, query, scope, setUserList, workspaceId]);

const result = searchFrontend(query, { workspaceId, scope, companyId, userList: userList || [] });

return { search, result };
};
11 changes: 5 additions & 6 deletions twake/frontend/src/app/features/users/hooks/use-user-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ export const useUserList = (): {

// Access from any services
// You can't use it before calling the useSetUserList hook
export let setUserList: (
recoilVal: RecoilState<UserType[]>,
valOrUpdater: UserType[] | ((currVal: UserType[]) => UserType[]),
) => void = _u => {};
export let setUserList: (nextList: UserType[]) => void = _ => {};

let currentUserList: UserType[] = [];

export const getCurrentUserList = () => currentUserList;

export const getUser = (userId: string) => {
return currentUserList.filter(u => u.id === userId)[0];
};
Expand Down Expand Up @@ -88,9 +87,9 @@ export function useSetUserList(key: string) {
currentUserList = newList;
}
}

setUserList = set;
});

setUserList = set;

return { set };
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ export default (props: Props) => {
let { message } = useMessage(context);
let parentMessage: NodeMessage | null = useMessage({ ...context, id: message.thread_id }).message;

let user = useUser(message.user_id);
const user = useUser(message.user_id);

const companyApplications =
useRecoilState(CompanyApplicationsStateFamily(context.companyId))[0] || [];
let application = companyApplications.find(a => a.id === message.application_id);
Expand Down

0 comments on commit fda0c03

Please sign in to comment.