Skip to content

Commit

Permalink
feat: Wallet with panels (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
valiafetisov authored Mar 30, 2022
1 parent 413a5a9 commit bc6bf23
Show file tree
Hide file tree
Showing 31 changed files with 869 additions and 288 deletions.
1 change: 1 addition & 0 deletions frontend/assets/styles/ant-design.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@primary-color: #1aab9b;
@modal-body-padding: 0px;
@dropdown-selected-color: @text-color;
@border-width-base: 2px;

.anticon {
vertical-align: 0.125em !important;
Expand Down
6 changes: 3 additions & 3 deletions frontend/components/MainFlow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
:auction-transaction="selectedAuction"
:is-connecting="isConnecting"
:is-authorizing="isAuthorizing"
:is-wallet-authorised="isWalletAuthorised"
:is-wallet-authorized="isWalletAuthorized"
:authorised-collaterals="authorisedCollaterals"
:is-executing="isExecuting"
:wallet-address="walletAddress"
Expand All @@ -63,7 +63,7 @@
:is-authorizing="isAuthorizing"
:is-depositing-or-withdrawing="isDepositingOrWithdrawing"
:is-executing="isExecuting"
:is-wallet-authorised="isWalletAuthorised"
:is-wallet-authorized="isWalletAuthorized"
:is-explanations-shown="isExplanationsShown"
:authorised-collaterals="authorisedCollaterals"
:wallet-address="walletAddress"
Expand Down Expand Up @@ -134,7 +134,7 @@ export default Vue.extend({
type: Boolean,
default: false,
},
isWalletAuthorised: {
isWalletAuthorized: {
type: Boolean,
default: false,
},
Expand Down
36 changes: 22 additions & 14 deletions frontend/components/common/BaseButton.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<Button
:disabled="disabled || isLoading"
:class="buttonStyles"
class="overflow-hidden"
:class="buttonClass"
class="Button"
:type="type"
:html-type="htmlType"
@click="$emit('click')"
Expand Down Expand Up @@ -43,35 +43,43 @@ export default Vue.extend({
},
},
computed: {
buttonStyles() {
buttonClass() {
if (this.type === 'primary') {
return 'Button-Primary';
return 'Primary';
}
if (this.type === 'link') {
return 'Button-Link';
return 'Link';
}
return '';
return 'Default';
},
},
});
</script>

<style>
.Button-Primary,
.dark .Button-Primary {
<style scoped>
.Button {
@apply overflow-hidden;
}
.Button.Default:enabled {
@apply border-primary text-primary hover:text-white hover:bg-primary-light hover:border-primary-light;
}
.Primary:enabled,
.dark .Primary:enabled {
@apply text-white bg-primary border-primary focus:bg-primary-light focus:border-primary-light hover:bg-primary-light hover:border-primary-light;
}
.Button-Link,
.dark .Button-Link {
@apply inline-flex items-center p-0 h-auto;
.Link,
.dark .Link {
@apply inline-flex items-center p-0 h-auto leading-4;
}
.Button-Link span {
.Link span {
@apply text-primary underline overflow-auto transition-colors;
}
.Button-Link:hover span {
.Link:hover span {
@apply text-primary-light no-underline;
}
</style>
25 changes: 15 additions & 10 deletions frontend/components/common/BasePanel.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,43 @@ storiesOf('common/BasePanel', module)
.add('Stack of panels', () => ({
...common,
template: `<div>
<BasePanel v-bind="$data" currentState="incorrect"> Error content </BasePanel>
<BasePanel v-bind="$data" currentState="notice"> Notice content </BasePanel>
<BasePanel v-bind="$data" currentState="correct"> Correct content </BasePanel>
<BasePanel v-bind="$data" currentState="inactive"> Inactive content </BasePanel>
<BasePanel currentState="incorrect"><template #title>{{ incorrect }}</template>Error content</BasePanel>
<BasePanel currentState="notice"><template #title>{{ notice }}</template>Notice content</BasePanel>
<BasePanel currentState="correct"><template #title>{{ correct }}</template>Correct content</BasePanel>
<BasePanel currentState="inactive"><template #title>{{ inactive }}</template>Inactive content</BasePanel>
</div>`,
}))
.add('Inactive', () => ({
...common,
template: '<BasePanel v-bind="$data" currentState="inactive"> Inactive content </BasePanel>',
template:
'<BasePanel currentState="inactive"><template #title>{{ inactive }}</template>Inactive content</BasePanel>',
}))
.add('Incorrect', () => ({
...common,
template: '<BasePanel v-bind="$data" currentState="incorrect"> Incorrect content </BasePanel>',
template:
'<BasePanel currentState="incorrect"><template #title>{{ incorrect }}</template>Incorrect content</BasePanel>',
}))
.add('Correct', () => ({
...common,
template: '<BasePanel v-bind="$data" currentState="correct"> Correct content </BasePanel>',
template:
'<BasePanel currentState="correct"><template #title>{{ correct }}</template>Correct content</BasePanel>',
}))
.add('Notice', () => ({
...common,
template: '<BasePanel v-bind="$data" currentState="notice"> Notice content </BasePanel>',
template:
'<BasePanel currentState="notice"><template #title>{{ notice }}</template>Notice content</BasePanel>',
}))
.add('Very long notice', () => ({
...common,
template: `<BasePanel notice="${faker.lorem.sentence(20)}" currentState="notice">
template: `<BasePanel currentState="notice">
<template #title>${faker.lorem.sentence(20)}</template>
Content: ${faker.lorem.sentence(50)}
</BasePanel>`,
}))
.add('Notice with html', () => ({
...common,
template: `<BasePanel currentState="notice">
<template #notice>Title with <i>italic</i> text</template>
<template #title>Title with <i>italic</i> text</template>
Content: ${faker.lorem.sentence(50)}
</BasePanel>`,
}));
41 changes: 22 additions & 19 deletions frontend/components/common/BasePanel.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<template>
<div class="BasePanel">
<button class="Title" :class="titleClass" @click="isExpanded = !isExpanded">
<button class="Title" type="button" :class="titleClass" @click="isExpanded = !isExpanded">
<div class="Icon" :class="iconClass">
<Icon v-if="currentState === 'inactive'" type="close" />
<Icon v-else-if="currentState === 'incorrect'" type="warning" theme="filled" />
<Icon v-else-if="currentState === 'correct'" type="check" />
<Icon v-else-if="currentState === 'notice'" type="warning" theme="filled" />
</div>
<slot :name="currentState">{{ $props[currentState] }}</slot>
<slot name="title" />
</button>
<div v-show="isExpanded" class="Content">
<slot />
</div>
<CollapseTransition>
<div v-show="isExpanded" class="Content">
<slot />
</div>
</CollapseTransition>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import { Icon } from 'ant-design-vue';
import CollapseTransition from '@ivanv/vue-collapse-transition';
const STATES = [
{
Expand Down Expand Up @@ -49,41 +52,32 @@ const STATES = [
export default Vue.extend({
components: {
Icon,
CollapseTransition,
},
props: {
currentState: {
type: String,
required: true,
validator: (value: string) => STATES.map(s => s.name).includes(value),
},
...STATES.reduce(
(props, state) => ({
...props,
[state.name]: {
type: String,
default: '',
},
}),
{}
),
},
data() {
return {
isExpanded: false,
};
},
computed: {
titleClass() {
titleClass(): string | undefined {
return STATES.find(s => s.name === this.currentState)?.titleClass;
},
iconClass() {
iconClass(): string | undefined {
return STATES.find(s => s.name === this.currentState)?.iconClass;
},
},
watch: {
currentState: {
immediate: true,
handler(newState: string) {
handler(newState: string): void {
this.isExpanded = STATES.filter(s => s.isExpanded)
.map(s => s.name)
.includes(newState);
Expand All @@ -98,6 +92,15 @@ export default Vue.extend({
@apply flex flex-col;
@apply border-2 border-gray-300 dark:border-gray-600 dark:text-gray-200;
}
.BasePanel:first-child {
@apply rounded-t;
}
.BasePanel:last-child {
@apply rounded-b;
}
.BasePanel:only-child {
@apply rounded;
}
.BasePanel + .BasePanel {
margin-top: -2px;
}
Expand All @@ -108,6 +111,6 @@ export default Vue.extend({
@apply inline;
}
.Content {
@apply px-2 py-1;
@apply px-3 pt-1 pb-3;
}
</style>
136 changes: 136 additions & 0 deletions frontend/components/common/BaseValueInput.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<template>
<div class="BaseValueInput">
<Tooltip :visible="!!errorMessage" placement="topLeft" :title="errorMessage">
<Input
v-model="inputText"
class="Input"
:class="{ Error: !!errorMessage }"
:disabled="disabled"
@focus="hideMaxValue"
@blur="showMaxValueIfEmpty"
/>
<div class="Overlay right-2" :class="{ 'opacity-50': disabled }">
<format-currency v-if="!inputValue && maxValue" :value="maxValue" />&nbsp;DAI
</div>
</Tooltip>
</div>
</template>

<script lang="ts">
import Vue from 'vue';
import BigNumber from 'bignumber.js';
import { Input, Tooltip } from 'ant-design-vue';
import FormatCurrency from '~/components/utils/FormatCurrency.vue';
export default Vue.extend({
components: { FormatCurrency, Tooltip, Input },
props: {
inputValue: {
type: Object as Vue.PropType<BigNumber> | undefined,
default: undefined,
},
minValue: {
type: Object as Vue.PropType<BigNumber>,
default: undefined,
},
maxValue: {
type: Object as Vue.PropType<BigNumber>,
default: undefined,
},
validator: {
type: Function as Vue.PropType<function>,
default: () => {},
},
disabled: {
type: Boolean,
default: false,
},
},
data() {
return {
inputText: '',
};
},
computed: {
isInputEmpty(): boolean {
return this.inputText.trim() === '';
},
inputTextParsed(): BigNumber | undefined {
if (this.isInputEmpty) {
return undefined;
}
return new BigNumber(this.inputText.trim());
},
errorMessage(): string {
try {
if (this.validator) {
this.validator(this.inputTextParsed, this.minValue, this.maxValue);
}
} catch (error) {
return error.message;
}
return '';
},
},
watch: {
inputText(_newInputText: string, oldInputText: string) {
if (this.errorMessage || !this.inputTextParsed) {
this.$emit('update:inputValue', new BigNumber(NaN));
return;
}
if (this.inputTextParsed.isNaN()) {
this.inputText = oldInputText || '';
return;
}
this.$emit('update:inputValue', this.inputTextParsed);
},
inputValue(newInputValue: BigNumber | undefined) {
if (!newInputValue) {
this.inputText = '';
return;
}
if (newInputValue.isEqualTo(this.minValue) && !newInputValue.isZero()) {
this.inputText = newInputValue.toFixed();
}
},
},
methods: {
hideMaxValue(): void {
if (!this.inputValue) {
this.$emit('update:inputValue', new BigNumber(NaN));
}
},
showMaxValueIfEmpty(): void {
if (this.isInputEmpty) {
this.$emit('update:inputValue', undefined);
}
},
},
});
</script>

<style scoped>
.BaseValueInput {
@apply w-full relative dark:text-gray-300;
}
.Input {
@apply text-right pr-8;
}
.Error {
@apply border-red-500 hover:border-red-400;
}
.Error:focus {
@apply border-red-400;
box-shadow: 0 0 3px rgb(239, 68, 68);
}
.Overlay {
@apply absolute pointer-events-none h-full flex items-center;
top: 0.5px;
}
</style>
Loading

0 comments on commit bc6bf23

Please sign in to comment.