Skip to content

Commit

Permalink
Merge branch 'release/2.6.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
ilya-lopukhin committed Mar 19, 2018
2 parents b008e0d + 8553608 commit 00c188f
Show file tree
Hide file tree
Showing 20 changed files with 185 additions and 27 deletions.
24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
<a name="2.6.0"></a>
# [2.6.0](https://github.com/web-pal/chronos-timetracker/compare/v2.5.20...v2.6.0) (2018-03-15)


### Bug Fixes

* accoutin deletion on logout ([280ff32](https://github.com/web-pal/chronos-timetracker/commit/280ff32))
* feature acknowlegement ([1721ffb](https://github.com/web-pal/chronos-timetracker/commit/1721ffb))
* hide login to exiting account button if no accounts present ([40956d3](https://github.com/web-pal/chronos-timetracker/commit/40956d3))
* issue form with multiple accounts ([290ef83](https://github.com/web-pal/chronos-timetracker/commit/290ef83))
* keys warning ([f146205](https://github.com/web-pal/chronos-timetracker/commit/f146205))
* memoized resourceMap list selectors ([54e00a2](https://github.com/web-pal/chronos-timetracker/commit/54e00a2))
* recent workogs with just created new issue ([4bcb9d4](https://github.com/web-pal/chronos-timetracker/commit/4bcb9d4))
* retry on connection refused ([db85971](https://github.com/web-pal/chronos-timetracker/commit/db85971))


### Features

* **Authorization:** support multiple accounts ([106d30a](https://github.com/web-pal/chronos-timetracker/commit/106d30a)), closes [#71](https://github.com/web-pal/chronos-timetracker/issues/71)
* make account step on login ([9d9ade9](https://github.com/web-pal/chronos-timetracker/commit/9d9ade9))
* make new feature presentation component ([ff76777](https://github.com/web-pal/chronos-timetracker/commit/ff76777))



<a name="2.5.20"></a>
## [2.5.20](https://github.com/web-pal/chronos-timetracker/compare/v2.5.19...v2.5.20) (2018-03-07)

Expand Down
1 change: 1 addition & 0 deletions app/actions/actionTypes/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export const INSTALL_UPDATE_REQUEST = 'ui/INSTALL_UPDATE_REQUEST';
export const ADD_FLAG = 'ui/ADD_FLAG';
export const DELETE_FLAG = 'ui/DELETE_FLAG';
export const ISSUE_WORKLOGS_SCROLL_TO_INDEX_REQUEST = 'ui/ISSUE_WORKLOGS_SCROLL_TO_INDEX_REQUEST';
export const ACKNOWLEDGE_FEATURE = 'ui/ACKNOWLEDGE_FEATURE';
6 changes: 6 additions & 0 deletions app/actions/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,9 @@ export const issueWorklogsScrollToIndexRequest = (
issueId,
});

export const acknowlegdeFeature = (payload: {
featureId: string,
}): UiAction => ({
type: actionTypes.ACKNOWLEDGE_FEATURE,
payload,
});
51 changes: 51 additions & 0 deletions app/components/FeatureHighlight/FeatureHighlight.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import type {
Node,
} from 'react';
import { connect } from 'react-redux';
import type { Dispatch } from 'react-redux';
import Tooltip from '@atlaskit/tooltip';
import Lozenge from '@atlaskit/lozenge';
import { getUiState } from 'selectors';
import { uiActions } from 'actions';

import { FeatureContainer } from './styled';

type Props = {
dispatch: Dispatch,
children: Node,
description: string,
acknowlegdedFeatures: Array<string>,
id: string,
};

const FeatureHighlight = ({
dispatch,
acknowlegdedFeatures,
description,
children,
id,
}: Props) => (!acknowlegdedFeatures.includes(id)
? (
<Tooltip
content={description}
>
<FeatureContainer
onClick={() => dispatch(uiActions.acknowlegdeFeature({ featureId: 'multiAccounts' }))}
>
{children}
<Lozenge appearance="new">New</Lozenge>
</FeatureContainer>
</Tooltip>
) : (
children
));

const connector = connect(
state => ({
acknowlegdedFeatures: getUiState('acknowlegdedFeatures')(state),
}),
dispatch => ({ dispatch }),
);

export default connector(FeatureHighlight);
1 change: 1 addition & 0 deletions app/components/FeatureHighlight/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default from './FeatureHighlight';
11 changes: 11 additions & 0 deletions app/components/FeatureHighlight/styled/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled from 'styled-components2';

export const FeatureContainer = styled.div`
position: relative;
& > span:last-child {
position: absolute;
top: 0;
right: 0;
transform: translateX(100%);
}
`;
1 change: 1 addition & 0 deletions app/components/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export TextField from './TextField';
export SingleSelect from './SingleSelect';
export * as ReduxFormComponents from './ReduxFormComponents';
export RemainingEstimatePicker from './RemainingEstimatePicker';
export FeatureHighlight from './FeatureHighlight';
2 changes: 1 addition & 1 deletion app/containers/AuthForm/EmailStep/EmailStep.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class EmailStep extends Component<Props> {
<Field
name="username"
type="text"
placeholder="Enter email"
placeholder="Enter username"
withRef
ref={(el) => {
this.usernameInput = el;
Expand Down
44 changes: 41 additions & 3 deletions app/containers/Header/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import {
} from 'data/svg';
import config from 'config';

import FeatureHighlight from '../../components/FeatureHighlight';

import {
HeaderContainer,
ProfileContainer,
Expand Down Expand Up @@ -88,9 +90,45 @@ const Header: StatelessFunctionalComponent<Props> = ({
<ProfileName>
{userData.displayName}
</ProfileName>
<ProfileTeam>
{host}
</ProfileTeam>
<FeatureHighlight
id="multiAccounts"
description="You can switch between your accounts here."
>
<DropdownMenu
triggerType="default"
position="right top"
trigger={
<ProfileTeam>
{host} <ChevronDownIcon />
</ProfileTeam>
}
>
{accounts.map((ac) => {
const isActive = transformValidHost(ac.host).host === host &&
(ac.username === userData.emailAddress ||
ac.username === userData.key ||
ac.username === userData.name);
return (
<DropdownItem
key={`${ac.host}:${ac.username}`}
onClick={() => dispatch(authActions.switchAccount(ac))}
isDisabled={isActive}
elemAfter={isActive && <Lozenge appearance="success">Active</Lozenge>}
>
<Tag text={ac.host} color="teal" />
{ac.username}
</DropdownItem>
);
})}
<DropdownItem
onClick={() => dispatch(authActions.logoutRequest({ dontForget: true }))}
>
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
<EditorAddIcon /> Add account
</span>
</DropdownItem>
</DropdownMenu>
</FeatureHighlight>
</ProfileInfo>
</ProfileContainer>

Expand Down
2 changes: 1 addition & 1 deletion app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Chronos",
"productName": "Chronos",
"version": "2.5.20",
"version": "2.6.0",
"description": "Native app for time-tracking fully integrated with JIRA",
"main": "./main.prod.js",
"scripts": {
Expand Down
2 changes: 2 additions & 0 deletions app/reducers/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
const initialState: UiState = {
initializeInProcess: false,
authorized: false,
accounts: [],
acknowlegdedFeatures: [],
authFormStep: 1,
loginError: null,
loginRequestInProcess: false,
Expand Down
1 change: 1 addition & 0 deletions app/sagas/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,6 @@ export default function* rootSaga(): Generator<*, void, *> {
fork(uiSagas.watchUiStateChange),
fork(uiSagas.watchScrollToIndexRequest),
fork(uiSagas.watchSetIssuesFilter),
fork(uiSagas.newFeaturesFlow),
]);
}
8 changes: 8 additions & 0 deletions app/sagas/initializeApp.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ export function* initialConfigureApp({
yield call(initializeMixpanel);
yield call(identifyInSentryAndMixpanel, host, userData);

let accounts = yield call(getFromStorage, 'accounts');
if (!accounts) accounts = [];
yield put(uiActions.setUiState('accounts', accounts));

let acknowlegdedFeatures = yield call(getFromStorage, 'acknowlegdedFeatures');
if (!acknowlegdedFeatures) acknowlegdedFeatures = [];
yield put(uiActions.setUiState('acknowlegdedFeatures', acknowlegdedFeatures));

const issuesSourceId: Id | null = yield call(getFromStorage, 'issuesSourceId');
const issuesSourceType = yield call(getFromStorage, 'issuesSourceType');
const issuesSprintId: Id | null = yield call(getFromStorage, 'issuesSprintId');
Expand Down
5 changes: 4 additions & 1 deletion app/sagas/issues.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,10 @@ export function* fetchIssues({
resolve();
}
} catch (err) {
if (err.code === 'ETIMEDOUT' && !tryCount) {
if (
['ETIMEDOUT', 'ECONNREFUSED', 'ESOCKETTIMEDOUT'].includes(err.code) &&
!tryCount
) {
yield fork(
fetchIssues,
{
Expand Down
13 changes: 13 additions & 0 deletions app/sagas/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {

import {
setToStorage,
getFromStorage,
} from './storage';
import {
issueSelectFlow,
Expand Down Expand Up @@ -219,3 +220,15 @@ export function* watchSetIssuesFilter(): Generator<*, *, *> {
onIssuesFilterChange,
);
}

export function* newFeaturesFlow(): Generator<*, *, *> {
function* flow({ payload: { featureId } }): Generator<*, void, *> {
let acknowlegdedFeatures = yield call(getFromStorage, 'acknowlegdedFeatures');
if (!acknowlegdedFeatures) acknowlegdedFeatures = [];
acknowlegdedFeatures.push(featureId);
yield call(setToStorage, 'acknowlegdedFeatures', acknowlegdedFeatures);
yield call(delay, 10000);
yield put(uiActions.setUiState('acknowlegdedFeatures', acknowlegdedFeatures));
}
yield takeLatest(actionTypes.ACKNOWLEDGE_FEATURE, flow);
}
2 changes: 1 addition & 1 deletion app/selectors/resources.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const getResourceMappedList = (
resourceName: string,
listName: string,
) => {
if (resourceSelectors[resourceName]) {
if (resourceSelectors[`${resourceName}${listName}`]) {
return resourceSelectors[`${resourceName}${listName}`];
}
resourceSelectors[`${resourceName}${listName}`] =
Expand Down
7 changes: 7 additions & 0 deletions app/types/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,20 @@ export type UiAction =
|} |
{|
type: typeof actionTypes.INSTALL_UPDATE_REQUEST,
|} | {|
type: typeof actionTypes.ACKNOWLEDGE_FEATURE,
payload: {
featureId: string,
},
|};

export type RemainingEstimate = 'auto' | 'new' | 'manual' | 'leave';

export type UiState = {|
initializeInProcess: boolean,
authorized: boolean,
accounts: Array<{ host: string, username: string }>,
acknowlegdedFeatures: Array<string>,
authFormStep: number,
loginError: null | string,
loginRequestInProcess: boolean,
Expand Down
10 changes: 5 additions & 5 deletions flow-typed/npm/redux_v3.x.x.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// flow-typed signature: ec7daead5cb4fec5ab25fedbedef29e8
// flow-typed version: 2c04631d20/redux_v3.x.x/flow_>=v0.55.x
// flow-typed signature: cca4916b0213065533df8335c3285a4a
// flow-typed version: cab04034e7/redux_v3.x.x/flow_>=v0.55.x

declare module 'redux' {

Expand Down Expand Up @@ -27,7 +27,7 @@ declare module 'redux' {
replaceReducer(nextReducer: Reducer<S, A>): void
};

declare export type Reducer<S, A> = (state: S, action: A) => S;
declare export type Reducer<S, A> = (state: S | void, action: A) => S;

declare export type CombinedReducer<S, A> = (state: $Shape<S> & {} | void, action: A) => S;

Expand All @@ -43,7 +43,7 @@ declare module 'redux' {
declare export type StoreEnhancer<S, A, D = Dispatch<A>> = (next: StoreCreator<S, A, D>) => StoreCreator<S, A, D>;

declare export function createStore<S, A, D>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
declare export function createStore<S, A, D>(reducer: Reducer<S, A>, preloadedState: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;
declare export function createStore<S, A, D>(reducer: Reducer<S, A>, preloadedState?: S, enhancer?: StoreEnhancer<S, A, D>): Store<S, A, D>;

declare export function applyMiddleware<S, A, D>(...middlewares: Array<Middleware<S, A, D>>): StoreEnhancer<S, A, D>;

Expand All @@ -56,4 +56,4 @@ declare module 'redux' {
declare export function combineReducers<O: Object, A>(reducers: O): CombinedReducer<$ObjMap<O, <S>(r: Reducer<S, any>) => S>, A>;

declare export var compose: $Compose;
}
}
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "Chronos",
"version": "2.5.20",
"version": "2.6.0",
"description": "Full functionality time tracking software with direct JIRA integration",
"scripts": {
"build": "concurrently \"yarn build-main\" \"yarn build-renderer\"",
Expand Down Expand Up @@ -151,7 +151,8 @@
"@atlaskit/modal-dialog": "3.3.10",
"@atlaskit/single-select": "3.2.2",
"@atlaskit/spinner": "4.1.2",
"@atlaskit/tooltip": "8.2.0",
"@atlaskit/tag": "3.1.3",
"@atlaskit/tooltip": "8.3.2",
"bufferutil": "3.0.3",
"calculate-size": "1.1.1",
"electron-json-storage": "4.0.2",
Expand Down Expand Up @@ -201,4 +202,4 @@
"path": "node_modules/cz-customizable"
}
}
}
}
14 changes: 2 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@
styled-components "^1.4.6"
uuid "^3.1.0"

"@atlaskit/layer-manager@^2.6.0", "@atlaskit/layer-manager@^2.7.1", "@atlaskit/layer-manager@^2.7.2", "@atlaskit/layer-manager@^2.7.4":
"@atlaskit/layer-manager@^2.7.1", "@atlaskit/layer-manager@^2.7.2", "@atlaskit/layer-manager@^2.7.4":
version "2.7.4"
resolved "https://registry.yarnpkg.com/@atlaskit/layer-manager/-/layer-manager-2.7.4.tgz#ad96a1335d7b77db7af8fe4b30ae8171c4febf83"
dependencies:
Expand Down Expand Up @@ -316,17 +316,7 @@
prop-types "^15.5.10"
styled-components "^1.4.6"

"@atlaskit/tooltip@8.2.0":
version "8.2.0"
resolved "https://registry.yarnpkg.com/@atlaskit/tooltip/-/tooltip-8.2.0.tgz#6484f2943d2856903bd4ec1519a459f1dd569d35"
dependencies:
"@atlaskit/layer-manager" "^2.6.0"
"@atlaskit/theme" "^2.3.1"
react-deprecate "^0.1.0"
react-transition-group "^2.2.1"
styled-components "^1.4.6"

"@atlaskit/tooltip@^8.3.2":
"@atlaskit/tooltip@8.3.2", "@atlaskit/tooltip@^8.3.2":
version "8.3.2"
resolved "https://registry.yarnpkg.com/@atlaskit/tooltip/-/tooltip-8.3.2.tgz#ed166fb9f46680e672f2404b310bcf5fd344d8f6"
dependencies:
Expand Down

0 comments on commit 00c188f

Please sign in to comment.