diff --git a/src/components/MewNotification/MewNotification.vue b/src/components/MewNotification/MewNotification.vue index aa0bec883..3a70b9d82 100644 --- a/src/components/MewNotification/MewNotification.vue +++ b/src/components/MewNotification/MewNotification.vue @@ -1,192 +1,204 @@ <template> - <!-- - ===================================================================================== - Mew Notifications - ===================================================================================== - --> - <div - @click="onToggle" - :class="[ - expanded ? 'expanded' : '', - notification.status.value + '-type', - 'notification-container', - 'px-1', - 'titlePrimary--text', - notification.read ? 'read' : '', - ]" - > - <v-container - fluid - class="px-0" - > - <v-row dense> - <v-col - class="d-flex align-center" - cols="8" + <div class="mew-components--mew-notification"> + <!-- ===================================================================================== --> + <!-- NEW --> + <!-- ===================================================================================== --> + <div class="notification-container"> + <v-expansion-panels flat> + <v-expansion-panel + :class=" + getBorderClasses( + notification.status.value.toLowerCase(), + notification.read + ) + " > - <!-- - ===================================================================================== - Displays indicator if notification not read - ===================================================================================== - --> - <div - :class="[ - getClasses(notification.status.value.toLowerCase()), - 'indicator', - 'ml-2', - 'd-none', - 'd-sm-flex', - ]" - v-if="$vuetify.breakpoint.smAndUp && !notification.read && showIndicator" - /> - <!-- - ===================================================================================== - Displays blockie if it is not a swap notification - ===================================================================================== - --> - <mew-blockie - class="d-flex ml-2" - v-if="!isSwap" - width="24px" - height="24px" - :address="notification.from.value" - /> - <!-- - ===================================================================================== - Displays swap icons if it is a swap notification - ===================================================================================== - --> - <div - v-else - class="d-flex flex-column currency-symbol" + <v-expansion-panel-header + hide-actions + class="px-2 py-0" + :color="backgroundColor" > - <img - :src="notification.fromObj.icon ? notification.fromObj.icon : ethTokenPlaceholder" - width="24px" - height="24px" + <v-container + fluid + class="px-0" > - <img - :src="notification.toObj.icon" - width="24px" - height="24px" - class="overlap" - > - </div> - <!-- - ===================================================================================== - Displays different notification info based on notification type - ===================================================================================== - --> - <div :class="['detail-container pr-1', isSwap ? 'ml-5' : 'ml-2']"> - <div v-if="!isSwap"> - <div class="caption font-weight-medium d-flex"> - {{ notification.from.string }}: - <mew-transform-hash - :hash="notification.from.value" - class="ml-1 detail-hash" - /> - </div> + <v-row dense> + <v-col + class="d-flex align-center" + cols="8" + > + <!-- ===================================================================================== --> + <!-- Displays indicator if notification not read --> + <!-- ===================================================================================== --> + <div + v-if=" + $vuetify.breakpoint.smAndUp && + !notification.read && + showIndicator + " + :class="[ + getClasses(notification.status.value.toLowerCase()), + 'indicator', + 'ml-2', + 'd-none', + 'd-sm-flex' + ]" + /> - <div class="caption font-weight-medium d-flex"> - {{ notification.amount.string }}: - {{ notification.amount.value }} - </div> - </div> - <div v-else> - <div class="caption font-weight-medium d-flex"> - {{ notification.to.string }}: - <mew-transform-hash - :hash="notification.toObj.to" - class="ml-1 detail-hash" - /> - </div> - <div class="caption mew-heading-2"> - <div class="d-inline-block mr-1"> - {{ notification.fromObj.amount }} - <span class="textPrimary--text">{{ - notification.fromObj.currency - }}</span> - </div> - <v-icon class="subtitle-1 d-inline-block"> - mdi-arrow-right - </v-icon> - <div class="d-inline-block mr-3"> - {{ notification.toObj.amount }} - <span class="textPrimary--text">{{ - notification.toObj.currency - }}</span> - </div> - </div> - </div> - </div> - </v-col> - <v-col - cols="4" - class="text-right pr-2" - > - <mew-badge - :badge-title="notification.type.string" - :badge-type="getBadgeType" - /> - <div class="caption mt-1 textPrimary--text font-weight-medium"> - {{ notification.timestamp.value }} - </div> - </v-col> - </v-row> - </v-container> - <!-- - ===================================================================================== - Displays more info if the notification is expanded - ===================================================================================== - --> - <div - class="expanded-container capitalize" - v-if="expanded" - > - <v-container class="pa-2"> - <v-row - v-for="(detail, idx) in getDetails" - :key="idx" - > - <v-col - cols="6" - class="textPrimary--text" - > - {{ detail.string }}: - </v-col> - <v-col - cols="6" - :class="[getClasses(detail.value) + '--text', 'text-right']" - v-if="!isHash(detail.string)" - > - {{ detail.value }} - </v-col> - <v-col - cols="6" - class="text-right" - v-if="isHash(detail.string)" + <!-- ===================================================================================== --> + <!-- Displays blockie if it is not a swap notification --> + <!-- ===================================================================================== --> + <mew-blockie + v-if="!isSwap" + class="d-flex ml-2" + width="24px" + height="24px" + :address="notification.from.value" + /> + + <!-- ===================================================================================== --> + <!-- Displays swap icons if it is a swap notification --> + <!-- ===================================================================================== --> + <div + v-else + class="d-flex flex-column currency-symbol" + > + <img + :src=" + notification.fromObj.icon + ? notification.fromObj.icon + : ethTokenPlaceholder + " + width="24px" + height="24px" + > + <img + :src="notification.toObj.icon" + width="24px" + height="24px" + class="overlap" + > + </div> + + <!-- ===================================================================================== --> + <!-- Displays different notification info based on notification type --> + <!-- ===================================================================================== --> + <div + :class="['detail-container pr-1', isSwap ? 'ml-5' : 'ml-2']" + > + <div v-if="!isSwap"> + <div class="caption font-weight-medium d-flex"> + {{ notification.from.string }}: + <mew-transform-hash + :hash="notification.from.value" + class="ml-1 detail-hash" + /> + </div> + + <div class="caption font-weight-medium d-flex"> + {{ notification.amount.string }}: + {{ notification.amount.value }} + </div> + </div> + <div v-else> + <div class="caption font-weight-medium d-flex"> + {{ notification.to.string }}: + <mew-transform-hash + :hash="notification.toObj.to" + class="ml-1 detail-hash" + /> + </div> + <div class="caption mew-heading-2"> + <div class="d-inline-block mr-1"> + {{ notification.fromObj.amount }} + <span class="textPrimary--text">{{ + notification.fromObj.currency + }}</span> + </div> + <v-icon class="subtitle-1 d-inline-block"> + mdi-arrow-right + </v-icon> + <div class="d-inline-block mr-3"> + {{ notification.toObj.amount }} + <span class="textPrimary--text">{{ + notification.toObj.currency + }}</span> + </div> + </div> + </div> + </div> + </v-col> + <v-col + cols="4" + class="text-right pr-2" + > + <mew-badge + :badge-title="notification.type.string" + :badge-type="getBadgeType" + /> + <div + class="caption mt-1 textPrimary--text font-weight-medium" + > + {{ notification.timestamp.value }} + </div> + </v-col> + </v-row> + </v-container> + </v-expansion-panel-header> + + <v-expansion-panel-content + class="pa-0" + :color="backgroundColor" > - <v-tooltip - eager - open-on-hover - content-class="tooltip-inner" - color="titlePrimary--text" - top - > - <template v-slot:activator="{ on }"> - <a - v-on="on" - :href="detail.link" - target="_blank" + <div class="expanded-container capitalize"> + <v-container> + <v-row + v-for="(detail, idx) in getDetails" + :key="idx" > - <mew-transform-hash :hash="detail.value" /> - </a> - </template> - <span>{{ detail.value }}</span> - </v-tooltip> - </v-col> - </v-row> - </v-container> + <v-col + cols="6" + class="textPrimary--text" + > + {{ detail.string }}: + </v-col> + <v-col + v-if="!isHash(detail.string)" + cols="6" + :class="[getClasses(detail.value) + '--text', 'text-right']" + > + {{ detail.value }} + </v-col> + <v-col + v-if="isHash(detail.string)" + cols="6" + class="text-right" + > + <v-tooltip + eager + open-on-hover + content-class="tooltip-inner" + color="titlePrimary--text" + top + > + <template #activator="{ on }"> + <a + :href="detail.link" + target="_blank" + v-on="on" + > + <mew-transform-hash :hash="detail.value" /> + </a> + </template> + <span>{{ detail.value }}</span> + </v-tooltip> + </v-col> + </v-row> + </v-container> + </div> + </v-expansion-panel-content> + </v-expansion-panel> + </v-expansion-panels> </div> </div> </template> @@ -202,50 +214,7 @@ export default { components: { MewBadge, MewBlockie, - MewTransformHash, - }, - data() { - return { - ethTokenPlaceholder: ethTokenPlaceholder, - expanded: false, - txTypes: { - in: 'txIn', - out: 'txOut', - swap: 'swap', - }, - txStatusOptions: { - success: 'success', - pending: 'pending', - failed: 'failed', - }, - hashType: 'Transaction Hash', - }; - }, - computed: { - getBadgeType() { - const type = this.notification.type.value.toLowerCase(); - return this.txTypes[type]; - }, - getDetails() { - const details = [], - detailTypes = [ - 'txHash', - 'gasPrice', - 'gasLimit', - 'total', - 'timestamp', - 'status', - ]; - for (const key in this.notification) { - if (detailTypes.indexOf(key) >= 0) { - details.push(this.notification[key]); - } - } - return details; - }, - isSwap() { - return this.notification.type.value.toLowerCase() === this.txTypes.swap; - }, + MewTransformHash }, props: { /** @@ -264,64 +233,116 @@ export default { return { txHash: { value: '', - string: '', + string: '' }, gasPrice: { value: '', - string: '', + string: '' }, gasLimit: { value: '', - string: '', + string: '' }, total: { value: '', - string: '', + string: '' }, from: { value: '', - string: '', + string: '' }, to: { value: '', - string: '', + string: '' }, amount: { value: '', - string: '', + string: '' }, timestamp: { value: '', - string: '', + string: '' }, status: { value: '', - string: '', + string: '' }, type: { value: '', - string: '', + string: '' }, fromObj: { currency: '', amount: '', - icon: '', + icon: '' }, toObj: { currency: '', amount: '', icon: '', - to: '', + to: '' }, read: false }; - }, + } }, showIndicator: { type: Boolean, default: true } }, + data() { + return { + ethTokenPlaceholder: ethTokenPlaceholder, + expanded: false, + txTypes: { + in: 'txIn', + out: 'txOut', + swap: 'swap' + }, + txStatusOptions: { + success: 'success', + pending: 'pending', + failed: 'failed' + }, + hashType: 'Transaction Hash' + }; + }, + computed: { + backgroundColor() { + if (this.notification.status.value == this.txStatusOptions.pending) { + return 'warning'; + } + if (this.notification.status.value == this.txStatusOptions.failed) { + return 'error lighten-1'; + } + return 'superPrimary'; + }, + getBadgeType() { + const type = this.notification.type.value.toLowerCase(); + return this.txTypes[type]; + }, + getDetails() { + const details = [], + detailTypes = [ + 'txHash', + 'gasPrice', + 'gasLimit', + 'total', + 'timestamp', + 'status' + ]; + for (const key in this.notification) { + if (detailTypes.indexOf(key) >= 0) { + details.push(this.notification[key]); + } + } + return details; + }, + isSwap() { + return this.notification.type.value.toLowerCase() === this.txTypes.swap; + } + }, methods: { isHash(type) { return type === this.hashType; @@ -337,20 +358,55 @@ export default { return 'error'; } }, + getBorderClasses(status, read) { + if (status === this.txStatusOptions.success) { + if (read) { + return 'success-type read'; + } + return 'success-type'; + } + if (status === this.txStatusOptions.pending) { + if (read) { + return 'sucpendingcess-type read'; + } + return 'pending-type'; + } + if (status === this.txStatusOptions.failed) { + if (read) { + return 'failed-type read'; + } + return 'failed-type'; + } + }, onToggle() { this.expanded = !this.expanded; - }, - }, + } + } }; </script> +<style lang="scss"> +.mew-components--mew-notification { + .v-expansion-panel-content__wrap { + padding: 10px !important; + } +} +</style> + <style lang="scss" scoped> -.notification-container { - border-radius: 6px; - overflow: auto; +.warning, +.error, +.primary { + border-radius: 0 !important; +} +.v-expansion-panel { + overflow: hidden; +} + +.notification-container { .detail-container { - max-width: 100%; + max-width: 85%; .detail-hash { max-width: 60%; @@ -358,7 +414,7 @@ export default { } .indicator { - border-radius: 50%; + border-radius: 50% !important; display: table; height: 6px; width: 6px; @@ -372,7 +428,7 @@ export default { } .success-type { - background-color: var(--v-superPrimary-base); + //background-color: var(--v-superPrimary-base); border: 1px solid var(--v-primary-base); &.expanded { border: 1px solid var(--v-superPrimary-base); @@ -384,7 +440,7 @@ export default { } .pending-type { - background-color: var(--v-warning-base); + //background-color: var(--v-warning-base); border: 1px solid var(--v-warning-darken1); &.expanded { border: 1px solid var(--v-warning-base); @@ -396,7 +452,7 @@ export default { } .failed-type { - background-color: var(--v-error-lighten1); + //background-color: var(--v-error-lighten1); border: 1px solid var(--v-error-base); &.expanded { border: 1px solid var(--v-error-lighten1);