Merge branch 'release/3.1.1'

This commit is contained in:
Sojan
2023-09-22 19:54:43 -07:00
313 changed files with 2395 additions and 949 deletions

View File

@@ -76,6 +76,7 @@ gem 'pundit'
# super admin
gem 'administrate', '>= 0.19.0'
gem 'administrate-field-active_storage'
gem 'administrate-field-belongs_to_search'
##--- gems for pubsub service ---##
# https://karolgalanciak.com/blog/2019/11/30/from-activerecord-callbacks-to-publish-slash-subscribe-pattern-and-event-driven-design/

View File

@@ -116,6 +116,11 @@ GEM
administrate-field-active_storage (0.4.2)
administrate (>= 0.2.2)
rails (>= 7.0)
administrate-field-belongs_to_search (0.8.0)
administrate (>= 0.3, < 1.0)
jbuilder (~> 2)
rails (>= 4.2, < 7.1)
selectize-rails (~> 0.6)
annotate (3.2.0)
activerecord (>= 3.2, < 8.0)
rake (>= 10.4, < 14.0)
@@ -831,6 +836,7 @@ DEPENDENCIES
acts-as-taggable-on
administrate (>= 0.19.0)
administrate-field-active_storage
administrate-field-belongs_to_search
annotate
attr_extras
audited (~> 5.3)

View File

@@ -1 +1 @@
2.17.0
3.1.0

View File

@@ -1 +1 @@
2.3.0
2.4.0

View File

@@ -78,11 +78,6 @@ $conv-header-height: 4rem;
$inbox-thumb-size: 4.8rem;
// Spinner
$spinkit-spinner-color: $color-white !default;
$spinkit-spinner-margin: 0 0 0 1.6rem !default;
$spinkit-size: 1.6rem !default;
// Snackbar default
$woot-snackbar-bg: #323232;
$woot-snackbar-button: #ffeb3b;

View File

@@ -25,7 +25,8 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
render json: { error: 'Specify search string with parameter q' }, status: :unprocessable_entity if params[:q].blank? && return
contacts = resolved_contacts.where(
'name ILIKE :search OR email ILIKE :search OR phone_number ILIKE :search OR contacts.identifier LIKE :search',
'name ILIKE :search OR email ILIKE :search OR phone_number ILIKE :search OR contacts.identifier LIKE :search
OR contacts.additional_attributes->>\'company_name\' ILIKE :search',
search: "%#{params[:q].strip}%"
)
@contacts_count = contacts.count

View File

@@ -1,4 +1,4 @@
class Api::V1::UploadController < Api::BaseController
class Api::V1::Accounts::UploadController < Api::V1::Accounts::BaseController
def create
file_blob = ActiveStorage::Blob.create_and_upload!(
key: nil,

View File

@@ -44,7 +44,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::B
end
def list_params
params.permit(:query, :locale, :sort)
params.permit(:query, :locale, :sort, :status)
end
def permitted_params

View File

@@ -6,6 +6,7 @@ class SuperAdmin::InstanceStatusesController < SuperAdmin::ApplicationController
postgres_status
redis_metrics
chatwoot_edition
instance_meta
end
def chatwoot_edition
@@ -18,6 +19,10 @@ class SuperAdmin::InstanceStatusesController < SuperAdmin::ApplicationController
end
end
def instance_meta
@metrics['Database Migrations'] = ActiveRecord::Base.connection.migration_context.needs_migration? ? 'pending' : 'completed'
end
def chatwoot_version
@metrics['Chatwoot version'] = Chatwoot.config[:version]
end

View File

@@ -18,8 +18,8 @@ class AccountDashboard < Administrate::BaseDashboard
end
ATTRIBUTE_TYPES = {
id: Field::Number,
name: Field::String,
id: Field::Number.with_options(searchable: true),
name: Field::String.with_options(searchable: true),
created_at: Field::DateTime,
updated_at: Field::DateTime,
users: CountField,

View File

@@ -8,9 +8,9 @@ class AccountUserDashboard < Administrate::BaseDashboard
# which determines how the attribute is displayed
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
account: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name', order: 'id DESC'),
user: Field::BelongsTo.with_options(searchable: true, searchable_field: 'name', order: 'id DESC'),
inviter: Field::BelongsTo.with_options(class_name: 'User', searchable: true, searchable_field: 'name'),
account: Field::BelongsToSearch.with_options(class_name: 'Account', searchable: true, searchable_field: [:name, :id], order: 'id DESC'),
user: Field::BelongsToSearch.with_options(class_name: 'User', searchable: true, searchable_field: [:name, :email, :id], order: 'id DESC'),
inviter: Field::BelongsToSearch.with_options(class_name: 'User', searchable: true, searchable_field: [:name, :email, :id], order: 'id DESC'),
id: Field::Number,
role: Field::Select.with_options(collection: AccountUser.roles.keys),
created_at: Field::DateTime,

View File

@@ -9,7 +9,7 @@ class UserDashboard < Administrate::BaseDashboard
# on pages throughout the dashboard.
ATTRIBUTE_TYPES = {
account_users: Field::HasMany,
id: Field::Number,
id: Field::Number.with_options(searchable: true),
avatar_url: AvatarField,
avatar: Field::ActiveStorage.with_options(
destroy_url: proc do |_namespace, _resource, attachment|
@@ -28,9 +28,9 @@ class UserDashboard < Administrate::BaseDashboard
confirmed_at: Field::DateTime,
confirmation_sent_at: Field::DateTime,
unconfirmed_email: Field::String,
name: Field::String,
name: Field::String.with_options(searchable: true),
display_name: Field::String,
email: Field::String,
email: Field::String.with_options(searchable: true),
tokens: Field::String.with_options(searchable: false),
created_at: Field::DateTime,
updated_at: Field::DateTime,

View File

@@ -26,14 +26,14 @@
<script>
import { mapGetters } from 'vuex';
import AddAccountModal from '../dashboard/components/layout/sidebarComponents/AddAccountModal';
import AddAccountModal from '../dashboard/components/layout/sidebarComponents/AddAccountModal.vue';
import LoadingState from './components/widgets/LoadingState.vue';
import NetworkNotification from './components/NetworkNotification';
import NetworkNotification from './components/NetworkNotification.vue';
import UpdateBanner from './components/app/UpdateBanner.vue';
import UpgradeBanner from './components/app/UpgradeBanner.vue';
import PaymentPendingBanner from './components/app/PaymentPendingBanner.vue';
import vueActionCable from './helper/actionCable';
import WootSnackbarBox from './components/SnackbarContainer';
import WootSnackbarBox from './components/SnackbarContainer.vue';
import rtlMixin from 'shared/mixins/rtlMixin';
import { setColorTheme } from './helper/themeHelper';
import {

View File

@@ -81,11 +81,6 @@ $conv-header-height: 2.5rem;
$inbox-thumb-size: 3rem;
// Spinner
$spinkit-spinner-color: $color-white !default;
$spinkit-spinner-margin: 0 0 0 1rem !default;
$spinkit-size: 1rem !default;
// Snackbar default
$woot-snackbar-bg: #323232;
$woot-snackbar-button: #ffeb3b;

View File

@@ -9,7 +9,6 @@
@import 'shared/assets/stylesheets/border-radius';
@import 'variables';
@import '~spinkit/scss/spinners/7-three-bounce';
@import 'vue-multiselect/dist/vue-multiselect.min.css';
@import '~shared/assets/stylesheets/ionicons';

View File

@@ -31,7 +31,7 @@
</template>
<script>
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
export default {
components: {

View File

@@ -193,17 +193,17 @@
<script>
import { mapGetters } from 'vuex';
import ConversationAdvancedFilter from './widgets/conversation/ConversationAdvancedFilter';
import ConversationBasicFilter from './widgets/conversation/ConversationBasicFilter';
import ChatTypeTabs from './widgets/ChatTypeTabs';
import ConversationCard from './widgets/conversation/ConversationCard';
import ConversationAdvancedFilter from './widgets/conversation/ConversationAdvancedFilter.vue';
import ConversationBasicFilter from './widgets/conversation/ConversationBasicFilter.vue';
import ChatTypeTabs from './widgets/ChatTypeTabs.vue';
import ConversationCard from './widgets/conversation/ConversationCard.vue';
import timeMixin from '../mixins/time';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import conversationMixin from '../mixins/conversations';
import wootConstants from 'dashboard/constants/globals';
import advancedFilterTypes from './widgets/conversation/advancedFilterItems';
import filterQueryGenerator from '../helper/filterQueryGenerator.js';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews.vue';
import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews.vue';
import ConversationBulkActions from './widgets/conversation/conversationBulkActions/Index.vue';
import alertMixin from 'shared/mixins/alertMixin';

View File

@@ -10,7 +10,7 @@
</template>
<script>
import WootSnackbar from './Snackbar';
import WootSnackbar from './Snackbar.vue';
export default {
components: {

View File

@@ -13,7 +13,7 @@
</template>
<script>
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
export default {
components: {

View File

@@ -90,7 +90,7 @@ import { getUnixTime } from 'date-fns';
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin';
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal';
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import {
hasPressedAltAndEKey,

View File

@@ -49,11 +49,11 @@
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu';
import WootDropdownHeader from 'shared/components/ui/dropdown/DropdownHeader';
import WootDropdownDivider from 'shared/components/ui/dropdown/DropdownDivider';
import AvailabilityStatusBadge from '../widgets/conversation/AvailabilityStatusBadge';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
import WootDropdownHeader from 'shared/components/ui/dropdown/DropdownHeader.vue';
import WootDropdownDivider from 'shared/components/ui/dropdown/DropdownDivider.vue';
import AvailabilityStatusBadge from '../widgets/conversation/AvailabilityStatusBadge.vue';
import wootConstants from 'dashboard/constants/globals';
const { AVAILABILITY_STATUS_KEYS } = wootConstants;

View File

@@ -35,8 +35,8 @@ import adminMixin from '../../mixins/isAdmin';
import { getSidebarItems } from './config/default-sidebar';
import alertMixin from 'shared/mixins/alertMixin';
import PrimarySidebar from './sidebarComponents/Primary';
import SecondarySidebar from './sidebarComponents/Secondary';
import PrimarySidebar from './sidebarComponents/Primary.vue';
import SecondarySidebar from './sidebarComponents/Secondary.vue';
import {
hasPressedAltAndCKey,
hasPressedAltAndRKey,

View File

@@ -16,7 +16,7 @@
</template>
<script>
import { mapGetters } from 'vuex';
import Thumbnail from '../../widgets/Thumbnail';
import Thumbnail from '../../widgets/Thumbnail.vue';
export default {
components: {

View File

@@ -109,9 +109,9 @@
import { mixin as clickaway } from 'vue-clickaway';
import { mapGetters } from 'vuex';
import Auth from '../../../api/auth';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu';
import AvailabilityStatus from 'dashboard/components/layout/AvailabilityStatus';
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
import AvailabilityStatus from 'dashboard/components/layout/AvailabilityStatus.vue';
export default {
components: {

View File

@@ -39,11 +39,11 @@
</div>
</template>
<script>
import Logo from './Logo';
import PrimaryNavItem from './PrimaryNavItem';
import OptionsMenu from './OptionsMenu';
import AgentDetails from './AgentDetails';
import NotificationBell from './NotificationBell';
import Logo from './Logo.vue';
import PrimaryNavItem from './PrimaryNavItem.vue';
import OptionsMenu from './OptionsMenu.vue';
import AgentDetails from './AgentDetails.vue';
import NotificationBell from './NotificationBell.vue';
import wootConstants from 'dashboard/constants/globals';
import { frontendURL } from 'dashboard/helper/URLHelper';
import { ACCOUNT_EVENTS } from '../../../helper/AnalyticsHelper/events';

View File

@@ -97,7 +97,7 @@ import {
getInboxWarningIconClass,
} from 'dashboard/helper/inbox';
import SecondaryChildNavItem from './SecondaryChildNavItem';
import SecondaryChildNavItem from './SecondaryChildNavItem.vue';
import {
isOnMentionsView,
isOnUnattendedView,

View File

@@ -28,8 +28,8 @@
</button>
</template>
<script>
import Spinner from 'shared/components/Spinner';
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
import Spinner from 'shared/components/Spinner.vue';
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
export default {
name: 'WootButton',

View File

@@ -108,7 +108,7 @@
<script>
import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue';
import AutomationActionFileInput from './AutomationFileInput.vue';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
export default {
components: {
AutomationActionTeamMessageInput,

View File

@@ -26,7 +26,7 @@
</template>
<script>
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
import alertMixin from 'shared/mixins/alertMixin';
export default {
components: {

View File

@@ -7,7 +7,7 @@
/>
</template>
<script>
import ChannelSelector from '../ChannelSelector';
import ChannelSelector from '../ChannelSelector.vue';
export default {
components: { ChannelSelector },
props: {

View File

@@ -21,7 +21,7 @@
</template>
<script>
import LoadingState from 'dashboard/components/widgets/LoadingState';
import LoadingState from 'dashboard/components/widgets/LoadingState.vue';
export default {
components: {
LoadingState,

View File

@@ -30,9 +30,9 @@
</template>
<script>
import AddLabel from 'shared/components/ui/dropdown/AddLabel';
import AddLabel from 'shared/components/ui/dropdown/AddLabel.vue';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import LabelDropdown from 'shared/components/ui/label/LabelDropdown';
import LabelDropdown from 'shared/components/ui/label/LabelDropdown.vue';
import { mixin as clickaway } from 'vue-clickaway';
import adminMixin from 'dashboard/mixins/isAdmin';
import {

View File

@@ -42,7 +42,7 @@
* Badge - Chat source indication { fb / telegram }
* Username - Username for avatar
*/
import Avatar from './Avatar';
import Avatar from './Avatar.vue';
import { removeEmoji } from 'shared/helpers/emoji';
export default {

View File

@@ -17,7 +17,7 @@
</div>
</template>
<script>
import Thumbnail from './Thumbnail';
import Thumbnail from './Thumbnail.vue';
export default {
components: {

View File

@@ -41,9 +41,9 @@ import {
triggerCharacters,
} from '@chatwoot/prosemirror-schema/src/mentions/plugin';
import TagAgents from '../conversation/TagAgents';
import CannedResponse from '../conversation/CannedResponse';
import VariableList from '../conversation/VariableList';
import TagAgents from '../conversation/TagAgents.vue';
import CannedResponse from '../conversation/CannedResponse.vue';
import VariableList from '../conversation/VariableList.vue';
import {
appendSignature,
removeSignature,
@@ -670,6 +670,10 @@ export default {
.ProseMirror-prompt {
@apply z-50 bg-slate-25 dark:bg-slate-700 rounded-md border border-solid border-slate-75 dark:border-slate-800;
h5 {
@apply dark:text-slate-25 text-slate-800;
}
}
.is-private {

View File

@@ -134,7 +134,7 @@ import {
ALLOWED_FILE_TYPES,
ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP,
} from 'shared/constants/messages';
import VideoCallButton from '../VideoCallButton';
import VideoCallButton from '../VideoCallButton.vue';
import AIAssistanceButton from '../AIAssistanceButton.vue';
import { REPLY_EDITOR_MODES } from './constants';
import { mapGetters } from 'vuex';

View File

@@ -46,7 +46,7 @@
import wootConstants from 'dashboard/constants/globals';
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import FilterItem from './FilterItem';
import FilterItem from './FilterItem.vue';
export default {
components: {

View File

@@ -58,11 +58,11 @@
</template>
<script>
import { mapGetters } from 'vuex';
import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel';
import ConversationHeader from './ConversationHeader';
import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel.vue';
import ConversationHeader from './ConversationHeader.vue';
import DashboardAppFrame from '../DashboardApp/Frame.vue';
import EmptyState from './EmptyState/EmptyState';
import MessagesView from './MessagesView';
import EmptyState from './EmptyState/EmptyState.vue';
import MessagesView from './MessagesView.vue';
export default {
components: {

View File

@@ -147,16 +147,16 @@
import { mapGetters } from 'vuex';
import { MESSAGE_TYPE } from 'widget/helpers/constants';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import Thumbnail from '../Thumbnail';
import Thumbnail from '../Thumbnail.vue';
import conversationMixin from '../../../mixins/conversations';
import timeMixin from '../../../mixins/time';
import router from '../../../routes';
import { frontendURL, conversationUrl } from '../../../helper/URLHelper';
import InboxName from '../InboxName';
import InboxName from '../InboxName.vue';
import inboxMixin from 'shared/mixins/inboxMixin';
import ConversationContextMenu from './contextMenu/Index.vue';
import alertMixin from 'shared/mixins/alertMixin';
import TimeAgo from 'dashboard/components/ui/TimeAgo';
import TimeAgo from 'dashboard/components/ui/TimeAgo.vue';
import CardLabels from './conversationCardComponents/CardLabels.vue';
import PriorityMark from './PriorityMark.vue';
const ATTACHMENT_ICONS = {

View File

@@ -73,12 +73,12 @@
import { hasPressedAltAndOKey } from 'shared/helpers/KeyboardHelpers';
import { mapGetters } from 'vuex';
import agentMixin from '../../../mixins/agentMixin.js';
import BackButton from '../BackButton';
import BackButton from '../BackButton.vue';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import inboxMixin from 'shared/mixins/inboxMixin';
import InboxName from '../InboxName';
import MoreActions from './MoreActions';
import Thumbnail from '../Thumbnail';
import InboxName from '../InboxName.vue';
import MoreActions from './MoreActions.vue';
import Thumbnail from '../Thumbnail.vue';
import wootConstants from 'dashboard/constants/globals';
import { conversationListPageURL } from 'dashboard/helper/URLHelper';
import { conversationReopenTime } from 'dashboard/helper/snoozeHelpers';

View File

@@ -37,8 +37,8 @@
import { mapGetters } from 'vuex';
import adminMixin from 'dashboard/mixins/isAdmin';
import accountMixin from 'dashboard/mixins/account';
import OnboardingView from '../OnboardingView';
import EmptyStateMessage from './EmptyStateMessage';
import OnboardingView from '../OnboardingView.vue';
import EmptyStateMessage from './EmptyStateMessage.vue';
export default {
components: {

View File

@@ -27,7 +27,7 @@
</template>
<script>
import Hotkey from 'dashboard/components/base/Hotkey';
import Hotkey from 'dashboard/components/base/Hotkey.vue';
export default {
components: {

View File

@@ -130,18 +130,18 @@
</template>
<script>
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import BubbleActions from './bubble/Actions';
import BubbleFile from './bubble/File';
import BubbleImage from './bubble/Image';
import BubbleVideo from './bubble/Video';
import BubbleImageAudioVideo from './bubble/ImageAudioVideo';
import BubbleActions from './bubble/Actions.vue';
import BubbleFile from './bubble/File.vue';
import BubbleImage from './bubble/Image.vue';
import BubbleVideo from './bubble/Video.vue';
import BubbleImageAudioVideo from './bubble/ImageAudioVideo.vue';
import BubbleIntegration from './bubble/Integration.vue';
import BubbleLocation from './bubble/Location';
import BubbleMailHead from './bubble/MailHead';
import BubbleText from './bubble/Text';
import BubbleContact from './bubble/Contact';
import Spinner from 'shared/components/Spinner';
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu';
import BubbleLocation from './bubble/Location.vue';
import BubbleMailHead from './bubble/MailHead.vue';
import BubbleText from './bubble/Text.vue';
import BubbleContact from './bubble/Contact.vue';
import Spinner from 'shared/components/Spinner.vue';
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu.vue';
import instagramImageErrorPlaceholder from './instagramImageErrorPlaceholder.vue';
import alertMixin from 'shared/mixins/alertMixin';
import contentTypeMixin from 'shared/mixins/contentTypeMixin';

View File

@@ -98,9 +98,9 @@
<script>
// components
import ReplyBox from './ReplyBox';
import Message from './Message';
import ConversationLabelSuggestion from './conversation/LabelSuggestion';
import ReplyBox from './ReplyBox.vue';
import Message from './Message.vue';
import ConversationLabelSuggestion from './conversation/LabelSuggestion.vue';
import Banner from 'dashboard/components/ui/Banner.vue';
// stores and apis

View File

@@ -39,8 +39,8 @@
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin';
import EmailTranscriptModal from './EmailTranscriptModal';
import ResolveAction from '../../buttons/ResolveAction';
import EmailTranscriptModal from './EmailTranscriptModal.vue';
import ResolveAction from '../../buttons/ResolveAction.vue';
import {
CMD_MUTE_CONVERSATION,
CMD_SEND_TRANSCRIPT,

View File

@@ -148,16 +148,16 @@ import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import alertMixin from 'shared/mixins/alertMixin';
import CannedResponse from './CannedResponse';
import ResizableTextArea from 'shared/components/ResizableTextArea';
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview';
import ReplyTopPanel from 'dashboard/components/widgets/WootWriter/ReplyTopPanel';
import ReplyEmailHead from './ReplyEmailHead';
import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel';
import CannedResponse from './CannedResponse.vue';
import ResizableTextArea from 'shared/components/ResizableTextArea.vue';
import AttachmentPreview from 'dashboard/components/widgets/AttachmentsPreview.vue';
import ReplyTopPanel from 'dashboard/components/widgets/WootWriter/ReplyTopPanel.vue';
import ReplyEmailHead from './ReplyEmailHead.vue';
import ReplyBottomPanel from 'dashboard/components/widgets/WootWriter/ReplyBottomPanel.vue';
import Banner from 'dashboard/components/ui/Banner.vue';
import { REPLY_EDITOR_MODES } from 'dashboard/components/widgets/WootWriter/constants';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
import WootAudioRecorder from 'dashboard/components/widgets/WootWriter/AudioRecorder';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
import WootAudioRecorder from 'dashboard/components/widgets/WootWriter/AudioRecorder.vue';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
import {

View File

@@ -31,7 +31,7 @@
import { mapGetters } from 'vuex';
import { hasPressedCommand } from 'shared/helpers/KeyboardHelpers';
import GalleryView from '../components/GalleryView';
import GalleryView from '../components/GalleryView.vue';
const ALLOWED_FILE_TYPES = {
IMAGE: 'image',

View File

@@ -150,7 +150,7 @@ import {
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
import timeMixin from 'dashboard/mixins/time';
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
const ALLOWED_FILE_TYPES = {
IMAGE: 'image',

View File

@@ -6,7 +6,7 @@
</template>
<script>
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
export default {
components: {

View File

@@ -96,7 +96,7 @@
<script>
import { mapGetters } from 'vuex';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
import { mixin as clickaway } from 'vue-clickaway';
export default {

View File

@@ -23,7 +23,7 @@
<script>
import { required } from 'vuelidate/lib/validators';
import Modal from '../../Modal';
import Modal from '../../Modal.vue';
export default {
components: {

View File

@@ -14,7 +14,7 @@
</modal>
</template>
<script>
import Modal from '../../Modal';
import Modal from '../../Modal.vue';
export default {
components: {

View File

@@ -22,7 +22,7 @@
</template>
<script>
import Modal from '../../Modal';
import Modal from '../../Modal.vue';
export default {
components: {

View File

@@ -95,7 +95,7 @@
<script>
import { mixin as clickaway } from 'vue-clickaway';
import { SHORTCUT_KEYS } from './constants';
import Hotkey from 'dashboard/components/base/Hotkey';
import Hotkey from 'dashboard/components/base/Hotkey.vue';
export default {
components: {

View File

@@ -1,3 +1,9 @@
import {
messageSchema,
MessageMarkdownTransformer,
MessageMarkdownSerializer,
} from '@chatwoot/prosemirror-schema';
/**
* The delimiter used to separate the signature from the rest of the body.
* @type {string}
@@ -5,12 +11,12 @@
export const SIGNATURE_DELIMITER = '--';
/**
* Trim the signature and remove all " \r" from the signature
* 1. Trim any extra lines or spaces at the start or end of the string
* 2. Converts all \r or \r\n to \f
* Parse and Serialize the markdown text to remove any extra spaces or new lines
*/
export function cleanSignature(signature) {
return signature.trim().replace(/\r\n?/g, '\n');
// convert from markdown to common mark format
const nodes = new MessageMarkdownTransformer(messageSchema).parse(signature);
return MessageMarkdownSerializer.serialize(nodes);
}
/**

View File

@@ -1,21 +1,34 @@
const setArrayValues = item => {
return item.values[0]?.id ? item.values.map(val => val.id) : item.values;
};
const generateValues = item => {
if (item.attribute_key === 'content') {
const values = item.values || '';
return values.split(',');
}
if (Array.isArray(item.values)) {
return setArrayValues(item);
}
if (typeof item.values === 'object') {
return [item.values.id];
}
if (!item.values) {
return [];
}
return [item.values];
};
const generatePayload = data => {
// Make a copy of data to avoid vue data reactivity issues
const filters = JSON.parse(JSON.stringify(data));
let payload = filters.map(item => {
if (Array.isArray(item.values)) {
item.values = setArrayValues(item);
} else if (typeof item.values === 'object') {
item.values = [item.values.id];
} else if (!item.values) {
item.values = [];
} else {
item.values = [item.values];
}
// If item key is content, we will split it using comma and return as array
// FIX ME: Make this generic option instead of using the key directly here
item.values = generateValues(item);
return item;
});
// For every query added, the query_operator is set default to and so the
// last query will have an extra query_operator, this would break the api.
// Setting this to null for all query payload

View File

@@ -3,6 +3,7 @@ import {
appendSignature,
removeSignature,
replaceSignature,
cleanSignature,
extractTextFromMarkdown,
} from '../editorHelper';
@@ -17,10 +18,18 @@ const DOES_NOT_HAVE_SIGNATURE = {
body: 'This is a test\n\n--\n\nThis is a signature\n\nThis is more text',
signature: 'This is a signature',
},
signature_has_images: {
'signature has images': {
body: 'This is a test',
signature:
'Testing \n![](http://localhost:3000/rails/active_storage/blobs/redirect/some-hash/image.png)',
'Testing\n![](http://localhost:3000/rails/active_storage/blobs/redirect/some-hash/image.png)',
},
'signature has non commonmark syntax': {
body: 'This is a test',
signature: '- Signature',
},
'signature has trailing spaces': {
body: 'This is a test',
signature: '**hello** \n**world**',
},
};
@@ -37,6 +46,10 @@ const HAS_SIGNATURE = {
body: '\n\n--\n\nThis is a signature',
signature: 'This is a signature',
},
'signature has non-commonmark syntax': {
body: '\n\n--\n\n* Signature',
signature: '- Signature',
},
};
describe('findSignatureInBody', () => {
@@ -58,9 +71,10 @@ describe('appendSignature', () => {
it('appends the signature if it is not present', () => {
Object.keys(DOES_NOT_HAVE_SIGNATURE).forEach(key => {
const { body, signature } = DOES_NOT_HAVE_SIGNATURE[key];
expect(appendSignature(body, signature)).toBe(
`${body}\n\n--\n\n${signature}`
);
const cleanedSignature = cleanSignature(signature);
expect(
appendSignature(body, signature).includes(cleanedSignature)
).toBeTruthy();
});
});
it('does not append signature if already present', () => {

View File

@@ -25,10 +25,10 @@ describe('#Upload Helpers', () => {
axios.post.mockResolvedValueOnce(mockResponse);
const result = await uploadFile(mockFile);
const result = await uploadFile(mockFile, '1602');
expect(axios.post).toHaveBeenCalledWith(
'/api/v1/upload',
'/api/v1/accounts/1602/upload',
expect.any(FormData),
{ headers: { 'Content-Type': 'multipart/form-data' } }
);

View File

@@ -21,17 +21,25 @@ const HEADERS = {
* @param {File} file - The file to be uploaded. It should be a File object (typically coming from a file input element).
* @returns {Promise} A promise that resolves with the server's response when the upload is successful, or rejects if there's an error.
*/
export async function uploadFile(file) {
export async function uploadFile(file, accountId) {
// Create a new FormData instance.
let formData = new FormData();
if (!accountId) {
accountId = window.location.pathname.split('/')[3];
}
// Append the file to the FormData instance under the key 'attachment'.
formData.append('attachment', file);
// Use axios to send a POST request to the upload endpoint.
const { data } = await axios.post(`/api/${API_VERSION}/upload`, formData, {
headers: HEADERS,
});
const { data } = await axios.post(
`/api/${API_VERSION}/accounts/${accountId}/upload`,
formData,
{
headers: HEADERS,
}
);
return {
fileUrl: data.file_url,

View File

@@ -371,6 +371,8 @@
"DETAILS": {
"LOADING_FB": "Authenticating you with Facebook...",
"ERROR_FB_AUTH": "Something went wrong, Please refresh page...",
"ERROR_FB_UNAUTHORIZED": "You're not authorized to perform this action. ",
"ERROR_FB_UNAUTHORIZED_HELP": "Please ensure you have access to the Facebook page with full control. You can read more about Facebook roles <a href=\" https://www.facebook.com/help/187316341316631\">here</a>.",
"CREATING_CHANNEL": "Creating your Inbox...",
"TITLE": "Configure Inbox Details",
"DESC": ""

View File

@@ -36,7 +36,7 @@
},
"MESSAGE_SIGNATURE_SECTION": {
"TITLE": "Personal message signature",
"NOTE": "Create a personal message signature that would be added to all the messages you send from your email inbox. Use the rich content editor to create a highly personalised signature.",
"NOTE": "Create a unique message signature to appear at the end of every message you send from any inbox. You can also include an inline image, which is supported in live-chat, email, and API inboxes.",
"BTN_TEXT": "Save message signature",
"API_ERROR": "Couldn't save signature! Try again",
"API_SUCCESS": "Signature saved successfully",

View File

@@ -110,7 +110,7 @@
"SNOOZE_CONVERSATION": "Adiar Conversa",
"ADD_LABEL": "Adicionar etiqueta à conversa",
"REMOVE_LABEL": "Remover etiqueta da conversa",
"SETTINGS": "Confirgurações",
"SETTINGS": "Configurações",
"AI_ASSIST": "Assistente IA",
"APPEARANCE": "Aspeto"
},

View File

@@ -40,8 +40,8 @@
"BTN_TEXT": "Salvar assinatura da mensagem",
"API_ERROR": "Não foi possível salvar a assinatura! Tente novamente",
"API_SUCCESS": "Assinatura salva com sucesso",
"IMAGE_UPLOAD_ERROR": "Couldn't upload image! Try again",
"IMAGE_UPLOAD_SUCCESS": "Image added successfully. Please click on save to save the signature",
"IMAGE_UPLOAD_ERROR": "Não foi possível carregar a imagem! Tente novamente",
"IMAGE_UPLOAD_SUCCESS": "Imagem adicionada. Clique em salvar para salvar a assinatura",
"IMAGE_UPLOAD_SIZE_ERROR": "O tamanho da imagem deve ser inferior a {size}MB"
},
"MESSAGE_SIGNATURE": {

View File

@@ -199,6 +199,12 @@ export default {
values: condition.values[0],
};
}
if (inputType === 'comma_separated_plain_text') {
return {
...condition,
values: condition.values.join(','),
};
}
return {
...condition,
query_operator: condition.query_operator || 'and',

View File

@@ -19,7 +19,7 @@
<script>
import alertMixin from 'shared/mixins/alertMixin';
import MergeContact from 'dashboard/modules/contact/components/MergeContact';
import MergeContact from 'dashboard/modules/contact/components/MergeContact.vue';
import ContactAPI from 'dashboard/api/contacts';

View File

@@ -36,7 +36,7 @@
</template>
<script>
import Modal from 'dashboard/components/Modal';
import Modal from 'dashboard/components/Modal.vue';
import alertMixin from 'shared/mixins/alertMixin';
import { required, minLength } from 'vuelidate/lib/validators';

View File

@@ -45,7 +45,7 @@
</template>
<script>
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
export default {
components: {

View File

@@ -24,7 +24,7 @@
</template>
<script>
import Thumbnail from '../../../components/widgets/Thumbnail';
import Thumbnail from '../../../components/widgets/Thumbnail.vue';
export default {
components: {

View File

@@ -52,7 +52,7 @@
</div>
</template>
<script>
import Attribute from './ContactAttribute';
import Attribute from './ContactAttribute.vue';
export default {
components: { Attribute },

View File

@@ -42,8 +42,8 @@
</div>
</template>
<script>
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import SocialIcons from 'dashboard/routes/dashboard/conversation/contact/SocialIcons';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import SocialIcons from 'dashboard/routes/dashboard/conversation/contact/SocialIcons.vue';
export default {
components: {

View File

@@ -30,11 +30,11 @@
</div>
</template>
<script>
import EditContact from 'dashboard/routes/dashboard/conversation/contact/EditContact';
import NewConversation from 'dashboard/routes/dashboard/conversation/contact/NewConversation';
import AddCustomAttribute from 'dashboard/modules/contact/components/AddCustomAttribute';
import ContactIntro from './ContactIntro';
import ContactFields from './ContactFields';
import EditContact from 'dashboard/routes/dashboard/conversation/contact/EditContact.vue';
import NewConversation from 'dashboard/routes/dashboard/conversation/contact/NewConversation.vue';
import AddCustomAttribute from 'dashboard/modules/contact/components/AddCustomAttribute.vue';
import ContactIntro from './ContactIntro.vue';
import ContactFields from './ContactFields.vue';
export default {
components: {

View File

@@ -110,8 +110,8 @@
import alertMixin from 'shared/mixins/alertMixin';
import { required } from 'vuelidate/lib/validators';
import MergeContactSummary from 'dashboard/modules/contact/components/MergeContactSummary';
import ContactDropdownItem from './ContactDropdownItem';
import MergeContactSummary from 'dashboard/modules/contact/components/MergeContactSummary.vue';
import ContactDropdownItem from './ContactDropdownItem.vue';
export default {
components: { MergeContactSummary, ContactDropdownItem },

View File

@@ -101,11 +101,11 @@ import alertMixin from 'shared/mixins/alertMixin';
import { mapGetters } from 'vuex';
import { mixin as clickaway } from 'vue-clickaway';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned';
import AddCannedModal from 'dashboard/routes/dashboard/settings/canned/AddCanned.vue';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
import { conversationUrl, frontendURL } from '../../../helper/URLHelper';
import { ACCOUNT_EVENTS } from '../../../helper/AnalyticsHelper/events';
import TranslateModal from 'dashboard/components/widgets/conversation/bubble/TranslateModal';
import TranslateModal from 'dashboard/components/widgets/conversation/bubble/TranslateModal.vue';
import MenuItem from '../../../components/widgets/conversation/contextMenu/menuItem.vue';
export default {

View File

@@ -9,7 +9,7 @@
<script>
import { mapGetters } from 'vuex';
import NoteList from './components/NoteList';
import NoteList from './components/NoteList.vue';
export default {
components: {

View File

@@ -22,7 +22,7 @@
</template>
<script>
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
import { hasPressedCommandAndEnter } from 'shared/helpers/KeyboardHelpers';
export default {
components: {

View File

@@ -51,7 +51,7 @@
</template>
<script>
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import timeMixin from 'dashboard/mixins/time';
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';

View File

@@ -23,9 +23,9 @@
</template>
<script>
import AddNote from './AddNote';
import ContactNote from './ContactNote';
import Spinner from 'shared/components/Spinner';
import AddNote from './AddNote.vue';
import ContactNote from './ContactNote.vue';
import Spinner from 'shared/components/Spinner.vue';
export default {
components: {

View File

@@ -30,7 +30,7 @@
import { mapGetters } from 'vuex';
import SearchResultConversationItem from './SearchResultConversationItem.vue';
import SearchResultSection from './SearchResultSection.vue';
import MessageContent from './MessageContent';
import MessageContent from './MessageContent.vue';
export default {
components: {

View File

@@ -48,10 +48,10 @@
</template>
<script>
import WidgetHead from './WidgetHead';
import WidgetBody from './WidgetBody';
import WidgetFooter from './WidgetFooter';
import InputRadioGroup from 'dashboard/routes/dashboard/settings/inbox/components/InputRadioGroup';
import WidgetHead from './WidgetHead.vue';
import WidgetBody from './WidgetBody.vue';
import WidgetFooter from './WidgetFooter.vue';
import InputRadioGroup from 'dashboard/routes/dashboard/settings/inbox/components/InputRadioGroup.vue';
import globalConfigMixin from 'shared/mixins/globalConfigMixin';
import { mapGetters } from 'vuex';

View File

@@ -47,7 +47,7 @@
</template>
<script>
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
export default {
name: 'WidgetBody',
components: {

View File

@@ -26,8 +26,8 @@
</template>
<script>
import CustomButton from 'dashboard/components/buttons/Button';
import ResizableTextArea from 'shared/components/ResizableTextArea';
import CustomButton from 'dashboard/components/buttons/Button.vue';
import ResizableTextArea from 'shared/components/ResizableTextArea.vue';
export default {
name: 'WidgetFooter',
components: {

View File

@@ -40,14 +40,14 @@
</template>
<script>
import Sidebar from '../../components/layout/Sidebar';
import Sidebar from '../../components/layout/Sidebar.vue';
import CommandBar from './commands/commandbar.vue';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import WootKeyShortcutModal from 'dashboard/components/widgets/modal/WootKeyShortcutModal';
import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAccountModal';
import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector';
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel';
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel';
import WootKeyShortcutModal from 'dashboard/components/widgets/modal/WootKeyShortcutModal.vue';
import AddAccountModal from 'dashboard/components/layout/sidebarComponents/AddAccountModal.vue';
import AccountSelector from 'dashboard/components/layout/sidebarComponents/AccountSelector.vue';
import AddLabelModal from 'dashboard/routes/dashboard/settings/labels/AddLabel.vue';
import NotificationPanel from 'dashboard/routes/dashboard/notifications/components/NotificationPanel.vue';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
import wootConstants from 'dashboard/constants/globals';

View File

@@ -80,9 +80,9 @@
</template>
<script>
import AccordionItem from 'dashboard/components/Accordion/AccordionItem';
import ContactConversations from 'dashboard/routes/dashboard/conversation/ContactConversations';
import ContactInfo from 'dashboard/routes/dashboard/conversation/contact/ContactInfo';
import AccordionItem from 'dashboard/components/Accordion/AccordionItem.vue';
import ContactConversations from 'dashboard/routes/dashboard/conversation/ContactConversations.vue';
import ContactInfo from 'dashboard/routes/dashboard/conversation/contact/ContactInfo.vue';
import ContactLabel from 'dashboard/routes/dashboard/contacts/components/ContactLabels.vue';
import CustomAttributes from 'dashboard/routes/dashboard/conversation/customAttributes/CustomAttributes.vue';
import CustomAttributeSelector from 'dashboard/routes/dashboard/conversation/customAttributes/CustomAttributeSelector.vue';

View File

@@ -37,7 +37,7 @@ import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import EmptyState from 'dashboard/components/widgets/EmptyState.vue';
import timeMixin from 'dashboard/mixins/time';
import rtlMixin from 'shared/mixins/rtlMixin';
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon';
import FluentIcon from 'shared/components/FluentIcon/DashboardIcon.vue';
export default {
components: {

View File

@@ -81,17 +81,17 @@
<script>
import { mapGetters } from 'vuex';
import ContactsHeader from './Header';
import ContactsTable from './ContactsTable';
import ContactInfoPanel from './ContactInfoPanel';
import CreateContact from 'dashboard/routes/dashboard/conversation/contact/CreateContact';
import TableFooter from 'dashboard/components/widgets/TableFooter';
import ContactsHeader from './Header.vue';
import ContactsTable from './ContactsTable.vue';
import ContactInfoPanel from './ContactInfoPanel.vue';
import CreateContact from 'dashboard/routes/dashboard/conversation/contact/CreateContact.vue';
import TableFooter from 'dashboard/components/widgets/TableFooter.vue';
import ImportContacts from './ImportContacts.vue';
import ContactsAdvancedFilters from './ContactsAdvancedFilters.vue';
import contactFilterItems from '../contactFilterItems';
import filterQueryGenerator from '../../../../helper/filterQueryGenerator';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews';
import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews';
import AddCustomViews from 'dashboard/routes/dashboard/customviews/AddCustomViews.vue';
import DeleteCustomViews from 'dashboard/routes/dashboard/customviews/DeleteCustomViews.vue';
import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';
import alertMixin from 'shared/mixins/alertMixin';
import countries from 'shared/constants/countries.js';

View File

@@ -42,7 +42,7 @@
</template>
<script>
import Modal from '../../../../components/Modal';
import Modal from '../../../../components/Modal.vue';
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import { CONTACTS_EVENTS } from '../../../../helper/AnalyticsHelper/events';

View File

@@ -56,10 +56,10 @@
<script>
import { mapGetters } from 'vuex';
import ContactInfoPanel from '../components/ContactInfoPanel.vue';
import ContactNotes from 'dashboard/modules/notes/NotesOnContactPage';
import ContactNotes from 'dashboard/modules/notes/NotesOnContactPage.vue';
import SettingsHeader from '../../settings/SettingsHeader.vue';
import Spinner from 'shared/components/Spinner';
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import Spinner from 'shared/components/Spinner.vue';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
export default {
components: {

View File

@@ -22,9 +22,9 @@
</template>
<script>
import ConversationCard from 'dashboard/components/widgets/conversation/ConversationCard';
import ConversationCard from 'dashboard/components/widgets/conversation/ConversationCard.vue';
import { mapGetters } from 'vuex';
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
export default {
components: {

View File

@@ -134,18 +134,18 @@
<script>
import { mapGetters } from 'vuex';
import alertMixin from 'shared/mixins/alertMixin';
import AccordionItem from 'dashboard/components/Accordion/AccordionItem';
import AccordionItem from 'dashboard/components/Accordion/AccordionItem.vue';
import ContactConversations from './ContactConversations.vue';
import ConversationAction from './ConversationAction.vue';
import ConversationParticipant from './ConversationParticipant.vue';
import ContactInfo from './contact/ContactInfo';
import ConversationInfo from './ConversationInfo';
import ContactInfo from './contact/ContactInfo.vue';
import ConversationInfo from './ConversationInfo.vue';
import CustomAttributes from './customAttributes/CustomAttributes.vue';
import CustomAttributeSelector from './customAttributes/CustomAttributeSelector.vue';
import draggable from 'vuedraggable';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
import MacrosList from './Macros/List';
import MacrosList from './Macros/List.vue';
export default {
components: {

View File

@@ -79,12 +79,12 @@
<script>
import { mixin as clickaway } from 'vue-clickaway';
import Spinner from 'shared/components/Spinner';
import Spinner from 'shared/components/Spinner.vue';
import alertMixin from 'shared/mixins/alertMixin';
import { mapGetters } from 'vuex';
import agentMixin from 'dashboard/mixins/agentMixin';
import ThumbnailGroup from 'dashboard/components/widgets/ThumbnailGroup';
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems';
import ThumbnailGroup from 'dashboard/components/widgets/ThumbnailGroup.vue';
import MultiselectDropdownItems from 'shared/components/ui/MultiselectDropdownItems.vue';
export default {
components: {

View File

@@ -27,9 +27,9 @@
<script>
import { mapGetters } from 'vuex';
import ChatList from '../../../components/ChatList';
import ConversationBox from '../../../components/widgets/conversation/ConversationBox';
import PopOverSearch from './search/PopOverSearch';
import ChatList from '../../../components/ChatList.vue';
import ConversationBox from '../../../components/widgets/conversation/ConversationBox.vue';
import PopOverSearch from './search/PopOverSearch.vue';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
import { BUS_EVENTS } from 'shared/constants/busEvents';
import wootConstants from 'dashboard/constants/globals';

View File

@@ -34,7 +34,7 @@
</template>
<script>
import { mapGetters } from 'vuex';
import MacroItem from './MacroItem';
import MacroItem from './MacroItem.vue';
import accountMixin from 'dashboard/mixins/account.js';
export default {

View File

@@ -36,7 +36,7 @@
<script>
import alertMixin from 'shared/mixins/alertMixin';
import { mixin as clickaway } from 'vue-clickaway';
import MacroPreview from './MacroPreview';
import MacroPreview from './MacroPreview.vue';
import { CONVERSATION_EVENTS } from '../../../../helper/AnalyticsHelper/events';
export default {

View File

@@ -166,13 +166,13 @@
<script>
import { mixin as clickaway } from 'vue-clickaway';
import timeMixin from 'dashboard/mixins/time';
import ContactInfoRow from './ContactInfoRow';
import ContactInfoRow from './ContactInfoRow.vue';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import SocialIcons from './SocialIcons';
import SocialIcons from './SocialIcons.vue';
import EditContact from './EditContact';
import NewConversation from './NewConversation';
import ContactMergeModal from 'dashboard/modules/contact/ContactMergeModal';
import EditContact from './EditContact.vue';
import NewConversation from './NewConversation.vue';
import ContactMergeModal from 'dashboard/modules/contact/ContactMergeModal.vue';
import alertMixin from 'shared/mixins/alertMixin';
import adminMixin from '../../../../mixins/isAdmin';
import { mapGetters } from 'vuex';

View File

@@ -58,7 +58,7 @@
</template>
<script>
import alertMixin from 'shared/mixins/alertMixin';
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
import { copyTextToClipboard } from 'shared/helpers/clipboard';
export default {

View File

@@ -158,11 +158,11 @@
<script>
import { mapGetters } from 'vuex';
import Thumbnail from 'dashboard/components/widgets/Thumbnail';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
import ReplyEmailHead from 'dashboard/components/widgets/conversation/ReplyEmailHead';
import Thumbnail from 'dashboard/components/widgets/Thumbnail.vue';
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor.vue';
import ReplyEmailHead from 'dashboard/components/widgets/conversation/ReplyEmailHead.vue';
import CannedResponse from 'dashboard/components/widgets/conversation/CannedResponse.vue';
import InboxDropdownItem from 'dashboard/components/widgets/InboxDropdownItem';
import InboxDropdownItem from 'dashboard/components/widgets/InboxDropdownItem.vue';
import WhatsappTemplates from './WhatsappTemplates.vue';
import alertMixin from 'shared/mixins/alertMixin';
import { INBOX_TYPES } from 'shared/mixins/inboxMixin';
@@ -393,8 +393,6 @@ export default {
.mention--box {
@apply left-0 m-auto right-0 top-auto h-fit;
}
/* TODO: Remove when have standardized a component out of multiselect */
.multiselect .multiselect__content .multiselect__option span {
@apply inline-flex w-6 text-slate-600 dark:text-slate-400;
}

View File

@@ -17,7 +17,7 @@
<script>
import { mapGetters } from 'vuex';
import ContactForm from './ContactForm';
import ContactForm from './ContactForm.vue';
export default {
components: {

View File

@@ -20,7 +20,7 @@
<script>
import { mapGetters } from 'vuex';
import ContactForm from './ContactForm';
import ContactForm from './ContactForm.vue';
export default {
components: {

View File

@@ -16,7 +16,7 @@
</template>
<script>
import ConversationForm from './ConversationForm';
import ConversationForm from './ConversationForm.vue';
export default {
components: {

View File

@@ -44,9 +44,9 @@
<script>
import { mapGetters } from 'vuex';
import Spinner from 'shared/components/Spinner';
import LabelDropdown from 'shared/components/ui/label/LabelDropdown';
import AddLabel from 'shared/components/ui/dropdown/AddLabel';
import Spinner from 'shared/components/Spinner.vue';
import LabelDropdown from 'shared/components/ui/label/LabelDropdown.vue';
import AddLabel from 'shared/components/ui/dropdown/AddLabel.vue';
import { mixin as clickaway } from 'vue-clickaway';
import adminMixin from 'dashboard/mixins/isAdmin';
import eventListenerMixins from 'shared/mixins/eventListenerMixins';

Some files were not shown because too many files have changed in this diff Show More