Skip to content

Commit

Permalink
React UI: batch of fixes (cvat-ai#1525)
Browse files Browse the repository at this point in the history
  • Loading branch information
ActiveChooN authored and Fernando Martínez González committed Aug 3, 2020
1 parent 89462be commit af70d2b
Show file tree
Hide file tree
Showing 15 changed files with 92 additions and 26 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Exporting frame stepped task (https://github.com/opencv/cvat/issues/1294, https://github.com/opencv/cvat/issues/1334)
- Fixed broken command line interface for `cvat` export format in Datumaro (https://github.com/opencv/cvat/issues/1494)
- Updated Rest API document, Swagger document serving instruction issue (https://github.com/opencv/cvat/issues/1495)
- Fixed cuboid occluded view (<https://github.com/opencv/cvat/pull/1500>)
- Non-informative lock icon (<https://github.com/opencv/cvat/pull/1434>)
- Sidebar in AAM has no hide/show button (<https://github.com/opencv/cvat/pull/1420>)
- Task/Job buttons has no "Open in new tab" option (<https://github.com/opencv/cvat/pull/1419>)
- Delete point context menu option has no shortcut hint (<https://github.com/opencv/cvat/pull/1416>)

### Security
-
Expand Down
4 changes: 4 additions & 0 deletions cvat-canvas/src/scss/canvas.scss
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ polyline.cvat_canvas_shape_splitting {
stroke-dasharray: 5;
}

.cvat_canvas_shape .svg_select_points, .cvat_canvas_shape .cvat_canvas_cuboid_projections {
stroke-dasharray: none;
}

.cvat_canvas_autoborder_point {
opacity: 0.55;
}
Expand Down
17 changes: 16 additions & 1 deletion cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ export class CanvasViewImpl implements CanvasView, Listener {

private selectize(value: boolean, shape: SVG.Element): void {
const self = this;
const { offset } = this.controller.geometry;
const translate = (points: number[]): number[] => points
.map((coord: number): number => coord - offset);

function dblClickHandler(e: MouseEvent): void {
const pointID = Array.prototype.indexOf
Expand All @@ -437,10 +440,22 @@ export class CanvasViewImpl implements CanvasView, Listener {
.filter((_state: any): boolean => (
_state.clientID === self.activeElement.clientID
));
if (['cuboid', 'rectangle'].includes(state.shapeType)) {
if (state.shapeType === 'rectangle') {
e.preventDefault();
return;
}
if (state.shapeType === 'cuboid') {
if (e.shiftKey) {
const points = translate(pointsToArray((e.target as any)
.parentElement.parentElement.instance.attr('points')));
self.onEditDone(
state,
points,
)
e.preventDefault();
return;
}
}
if (e.ctrlKey) {
const { points } = state;
self.onEditDone(
Expand Down
32 changes: 20 additions & 12 deletions cvat-canvas/src/typescript/svg.patch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,10 +263,10 @@ function getTopDown(edgeIndex: EdgeIndex): number[] {
this.rbProj = this.line(this.updateProjectionLine(this.cuboidModel.rb.getEquation(),
this.cuboidModel.rb.points[1], this.cuboidModel.vpr));

this.ftProj.stroke({ color: '#C0C0C0' });
this.fbProj.stroke({ color: '#C0C0C0' });
this.rtProj.stroke({ color: '#C0C0C0' });
this.rbProj.stroke({ color: '#C0C0C0' });
this.ftProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections');
this.fbProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections');
this.rtProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections');
this.rbProj.stroke({ color: '#C0C0C0' }).addClass('cvat_canvas_cuboid_projections');
},

setupEdges() {
Expand All @@ -281,7 +281,7 @@ function getTopDown(edgeIndex: EdgeIndex): number[] {
this.rightBotEdge = this.line(this.cuboidModel.rb.points);
},

setupGrabPoints(circleType) {
setupGrabPoints(circleType: Function | string) {
const viewModel = this.cuboidModel;
const circle = typeof circleType === 'function' ? circleType : this.circle;

Expand Down Expand Up @@ -372,29 +372,37 @@ function getTopDown(edgeIndex: EdgeIndex): number[] {
}

if (value === false) {
this.getGrabPoints().forEach((point) => {point && point.remove()});
this.getGrabPoints().forEach((point: SVG.Element) => {point && point.remove()});
} else {
this.setupGrabPoints(this.face.remember('_selectHandler').drawPoint.bind(
{nested: this, options: this.face.remember('_selectHandler').options}
));

// setup proper classes for selection points for proper cursor
Array.from(this.face.remember('_selectHandler').nested.node.children)
.forEach((point: SVG.Circle, i: number) => {
.forEach((point: SVG.LinkedHTMLElement, i: number) => {
point.classList.add(`svg_select_points_${['lt', 'lb', 'rb', 'rt'][i]}`)
});

if (this.cuboidModel.orientation === Orientation.LEFT) {
Array.from(this.dorsalRightEdge.remember('_selectHandler').nested.node.children)
.forEach((point: SVG.Circle, i: number) => {
.forEach((point: SVG.LinkedHTMLElement, i: number) => {
point.classList.add(`svg_select_points_${['t', 'b'][i]}`);
point.ondblclick = this.resetPerspective.bind(this);
point.ondblclick = (e: MouseEvent) => {
if (e.shiftKey) {
this.resetPerspective()
}
};
});
} else {
Array.from(this.dorsalLeftEdge.remember('_selectHandler').nested.node.children)
.forEach((point: SVG.Circle, i: number) => {
.forEach((point: SVG.LinkedHTMLElement, i: number) => {
point.classList.add(`svg_select_points_${['t', 'b'][i]}`);
point.ondblclick = this.resetPerspective.bind(this);
point.ondblclick = (e: MouseEvent) => {
if (e.shiftKey) {
this.resetPerspective()
}
};
});
}

Expand Down Expand Up @@ -584,7 +592,7 @@ function getTopDown(edgeIndex: EdgeIndex): number[] {
setupDorsalEdge.call(this, this.dorsalLeftEdge, this.cuboidModel.orientation);
}

function horizontalEdgeControl(updatingFace, midX, midY) {
function horizontalEdgeControl(updatingFace: any, midX: number, midY: number) {
const leftPoints = this.updatedEdge(
this.cuboidModel.fl.points[0],
{x: midX, y: midY},
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.0.1",
"version": "1.0.2",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SelectValue } from 'antd/lib/select';
import { CheckboxChangeEvent } from 'antd/lib/checkbox';
import { Row, Col } from 'antd/lib/grid';
import Text from 'antd/lib/typography/Text';
import Icon from 'antd/lib/icon';

import { LogType } from 'cvat-logger';
import {
Expand Down Expand Up @@ -106,6 +107,8 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
}, {}),
);

const [sidebarCollapsed, setSidebarCollapsed] = useState(false);

const [activeObjectState] = activatedStateID === null
? [null] : states.filter((objectState: any): boolean => (
objectState.clientID === activatedStateID
Expand Down Expand Up @@ -175,6 +178,7 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
reverseArrow: true,
collapsible: true,
trigger: null,
collapsed: sidebarCollapsed,
};

const subKeyMap = {
Expand Down Expand Up @@ -218,8 +222,18 @@ function AttributeAnnotationSidebar(props: StateToProps & DispatchToProps): JSX.
if (activeObjectState) {
return (
<Layout.Sider {...siderProps}>
{/* eslint-disable-next-line */}
<span
className={`cvat-objects-sidebar-sider
ant-layout-sider-zero-width-trigger
ant-layout-sider-zero-width-trigger-left`}
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
>
{sidebarCollapsed ? <Icon type='menu-fold' title='Show' />
: <Icon type='menu-unfold' title='Hide' />}
</span>
<GlobalHotKeys keyMap={subKeyMap} handlers={handlers} allowChanges />
<Row>
<Row className='cvat-objects-sidebar-filter-input'>
<Col>
<AnnotationsFiltersInput />
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'antd/lib/button';
import Tooltip from 'antd/lib/tooltip';

interface Props {
activatedStateID: number | null;
Expand All @@ -29,9 +30,11 @@ export default function CanvasPointContextMenu(props: Props): JSX.Element | null

return ReactDOM.createPortal(
<div className='cvat-canvas-point-context-menu' style={{ top, left }}>
<Button type='link' icon='delete' onClick={onPointDelete}>
Delete point
</Button>
<Tooltip title='Delete point [Ctrl + dblclick]'>
<Button type='link' icon='delete' onClick={onPointDelete}>
Delete point
</Button>
</Tooltip>
</div>,
window.document.body,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ function ItemButtonsComponent(props: ItemButtonsComponentProps): JSX.Element {
<Col>
<Tooltip title={`Switch lock property ${switchLockShortcut}`}>
{ locked
? <Icon type='lock' onClick={unlock} />
? <Icon type='lock' onClick={unlock} theme='filled'/>
: <Icon type='unlock' onClick={lock} />}
</Tooltip>
</Col>
Expand Down Expand Up @@ -388,7 +388,7 @@ function ItemButtonsComponent(props: ItemButtonsComponentProps): JSX.Element {
<Col>
<Tooltip title={`Switch lock property ${switchLockShortcut}`}>
{ locked
? <Icon type='lock' onClick={unlock} />
? <Icon type='lock' onClick={unlock} theme='filled' />
: <Icon type='unlock' onClick={lock} />}
</Tooltip>
</Col>
Expand All @@ -405,7 +405,7 @@ function ItemButtonsComponent(props: ItemButtonsComponentProps): JSX.Element {
<Col>
<Tooltip title={`Switch lock property ${switchLockShortcut}`}>
{ locked
? <Icon type='lock' onClick={unlock} />
? <Icon type='lock' onClick={unlock} theme='filled'/>
: <Icon type='unlock' onClick={lock} />}
</Tooltip>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ function ObjectListHeader(props: Props): JSX.Element {
<Col span={2}>
<Tooltip title={`Switch lock property for all ${switchLockAllShortcut}`}>
{ statesLocked
? <Icon type='lock' onClick={unlockAllStates} />
? <Icon type='lock' onClick={unlockAllStates} theme='filled' />
: <Icon type='unlock' onClick={lockAllStates} />}
</Tooltip>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,18 @@
background-color: $background-color-1;
}

.cvat-objects-sidebar-filter-input {
width: calc(100% - 35px);
}

.cvat-objects-sidebar-sider {
top: 0px;
right: 0px;
left: auto;
background-color: $background-color-2;
border-left: 1px solid $border-color-1;
border-bottom: 1px solid $border-color-1;
border-radius: 4px 0 0 4px;
z-index: 2;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Props {
dumpActivities: string[] | null;
exportActivities: string[] | null;
installedReID: boolean;
taskID: number;
onClickMenu(params: ClickParam, file?: File): void;
}

Expand All @@ -40,6 +41,7 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
dumpActivities,
exportActivities,
installedReID,
taskID,
} = props;

let latestParams: ClickParam | null = null;
Expand Down Expand Up @@ -119,7 +121,9 @@ export default function AnnotationMenuComponent(props: Props): JSX.Element {
Remove annotations
</Menu.Item>
<Menu.Item key={Actions.OPEN_TASK}>
Open the task
<a href={`/tasks/${taskID}`} onClick={(e: React.MouseEvent) => e.preventDefault()}>
Open the task
</a>
</Menu.Item>
{ installedReID && <ReIDPlugin /> }
</Menu>
Expand Down
4 changes: 3 additions & 1 deletion cvat-ui/src/components/task-page/job-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ function JobListComponent(props: Props & RouteComponentProps): JSX.Element {
<div>
<Button
type='link'
onClick={(): void => {
onClick={(e: React.MouseEvent): void => {
e.preventDefault();
push(`/tasks/${taskId}/jobs/${id}`);
}}
href={`/tasks/${taskId}/jobs/${id}`}
>
{`Job #${id}`}
</Button>
Expand Down
6 changes: 5 additions & 1 deletion cvat-ui/src/components/tasks-page/task-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ class TaskItemComponent extends React.PureComponent<TaskItemProps & RouteCompone
type='primary'
size='large'
ghost
onClick={(): void => history.push(`/tasks/${id}`)}
href={`/tasks/${id}`}
onClick={(e: React.MouseEvent): void => {
e.preventDefault();
history.push(`/tasks/${id}`)
}}
>
Open
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ function AnnotationMenuContainer(props: Props): JSX.Element {
exportActivities={exportActivities}
installedReID={installedReID}
onClickMenu={onClickMenu}
taskID={jobInstance.task.id}
/>
);
}
Expand Down

0 comments on commit af70d2b

Please sign in to comment.