Merge branch 'develop' into feat/new-auth-screens

This commit is contained in:
Sivin Varghese 2022-11-07 16:37:59 +05:30 committed by GitHub
commit 3276a6d840
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 185 additions and 4 deletions

View file

@ -56,7 +56,7 @@ RAILS_MAX_THREADS=5
# The email from which all outgoing emails are sent
# could user either `email@yourdomain.com` or `BrandName <email@yourdomain.com>`
MAILER_SENDER_EMAIL="Chatwoot <accounts@chatwoot.com>"
MAILER_SENDER_EMAIL=Chatwoot <accounts@chatwoot.com>
#SMTP domain key is set up for HELO checking
SMTP_DOMAIN=chatwoot.com

View file

@ -1,5 +1,5 @@
<template>
<div class="user-thumbnail-box" :style="{ height: size, width: size }">
<div :class="thumbnailBoxClass" :style="{ height: size, width: size }">
<img
v-if="!imgError && src"
:src="src"
@ -120,6 +120,10 @@ export default {
this.variant === 'circle' ? 'thumbnail-rounded' : 'thumbnail-square';
return `user-thumbnail ${classname} ${variant}`;
},
thumbnailBoxClass() {
const boxClass = this.variant === 'circle' ? 'is-rounded' : '';
return `user-thumbnail-box ${boxClass}`;
},
},
watch: {
src(value, oldValue) {
@ -142,6 +146,10 @@ export default {
max-width: 100%;
position: relative;
&.is-rounded {
border-radius: 50%;
}
.user-thumbnail {
border-radius: 50%;
&.thumbnail-square {

View file

@ -0,0 +1,75 @@
<template>
<div class="overlapping-thumbnails">
<thumbnail
v-for="user in usersList"
:key="user.id"
:src="user.thumbnail"
:username="user.name"
:has-border="true"
:size="size"
class="overlapping-thumbnail"
/>
<span v-if="showMoreThumbnailsCount" class="thumbnail-more-text">
{{ moreThumbnailsText }}
</span>
</div>
</template>
<script>
import Thumbnail from './Thumbnail';
export default {
components: {
Thumbnail,
},
props: {
usersList: {
type: Array,
default: () => [],
},
size: {
type: String,
default: '24px',
},
showMoreThumbnailsCount: {
type: Boolean,
default: false,
},
moreThumbnailsText: {
type: String,
default: '',
},
},
};
</script>
<style lang="scss" scoped>
.overlapping-thumbnails {
display: flex;
}
.overlapping-thumbnail {
position: relative;
box-shadow: var(--shadow-small);
&:not(:first-child) {
margin-left: var(--space-minus-small);
}
}
.thumbnail-more-text {
display: inline-flex;
align-items: center;
position: relative;
margin-left: var(--space-minus-small);
padding: 0 var(--space-small);
box-shadow: var(--shadow-small);
background: var(--color-background);
border-radius: var(--space-giga);
border: 1px solid var(--white);
color: var(--s-600);
font-size: var(--font-size-mini);
font-weight: var(--font-weight-medium);
}
</style>

View file

@ -0,0 +1,69 @@
import ThumbnailGroup from '../ThumbnailGroup.vue';
export default {
title: 'Components/ThumbnailGroup',
component: ThumbnailGroup,
argTypes: {
usersList: {
defaultValue: [
{
name: 'John',
id: 1,
thumbnail: '',
},
{
name: 'John',
id: 2,
thumbnail: '',
},
{
name: 'John',
id: 3,
thumbnail: '',
},
{
name: 'John',
id: 4,
thumbnail: '',
},
{
name: 'John',
id: 5,
thumbnail: '',
},
{
name: 'John',
id: 6,
thumbnail: '',
},
],
control: {
type: 'object',
},
},
size: {
control: {
type: 'text',
},
},
moreThumbnailsText: {
control: {
type: 'text',
default: '2 more',
},
},
showMoreThumbnailsCount: {
control: {
type: 'boolean',
},
},
},
};
const Template = (args, { argTypes }) => ({
props: Object.keys(argTypes),
components: { ThumbnailGroup },
template: '<ThumbnailGroup v-bind="$props"/>',
});
export const Primary = Template.bind({});

View file

@ -10,6 +10,13 @@ export const MESSAGE_TYPE = {
ACTIVITY: 2,
TEMPLATE: 3,
};
export const CONVERSATION_STATUS = {
OPEN: 'open',
RESOLVED: 'resolved',
PENDING: 'pending',
SNOOZED: 'snoozed',
};
// Size in mega bytes
export const MAXIMUM_FILE_UPLOAD_SIZE = 40;
export const MAXIMUM_FILE_UPLOAD_SIZE_TWILIO_SMS_CHANNEL = 5;

View file

@ -1,4 +1,5 @@
@import 'shared/assets/stylesheets/animations';
@import 'shared/assets/stylesheets/colors';
@import 'reset';
@import 'tailwindcss/base';

View file

@ -1,5 +1,5 @@
<template>
<div class="conversation--container">
<div class="conversation--container" :class="colorSchemeClass">
<div class="conversation-wrap" :class="{ 'is-typing': isAgentTyping }">
<div v-if="isFetchingList" class="message--loader">
<spinner />
@ -26,6 +26,8 @@ import ChatMessage from 'widget/components/ChatMessage.vue';
import AgentTypingBubble from 'widget/components/AgentTypingBubble.vue';
import DateSeparator from 'shared/components/DateSeparator.vue';
import Spinner from 'shared/components/Spinner.vue';
import darkModeMixin from 'widget/mixins/darkModeMixin';
import { mapActions, mapGetters } from 'vuex';
export default {
@ -36,6 +38,7 @@ export default {
DateSeparator,
Spinner,
},
mixins: [darkModeMixin],
props: {
groupedMessages: {
type: Array,
@ -56,6 +59,9 @@ export default {
conversationSize: 'conversation/getConversationSize',
isAgentTyping: 'conversation/getIsAgentTyping',
}),
colorSchemeClass() {
return `${this.darkMode === 'light' ? 'light' : 'dark'}`;
},
},
watch: {
allMessagesLoaded() {
@ -110,6 +116,13 @@ export default {
flex: 1;
overflow-y: auto;
color-scheme: light dark;
&.light {
color-scheme: light;
}
&.dark {
color-scheme: dark;
}
}
.conversation-wrap {

View file

@ -1,7 +1,7 @@
<template>
<div v-if="showHeaderActions" class="actions flex items-center">
<button
v-if="conversationStatus === 'open' && hasEndConversationEnabled"
v-if="canLeaveConversation && hasEndConversationEnabled"
class="button transparent compact"
:title="$t('END_CONVERSATION')"
@click="resolveConversation"
@ -45,6 +45,7 @@ import { popoutChatWindow } from '../helpers/popoutHelper';
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import darkModeMixin from 'widget/mixins/darkModeMixin';
import configMixin from 'widget/mixins/configMixin';
import { CONVERSATION_STATUS } from 'shared/constants/messages';
export default {
name: 'HeaderActions',
@ -60,6 +61,13 @@ export default {
...mapGetters({
conversationAttributes: 'conversationAttributes/getConversationParams',
}),
canLeaveConversation() {
return [
CONVERSATION_STATUS.OPEN,
CONVERSATION_STATUS.SNOOZED,
CONVERSATION_STATUS.PENDING,
].includes(this.conversationStatus);
},
isIframe() {
return IFrameHelper.isIFrame();
},