Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to customize logo and title #9052

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog.d/20250205_141639_klakhov_setup_logo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
### Added

- Ability to customize title and logo
(<https://github.com/cvat-ai/cvat/pull/9052>)
2 changes: 2 additions & 0 deletions cvat-core/src/server-response-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ export interface SerializedAbout {
description: string;
name: string;
version: string;
logo: string;
title: string;
}

export interface SerializedRemoteFile {
Expand Down
17 changes: 17 additions & 0 deletions cvat-ui/src/components/common/cvat-logo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { useSelector } from 'react-redux';

function CVATLogo(): JSX.Element {
const SVGLogo = useSelector((state: any) => state.about.server.logo);

return (
<div className='cvat-logo-icon'>
<img
src={`data:image/svg+xml;utf8,${encodeURIComponent(SVGLogo)}`}
alt='CVAT Logo'
/>
</div>
);
}

export default React.memo(CVATLogo);
9 changes: 5 additions & 4 deletions cvat-ui/src/components/cvat-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
loadServerAPISchema();
}

if (!aboutInitialized && !aboutFetching) {
loadAbout();
return;
}

if (user == null || !user.isVerified || !user.id) {
return;
}
Expand All @@ -337,10 +342,6 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
loadFormats();
}

if (!aboutInitialized && !aboutFetching) {
loadAbout();
}

if (organizationInitialized && !requestsInitialized && !requestsFetching) {
initRequests();
}
Expand Down
6 changes: 3 additions & 3 deletions cvat-ui/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import { useHistory, useLocation } from 'react-router';
import { Row, Col } from 'antd/lib/grid';
import { MenuProps } from 'antd/lib/menu';
import Icon, {
import {
SettingOutlined,
InfoCircleOutlined,
EditOutlined,
Expand All @@ -34,9 +34,9 @@ import notification from 'antd/lib/notification';
import config from 'config';

import { Organization, getCore } from 'cvat-core-wrapper';
import { CVATLogo } from 'icons';
import ChangePasswordDialog from 'components/change-password-modal/change-password-modal';
import CVATTooltip from 'components/common/cvat-tooltip';
import CVATLogo from 'components/common/cvat-logo';
import { switchSettingsModalVisible as switchSettingsModalVisibleAction } from 'actions/settings-actions';
import { logoutAsync, authActions } from 'actions/auth-actions';
import { shortcutsActions, registerComponentShortcuts } from 'actions/shortcuts-actions';
Expand Down Expand Up @@ -430,7 +430,7 @@ function HeaderComponent(props: Props): JSX.Element {
<Layout.Header className='cvat-header'>
<GlobalHotKeys keyMap={subKeyMap(componentShortcuts, keyMap)} handlers={handlers} />
<div className='cvat-left-header'>
<Icon className='cvat-logo-icon' component={CVATLogo} />
<CVATLogo />
<Button
className={getButtonClassName('projects')}
type='link'
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/components/header/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
}
}

.anticon.cvat-logo-icon {
.cvat-logo-icon {
margin: 0 $grid-unit-size * 2;
}

Expand Down
11 changes: 6 additions & 5 deletions cvat-ui/src/components/signing-common/signing-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

import './styles.scss';
import React from 'react';
import { useSelector } from 'react-redux';
import Layout from 'antd/lib/layout';
import { Col, Row } from 'antd/lib/grid';
import { CVATLogo } from 'icons';
import Icon from '@ant-design/icons';
import Title from 'antd/lib/typography/Title';
import CVATLogo from 'components/common/cvat-logo';
import SVGSigningBackground from '../../assets/signing-background.svg';

interface SignInLayoutComponentProps {
Expand Down Expand Up @@ -51,6 +51,8 @@ export const formSizes: FormSizes = {
function SignInLayout(props: SignInLayoutComponentProps): JSX.Element {
const { children } = props;
const { Content, Header } = Layout;
const title = useSelector((state: any) => state.about.server.title);

const titleSizes = {
xs: { span: 0 },
sm: { span: 0 },
Expand All @@ -73,16 +75,15 @@ function SignInLayout(props: SignInLayoutComponentProps): JSX.Element {
<Header className='cvat-signing-header'>
<Row justify='center' align='middle'>
<Col {...logoSizes}>
<Icon className='cvat-logo-icon' component={CVATLogo} />
<CVATLogo />
</Col>
</Row>
</Header>
<Layout className='cvat-signing-layout'>
<Content>
<Row justify='center' align='middle' style={{ height: '100%' }}>
<Col {...titleSizes} className='cvat-signing-title'>
<Title>Open Data</Title>
<Title>Annotation Platform</Title>
<Title>{title}</Title>
</Col>
{children}
</Row>
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/components/signing-common/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ $social-google-background: #4286f5;
width: 100%;

.cvat-logo-icon {
fill: white;
filter: brightness(0) invert(1);
}
}

Expand Down
2 changes: 0 additions & 2 deletions cvat-ui/src/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import React from 'react';

import SVGCVATLogo from './assets/cvat-logo.svg';
import SVGCVATIcon from './assets/cvat-icon.svg';
import SVGCursorIcon from './assets/cursor-icon.svg';
import SVGMoveIcon from './assets/move-icon.svg';
Expand Down Expand Up @@ -72,7 +71,6 @@ import SVGShowGroundTruthIcon from './assets/show-gt-icon.svg';
import SVGJoinIcon from './assets/join-icon.svg';
import SVGSliceIcon from './assets/slice-icon.svg';

export const CVATLogo = React.memo((): JSX.Element => <SVGCVATLogo />);
export const CVATIcon = React.memo((): JSX.Element => <SVGCVATIcon />);
export const CursorIcon = React.memo((): JSX.Element => <SVGCursorIcon />);
export const MoveIcon = React.memo((): JSX.Element => <SVGMoveIcon />);
Expand Down
File renamed without changes
2 changes: 2 additions & 0 deletions cvat/apps/engine/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2627,6 +2627,8 @@ class AboutSerializer(serializers.Serializer):
name = serializers.CharField(max_length=128)
description = serializers.CharField(max_length=2048)
version = serializers.CharField(max_length=64)
logo = serializers.CharField()
title = serializers.CharField(max_length=1024)

class FrameMetaSerializer(serializers.Serializer):
width = serializers.IntegerField()
Expand Down
18 changes: 10 additions & 8 deletions cvat/apps/engine/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@
_DATA_UPDATED_DATE_HEADER_NAME = 'X-Updated-Date'
_RETRY_AFTER_TIMEOUT = 10

ICON_FILE = "assets/logo.svg"

def get_logo() -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check that we don't read it on every about request.

with open(osp.join(osp.dirname(__file__), ICON_FILE)) as f:
return f.read()

@extend_schema(tags=['server'])
class ServerViewSet(viewsets.ViewSet):
serializer_class = None
Expand All @@ -210,15 +216,11 @@ def get_serializer(self, *args, **kwargs):
def about(request):
from cvat import __version__ as cvat_version
about = {
"name": "Computer Vision Annotation Tool",
"name": settings.ABOUT_INFO["name"],
"title": settings.ABOUT_INFO["title"],
"description": settings.ABOUT_INFO["description"],
"version": cvat_version,
"description": "CVAT is completely re-designed and re-implemented " +
"version of Video Annotation Tool from Irvine, California " +
"tool. It is free, online, interactive video and image annotation " +
"tool for computer vision. It is being used by our team to " +
"annotate million of objects with different properties. Many UI " +
"and UX decisions are based on feedbacks from professional data " +
"annotation team."
"logo": get_logo(),
}
serializer = AboutSerializer(data=about)
if serializer.is_valid(raise_exception=True):
Expand Down
7 changes: 7 additions & 0 deletions cvat/schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6905,9 +6905,16 @@ components:
version:
type: string
maxLength: 64
logo:
type: string
title:
type: string
maxLength: 1024
required:
- description
- logo
- name
- title
- version
AcceptInvitationRead:
type: object
Expand Down
12 changes: 12 additions & 0 deletions cvat/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,15 @@ class CVAT_QUEUES(Enum):

# Indicates the maximum number of days a file or directory is retained in the temporary directory
TMP_FILE_OR_DIR_RETENTION_DAYS = 3

ABOUT_INFO = {
"name": "Computer Vision Annotation Tool",
"title": "Open Data Annotation Platform",
"description": "CVAT is completely re-designed and re-implemented " +
"version of Video Annotation Tool from Irvine, California " +
"tool. It is free, online, interactive video and image annotation " +
"tool for computer vision. It is being used by our team to " +
"annotate million of objects with different properties. Many UI " +
"and UX decisions are based on feedbacks from professional data " +
"annotation team.",
}
Loading