Fixes/08 03 2022 (#3273)

* Fixes: Misc issue fixes

* Fixed issues for adding Glossary terms as tags

* Fixed UI unit tests
This commit is contained in:
darth-coder00 2022-03-08 21:51:48 +05:30 committed by GitHub
parent 876ac24e44
commit bf079a019e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 491 additions and 200 deletions

View File

@ -162,25 +162,16 @@ const AddGlossary = ({
const fetchRightPanel = () => { const fetchRightPanel = () => {
return ( return (
<> <>
<h6 className="tw-heading tw-text-base">Configure Your Glossary</h6> <h6 className="tw-heading tw-text-base">Configure Glossary</h6>
<div className="tw-mb-5"> <div className="tw-mb-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do A Glossary is a controlled vocabulary used to define the concepts and
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad terminology in an organization. Glossaries can be specific to a
minim veniam, quis nostrud exercitation ullamco laboris nisi ut certain domain (for e.g., Business Glossary, Technical Glossary). In
aliquip ex ea commodo consequat. Duis aute irure dolor in the glossary, the standard terms and concepts can be defined along
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla with the synonyms, and related terms. Control can be established over
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in how and who can add the terms in the glossary.
culpa qui officia deserunt mollit anim id est laborum.
<br />
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</div> </div>
{/* {getDocButton('Read Webhook Doc', '', 'webhook-doc')} */} {/* {getDocButton('Read Glossary Doc', '', 'glossary-doc')} */}
</> </>
); );
}; };

View File

@ -249,25 +249,16 @@ const AddGlossaryTerm = ({
const fetchRightPanel = () => { const fetchRightPanel = () => {
return ( return (
<> <>
<h6 className="tw-heading tw-text-base">Configure Your Glossary</h6> <h6 className="tw-heading tw-text-base">Configure Glossary Term</h6>
<div className="tw-mb-5"> <div className="tw-mb-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do Every term in the glossary has a unique definition. Along with
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad defining the standard term for a concept, the synonyms as well as
minim veniam, quis nostrud exercitation ullamco laboris nisi ut related terms (for e.g., parent and child terms) can be specified.
aliquip ex ea commodo consequat. Duis aute irure dolor in References can be added to the assets related to the terms. New terms
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla can be added or updated to the Glossary. The glossary terms can be
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in reviewed by certain users, who can accept or reject the terms.
culpa qui officia deserunt mollit anim id est laborum.
<br />
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</div> </div>
{/* {getDocButton('Read Webhook Doc', '', 'webhook-doc')} */} {/* {getDocButton('Read Glossary Term Doc', '', 'glossary-term-doc')} */}
</> </>
); );
}; };

View File

@ -15,6 +15,7 @@ import { AxiosError, AxiosResponse } from 'axios';
import { LoadingState } from 'Models'; import { LoadingState } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom'; import { useHistory, useParams } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
addGlossaryTerm, addGlossaryTerm,
getGlossariesByName, getGlossariesByName,
@ -35,7 +36,8 @@ const AddGlossaryTermPage = () => {
useParams<{ [key: string]: string }>(); useParams<{ [key: string]: string }>();
const showToast = useToastContext(); const showToast = useToastContext();
const history = useHistory(); const history = useHistory();
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [status, setStatus] = useState<LoadingState>('initial'); const [status, setStatus] = useState<LoadingState>('initial');
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [glossaryData, setGlossaryData] = useState<Glossary>(); const [glossaryData, setGlossaryData] = useState<Glossary>();

View File

@ -439,23 +439,17 @@ const AddWebhook: FunctionComponent<AddWebhookProps> = ({
const fetchRightPanel = () => { const fetchRightPanel = () => {
return ( return (
<> <>
<h6 className="tw-heading tw-text-base">Configure Your Webhook</h6> <h6 className="tw-heading tw-text-base">Configure Webhooks</h6>
<div className="tw-mb-5"> <div className="tw-mb-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do OpenMetadata can be configured to automatically send out event
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad notifications to registered webhooks. Enter the webhook name, and an
minim veniam, quis nostrud exercitation ullamco laboris nisi ut Endpoint URL to receive the HTTP call back on. Use Event Filters to
aliquip ex ea commodo consequat. Duis aute irure dolor in only receive notifications based on events of interest, like when an
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla entity is created, updated, or deleted; and for the entities your
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in application is interested in. Add a description to help people
culpa qui officia deserunt mollit anim id est laborum. understand the purpose of the webhook and to keep track of the use
<br /> case. Use advanced configuration to set up a shared secret key to
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do verify the webhook events using HMAC signature.
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum.
</div> </div>
{getDocButton('Read Webhook Doc', '', 'webhook-doc')} {getDocButton('Read Webhook Doc', '', 'webhook-doc')}
</> </>

View File

@ -16,13 +16,13 @@ import { compare } from 'fast-json-patch';
import { EntityTags } from 'Models'; import { EntityTags } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getTeamDetailsPath } from '../../constants/constants'; import { getTeamDetailsPath } from '../../constants/constants';
import { EntityType } from '../../enums/entity.enum'; import { EntityType } from '../../enums/entity.enum';
import { Dashboard } from '../../generated/entity/data/dashboard'; import { Dashboard } from '../../generated/entity/data/dashboard';
import { Operation } from '../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../generated/entity/policies/accessControl/rule';
import { EntityReference, User } from '../../generated/entity/teams/user'; import { EntityReference, User } from '../../generated/entity/teams/user';
import { LabelType, State, TagLabel } from '../../generated/type/tagLabel'; import { LabelType, State, TagLabel } from '../../generated/type/tagLabel';
import { useAuth } from '../../hooks/authHooks';
import { import {
getCurrentUserId, getCurrentUserId,
getHtmlForNonAdminAction, getHtmlForNonAdminAction,
@ -92,7 +92,7 @@ const DashboardDetails = ({
createThread, createThread,
dashboardFQN, dashboardFQN,
}: DashboardDetailsProps) => { }: DashboardDetailsProps) => {
const { isAuthDisabled } = useAuth(); const { isAuthDisabled } = useAuthContext();
const [isEdit, setIsEdit] = useState(false); const [isEdit, setIsEdit] = useState(false);
const [followersCount, setFollowersCount] = useState(0); const [followersCount, setFollowersCount] = useState(0);
const [isFollowing, setIsFollowing] = useState(false); const [isFollowing, setIsFollowing] = useState(false);
@ -245,22 +245,9 @@ const DashboardDetails = ({
} }
}; };
const onTagUpdate = (selectedTags?: Array<string>) => { const onTagUpdate = (selectedTags?: Array<EntityTags>) => {
if (selectedTags) { if (selectedTags) {
const prevTags = const updatedTags = [...(tier ? [tier] : []), ...selectedTags];
dashboardDetails?.tags?.filter((tag) =>
selectedTags.includes(tag?.tagFQN as string)
) || [];
const newTags = selectedTags
.filter((tag) => {
return !prevTags?.map((prevTag) => prevTag.tagFQN).includes(tag);
})
.map((tag) => ({
labelType: LabelType.Manual,
state: State.Confirmed,
tagFQN: tag,
}));
const updatedTags = [...prevTags, ...newTags];
const updatedDashboard = { ...dashboardDetails, tags: updatedTags }; const updatedDashboard = { ...dashboardDetails, tags: updatedTags };
tagUpdateHandler(updatedDashboard); tagUpdateHandler(updatedDashboard);
} }
@ -304,7 +291,10 @@ const DashboardDetails = ({
} }
}; };
const handleChartTagSelection = (selectedTags?: Array<EntityTags>) => { const handleChartTagSelection = (
selectedTags?: Array<EntityTags>,
allTags?: Array<string>
) => {
if (selectedTags && editChartTags) { if (selectedTags && editChartTags) {
const prevTags = editChartTags.chart.tags?.filter((tag) => const prevTags = editChartTags.chart.tags?.filter((tag) =>
selectedTags.some((selectedTag) => selectedTag.tagFQN === tag.tagFQN) selectedTags.some((selectedTag) => selectedTag.tagFQN === tag.tagFQN)
@ -319,6 +309,7 @@ const DashboardDetails = ({
.map((tag) => ({ .map((tag) => ({
labelType: 'Manual', labelType: 'Manual',
state: 'Confirmed', state: 'Confirmed',
source: (allTags || []).includes(tag.tagFQN) ? 'Tag' : 'Glossary',
tagFQN: tag.tagFQN, tagFQN: tag.tagFQN,
})); }));
@ -554,7 +545,7 @@ const DashboardDetails = ({
handleChartTagSelection(); handleChartTagSelection();
}} }}
onSelectionChange={(tags) => { onSelectionChange={(tags) => {
handleChartTagSelection(tags); handleChartTagSelection(tags, tagList);
}}> }}>
{chart.tags?.length ? ( {chart.tags?.length ? (
<button <button

View File

@ -20,6 +20,18 @@ import { EntityLineage } from '../../generated/type/entityLineage';
import { TagLabel } from '../../generated/type/tagLabel'; import { TagLabel } from '../../generated/type/tagLabel';
import DashboardDetails from './DashboardDetails.component'; import DashboardDetails from './DashboardDetails.component';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockUserTeam = [ const mockUserTeam = [
{ {
description: 'description', description: 'description',

View File

@ -15,6 +15,7 @@ import classNames from 'classnames';
import { isEqual, isNil, isUndefined } from 'lodash'; import { isEqual, isNil, isUndefined } from 'lodash';
import { ColumnJoins, EntityTags, ExtraInfo } from 'Models'; import { ColumnJoins, EntityTags, ExtraInfo } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getTeamDetailsPath, ROUTES } from '../../constants/constants'; import { getTeamDetailsPath, ROUTES } from '../../constants/constants';
import { CSMode } from '../../enums/codemirror.enum'; import { CSMode } from '../../enums/codemirror.enum';
import { EntityType } from '../../enums/entity.enum'; import { EntityType } from '../../enums/entity.enum';
@ -26,7 +27,6 @@ import {
} from '../../generated/entity/data/table'; } from '../../generated/entity/data/table';
import { User } from '../../generated/entity/teams/user'; import { User } from '../../generated/entity/teams/user';
import { LabelType, State } from '../../generated/type/tagLabel'; import { LabelType, State } from '../../generated/type/tagLabel';
import { useAuth } from '../../hooks/authHooks';
import { import {
getCurrentUserId, getCurrentUserId,
getPartialNameFromFQN, getPartialNameFromFQN,
@ -118,7 +118,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
qualityTestFormHandler, qualityTestFormHandler,
selectedColumn, selectedColumn,
}: DatasetDetailsProps) => { }: DatasetDetailsProps) => {
const { isAuthDisabled } = useAuth(); const { isAuthDisabled } = useAuthContext();
const [isEdit, setIsEdit] = useState(false); const [isEdit, setIsEdit] = useState(false);
const [followersCount, setFollowersCount] = useState(0); const [followersCount, setFollowersCount] = useState(0);
const [isFollowing, setIsFollowing] = useState(false); const [isFollowing, setIsFollowing] = useState(false);

View File

@ -27,6 +27,18 @@ import { DatasetTestModeType } from '../../interface/dataQuality.interface';
import DatasetDetails from './DatasetDetails.component'; import DatasetDetails from './DatasetDetails.component';
import { DatasetOwner } from './DatasetDetails.interface'; import { DatasetOwner } from './DatasetDetails.interface';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockUserTeam = [ const mockUserTeam = [
{ {
description: 'description', description: 'description',

View File

@ -36,6 +36,7 @@ import ReactFlow, {
ReactFlowProvider, ReactFlowProvider,
removeElements, removeElements,
} from 'react-flow-renderer'; } from 'react-flow-renderer';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getTableDetails } from '../../axiosAPIs/tableAPI'; import { getTableDetails } from '../../axiosAPIs/tableAPI';
import { Column } from '../../generated/entity/data/table'; import { Column } from '../../generated/entity/data/table';
import { Operation } from '../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../generated/entity/policies/accessControl/rule';
@ -91,7 +92,8 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
entityLineageHandler, entityLineageHandler,
}: EntityLineageProp) => { }: EntityLineageProp) => {
const showToast = useToastContext(); const showToast = useToastContext();
const { userPermissions, isAuthDisabled, isAdminUser } = useAuth(); const { userPermissions, isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const reactFlowWrapper = useRef<HTMLDivElement>(null); const reactFlowWrapper = useRef<HTMLDivElement>(null);
const [lineageData, setLineageData] = useState<EntityLineage>(entityLineage); const [lineageData, setLineageData] = useState<EntityLineage>(entityLineage);
const [reactFlowInstance, setReactFlowInstance] = useState<OnLoadParams>(); const [reactFlowInstance, setReactFlowInstance] = useState<OnLoadParams>();

View File

@ -203,6 +203,7 @@ const EntityTable = ({
.map((tag) => ({ .map((tag) => ({
labelType: LabelType.Manual, labelType: LabelType.Manual,
state: State.Confirmed, state: State.Confirmed,
source: allTags.includes(tag) ? 'Tag' : 'Glossary',
tagFQN: tag, tagFQN: tag,
})); }));
const updatedTags = [...(prevTags as TagLabel[]), ...newTags]; const updatedTags = [...(prevTags as TagLabel[]), ...newTags];

View File

@ -24,6 +24,18 @@ jest.mock('react-router-dom', () => ({
.mockImplementation(() => ({ search: '', pathname: '/explore' })), .mockImplementation(() => ({ search: '', pathname: '/explore' })),
})); }));
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../../utils/FilterUtils', () => ({ jest.mock('../../utils/FilterUtils', () => ({
getFilterString: jest.fn().mockImplementation(() => 'user.address'), getFilterString: jest.fn().mockImplementation(() => 'user.address'),
getFilterCount: jest.fn().mockImplementation(() => 10), getFilterCount: jest.fn().mockImplementation(() => 10),

View File

@ -2,6 +2,7 @@ import classNames from 'classnames';
import { isNil } from 'lodash'; import { isNil } from 'lodash';
import React, { FunctionComponent } from 'react'; import React, { FunctionComponent } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { ROUTES, TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants'; import { ROUTES, TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
import { Button } from '../buttons/Button/Button'; import { Button } from '../buttons/Button/Button';
@ -16,7 +17,8 @@ const Glossary: FunctionComponent<GlossaryProps> = ({
paging, paging,
onPageChange, onPageChange,
}: GlossaryProps) => { }: GlossaryProps) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const history = useHistory(); const history = useHistory();
const onAddGlossary = () => { const onAddGlossary = () => {

View File

@ -17,6 +17,7 @@ import { GlossaryTermAssets, LoadingState } from 'Models';
import RcTree from 'rc-tree'; import RcTree from 'rc-tree';
import { DataNode, EventDataNode } from 'rc-tree/lib/interface'; import { DataNode, EventDataNode } from 'rc-tree/lib/interface';
import React, { useEffect, useRef, useState } from 'react'; import React, { useEffect, useRef, useState } from 'react';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants'; import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
import { Glossary } from '../../generated/entity/data/glossary'; import { Glossary } from '../../generated/entity/data/glossary';
import { GlossaryTerm } from '../../generated/entity/data/glossaryTerm'; import { GlossaryTerm } from '../../generated/entity/data/glossaryTerm';
@ -96,7 +97,8 @@ const GlossaryV1 = ({
onAssetPaginate, onAssetPaginate,
}: // handlePathChange, }: // handlePathChange,
Props) => { Props) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const treeRef = useRef<RcTree<DataNode>>(null); const treeRef = useRef<RcTree<DataNode>>(null);
const [treeData, setTreeData] = useState<DataNode[]>([]); const [treeData, setTreeData] = useState<DataNode[]>([]);
const [breadcrumb, setBreadcrumb] = useState< const [breadcrumb, setBreadcrumb] = useState<

View File

@ -15,6 +15,7 @@ import classNames from 'classnames';
import cronstrue from 'cronstrue'; import cronstrue from 'cronstrue';
import { capitalize, isNil, lowerCase } from 'lodash'; import { capitalize, isNil, lowerCase } from 'lodash';
import React, { Fragment, useCallback, useState } from 'react'; import React, { Fragment, useCallback, useState } from 'react';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants'; import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
import { import {
AirflowPipeline, AirflowPipeline,
@ -48,7 +49,8 @@ const Ingestion: React.FC<Props> = ({
paging, paging,
pagingHandler, pagingHandler,
}: Props) => { }: Props) => {
const { isAdminUser, isAuthDisabled } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const showToast = useToastContext(); const showToast = useToastContext();
const [searchText, setSearchText] = useState(''); const [searchText, setSearchText] = useState('');
const [currTriggerId, setCurrTriggerId] = useState({ id: '', state: '' }); const [currTriggerId, setCurrTriggerId] = useState({ id: '', state: '' });

View File

@ -24,6 +24,18 @@ import { AirflowPipeline } from '../../generated/operations/pipelines/airflowPip
import Ingestion from './Ingestion.component'; import Ingestion from './Ingestion.component';
import { mockIngestionWorkFlow } from './Ingestion.mock'; import { mockIngestionWorkFlow } from './Ingestion.mock';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockPaging = { const mockPaging = {
after: 'after', after: 'after',
before: 'befor', before: 'befor',

View File

@ -18,6 +18,7 @@ import { observer } from 'mobx-react';
import { TableDetail } from 'Models'; import { TableDetail } from 'Models';
import React, { FunctionComponent, useEffect, useState } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import appState from '../../AppState'; import appState from '../../AppState';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getCategory } from '../../axiosAPIs/tagAPI'; import { getCategory } from '../../axiosAPIs/tagAPI';
import { Operation } from '../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../generated/entity/policies/accessControl/rule';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
@ -48,7 +49,8 @@ const ManageTab: FunctionComponent<Props> = ({
onSave, onSave,
hasEditAccess, hasEditAccess,
}: Props) => { }: Props) => {
const { userPermissions, isAuthDisabled } = useAuth(); const { userPermissions } = useAuth();
const { isAuthDisabled } = useAuthContext();
const getOwnerList = () => { const getOwnerList = () => {
const user = !isEmpty(appState.userDetails) const user = !isEmpty(appState.userDetails)
? appState.userDetails ? appState.userDetails

View File

@ -21,6 +21,18 @@ import {
import React from 'react'; import React from 'react';
import ManageTab from './ManageTab.component'; import ManageTab from './ManageTab.component';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockTierData = { const mockTierData = {
children: [ children: [
{ {

View File

@ -16,6 +16,18 @@ import React from 'react';
import { MemoryRouter } from 'react-router'; import { MemoryRouter } from 'react-router';
import MyAssetStats from './MyAssetStats.component'; import MyAssetStats from './MyAssetStats.component';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
describe('Test MyDataHeader Component', () => { describe('Test MyDataHeader Component', () => {
it('Component should render', () => { it('Component should render', () => {
const { container } = render( const { container } = render(

View File

@ -27,6 +27,18 @@ import { User } from '../../generated/entity/teams/user';
import { formatDataResponse } from '../../utils/APIUtils'; import { formatDataResponse } from '../../utils/APIUtils';
import MyDataPage from './MyData.component'; import MyDataPage from './MyData.component';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockData = { const mockData = {
data: { data: {
took: 50, took: 50,

View File

@ -17,13 +17,13 @@ import { isNil } from 'lodash';
import { EntityFieldThreads, EntityTags } from 'Models'; import { EntityFieldThreads, EntityTags } from 'Models';
import React, { Fragment, useEffect, useState } from 'react'; import React, { Fragment, useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getTeamDetailsPath } from '../../constants/constants'; import { getTeamDetailsPath } from '../../constants/constants';
import { EntityType } from '../../enums/entity.enum'; import { EntityType } from '../../enums/entity.enum';
import { Pipeline, Task } from '../../generated/entity/data/pipeline'; import { Pipeline, Task } from '../../generated/entity/data/pipeline';
import { Operation } from '../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../generated/entity/policies/accessControl/rule';
import { EntityReference, User } from '../../generated/entity/teams/user'; import { EntityReference, User } from '../../generated/entity/teams/user';
import { LabelType, State } from '../../generated/type/tagLabel'; import { LabelType, State } from '../../generated/type/tagLabel';
import { useAuth } from '../../hooks/authHooks';
import { import {
getCurrentUserId, getCurrentUserId,
getHtmlForNonAdminAction, getHtmlForNonAdminAction,
@ -93,7 +93,7 @@ const PipelineDetails = ({
createThread, createThread,
pipelineFQN, pipelineFQN,
}: PipeLineDetailsProp) => { }: PipeLineDetailsProp) => {
const { isAuthDisabled } = useAuth(); const { isAuthDisabled } = useAuthContext();
const [isEdit, setIsEdit] = useState(false); const [isEdit, setIsEdit] = useState(false);
const [followersCount, setFollowersCount] = useState(0); const [followersCount, setFollowersCount] = useState(0);
const [isFollowing, setIsFollowing] = useState(false); const [isFollowing, setIsFollowing] = useState(false);
@ -247,22 +247,9 @@ const PipelineDetails = ({
} }
}; };
const onTagUpdate = (selectedTags?: Array<string>) => { const onTagUpdate = (selectedTags?: Array<EntityTags>) => {
if (selectedTags) { if (selectedTags) {
const prevTags = const updatedTags = [...(tier ? [tier] : []), ...selectedTags];
pipelineDetails?.tags?.filter((tag) =>
selectedTags.includes(tag?.tagFQN as string)
) || [];
const newTags = selectedTags
.filter((tag) => {
return !prevTags?.map((prevTag) => prevTag.tagFQN).includes(tag);
})
.map((tag) => ({
labelType: LabelType.Manual,
state: State.Confirmed,
tagFQN: tag,
}));
const updatedTags = [...prevTags, ...newTags];
const updatedPipeline = { ...pipelineDetails, tags: updatedTags }; const updatedPipeline = { ...pipelineDetails, tags: updatedTags };
tagUpdateHandler(updatedPipeline); tagUpdateHandler(updatedPipeline);
} }

View File

@ -14,6 +14,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { FC, Fragment } from 'react'; import React, { FC, Fragment } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants'; import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
import { excludedMetrics } from '../../constants/profiler.constant'; import { excludedMetrics } from '../../constants/profiler.constant';
import { Table, TableProfile } from '../../generated/entity/data/table'; import { Table, TableProfile } from '../../generated/entity/data/table';
@ -68,7 +69,8 @@ const TableProfiler: FC<Props> = ({
columns, columns,
qualityTestFormHandler, qualityTestFormHandler,
}) => { }) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const modifiedData = tableProfiles?.map((tableProfile: TableProfile) => ({ const modifiedData = tableProfiles?.map((tableProfile: TableProfile) => ({
rows: tableProfile.rowCount, rows: tableProfile.rowCount,
profileDate: tableProfile.profileDate, profileDate: tableProfile.profileDate,

View File

@ -13,12 +13,12 @@
import { EntityTags } from 'Models'; import { EntityTags } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { getTeamDetailsPath } from '../../constants/constants'; import { getTeamDetailsPath } from '../../constants/constants';
import { EntityType } from '../../enums/entity.enum'; import { EntityType } from '../../enums/entity.enum';
import { Topic } from '../../generated/entity/data/topic'; import { Topic } from '../../generated/entity/data/topic';
import { EntityReference, User } from '../../generated/entity/teams/user'; import { EntityReference, User } from '../../generated/entity/teams/user';
import { LabelType, State } from '../../generated/type/tagLabel'; import { LabelType, State } from '../../generated/type/tagLabel';
import { useAuth } from '../../hooks/authHooks';
import { getCurrentUserId, getUserTeams } from '../../utils/CommonUtils'; import { getCurrentUserId, getUserTeams } from '../../utils/CommonUtils';
import { getEntityFeedLink } from '../../utils/EntityUtils'; import { getEntityFeedLink } from '../../utils/EntityUtils';
import { getDefaultValue } from '../../utils/FeedElementUtils'; import { getDefaultValue } from '../../utils/FeedElementUtils';
@ -71,7 +71,7 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
createThread, createThread,
topicFQN, topicFQN,
}: TopicDetailsProps) => { }: TopicDetailsProps) => {
const { isAuthDisabled } = useAuth(); const { isAuthDisabled } = useAuthContext();
const [isEdit, setIsEdit] = useState(false); const [isEdit, setIsEdit] = useState(false);
const [followersCount, setFollowersCount] = useState(0); const [followersCount, setFollowersCount] = useState(0);
const [isFollowing, setIsFollowing] = useState(false); const [isFollowing, setIsFollowing] = useState(false);
@ -274,22 +274,9 @@ const TopicDetails: React.FC<TopicDetailsProps> = ({
); );
}; };
const onTagUpdate = (selectedTags?: Array<string>) => { const onTagUpdate = (selectedTags?: Array<EntityTags>) => {
if (selectedTags) { if (selectedTags) {
const prevTags = const updatedTags = [...(tier ? [tier] : []), ...selectedTags];
topicDetails?.tags?.filter((tag) =>
selectedTags.includes(tag?.tagFQN as string)
) || [];
const newTags = selectedTags
.filter((tag) => {
return !prevTags?.map((prevTag) => prevTag.tagFQN).includes(tag);
})
.map((tag) => ({
labelType: LabelType.Manual,
state: State.Confirmed,
tagFQN: tag,
}));
const updatedTags = [...prevTags, ...newTags];
const updatedTopic = { ...topicDetails, tags: updatedTags }; const updatedTopic = { ...topicDetails, tags: updatedTags };
tagUpdateHandler(updatedTopic); tagUpdateHandler(updatedTopic);
} }

View File

@ -12,12 +12,14 @@
*/ */
import { Paging } from 'Models'; import { Paging } from 'Models';
import { Webhook } from '../../generated/entity/events/webhook'; import { Status, Webhook } from '../../generated/entity/events/webhook';
export interface WebhooksProps { export interface WebhooksProps {
data: Array<Webhook>; data: Array<Webhook>;
paging: Paging; paging: Paging;
selectedStatus: Status[];
onAddWebhook: () => void; onAddWebhook: () => void;
onClickWebhook: (name: string) => void; onClickWebhook: (name: string) => void;
onPageChange: (type: string) => void; onPageChange: (type: string) => void;
onStatusFilter: (status: Status[]) => void;
} }

View File

@ -12,10 +12,10 @@
*/ */
import classNames from 'classnames'; import classNames from 'classnames';
import { isNil, startCase } from 'lodash'; import { cloneDeep, isNil, startCase } from 'lodash';
import React, { FunctionComponent } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants'; import { TITLE_FOR_NON_ADMIN_ACTION } from '../../constants/constants';
import { Status } from '../../generated/entity/events/webhook'; import { Status, Webhook } from '../../generated/entity/events/webhook';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
import { getDocButton } from '../../utils/CommonUtils'; import { getDocButton } from '../../utils/CommonUtils';
import { Button } from '../buttons/Button/Button'; import { Button } from '../buttons/Button/Button';
@ -52,11 +52,34 @@ const statuses = [
const Webhooks: FunctionComponent<WebhooksProps> = ({ const Webhooks: FunctionComponent<WebhooksProps> = ({
data = [], data = [],
paging, paging,
selectedStatus = [],
onAddWebhook, onAddWebhook,
onClickWebhook, onClickWebhook,
onPageChange, onPageChange,
onStatusFilter,
}: WebhooksProps) => { }: WebhooksProps) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAuthDisabled, isAdminUser } = useAuth();
const [filteredData, setFilteredData] = useState<Array<Webhook>>(data);
const getFilteredWebhooks = () => {
return selectedStatus.length
? data.filter(
(item) => item.status && selectedStatus.includes(item.status)
)
: data;
};
const handleStatusSelection = (status: Status) => {
const arrStatus = cloneDeep(selectedStatus);
if (arrStatus.includes(status)) {
const index = arrStatus.indexOf(status);
arrStatus.splice(index, 1);
} else {
arrStatus.push(status);
}
onStatusFilter(arrStatus);
};
const fetchLeftPanel = () => { const fetchLeftPanel = () => {
return ( return (
@ -78,9 +101,13 @@ const Webhooks: FunctionComponent<WebhooksProps> = ({
key={index}> key={index}>
<div className="tw-flex"> <div className="tw-flex">
<input <input
checked={selectedStatus.includes(statusType.value)}
className="tw-mr-1 custom-checkbox" className="tw-mr-1 custom-checkbox"
data-testid="checkbox" data-testid="checkbox"
type="checkbox" type="checkbox"
onChange={() => {
handleStatusSelection(statusType.value);
}}
/> />
<div <div
className="tw-flex tw-items-center filters-title tw-truncate custom-checkbox-label" className="tw-flex tw-items-center filters-title tw-truncate custom-checkbox-label"
@ -99,53 +126,20 @@ const Webhooks: FunctionComponent<WebhooksProps> = ({
return ( return (
<> <>
<div className="tw-mb-5 tw-mt-11"> <div className="tw-mb-5 tw-mt-11">
Webhook allow external services to be notified when certain events The webhook allows external services to be notified of the metadata
happen. When the special event happen, well send a POST request to change events happening in your organization through APIs. Register
each of the URLs you provide. Learn more in our Webhooks Guide . callback URLs with webhook integration to receive metadata event
notifications. You can add, list, update, and delete webhooks.
</div> </div>
{getDocButton('Webhooks Guide', '', 'webhook-doc')} {getDocButton('Webhooks Guide', '', 'webhook-doc')}
</> </>
); );
}; };
return data.length ? ( const fetchErrorPlaceHolder = (message: string) => {
<PageLayout leftPanel={fetchLeftPanel()} rightPanel={fetchRightPanel()}> return (
<div className="">
<div className="tw-flex tw-justify-end tw-items-center">
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
})}
data-testid="add-webhook-button"
size="small"
theme="primary"
variant="contained"
onClick={onAddWebhook}>
Add Webhook
</Button>
</NonAdminAction>
</div>
{data.map((webhook, index) => (
<div className="tw-mb-3" key={index}>
<WebhookDataCard
description={webhook.description}
endpoint={webhook.endpoint}
name={webhook.name}
status={webhook.status}
onClick={onClickWebhook}
/>
</div>
))}
{Boolean(!isNil(paging.after) || !isNil(paging.before)) && (
<NextPrevious paging={paging} pagingHandler={onPageChange} />
)}
</div>
</PageLayout>
) : (
<PageLayout>
<ErrorPlaceHolder> <ErrorPlaceHolder>
<p className="tw-text-center">No webhooks found</p> <p className="tw-text-center">{message}</p>
<p className="tw-text-center"> <p className="tw-text-center">
<NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}> <NonAdminAction position="bottom" title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button <Button
@ -157,12 +151,62 @@ const Webhooks: FunctionComponent<WebhooksProps> = ({
theme="primary" theme="primary"
variant="contained" variant="contained"
onClick={onAddWebhook}> onClick={onAddWebhook}>
Add New Webhook Add Webhook
</Button> </Button>
</NonAdminAction> </NonAdminAction>
</p> </p>
</ErrorPlaceHolder> </ErrorPlaceHolder>
);
};
useEffect(() => {
setFilteredData(getFilteredWebhooks());
}, [data, selectedStatus]);
return data.length ? (
<PageLayout leftPanel={fetchLeftPanel()} rightPanel={fetchRightPanel()}>
<div>
{filteredData.length ? (
<>
<div className="tw-flex tw-justify-end tw-items-center">
<NonAdminAction
position="bottom"
title={TITLE_FOR_NON_ADMIN_ACTION}>
<Button
className={classNames('tw-h-8 tw-rounded tw-mb-3', {
'tw-opacity-40': !isAdminUser && !isAuthDisabled,
})}
data-testid="add-webhook-button"
size="small"
theme="primary"
variant="contained"
onClick={onAddWebhook}>
Add Webhook
</Button>
</NonAdminAction>
</div>
{filteredData.map((webhook, index) => (
<div className="tw-mb-3" key={index}>
<WebhookDataCard
description={webhook.description}
endpoint={webhook.endpoint}
name={webhook.name}
status={webhook.status}
onClick={onClickWebhook}
/>
</div>
))}
{Boolean(!isNil(paging.after) || !isNil(paging.before)) && (
<NextPrevious paging={paging} pagingHandler={onPageChange} />
)}
</>
) : (
fetchErrorPlaceHolder('No webhooks found for applied filters')
)}
</div>
</PageLayout> </PageLayout>
) : (
<PageLayout>{fetchErrorPlaceHolder('No webhooks found')}</PageLayout>
); );
}; };

View File

@ -18,7 +18,7 @@ import React, { Fragment, useEffect, useState } from 'react';
import { FOLLOWERS_VIEW_CAP, LIST_SIZE } from '../../../constants/constants'; import { FOLLOWERS_VIEW_CAP, LIST_SIZE } from '../../../constants/constants';
import { Operation } from '../../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../../generated/entity/policies/accessControl/rule';
import { User } from '../../../generated/entity/teams/user'; import { User } from '../../../generated/entity/teams/user';
import { TagLabel } from '../../../generated/type/tagLabel'; import { LabelType, State, TagLabel } from '../../../generated/type/tagLabel';
import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils'; import { getHtmlForNonAdminAction } from '../../../utils/CommonUtils';
import { getEntityFeedLink, getInfoElements } from '../../../utils/EntityUtils'; import { getEntityFeedLink, getInfoElements } from '../../../utils/EntityUtils';
import SVGIcons, { Icons } from '../../../utils/SvgUtils'; import SVGIcons, { Icons } from '../../../utils/SvgUtils';
@ -53,7 +53,7 @@ type Props = {
entityFieldThreads?: EntityFieldThreads[]; entityFieldThreads?: EntityFieldThreads[];
onThreadLinkSelect?: (value: string) => void; onThreadLinkSelect?: (value: string) => void;
followHandler?: () => void; followHandler?: () => void;
tagsHandler?: (selectedTags?: Array<string>) => void; tagsHandler?: (selectedTags?: Array<EntityTags>) => void;
versionHandler?: () => void; versionHandler?: () => void;
}; };
@ -85,13 +85,34 @@ const EntityPageInfo = ({
const [entityFollowers, setEntityFollowers] = const [entityFollowers, setEntityFollowers] =
useState<Array<User>>(followersList); useState<Array<User>>(followersList);
const [isViewMore, setIsViewMore] = useState<boolean>(false); const [isViewMore, setIsViewMore] = useState<boolean>(false);
const handleTagSelection = (selectedTags?: Array<EntityTags>) => {
tagsHandler?.(selectedTags?.map((tag) => tag.tagFQN));
setIsEditable(false);
};
const [tagList, setTagList] = useState<Array<string>>([]); const [tagList, setTagList] = useState<Array<string>>([]);
const [isTagLoading, setIsTagLoading] = useState<boolean>(false); const [isTagLoading, setIsTagLoading] = useState<boolean>(false);
const handleTagSelection = (selectedTags?: Array<EntityTags>) => {
if (selectedTags) {
const prevTags =
tags?.filter((tag) =>
selectedTags
.map((selTag) => selTag.tagFQN)
.includes(tag?.tagFQN as string)
) || [];
const newTags = selectedTags
.filter((tag) => {
return !prevTags
?.map((prevTag) => prevTag.tagFQN)
.includes(tag.tagFQN);
})
.map((tag) => ({
labelType: LabelType.Manual,
state: State.Confirmed,
source: tagList.includes(tag.tagFQN) ? 'Tag' : 'Glossary',
tagFQN: tag.tagFQN,
}));
tagsHandler?.([...prevTags, ...newTags]);
}
setIsEditable(false);
};
const getSelectedTags = () => { const getSelectedTags = () => {
return tier?.tagFQN return tier?.tagFQN
? [ ? [

View File

@ -15,7 +15,7 @@ import { uniqueId } from 'lodash';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import React from 'react'; import React from 'react';
import AppState from '../../../AppState'; import AppState from '../../../AppState';
import { useAuth } from '../../../hooks/authHooks'; import { useAuthContext } from '../../../auth-provider/AuthProvider';
type Props = { type Props = {
type: 'error' | 'noData'; type: 'error' | 'noData';
@ -54,7 +54,7 @@ const stepsData = [
]; ];
const ErrorPlaceHolderES = ({ type, errorMessage, query = '' }: Props) => { const ErrorPlaceHolderES = ({ type, errorMessage, query = '' }: Props) => {
const { isAuthDisabled } = useAuth(); const { isAuthDisabled } = useAuthContext();
const getUserDisplayName = () => { const getUserDisplayName = () => {
return isAuthDisabled return isAuthDisabled
? AppState.users?.length > 0 ? AppState.users?.length > 0

View File

@ -27,6 +27,18 @@ jest.mock('../../../hooks/authHooks', () => ({
useAuth: jest.fn(() => mockAuth), useAuth: jest.fn(() => mockAuth),
})); }));
jest.mock('../../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../popover/PopOver', () => { jest.mock('../popover/PopOver', () => {
return jest return jest
.fn() .fn()

View File

@ -13,6 +13,7 @@
import { UserPermissions } from 'Models'; import { UserPermissions } from 'Models';
import React from 'react'; import React from 'react';
import { useAuthContext } from '../../../auth-provider/AuthProvider';
import { Operation } from '../../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../../generated/entity/policies/accessControl/rule';
import { useAuth } from '../../../hooks/authHooks'; import { useAuth } from '../../../hooks/authHooks';
import PopOver from '../popover/PopOver'; import PopOver from '../popover/PopOver';
@ -38,7 +39,8 @@ const NonAdminAction = ({
trigger = 'mouseenter', trigger = 'mouseenter',
permission, permission,
}: Props) => { }: Props) => {
const { isAuthDisabled, isAdminUser, userPermissions } = useAuth(); const { isAdminUser, userPermissions } = useAuth();
const { isAuthDisabled } = useAuthContext();
const handleCapturedEvent = ( const handleCapturedEvent = (
e: React.KeyboardEvent | React.MouseEvent e: React.KeyboardEvent | React.MouseEvent

View File

@ -40,6 +40,7 @@ const WebhookDataCardBody: FunctionComponent<Props> = ({
<span className="tw-ml-1">{startCase(status)}</span> <span className="tw-ml-1">{startCase(status)}</span>
</span> </span>
<span className="tw-mx-1.5 tw-inline-block tw-text-gray-400">|</span> <span className="tw-mx-1.5 tw-inline-block tw-text-gray-400">|</span>
<span className="tw-text-grey-muted">Url:&nbsp;</span>
<span>{endpoint}</span> <span>{endpoint}</span>
</div> </div>
<div className="description-text" data-testid="description-text"> <div className="description-text" data-testid="description-text">

View File

@ -14,12 +14,14 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
import SVGIcons from '../../utils/SvgUtils'; import SVGIcons from '../../utils/SvgUtils';
import { DropDownListItem, DropDownListProp } from './types'; import { DropDownListItem, DropDownListProp } from './types';
const AnchorDropDownList = ({ dropDownList, setIsOpen }: DropDownListProp) => { const AnchorDropDownList = ({ dropDownList, setIsOpen }: DropDownListProp) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
return ( return (
<> <>

View File

@ -12,6 +12,7 @@
*/ */
import React, { Fragment } from 'react'; import React, { Fragment } from 'react';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { useAuth } from '../../hooks/authHooks'; import { useAuth } from '../../hooks/authHooks';
import { DropDownListItem, DropDownListProp } from './types'; import { DropDownListItem, DropDownListProp } from './types';
@ -22,7 +23,8 @@ const CheckBoxDropDownList = ({
selectedItems, selectedItems,
disabledItems, disabledItems,
}: DropDownListProp) => { }: DropDownListProp) => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
return ( return (
<> <>

View File

@ -21,6 +21,18 @@ import React from 'react';
import { MemoryRouter } from 'react-router-dom'; import { MemoryRouter } from 'react-router-dom';
import DropDown from './DropDown'; import DropDown from './DropDown';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockDropDown = [ const mockDropDown = [
{ name: 'Test1', to: '/test1', disabled: false }, { name: 'Test1', to: '/test1', disabled: false },
{ name: 'Test2', to: '/test2', disabled: false }, { name: 'Test2', to: '/test2', disabled: false },

View File

@ -83,7 +83,7 @@ const DropDownList: FunctionComponent<DropDownListProp> = ({
key={index} key={index}
role="menuitem" role="menuitem"
onClick={(e) => !item.disabled && onSelect?.(e, item.value)}> onClick={(e) => !item.disabled && onSelect?.(e, item.value)}>
<p className="tw-truncate tw-w-52" title={item.name as string}> <p className="tw-truncate tw-w-80" title={item.name as string}>
{item.name} {item.name}
</p> </p>
</div> </div>

View File

@ -24,6 +24,18 @@ import {
} from '../../generated/entity/data/table'; } from '../../generated/entity/data/table';
import SchemaTable from './SchemaTable'; import SchemaTable from './SchemaTable';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => { jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>); return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
}); });

View File

@ -135,7 +135,7 @@ const TagsContainer: FunctionComponent<TagsContainerProps> = ({
}) })
.map((glossary) => { .map((glossary) => {
return { return {
name: glossary.name, name: glossary.fqdn,
value: glossary.fqdn, value: glossary.fqdn,
}; };
}); });

View File

@ -2,6 +2,7 @@ import { AxiosError } from 'axios';
import { LoadingState } from 'Models'; import { LoadingState } from 'Models';
import React, { FunctionComponent, useState } from 'react'; import React, { FunctionComponent, useState } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { addGlossaries } from '../../axiosAPIs/glossaryAPI'; import { addGlossaries } from '../../axiosAPIs/glossaryAPI';
import AddGlossary from '../../components/AddGlossary/AddGlossary.component'; import AddGlossary from '../../components/AddGlossary/AddGlossary.component';
import PageContainerV1 from '../../components/containers/PageContainerV1'; import PageContainerV1 from '../../components/containers/PageContainerV1';
@ -12,7 +13,8 @@ import useToastContext from '../../hooks/useToastContext';
import { getTagCategories, getTaglist } from '../../utils/TagsUtils'; import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
const AddGlossaryPage: FunctionComponent = () => { const AddGlossaryPage: FunctionComponent = () => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const history = useHistory(); const history = useHistory();
const showToast = useToastContext(); const showToast = useToastContext();
const [tagList, setTagList] = useState<Array<string>>([]); const [tagList, setTagList] = useState<Array<string>>([]);

View File

@ -15,6 +15,7 @@ import { AxiosError } from 'axios';
import { LoadingState } from 'Models'; import { LoadingState } from 'Models';
import React, { FunctionComponent, useState } from 'react'; import React, { FunctionComponent, useState } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { addWebhook } from '../../axiosAPIs/webhookAPI'; import { addWebhook } from '../../axiosAPIs/webhookAPI';
import AddWebhook from '../../components/AddWebhook/AddWebhook'; import AddWebhook from '../../components/AddWebhook/AddWebhook';
import PageContainerV1 from '../../components/containers/PageContainerV1'; import PageContainerV1 from '../../components/containers/PageContainerV1';
@ -25,7 +26,8 @@ import { useAuth } from '../../hooks/authHooks';
import useToastContext from '../../hooks/useToastContext'; import useToastContext from '../../hooks/useToastContext';
const AddWebhookPage: FunctionComponent = () => { const AddWebhookPage: FunctionComponent = () => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const history = useHistory(); const history = useHistory();
const showToast = useToastContext(); const showToast = useToastContext();
const [status, setStatus] = useState<LoadingState>('initial'); const [status, setStatus] = useState<LoadingState>('initial');
@ -51,7 +53,7 @@ const AddWebhookPage: FunctionComponent = () => {
.catch((err: AxiosError) => { .catch((err: AxiosError) => {
showToast({ showToast({
variant: 'error', variant: 'error',
body: err.message || 'Something went wrong!', body: err.response?.data?.message || 'Something went wrong!',
}); });
setStatus('initial'); setStatus('initial');
}); });

View File

@ -11,6 +11,18 @@ jest.mock('../../components/containers/PageContainerV1', () => {
)); ));
}); });
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../../components/AddWebhook/AddWebhook', () => { jest.mock('../../components/AddWebhook/AddWebhook', () => {
return jest.fn().mockImplementation(() => <div>AddWebhookComponent</div>); return jest.fn().mockImplementation(() => <div>AddWebhookComponent</div>);
}); });

View File

@ -159,7 +159,7 @@ const DashboardDetailsPage = () => {
const saveUpdatedDashboardData = ( const saveUpdatedDashboardData = (
updatedData: Dashboard updatedData: Dashboard
): Promise<AxiosResponse> => { ): Promise<AxiosResponse> => {
const jsonPatch = compare(DashboardDetails, updatedData); const jsonPatch = compare(dashboardDetails, updatedData);
return patchDashboardDetails( return patchDashboardDetails(
dashboardId, dashboardId,

View File

@ -15,6 +15,7 @@ import { AxiosError } from 'axios';
import { LoadingState } from 'Models'; import { LoadingState } from 'Models';
import React, { FunctionComponent, useEffect, useState } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import { useHistory, useParams } from 'react-router-dom'; import { useHistory, useParams } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
deleteWebhook, deleteWebhook,
getWebhookByName, getWebhookByName,
@ -32,7 +33,8 @@ import useToastContext from '../../hooks/useToastContext';
const EditWebhookPage: FunctionComponent = () => { const EditWebhookPage: FunctionComponent = () => {
const { webhookName } = useParams<{ [key: string]: string }>(); const { webhookName } = useParams<{ [key: string]: string }>();
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const history = useHistory(); const history = useHistory();
const showToast = useToastContext(); const showToast = useToastContext();
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
@ -49,7 +51,7 @@ const EditWebhookPage: FunctionComponent = () => {
.catch((err: AxiosError) => { .catch((err: AxiosError) => {
showToast({ showToast({
variant: 'error', variant: 'error',
body: err.message || 'Something went wrong!', body: err.response?.data?.message || 'Something went wrong!',
}); });
}) })
.finally(() => setIsLoading(false)); .finally(() => setIsLoading(false));
@ -77,7 +79,7 @@ const EditWebhookPage: FunctionComponent = () => {
.catch((err: AxiosError) => { .catch((err: AxiosError) => {
showToast({ showToast({
variant: 'error', variant: 'error',
body: err.message || 'Something went wrong!', body: err.response?.data?.message || 'Something went wrong!',
}); });
setStatus('initial'); setStatus('initial');
}); });
@ -93,7 +95,7 @@ const EditWebhookPage: FunctionComponent = () => {
.catch((err: AxiosError) => { .catch((err: AxiosError) => {
showToast({ showToast({
variant: 'error', variant: 'error',
body: err.message || 'Something went wrong!', body: err.response?.data?.message || 'Something went wrong!',
}); });
setDeleteStatus('initial'); setDeleteStatus('initial');
}); });

View File

@ -23,6 +23,7 @@ import {
} from 'Models'; } from 'Models';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
deleteGlossary, deleteGlossary,
deleteGlossaryTerm, deleteGlossaryTerm,
@ -37,7 +38,6 @@ import { getSuggestions, searchData } from '../../axiosAPIs/miscAPI';
import PageContainerV1 from '../../components/containers/PageContainerV1'; import PageContainerV1 from '../../components/containers/PageContainerV1';
import GlossaryV1 from '../../components/Glossary/GlossaryV1.component'; import GlossaryV1 from '../../components/Glossary/GlossaryV1.component';
import Loader from '../../components/Loader/Loader'; import Loader from '../../components/Loader/Loader';
import { WILD_CARD_CHAR } from '../../constants/char.constants';
import { import {
getAddGlossaryTermsPath, getAddGlossaryTermsPath,
PAGE_SIZE, PAGE_SIZE,
@ -63,7 +63,8 @@ const GlossaryPageV1 = () => {
// const { glossaryName, glossaryTermsFQN } = // const { glossaryName, glossaryTermsFQN } =
// useParams<{ [key: string]: string }>(); // useParams<{ [key: string]: string }>();
const { isAdminUser, isAuthDisabled } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const history = useHistory(); const history = useHistory();
const showToast = useToastContext(); const showToast = useToastContext();
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
@ -394,12 +395,13 @@ const GlossaryPageV1 = () => {
}; };
const fetchGlossaryTermAssets = (data: GlossaryTerm, forceReset = false) => { const fetchGlossaryTermAssets = (data: GlossaryTerm, forceReset = false) => {
if (data?.fullyQualifiedName) { if (data?.fullyQualifiedName || data?.name) {
const tagName = data?.fullyQualifiedName || data?.name; // Incase fqn is not fetched yet.
searchData( searchData(
WILD_CARD_CHAR, '',
forceReset ? 1 : assetData.currPage, forceReset ? 1 : assetData.currPage,
PAGE_SIZE, PAGE_SIZE,
`(tags:${data.fullyQualifiedName})`, `(tags:${tagName})`,
'', '',
'', '',
myDataSearchIndex myDataSearchIndex

View File

@ -17,6 +17,7 @@ import { isEmpty } from 'lodash';
import { Key } from 'rc-tree/lib/interface'; import { Key } from 'rc-tree/lib/interface';
import React, { FunctionComponent, useEffect, useState } from 'react'; import React, { FunctionComponent, useEffect, useState } from 'react';
import { useLocation, useParams } from 'react-router-dom'; import { useLocation, useParams } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
getGlossariesByName, getGlossariesByName,
getGlossaryTermByFQN, getGlossaryTermByFQN,
@ -36,7 +37,8 @@ import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
const GlossaryTermPage: FunctionComponent = () => { const GlossaryTermPage: FunctionComponent = () => {
const showToast = useToastContext(); const showToast = useToastContext();
const { isAdminUser, isAuthDisabled } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const { glossaryName, glossaryTermsFQN } = const { glossaryName, glossaryTermsFQN } =
useParams<{ [key: string]: string }>(); useParams<{ [key: string]: string }>();
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);

View File

@ -6,6 +6,18 @@ jest.mock('../../components/GlossaryTerms/GlossaryTerms.component', () => {
return jest.fn().mockReturnValue(<div>GlossaryTerms.component</div>); return jest.fn().mockReturnValue(<div>GlossaryTerms.component</div>);
}); });
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../../axiosAPIs/glossaryAPI', () => ({ jest.mock('../../axiosAPIs/glossaryAPI', () => ({
getGlossariesByName: jest.fn().mockImplementation(() => Promise.resolve()), getGlossariesByName: jest.fn().mockImplementation(() => Promise.resolve()),
getGlossaryTermsById: jest.fn().mockImplementation(() => Promise.resolve()), getGlossaryTermsById: jest.fn().mockImplementation(() => Promise.resolve()),

View File

@ -19,6 +19,7 @@ import { observer } from 'mobx-react';
import { FormErrorData } from 'Models'; import { FormErrorData } from 'Models';
import React, { Fragment, useEffect, useState } from 'react'; import React, { Fragment, useEffect, useState } from 'react';
import AppState from '../../AppState'; import AppState from '../../AppState';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
createRole, createRole,
getPolicy, getPolicy,
@ -66,7 +67,8 @@ const getActiveTabClass = (tab: number, currentTab: number) => {
const RolesPage = () => { const RolesPage = () => {
const showToast = useToastContext(); const showToast = useToastContext();
const [roles, setRoles] = useState<Array<Role>>([]); const [roles, setRoles] = useState<Array<Role>>([]);
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [currentRole, setCurrentRole] = useState<Role>(); const [currentRole, setCurrentRole] = useState<Role>();
const [currentPolicy, setCurrentPolicy] = useState<Policy>(); const [currentPolicy, setCurrentPolicy] = useState<Policy>();
const [error, setError] = useState<string>(''); const [error, setError] = useState<string>('');

View File

@ -32,6 +32,18 @@ jest.mock('../../axiosAPIs/rolesAPI', () => ({
updateRole: jest.fn(), updateRole: jest.fn(),
})); }));
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock( jest.mock(
'../../components/containers/PageLayout', '../../components/containers/PageLayout',
() => () =>

View File

@ -24,7 +24,7 @@ import {
pagingObject, pagingObject,
ROUTES, ROUTES,
} from '../../constants/constants'; } from '../../constants/constants';
import { Webhook } from '../../generated/entity/events/webhook'; import { Status, Webhook } from '../../generated/entity/events/webhook';
import useToastContext from '../../hooks/useToastContext'; import useToastContext from '../../hooks/useToastContext';
const WebhooksPage: FunctionComponent = () => { const WebhooksPage: FunctionComponent = () => {
@ -33,6 +33,7 @@ const WebhooksPage: FunctionComponent = () => {
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
const [paging, setPaging] = useState<Paging>(pagingObject); const [paging, setPaging] = useState<Paging>(pagingObject);
const [data, setData] = useState<Array<Webhook>>([]); const [data, setData] = useState<Array<Webhook>>([]);
const [selectedStatus, setSelectedStatus] = useState<Status[]>([]);
const fetchData = (paging?: string) => { const fetchData = (paging?: string) => {
setIsLoading(true); setIsLoading(true);
@ -64,6 +65,10 @@ const WebhooksPage: FunctionComponent = () => {
fetchData(pagingString); fetchData(pagingString);
}; };
const handleStatusFilter = (status: Status[]) => {
setSelectedStatus(status);
};
const handleAddWebhook = () => { const handleAddWebhook = () => {
history.push(ROUTES.ADD_WEBHOOK); history.push(ROUTES.ADD_WEBHOOK);
}; };
@ -82,9 +87,11 @@ const WebhooksPage: FunctionComponent = () => {
<Webhooks <Webhooks
data={data} data={data}
paging={paging} paging={paging}
selectedStatus={selectedStatus}
onAddWebhook={handleAddWebhook} onAddWebhook={handleAddWebhook}
onClickWebhook={handleClickWebhook} onClickWebhook={handleClickWebhook}
onPageChange={handlePageChange} onPageChange={handlePageChange}
onStatusFilter={handleStatusFilter}
/> />
) : ( ) : (
<Loader /> <Loader />

View File

@ -79,6 +79,18 @@ const mockTableData = {
paging: { after: 'ZMbpLOqQQsREk_7DmEOr', total: 12 }, paging: { after: 'ZMbpLOqQQsREk_7DmEOr', total: 12 },
}; };
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock( jest.mock(
'../../components/common/rich-text-editor/RichTextEditorPreviewer', '../../components/common/rich-text-editor/RichTextEditorPreviewer',
() => { () => {

View File

@ -23,6 +23,18 @@ import { MemoryRouter } from 'react-router-dom';
import { act } from 'react-test-renderer'; import { act } from 'react-test-renderer';
import ServicePage from './index'; import ServicePage from './index';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockData = { const mockData = {
description: '', description: '',
href: 'link', href: 'link',

View File

@ -25,6 +25,7 @@ import {
import React, { Fragment, FunctionComponent, useEffect, useState } from 'react'; import React, { Fragment, FunctionComponent, useEffect, useState } from 'react';
import { Link, useHistory, useParams } from 'react-router-dom'; import { Link, useHistory, useParams } from 'react-router-dom';
import AppState from '../../AppState'; import AppState from '../../AppState';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
addAirflowPipeline, addAirflowPipeline,
deleteAirflowPipelineById, deleteAirflowPipelineById,
@ -113,7 +114,8 @@ const ServicePage: FunctionComponent = () => {
const { serviceFQN, serviceType, serviceCategory, tab } = const { serviceFQN, serviceType, serviceCategory, tab } =
useParams() as Record<string, string>; useParams() as Record<string, string>;
const history = useHistory(); const history = useHistory();
const { isAdminUser, isAuthDisabled } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [serviceName, setServiceName] = useState( const [serviceName, setServiceName] = useState(
serviceCategory || getServiceCategoryFromType(serviceType) serviceCategory || getServiceCategoryFromType(serviceType)
); );

View File

@ -136,6 +136,18 @@ const mockPipelineService = {
}, },
}; };
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../../axiosAPIs/serviceAPI', () => ({ jest.mock('../../axiosAPIs/serviceAPI', () => ({
deleteService: jest.fn(), deleteService: jest.fn(),
getServiceDetails: jest getServiceDetails: jest

View File

@ -17,6 +17,7 @@ import { isNil } from 'lodash';
import { Paging, ServiceCollection, ServiceData, ServiceTypes } from 'Models'; import { Paging, ServiceCollection, ServiceData, ServiceTypes } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { addAirflowPipeline } from '../../axiosAPIs/airflowPipelineAPI'; import { addAirflowPipeline } from '../../axiosAPIs/airflowPipelineAPI';
import { import {
deleteService, deleteService,
@ -94,7 +95,8 @@ export type ApiData = {
const ServicesPage = () => { const ServicesPage = () => {
const showToast = useToastContext(); const showToast = useToastContext();
const { isAdminUser, isAuthDisabled } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false); const [isConfirmationModalOpen, setIsConfirmationModalOpen] = useState(false);
const [deleteSelection, setDeleteSelection] = useState({ const [deleteSelection, setDeleteSelection] = useState({

View File

@ -21,6 +21,18 @@ import {
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import TagsPage from '.'; import TagsPage from '.';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockTagsCategory = [ const mockTagsCategory = [
{ {
categoryType: 'Classification', categoryType: 'Classification',

View File

@ -17,6 +17,7 @@ import { isUndefined, toLower } from 'lodash';
import { EntityTags, FormErrorData } from 'Models'; import { EntityTags, FormErrorData } from 'Models';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
createTag, createTag,
createTagCategory, createTagCategory,
@ -56,7 +57,8 @@ import { getTagCategories, getTaglist } from '../../utils/TagsUtils';
import Form from './Form'; import Form from './Form';
// import { Tag, TagsCategory } from './tagsTypes'; // import { Tag, TagsCategory } from './tagsTypes';
const TagsPage = () => { const TagsPage = () => {
const { isAuthDisabled, isAdminUser } = useAuth(); const { isAdminUser } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [categories, setCategoreis] = useState<Array<TagCategory>>([]); const [categories, setCategoreis] = useState<Array<TagCategory>>([]);
const [currentCategory, setCurrentCategory] = useState<TagCategory>(); const [currentCategory, setCurrentCategory] = useState<TagCategory>();
const [isEditCategory, setIsEditCategory] = useState<boolean>(false); const [isEditCategory, setIsEditCategory] = useState<boolean>(false);

View File

@ -24,6 +24,18 @@ const mockItem = {
const mockRemove = jest.fn(); const mockRemove = jest.fn();
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
jest.mock('../../components/common/avatar/Avatar', () => { jest.mock('../../components/common/avatar/Avatar', () => {
return jest.fn().mockReturnValue(<p data-testid="avatar">Avatar</p>); return jest.fn().mockReturnValue(<p data-testid="avatar">Avatar</p>);
}); });

View File

@ -15,6 +15,7 @@ import classNames from 'classnames';
import { capitalize } from 'lodash'; import { capitalize } from 'lodash';
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import Avatar from '../../components/common/avatar/Avatar'; import Avatar from '../../components/common/avatar/Avatar';
import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction'; import NonAdminAction from '../../components/common/non-admin-action/NonAdminAction';
import { SearchIndex } from '../../enums/search.enum'; import { SearchIndex } from '../../enums/search.enum';
@ -49,7 +50,8 @@ const UserCard = ({
onSelect, onSelect,
onRemove, onRemove,
}: Props) => { }: Props) => {
const { isAuthDisabled, isAdminUser, userPermissions } = useAuth(); const { isAdminUser, userPermissions } = useAuth();
const { isAuthDisabled } = useAuthContext();
const getArrForPartialName = ( const getArrForPartialName = (
type: string type: string
): Array<'service' | 'database' | 'table' | 'column'> => { ): Array<'service' | 'database' | 'table' | 'column'> => {

View File

@ -20,6 +20,18 @@ import {
import React, { ReactNode } from 'react'; import React, { ReactNode } from 'react';
import TeamsPage from './index'; import TeamsPage from './index';
jest.mock('../../auth-provider/AuthProvider', () => {
return {
useAuthContext: jest.fn(() => ({
isAuthDisabled: false,
isAuthenticated: true,
isProtectedRoute: jest.fn().mockReturnValue(true),
isTourRoute: jest.fn().mockReturnValue(false),
onLogoutHandler: jest.fn(),
})),
};
});
const mockTeamsData = [ const mockTeamsData = [
{ {
description: '', description: '',

View File

@ -20,6 +20,7 @@ import { FormErrorData } from 'Models';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Link, useHistory, useParams } from 'react-router-dom'; import { Link, useHistory, useParams } from 'react-router-dom';
import AppState from '../../AppState'; import AppState from '../../AppState';
import { useAuthContext } from '../../auth-provider/AuthProvider';
import { import {
createTeam, createTeam,
getTeamByName, getTeamByName,
@ -57,7 +58,8 @@ import UserCard from './UserCard';
const TeamsPage = () => { const TeamsPage = () => {
const { team } = useParams() as Record<string, string>; const { team } = useParams() as Record<string, string>;
const history = useHistory(); const history = useHistory();
const { isAuthDisabled, isAdminUser, userPermissions } = useAuth(); const { isAdminUser, userPermissions } = useAuth();
const { isAuthDisabled } = useAuthContext();
const [teams, setTeams] = useState<Array<Team>>([]); const [teams, setTeams] = useState<Array<Team>>([]);
const [currentTeam, setCurrentTeam] = useState<Team>(); const [currentTeam, setCurrentTeam] = useState<Team>();
const [error, setError] = useState<string>(''); const [error, setError] = useState<string>('');

View File

@ -389,12 +389,16 @@ export const getSvgArrow = (isActive: boolean) => {
}; };
export const isValidUrl = (href: string) => { export const isValidUrl = (href: string) => {
const regex = new RegExp( if (!href) {
// eslint-disable-next-line no-useless-escape return false;
/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g }
); try {
const url = new URL(href);
return href.match(regex); return Boolean(url.href);
} catch {
return false;
}
}; };
export const getFields = (defaultFields: string, tabSpecificField: string) => { export const getFields = (defaultFields: string, tabSpecificField: string) => {

View File

@ -118,13 +118,13 @@ module.exports = {
'status-queued': statusQueued, 'status-queued': statusQueued,
// Ingestion statuses end // Ingestion statuses end
// Webhook statuses begin // Webhook statuses begin
notStarted: ideal, disabled: ideal,
started: success, active: success,
failed: error, failed: error,
awaitingRetry: success, awaitingRetry: success,
retryLimitReached: warning, retryLimitReached: warning,
'notStarted-lite': idealBG, 'disabled-lite': idealBG,
'started-lite': successBG, 'active-lite': successBG,
'failed-lite': errorBG, 'failed-lite': errorBG,
'awaitingRetry-lite': successBG, 'awaitingRetry-lite': successBG,
'retryLimitReached-lite': warningBG, 'retryLimitReached-lite': warningBG,