Merge branch 'develop' into CW-2773
This commit is contained in:
@@ -162,7 +162,7 @@ gem 'omniauth-oauth2'
|
||||
gem 'audited', '~> 5.4', '>= 5.4.1'
|
||||
|
||||
# need for google auth
|
||||
gem 'omniauth'
|
||||
gem 'omniauth', '>= 2.1.2'
|
||||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-rails_csrf_protection', '~> 1.0'
|
||||
|
||||
|
||||
+4
-4
@@ -511,7 +511,7 @@ GEM
|
||||
rack (>= 1.2, < 4)
|
||||
snaky_hash (~> 2.0)
|
||||
version_gem (~> 1.1)
|
||||
omniauth (2.1.1)
|
||||
omniauth (2.1.2)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 2.2.3)
|
||||
rack-protection
|
||||
@@ -568,8 +568,8 @@ GEM
|
||||
rack (>= 2.0.0)
|
||||
rack-mini-profiler (3.2.0)
|
||||
rack (>= 1.2.0)
|
||||
rack-protection (3.0.6)
|
||||
rack
|
||||
rack-protection (3.1.0)
|
||||
rack (~> 2.2, >= 2.2.4)
|
||||
rack-proxy (0.7.6)
|
||||
rack
|
||||
rack-test (2.1.0)
|
||||
@@ -905,7 +905,7 @@ DEPENDENCIES
|
||||
neighbor
|
||||
newrelic-sidekiq-metrics (>= 1.6.2)
|
||||
newrelic_rpm
|
||||
omniauth
|
||||
omniauth (>= 2.1.2)
|
||||
omniauth-google-oauth2
|
||||
omniauth-oauth2
|
||||
omniauth-rails_csrf_protection (~> 1.0)
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
<template>
|
||||
<transition name="network-notification-fade" tag="div">
|
||||
<div v-show="showNotification" class="ui-notification-container">
|
||||
<div class="ui-notification">
|
||||
<fluent-icon icon="wifi-off" />
|
||||
<p class="ui-notification-text">
|
||||
{{
|
||||
useInstallationName(
|
||||
$t('NETWORK.NOTIFICATION.TEXT'),
|
||||
globalConfig.installationName
|
||||
)
|
||||
}}
|
||||
</p>
|
||||
<woot-button variant="clear" size="small" @click="refreshPage">
|
||||
{{ $t('NETWORK.BUTTON.REFRESH') }}
|
||||
</woot-button>
|
||||
<div v-show="showNotification" class="fixed top-4 left-2 z-50 group">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 w-full rounded-lg shadow-lg bg-yellow-200 dark:bg-yellow-700 relative"
|
||||
>
|
||||
<fluent-icon
|
||||
icon="wifi-off"
|
||||
class="text-yellow-700/50 dark:text-yellow-50"
|
||||
size="18"
|
||||
/>
|
||||
<span
|
||||
class="text-xs tracking-wide font-medium px-2 text-yellow-700/70 dark:text-yellow-50"
|
||||
>
|
||||
{{ $t('NETWORK.NOTIFICATION.OFFLINE') }}
|
||||
</span>
|
||||
<woot-button
|
||||
variant="smooth"
|
||||
:title="$t('NETWORK.BUTTON.REFRESH')"
|
||||
variant="clear"
|
||||
size="small"
|
||||
color-scheme="warning"
|
||||
icon="dismiss-circle"
|
||||
icon="arrow-clockwise"
|
||||
class="visible transition-all duration-500 ease-in-out ml-1"
|
||||
@click="refreshPage"
|
||||
/>
|
||||
<woot-button
|
||||
variant="clear"
|
||||
size="small"
|
||||
color-scheme="warning"
|
||||
icon="dismiss"
|
||||
@click="closeNotification"
|
||||
/>
|
||||
</div>
|
||||
@@ -47,7 +56,12 @@ export default {
|
||||
mounted() {
|
||||
window.addEventListener('offline', this.updateOnlineStatus);
|
||||
window.bus.$on(BUS_EVENTS.WEBSOCKET_DISCONNECT, () => {
|
||||
this.updateOnlineStatus({ type: 'offline' });
|
||||
// TODO: Remove this after completing the conversation list refetching
|
||||
// TODO: DIRTY FIX : CLEAN UP THIS WITH PROPER FIX, DELAYING THE RECONNECT FOR NOW
|
||||
// THE CABLE IS FIRING IS VERY COMMON AND THUS INTERFERING USER EXPERIENCE
|
||||
setTimeout(() => {
|
||||
this.updateOnlineStatus({ type: 'offline' });
|
||||
}, 4000);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -72,33 +86,3 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~dashboard/assets/scss/mixins';
|
||||
|
||||
.ui-notification-container {
|
||||
max-width: 25rem;
|
||||
position: absolute;
|
||||
right: var(--space-normal);
|
||||
top: var(--space-normal);
|
||||
z-index: var(--z-index-very-high);
|
||||
}
|
||||
|
||||
.ui-notification {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
background-color: var(--y-100);
|
||||
border-radius: var(--border-radius-medium);
|
||||
box-shadow: var(--shadow-large);
|
||||
|
||||
min-width: 15rem;
|
||||
padding: var(--space-normal);
|
||||
}
|
||||
|
||||
.ui-notification-text {
|
||||
margin: 0 var(--space-small);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -84,7 +84,10 @@ import {
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings';
|
||||
import { replaceVariablesInMessage } from '@chatwoot/utils';
|
||||
import {
|
||||
replaceVariablesInMessage,
|
||||
createTypingIndicator,
|
||||
} from '@chatwoot/utils';
|
||||
import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
||||
import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
|
||||
import { uploadFile } from 'dashboard/helper/uploadHelper';
|
||||
@@ -140,6 +143,15 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typingIndicator: createTypingIndicator(
|
||||
() => {
|
||||
this.$emit('typing-on');
|
||||
},
|
||||
() => {
|
||||
this.$emit('typing-off');
|
||||
},
|
||||
TYPING_INDICATOR_IDLE_TIME
|
||||
),
|
||||
showUserMentions: false,
|
||||
showCannedMenu: false,
|
||||
showVariables: false,
|
||||
@@ -638,15 +650,6 @@ export default {
|
||||
hideMentions() {
|
||||
this.showUserMentions = false;
|
||||
},
|
||||
resetTyping() {
|
||||
this.$emit('typing-off');
|
||||
this.idleTimer = null;
|
||||
},
|
||||
turnOffIdleTimer() {
|
||||
if (this.idleTimer) {
|
||||
clearTimeout(this.idleTimer);
|
||||
}
|
||||
},
|
||||
handleLineBreakWhenEnterToSendEnabled(event) {
|
||||
if (
|
||||
hasPressedEnterAndNotCmdOrShift(event) &&
|
||||
@@ -666,14 +669,7 @@ export default {
|
||||
}
|
||||
},
|
||||
onKeyup() {
|
||||
if (!this.idleTimer) {
|
||||
this.$emit('typing-on');
|
||||
}
|
||||
this.turnOffIdleTimer();
|
||||
this.idleTimer = setTimeout(
|
||||
() => this.resetTyping(),
|
||||
TYPING_INDICATOR_IDLE_TIME
|
||||
);
|
||||
this.typingIndicator.start();
|
||||
this.updateImgToolbarOnDelete();
|
||||
},
|
||||
onKeydown(event) {
|
||||
@@ -685,8 +681,7 @@ export default {
|
||||
}
|
||||
},
|
||||
onBlur() {
|
||||
this.turnOffIdleTimer();
|
||||
this.resetTyping();
|
||||
this.typingIndicator.stop();
|
||||
this.$emit('blur');
|
||||
},
|
||||
onFocus() {
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
},
|
||||
"NETWORK": {
|
||||
"NOTIFICATION": {
|
||||
"TEXT": "Disconnected from Chatwoot"
|
||||
"OFFLINE": "Offline"
|
||||
},
|
||||
"BUTTON": {
|
||||
"REFRESH": "Refresh"
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"HEADER": {
|
||||
"FILTER": "Filter by",
|
||||
"SORT": "Sort by",
|
||||
"LOCALE": "Locale",
|
||||
"SETTINGS_BUTTON": "Settings",
|
||||
"NEW_BUTTON": "New Article",
|
||||
"DROPDOWN_OPTIONS": {
|
||||
@@ -15,6 +16,12 @@
|
||||
"MINE": "My Articles",
|
||||
"DRAFT": "Draft Articles",
|
||||
"ARCHIVED": "Archived Articles"
|
||||
},
|
||||
"LOCALE_SELECT": {
|
||||
"TITLE": "Select locale",
|
||||
"PLACEHOLDER": "Select locale",
|
||||
"NO_RESULT": "No locale found",
|
||||
"SEARCH_PLACEHOLDER": "Search locale"
|
||||
}
|
||||
},
|
||||
"EDIT_HEADER": {
|
||||
|
||||
+78
-3
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex px-4 items-center justify-between w-full h-16 pt-2 sticky top-0 bg-white dark:bg-slate-900"
|
||||
class="flex px-4 items-center justify-between w-full h-16 pt-2 sticky top-0 z-10 bg-white dark:bg-slate-900"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<woot-sidemenu-icon />
|
||||
@@ -86,6 +86,45 @@
|
||||
size="small"
|
||||
color-scheme="secondary"
|
||||
/>
|
||||
<div class="relative">
|
||||
<woot-button
|
||||
v-if="shouldShowLocaleDropdown"
|
||||
icon="globe"
|
||||
color-scheme="secondary"
|
||||
size="small"
|
||||
variant="hollow"
|
||||
@click="openLocaleDropdown"
|
||||
>
|
||||
<div class="flex justify-between w-full min-w-0 items-center">
|
||||
<span
|
||||
class="inline-flex ml-1 rtl:ml-0 rtl:mr-1 items-center text-slate-800 dark:text-slate-100"
|
||||
>
|
||||
{{ selectedLocale }}
|
||||
<Fluent-icon
|
||||
class="dropdown-arrow"
|
||||
icon="chevron-down"
|
||||
size="14"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</woot-button>
|
||||
<div
|
||||
v-if="showLocaleDropdown"
|
||||
v-on-clickaway="closeLocaleDropdown"
|
||||
class="dropdown-pane dropdown-pane--open"
|
||||
>
|
||||
<multiselect-dropdown-items
|
||||
:options="switchableLocales"
|
||||
:has-thumbnail="false"
|
||||
:selected-items="[selectedLocale]"
|
||||
:input-placeholder="
|
||||
$t('HELP_CENTER.HEADER.LOCALE_SELECT.SEARCH_PLACEHOLDER')
|
||||
"
|
||||
:no-search-result="$t('HELP_CENTER.HEADER.LOCALE_SELECT.NO_RESULT')"
|
||||
@click="onClickSelectItem"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<woot-button
|
||||
size="small"
|
||||
icon="add"
|
||||
@@ -103,12 +142,15 @@ import { mixin as clickaway } from 'vue-clickaway';
|
||||
|
||||
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
|
||||
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
|
||||
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems.vue';
|
||||
|
||||
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon.vue';
|
||||
export default {
|
||||
components: {
|
||||
FluentIcon,
|
||||
WootDropdownItem,
|
||||
WootDropdownMenu,
|
||||
MultiselectDropdownItems,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
props: {
|
||||
@@ -124,16 +166,35 @@ export default {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
selectedLocale: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
shouldShowSettings: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
allLocales: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showSortByDropdown: false,
|
||||
showLocaleDropdown: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
shouldShowLocaleDropdown() {
|
||||
return this.allLocales.length > 1;
|
||||
},
|
||||
switchableLocales() {
|
||||
return this.allLocales.filter(
|
||||
locale => locale.name !== this.selectedLocale
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
openFilterModal() {
|
||||
this.$emit('openModal');
|
||||
@@ -146,8 +207,22 @@ export default {
|
||||
this.$emit('close');
|
||||
this.showSortByDropdown = false;
|
||||
},
|
||||
openLocaleDropdown() {
|
||||
this.showLocaleDropdown = true;
|
||||
},
|
||||
closeLocaleDropdown() {
|
||||
this.showLocaleDropdown = false;
|
||||
},
|
||||
onClickNewArticlePage() {
|
||||
this.$emit('newArticlePage');
|
||||
this.$emit('new-article-page');
|
||||
},
|
||||
onClickSelectItem(value) {
|
||||
const { name, code } = value;
|
||||
this.closeLocaleDropdown();
|
||||
if (!name || name === this.selectedLocale) {
|
||||
return;
|
||||
}
|
||||
this.$emit('change-locale', code);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -155,7 +230,7 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dropdown-pane--open {
|
||||
@apply top-12 right-[9.25rem];
|
||||
@apply absolute top-10 right-0 z-50 min-w-[8rem];
|
||||
}
|
||||
.dropdown-arrow {
|
||||
@apply ml-1 rtl:ml-0 rtl:mr-1;
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
v-if="isHelpCenterEnabled"
|
||||
class="flex h-full min-h-0 overflow-hidden flex-1 px-0 bg-white dark:bg-slate-900"
|
||||
>
|
||||
<router-view />
|
||||
<router-view @reload-locale="fetchPortalAndItsCategories" />
|
||||
<command-bar />
|
||||
<account-selector
|
||||
:show-account-modal="showAccountModal"
|
||||
|
||||
+39
-2
@@ -5,8 +5,11 @@
|
||||
<article-header
|
||||
:header-title="headerTitle"
|
||||
:count="meta.count"
|
||||
:selected-locale="activeLocaleName"
|
||||
:all-locales="allowedLocales"
|
||||
selected-value="Published"
|
||||
@newArticlePage="newArticlePage"
|
||||
@new-article-page="newArticlePage"
|
||||
@change-locale="onChangeLocale"
|
||||
/>
|
||||
<article-table
|
||||
:articles="articles"
|
||||
@@ -32,6 +35,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import allLocales from 'shared/constants/locales.js';
|
||||
|
||||
import Spinner from 'shared/components/Spinner.vue';
|
||||
import ArticleHeader from 'dashboard/routes/dashboard/helpcenter/components/Header/ArticleHeader.vue';
|
||||
@@ -58,6 +62,7 @@ export default {
|
||||
meta: 'articles/getMeta',
|
||||
isFetching: 'articles/isFetching',
|
||||
currentUserId: 'getCurrentUserID',
|
||||
getPortalBySlug: 'portals/portalBySlug',
|
||||
}),
|
||||
selectedCategory() {
|
||||
return this.categories.find(
|
||||
@@ -118,6 +123,28 @@ export default {
|
||||
? this.selectedCategory.name
|
||||
: '';
|
||||
},
|
||||
activeLocale() {
|
||||
return this.$route.params.locale;
|
||||
},
|
||||
activeLocaleName() {
|
||||
return allLocales[this.activeLocale];
|
||||
},
|
||||
portal() {
|
||||
return this.getPortalBySlug(this.selectedPortalSlug);
|
||||
},
|
||||
allowedLocales() {
|
||||
if (!this.portal) {
|
||||
return [];
|
||||
}
|
||||
const { allowed_locales: allowedLocales } = this.portal.config;
|
||||
return allowedLocales.map(locale => {
|
||||
return {
|
||||
id: locale.code,
|
||||
name: allLocales[locale.code],
|
||||
code: locale.code,
|
||||
};
|
||||
});
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
@@ -137,7 +164,7 @@ export default {
|
||||
this.$store.dispatch('articles/index', {
|
||||
pageNumber: pageNumber || this.pageNumber,
|
||||
portalSlug: this.$route.params.portalSlug,
|
||||
locale: this.$route.params.locale,
|
||||
locale: this.activeLocale,
|
||||
status: this.status,
|
||||
authorId: this.author,
|
||||
categorySlug: this.selectedCategorySlug,
|
||||
@@ -152,6 +179,16 @@ export default {
|
||||
portalSlug: this.$route.params.portalSlug,
|
||||
});
|
||||
},
|
||||
onChangeLocale(locale) {
|
||||
this.$router.push({
|
||||
name: 'list_all_locale_articles',
|
||||
params: {
|
||||
portalSlug: this.$route.params.portalSlug,
|
||||
locale,
|
||||
},
|
||||
});
|
||||
this.$emit('reload-locale');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
removeSignature,
|
||||
extractTextFromMarkdown,
|
||||
} from 'dashboard/helper/editorHelper';
|
||||
import { createTypingIndicator } from '@chatwoot/utils';
|
||||
|
||||
const TYPING_INDICATOR_IDLE_TIME = 4000;
|
||||
export default {
|
||||
@@ -54,7 +55,15 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
idleTimer: null,
|
||||
typingIndicator: createTypingIndicator(
|
||||
() => {
|
||||
this.$emit('typing-on');
|
||||
},
|
||||
() => {
|
||||
this.$emit('typing-off');
|
||||
},
|
||||
TYPING_INDICATOR_IDLE_TIME
|
||||
),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -137,28 +146,11 @@ export default {
|
||||
this.$emit('input', event.target.value);
|
||||
this.resizeTextarea();
|
||||
},
|
||||
resetTyping() {
|
||||
this.$emit('typing-off');
|
||||
this.idleTimer = null;
|
||||
},
|
||||
turnOffIdleTimer() {
|
||||
if (this.idleTimer) {
|
||||
clearTimeout(this.idleTimer);
|
||||
}
|
||||
},
|
||||
onKeyup() {
|
||||
if (!this.idleTimer) {
|
||||
this.$emit('typing-on');
|
||||
}
|
||||
this.turnOffIdleTimer();
|
||||
this.idleTimer = setTimeout(
|
||||
() => this.resetTyping(),
|
||||
TYPING_INDICATOR_IDLE_TIME
|
||||
);
|
||||
this.typingIndicator.start();
|
||||
},
|
||||
onBlur() {
|
||||
this.turnOffIdleTimer();
|
||||
this.resetTyping();
|
||||
this.typingIndicator.stop();
|
||||
this.$emit('blur');
|
||||
},
|
||||
onFocus() {
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
"dependencies": {
|
||||
"@braid/vue-formulate": "^2.5.2",
|
||||
"@chatwoot/prosemirror-schema": "1.0.3",
|
||||
"@chatwoot/utils": "^0.0.20",
|
||||
"@chatwoot/utils": "^0.0.21",
|
||||
"@hcaptcha/vue-hcaptcha": "^0.3.2",
|
||||
"@june-so/analytics-next": "^1.36.5",
|
||||
"@radix-ui/colors": "^1.0.1",
|
||||
|
||||
@@ -3177,10 +3177,10 @@
|
||||
prosemirror-utils "^0.9.6"
|
||||
prosemirror-view "^1.17.2"
|
||||
|
||||
"@chatwoot/utils@^0.0.20":
|
||||
version "0.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@chatwoot/utils/-/utils-0.0.20.tgz#d7cb407da434efcce4262178dbef55441f218489"
|
||||
integrity sha512-rChMLxxbtzDpS2wePhnsdu+NDfRWbV+9Jw9eZ34jQRxkQ4LYVUoj6z5gC7a5+3izZQZ1XEwDSPHIiIvIUX4tzg==
|
||||
"@chatwoot/utils@^0.0.21":
|
||||
version "0.0.21"
|
||||
resolved "https://registry.yarnpkg.com/@chatwoot/utils/-/utils-0.0.21.tgz#f9116daac0514a8a8fa6ce594efff10062222be0"
|
||||
integrity sha512-eUDJ1K5x1rFlBywRctU3hXXiJ1U0EZiklowNl/YJOh1/BWDns4It3DWrQmAcjvsNbEUNWMfY+ShJmjdeei71Cw==
|
||||
dependencies:
|
||||
date-fns "^2.29.1"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user