mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-26 06:53:37 +00:00
test(ui): unit tests for users tab and user profile icon component (#15053)
* unit test case of Users tab * unit test case of user profile icon component * added test case of userProfileIcon * code cleanup and add test case of user profile icon * minor fix * minor fix
This commit is contained in:
parent
dcc91a8f37
commit
d4ac43d0d5
@ -26,6 +26,7 @@ import {
|
||||
} from 'antd';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LIGHT_GREEN_COLOR } from '../../../constants/constants';
|
||||
import { Transi18next } from '../../../utils/CommonUtils';
|
||||
import { getRelativeTime } from '../../../utils/date-time/DateTimeUtils';
|
||||
import { getEntityName } from '../../../utils/EntityUtils';
|
||||
@ -50,7 +51,7 @@ const AppInstallVerifyCard = ({
|
||||
<Space className="p-t-lg">
|
||||
<AppLogo appName={appData?.fullyQualifiedName ?? ''} />
|
||||
<Divider dashed className="w-44 app-card-divider">
|
||||
<CheckCircleTwoTone twoToneColor="#4CAF50" />
|
||||
<CheckCircleTwoTone twoToneColor={LIGHT_GREEN_COLOR} />
|
||||
</Divider>
|
||||
<Avatar
|
||||
className="app-marketplace-avatar flex-center bg-white border"
|
||||
|
||||
@ -17,6 +17,7 @@ import { AxiosError } from 'axios';
|
||||
import { isEmpty, toString } from 'lodash';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LIGHT_GREEN_COLOR } from '../../../constants/constants';
|
||||
import { ERROR_PLACEHOLDER_TYPE } from '../../../enums/common.enum';
|
||||
import { WidgetWidths } from '../../../enums/CustomizablePage.enum';
|
||||
import { Document } from '../../../generated/entity/docStore/document';
|
||||
@ -88,7 +89,7 @@ function AddWidgetModal({
|
||||
<CheckOutlined
|
||||
className="m-l-xs"
|
||||
data-testid={`${widget.name}-check-icon`}
|
||||
style={{ color: '#4CAF50' }}
|
||||
style={{ color: LIGHT_GREEN_COLOR }}
|
||||
/>
|
||||
)}
|
||||
</Space>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { CheckOutlined } from '@ant-design/icons';
|
||||
import { Dropdown, Tooltip, Typography } from 'antd';
|
||||
import { Dropdown, Space, Tooltip, Typography } from 'antd';
|
||||
import { ItemType } from 'antd/lib/menu/hooks/useItems';
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, {
|
||||
@ -27,6 +27,7 @@ import { ReactComponent as DropDownIcon } from '../../../assets/svg/DropDown.svg
|
||||
import {
|
||||
getTeamAndUserDetailsPath,
|
||||
getUserPath,
|
||||
LIGHT_GREEN_COLOR,
|
||||
NO_DATA_PLACEHOLDER,
|
||||
TERM_ADMIN,
|
||||
TERM_USER,
|
||||
@ -111,6 +112,8 @@ export const UserProfileIcon = () => {
|
||||
useEffect(() => {
|
||||
if (profilePicture) {
|
||||
setIsImgUrlValid(true);
|
||||
} else {
|
||||
setIsImgUrlValid(false);
|
||||
}
|
||||
}, [profilePicture]);
|
||||
|
||||
@ -133,12 +136,19 @@ export const UserProfileIcon = () => {
|
||||
|
||||
const personaLabelRenderer = useCallback(
|
||||
(item: EntityReference) => (
|
||||
<span onClick={() => handleSelectedPersonaChange(item)}>
|
||||
<Space
|
||||
className="w-full"
|
||||
data-testid="persona-label"
|
||||
onClick={() => handleSelectedPersonaChange(item)}>
|
||||
{getEntityName(item)}{' '}
|
||||
{selectedPersona?.id === item.id && (
|
||||
<CheckOutlined className="m-l-xs" style={{ color: '#4CAF50' }} />
|
||||
<CheckOutlined
|
||||
className="m-l-xs"
|
||||
data-testid="check-outlined"
|
||||
style={{ color: LIGHT_GREEN_COLOR }}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</Space>
|
||||
),
|
||||
[handleSelectedPersonaChange, selectedPersona]
|
||||
);
|
||||
@ -317,7 +327,8 @@ export const UserProfileIcon = () => {
|
||||
{isImgUrlValid ? (
|
||||
<img
|
||||
alt="user"
|
||||
className="app-bar-user-avatar"
|
||||
className="app-bar-user-profile-pic"
|
||||
data-testid="app-bar-user-profile-pic"
|
||||
referrerPolicy="no-referrer"
|
||||
src={profilePicture ?? ''}
|
||||
onError={handleOnImageError}
|
||||
@ -333,6 +344,7 @@ export const UserProfileIcon = () => {
|
||||
</Tooltip>
|
||||
<Typography.Text
|
||||
className="text-grey-muted text-xs w-28"
|
||||
data-testid="default-persona"
|
||||
ellipsis={{ tooltip: true }}>
|
||||
{isEmpty(selectedPersona)
|
||||
? t('label.default')
|
||||
|
||||
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { getImageWithResolutionAndFallback } from '../../../utils/ProfilerUtils';
|
||||
import { useApplicationConfigContext } from '../../ApplicationConfigProvider/ApplicationConfigProvider';
|
||||
import { useAuthContext } from '../../Auth/AuthProviders/AuthProvider';
|
||||
import { mockPersonaData, mockUserData } from '../mocks/User.mocks';
|
||||
import { UserProfileIcon } from './UserProfileIcon.component';
|
||||
|
||||
const mockLogout = jest.fn();
|
||||
const mockUpdateSelectedPersona = jest.fn();
|
||||
|
||||
jest.mock('../../ApplicationConfigProvider/ApplicationConfigProvider', () => ({
|
||||
useApplicationConfigContext: jest.fn().mockImplementation(() => ({
|
||||
selectedPersona: {},
|
||||
updateSelectedPersona: mockUpdateSelectedPersona,
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('../../../utils/EntityUtils', () => ({
|
||||
getEntityName: jest.fn().mockReturnValue('Test User'),
|
||||
}));
|
||||
|
||||
jest.mock('../../../utils/ProfilerUtils', () => ({
|
||||
getImageWithResolutionAndFallback: jest
|
||||
.fn()
|
||||
.mockImplementation(() => 'valid-image-url'),
|
||||
ImageQuality: jest.fn().mockReturnValue('6x'),
|
||||
}));
|
||||
|
||||
jest.mock('../../common/AvatarComponent/Avatar', () =>
|
||||
jest.fn().mockReturnValue(<div>Avatar</div>)
|
||||
);
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
Link: jest
|
||||
.fn()
|
||||
.mockImplementation(({ children }: { children: React.ReactNode }) => (
|
||||
<p data-testid="link">{children}</p>
|
||||
)),
|
||||
}));
|
||||
|
||||
jest.mock('../../Auth/AuthProviders/AuthProvider', () => ({
|
||||
useAuthContext: jest.fn(() => ({
|
||||
currentUser: mockUserData,
|
||||
})),
|
||||
onLogoutHandler: mockLogout,
|
||||
}));
|
||||
|
||||
describe('UserProfileIcon', () => {
|
||||
it('should render User Profile Icon', () => {
|
||||
const { getByTestId } = render(<UserProfileIcon />);
|
||||
|
||||
expect(getByTestId('dropdown-profile')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display the user name', () => {
|
||||
const { getByText } = render(<UserProfileIcon />);
|
||||
|
||||
expect(getByText('Test User')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display default in case of no persona is selected', () => {
|
||||
const { getByText } = render(<UserProfileIcon />);
|
||||
|
||||
expect(getByText('label.default')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display image if profile pic is valid', () => {
|
||||
const { getByTestId } = render(<UserProfileIcon />);
|
||||
|
||||
expect(getByTestId('app-bar-user-profile-pic')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not display profile pic if image url is invalid', () => {
|
||||
(getImageWithResolutionAndFallback as jest.Mock).mockImplementation(
|
||||
() => undefined
|
||||
);
|
||||
const { queryByTestId, getByText } = render(<UserProfileIcon />);
|
||||
|
||||
expect(queryByTestId('app-bar-user-profile-pic')).not.toBeInTheDocument();
|
||||
expect(getByText('Avatar')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display the user team', () => {
|
||||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({
|
||||
selectedPersona: {
|
||||
id: '3362fe18-05ad-4457-9632-84f22887dda6',
|
||||
type: 'team',
|
||||
},
|
||||
updateSelectedPersona: jest.fn(),
|
||||
}));
|
||||
const { getByTestId } = render(<UserProfileIcon />);
|
||||
|
||||
expect(getByTestId('default-persona')).toHaveTextContent('Test User');
|
||||
});
|
||||
|
||||
it('should show empty placeholder when no teams data', async () => {
|
||||
(useAuthContext as jest.Mock).mockImplementation(() => ({
|
||||
currentUser: { ...mockUserData, teams: [] },
|
||||
onLogoutHandler: mockLogout,
|
||||
}));
|
||||
const teamLabels = screen.queryAllByText('label.team-plural');
|
||||
|
||||
teamLabels.forEach((label) => {
|
||||
expect(label).toHaveTextContent('--');
|
||||
});
|
||||
});
|
||||
|
||||
it('should show checked if selected persona is true', async () => {
|
||||
(useAuthContext as jest.Mock).mockImplementation(() => ({
|
||||
currentUser: {
|
||||
...mockUserData,
|
||||
personas: mockPersonaData,
|
||||
},
|
||||
onLogoutHandler: mockLogout,
|
||||
}));
|
||||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({
|
||||
selectedPersona: {
|
||||
id: '0430976d-092a-46c9-90a8-61c6091a6f38',
|
||||
type: 'persona',
|
||||
},
|
||||
updateSelectedPersona: jest.fn(),
|
||||
}));
|
||||
const { getByTestId } = render(<UserProfileIcon />);
|
||||
await act(async () => {
|
||||
userEvent.click(getByTestId('dropdown-profile'));
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(getByTestId('persona-label'));
|
||||
});
|
||||
|
||||
expect(getByTestId('check-outlined')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show checked if selected persona is true', async () => {
|
||||
(useAuthContext as jest.Mock).mockImplementation(() => ({
|
||||
currentUser: {
|
||||
...mockUserData,
|
||||
personas: mockPersonaData,
|
||||
},
|
||||
onLogoutHandler: mockLogout,
|
||||
}));
|
||||
(useApplicationConfigContext as jest.Mock).mockImplementation(() => ({
|
||||
selectedPersona: {
|
||||
id: 'test',
|
||||
type: 'persona',
|
||||
},
|
||||
updateSelectedPersona: jest.fn(),
|
||||
}));
|
||||
const { getByTestId, queryByTestId } = render(<UserProfileIcon />);
|
||||
await act(async () => {
|
||||
userEvent.click(getByTestId('dropdown-profile'));
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(getByTestId('persona-label'));
|
||||
});
|
||||
|
||||
expect(queryByTestId('check-outlined')).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2024 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { act, fireEvent, render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { getUserById } from '../../../rest/userAPI';
|
||||
import { mockUsersTabData } from '../mocks/User.mocks';
|
||||
import { UsersTab } from './UsersTabs.component';
|
||||
|
||||
jest.mock('../../../rest/userAPI', () => ({
|
||||
getUserById: jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve(mockUsersTabData)),
|
||||
}));
|
||||
|
||||
jest.mock('../../common/PopOverCard/UserPopOverCard', () =>
|
||||
jest.fn().mockReturnValue('Aaron Johnson')
|
||||
);
|
||||
jest.mock('react-router-dom', () => ({
|
||||
Link: jest
|
||||
.fn()
|
||||
.mockImplementation(({ children }: { children: React.ReactNode }) => (
|
||||
<p data-testid="link">{children}</p>
|
||||
)),
|
||||
useHistory: jest.fn(),
|
||||
}));
|
||||
|
||||
const mockUsers = [
|
||||
{
|
||||
deleted: false,
|
||||
displayName: 'Aaron Johnson',
|
||||
fullyQualifiedName: 'aaron_johnson0',
|
||||
href: 'http://localhost:8585/api/v1/users/f281e7fd-5fd3-4279-8a2d-ade80febd743',
|
||||
id: 'f281e7fd-5fd3-4279-8a2d-ade80febd743',
|
||||
name: 'aaron_johnson0',
|
||||
type: 'user',
|
||||
},
|
||||
];
|
||||
|
||||
const mockOnRemoveUser = jest.fn();
|
||||
|
||||
describe('UsersTab', () => {
|
||||
it('should renders Users Tab', async () => {
|
||||
await act(async () => {
|
||||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
});
|
||||
|
||||
expect(await screen.findByText('label.username')).toBeInTheDocument();
|
||||
expect(await screen.findByText('label.team-plural')).toBeInTheDocument();
|
||||
expect(await screen.findByText('label.role-plural')).toBeInTheDocument();
|
||||
expect(await screen.findByText('label.action-plural')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display the user details', async () => {
|
||||
await act(async () => {
|
||||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
});
|
||||
|
||||
expect(await screen.findByText('Aaron Johnson')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Sales')).toBeInTheDocument();
|
||||
expect(await screen.findByText('Data Steward')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render empty placeholder if no data', async () => {
|
||||
(getUserById as jest.Mock).mockImplementation(() => Promise.resolve([])),
|
||||
await act(async () => {
|
||||
render(<UsersTab users={[]} onRemoveUser={mockOnRemoveUser} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
});
|
||||
|
||||
expect(
|
||||
await screen.findByTestId('assign-error-placeholder-label.user')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should display the remove confirmation modal when remove button is clicked', async () => {
|
||||
await act(async () => {
|
||||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
});
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByTestId('remove-user-btn'));
|
||||
});
|
||||
|
||||
expect(
|
||||
await screen.getByTestId('remove-confirmation-modal')
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should close the remove confirmation modal when cancel button is clicked', async () => {
|
||||
await act(async () => {
|
||||
render(<UsersTab users={mockUsers} onRemoveUser={mockOnRemoveUser} />, {
|
||||
wrapper: MemoryRouter,
|
||||
});
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.click(screen.getByTestId('remove-user-btn'));
|
||||
});
|
||||
await act(async () => {
|
||||
userEvent.click(screen.getByText('label.cancel'));
|
||||
});
|
||||
|
||||
expect(
|
||||
screen.queryByTestId('remove-confirmation-modal')
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@ -134,20 +134,22 @@ export const UsersTab = ({ users, onRemoveUser }: UsersTabProps) => {
|
||||
rowKey="fullyQualifiedName"
|
||||
size="small"
|
||||
/>
|
||||
<Modal
|
||||
cancelText={t('label.cancel')}
|
||||
data-testid="remove-confirmation-modal"
|
||||
okText={t('label.confirm')}
|
||||
open={Boolean(removeUserDetails?.state)}
|
||||
title={t('label.removing-user')}
|
||||
onCancel={handleRemoveCancel}
|
||||
onOk={handleRemoveConfirm}>
|
||||
{t('message.are-you-sure-want-to-text', {
|
||||
text: t('label.remove-entity-lowercase', {
|
||||
entity: removeUserDetails?.user.name,
|
||||
}),
|
||||
})}
|
||||
</Modal>
|
||||
{Boolean(removeUserDetails?.state) && (
|
||||
<Modal
|
||||
cancelText={t('label.cancel')}
|
||||
data-testid="remove-confirmation-modal"
|
||||
okText={t('label.confirm')}
|
||||
open={Boolean(removeUserDetails?.state)}
|
||||
title={t('label.removing-user')}
|
||||
onCancel={handleRemoveCancel}
|
||||
onOk={handleRemoveConfirm}>
|
||||
{t('message.are-you-sure-want-to-text', {
|
||||
text: t('label.remove-entity-lowercase', {
|
||||
entity: removeUserDetails?.user.name,
|
||||
}),
|
||||
})}
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -208,6 +208,71 @@ export const mockTeamsData = {
|
||||
],
|
||||
paging: { total: 7 },
|
||||
};
|
||||
export const mockUsersTabData = {
|
||||
id: 'f281e7fd-5fd3-4279-8a2d-ade80febd743',
|
||||
name: 'aaron_johnson0',
|
||||
fullyQualifiedName: 'aaron_johnson0',
|
||||
displayName: 'Aaron Johnson',
|
||||
version: 1.5,
|
||||
updatedAt: 1707198736848,
|
||||
updatedBy: 'admin',
|
||||
email: 'aaron_johnson0@gmail.com',
|
||||
href: 'http://localhost:8585/api/v1/users/f281e7fd-5fd3-4279-8a2d-ade80febd743',
|
||||
isAdmin: false,
|
||||
teams: [
|
||||
{
|
||||
id: '35c03c5c-5160-41af-b08d-ef2b2b9e6adf',
|
||||
type: 'team',
|
||||
name: 'Sales',
|
||||
fullyQualifiedName: 'Sales',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/teams/35c03c5c-5160-41af-b08d-ef2b2b9e6adf',
|
||||
},
|
||||
],
|
||||
changeDescription: {
|
||||
fieldsAdded: [
|
||||
{
|
||||
name: 'teams',
|
||||
newValue:
|
||||
'[{"id":"35c03c5c-5160-41af-b08d-ef2b2b9e6adf","type":"team","name":"Sales","fullyQualifiedName":"Sales","deleted":false}]',
|
||||
},
|
||||
],
|
||||
fieldsUpdated: [],
|
||||
fieldsDeleted: [
|
||||
{
|
||||
name: 'teams',
|
||||
oldValue: '[{"id":"f39f326a-81a1-42ca-976]',
|
||||
},
|
||||
],
|
||||
previousVersion: 1.4,
|
||||
},
|
||||
deleted: false,
|
||||
roles: [
|
||||
{
|
||||
id: 'e4b20aef-c6c4-4416-aaae-f60185c7cac0',
|
||||
type: 'role',
|
||||
name: 'DataSteward',
|
||||
fullyQualifiedName: 'DataSteward',
|
||||
description: 'Users with Data Steward',
|
||||
displayName: 'Data Steward',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/roles/e4b20aef-c6c4-4416-aaae-f60185c7cac0',
|
||||
},
|
||||
],
|
||||
inheritedRoles: [
|
||||
{
|
||||
id: '5f1445a7-c299-4dde-8c5b-704c6cd68ee6',
|
||||
type: 'role',
|
||||
name: 'DataConsumer',
|
||||
fullyQualifiedName: 'DataConsumer',
|
||||
description:
|
||||
'Users with Data Consumer role use different data assets for their day to day work.',
|
||||
displayName: 'Data Consumer',
|
||||
deleted: false,
|
||||
href: 'http://localhost:8585/api/v1/roles/5f1445a7-c299-4dde-8c5b-704c6cd68ee6',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const mockUserRole = {
|
||||
data: [
|
||||
@ -1039,3 +1104,14 @@ export const mockAccessData = {
|
||||
tokenType: TokenType.PersonalAccessToken,
|
||||
userId: '445291f4d62c1bae',
|
||||
};
|
||||
export const mockPersonaData = [
|
||||
{
|
||||
description: 'Person-04',
|
||||
displayName: 'Person-04',
|
||||
fullyQualifiedName: 'Person-04',
|
||||
href: 'http://localhost:8585/api/v1/personas/0430976d-092a-46c9-90a8-61c6091a6f38',
|
||||
id: '0430976d-092a-46c9-90a8-61c6091a6f38',
|
||||
name: 'Person-04',
|
||||
type: 'persona',
|
||||
},
|
||||
];
|
||||
|
||||
@ -136,7 +136,7 @@ describe('FeedsWidget', () => {
|
||||
const { getAllByRole } = render(<FeedsWidget {...widgetProps} />);
|
||||
const tabs = getAllByRole('tab');
|
||||
const selectedTab = tabs[index];
|
||||
selectedTab.click();
|
||||
fireEvent.click(selectedTab);
|
||||
|
||||
expect(selectedTab.getAttribute('aria-selected')).toBe('true');
|
||||
});
|
||||
|
||||
@ -42,6 +42,7 @@ export const GREEN_COLOR_OPACITY_30 = '#28A74530';
|
||||
export const BORDER_COLOR = '#0000001a';
|
||||
export const BLACK_COLOR = '#000000';
|
||||
export const WHITE_COLOR = '#ffffff';
|
||||
export const LIGHT_GREEN_COLOR = '#4CAF50';
|
||||
|
||||
export const DEFAULT_CHART_OPACITY = 1;
|
||||
export const HOVER_CHART_OPACITY = 0.3;
|
||||
|
||||
@ -700,7 +700,7 @@ a[href].link-text-grey,
|
||||
padding-right: 0.25rem;
|
||||
}
|
||||
|
||||
.app-bar-user-avatar {
|
||||
.app-bar-user-profile-pic {
|
||||
display: inline-block;
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user