Saving settings to local storage (#3017)

* Added saving settings to local storage

* Added tooltip

* Added CHANGELOG increased package version

* Changed CHANGELOG
main
Dmitry Kalinin 5 years ago committed by GitHub
parent 70a9071de8
commit f5277f9725
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [Market-1501](https://www.aitribune.com/dataset/2018051063) format support (<https://github.com/openvinotoolkit/cvat/pull/2869>) - [Market-1501](https://www.aitribune.com/dataset/2018051063) format support (<https://github.com/openvinotoolkit/cvat/pull/2869>)
- Ability of upload manifest for dataset with images (<https://github.com/openvinotoolkit/cvat/pull/2763>) - Ability of upload manifest for dataset with images (<https://github.com/openvinotoolkit/cvat/pull/2763>)
- Annotations filters UI using react-awesome-query-builder (https://github.com/openvinotoolkit/cvat/issues/1418) - Annotations filters UI using react-awesome-query-builder (https://github.com/openvinotoolkit/cvat/issues/1418)
- Storing settings in local storage to keep them between browser sessions (<https://github.com/openvinotoolkit/cvat/pull/3017>)
- [ICDAR](https://rrc.cvc.uab.es/?ch=2) format support (<https://github.com/openvinotoolkit/cvat/pull/2866>) - [ICDAR](https://rrc.cvc.uab.es/?ch=2) format support (<https://github.com/openvinotoolkit/cvat/pull/2866>)
- Added switcher to maintain poylgon crop behaviour (<https://github.com/openvinotoolkit/cvat/pull/3021>) - Added switcher to maintain poylgon crop behaviour (<https://github.com/openvinotoolkit/cvat/pull/3021>)

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import { AnyAction } from 'redux'; import { AnyAction } from 'redux';
import { GridColor, ColorBy } from 'reducers/interfaces'; import { GridColor, ColorBy, SettingsState } from 'reducers/interfaces';
export enum SettingsActionTypes { export enum SettingsActionTypes {
SWITCH_ROTATE_ALL = 'SWITCH_ROTATE_ALL', SWITCH_ROTATE_ALL = 'SWITCH_ROTATE_ALL',
@ -32,6 +32,7 @@ export enum SettingsActionTypes {
SWITCH_SHOWING_OBJECTS_TEXT_ALWAYS = 'SWITCH_SHOWING_OBJECTS_TEXT_ALWAYS', SWITCH_SHOWING_OBJECTS_TEXT_ALWAYS = 'SWITCH_SHOWING_OBJECTS_TEXT_ALWAYS',
CHANGE_CANVAS_BACKGROUND_COLOR = 'CHANGE_CANVAS_BACKGROUND_COLOR', CHANGE_CANVAS_BACKGROUND_COLOR = 'CHANGE_CANVAS_BACKGROUND_COLOR',
SWITCH_SETTINGS_DIALOG = 'SWITCH_SETTINGS_DIALOG', SWITCH_SETTINGS_DIALOG = 'SWITCH_SETTINGS_DIALOG',
SET_SETTINGS = 'SET_SETTINGS',
} }
export function changeShapesOpacity(opacity: number): AnyAction { export function changeShapesOpacity(opacity: number): AnyAction {
@ -268,3 +269,12 @@ export function switchSettingsDialog(show?: boolean): AnyAction {
}, },
}; };
} }
export function setSettings(settings: Partial<SettingsState>): AnyAction {
return {
type: SettingsActionTypes.SET_SETTINGS,
payload: {
settings,
},
};
}

@ -1,17 +1,22 @@
// Copyright (C) 2020 Intel Corporation // Copyright (C) 2020-2021 Intel Corporation
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
import './styles.scss'; import './styles.scss';
import React from 'react'; import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Tabs from 'antd/lib/tabs'; import Tabs from 'antd/lib/tabs';
import Text from 'antd/lib/typography/Text'; import Text from 'antd/lib/typography/Text';
import Modal from 'antd/lib/modal/Modal'; import Modal from 'antd/lib/modal/Modal';
import Button from 'antd/lib/button';
import notification from 'antd/lib/notification';
import Tooltip from 'antd/lib/tooltip';
import { PlayCircleOutlined, LaptopOutlined } from '@ant-design/icons'; import { PlayCircleOutlined, LaptopOutlined } from '@ant-design/icons';
import { setSettings } from 'actions/settings-actions';
import WorkspaceSettingsContainer from 'containers/header/settings-modal/workspace-settings'; import WorkspaceSettingsContainer from 'containers/header/settings-modal/workspace-settings';
import PlayerSettingsContainer from 'containers/header/settings-modal/player-settings'; import PlayerSettingsContainer from 'containers/header/settings-modal/player-settings';
import Button from 'antd/lib/button'; import { CombinedState } from 'reducers/interfaces';
interface SettingsModalProps { interface SettingsModalProps {
visible: boolean; visible: boolean;
@ -21,6 +26,44 @@ interface SettingsModalProps {
const SettingsModal = (props: SettingsModalProps): JSX.Element => { const SettingsModal = (props: SettingsModalProps): JSX.Element => {
const { visible, onClose } = props; const { visible, onClose } = props;
const settings = useSelector((state: CombinedState) => state.settings);
const dispatch = useDispatch();
const onSaveSettings = (): void => {
const settingsForSaving: any = {};
for (const [key, value] of Object.entries(settings)) {
if (typeof value === 'object') {
settingsForSaving[key] = value;
}
}
localStorage.setItem('clientSettings', JSON.stringify(settingsForSaving));
notification.success({
message: 'Settings was successfully saved',
});
};
useEffect(() => {
try {
const newSettings: any = {};
const loadedSettings = JSON.parse(localStorage.getItem('clientSettings') as string);
for (const [sectionKey, section] of Object.entries(settings)) {
for (const [key, value] of Object.entries(section)) {
let settedValue = value;
if (sectionKey in loadedSettings && key in loadedSettings[sectionKey]) {
settedValue = loadedSettings[sectionKey][key];
}
if (!(sectionKey in newSettings)) newSettings[sectionKey] = {};
newSettings[sectionKey][key] = settedValue;
}
}
dispatch(setSettings(newSettings));
} catch {
notification.error({
message: 'Failed to load settings from local storage',
});
}
}, []);
return ( return (
<Modal <Modal
title='Settings' title='Settings'
@ -29,9 +72,16 @@ const SettingsModal = (props: SettingsModalProps): JSX.Element => {
width={800} width={800}
className='cvat-settings-modal' className='cvat-settings-modal'
footer={( footer={(
<Button type='primary' onClick={onClose}> <>
<Tooltip title='Will save settings from this page and appearance settings on standard workspace page in browser'>
<Button type='primary' onClick={onSaveSettings}>
Save
</Button>
</Tooltip>
<Button type='default' onClick={onClose}>
Close Close
</Button> </Button>
</>
)} )}
> >
<div className='cvat-settings-tabs'> <div className='cvat-settings-tabs'>

@ -283,14 +283,20 @@ export default (state = defaultState, action: AnyAction): SettingsState => {
showDialog: typeof action.payload.show === 'undefined' ? !state.showDialog : action.payload.show, showDialog: typeof action.payload.show === 'undefined' ? !state.showDialog : action.payload.show,
}; };
} }
case SettingsActionTypes.SET_SETTINGS: {
return {
...state,
...action.payload.settings,
};
}
case BoundariesActionTypes.RESET_AFTER_ERROR: case BoundariesActionTypes.RESET_AFTER_ERROR:
case AnnotationActionTypes.GET_JOB_SUCCESS: { case AnnotationActionTypes.GET_JOB_SUCCESS: {
const { job } = action.payload; const { job } = action.payload;
return { return {
...defaultState, ...state,
player: { player: {
...defaultState.player, ...state.player,
resetZoom: job && job.task.mode === 'annotation', resetZoom: job && job.task.mode === 'annotation',
}, },
}; };

@ -1583,7 +1583,7 @@ The "Add rule" button adds a rule for objects display. A rule may use the follow
**Supported properties:** **Supported properties:**
| Properties | Supported values | Description | | Properties | Supported values | Description |
| ----------- | ------------------------------------------------------ | --------------------------------------------| | ------------ | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `Label` | all the label names that are in the task | label name | | `Label` | all the label names that are in the task | label name |
| `Type` | shape, track or tag | type of object | | `Type` | shape, track or tag | type of object |
| `Shape` | all shape types | type of shape | | `Shape` | all shape types | type of shape |

Loading…
Cancel
Save