web/satellite: merge HeaderedInput and HeaderlessInput components

Merged two components into single one to have single source of truth.
Also this may fix some go-rod test problems.

Change-Id: Iffa86d1b3c24a0e2a551335ecda721a93ff616e3
This commit is contained in:
Vitalii 2022-05-06 17:50:20 +03:00 committed by Vitalii Shpital
parent 289be4f1e9
commit cce0a18bf8
30 changed files with 239 additions and 562 deletions

View File

@ -24,7 +24,7 @@
<div>
<p>This action cannot be undone.</p>
</div>
<headerless-input
<VInput
placeholder="Type the name of the access"
@setData="setConfirmedInput"
/>
@ -59,7 +59,7 @@
import { Component, Vue } from 'vue-property-decorator';
import VButton from '@/components/common/VButton.vue';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue'
import VInput from '@/components/common/VInput.vue'
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
@ -70,7 +70,7 @@ import { AccessGrant } from '@/types/accessGrants';
@Component({
components: {
VButton,
HeaderlessInput,
VInput,
CloseCrossIcon,
},
})

View File

@ -46,7 +46,7 @@
/>
</div>
<div v-else class="create-passphrase__container__value-area__password">
<HeaderedInput
<VInput
placeholder="Enter encryption passphrase here"
:error="errorMessage"
@setData="onChangePassphrase"
@ -92,7 +92,7 @@ import { AnalyticsEvent } from "@/utils/constants/analyticsEventNames";
import { AnalyticsHttpApi } from "@/api/analytics";
import VButton from "@/components/common/VButton.vue";
import HeaderedInput from "@/components/common/HeaderedInput.vue";
import VInput from "@/components/common/VInput.vue";
import BackIcon from '@/../static/images/accessGrants/back.svg';
import GreenWarningIcon from '@/../static/images/accessGrants/greenWarning.svg';
@ -103,7 +103,7 @@ import GreenWarningIcon from '@/../static/images/accessGrants/greenWarning.svg';
BackIcon,
GreenWarningIcon,
VButton,
HeaderedInput,
VInput,
},
})
export default class CreatePassphraseStep extends Vue {

View File

@ -6,7 +6,7 @@
<BackIcon class="enter-passphrase__back-icon" @click="onBackClick" />
<h1 class="enter-passphrase__title">Enter Encryption Passphrase</h1>
<p class="enter-passphrase__sub-title">Enter the passphrase you most recently generated for Access Grants</p>
<HeaderedInput
<VInput
label="Encryption Passphrase"
placeholder="Enter your passphrase here"
:error="errorMessage"
@ -26,7 +26,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import BackIcon from '@/../static/images/accessGrants/back.svg';
@ -37,7 +37,7 @@ import { MetaUtils } from '@/utils/meta';
// @vue/component
@Component({
components: {
HeaderedInput,
VInput,
VButton,
BackIcon,
},

View File

@ -5,7 +5,7 @@
<div class="name-step" :class="{ 'border-radius': isOnboardingTour }">
<h1 class="name-step__title" aria-roledescription="name-ag-title">Name Your Access Grant</h1>
<p class="name-step__sub-title">Enter a name for your new Access grant to get started.</p>
<HeaderedInput
<VInput
label="Access Grant Name"
placeholder="Enter a name here..."
:error="errorMessage"
@ -36,7 +36,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import { RouteConfig } from '@/router';
@ -47,7 +47,7 @@ import { AccessGrant } from '@/types/accessGrants';
// @vue/component
@Component({
components: {
HeaderedInput,
VInput,
VButton,
},
})

View File

@ -9,7 +9,7 @@
<ChangePasswordIcon class="change-password-popup__form-container__svg" />
<h2 class="change-password-popup__form-container__main-label-text">Change Password</h2>
</div>
<HeaderlessInput
<VInput
class="full-input"
label="Old Password"
placeholder="Enter Old Password"
@ -18,7 +18,7 @@
@setData="setOldPassword"
/>
<div class="password-input">
<HeaderlessInput
<VInput
class="full-input"
label="New Password"
placeholder="Enter New Password"
@ -33,7 +33,7 @@
:is-shown="isPasswordStrengthShown"
/>
</div>
<HeaderlessInput
<VInput
class="full-input"
label="Confirm Password"
placeholder="Confirm Password"
@ -67,7 +67,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import PasswordStrength from '@/components/common/PasswordStrength.vue';
import VButton from '@/components/common/VButton.vue';
@ -83,7 +83,7 @@ import { Validator } from '@/utils/validation';
components: {
ChangePasswordIcon,
CloseCrossIcon,
HeaderlessInput,
VInput,
VButton,
PasswordStrength,
},

View File

@ -11,7 +11,7 @@
</div>
<h2 class="edit-profile-popup__form-container__main-label-text">Edit Profile</h2>
</div>
<HeaderedInput
<VInput
label="Full Name"
placeholder="Enter Full Name"
:error="fullNameError"
@ -44,7 +44,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
@ -57,7 +57,7 @@ import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
@Component({
components: {
CloseCrossIcon,
HeaderedInput,
VInput,
VButton,
},
})

View File

@ -11,7 +11,7 @@
src="@/../static/images/account/billing/coupon.png"
alt="Coupon"
>
<HeaderlessInput
<VInput
:label="inputLabel"
placeholder="Enter Coupon Code"
height="52px"
@ -68,7 +68,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import ValidationMessage from '@/components/common/ValidationMessage.vue';
import VButton from '@/components/common/VButton.vue';
@ -82,7 +82,7 @@ import { PAYMENTS_ACTIONS } from '@/store/modules/payments';
@Component({
components: {
VButton,
HeaderlessInput,
VInput,
CheckIcon,
ValidationMessage,
},

View File

@ -48,7 +48,7 @@
/>
</div>
<div v-else class="encrypt-container__functional__enter">
<HeaderlessInput
<VInput
label="Your Passphrase"
placeholder="Enter a passphrase here..."
:error="enterError"
@ -104,7 +104,7 @@ import { Download } from "@/utils/download";
import VButton from '@/components/common/VButton.vue';
import VInfo from "@/components/common/VInfo.vue";
import HeaderlessInput from "@/components/common/HeaderlessInput.vue";
import VInput from "@/components/common/VInput.vue";
import VCheckbox from "@/components/common/VCheckbox.vue";
import EncryptIcon from "@/../static/images/objects/encrypt.svg";
@ -117,7 +117,7 @@ import InfoIcon from "@/../static/images/common/smallGreyInfo.svg";
InfoIcon,
VInfo,
VButton,
HeaderlessInput,
VInput,
VCheckbox,
},
})

View File

@ -1,347 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
<div class="input-wrap" :aria-roledescription="roleDescription">
<div class="label-container">
<ErrorIcon v-if="error" />
<p v-if="isLabelShown" class="label-container__label" :style="style.labelStyle">{{ label }}</p>
<p v-if="error" class="label-container__error" aria-roledescription="error-text" :style="style.errorStyle">{{ error }}</p>
</div>
<input
v-model="value"
class="headerless-input"
:class="{'inputError' : error, 'password': isPassword}"
:placeholder="placeholder"
:type="type"
:style="style.inputStyle"
:optionsShown="optionsShown"
:disabled="isDisabled"
@input="onInput"
@change="onInput"
@focus="showPasswordStrength"
@blur="hidePasswordStrength"
@click="showOptions"
@optionsList="optionsList"
>
<!-- Shown if there are input choice options -->
<InputCaret v-if="optionsList.length > 0" class="headerless-input__caret" />
<ul v-if="optionsShown" v-click-outside="hideOptions" class="headerless-input__options-wrapper">
<li
v-for="(option, index) in optionsList"
:key="index"
class="headerless-input__option"
@click="chooseOption(option)"
>
{{ option }}
</li>
</ul>
<!-- end of option render logic-->
<!--2 conditions of eye image (crossed or not) -->
<PasswordHiddenIcon
v-if="isPasswordHiddenState"
class="input-wrap__image"
@click="changeVision"
/>
<PasswordShownIcon
v-if="isPasswordShownState"
class="input-wrap__image"
@click="changeVision"
/>
<!-- end of image-->
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import InputCaret from '@/../static/images/common/caret.svg';
import PasswordHiddenIcon from '@/../static/images/common/passwordHidden.svg';
import PasswordShownIcon from '@/../static/images/common/passwordShown.svg';
import ErrorIcon from '@/../static/images/register/ErrorInfo.svg';
// Custom input component for login page
// @vue/component
@Component({
components: {
InputCaret,
ErrorIcon,
PasswordHiddenIcon,
PasswordShownIcon,
},
})
export default class HeaderlessInput extends Vue {
private readonly textType: string = 'text';
private readonly passwordType: string = 'password';
private type: string = this.textType;
private isPasswordShown = false;
public value: string;
@Prop({default: ''})
protected readonly initValue: string;
@Prop({default: ''})
protected readonly label: string;
@Prop({default: 'default'})
protected readonly placeholder: string;
@Prop({default: false})
protected readonly isPassword: boolean;
@Prop({default: '48px'})
protected readonly height: string;
@Prop({default: '100%'})
protected readonly width: string;
@Prop({default: ''})
protected readonly error: string;
@Prop({default: Number.MAX_SAFE_INTEGER})
protected readonly maxSymbols: number;
@Prop({default: () => []})
protected readonly optionsList: string[];
@Prop({default: false})
protected optionsShown: boolean;
@Prop({default: false})
protected inputClicked: boolean;
@Prop({default: false})
private readonly isWhite: boolean;
@Prop({default: false})
private readonly isDisabled: boolean;
@Prop({default: false})
private readonly withIcon: boolean;
@Prop({default: 'input-container'})
private readonly roleDescription: boolean;
public created() {
this.type = this.isPassword ? this.passwordType : this.textType;
this.value = this.initValue;
}
/**
* Used to set default value from parent component.
* @param value
*/
public setValue(value: string): void {
this.value = value;
}
public showPasswordStrength(): void {
this.$emit('showPasswordStrength');
}
public hidePasswordStrength(): void {
this.$emit('hidePasswordStrength');
}
/**
* triggers on input.
*/
public onInput(event: Event): void {
const target = event.target as HTMLInputElement;
if (target.value.length > this.maxSymbols) {
this.value = target.value.slice(0, this.maxSymbols);
} else {
this.value = target.value;
}
this.$emit('setData', this.value);
}
/**
* Triggers input type between text and password to show/hide symbols.
*/
public changeVision(): void {
this.isPasswordShown = !this.isPasswordShown;
this.type = this.isPasswordShown ? this.textType : this.passwordType;
}
/**
* Chose a dropdown option as the input value.
*/
public chooseOption(option: string): void {
this.value = option;
this.$emit('setData', this.value);
this.optionsShown = false;
}
/**
* Show dropdown options when the input is clicked, if they exist.
*/
public showOptions(): void {
if (this.optionsList.length > 0) {
this.optionsShown = true;
this.inputClicked = true;
}
}
/**
* Hide the dropdown options from view when there is a click outside of the dropdown.
*/
public hideOptions(): void {
if (this.optionsList.length > 0 && !this.inputClicked && this.optionsShown) {
this.optionsShown = false;
this.inputClicked = false;
}
this.inputClicked = false;
}
public get isLabelShown(): boolean {
return !!(!this.error && this.label);
}
public get isPasswordHiddenState(): boolean {
return this.isPassword && !this.isPasswordShown;
}
public get isPasswordShownState(): boolean {
return this.isPassword && this.isPasswordShown;
}
/**
* Returns style objects depends on props.
*/
protected get style(): Record<string, unknown> {
return {
inputStyle: {
width: this.width,
height: this.height,
padding: this.withIcon ? '0 30px 0 50px' : '',
},
labelStyle: {
color: this.isWhite ? 'white' : '#354049',
},
errorStyle: {
color: this.isWhite ? 'white' : '#FF5560',
},
};
}
}
</script>
<style scoped lang="scss">
.input-wrap {
position: relative;
width: 100%;
font-family: 'font_regular', sans-serif;
&__image {
position: absolute;
right: 25px;
bottom: 5px;
transform: translateY(-50%);
z-index: 20;
cursor: pointer;
&:hover .input-wrap__image__path {
fill: #2683ff !important;
}
}
.headerless-input {
font-size: 16px;
line-height: 21px;
resize: none;
height: 46px;
padding: 0 30px 0 0;
text-indent: 20px;
border: 1px solid rgb(56 75 101 / 40%);
border-radius: 6px;
box-sizing: border-box;
&__caret {
position: absolute;
right: 28px;
bottom: 18px;
}
&__options-wrapper {
border: 1px solid rgb(56 75 101 / 40%);
position: absolute;
width: calc(100% - 5px);
top: 70px;
padding: 0;
background: #fff;
z-index: 21;
border-radius: 0 0 6px 6px;
list-style: none;
border-top: none;
height: 176px;
margin-top: 0;
}
&__option {
cursor: pointer;
padding: 20px 22px;
&:hover {
background: #2582ff;
color: #fff;
}
}
}
.headerless-input::placeholder {
color: #384b65;
opacity: 0.4;
}
&:focus-within {
.headerless-input {
position: relative;
z-index: 22;
&__options-wrapper {
border-top: 3px solid #145ecc;
}
&__caret {
z-index: 23;
}
}
}
}
.label-container {
display: flex;
justify-content: flex-start;
align-items: flex-end;
padding-bottom: 8px;
flex-direction: row;
&__label {
font-size: 16px;
line-height: 21px;
color: #354049;
margin-bottom: 0;
}
&__add-label {
margin-left: 5px;
font-size: 16px;
line-height: 21px;
color: rgb(56 75 101 / 40%);
}
&__error {
font-size: 16px;
margin: 18px 0 0 10px;
}
}
.inputError::placeholder {
color: #eb5757;
opacity: 0.4;
}
.error {
color: #ff5560;
margin-left: 10px;
}
.password {
padding-right: 75px;
}
</style>

View File

@ -30,7 +30,7 @@
width="450px"
height="50px"
:on-press="onResendEmailButtonClick"
:is-disabled="secondsToWait != 0"
:is-disabled="secondsToWait !== 0"
/>
</div>
<p class="register-success-area__form-container__contact">

View File

@ -1,4 +1,4 @@
// Copyright (C) 2019 Storj Labs, Inc.
// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
<template>
@ -21,13 +21,14 @@
v-if="isMultiline"
:id="label"
v-model="value"
class="headered-textarea"
class="textarea"
:placeholder="placeholder"
:style="style.inputStyle"
:rows="5"
:cols="40"
:maxlength="maxSymbols"
:disabled="disabled"
wrap="hard"
:disabled="isDisabled"
@input="onInput"
@change="onInput"
/>
@ -35,33 +36,50 @@
v-if="!isMultiline"
:id="label"
v-model="value"
class="headered-input"
class="input"
:placeholder="placeholder"
:type="[isPassword ? 'password': 'text']"
:type="type"
:style="style.inputStyle"
:disabled="isDisabled"
:maxlength="maxSymbols"
:disabled="disabled"
@input="onInput"
@change="onInput"
@focus="showPasswordStrength"
@blur="hidePasswordStrength"
>
<!--2 conditions of eye image (crossed or not) -->
<PasswordHiddenIcon
v-if="isPasswordHiddenState"
class="input-container__image"
@click="changeVision"
/>
<PasswordShownIcon
v-if="isPasswordShownState"
class="input-container__image"
@click="changeVision"
/>
<!-- end of image-->
</div>
</template>
<script lang="ts">
import { Component, Prop } from 'vue-property-decorator';
import { Component, Prop, Vue } from 'vue-property-decorator';
import PasswordHiddenIcon from '@/../static/images/common/passwordHidden.svg';
import PasswordShownIcon from '@/../static/images/common/passwordShown.svg';
import ErrorIcon from '@/../static/images/register/ErrorInfo.svg';
import HeaderlessInput from './HeaderlessInput.vue';
// Custom input component with labeled header
// @vue/component
@Component({
components: {
ErrorIcon,
PasswordHiddenIcon,
PasswordShownIcon,
},
})
// TODO: merge these two components to have one single source of truth.
export default class HeaderedInput extends HeaderlessInput {
export default class VInput extends Vue {
@Prop({default: ''})
private readonly additionalLabel: string;
@Prop({default: 0})
@ -74,6 +92,96 @@ export default class HeaderedInput extends HeaderlessInput {
private readonly isMultiline: boolean;
@Prop({default: false})
private readonly isLoading: boolean;
@Prop({default: ''})
protected readonly initValue: string;
@Prop({default: ''})
protected readonly label: string;
@Prop({default: 'default'})
protected readonly placeholder: string;
@Prop({default: false})
protected readonly isPassword: boolean;
@Prop({default: '48px'})
protected readonly height: string;
@Prop({default: '100%'})
protected readonly width: string;
@Prop({default: ''})
protected readonly error: string;
@Prop({default: Number.MAX_SAFE_INTEGER})
protected readonly maxSymbols: number;
@Prop({default: false})
private readonly isWhite: boolean;
@Prop({default: false})
private readonly withIcon: boolean;
@Prop({default: false})
private readonly disabled: boolean;
@Prop({default: 'input-container'})
private readonly roleDescription: boolean;
private readonly textType: string = 'text';
private readonly passwordType: string = 'password';
private type: string = this.textType;
private isPasswordShown = false;
public value: string;
public created() {
this.type = this.isPassword ? this.passwordType : this.textType;
this.value = this.initValue;
}
public showPasswordStrength(): void {
this.$emit('showPasswordStrength');
}
public hidePasswordStrength(): void {
this.$emit('hidePasswordStrength');
}
/**
* triggers on input.
*/
public onInput(event: Event): void {
const target = event.target as HTMLInputElement;
this.value = target.value;
this.$emit('setData', this.value);
}
/**
* Triggers input type between text and password to show/hide symbols.
*/
public changeVision(): void {
this.isPasswordShown = !this.isPasswordShown;
this.type = this.isPasswordShown ? this.textType : this.passwordType;
}
public get isPasswordHiddenState(): boolean {
return this.isPassword && !this.isPasswordShown;
}
public get isPasswordShownState(): boolean {
return this.isPassword && this.isPasswordShown;
}
/**
* Returns style objects depends on props.
*/
protected get style(): Record<string, unknown> {
return {
inputStyle: {
width: this.width,
height: this.height,
padding: this.withIcon ? '0 30px 0 50px' : '',
},
labelStyle: {
color: this.isWhite ? 'white' : '#354049',
},
errorStyle: {
color: this.isWhite ? 'white' : '#FF5560',
},
};
}
}
</script>
@ -85,6 +193,20 @@ export default class HeaderedInput extends HeaderlessInput {
margin-top: 10px;
width: 100%;
font-family: 'font_regular', sans-serif;
position: relative;
&__image {
position: absolute;
right: 25px;
bottom: 5px;
transform: translateY(-50%);
z-index: 20;
cursor: pointer;
&:hover .input-container__image__path {
fill: #2683ff !important;
}
}
}
.label-container {
@ -139,8 +261,8 @@ export default class HeaderedInput extends HeaderlessInput {
}
}
.headered-input,
.headered-textarea {
.input,
.textarea {
font-size: 16px;
line-height: 21px;
resize: none;
@ -159,7 +281,7 @@ export default class HeaderedInput extends HeaderlessInput {
}
}
.headered-textarea {
.textarea {
padding: 15px 22px;
text-indent: 0;
line-height: 26px;

View File

@ -3,7 +3,7 @@
<template>
<div v-if="showMessage" class="validation-message__wrapper" :class="{'success-message__wrapper' : isValid, 'error-message__wrapper' : !isValid}">
<ErrorIcon v-if="invalid" class="error-message__icon" />
<ErrorIcon v-if="!isValid" class="error-message__icon" />
<p v-if="isValid" class="success-message__text validation-message__text">{{ successMessage }}</p>
<p v-if="!isValid" class="error-message__text validation-message__text">{{ errorMessage }}</p>
</div>
@ -21,7 +21,6 @@ import ErrorIcon from '@/../static/images/common/errorNotice.svg';
},
})
export default class ValidationMessage extends Vue {
@Prop({default: 'Valid!'})
protected readonly successMessage: string;
@Prop({default: 'Invalid. Please Try again'})
@ -30,7 +29,6 @@ export default class ValidationMessage extends Vue {
protected readonly isValid: boolean;
@Prop({default: false})
protected readonly showMessage: boolean;
}
</script>

View File

@ -10,14 +10,14 @@
<p class="modal__info">
To open a bucket and view your files, please enter the encryption passphrase you saved upon creating this bucket.
</p>
<HeaderlessInput
<VInput
class="modal__input"
label="Bucket Name"
:init-value="bucketName"
role-description="bucket"
is-disabled="true"
disabled="true"
/>
<HeaderlessInput
<VInput
label="Encryption Passphrase"
placeholder="Enter a passphrase here"
:error="enterError"
@ -57,7 +57,7 @@ import { AccessGrant, EdgeCredentials } from "@/types/accessGrants";
import { ACCESS_GRANTS_ACTIONS } from "@/store/modules/accessGrants";
import VModal from "@/components/common/VModal.vue";
import HeaderlessInput from "@/components/common/HeaderlessInput.vue";
import VInput from "@/components/common/VInput.vue";
import VButton from "@/components/common/VButton.vue";
import Icon from "@/../static/images/objects/openBucket.svg";
@ -65,7 +65,7 @@ import Icon from "@/../static/images/objects/openBucket.svg";
// @vue/component
@Component({
components: {
HeaderlessInput,
VInput,
VModal,
Icon,
VButton,

View File

@ -67,7 +67,7 @@
/>
</div>
<div v-else class="encrypt-container__functional__enter">
<headerless-input
<v-input
label="Your Passphrase"
placeholder="Enter a passphrase here..."
:error="enterError"
@ -120,7 +120,7 @@ import { generateMnemonic } from "bip39";
import { Download } from "@/utils/download";
import VButton from '@/components/common/VButton.vue';
import HeaderlessInput from "@/components/common/HeaderlessInput.vue";
import VInput from "@/components/common/VInput.vue";
import VCheckbox from "@/components/common/VCheckbox.vue";
import BucketIcon from "@/../static/images/objects/bucketCreation.svg";
@ -140,7 +140,7 @@ enum GenerationSteps {
KeyIcon,
FingerprintIcon,
VButton,
HeaderlessInput,
VInput,
VCheckbox,
},
})

View File

@ -15,7 +15,7 @@
Buckets are used to store your files. Its recommended that every bucket should have its own encryption passphrase.
</p>
</div>
<headered-input
<v-input
label="Bucket Name"
placeholder="Enter a name here..."
:error="nameError"
@ -53,7 +53,7 @@ import { Validator } from "@/utils/validation";
import { LocalData } from "@/utils/localData";
import { BUCKET_ACTIONS } from "@/store/modules/buckets";
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import VLoader from "@/components/common/VLoader.vue";
@ -62,7 +62,7 @@ import BucketIcon from "@/../static/images/objects/bucketCreation.svg";
// @vue/component
@Component({
components: {
HeaderedInput,
VInput,
VButton,
BucketIcon,
VLoader,

View File

@ -10,7 +10,7 @@
<WarningIcon />
<p class="objects-popup__container__info__msg">Only lowercase alphanumeric characters are allowed.</p>
</div>
<HeaderedInput
<VInput
class="objects-popup__container__input"
label="Bucket Name"
placeholder="Enter bucket name"
@ -35,7 +35,7 @@
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import CloseCrossIcon from '@/../static/images/common/closeCross.svg';
@ -44,7 +44,7 @@ import WarningIcon from '@/../static/images/objects/warning.svg';
// @vue/component
@Component({
components: {
HeaderedInput,
VInput,
VButton,
CloseCrossIcon,
WarningIcon,

View File

@ -13,7 +13,7 @@
</template>
<template #content class="permissions">
<p class="permissions__msg">Access Grants are keys that allow access to upload, delete, and view your projects data.</p>
<HeaderedInput
<VInput
label="Access Grant Name"
placeholder="Enter a name here..."
:error="errorMessage"
@ -33,7 +33,7 @@ import { ACCESS_GRANTS_ACTIONS} from "@/store/modules/accessGrants";
import { APP_STATE_MUTATIONS } from "@/store/mutationConstants";
import CLIFlowContainer from "@/components/onboardingTour/steps/common/CLIFlowContainer.vue";
import HeaderedInput from "@/components/common/HeaderedInput.vue";
import VInput from "@/components/common/VInput.vue";
import Icon from '@/../static/images/onboardingTour/accessGrant.svg';
@ -41,7 +41,7 @@ import Icon from '@/../static/images/onboardingTour/accessGrant.svg';
@Component({
components: {
CLIFlowContainer,
HeaderedInput,
VInput,
Icon,
}
})

View File

@ -12,7 +12,7 @@
>
</div>
<h2 class="create-project__container__title" aria-roledescription="title">Create a Project</h2>
<HeaderedInput
<VInput
label="Project Name"
additional-label="Up To 20 Characters"
placeholder="Enter Project Name"
@ -23,7 +23,7 @@
:error="nameError"
@setData="setProjectName"
/>
<HeaderedInput
<VInput
label="Description"
placeholder="Enter Project Description"
additional-label="Optional"
@ -62,7 +62,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import VButton from '@/components/common/VButton.vue';
import VLoader from "@/components/common/VLoader.vue";
@ -74,7 +74,7 @@ import { LocalData } from '@/utils/localData';
// @vue/component
@Component({
components: {
HeaderedInput,
VInput,
VButton,
VLoader,
},

View File

@ -214,7 +214,6 @@ import {
import { MetaUtils } from '@/utils/meta';
// @vue/component
@Component({
components: {

View File

@ -11,7 +11,7 @@
<div v-else class="activate-area__content-area__container">
<h1 class="activate-area__content-area__container__title">Activate Account</h1>
<div class="activate-area__content-area__container__input-wrapper">
<HeaderlessInput
<VInput
label="Email Address"
placeholder="user@example.com"
:error="emailError"
@ -32,7 +32,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import RegistrationSuccess from '@/components/common/RegistrationSuccess.vue';
import LogoIcon from '@/../static/images/logo.svg';
@ -46,7 +46,7 @@ import { MetaUtils } from '@/utils/meta';
@Component({
components: {
LogoIcon,
HeaderlessInput,
VInput,
RegistrationSuccess,
},
})

View File

@ -30,7 +30,7 @@
<p>Automatically send updates to:</p>
<div class="authorize-area__input-wrapper">
<HeaderlessInput
<VInput
label="Project"
role-description="project"
:error="projectErr"
@ -40,7 +40,7 @@
</div>
<div class="authorize-area__input-wrapper">
<HeaderlessInput
<VInput
label="Bucket"
role-description="bucket"
:error="bucketErr"
@ -56,7 +56,7 @@
</div>
<div class="authorize-area__input-wrapper">
<HeaderlessInput
<VInput
label="Passphrase"
role-description="passphrase"
placeholder="Passphrase"
@ -89,7 +89,7 @@
<script lang="ts">
import {Component, Vue} from 'vue-property-decorator';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import LogoIcon from '@/../static/images/logo.svg';
import {Validator} from '@/utils/validation';
import {RouteConfig} from '@/router';
@ -109,7 +109,7 @@ const oauthClientsAPI = new OAuthClientsAPI();
// @vue/component
@Component({
components: {
HeaderlessInput,
VInput,
LogoIcon,
},
})

View File

@ -26,7 +26,7 @@
</div>
<p class="forgot-area__content-area__container__message">If youve forgotten your account password, you can reset it here. Make sure youre signing in to the right satellite.</p>
<div class="forgot-area__content-area__container__input-wrapper">
<HeaderlessInput
<VInput
label="Email Address"
placeholder="user@example.com"
:error="emailError"
@ -47,7 +47,7 @@
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import BottomArrowIcon from '@/../static/images/common/lightBottomArrow.svg';
import SelectedCheckIcon from '@/../static/images/common/selectedCheck.svg';
@ -62,7 +62,7 @@ import { MetaUtils } from '@/utils/meta';
// @vue/component
@Component({
components: {
HeaderlessInput,
VInput,
BottomArrowIcon,
SelectedCheckIcon,
LogoIcon,

View File

@ -42,7 +42,7 @@
</p>
</div>
<div class="login-area__input-wrapper">
<HeaderlessInput
<VInput
label="Email Address"
placeholder="user@example.com"
:error="emailError"
@ -51,7 +51,7 @@
/>
</div>
<div class="login-area__input-wrapper">
<HeaderlessInput
<VInput
label="Password"
placeholder="Password"
:error="passwordError"
@ -102,7 +102,7 @@
import { Component, Vue } from 'vue-property-decorator';
import ConfirmMFAInput from '@/components/account/mfa/ConfirmMFAInput.vue';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import WarningIcon from '@/../static/images/accessGrants/warning.svg';
import GreyWarningIcon from '@/../static/images/common/greyWarning.svg';
@ -128,7 +128,7 @@ interface ClearInput {
// @vue/component
@Component({
components: {
HeaderlessInput,
VInput,
BottomArrowIcon,
SelectedCheckIcon,
LogoIcon,

View File

@ -69,7 +69,7 @@
</ul>
</div>
<div class="register-area__input-wrapper first-input">
<HeaderlessInput
<VInput
label="Full Name"
placeholder="Enter Full Name"
:error="fullNameError"
@ -78,7 +78,7 @@
/>
</div>
<div class="register-area__input-wrapper">
<HeaderlessInput
<VInput
label="Email Address"
placeholder="user@example.com"
:error="emailError"
@ -88,7 +88,7 @@
</div>
<div v-if="isProfessional">
<div class="register-area__input-wrapper">
<HeaderlessInput
<VInput
label="Company Name"
placeholder="Acme Corp."
:error="companyNameError"
@ -97,7 +97,7 @@
/>
</div>
<div class="register-area__input-wrapper">
<HeaderlessInput
<VInput
label="Position"
placeholder="Position Title"
:error="positionError"
@ -115,7 +115,7 @@
</div>
<div class="register-input">
<div class="register-area__input-wrapper">
<HeaderlessInput
<VInput
label="Password"
placeholder="Enter Password"
:error="passwordError"
@ -132,7 +132,7 @@
</div>
</div>
<div class="register-area__input-wrapper">
<HeaderlessInput
<VInput
label="Retype Password"
placeholder="Retype Password"
:error="repeatedPasswordError"
@ -230,7 +230,7 @@ import VueRecaptcha from 'vue-recaptcha';
import VueHcaptcha from '@hcaptcha/vue-hcaptcha';
import AddCouponCodeInput from '@/components/common/AddCouponCodeInput.vue';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import PasswordStrength from '@/components/common/PasswordStrength.vue';
import SelectInput from '@/components/common/SelectInput.vue';
@ -251,7 +251,7 @@ import { Validator } from '@/utils/validation';
// @vue/component
@Component({
components: {
HeaderlessInput,
VInput,
BottomArrowIcon,
ErrorIcon,
SelectedCheckIcon,
@ -308,7 +308,6 @@ export default class RegisterArea extends Vue {
// Employee Count dropdown options
public employeeCountOptions = ['1-50', '51-1000', '1001+'];
public optionsShown = false;
public readonly loginPath: string = RouteConfig.Login.path;
@ -386,13 +385,6 @@ export default class RegisterArea extends Vue {
window.location.href = homepageURL;
}
/**
* Changes location to login route.
*/
public onLoginClick(): void {
this.$router.push(RouteConfig.Login.path);
}
/**
* Sets user's email field from value string.
*/

View File

@ -38,7 +38,7 @@
<template v-else>
<p class="reset-area__content-area__container__message">Please enter your new password.</p>
<div class="reset-area__content-area__container__input-wrapper password">
<HeaderlessInput
<VInput
label="Password"
placeholder="Enter Password"
:error="passwordError"
@ -53,7 +53,7 @@
/>
</div>
<div class="reset-area__content-area__container__input-wrapper">
<HeaderlessInput
<VInput
label="Retype Password"
placeholder="Retype Password"
:error="repeatedPasswordError"
@ -78,7 +78,7 @@
import { Component, Vue } from 'vue-property-decorator';
import ConfirmMFAInput from '@/components/account/mfa/ConfirmMFAInput.vue';
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import VInput from '@/components/common/VInput.vue';
import PasswordStrength from '@/components/common/PasswordStrength.vue';
import GreyWarningIcon from '@/../static/images/common/greyWarning.svg';
@ -96,7 +96,7 @@ import { MetaUtils } from '@/utils/meta';
@Component({
components: {
LogoIcon,
HeaderlessInput,
VInput,
PasswordStrength,
KeyIcon,
ConfirmMFAInput,

View File

@ -1,55 +0,0 @@
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
import HeaderlessInput from '@/components/common/HeaderlessInput.vue';
import { mount, shallowMount } from '@vue/test-utils';
describe('HeaderlessInput.vue', () => {
it('renders correctly with default props', () => {
const wrapper = shallowMount(HeaderlessInput);
expect(wrapper).toMatchSnapshot();
});
it('renders correctly with size props', () => {
const placeholder = 'test';
const width = '30px';
const height = '20px';
const wrapper = shallowMount(HeaderlessInput, {
propsData: {placeholder, width, height},
});
const el = wrapper.find('input').element as HTMLElement;
expect(el.style.width).toMatch(width);
expect(el.style.height).toMatch(height);
expect(wrapper).toMatchSnapshot();
});
it('renders correctly with isPassword prop', () => {
const wrapper = mount(HeaderlessInput, {
propsData: {isPassword: true},
});
expect(wrapper).toMatchSnapshot();
});
it('emit setData on input correctly', () => {
const testData = 'testData';
const wrapper = mount(HeaderlessInput);
wrapper.find('input').trigger('input');
let emittedSetData = wrapper.emitted('setData');
if (emittedSetData) expect(emittedSetData.length).toEqual(1);
wrapper.vm.$emit('setData', testData);
emittedSetData = wrapper.emitted('setData');
if (emittedSetData) expect(emittedSetData[1][0]).toEqual(testData);
});
});

View File

@ -1,21 +1,21 @@
// Copyright (C) 2019 Storj Labs, Inc.
// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
import HeaderedInput from '@/components/common/HeaderedInput.vue';
import VInput from '@/components/common/VInput.vue';
import { mount, shallowMount } from '@vue/test-utils';
describe('HeaderedInput.vue', () => {
describe('VInput.vue', () => {
it('renders correctly with default props', () => {
const wrapper = shallowMount(HeaderedInput);
const wrapper = shallowMount(VInput);
expect(wrapper).toMatchSnapshot();
});
it('renders correctly with isMultiline props', () => {
const wrapper = shallowMount(HeaderedInput, {
const wrapper = shallowMount(VInput, {
propsData: {isMultiline: true},
});
@ -30,7 +30,7 @@ describe('HeaderedInput.vue', () => {
const width = '30px';
const height = '20px';
const wrapper = shallowMount(HeaderedInput, {
const wrapper = shallowMount(VInput, {
propsData: {label, width, height, additionalLabel},
});
@ -44,7 +44,7 @@ describe('HeaderedInput.vue', () => {
it('renders correctly with isOptional props', () => {
const wrapper = shallowMount(HeaderedInput, {
const wrapper = shallowMount(VInput, {
propsData: {
isOptional: true,
},
@ -56,7 +56,7 @@ describe('HeaderedInput.vue', () => {
it('renders correctly with input error', () => {
const error = 'testError';
const wrapper = shallowMount(HeaderedInput, {
const wrapper = shallowMount(VInput, {
propsData: {
error,
},
@ -69,7 +69,7 @@ describe('HeaderedInput.vue', () => {
it('emit setData on input correctly', async () => {
const testData = 'testData';
const wrapper = mount(HeaderedInput);
const wrapper = mount(VInput);
await wrapper.find('input').trigger('input');

View File

@ -1,42 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`HeaderlessInput.vue renders correctly with default props 1`] = `
<div aria-roledescription="input-container" class="input-wrap">
<div class="label-container">
<!---->
<!---->
<!---->
</div> <input placeholder="default" type="text" class="headerless-input" style="width: 100%; height: 48px;">
<!---->
<!---->
<!---->
<!---->
</div>
`;
exports[`HeaderlessInput.vue renders correctly with isPassword prop 1`] = `
<div aria-roledescription="input-container" class="input-wrap">
<div class="label-container">
<!---->
<!---->
<!---->
</div> <input placeholder="default" type="password" class="headerless-input password" style="width: 100%; height: 48px;">
<!---->
<!----> <svg class="input-wrap__image"></svg>
<!---->
</div>
`;
exports[`HeaderlessInput.vue renders correctly with size props 1`] = `
<div aria-roledescription="input-container" class="input-wrap">
<div class="label-container">
<!---->
<!---->
<!---->
</div> <input placeholder="test" type="text" class="headerless-input" style="width: 30px; height: 20px;">
<!---->
<!---->
<!---->
<!---->
</div>
`;

View File

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`HeaderedInput.vue renders correctly with default props 1`] = `
exports[`VInput.vue renders correctly with default props 1`] = `
<div aria-roledescription="input-container" class="input-container">
<div class="label-container">
<div class="label-container__main">
@ -13,11 +13,13 @@ exports[`HeaderedInput.vue renders correctly with default props 1`] = `
<!---->
</div>
<!---->
<!----> <input id="" placeholder="default" type="text" class="headered-input" style="width: 100%; height: 48px;">
<!----> <input id="" placeholder="default" maxlength="9007199254740991" type="text" class="input" style="width: 100%; height: 48px;">
<!---->
<!---->
</div>
`;
exports[`HeaderedInput.vue renders correctly with input error 1`] = `
exports[`VInput.vue renders correctly with input error 1`] = `
<div aria-roledescription="input-container" class="input-container">
<div class="label-container">
<div class="label-container__main">
@ -30,11 +32,13 @@ exports[`HeaderedInput.vue renders correctly with input error 1`] = `
<!---->
</div>
<!---->
<!----> <input id="" placeholder="default" type="text" class="headered-input" style="width: 100%; height: 48px;">
<!----> <input id="" placeholder="default" maxlength="9007199254740991" type="text" class="input" style="width: 100%; height: 48px;">
<!---->
<!---->
</div>
`;
exports[`HeaderedInput.vue renders correctly with isMultiline props 1`] = `
exports[`VInput.vue renders correctly with isMultiline props 1`] = `
<div aria-roledescription="input-container" class="input-container">
<div class="label-container">
<div class="label-container__main">
@ -46,7 +50,9 @@ exports[`HeaderedInput.vue renders correctly with isMultiline props 1`] = `
</div>
<!---->
</div>
<!----> <textarea id="" placeholder="default" rows="5" cols="40" wrap="hard" class="headered-textarea" style="width: 100%; height: 48px;"></textarea>
<!----> <textarea id="" placeholder="default" rows="5" cols="40" maxlength="9007199254740991" wrap="hard" class="textarea" style="width: 100%; height: 48px;"></textarea>
<!---->
<!---->
<!---->
</div>
`;

View File

@ -17,7 +17,9 @@ exports[`CreateProject.vue renders correctly 1`] = `
<h3 class="label-container__limit">0/20</h3>
</div>
<!---->
<!----> <input id="Project Name" placeholder="Enter Project Name" type="text" class="headered-input" style="width: 100%; height: 48px;">
<!----> <input id="Project Name" placeholder="Enter Project Name" maxlength="20" type="text" class="input" style="width: 100%; height: 48px;">
<!---->
<!---->
</div>
<div aria-roledescription="input-container" class="input-container full-input">
<div class="label-container">
@ -30,7 +32,9 @@ exports[`CreateProject.vue renders correctly 1`] = `
</div>
<h3 class="label-container__limit">0/100</h3>
</div>
<!----> <textarea id="Description" placeholder="Enter Project Description" rows="5" cols="40" wrap="hard" class="headered-textarea" style="width: 100%; height: 100px;"></textarea>
<!----> <textarea id="Description" placeholder="Enter Project Description" rows="5" cols="40" maxlength="100" wrap="hard" class="textarea" style="width: 100%; height: 100px;"></textarea>
<!---->
<!---->
<!---->
</div>
<div class="create-project__container__button-container">