Merge branch 'release/3.1.1'
This commit is contained in:
1
Gemfile
1
Gemfile
@@ -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/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.17.0
|
||||
3.1.0
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.3.0
|
||||
2.4.0
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WootSnackbar from './Snackbar';
|
||||
import WootSnackbar from './Snackbar.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Spinner from 'shared/components/Spinner';
|
||||
import Spinner from 'shared/components/Spinner.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import Thumbnail from '../../widgets/Thumbnail';
|
||||
import Thumbnail from '../../widgets/Thumbnail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -97,7 +97,7 @@ import {
|
||||
getInboxWarningIconClass,
|
||||
} from 'dashboard/helper/inbox';
|
||||
|
||||
import SecondaryChildNavItem from './SecondaryChildNavItem';
|
||||
import SecondaryChildNavItem from './SecondaryChildNavItem.vue';
|
||||
import {
|
||||
isOnMentionsView,
|
||||
isOnUnattendedView,
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import ChannelSelector from '../ChannelSelector';
|
||||
import ChannelSelector from '../ChannelSelector.vue';
|
||||
export default {
|
||||
components: { ChannelSelector },
|
||||
props: {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Thumbnail from './Thumbnail';
|
||||
import Thumbnail from './Thumbnail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Hotkey from 'dashboard/components/base/Hotkey';
|
||||
import Hotkey from 'dashboard/components/base/Hotkey.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Spinner from 'shared/components/Spinner';
|
||||
import Spinner from 'shared/components/Spinner.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<script>
|
||||
import { required } from 'vuelidate/lib/validators';
|
||||
import Modal from '../../Modal';
|
||||
import Modal from '../../Modal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</modal>
|
||||
</template>
|
||||
<script>
|
||||
import Modal from '../../Modal';
|
||||
import Modal from '../../Modal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Modal from '../../Modal';
|
||||
import Modal from '../../Modal.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
'Testing\n',
|
||||
},
|
||||
'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', () => {
|
||||
|
||||
@@ -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' } }
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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": ""
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon';
|
||||
import EmojiOrIcon from 'shared/components/EmojiOrIcon.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Thumbnail from '../../../components/widgets/Thumbnail';
|
||||
import Thumbnail from '../../../components/widgets/Thumbnail.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Attribute from './ContactAttribute';
|
||||
import Attribute from './ContactAttribute.vue';
|
||||
|
||||
export default {
|
||||
components: { Attribute },
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import NoteList from './components/NoteList';
|
||||
import NoteList from './components/NoteList.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import ContactForm from './ContactForm';
|
||||
import ContactForm from './ContactForm.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import ContactForm from './ContactForm';
|
||||
import ContactForm from './ContactForm.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ConversationForm from './ConversationForm';
|
||||
import ConversationForm from './ConversationForm.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user