From 0e37d70b1a0525dd0ded3e3bb760e6c5ca8d1f30 Mon Sep 17 00:00:00 2001 From: Dmitry Kalinin Date: Tue, 1 Sep 2020 13:53:38 +0300 Subject: [PATCH] CVAT UI: batch of fixes (#2084) * fixed object item border color * Fixed default collapsed prop in object item * Added color picker for shape outline * Added CHANGELOG, increased npm version * Fixed object details collapsing * Fixed default collapsed --- CHANGELOG.md | 3 ++ cvat-ui/package-lock.json | 2 +- cvat-ui/package.json | 2 +- cvat-ui/src/actions/auth-actions.ts | 4 +- cvat-ui/src/actions/settings-actions.ts | 9 ++-- cvat-ui/src/base.scss | 2 +- .../annotation-page/appearance-block.tsx | 43 +++++++++++++------ .../canvas-context-menu.tsx | 6 ++- .../standard-workspace/canvas-wrapper.tsx | 14 +++--- .../objects-side-bar/objects-list.tsx | 12 ++++-- .../standard-workspace/canvas-wrapper.tsx | 9 ++-- .../objects-side-bar/object-item.tsx | 3 +- .../objects-side-bar/objects-list.tsx | 12 +++--- cvat-ui/src/reducers/annotation-reducer.ts | 4 ++ cvat-ui/src/reducers/interfaces.ts | 4 +- cvat-ui/src/reducers/settings-reducer.ts | 8 ++-- 16 files changed, 92 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 562ef21fda7e..fe4304290c4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Ability to configure email verification for new users () - Link to django admin page from UI () - Notification message when users use wrong browser () +- Annotation in process outline color wheel () ### Changed - Shape coordinates are rounded to 2 digits in dumped annotations () @@ -44,6 +45,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed a case in which exported masks could have wrong color order () - Fixed error with creating task with labels with the same name () - Django RQ dashboard view () +- Object's details menu settings () +- ## [1.1.0-beta] - 2020-08-03 ### Added diff --git a/cvat-ui/package-lock.json b/cvat-ui/package-lock.json index 4cfa9ddf44f9..7370e0fa5462 100644 --- a/cvat-ui/package-lock.json +++ b/cvat-ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.9.0", + "version": "1.9.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/cvat-ui/package.json b/cvat-ui/package.json index e587666f44c7..66ba9e864eed 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.9.0", + "version": "1.9.1", "description": "CVAT single-page application", "main": "src/index.tsx", "scripts": { diff --git a/cvat-ui/src/actions/auth-actions.ts b/cvat-ui/src/actions/auth-actions.ts index ad09019c2c6d..c169874759f7 100644 --- a/cvat-ui/src/actions/auth-actions.ts +++ b/cvat-ui/src/actions/auth-actions.ts @@ -94,8 +94,8 @@ export const registerAsync = ( dispatch(authActions.register()); try { - const user = await cvat.server.register(username, firstName, lastName, email, password1, password2, - confirmations); + const user = await cvat.server.register(username, firstName, lastName, email, password1, + password2, confirmations); dispatch(authActions.registerSuccess(user)); } catch (error) { diff --git a/cvat-ui/src/actions/settings-actions.ts b/cvat-ui/src/actions/settings-actions.ts index 9108b02a21a8..737baa267a11 100644 --- a/cvat-ui/src/actions/settings-actions.ts +++ b/cvat-ui/src/actions/settings-actions.ts @@ -17,7 +17,7 @@ export enum SettingsActionTypes { CHANGE_SHAPES_OPACITY = 'CHANGE_SHAPES_OPACITY', CHANGE_SELECTED_SHAPES_OPACITY = 'CHANGE_SELECTED_SHAPES_OPACITY', CHANGE_SHAPES_COLOR_BY = 'CHANGE_SHAPES_COLOR_BY', - CHANGE_SHAPES_BLACK_BORDERS = 'CHANGE_SHAPES_BLACK_BORDERS', + CHANGE_SHAPES_OUTLINED_BORDERS = 'CHANGE_SHAPES_OUTLINED_BORDERS', CHANGE_SHAPES_SHOW_PROJECTIONS = 'CHANGE_SHAPES_SHOW_PROJECTIONS', CHANGE_SHOW_UNLABELED_REGIONS = 'CHANGE_SHOW_UNLABELED_REGIONS', CHANGE_FRAME_STEP = 'CHANGE_FRAME_STEP', @@ -63,11 +63,12 @@ export function changeShapesColorBy(colorBy: ColorBy): AnyAction { }; } -export function changeShapesBlackBorders(blackBorders: boolean): AnyAction { +export function changeShapesOutlinedBorders(outlined: boolean, color: string): AnyAction { return { - type: SettingsActionTypes.CHANGE_SHAPES_BLACK_BORDERS, + type: SettingsActionTypes.CHANGE_SHAPES_OUTLINED_BORDERS, payload: { - blackBorders, + outlined, + color, }, }; } diff --git a/cvat-ui/src/base.scss b/cvat-ui/src/base.scss index 75b561ca0245..86bae7310c1a 100644 --- a/cvat-ui/src/base.scss +++ b/cvat-ui/src/base.scss @@ -22,7 +22,7 @@ $info-icon-color: #0074d9; $objects-bar-tabs-color: #bebebe; $objects-bar-icons-color: #242424; // #6e6e6e $active-label-background-color: #d8ecff; -$object-item-border-color: #000; +$object-item-border-color: rgba(0, 0, 0, 0.7); $slider-color: #1890ff; $monospaced-fonts-stack: Consolas, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace; diff --git a/cvat-ui/src/components/annotation-page/appearance-block.tsx b/cvat-ui/src/components/annotation-page/appearance-block.tsx index 06a060fa72a4..42e8fc201c61 100644 --- a/cvat-ui/src/components/annotation-page/appearance-block.tsx +++ b/cvat-ui/src/components/annotation-page/appearance-block.tsx @@ -11,6 +11,8 @@ import Slider, { SliderValue } from 'antd/lib/slider'; import Checkbox, { CheckboxChangeEvent } from 'antd/lib/checkbox'; import Collapse from 'antd/lib/collapse'; +import ColorPicker from 'components/annotation-page/standard-workspace/objects-side-bar/color-picker'; +import { ColorizeIcon } from 'icons'; import { ColorBy, CombinedState } from 'reducers/interfaces'; import { collapseAppearance as collapseAppearanceAction, @@ -20,17 +22,19 @@ import { changeShapesColorBy as changeShapesColorByAction, changeShapesOpacity as changeShapesOpacityAction, changeSelectedShapesOpacity as changeSelectedShapesOpacityAction, - changeShapesBlackBorders as changeShapesBlackBordersAction, + changeShapesOutlinedBorders as changeShapesOutlinedBordersAction, changeShowBitmap as changeShowBitmapAction, changeShowProjections as changeShowProjectionsAction, } from 'actions/settings-actions'; +import Button from 'antd/lib/button'; interface StateToProps { appearanceCollapsed: boolean; colorBy: ColorBy; opacity: number; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; } @@ -40,7 +44,7 @@ interface DispatchToProps { changeShapesColorBy(event: RadioChangeEvent): void; changeShapesOpacity(event: SliderValue): void; changeSelectedShapesOpacity(event: SliderValue): void; - changeShapesBlackBorders(event: CheckboxChangeEvent): void; + changeShapesOutlinedBorders(outlined: boolean, color: string): void; changeShowBitmap(event: CheckboxChangeEvent): void; changeShowProjections(event: CheckboxChangeEvent): void; } @@ -72,7 +76,8 @@ function mapStateToProps(state: CombinedState): StateToProps { colorBy, opacity, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, }, @@ -84,7 +89,8 @@ function mapStateToProps(state: CombinedState): StateToProps { colorBy, opacity, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, }; @@ -119,8 +125,8 @@ function mapDispatchToProps(dispatch: Dispatch): DispatchToProps { changeSelectedShapesOpacity(value: SliderValue): void { dispatch(changeSelectedShapesOpacityAction(value as number)); }, - changeShapesBlackBorders(event: CheckboxChangeEvent): void { - dispatch(changeShapesBlackBordersAction(event.target.checked)); + changeShapesOutlinedBorders(outlined: boolean, color: string): void { + dispatch(changeShapesOutlinedBordersAction(outlined, color)); }, changeShowBitmap(event: CheckboxChangeEvent): void { dispatch(changeShowBitmapAction(event.target.checked)); @@ -139,14 +145,15 @@ function AppearanceBlock(props: Props): JSX.Element { colorBy, opacity, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, collapseAppearance, changeShapesColorBy, changeShapesOpacity, changeSelectedShapesOpacity, - changeShapesBlackBorders, + changeShapesOutlinedBorders, changeShowBitmap, changeShowProjections, } = props; @@ -185,10 +192,22 @@ function AppearanceBlock(props: Props): JSX.Element { max={100} /> { + changeShapesOutlinedBorders(event.target.checked, outlineColor); + }} + checked={outlined} > - Black borders + Outlined borders + changeShapesOutlinedBorders(outlined, color)} + value={outlineColor} + placement='top' + resetVisible={false} + > + + - + , window.document.body, ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index 14a13014e762..35de27e1c2cf 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -42,7 +42,8 @@ interface Props { opacity: number; colorBy: ColorBy; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; grid: boolean; @@ -125,7 +126,8 @@ export default class CanvasWrapperComponent extends React.PureComponent { opacity, colorBy, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, frameData, frameAngle, @@ -230,7 +232,8 @@ export default class CanvasWrapperComponent extends React.PureComponent { }, { once: true }); } - if (prevProps.opacity !== opacity || prevProps.blackBorders !== blackBorders + if (prevProps.opacity !== opacity || prevProps.outlined !== outlined + || prevProps.outlineColor !== outlineColor || prevProps.selectedOpacity !== selectedOpacity || prevProps.colorBy !== colorBy ) { this.updateShapesView(); @@ -602,7 +605,8 @@ export default class CanvasWrapperComponent extends React.PureComponent { annotations, opacity, colorBy, - blackBorders, + outlined, + outlineColor, } = this.props; for (const state of annotations) { @@ -625,7 +629,7 @@ export default class CanvasWrapperComponent extends React.PureComponent { } (shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 }); - (shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor }); + (shapeView as any).instance.stroke({ color: outlined ? outlineColor : shapeColor }); } } } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx index f91989ad3363..456826264d88 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx @@ -12,7 +12,7 @@ interface Props { listHeight: number; statesHidden: boolean; statesLocked: boolean; - statesCollapsed: boolean; + statesCollapsedAll: boolean; statesOrdering: StatesOrdering; sortedStatesID: number[]; switchLockAllShortcut: string; @@ -31,7 +31,7 @@ function ObjectListComponent(props: Props): JSX.Element { listHeight, statesHidden, statesLocked, - statesCollapsed, + statesCollapsedAll, statesOrdering, sortedStatesID, switchLockAllShortcut, @@ -50,7 +50,7 @@ function ObjectListComponent(props: Props): JSX.Element {
{ sortedStatesID.map((id: number): JSX.Element => ( - + ))}
diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/canvas-wrapper.tsx index 4591ad5a1600..513b289a1ef8 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -64,7 +64,8 @@ interface StateToProps { opacity: number; colorBy: ColorBy; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; grid: boolean; @@ -179,7 +180,8 @@ function mapStateToProps(state: CombinedState): StateToProps { opacity, colorBy, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, }, @@ -204,7 +206,8 @@ function mapStateToProps(state: CombinedState): StateToProps { opacity, colorBy, selectedOpacity, - blackBorders, + outlined, + outlineColor, showBitmap, showProjections, grid, diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx index e0b29e369c01..09701627318c 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/object-item.tsx @@ -30,6 +30,7 @@ import { shift } from 'utils/math'; interface OwnProps { clientID: number; + initialCollapsed: boolean; } interface StateToProps { @@ -101,7 +102,7 @@ function mapStateToProps(state: CombinedState, own: OwnProps): StateToProps { .indexOf(own.clientID); const collapsedState = typeof (statesCollapsed[own.clientID]) === 'undefined' - ? true : statesCollapsed[own.clientID]; + ? own.initialCollapsed : statesCollapsed[own.clientID]; return { objectState: states[index], diff --git a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx index 14e445deee97..58204bc282f1 100644 --- a/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx +++ b/cvat-ui/src/containers/annotation-page/standard-workspace/objects-side-bar/objects-list.tsx @@ -30,7 +30,8 @@ interface StateToProps { listHeight: number; statesHidden: boolean; statesLocked: boolean; - statesCollapsed: boolean; + statesCollapsedAll: boolean; + collapsedStates: Record; objectStates: any[]; annotationsFilters: string[]; colors: string[]; @@ -62,6 +63,7 @@ function mapStateToProps(state: CombinedState): StateToProps { filters: annotationsFilters, filtersHistory: annotationsFiltersHistory, collapsed, + collapsedAll, activatedStateID, zLayer: { min: minZLayer, @@ -95,25 +97,23 @@ function mapStateToProps(state: CombinedState): StateToProps { let statesHidden = true; let statesLocked = true; - let statesCollapsed = true; objectStates.forEach((objectState: any) => { - const { clientID, lock } = objectState; + const { lock } = objectState; if (!lock) { if (objectState.objectType !== ObjectType.TAG) { statesHidden = statesHidden && objectState.hidden; } statesLocked = statesLocked && objectState.lock; } - const stateCollapsed = clientID in collapsed ? collapsed[clientID] : true; - statesCollapsed = statesCollapsed && stateCollapsed; }); return { listHeight, statesHidden, statesLocked, - statesCollapsed, + statesCollapsedAll: collapsedAll, + collapsedStates: collapsed, objectStates, frameNumber, jobInstance, diff --git a/cvat-ui/src/reducers/annotation-reducer.ts b/cvat-ui/src/reducers/annotation-reducer.ts index b37e3cb67370..ca9567e1221d 100644 --- a/cvat-ui/src/reducers/annotation-reducer.ts +++ b/cvat-ui/src/reducers/annotation-reducer.ts @@ -67,6 +67,7 @@ const defaultState: AnnotationState = { statuses: [], }, collapsed: {}, + collapsedAll: true, states: [], filters: [], filtersHistory: JSON.parse( @@ -352,6 +353,7 @@ export default (state = defaultState, action: AnyAction): AnnotationState => { } = action.payload; const updatedCollapsedStates = { ...state.annotations.collapsed }; + const totalStatesCount = state.annotations.states.length; for (const objectState of states) { updatedCollapsedStates[objectState.clientID] = collapsed; } @@ -361,6 +363,8 @@ export default (state = defaultState, action: AnyAction): AnnotationState => { annotations: { ...state.annotations, collapsed: updatedCollapsedStates, + collapsedAll: states.length === totalStatesCount + ? collapsed : state.annotations.collapsedAll, }, }; } diff --git a/cvat-ui/src/reducers/interfaces.ts b/cvat-ui/src/reducers/interfaces.ts index 79f5531afae1..8f9e7af4fff9 100644 --- a/cvat-ui/src/reducers/interfaces.ts +++ b/cvat-ui/src/reducers/interfaces.ts @@ -361,6 +361,7 @@ export interface AnnotationState { activatedStateID: number | null; activatedAttributeID: number | null; collapsed: Record; + collapsedAll: boolean; states: any[]; filters: string[]; filtersHistory: string[]; @@ -452,7 +453,8 @@ export interface ShapesSettingsState { colorBy: ColorBy; opacity: number; selectedOpacity: number; - blackBorders: boolean; + outlined: boolean; + outlineColor: string; showBitmap: boolean; showProjections: boolean; } diff --git a/cvat-ui/src/reducers/settings-reducer.ts b/cvat-ui/src/reducers/settings-reducer.ts index eb4fd7555552..bb71a700a580 100644 --- a/cvat-ui/src/reducers/settings-reducer.ts +++ b/cvat-ui/src/reducers/settings-reducer.ts @@ -21,7 +21,8 @@ const defaultState: SettingsState = { colorBy: ColorBy.LABEL, opacity: 3, selectedOpacity: 30, - blackBorders: false, + outlined: false, + outlineColor: '#000000', showBitmap: false, showProjections: false, }, @@ -124,12 +125,13 @@ export default (state = defaultState, action: AnyAction): SettingsState => { }, }; } - case SettingsActionTypes.CHANGE_SHAPES_BLACK_BORDERS: { + case SettingsActionTypes.CHANGE_SHAPES_OUTLINED_BORDERS: { return { ...state, shapes: { ...state.shapes, - blackBorders: action.payload.blackBorders, + outlined: action.payload.outlined, + outlineColor: action.payload.color, }, }; }