From 106d30aee248f3bdc70d1673175fe815c817bae9 Mon Sep 17 00:00:00 2001 From: Architektor Date: Wed, 14 Mar 2018 04:06:27 +0300 Subject: [PATCH] feat(Authorization): support multiple accounts now all accounts are saved and can be choosen by pressing on hostname / jira instance name in header next to avatar ISSUES CLOSED: #71 --- app/actions/actionTypes/auth.js | 1 + app/actions/auth.js | 13 +- app/containers/Header/Header.jsx | 48 +++++- app/reducers/ui.js | 2 + app/sagas/auth.js | 112 +++++++++++-- app/sagas/index.js | 1 + app/sagas/initializeApp.js | 7 +- app/styles/index.jsx | 1 - app/types/auth.js | 3 + app/types/profile.js | 1 + app/types/ui.js | 2 + flow-typed/npm/ramda_v0.x.x.js | 278 +++++++++++++++++++++---------- package.json | 5 +- yarn.lock | 79 ++++++++- 14 files changed, 439 insertions(+), 114 deletions(-) diff --git a/app/actions/actionTypes/auth.js b/app/actions/actionTypes/auth.js index 67da07d91..d2633e955 100644 --- a/app/actions/actionTypes/auth.js +++ b/app/actions/actionTypes/auth.js @@ -5,3 +5,4 @@ export const LOGIN_OAUTH_REQUEST = 'auth/LOGIN_OAUTH_REQUEST'; export const LOGOUT_REQUEST = 'auth/LOGOUT_REQUEST'; export const ACCEPT_OAUTH = 'auth/ACCEPT_OAUTH'; export const DENY_OAUTH = 'auth/DENY_OAUTH'; +export const SWITCH_ACCOUNT = 'auth/SWITCH_ACCOUNT'; diff --git a/app/actions/auth.js b/app/actions/auth.js index e23b0e1ab..51d349ec3 100644 --- a/app/actions/auth.js +++ b/app/actions/auth.js @@ -20,8 +20,11 @@ export const loginOAuthRequest = (host: string): AuthAction => ({ host, }); -export const logoutRequest = (): AuthAction => ({ +export const logoutRequest = (payload: { + dontForget: boolean +} = { dontForget: false }): AuthAction => ({ type: actionTypes.LOGOUT_REQUEST, + payload, }); export const acceptOAuth = (code: string): AuthAction => ({ @@ -32,3 +35,11 @@ export const acceptOAuth = (code: string): AuthAction => ({ export const denyOAuth = (): AuthAction => ({ type: actionTypes.DENY_OAUTH, }); + +export const switchAccount = (payload: {| + host: string, + username: string, +|}) => ({ + type: actionTypes.SWITCH_ACCOUNT, + payload, +}); diff --git a/app/containers/Header/Header.jsx b/app/containers/Header/Header.jsx index 9fa540f54..1a6c0dfee 100644 --- a/app/containers/Header/Header.jsx +++ b/app/containers/Header/Header.jsx @@ -17,11 +17,13 @@ import type { import type { Connector, } from 'react-redux'; +import Tag from '@atlaskit/tag'; import type { User, Dispatch, } from 'types'; +import Lozenge from '@atlaskit/lozenge'; import DropdownMenu, { DropdownItemGroup, @@ -43,6 +45,9 @@ import { refreshWhite, } from 'data/svg'; import config from 'config'; +import EditorAddIcon from '@atlaskit/icon/glyph/editor/add'; + +import { transformValidHost } from '../../sagas/auth'; import { HeaderContainer, @@ -63,6 +68,10 @@ import { type Props = { userData: User, + accounts: Array<{| + host: string, + username: string, + |}>, host: string, updateAvailable: string, updateFetching: boolean, @@ -72,6 +81,7 @@ type Props = { const Header: StatelessFunctionalComponent = ({ userData, + accounts, host, updateAvailable, updateFetching, @@ -88,9 +98,40 @@ const Header: StatelessFunctionalComponent = ({ {userData.displayName} - - {host} - + + {host} + + } + > + {accounts.map((ac) => { + const isActive = transformValidHost(ac.host).host === host && + (ac.username === userData.emailAddress || + ac.username === userData.key || + ac.username === userData.name); + return ( + dispatch(authActions.switchAccount(ac))} + isDisabled={isActive} + elemAfter={isActive && Active} + > + + {ac.username} + + ); + })} + dispatch(authActions.logoutRequest({ dontForget: true }))} + > + + Add account + + + @@ -168,6 +209,7 @@ function mapStateToProps(state) { return { userData: getUserData(state), host: getUiState('host')(state), + accounts: getUiState('accounts')(state), updateAvailable: getUiState('updateAvailable')(state), updateFetching: getUiState('updateFetching')(state), issuesFetching: getResourceStatus( diff --git a/app/reducers/ui.js b/app/reducers/ui.js index 102a2840e..fcf42a42d 100644 --- a/app/reducers/ui.js +++ b/app/reducers/ui.js @@ -14,6 +14,7 @@ import { const initialState: UiState = { initializeInProcess: false, authorized: false, + accounts: [], authFormStep: 1, loginError: null, loginRequestInProcess: false, @@ -59,6 +60,7 @@ const initialState: UiState = { confirmDeleteWorklog: false, settings: false, worklog: false, + accounts: false, }, flags: [], diff --git a/app/sagas/auth.js b/app/sagas/auth.js index e30c0fea1..a0246175c 100644 --- a/app/sagas/auth.js +++ b/app/sagas/auth.js @@ -22,6 +22,7 @@ import { import { setToStorage, + getFromStorage, removeFromStorage, } from './storage'; import { @@ -29,6 +30,7 @@ import { } from './initializeApp'; import { throwError, + notify, } from './ui'; import createIpcChannel from './ipc'; @@ -99,6 +101,26 @@ export function* chronosBackendAuth({ } } +function storeInKeytar(payload, host) { + ipcRenderer.sendSync( + 'store-credentials', + { + ...payload, + host: host.hostname, + }, + ); +} + +function* saveAccount(payload: { host: string, username: string }): Generator<*, void, *> { + const { host } = payload; + let accounts = yield call(getFromStorage, 'accounts'); + if (!accounts) accounts = []; + if (!accounts.find(ac => ac.host === host)) { + accounts.push(payload); + yield call(setToStorage, 'accounts', accounts); + } +} + export function* basicAuthLoginForm(): Generator<*, void, *> { while (true) { try { @@ -141,30 +163,27 @@ export function* basicAuthLoginForm(): Generator<*, void, *> { */ yield call( setToStorage, - 'jira_credentials', + 'last_used_account', { username: payload.username, host: payload.host, }, ); yield call( - initialConfigureApp, + saveAccount, { - host: host.hostname, - protocol, + username: payload.username, + host: payload.host, }, ); yield call( - (): void => { - ipcRenderer.sendSync( - 'store-credentials', - { - ...payload, - host: host.hostname, - }, - ); + initialConfigureApp, + { + host: host.hostname, + protocol, }, ); + yield call(storeInKeytar, payload, host); yield put(uiActions.setUiState('loginRequestInProcess', false)); trackMixpanel('Jira login'); incrementMixpanel('Jira login', 1); @@ -259,7 +278,7 @@ export function* oAuthLoginForm(): Generator<*, *, *> { export function* logoutFlow(): Generator<*, *, *> { while (true) { - yield take(actionTypes.LOGOUT_REQUEST); + const { payload: { dontForget } } = yield take(actionTypes.LOGOUT_REQUEST); try { const { getGlobal } = remote; const { running, uploading } = getGlobal('sharedObj'); @@ -272,9 +291,9 @@ export function* logoutFlow(): Generator<*, *, *> { // eslint-disable-next-line no-alert window.alert('Currently app in process of saving worklog, wait few seconds please'); } - if (!running && !uploading) { + if (!running && !uploading && !dontForget) { yield call(removeFromStorage, 'desktop_tracker_jwt'); - yield call(removeFromStorage, 'jira_credentials'); + yield call(removeFromStorage, 'last_used_account'); } yield put({ type: actionTypes.__CLEAR_ALL_REDUCERS__, @@ -312,6 +331,69 @@ function getOauthChannelListener(channel, type) { }; } +export function* switchAccountFlow(): Generator<*, *, *> { + while (true) { + const { payload } = yield take(actionTypes.SWITCH_ACCOUNT); + try { + const { getGlobal } = remote; + const { running, uploading } = getGlobal('sharedObj'); + + if (running) { + // eslint-disable-next-line no-alert + window.alert('Tracking in progress, save worklog before logout!'); + } + if (uploading) { + // eslint-disable-next-line no-alert + window.alert('Currently app in process of saving worklog, wait few seconds please'); + } + if (!running && !uploading) { + const host = yield call(transformValidHost, payload.host); + const { + credentials, + error, + } = ipcRenderer.sendSync( + 'get-credentials', + { + username: payload.username, + host: host.hostname, + }, + ); + if (error) { + Raven.captureMessage('keytar error!', { + level: 'error', + extra: { + error: error.err, + }, + }); + yield call( + throwError, + error.err, + ); + if (error.platform === 'linux') { + yield fork( + notify, + { + type: 'libSecretError', + autoDelete: false, + }, + ); + } + } else { + yield put({ + type: actionTypes.__CLEAR_ALL_REDUCERS__, + }); + yield put(uiActions.setUiState('initializeInProcess', true)); + yield put(authActions.loginRequest({ ...payload, password: credentials.password })); + } + } + trackMixpanel('SwitchAccounts'); + incrementMixpanel('SwitchAccounts', 1); + } catch (err) { + yield call(throwError, err); + } + } +} + export function* createIpcAuthListeners(): Generator<*, *, *> { const oAuthAcceptedChannel = yield call(createIpcChannel, 'oauth-accepted'); const oAuthDeniedChannel = yield call(createIpcChannel, 'oauth-denied'); diff --git a/app/sagas/index.js b/app/sagas/index.js index 496355cf6..62d42fd67 100644 --- a/app/sagas/index.js +++ b/app/sagas/index.js @@ -31,6 +31,7 @@ export default function* rootSaga(): Generator<*, void, *> { fork(authSagas.basicAuthLoginForm), fork(authSagas.oAuthLoginForm), fork(authSagas.logoutFlow), + fork(authSagas.switchAccountFlow), // projects fork(projectSagas.watchFetchProjectStatusesRequest), diff --git a/app/sagas/initializeApp.js b/app/sagas/initializeApp.js index edcb8ff13..0b63bb400 100644 --- a/app/sagas/initializeApp.js +++ b/app/sagas/initializeApp.js @@ -109,6 +109,10 @@ 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)); + const issuesSourceId: Id | null = yield call(getFromStorage, 'issuesSourceId'); const issuesSourceType = yield call(getFromStorage, 'issuesSourceType'); const issuesSprintId: Id | null = yield call(getFromStorage, 'issuesSprintId'); @@ -153,6 +157,7 @@ export function* initialConfigureApp({ refetchFilterIssuesMarker: false, }, })); + yield put(uiActions.setUiState('initializeInProcess', false)); /* const isPaidChronosUser = yield select(getIsPaidUser); @@ -166,7 +171,7 @@ export function* initialConfigureApp({ function* getInitializeAppData(): Generator<*, *, *> { const basicAuthCredentials = yield call( getFromStorage, - 'jira_credentials', + 'last_used_account', ); const basicAuthDataExist = basicAuthCredentials !== null && diff --git a/app/styles/index.jsx b/app/styles/index.jsx index a4581216a..557baabe4 100644 --- a/app/styles/index.jsx +++ b/app/styles/index.jsx @@ -1,7 +1,6 @@ // @flow import styled from 'styled-components2'; - export const AppWrapper = styled.div` height: 100%; overflow: hidden; diff --git a/app/types/auth.js b/app/types/auth.js index 26aa6a3b7..3eb181c6a 100644 --- a/app/types/auth.js +++ b/app/types/auth.js @@ -17,6 +17,9 @@ export type AuthAction = |} | {| type: typeof actionTypes.LOGOUT_REQUEST, + payload: { + dontForget: boolean, + } |} | {| type: typeof actionTypes.ACCEPT_OAUTH, diff --git a/app/types/profile.js b/app/types/profile.js index af032432e..0b9713d2c 100644 --- a/app/types/profile.js +++ b/app/types/profile.js @@ -22,6 +22,7 @@ export type User = { items: Array, }, key: string, + name: string, locale?: string, self: string, timeZone: string, diff --git a/app/types/ui.js b/app/types/ui.js index a20112a77..0bc6f0406 100644 --- a/app/types/ui.js +++ b/app/types/ui.js @@ -56,6 +56,7 @@ export type RemainingEstimate = 'auto' | 'new' | 'manual' | 'leave'; export type UiState = {| initializeInProcess: boolean, authorized: boolean, + accounts: Array<{ host: string, username: string }>, authFormStep: number, loginError: null | string, loginRequestInProcess: boolean, @@ -101,6 +102,7 @@ export type UiState = {| confirmDeleteWorklog: boolean, settings: boolean, worklog: boolean, + accounts: boolean, |}, flags: Array, diff --git a/flow-typed/npm/ramda_v0.x.x.js b/flow-typed/npm/ramda_v0.x.x.js index 515b83baf..86afb0759 100644 --- a/flow-typed/npm/ramda_v0.x.x.js +++ b/flow-typed/npm/ramda_v0.x.x.js @@ -1,5 +1,5 @@ -// flow-typed signature: faac0f4abd84249ad0a0cb24383e72d3 -// flow-typed version: 03a0733eae/ramda_v0.x.x/flow_>=v0.62.x +// flow-typed signature: 0bfb497b3c0b55eb42ce36e313be23a2 +// flow-typed version: 973a250339/ramda_v0.x.x/flow_>=v0.62.x /* eslint-disable no-unused-vars, no-redeclare */ @@ -503,9 +503,18 @@ declare module ramda { >; declare var split: CurriedFunction2>; declare var test: CurriedFunction2; - declare var startsWith: CurriedFunction2, string, boolean>; + declare var startsWith: CurriedFunction2< + string | Array, + string | Array, + boolean + >; + declare var endsWith: CurriedFunction2< + string | Array, + string | Array, + boolean + >; declare function toLower(a: string): string; - declare function toString(a: any): string; + declare function toString(x: any): string; declare function toUpper(a: string): string; declare function trim(a: string): string; @@ -876,7 +885,10 @@ declare module ramda { ...rest: Array ): (xs: T) => T; - declare function sortWith>(fns: Array<(a: V, b: V) => number>, xs: T): T; + declare function sortWith>( + fns: Array<(a: V, b: V) => number>, + xs: T + ): T; declare function sortWith>( fns: Array<(a: V, b: V) => number>, ...rest: Array @@ -980,10 +992,6 @@ declare module ramda { declare function length(xs: Array): number; - declare function mergeAll( - objs: Array<{ [key: string]: any }> - ): { [key: string]: any }; - declare function reverse | string>(xs: V): V; declare type Reduce = (( @@ -1060,6 +1068,43 @@ declare module ramda { xs: Array ): A; + declare function reduceWhile( + pred: (acc: A, curr: B) => boolean, + ...rest: Array + ): (( + fn: (a: A, b: B) => A, + ...rest: Array + ) => ( + init: A, + ...rest: Array + ) => ( + xs: Array + ) => A & + (( + fn: (a: A, b: B) => A, + ...rest: Array + ) => (init: A, xs: Array) => A)) & + (( + fn: (a: A, b: B) => A, + init: A, + ...rest: Array + ) => (xs: Array) => A) & + ((fn: (a: A, b: B) => A, init: A, xs: Array) => A); + + declare function reduceWhile( + pred: (acc: A, curr: B) => boolean, + fn: (a: A, b: B) => A, + ...rest: Array + ): ((init: A, ...rest: Array) => (xs: Array) => A) & + ((init: A, xs: Array) => A); + + declare function reduceWhile( + fn: (acc: A, curr: B) => boolean, + fn: (a: A, b: B) => A, + init: A, + xs: Array + ): A; + declare function scan( fn: (acc: A, elem: B) => A, ...rest: Array @@ -1220,6 +1265,24 @@ declare module ramda { declare function identical(x: T, ...rest: Array): (y: T) => boolean; declare function identical(x: T, y: T): boolean; + declare function innerJoin( + pred: (a: A, b: B) => boolean, + ...rest: Array + ): ( + a: Array, + ...rest: Array + ) => (b: Array) => Array & ((a: Array, b: Array) => Array); + declare function innerJoin( + pred: (a: A, b: B) => boolean, + a: Array, + ...rest: Array + ): (b: Array) => Array; + declare function innerJoin( + pred: (a: A, b: B) => boolean, + a: Array, + b: Array + ): Array; + declare function intersection(x: Array, y: Array): Array; declare function intersection(x: Array): (y: Array) => Array; @@ -1402,12 +1465,21 @@ declare module ramda { declare function keys(o: Object): Array; - /* TODO - lens - lensIndex - lensPath - lensProp - */ + declare type Lens = (x: T) => V; + + declare function lens( + getter: (s: T) => U, + setter: (a: U, s: T) => V + ): Lens; + declare function lens( + getter: (s: T) => U + ): (setter: (a: U, s: T) => V) => Lens; + + declare function lensIndex(n: number): Lens; + + declare function lensPath(a: Array): Lens; + + declare function lensProp(str: string): Lens; declare function mapObjIndexed( fn: (val: A, key: string, o: Object) => B, @@ -1418,78 +1490,70 @@ declare module ramda { ...args: Array ): (o: { [key: string]: A }) => { [key: string]: B }; - declare function merge(o1: A, ...rest: Array): (o2: B) => A & B; - declare function merge(o1: A, o2: B): A & B; + declare type Merge = ((a: A, b: B) => A & B) & + ((a: A, ...rest: Array) => (b: B) => A & B); + + declare var merge: Merge; declare function mergeAll( os: Array<{ [k: string]: T }> ): { [k: string]: T }; - declare function mergeWith< - T, - S, - R, - A: { [k: string]: T }, - B: { [k: string]: S } - >( - fn: (v1: T, v2: S) => R - ): ((o1: A, ...rest: Array) => (o2: B) => A & B) & - ((o1: A, o2: B) => A & B); - declare function mergeWith< - T, - S, - R, - A: { [k: string]: T }, - B: { [k: string]: S } - >( - fn: (v1: T, v2: S) => R, - o1: A, - o2: B - ): A & B; - declare function mergeWith< - T, - S, - R, - A: { [k: string]: T }, - B: { [k: string]: S } - >( - fn: (v1: T, v2: S) => R, - o1: A, - ...rest: Array - ): (o2: B) => A & B; + declare var mergeDeepLeft: Merge; - declare function mergeWithKey< - T, - S, - R, - A: { [k: string]: T }, - B: { [k: string]: S } - >( - fn: (key: $Keys, v1: T, v2: S) => R - ): ((o1: A, ...rest: Array) => (o2: B) => A & B) & - ((o1: A, o2: B) => A & B); - declare function mergeWithKey< - T, - S, - R, - A: { [k: string]: T }, - B: { [k: string]: S } - >( - fn: (key: $Keys, v1: T, v2: S) => R, - o1: A, - o2: B - ): A & B; - declare function mergeWithKey< - T, - S, - R, + declare var mergeDeepRight: ((a: A, b: B) => B & A) & + ((a: A, ...rest: Array) => (b: B) => B & A); + + declare type MergeWith = (( + fn: (a: T, b: T) => T, + a: A, + b: B + ) => A & B) & + (( + fn: (a: T, b: T) => T, + ...rest: Array + ) => (a: A, ...rest: Array) => (b: B) => A & B) & + (( + fn: (a: T, b: T) => T, + ...rest: Array + ) => (a: A, b: B) => A & B) & + (( + fn: (a: T, b: T) => T, + a: A, + ...rest: Array + ) => (b: B) => A & B); + + declare type MergeWithKey = (< + S: string, A: { [k: string]: T }, - B: { [k: string]: S } + B: { [k: string]: T }, + T >( - fn: (key: $Keys, v1: T, v2: S) => R, - o1: A, - ...rest: Array - ): (o2: B) => A & B; + fn: (s: S, a: T, b: T) => T, + a: A, + b: B + ) => A & B) & + (( + fn: (s: S, a: T, b: T) => T, + ...rest: Array + ) => (a: A, b: B) => A & B) & + (( + fn: (s: S, a: T, b: T) => T, + ...rest: Array + ) => (a: A, ...rest: Array) => (b: B) => A & B) & + (( + fn: (s: S, a: T, b: T) => T, + a: A, + ...rest: Array + ) => (b: B) => A & B); + + declare var mergeDeepWith: MergeWith; + + declare var mergeDeepWithKey: MergeWithKey; + + declare var mergeWith: MergeWith; + + declare var mergeWithKey: MergeWithKey; declare function objOf( key: string, @@ -1498,12 +1562,16 @@ declare module ramda { declare function objOf(key: string, val: T): { [key: string]: T }; declare function omit( - keys: Array<$Keys>, + keys: Array, ...rest: Array ): (val: T) => Object; - declare function omit(keys: Array<$Keys>, val: T): Object; + declare function omit(keys: Array, val: T): Object; - // TODO over + declare function over(lens: Lens, x: (any) => mixed, val: V): U; + declare function over( + lens: Lens, + ...rest: Array + ): ((x: (any) => mixed, ...rest: Array) => (val: V) => U) & ((x: (any) => mixed, val: V) => U); declare function path( p: Array, @@ -1602,16 +1670,16 @@ declare module ramda { declare function propOr( or: T, ...rest: Array - ): ((p: $Keys, ...rest: Array) => (o: A) => V | T) & - ((p: $Keys, o: A) => V | T); + ): ((p: string, ...rest: Array) => (o: A) => V | T) & + ((p: string, o: A) => V | T); declare function propOr( or: T, - p: $Keys, + p: string, ...rest: Array ): (o: A) => V | T; declare function propOr( or: T, - p: $Keys, + p: string, o: A ): V | T; @@ -1626,7 +1694,11 @@ declare module ramda { o: O ): Array<$ElementType>; - // TODO set + declare function set(lens: Lens, x: T, val: V): U; + declare function set( + lens: Lens, + ...rest: Array + ): ((x: (any) => mixed, ...rest: Array) => (val: V) => U) & ((x: (any) => mixed, val: V) => U); declare function toPairs( o: O @@ -1657,7 +1729,8 @@ declare module ramda { o: $Shape ): boolean; - // TODO view + declare function view(lens: Lens, val: T): V; + declare function view(lens: Lens): (val: T) => V; // *Function declare var __: $npm$ramda$Placeholder; @@ -1692,6 +1765,12 @@ declare module ramda { spec: T ): (...args: A) => NestedObject; + declare function applyTo( + a: A, + ...rest: Array + ): (fn: (x: A) => B) => B; + declare function applyTo(a: A, fn: (x: A) => B): B; + declare function binary( fn: (...args: Array) => T ): (x: any, y: any) => T; @@ -1769,6 +1848,15 @@ declare module ramda { declare function memoize) => B>(fn: T): T; + declare function memoizeWith( + keyFn: (x: A) => string, + ...rest: Array + ): (fn: (x: B) => B) => A; + declare function memoizeWith( + keyFn: (x: A) => string, + fn: (x: B) => B + ): A; + declare function nAry( arity: number, fn: (...args: Array) => T @@ -1776,6 +1864,18 @@ declare module ramda { declare function nthArg(n: number): (...args: Array) => T; + declare var o: (( + fn1: (b: B) => C, + ...rest: void[] + ) => ((fn2: (a: A) => B, ...rest: void[]) => (x: A) => C) & + ((fn2: (a: A) => B, x: A) => C)) & + (( + fn1: (b: B) => C, + fn2: (a: A) => B, + ...rest: void[] + ) => (x: A) => C) & + ((fn1: (b: B) => C, fn2: (a: A) => B, x: A) => C); + declare function of(x: T): Array; declare function once) => B>(fn: T): T; @@ -1976,4 +2076,4 @@ declare module ramda { fn: (x: S) => V, x: T | S ): T | V; -} +} \ No newline at end of file diff --git a/package.json b/package.json index 1cff91200..e0e18ee4f 100644 --- a/package.json +++ b/package.json @@ -136,6 +136,7 @@ "webpack-sentry-plugin": "1.14.1" }, "dependencies": { + "@atlaskit/badge": "6.2.2", "@atlaskit/button": "6.3.1", "@atlaskit/calendar": "3.1.0", "@atlaskit/checkbox": "1.2.1", @@ -148,9 +149,11 @@ "@atlaskit/inline-dialog": "5.2.0", "@atlaskit/inline-edit": "4.5.14", "@atlaskit/input": "1.6.3", + "@atlaskit/lozenge": "3.5.2", "@atlaskit/modal-dialog": "3.3.10", "@atlaskit/single-select": "3.2.2", "@atlaskit/spinner": "4.1.2", + "@atlaskit/tag": "3.1.3", "@atlaskit/tooltip": "8.2.0", "bufferutil": "3.0.3", "calculate-size": "1.1.1", @@ -201,4 +204,4 @@ "path": "node_modules/cz-customizable" } } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 71aaaffc5..fd8d2dd48 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37,6 +37,14 @@ clone-deep "^3.0.1" prop-types "^15.5.10" +"@atlaskit/badge@6.2.2": + version "6.2.2" + resolved "https://registry.yarnpkg.com/@atlaskit/badge/-/badge-6.2.2.tgz#e9d57a9bcaefb73269cd678ade16f99f371f70e8" + dependencies: + "@atlaskit/theme" "^2.3.4" + babel-runtime "^6.26.0" + styled-components "^1.4.6" + "@atlaskit/blanket@^4.0.7": version "4.0.9" resolved "https://registry.yarnpkg.com/@atlaskit/blanket/-/blanket-4.0.9.tgz#1c2bc78fca2964833d4e7440bdea86afe99791b7" @@ -262,6 +270,14 @@ dependencies: styled-components "^1.4.6" +"@atlaskit/lozenge@3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@atlaskit/lozenge/-/lozenge-3.5.2.tgz#9f6a4837dbdc9e6d287cddde591b597c835261b4" + dependencies: + "@atlaskit/util-shared-styles" "^2.10.3" + babel-runtime "^6.26.0" + styled-components "^1.4.6" + "@atlaskit/modal-dialog@3.3.10": version "3.3.10" resolved "https://registry.yarnpkg.com/@atlaskit/modal-dialog/-/modal-dialog-3.3.10.tgz#2fa3f44f170fc5c1d0441ba05a676183dcb5fa66" @@ -309,6 +325,18 @@ react-transition-group "^2.2.1" styled-components "^1.4.6" +"@atlaskit/tag@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@atlaskit/tag/-/tag-3.1.3.tgz#9e4a52c5e77ee168f688459de3e28afde4428daa" + dependencies: + "@atlaskit/icon" "^10.9.2" + "@atlaskit/theme" "^2.3.4" + "@atlaskit/util-common" "^1.5.2" + babel-runtime "^6.26.0" + create-error "^0.3.1" + debug "^2.2.0" + styled-components "^1.4.6" + "@atlaskit/theme@^2.3.0", "@atlaskit/theme@^2.3.1", "@atlaskit/theme@^2.3.3", "@atlaskit/theme@^2.3.4": version "2.3.4" resolved "https://registry.yarnpkg.com/@atlaskit/theme/-/theme-2.3.4.tgz#781c70b7b439e7f67b0259cc6292f0654491489d" @@ -336,6 +364,14 @@ react-transition-group "^2.2.1" styled-components "^1.4.6" +"@atlaskit/util-common@^1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@atlaskit/util-common/-/util-common-1.5.2.tgz#ae9e96c540aa2517ca922542333ac24eb3473cbc" + dependencies: + babel-runtime "^6.11.6" + create-error "^0.3.1" + keycode "^2.1.2" + "@atlaskit/util-readme@^3.6.5": version "3.6.5" resolved "https://registry.yarnpkg.com/@atlaskit/util-readme/-/util-readme-3.6.5.tgz#33a8e0c90108f6589a62d89974e1f7d09e7dcee7" @@ -354,6 +390,12 @@ babel-runtime "^6.11.6" styled-components "^1.4.6" +"@atlaskit/util-shared-styles@^2.10.3": + version "2.10.7" + resolved "https://registry.yarnpkg.com/@atlaskit/util-shared-styles/-/util-shared-styles-2.10.7.tgz#d5b4a38f42daa08154e43a3e85f7605182903b41" + dependencies: + babel-runtime "^6.11.6" + "@babel/code-frame@7.0.0-beta.36": version "7.0.0-beta.36" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.36.tgz#2349d7ec04b3a06945ae173280ef8579b63728e4" @@ -2681,6 +2723,10 @@ create-error-class@^3.0.0: dependencies: capture-stack-trace "^1.0.0" +create-error@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/create-error/-/create-error-0.3.1.tgz#69810245a629e654432bf04377360003a5351a23" + create-hash@^1.1.0, create-hash@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.3.tgz#606042ac8b9262750f483caddab0f5819172d8fd" @@ -5455,7 +5501,7 @@ isurl@^1.0.0-alpha5: resolved "https://codeload.github.com/web-pal/jira-connector/tar.gz/56c56015371481701b7ae6fc2fd64ddf07a13b78" dependencies: oauth "^0.9.12" - request "^2.83.0" + request "^2.51.0" js-base64@^2.1.9: version "2.4.3" @@ -5572,7 +5618,7 @@ keyboardevents-areequal@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz#88191ec738ce9f7591c25e9056de928b40277194" -keycode@^2.1.7: +keycode@^2.1.2, keycode@^2.1.7: version "2.1.9" resolved "https://registry.yarnpkg.com/keycode/-/keycode-2.1.9.tgz#964a23c54e4889405b4861a5c9f0480d45141dfa" @@ -7906,7 +7952,7 @@ request@2.81.0: tunnel-agent "^0.6.0" uuid "^3.0.0" -request@^2.45.0, request@^2.79.0, request@^2.83.0: +request@^2.45.0, request@^2.79.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -7933,6 +7979,33 @@ request@^2.45.0, request@^2.79.0, request@^2.83.0: tunnel-agent "^0.6.0" uuid "^3.1.0" +request@^2.51.0: + version "2.85.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"