Feature: Contact Panel with conversation details (#397)

* Add Contact panel changes

* Fix parent iframe blocked

* Add Conversation Panel, Contact messages

* Update contact panel with conversation details

* Update designs in sidebar

* Fix specs

* Specs: Add specs for conversationMetadata and contact modules

* Fix currentUrl issues

* Fix spelling

* Set default to empty string
This commit is contained in:
Pranav Raj S
2020-01-01 22:30:43 +05:30
committed by Sojan Jose
parent 434d6c2656
commit 439e064d90
28 changed files with 662 additions and 42 deletions

View File

@@ -0,0 +1,47 @@
<template>
<div class="conv-details--item">
<div class="conv-details--item__label">
<i :class="icon" class="conv-details--item__icon"></i>
{{ title }}
</div>
<div class="conv-details--item__value">
{{ value }}
</div>
</div>
</template>
<script>
export default {
props: {
title: { type: String, required: true },
icon: { type: String, required: true },
value: { type: [String, Number], default: '' },
},
};
</script>
<style lang="scss" scoped>
@import '~dashboard/assets/scss/variables';
@import '~dashboard/assets/scss/mixins';
.conv-details--item {
padding-bottom: $space-normal;
&:last-child {
padding-bottom: 0;
}
.conv-details--item__icon {
padding-right: $space-micro;
}
.conv-details--item__label {
font-weight: $font-weight-medium;
margin-bottom: $space-micro;
}
.conv-details--item__value {
word-break: break-all;
}
}
</style>

View File

@@ -1,37 +1,127 @@
<template>
<div class="medium-3 bg-white contact--panel">
<thumbnail
:src="contactImage"
size="80px"
:badge="contact.channel"
:username="contact.name"
/>
<h4>
{{ contact.name }}
</h4>
<div class="contact--profile">
<div class="contact--info">
<thumbnail
:src="contact.avatar_url"
size="56px"
:badge="contact.channel"
:username="contact.name"
/>
<div class="contact--details">
<div class="contact--name">
{{ contact.name }}
</div>
<a
v-if="contact.email"
:href="`mailto:${contact.email}`"
class="contact--email"
>
{{ contact.email }}
</a>
<div class="contact--location">
{{ contact.location }}
</div>
</div>
</div>
<div v-if="contact.bio" class="contact--bio">
{{ contact.bio }}
</div>
</div>
<div v-if="browser" class="conversation--details">
<contact-details-item
v-if="browser.browser_name"
:title="$t('CONTACT_PANEL.BROWSER')"
:value="browserName"
icon="ion-ios-world-outline"
/>
<contact-details-item
v-if="browser.platform_name"
:title="$t('CONTACT_PANEL.OS')"
:value="platformName"
icon="ion-laptop"
/>
<contact-details-item
v-if="referer"
:title="$t('CONTACT_PANEL.INITIATED_FROM')"
:value="referer"
icon="ion-link"
/>
<contact-details-item
v-if="initiatedAt"
:title="$t('CONTACT_PANEL.INITIATED_AT')"
:value="initiatedAt.timestamp"
icon="ion-clock"
/>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import ContactDetailsItem from './ContactDetailsItem.vue';
export default {
components: {
ContactDetailsItem,
Thumbnail,
},
props: {
conversationId: {
type: [Number, String],
required: true,
},
},
computed: {
...mapGetters({
currentChat: 'getSelectedChat',
}),
currentConversationMetaData() {
return this.$store.getters[
'conversationMetadata/getConversationMetadata'
](this.conversationId);
},
additionalAttributes() {
return this.currentConversationMetaData.additional_attributes || {};
},
browser() {
return this.additionalAttributes.browser || {};
},
referer() {
return this.additionalAttributes.referer;
},
initiatedAt() {
return this.additionalAttributes.initiated_at;
},
browserName() {
return `${this.browser.browser_name || ''} ${this.browser
.browser_version || ''}`;
},
platformName() {
const {
platform_name: platformName,
platform_version: platformVersion,
} = this.browser;
return `${platformName || ''} ${platformVersion || ''}`;
},
contactId() {
return this.currentConversationMetaData.contact_id;
},
contact() {
const { meta: { sender = {} } = {} } = this.currentChat || {};
return sender;
return this.$store.getters['contacts/getContact'](this.contactId);
},
contactImage() {
return `/uploads/avatar/contact/${this.contact.id}/profilepic.jpeg`;
},
watch: {
contactId(newContactId, prevContactId) {
if (newContactId && newContactId !== prevContactId) {
this.$store.dispatch('contacts/show', {
id: this.currentConversationMetaData.contact_id,
});
}
},
},
mounted() {
this.$store.dispatch('contacts/show', {
id: this.currentConversationMetaData.contact_id,
});
},
};
</script>
@@ -41,9 +131,70 @@ export default {
.contact--panel {
@include border-normal-left;
font-size: $font-size-small;
overflow-y: auto;
background: $color-white;
overflow: auto;
}
.contact--profile {
width: 100%;
padding: $space-normal $space-medium $zero;
align-items: center;
.user-thumbnail-box {
margin-right: $space-normal;
}
}
.contact--details {
p {
margin-bottom: 0;
}
}
.contact--info {
display: flex;
flex-direction: column;
padding: $space-large $space-normal $space-normal;
align-items: center;
}
.contact--name {
@include text-ellipsis;
font-weight: $font-weight-bold;
font-size: $font-size-default;
}
.contact--email {
@include text-ellipsis;
color: $color-body;
display: block;
line-height: $space-medium;
text-decoration: underline;
}
.contact--bio {
margin-top: $space-normal;
}
.conversation--details {
padding: $space-normal $space-medium;
width: 100%;
}
.conversation--labels {
padding: $space-medium;
.icon {
margin-right: $space-micro;
font-size: $font-size-micro;
color: #fff;
}
.label {
color: #fff;
padding: 0.2rem;
}
}
</style>

View File

@@ -11,7 +11,10 @@
@contactPanelToggle="onToggleContactPanel"
>
</conversation-box>
<contact-panel v-if="isContactPanelOpen"></contact-panel>
<contact-panel
v-if="isContactPanelOpen"
:conversation-id="conversationId"
/>
</section>
</template>