satellite bugfix (#1816)

* satellite bugfix
This commit is contained in:
Yehor Butko 2019-04-23 17:46:54 +03:00 committed by GitHub
parent 78dedbb5bb
commit 4185f2d8ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 110 additions and 43 deletions

View File

@ -317,6 +317,7 @@ func (s *Service) UpdateAccount(ctx context.Context, info UserInfo) (err error)
ShortName: info.ShortName, ShortName: info.ShortName,
Email: email, Email: email,
PasswordHash: nil, PasswordHash: nil,
Status: auth.User.Status,
}) })
if err != nil { if err != nil {
return errs.New(internalErrMsg) return errs.New(internalErrMsg)

View File

@ -2,7 +2,7 @@
// See LICENSE for copying information. // See LICENSE for copying information.
<template> <template>
<div id="app"> <div id="app" v-on:click="onClick">
<router-view/> <router-view/>
<!-- Area for displaying notification --> <!-- Area for displaying notification -->
<NotificationArea/> <NotificationArea/>
@ -15,9 +15,34 @@ import NotificationArea from '@/components/notifications/NotificationArea.vue';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames'; import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
@Component({ @Component({
data: function() {
return {
ids: [
'accountDropdown',
'accountDropdownButton',
'projectDropdown',
'projectDropdownButton',
'sortTeamMemberByDropdown',
'sortTeamMemberByDropdownButton',
'notificationArea',
]
};
},
components: { components: {
NotificationArea NotificationArea
}, },
methods: {
onClick: function(e) {
let target: any = e.target;
while (target) {
if (this.$data.ids.includes(target.id)) {
return;
}
target = target.parentNode;
}
this.$store.dispatch(APP_STATE_ACTIONS.CLOSE_POPUPS);
}
}
}) })
export default class App extends Vue { export default class App extends Vue {

View File

@ -9,11 +9,11 @@
<h3 class="label-container__error" v-if="error" :style="style.errorStyle">{{error}}</h3> <h3 class="label-container__error" v-if="error" :style="style.errorStyle">{{error}}</h3>
</div> </div>
<input <input
v-bind:class="[error ? 'inputError' : null]" :class="{'inputError' : error}"
@input="onInput" @input="onInput"
:placeholder="this.$props.placeholder" :placeholder="placeholder"
v-model="value" v-model="value"
v-bind:type="[isPassword ? passwordType : textType]" :type="[isPassword ? passwordType : textType]"
:style="style.inputStyle"/> :style="style.inputStyle"/>
<!--2 conditions of eye image (crossed or not) --> <!--2 conditions of eye image (crossed or not) -->
<svg v-if="isPassword && !isPasswordShown" v-on:click="changeVision()" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg v-if="isPassword && !isPasswordShown" v-on:click="changeVision()" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
@ -141,8 +141,14 @@ h3 {
.label-container { .label-container {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-end;
padding-bottom: 8px;
flex-direction: row; flex-direction: row;
h3 {
margin-bottom: 0;
}
&__add-label { &__add-label {
margin-left: 5px; margin-left: 5px;
font-family: 'font_regular'; font-family: 'font_regular';

View File

@ -69,16 +69,9 @@ export const appStateModule = {
}, },
// Mutation that closes each popup/dropdown // Mutation that closes each popup/dropdown
[APP_STATE_MUTATIONS.CLOSE_ALL](state: any): void { [APP_STATE_MUTATIONS.CLOSE_ALL](state: any): void {
state.appState.isAddTeamMembersPopupShown = false;
state.appState.isNewProjectPopupShown = false;
state.appState.isProjectsDropdownShown = false; state.appState.isProjectsDropdownShown = false;
state.appState.isAccountDropdownShown = false; state.appState.isAccountDropdownShown = false;
state.appState.isDeleteProjectPopupShown = false;
state.appState.isDeleteAccountPopupShown = false;
state.appState.isSortProjectMembersByPopupShown = false; state.appState.isSortProjectMembersByPopupShown = false;
state.appState.isNewAPIKeyPopupShown = false;
state.appState.isSuccessfulRegistrationPopupShown = false;
state.appState.isSuccessfulProjectCreationPopupShown = false;
}, },
[APP_STATE_MUTATIONS.CHANGE_STATE](state: any, newFetchState: AppState): void { [APP_STATE_MUTATIONS.CHANGE_STATE](state: any, newFetchState: AppState): void {
state.appState.fetchState = newFetchState; state.appState.fetchState = newFetchState;

View File

@ -26,6 +26,7 @@ export const projectsModule = {
}, },
[PROJECTS_MUTATIONS.SELECT](state: any, projectID: string): void { [PROJECTS_MUTATIONS.SELECT](state: any, projectID: string): void {
const selected = state.projects.find((project: any) => project.id === projectID); const selected = state.projects.find((project: any) => project.id === projectID);
if (!selected) { if (!selected) {
return; return;
} }

View File

@ -1,4 +1,4 @@
// Copyright (C) 2018 Storj Labs, Inc. // Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information. // See LICENSE for copying information.
// getColor - returns color string depends on first symbol of first name // getColor - returns color string depends on first symbol of first name

View File

@ -5,11 +5,12 @@
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator'; import { Component, Vue } from 'vue-property-decorator';
import HeaderlessInput from '../../components/common/HeaderlessInput.vue'; import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import { LOADING_CLASSES } from '@/utils/constants/classConstants'; import { LOADING_CLASSES } from '@/utils/constants/classConstants';
import { forgotPasswordRequest } from '@/api/users'; import { forgotPasswordRequest } from '@/api/users';
import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames'; import { NOTIFICATION_ACTIONS } from '@/utils/constants/actionNames';
import ROUTES from '@/utils/constants/routerConstants'; import ROUTES from '@/utils/constants/routerConstants';
import { validateEmail } from '@/utils/validation';
@Component( @Component(
{ {
@ -17,6 +18,7 @@
return { return {
loadingClassName: LOADING_CLASSES.LOADING_OVERLAY, loadingClassName: LOADING_CLASSES.LOADING_OVERLAY,
email: '', email: '',
emailError: '',
}; };
}, },
components: { components: {
@ -25,24 +27,38 @@
methods: { methods: {
setEmail: function (value: string): void { setEmail: function (value: string): void {
this.$data.email = value; this.$data.email = value;
this.$data.emailError = '';
}, },
onSendConfigurations: async function (): Promise<any> { onSendConfigurations: async function (): Promise<any> {
if (!this.$data.email) { let self = this as any;
if (!self.validateFields()) {
return; return;
} }
let passwordRecoveryResponse = await forgotPasswordRequest(this.$data.email); let passwordRecoveryResponse = await forgotPasswordRequest(this.$data.email);
if (passwordRecoveryResponse.isSuccess) { if (!passwordRecoveryResponse.isSuccess) {
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Please look for instructions at your email');
} else {
this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, passwordRecoveryResponse.errorMessage); this.$store.dispatch(NOTIFICATION_ACTIONS.ERROR, passwordRecoveryResponse.errorMessage);
return;
} }
this.$store.dispatch(NOTIFICATION_ACTIONS.SUCCESS, 'Please look for instructions at your email');
}, },
onBackToLoginClick: function() { onBackToLoginClick: function() {
this.$router.push(ROUTES.LOGIN.path); this.$router.push(ROUTES.LOGIN.path);
}, },
onLogoClick: function () { onLogoClick: function () {
location.reload() location.reload();
},
validateFields: function (): boolean {
const isEmailValid = validateEmail(this.$data.email.trim());
if (!isEmailValid) {
this.$data.emailError = 'Invalid Email';
}
return isEmailValid;
} }
} }
}) })

View File

@ -8,8 +8,8 @@
<img class="image" src="../../../static/images/AuthImage.svg" alt="" > <img class="image" src="../../../static/images/AuthImage.svg" alt="" >
<div class="forgot-password-container__wrapper"> <div class="forgot-password-container__wrapper">
<div class="forgot-password-container__header"> <div class="forgot-password-container__header">
<img v-on:click="onLogoClick" class="forgot-password-container__logo" src="../../../static/images/Logo.svg" alt="logo"> <img @click="onLogoClick" class="forgot-password-container__logo" src="../../../static/images/Logo.svg" alt="logo">
<div class="forgot-password-container__login-button" v-on:click="onBackToLoginClick"> <div class="forgot-password-container__login-button" @click="onBackToLoginClick">
<p>Back to Login</p> <p>Back to Login</p>
</div> </div>
</div> </div>
@ -22,12 +22,12 @@
<HeaderlessInput <HeaderlessInput
class="full-input" class="full-input"
placeholder="Enter Your Email" placeholder="Enter Your Email"
:error="emailError"
@setData="setEmail" @setData="setEmail"
width="100%" width="100%"
height="46px" height="46px">
isWhite>
</HeaderlessInput> </HeaderlessInput>
<div class="forgot-password-area__submit-container" v-on:click.prevent="onSendConfigurations"> <div class="forgot-password-area__submit-container" @click.prevent="onSendConfigurations">
<div class="forgot-password-area__submit-container__send-button" > <div class="forgot-password-area__submit-container__send-button" >
<p>Send Configurations</p> <p>Send Configurations</p>
</div> </div>

View File

@ -160,7 +160,7 @@ body {
} }
&:hover { &:hover {
box-shadow: 0px 16px 24px #3A54DF; box-shadow: 0px 4px 20px rgba(35, 121, 236, 0.4);
} }
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright (C) 2019 Storj Labs, Inc. // Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information. // See LICENSE for copying information.
<template src="./login.html"></template> <template src="./login.html"></template>
@ -13,16 +13,18 @@ import { APP_STATE_ACTIONS, NOTIFICATION_ACTIONS } from '@/utils/constants/actio
import { getTokenRequest } from '@/api/users'; import { getTokenRequest } from '@/api/users';
import { LOADING_CLASSES } from '@/utils/constants/classConstants'; import { LOADING_CLASSES } from '@/utils/constants/classConstants';
import { AppState } from '@/utils/constants/appStateEnum'; import { AppState } from '@/utils/constants/appStateEnum';
import { validateEmail, validatePassword } from '@/utils/validation';
@Component({ @Component({
data: function () { data: function () {
return { return {
email: '', email: '',
password: '', password: '',
loadingClassName: LOADING_CLASSES.LOADING_OVERLAY, loadingClassName: LOADING_CLASSES.LOADING_OVERLAY,
loadingLogoClassName: LOADING_CLASSES.LOADING_LOGO, loadingLogoClassName: LOADING_CLASSES.LOADING_LOGO,
forgotPasswordRouterPath: ROUTES.FORGOT_PASSWORD.path, forgotPasswordRouterPath: ROUTES.FORGOT_PASSWORD.path,
emailError: '',
passwordError: '',
}; };
}, },
methods: { methods: {
@ -31,16 +33,20 @@ import { AppState } from '@/utils/constants/appStateEnum';
}, },
setEmail: function (value: string): void { setEmail: function (value: string): void {
this.$data.email = value; this.$data.email = value;
this.$data.emailError = '';
}, },
setPassword: function (value: string): void { setPassword: function (value: string): void {
this.$data.password = value; this.$data.password = value;
this.$data.passwordError = '';
}, },
activateLoadingOverlay: function(): void { activateLoadingOverlay: function(): void {
this.$data.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY_ACTIVE; this.$data.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY_ACTIVE;
this.$data.loadingLogoClassName = LOADING_CLASSES.LOADING_LOGO_ACTIVE; this.$data.loadingLogoClassName = LOADING_CLASSES.LOADING_LOGO_ACTIVE;
}, },
onLogin: async function (): Promise<any> { onLogin: async function (): Promise<any> {
if (!this.$data.email || !this.$data.password) { let self = this as any;
if (!self.validateFields()) {
return; return;
} }
@ -59,6 +65,21 @@ import { AppState } from '@/utils/constants/appStateEnum';
this.$router.push(ROUTES.PROJECT_DETAILS.path); this.$router.push(ROUTES.PROJECT_DETAILS.path);
}, 2000); }, 2000);
}, },
validateFields: function (): boolean {
let isNoErrors = true;
if (!validateEmail(this.$data.email.trim())) {
this.$data.emailError = 'Invalid Email';
isNoErrors = false;
}
if (!validatePassword(this.$data.password)) {
this.$data.passwordError = 'Invalid Password';
isNoErrors = false;
}
return isNoErrors;
},
onSignUpClick: function (): void { onSignUpClick: function (): void {
this.$router.push(ROUTES.REGISTER.path); this.$router.push(ROUTES.REGISTER.path);
}, },

View File

@ -1,14 +1,14 @@
<!--Copyright (C) 2019 Storj Labs, Inc.--> <!--Copyright (C) 2019 Storj Labs, Inc.-->
<!--See LICENSE for copying information.--> <!--See LICENSE for copying information.-->
<div class="login-container" v-on:keyup.enter="onLogin"> <div class="login-container" @keyup.enter="onLogin">
<div v-bind:class="loadingClassName"></div> <div :class="loadingClassName"></div>
<img v-bind:class="loadingLogoClassName" src="../../../static/images/LogoWhite.svg" alt="loading-logo"> <img :class="loadingLogoClassName" src="../../../static/images/LogoWhite.svg" alt="loading-logo">
<img class="image" src="../../../static/images/AuthImage.svg" alt="" > <img class="image" src="../../../static/images/AuthImage.svg" alt="" >
<div class="login-container__wrapper"> <div class="login-container__wrapper">
<div class="login-container__header"> <div class="login-container__header">
<img class="login-container__logo" src="../../../static/images/Logo.svg" alt="logo" v-on:click="onLogoClick"> <img class="login-container__logo" src="../../../static/images/Logo.svg" alt="logo" @click="onLogoClick">
<div class="login-container__register-button" v-on:click.prevent="onSignUpClick"> <div class="login-container__register-button" @click.prevent="onSignUpClick">
<p>Create Account</p> <p>Create Account</p>
</div> </div>
</div> </div>
@ -20,6 +20,7 @@
<HeaderlessInput <HeaderlessInput
class="login-area__email-input" class="login-area__email-input"
placeholder="Email" placeholder="Email"
:error="emailError"
@setData="setEmail" @setData="setEmail"
height="46px" height="46px"
width="100%"> width="100%">
@ -27,16 +28,17 @@
<HeaderlessInput <HeaderlessInput
class="login-area__password-input" class="login-area__password-input"
placeholder="Password" placeholder="Password"
:error="passwordError"
@setData="setPassword" @setData="setPassword"
width="100%" width="100%"
height="46px" height="46px"
isPassword> isPassword>
</HeaderlessInput> </HeaderlessInput>
<div class="login-area__submit-area"> <div class="login-area__submit-area">
<router-link v-bind:to="forgotPasswordRouterPath" class="login-area__navigation-area__nav-link" exact> <router-link :to="forgotPasswordRouterPath" class="login-area__navigation-area__nav-link" exact>
<h3><strong>Forgot password?</strong></h3> <h3><strong>Forgot password?</strong></h3>
</router-link> </router-link>
<div class="login-area__submit-area__login-button" v-on:click.prevent="onLogin"> <div class="login-area__submit-area__login-button" @click.prevent="onLogin">
<p>Log In</p> <p>Log In</p>
</div> </div>
</div> </div>

View File

@ -158,7 +158,7 @@
&__info-area { &__info-area {
width: 100%; width: 100%;
height: 42px; height: 42px;
margin-top: 300px; margin-top: 250px;
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
justify-content: flex-start; justify-content: flex-start;
@ -255,8 +255,8 @@
&__logo { &__logo {
position: absolute; position: absolute;
left: 50%; left: calc(50% - 104px);
top: 50%; top: calc(50% - 60px);
transform: translate(-50%); transform: translate(-50%);
display: block; display: block;
width: 240px; width: 240px;
@ -391,7 +391,7 @@
} }
&__info-area { &__info-area {
margin-top: 200px; margin-top: 150px;
font-size: 10px; font-size: 10px;
&__signature { &__signature {
@ -484,7 +484,7 @@
@media screen and (max-height: 850px) { @media screen and (max-height: 850px) {
.login-area { .login-area {
&__info-area { &__info-area {
margin-top: 200px; margin-top: 150px;
} }
} }
} }
@ -492,7 +492,7 @@
@media screen and (max-height: 700px) { @media screen and (max-height: 700px) {
.login-area { .login-area {
&__info-area { &__info-area {
margin-top: 150px; margin-top: 100px;
} }
} }
} }
@ -500,7 +500,7 @@
@media screen and (max-height: 610px) { @media screen and (max-height: 610px) {
.login-area { .login-area {
&__info-area { &__info-area {
margin-top: 100px; margin-top: 50px;
} }
} }
} }

View File

@ -102,7 +102,9 @@ import { createUserRequest } from '../../api/users';
onCreateClick: function (): any { onCreateClick: function (): any {
let self = this as any; let self = this as any;
if (!self.validateFields()) return; if (!self.validateFields()) {
return;
}
this.$data.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY_ACTIVE; this.$data.loadingClassName = LOADING_CLASSES.LOADING_OVERLAY_ACTIVE;

View File

@ -27,7 +27,7 @@ body {
span { span {
position: absolute; position: absolute;
top: 66px; top: 58px;
right: 43px; right: 43px;
} }
} }