feat: Display reply time in widget (#1349)

Fixes #1132
This commit is contained in:
Pranav Raj S
2020-10-18 23:32:22 +05:30
committed by GitHub
parent bd11b2ec58
commit 85514cae8d
43 changed files with 707 additions and 345 deletions

View File

@@ -25,8 +25,8 @@ export default {
@import '~widget/assets/scss/variables.scss';
.typing-bubble {
max-width: $space-medium;
padding: $space-smaller $space-small;
max-width: $space-normal * 2.4;
padding: $space-small;
border-bottom-left-radius: $space-two;
border-top-left-radius: $space-small;

View File

@@ -1,80 +1,27 @@
<template>
<div class="available-agents">
<div class="toast-bg">
<div class="avatars-wrap">
<GroupedAvatars :users="users" />
</div>
<div class="title">
{{ title }}
</div>
</div>
</div>
<grouped-avatars :users="users" />
</template>
<script>
import GroupedAvatars from 'widget/components/GroupedAvatars.vue';
import agentMixin from '../mixins/agentMixin';
export default {
name: 'AvailableAgents',
components: { GroupedAvatars },
mixins: [agentMixin],
props: {
agents: {
type: Array,
default: () => [],
},
onClose: {
type: Function,
default: () => {},
},
},
computed: {
users() {
return this.agents.map(agent => ({
return this.agents.slice(0, 5).map(agent => ({
id: agent.id,
avatar: agent.avatar_url,
name: agent.name,
}));
},
title() {
return this.getAvailableAgentsText(this.agents);
},
},
};
</script>
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.available-agents {
display: flex;
position: relative;
justify-content: center;
margin: $space-normal $space-medium;
box-sizing: border-box;
.toast-bg {
border-radius: $space-large;
background: $color-body;
@include shadow-medium;
}
.title {
font-size: $font-size-default;
font-weight: $font-weight-medium;
color: $color-white;
padding: $space-small $space-normal $space-small $space-small;
line-height: 1.4;
display: inline-block;
vertical-align: middle;
}
.avatars-wrap {
display: inline-block;
vertical-align: middle;
margin-left: $space-small;
}
}
</style>

View File

@@ -1,8 +1,27 @@
<template>
<header class="header-collapsed">
<div class="header-branding">
<img v-if="avatarUrl" :src="avatarUrl" alt="avatar" />
<h2 class="title" v-html="title"></h2>
<img
v-if="avatarUrl"
class="inbox--avatar mr-3"
:src="avatarUrl"
alt="avatar"
/>
<div>
<div class="text-black-900 font-medium text-base flex items-center">
<span class="mr-1" v-html="title" />
<div
:class="
`status-view--badge rounded-full leading-4 ${
availableAgents.length ? 'bg-green-500' : 'hidden'
}`
"
/>
</div>
<div class="text-xs mt-1 text-black-700">
{{ replyTimeStatus }}
</div>
</div>
</div>
<header-actions :show-popout-button="showPopoutButton" />
</header>
@@ -11,11 +30,15 @@
<script>
import { mapGetters } from 'vuex';
import HeaderActions from './HeaderActions';
import configMixin from 'widget/mixins/configMixin';
import teamAvailabilityMixin from 'widget/mixins/teamAvailabilityMixin';
export default {
name: 'ChatHeader',
components: {
HeaderActions,
},
mixins: [configMixin, teamAvailabilityMixin],
props: {
avatarUrl: {
type: String,
@@ -29,6 +52,10 @@ export default {
type: Boolean,
default: false,
},
availableAgents: {
type: Array,
default: () => {},
},
},
computed: {
...mapGetters({
@@ -48,7 +75,8 @@ export default {
padding: $space-two $space-medium;
width: 100%;
box-sizing: border-box;
color: $color-white;
background: white;
@include shadow-large;
.header-branding {
display: flex;
@@ -60,15 +88,17 @@ export default {
}
.title {
font-size: $font-size-large;
font-weight: $font-weight-medium;
color: $color-heading;
}
img {
height: 24px;
width: 24px;
margin-right: $space-small;
.inbox--avatar {
height: 32px;
width: 32px;
}
}
.status-view--badge {
height: $space-small;
width: $space-small;
}
</style>

View File

@@ -1,11 +1,14 @@
<template>
<header class="header-expanded">
<div class="header--row">
<header class="header-expanded py-8 px-6 bg-white relative box-border w-full">
<div class="flex justify-between items-start">
<img v-if="avatarUrl" class="logo" :src="avatarUrl" />
<header-actions :show-popout-button="showPopoutButton" />
</div>
<h2 class="title" v-html="introHeading"></h2>
<p class="body" v-html="introBody"></p>
<h2
class="text-slate-900 mt-6 text-4xl mb-3 font-normal"
v-html="introHeading"
/>
<p class="text-lg text-black-700 leading-normal" v-html="introBody" />
</header>
</template>
@@ -44,38 +47,14 @@ export default {
</script>
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.header-expanded {
padding: $space-large $space-medium $space-large;
width: 100%;
box-sizing: border-box;
position: relative;
@include shadow-large;
.logo {
width: 56px;
height: 56px;
}
.title {
color: $color-heading;
font-size: $font-size-mega;
font-weight: $font-weight-normal;
margin-bottom: $space-slab;
margin-top: $space-medium;
}
.body {
color: $color-body;
font-size: 1.8rem;
line-height: 1.5;
}
}
.header--row {
display: flex;
align-items: flex-start;
justify-content: space-between;
}
</style>

View File

@@ -2,7 +2,7 @@
<button
type="submit"
:disabled="disabled"
class="send-button"
class="send-button ml-1"
@click="onClick"
>
<i

View File

@@ -1,8 +1,16 @@
<template>
<div class="avatars">
<span v-for="user in users" :key="user.id" class="avatar">
<Thumbnail
size="24px"
<div class="flex overflow-hidden">
<span
v-for="(user, index) in users"
:key="user.id"
:class="
`${
index ? '-ml-4' : ''
} inline-block rounded-full text-white shadow-solid`
"
>
<thumbnail
size="40px"
:username="user.name"
:src="user.avatar"
has-border
@@ -25,22 +33,3 @@ export default {
},
};
</script>
<style scoped lang="scss">
@import '~widget/assets/scss/variables.scss';
@import '~widget/assets/scss/mixins.scss';
.avatars {
display: inline-block;
padding-left: $space-one;
.avatar {
margin-left: -$space-slab;
position: relative;
display: inline-block;
overflow: hidden;
width: $space-medium;
height: $space-medium;
}
}
</style>

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="isIframe" class="actions">
<div v-if="isIframe" class="actions flex items-center">
<button
v-if="showPopoutButton"
class="button transparent compact new-window--button"
@@ -66,9 +66,6 @@ export default {
@import '~widget/assets/scss/variables.scss';
.actions {
display: flex;
align-items: center;
button {
margin-left: $space-normal;
}

View File

@@ -0,0 +1,59 @@
<template>
<div class="px-4">
<div class="flex items-center justify-between mb-4">
<div class="text-black-700">
<div class="text-base leading-5 font-medium mb-1">
{{ teamAvailabilityStatus }}
</div>
<div class="text-xs leading-4 mt-1">
{{ replyTimeStatus }}
</div>
</div>
<available-agents :agents="availableAgents" />
</div>
<woot-button
class="font-medium"
block
:bg-color="widgetColor"
:text-color="textColor"
@click="startConversation"
>
{{ $t('START_CONVERSATION') }}
</woot-button>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import AvailableAgents from 'widget/components/AvailableAgents.vue';
import { getContrastingTextColor } from 'shared/helpers/ColorHelper';
import WootButton from 'shared/components/Button';
import configMixin from 'widget/mixins/configMixin';
import teamAvailabilityMixin from 'widget/mixins/teamAvailabilityMixin';
export default {
name: 'TeamAvailability',
components: {
AvailableAgents,
WootButton,
},
mixins: [configMixin, teamAvailabilityMixin],
props: {
availableAgents: {
type: Array,
default: () => {},
},
},
computed: {
...mapGetters({ widgetColor: 'appConfig/getWidgetColor' }),
textColor() {
return getContrastingTextColor(this.widgetColor);
},
},
methods: {
startConversation() {
this.$emit('start-conversation');
},
},
};
</script>