Files
chatwoot/app/javascript/widget/components/HeaderActions.vue
Sivin Varghese 3a693947b5 feat: Add RTL Support to Widget (#11022)
This PR adds RTL support to the web widget for improved right-to-left language compatibility, updates colors, and cleans up code.

Fixes https://linear.app/chatwoot/issue/CW-4089/rtl-issues-on-widget

https://github.com/chatwoot/chatwoot/issues/9791

Other PR: https://github.com/chatwoot/chatwoot/pull/11016
2025-03-21 09:39:03 -07:00

124 lines
3.1 KiB
Vue

<script>
import { mapGetters } from 'vuex';
import { IFrameHelper, RNHelper } from 'widget/helpers/utils';
import { popoutChatWindow } from '../helpers/popoutHelper';
import FluentIcon from 'shared/components/FluentIcon/Index.vue';
import configMixin from 'widget/mixins/configMixin';
import { CONVERSATION_STATUS } from 'shared/constants/messages';
export default {
name: 'HeaderActions',
components: { FluentIcon },
mixins: [configMixin],
props: {
showPopoutButton: {
type: Boolean,
default: false,
},
showEndConversationButton: {
type: Boolean,
default: true,
},
},
computed: {
...mapGetters({
conversationAttributes: 'conversationAttributes/getConversationParams',
}),
canLeaveConversation() {
return [
CONVERSATION_STATUS.OPEN,
CONVERSATION_STATUS.SNOOZED,
CONVERSATION_STATUS.PENDING,
].includes(this.conversationStatus);
},
isIframe() {
return IFrameHelper.isIFrame();
},
isRNWebView() {
return RNHelper.isRNWebView();
},
showHeaderActions() {
return this.isIframe || this.isRNWebView || this.hasWidgetOptions;
},
conversationStatus() {
return this.conversationAttributes.status;
},
hasWidgetOptions() {
return this.showPopoutButton || this.conversationStatus === 'open';
},
},
methods: {
popoutWindow() {
this.closeWindow();
const {
location: { origin },
chatwootWebChannel: { websiteToken },
authToken,
} = window;
popoutChatWindow(
origin,
websiteToken,
this.$root.$i18n.locale,
authToken
);
},
closeWindow() {
if (IFrameHelper.isIFrame()) {
IFrameHelper.sendMessage({ event: 'closeWindow' });
} else if (RNHelper.isRNWebView) {
RNHelper.sendMessage({ type: 'close-widget' });
}
},
resolveConversation() {
this.$store.dispatch('conversation/resolveConversation');
},
},
};
</script>
<!-- eslint-disable-next-line vue/no-root-v-if -->
<template>
<div v-if="showHeaderActions" class="actions flex items-center gap-3">
<button
v-if="
canLeaveConversation &&
hasEndConversationEnabled &&
showEndConversationButton
"
class="button transparent compact"
:title="$t('END_CONVERSATION')"
@click="resolveConversation"
>
<FluentIcon icon="sign-out" size="22" class="text-n-slate-12" />
</button>
<button
v-if="showPopoutButton"
class="button transparent compact new-window--button"
@click="popoutWindow"
>
<FluentIcon icon="open" size="22" class="text-n-slate-12" />
</button>
<button
class="button transparent compact close-button"
:class="{
'rn-close-button': isRNWebView,
}"
@click="closeWindow"
>
<FluentIcon icon="dismiss" size="24" class="text-n-slate-12" />
</button>
</div>
</template>
<style scoped lang="scss">
.actions {
.close-button {
display: none;
}
.rn-close-button {
display: block !important;
}
}
</style>