mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-08-21 15:38:11 +00:00
This commit is contained in:
parent
83ab679a13
commit
a977aa90bc
@ -42,6 +42,7 @@ const CreateUser = ({
|
|||||||
const markdownRef = useRef<EditorContentRef>();
|
const markdownRef = useRef<EditorContentRef>();
|
||||||
const [description] = useState<string>('');
|
const [description] = useState<string>('');
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
|
const [displayName, setDisplayName] = useState('');
|
||||||
const [isAdmin, setIsAdmin] = useState(false);
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
const [isBot, setIsBot] = useState(false);
|
const [isBot, setIsBot] = useState(false);
|
||||||
const [selectedRoles, setSelectedRoles] = useState<Array<string | undefined>>(
|
const [selectedRoles, setSelectedRoles] = useState<Array<string | undefined>>(
|
||||||
@ -52,6 +53,7 @@ const CreateUser = ({
|
|||||||
);
|
);
|
||||||
const [showErrorMsg, setShowErrorMsg] = useState({
|
const [showErrorMsg, setShowErrorMsg] = useState({
|
||||||
email: false,
|
email: false,
|
||||||
|
displayName: false,
|
||||||
validEmail: false,
|
validEmail: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -77,6 +79,12 @@ const CreateUser = ({
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'displayName':
|
||||||
|
setDisplayName(value);
|
||||||
|
setShowErrorMsg({ ...showErrorMsg, displayName: false });
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -166,6 +174,7 @@ const CreateUser = ({
|
|||||||
const userProfile: CreateUserSchema = {
|
const userProfile: CreateUserSchema = {
|
||||||
description: markdownRef.current?.getEditorContent() || undefined,
|
description: markdownRef.current?.getEditorContent() || undefined,
|
||||||
name: email.split('@')[0],
|
name: email.split('@')[0],
|
||||||
|
displayName,
|
||||||
roles: validRole.length ? validRole : undefined,
|
roles: validRole.length ? validRole : undefined,
|
||||||
teams: validTeam.length ? validTeam : undefined,
|
teams: validTeam.length ? validTeam : undefined,
|
||||||
email: email,
|
email: email,
|
||||||
@ -223,7 +232,7 @@ const CreateUser = ({
|
|||||||
<h6 className="tw-heading tw-text-base">Create User</h6>
|
<h6 className="tw-heading tw-text-base">Create User</h6>
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label tw-mb-0" htmlFor="email">
|
<label className="tw-block tw-form-label tw-mb-0" htmlFor="email">
|
||||||
{requiredField('Email:')}
|
{requiredField('Email')}
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
className="tw-form-inputs tw-px-3 tw-py-1"
|
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||||
@ -242,14 +251,35 @@ const CreateUser = ({
|
|||||||
? errorMsg(jsonData['form-error-messages']['invalid-email'])
|
? errorMsg(jsonData['form-error-messages']['invalid-email'])
|
||||||
: null}
|
: null}
|
||||||
</Field>
|
</Field>
|
||||||
|
<Field>
|
||||||
|
<label className="tw-block tw-form-label tw-mb-0" htmlFor="displayName">
|
||||||
|
Display Name
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className="tw-form-inputs tw-px-3 tw-py-1"
|
||||||
|
data-testid="displayName"
|
||||||
|
id="displayName"
|
||||||
|
name="displayName"
|
||||||
|
placeholder="displayName"
|
||||||
|
type="text"
|
||||||
|
value={displayName}
|
||||||
|
onChange={handleValidation}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{showErrorMsg.email
|
||||||
|
? errorMsg(jsonData['form-error-messages']['empty-email'])
|
||||||
|
: showErrorMsg.validEmail
|
||||||
|
? errorMsg(jsonData['form-error-messages']['invalid-email'])
|
||||||
|
: null}
|
||||||
|
</Field>
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label tw-mb-0" htmlFor="description">
|
<label className="tw-block tw-form-label tw-mb-0" htmlFor="description">
|
||||||
Description:
|
Description
|
||||||
</label>
|
</label>
|
||||||
<RichTextEditor initialValue={description} ref={markdownRef} />
|
<RichTextEditor initialValue={description} ref={markdownRef} />
|
||||||
</Field>
|
</Field>
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label tw-mb-0">Teams:</label>
|
<label className="tw-block tw-form-label tw-mb-0">Teams</label>
|
||||||
<DropDown
|
<DropDown
|
||||||
className={classNames('tw-bg-white', {
|
className={classNames('tw-bg-white', {
|
||||||
'tw-bg-gray-100 tw-cursor-not-allowed': teams.length === 0,
|
'tw-bg-gray-100 tw-cursor-not-allowed': teams.length === 0,
|
||||||
@ -263,7 +293,7 @@ const CreateUser = ({
|
|||||||
</Field>
|
</Field>
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label tw-mb-0" htmlFor="role">
|
<label className="tw-block tw-form-label tw-mb-0" htmlFor="role">
|
||||||
Roles:
|
Roles
|
||||||
</label>
|
</label>
|
||||||
<DropDown
|
<DropDown
|
||||||
className={classNames('tw-bg-white', {
|
className={classNames('tw-bg-white', {
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import { findByTestId, queryByTestId, render } from '@testing-library/react';
|
import { findByTestId, queryByTestId, render } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
import { MemoryRouter } from 'react-router-dom';
|
||||||
|
import { FeedFilter } from '../../enums/mydata.enum';
|
||||||
import Users from './Users.component';
|
import Users from './Users.component';
|
||||||
|
|
||||||
const mockUserData = {
|
const mockUserData = {
|
||||||
@ -102,25 +103,61 @@ jest.mock('../common/TabsPane/TabsPane', () => {
|
|||||||
return jest.fn().mockReturnValue(<p data-testid="tabs">Tabs</p>);
|
return jest.fn().mockReturnValue(<p data-testid="tabs">Tabs</p>);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('../ActivityFeed/ActivityFeedList/ActivityFeedList.tsx', () => {
|
||||||
|
return jest.fn().mockReturnValue(<p>FeedCards</p>);
|
||||||
|
});
|
||||||
|
|
||||||
|
const mockObserve = jest.fn();
|
||||||
|
const mockunObserve = jest.fn();
|
||||||
|
|
||||||
|
window.IntersectionObserver = jest.fn().mockImplementation(() => ({
|
||||||
|
observe: mockObserve,
|
||||||
|
unobserve: mockunObserve,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const mockFetchFeedHandler = jest.fn();
|
||||||
|
const feedFilterHandler = jest.fn();
|
||||||
|
const fetchData = jest.fn();
|
||||||
|
const postFeed = jest.fn();
|
||||||
|
const mockPaging = {
|
||||||
|
after: 'MTY0OTIzNTQ3MzExMg==',
|
||||||
|
total: 202,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockProp = {
|
||||||
|
feedData: [],
|
||||||
|
feedFilter: FeedFilter.ALL,
|
||||||
|
feedFilterHandler: feedFilterHandler,
|
||||||
|
fetchData: fetchData,
|
||||||
|
fetchFeedHandler: mockFetchFeedHandler,
|
||||||
|
isFeedLoading: false,
|
||||||
|
paging: mockPaging,
|
||||||
|
postFeedHandler: postFeed,
|
||||||
|
};
|
||||||
|
|
||||||
describe('Test User Component', () => {
|
describe('Test User Component', () => {
|
||||||
it('Should render user component', async () => {
|
it('Should render user component', async () => {
|
||||||
const { container } = render(<Users userData={mockUserData} />, {
|
const { container } = render(
|
||||||
wrapper: MemoryRouter,
|
<Users userData={mockUserData} {...mockProp} />,
|
||||||
});
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const tabs = await findByTestId(container, 'tabs');
|
const tabs = await findByTestId(container, 'tabs');
|
||||||
const noAssets = await findByTestId(container, 'no-assets');
|
|
||||||
const leftPanel = await findByTestId(container, 'left-panel');
|
const leftPanel = await findByTestId(container, 'left-panel');
|
||||||
|
|
||||||
expect(tabs).toBeInTheDocument();
|
expect(tabs).toBeInTheDocument();
|
||||||
expect(noAssets).toBeInTheDocument();
|
|
||||||
expect(leftPanel).toBeInTheDocument();
|
expect(leftPanel).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should render non deleted teams', async () => {
|
it('Should render non deleted teams', async () => {
|
||||||
const { container } = render(<Users userData={mockUserData} />, {
|
const { container } = render(
|
||||||
wrapper: MemoryRouter,
|
<Users userData={mockUserData} {...mockProp} />,
|
||||||
});
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const teamFinance = await findByTestId(container, 'Finance');
|
const teamFinance = await findByTestId(container, 'Finance');
|
||||||
const teamDataPlatform = await findByTestId(container, 'Data_Platform');
|
const teamDataPlatform = await findByTestId(container, 'Data_Platform');
|
||||||
@ -130,12 +167,30 @@ describe('Test User Component', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Should not render deleted teams', async () => {
|
it('Should not render deleted teams', async () => {
|
||||||
const { container } = render(<Users userData={mockUserData} />, {
|
const { container } = render(
|
||||||
wrapper: MemoryRouter,
|
<Users userData={mockUserData} {...mockProp} />,
|
||||||
});
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const deletedTeam = queryByTestId(container, 'Customer_Support');
|
const deletedTeam = queryByTestId(container, 'Customer_Support');
|
||||||
|
|
||||||
expect(deletedTeam).not.toBeInTheDocument();
|
expect(deletedTeam).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should create an observer if IntersectionObserver is available', async () => {
|
||||||
|
const { container } = render(
|
||||||
|
<Users userData={mockUserData} {...mockProp} />,
|
||||||
|
{
|
||||||
|
wrapper: MemoryRouter,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const obServerElement = await findByTestId(container, 'observer-element');
|
||||||
|
|
||||||
|
expect(obServerElement).toBeInTheDocument();
|
||||||
|
|
||||||
|
expect(mockObserve).toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,28 +11,77 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import { EntityThread } from 'Models';
|
||||||
|
import React, { Fragment, RefObject, useEffect, useState } from 'react';
|
||||||
|
import { filterList, observerOptions } from '../../constants/Mydata.constants';
|
||||||
import { AssetsType } from '../../enums/entity.enum';
|
import { AssetsType } from '../../enums/entity.enum';
|
||||||
|
import { FeedFilter } from '../../enums/mydata.enum';
|
||||||
import { EntityReference, User } from '../../generated/entity/teams/user';
|
import { EntityReference, User } from '../../generated/entity/teams/user';
|
||||||
|
import { Paging } from '../../generated/type/paging';
|
||||||
|
import { useInfiniteScroll } from '../../hooks/useInfiniteScroll';
|
||||||
import UserCard from '../../pages/teams/UserCard';
|
import UserCard from '../../pages/teams/UserCard';
|
||||||
import { getNonDeletedTeams } from '../../utils/CommonUtils';
|
import { getNonDeletedTeams } from '../../utils/CommonUtils';
|
||||||
|
import { dropdownIcon as DropDownIcon } from '../../utils/svgconstant';
|
||||||
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
||||||
|
import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList';
|
||||||
|
import { Button } from '../buttons/Button/Button';
|
||||||
import Avatar from '../common/avatar/Avatar';
|
import Avatar from '../common/avatar/Avatar';
|
||||||
import TabsPane from '../common/TabsPane/TabsPane';
|
import TabsPane from '../common/TabsPane/TabsPane';
|
||||||
import PageLayout from '../containers/PageLayout';
|
import PageLayout from '../containers/PageLayout';
|
||||||
|
import DropDownList from '../dropdown/DropDownList';
|
||||||
|
import Loader from '../Loader/Loader';
|
||||||
|
import Onboarding from '../onboarding/Onboarding';
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
userData: User;
|
userData: User;
|
||||||
};
|
feedData: EntityThread[];
|
||||||
|
feedFilter: FeedFilter;
|
||||||
|
paging: Paging;
|
||||||
|
isFeedLoading: boolean;
|
||||||
|
feedFilterHandler: (v: FeedFilter) => void;
|
||||||
|
fetchFeedHandler: (filterType: FeedFilter, after?: string) => void;
|
||||||
|
postFeedHandler: (value: string, id: string) => void;
|
||||||
|
deletePostHandler?: (threadId: string, postId: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
const Users = ({ userData }: Props) => {
|
const Users = ({
|
||||||
|
userData,
|
||||||
|
feedData,
|
||||||
|
feedFilter,
|
||||||
|
feedFilterHandler,
|
||||||
|
isFeedLoading,
|
||||||
|
postFeedHandler,
|
||||||
|
deletePostHandler,
|
||||||
|
fetchFeedHandler,
|
||||||
|
paging,
|
||||||
|
}: Props) => {
|
||||||
const [activeTab, setActiveTab] = useState(1);
|
const [activeTab, setActiveTab] = useState(1);
|
||||||
|
const [fieldListVisible, setFieldListVisible] = useState<boolean>(false);
|
||||||
|
const [elementRef, isInView] = useInfiniteScroll(observerOptions);
|
||||||
const activeTabHandler = (tab: number) => {
|
const activeTabHandler = (tab: number) => {
|
||||||
setActiveTab(tab);
|
setActiveTab(tab);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDropDown = (
|
||||||
|
_e: React.MouseEvent<HTMLElement, MouseEvent>,
|
||||||
|
value?: string
|
||||||
|
) => {
|
||||||
|
feedFilterHandler((value as FeedFilter) || FeedFilter.ALL);
|
||||||
|
setFieldListVisible(false);
|
||||||
|
};
|
||||||
|
|
||||||
const tabs = [
|
const tabs = [
|
||||||
|
{
|
||||||
|
name: 'Activity Feed',
|
||||||
|
icon: {
|
||||||
|
alt: 'activity_feed',
|
||||||
|
name: 'activity_feed',
|
||||||
|
title: 'Activity Feed',
|
||||||
|
selectedName: 'activity-feed-color',
|
||||||
|
},
|
||||||
|
isProtected: false,
|
||||||
|
position: 1,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'Owned Data',
|
name: 'Owned Data',
|
||||||
icon: {
|
icon: {
|
||||||
@ -42,7 +91,7 @@ const Users = ({ userData }: Props) => {
|
|||||||
selectedName: 'owned-data',
|
selectedName: 'owned-data',
|
||||||
},
|
},
|
||||||
isProtected: false,
|
isProtected: false,
|
||||||
position: 1,
|
position: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Following',
|
name: 'Following',
|
||||||
@ -53,7 +102,7 @@ const Users = ({ userData }: Props) => {
|
|||||||
selectedName: 'following',
|
selectedName: 'following',
|
||||||
},
|
},
|
||||||
isProtected: false,
|
isProtected: false,
|
||||||
position: 2,
|
position: 3,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -88,6 +137,7 @@ const Users = ({ userData }: Props) => {
|
|||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="tw-mt-2">{userData.email}</p>
|
<p className="tw-mt-2">{userData.email}</p>
|
||||||
|
<p className="tw-mt-2">{userData.description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-pb-4 tw-mb-4 tw-border-b">
|
<div className="tw-pb-4 tw-mb-4 tw-border-b">
|
||||||
<h6 className="tw-heading tw-mb-3">Teams</h6>
|
<h6 className="tw-heading tw-mb-3">Teams</h6>
|
||||||
@ -150,6 +200,80 @@ const Users = ({ userData }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getFilterDropDown = () => {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<div className="tw-relative tw-mt-5">
|
||||||
|
<Button
|
||||||
|
className="hover:tw-no-underline focus:tw-no-underline"
|
||||||
|
data-testid="feeds"
|
||||||
|
size="custom"
|
||||||
|
tag="button"
|
||||||
|
theme="primary"
|
||||||
|
variant="link"
|
||||||
|
onClick={() => setFieldListVisible((visible) => !visible)}>
|
||||||
|
<span className="tw-font-medium">
|
||||||
|
{filterList.find((f) => f.value === feedFilter)?.name}
|
||||||
|
</span>
|
||||||
|
<DropDownIcon />
|
||||||
|
</Button>
|
||||||
|
{fieldListVisible && (
|
||||||
|
<DropDownList
|
||||||
|
dropDownList={filterList}
|
||||||
|
value={feedFilter}
|
||||||
|
onSelect={handleDropDown}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLoader = () => {
|
||||||
|
return isFeedLoading ? <Loader /> : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFeedTabData = () => {
|
||||||
|
return (
|
||||||
|
<Fragment>
|
||||||
|
{feedData?.length > 0 || feedFilter !== FeedFilter.ALL ? (
|
||||||
|
<Fragment>
|
||||||
|
{getFilterDropDown()}
|
||||||
|
<ActivityFeedList
|
||||||
|
withSidePanel
|
||||||
|
className=""
|
||||||
|
deletePostHandler={deletePostHandler}
|
||||||
|
feedList={feedData}
|
||||||
|
postFeedHandler={postFeedHandler}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
) : (
|
||||||
|
<Onboarding />
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
data-testid="observer-element"
|
||||||
|
id="observer-element"
|
||||||
|
ref={elementRef as RefObject<HTMLDivElement>}>
|
||||||
|
{getLoader()}
|
||||||
|
</div>
|
||||||
|
</Fragment>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchMoreFeed = (
|
||||||
|
isElementInView: boolean,
|
||||||
|
pagingObj: Paging,
|
||||||
|
isLoading: boolean
|
||||||
|
) => {
|
||||||
|
if (isElementInView && pagingObj?.after && !isLoading) {
|
||||||
|
fetchFeedHandler(feedFilter, pagingObj.after);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchMoreFeed(isInView as boolean, paging, isFeedLoading);
|
||||||
|
}, [isInView, paging, isFeedLoading]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageLayout classes="tw-h-full tw-px-6" leftPanel={fetchLeftPanel()}>
|
<PageLayout classes="tw-h-full tw-px-6" leftPanel={fetchLeftPanel()}>
|
||||||
<div className="tw-mb-3">
|
<div className="tw-mb-3">
|
||||||
@ -161,14 +285,15 @@ const Users = ({ userData }: Props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{activeTab === 1 &&
|
{activeTab === 1 && getFeedTabData()}
|
||||||
|
{activeTab === 2 &&
|
||||||
getEntityData(
|
getEntityData(
|
||||||
getAssets(userData?.owns || []),
|
getAssets(userData?.owns || []),
|
||||||
`${
|
`${
|
||||||
userData?.displayName || userData?.name || 'User'
|
userData?.displayName || userData?.name || 'User'
|
||||||
} does not own anything yet`
|
} does not own anything yet`
|
||||||
)}
|
)}
|
||||||
{activeTab === 2 &&
|
{activeTab === 3 &&
|
||||||
getEntityData(
|
getEntityData(
|
||||||
getAssets(userData?.follows || []),
|
getAssets(userData?.follows || []),
|
||||||
`${
|
`${
|
||||||
|
@ -12,21 +12,37 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { AxiosError, AxiosResponse } from 'axios';
|
import { AxiosError, AxiosResponse } from 'axios';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { EntityThread } from 'Models';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
|
import AppState from '../../AppState';
|
||||||
|
import { getFeedsWithFilter, postFeedById } from '../../axiosAPIs/feedsAPI';
|
||||||
import { getUserByName } from '../../axiosAPIs/userAPI';
|
import { getUserByName } from '../../axiosAPIs/userAPI';
|
||||||
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
import PageContainerV1 from '../../components/containers/PageContainerV1';
|
||||||
import Loader from '../../components/Loader/Loader';
|
import Loader from '../../components/Loader/Loader';
|
||||||
import Users from '../../components/Users/Users.component';
|
import Users from '../../components/Users/Users.component';
|
||||||
|
import {
|
||||||
|
onConfirmText,
|
||||||
|
onErrorText,
|
||||||
|
onUpdatedConversastionError,
|
||||||
|
} from '../../constants/feed.constants';
|
||||||
|
import { FeedFilter } from '../../enums/mydata.enum';
|
||||||
import { User } from '../../generated/entity/teams/user';
|
import { User } from '../../generated/entity/teams/user';
|
||||||
|
import { Paging } from '../../generated/type/paging';
|
||||||
import jsonData from '../../jsons/en';
|
import jsonData from '../../jsons/en';
|
||||||
import { showErrorToast } from '../../utils/ToastUtils';
|
import { deletePost, getUpdatedThread } from '../../utils/FeedUtils';
|
||||||
|
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
||||||
|
|
||||||
const UserPage = () => {
|
const UserPage = () => {
|
||||||
const { username } = useParams<{ [key: string]: string }>();
|
const { username } = useParams<{ [key: string]: string }>();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
const [userData, setUserData] = useState<User>({} as User);
|
const [userData, setUserData] = useState<User>({} as User);
|
||||||
const [isError, setIsError] = useState(false);
|
const [isError, setIsError] = useState(false);
|
||||||
|
const [feedFilter, setFeedFilter] = useState<FeedFilter>(FeedFilter.ALL);
|
||||||
|
const [entityThread, setEntityThread] = useState<EntityThread[]>([]);
|
||||||
|
const [isFeedLoading, setIsFeedLoading] = useState<boolean>(false);
|
||||||
|
const [paging, setPaging] = useState<Paging>({} as Paging);
|
||||||
|
|
||||||
const fetchUserData = () => {
|
const fetchUserData = () => {
|
||||||
getUserByName(username, 'profile,roles,teams,follows,owns')
|
getUserByName(username, 'profile,roles,teams,follows,owns')
|
||||||
@ -63,16 +79,114 @@ const UserPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const feedFilterHandler = (filter: FeedFilter) => {
|
||||||
|
setFeedFilter(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFeedData = (filterType: FeedFilter, after?: string) => {
|
||||||
|
setIsFeedLoading(true);
|
||||||
|
const currentUserId = AppState.getCurrentUserDetails()?.id;
|
||||||
|
getFeedsWithFilter(currentUserId, filterType, after)
|
||||||
|
.then((res: AxiosResponse) => {
|
||||||
|
const { data, paging: pagingObj } = res.data;
|
||||||
|
setPaging(pagingObj);
|
||||||
|
|
||||||
|
setEntityThread((prevData) => [...prevData, ...data]);
|
||||||
|
})
|
||||||
|
.catch((err: AxiosError) => {
|
||||||
|
showErrorToast(
|
||||||
|
err,
|
||||||
|
jsonData['api-error-messages']['fetch-activity-feed-error']
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setIsFeedLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const postFeedHandler = (value: string, id: string) => {
|
||||||
|
const currentUser = AppState.userDetails?.name ?? AppState.users[0]?.name;
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
message: value,
|
||||||
|
from: currentUser,
|
||||||
|
};
|
||||||
|
postFeedById(id, data)
|
||||||
|
.then((res: AxiosResponse) => {
|
||||||
|
if (res.data) {
|
||||||
|
const { id, posts } = res.data;
|
||||||
|
setEntityThread((pre) => {
|
||||||
|
return pre.map((thread) => {
|
||||||
|
if (thread.id === id) {
|
||||||
|
return { ...res.data, posts: posts.slice(-3) };
|
||||||
|
} else {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err: AxiosError) => {
|
||||||
|
showErrorToast(err, jsonData['api-error-messages']['feed-post-error']);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deletePostHandler = (threadId: string, postId: string) => {
|
||||||
|
deletePost(threadId, postId)
|
||||||
|
.then(() => {
|
||||||
|
getUpdatedThread(threadId)
|
||||||
|
.then((data) => {
|
||||||
|
setEntityThread((pre) => {
|
||||||
|
return pre.map((thread) => {
|
||||||
|
if (thread.id === data.id) {
|
||||||
|
return {
|
||||||
|
...thread,
|
||||||
|
posts: data.posts.slice(-3),
|
||||||
|
postsCount: data.postsCount,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return thread;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message = error?.message;
|
||||||
|
showErrorToast(message ?? onUpdatedConversastionError);
|
||||||
|
});
|
||||||
|
showSuccessToast(onConfirmText);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
const message = error?.message;
|
||||||
|
showErrorToast(message ?? onErrorText);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchUserData();
|
fetchUserData();
|
||||||
}, [username]);
|
}, [username]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getFeedData(feedFilter);
|
||||||
|
setEntityThread([]);
|
||||||
|
}, [feedFilter]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageContainerV1 className="tw-pt-4">
|
<PageContainerV1 className="tw-pt-4">
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
) : !isError ? (
|
) : !isError ? (
|
||||||
<Users userData={userData} />
|
<Users
|
||||||
|
deletePostHandler={deletePostHandler}
|
||||||
|
feedData={entityThread || []}
|
||||||
|
feedFilter={feedFilter}
|
||||||
|
feedFilterHandler={feedFilterHandler}
|
||||||
|
fetchFeedHandler={getFeedData}
|
||||||
|
isFeedLoading={isFeedLoading}
|
||||||
|
paging={paging}
|
||||||
|
postFeedHandler={postFeedHandler}
|
||||||
|
userData={userData}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<ErrorPlaceholder />
|
<ErrorPlaceholder />
|
||||||
)}
|
)}
|
||||||
@ -80,4 +194,4 @@ const UserPage = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default UserPage;
|
export default observer(UserPage);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user