Fix eslint warnings, update eslint config

This commit is contained in:
Pranav Raj Sreepuram 2019-08-25 11:04:33 +05:30
parent aa8a43344b
commit f18f01a047
8 changed files with 227 additions and 132 deletions

View file

@ -1,37 +1,47 @@
module.exports = { module.exports = {
"extends": ["airbnb/base", "prettier"], extends: ['airbnb/base', 'prettier', 'plugin:vue/recommended'],
"plugins": [ parserOptions: {
"prettier", "babel", "html" parser: 'babel-eslint',
], ecmaVersion: 2017,
"rules": { sourceType: 'module',
"prettier/prettier": ["error"],
"camelcase": "off",
"import/no-extraneous-dependencies": "off",
"import/prefer-default-export": "off",
"import/no-named-as-default": "off",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/label-has-for": "off",
"jsx-a11y/anchor-is-valid": "off",
'import/no-unresolved': "off",
}, },
"settings": { plugins: ['html', 'prettier', 'babel'],
"import/resolver": { rules: {
"webpack": { 'prettier/prettier': ['error'],
"config": "config/webpack/resolve.js" camelcase: 'off',
} 'import/no-extraneous-dependencies': 'off',
'import/prefer-default-export': 'off',
'import/no-named-as-default': 'off',
'jsx-a11y/no-static-element-interactions': 'off',
'jsx-a11y/click-events-have-key-events': 'off',
'jsx-a11y/label-has-associated-control': 'off',
'jsx-a11y/label-has-for': 'off',
'jsx-a11y/anchor-is-valid': 'off',
'import/no-unresolved': 'off',
'vue/max-attributes-per-line': ['error', {
'singleline': 3,
'multiline': {
'max': 1,
'allowFirstLine': false
} }
}],
'vue/html-self-closing': false
}, },
"env": { settings: {
"browser": true, 'import/resolver': {
"node": true, webpack: {
"jest": true config: 'config/webpack/resolve.js',
}, },
"parser": "babel-eslint", },
"globals": { },
"__WEBPACK_ENV__": true, env: {
"__PUSHER__": true, browser: true,
"__FB_APP_ID__": true node: true,
} jest: true,
} },
globals: {
__WEBPACK_ENV__: true,
__PUSHER__: true,
__FB_APP_ID__: true,
},
};

View file

@ -53,8 +53,8 @@ window.onload = () => {
window.WOOT = new Vue({ window.WOOT = new Vue({
router, router,
store, store,
template: '<App/>',
components: { App }, components: { App },
template: '<App/>',
}).$mount('#app'); }).$mount('#app');
}; };
window.pusher = vuePusher.init(); window.pusher = vuePusher.init();

View file

@ -1,18 +1,32 @@
<template> <template>
<router-link :to="menuItem.toState" tag="li" active-class="active" :class="computedClass">
<a :class="getMenuItemClass" data-tooltip aria-haspopup="true" :title="menuItem.toolTip" >
<i :class="menuItem.icon"></i>
{{menuItem.label}}
<span class="ion-ios-plus-outline" v-if="showItem(menuItem)" @click.prevent="newLinkClick">
</span>
</a>
<ul class="nested vertical menu" v-if="menuItem.hasSubMenu">
<router-link <router-link
:to="child.toState" :to="menuItem.toState"
tag="li" tag="li"
active-class="active flex-container" active-class="active"
:class="computedClass"
>
<a
:class="getMenuItemClass"
data-tooltip
aria-haspopup="true"
:title="menuItem.toolTip"
>
<i :class="menuItem.icon" />
{{ menuItem.label }}
<span
v-if="showItem(menuItem)"
class="ion-ios-plus-outline"
@click.prevent="newLinkClick"
/>
</a>
<ul v-if="menuItem.hasSubMenu" class="nested vertical menu">
<router-link
v-for="child in menuItem.children" v-for="child in menuItem.children"
:key="child.label"
active-class="active flex-container"
:class="computedInboxClass(child)" :class="computedInboxClass(child)"
tag="li"
:to="child.toState"
> >
<a>{{ child.label }}</a> <a>{{ child.label }}</a>
</router-link> </router-link>
@ -28,20 +42,32 @@ import router from '../../routes';
import auth from '../../api/auth'; import auth from '../../api/auth';
export default { export default {
props: ['menuItem'], props: {
menuItem: {
type: Object,
default() {
return {};
},
},
},
computed: { computed: {
...mapGetters({ ...mapGetters({
activeInbox: 'getSelectedInbox', activeInbox: 'getSelectedInbox',
}), }),
getMenuItemClass() { getMenuItemClass() {
return this.menuItem.cssClass ? `side-menu ${this.menuItem.cssClass}` : 'side-menu'; return this.menuItem.cssClass
? `side-menu ${this.menuItem.cssClass}`
: 'side-menu';
}, },
computedClass() { computedClass() {
// If active Inbox is present // If active Inbox is present
// donot highlight conversations // donot highlight conversations
if (this.activeInbox) return ' '; if (this.activeInbox) return ' ';
if (this.$store.state.route.name === 'inbox_conversation' && this.menuItem.toStateName === 'home') { if (
this.$store.state.route.name === 'inbox_conversation' &&
this.menuItem.toStateName === 'home'
) {
return 'active'; return 'active';
} }
return ' '; return ' ';

View file

@ -1,27 +1,40 @@
<template> <template>
<woot-tabs :index="tabsIndex" <woot-tabs :index="tabsIndex" @change="onTabChange">
@change="onTabChange"> <woot-tabs-item
<woot-tabs-item :name="item.name" :count="item.count" v-for="item in items"></woot-tabs-item> v-for="item in items"
:key="item.name"
:name="item.name"
:count="item.count"
/>
</woot-tabs> </woot-tabs>
</template> </template>
<script> <script>
/* eslint no-console: 0 */ /* eslint no-console: 0 */
export default { export default {
props: ['items', 'activeTabIndex'], props: {
items: {
type: Array,
default: () => [],
},
activeTabIndex: {
type: Number,
default: 0,
},
},
data() { data() {
return { return {
tabsIndex: 0, tabsIndex: 0,
}; };
}, },
methods: {
onTabChange(...args) {
this.$emit('chatTabChange', args[0]);
this.tabsIndex = args[0];
},
},
created() { created() {
this.tabsIndex = this.activeTabIndex; this.tabsIndex = this.activeTabIndex;
}, },
methods: {
onTabChange(selectedTabIndex) {
this.$emit('chatTabChange', selectedTabIndex);
this.tabsIndex = selectedTabIndex;
},
},
}; };
</script> </script>

View file

@ -1,31 +1,51 @@
<template> <template>
<div class="medium-8 columns conversation-wrap"> <div class="medium-8 columns conversation-wrap">
<div class="view-box columns" v-if="currentChat.id !== null"> <div v-if="currentChat.id !== null" class="view-box columns">
<conversation-header :chat="currentChat" /> <conversation-header :chat="currentChat" />
<ul class="conversation-panel"> <ul class="conversation-panel">
<transition name="slide-up"> <transition name="slide-up">
<li><span class="spinner message" v-if="shouldShowSpinner"></span></li> <li>
</transition> <span v-if="shouldShowSpinner" class="spinner message" />
<conversation v-for="message in getReadMessages" :data="message"></conversation>
<li class="unread--toast" v-show="getUnreadCount != 0">
<span>{{getUnreadCount}} UNREAD MESSAGE{{ getUnreadCount > 1 ? 'S' : '' }}</span>
</li> </li>
<conversation v-for="message in getUnReadMessages" :data="message"></conversation> </transition>
<conversation
v-for="message in getReadMessages"
:key="message.id"
:data="message"
/>
<li v-show="getUnreadCount != 0" class="unread--toast">
<span>
{{ getUnreadCount }} UNREAD MESSAGE{{
getUnreadCount > 1 ? 'S' : ''
}}
</span>
</li>
<conversation
v-for="message in getUnReadMessages"
:key="message.id"
:data="message"
/>
</ul> </ul>
<ReplyBox v-on:scrollToMessage='focusLastMessage' :conversationId="currentChat.id" /> <ReplyBox
:conversation-id="currentChat.id"
@scrollToMessage="focusLastMessage"
/>
</div> </div>
<!-- No Conversation Selected --> <!-- No Conversation Selected -->
<div class="columns full-height conv-empty-state"> <div class="columns full-height conv-empty-state">
<!-- Loading status --> <!-- Loading status -->
<woot-loading-state :message="loadingIndicatorMessage" v-if="fetchingInboxes || loadingChatList" /> <woot-loading-state
v-if="fetchingInboxes || loadingChatList"
:message="loadingIndicatorMessage"
/>
<!-- Show empty state images if not loading --> <!-- Show empty state images if not loading -->
<div class="current-chat" v-if="!fetchingInboxes && !loadingChatList"> <div v-if="!fetchingInboxes && !loadingChatList" class="current-chat">
<!-- No inboxes attached --> <!-- No inboxes attached -->
<div v-if="!inboxesList.length"> <div v-if="!inboxesList.length">
<img src="~assets/images/inboxes.svg" alt="No Inboxes" /> <img src="~assets/images/inboxes.svg" alt="No Inboxes" />
<span v-if="isAdmin()"> <span v-if="isAdmin()">
{{ $t('CONVERSATION.NO_INBOX_1') }} {{ $t('CONVERSATION.NO_INBOX_1') }}
<br> <br />
<router-link to="/u/settings/inboxes/new"> <router-link to="/u/settings/inboxes/new">
{{ $t('CONVERSATION.CLICK_HERE') }} {{ $t('CONVERSATION.CLICK_HERE') }}
</router-link> </router-link>
@ -40,7 +60,7 @@
<img src="~assets/images/chat.svg" alt="No Chat" /> <img src="~assets/images/chat.svg" alt="No Chat" />
<span> <span>
{{ $t('CONVERSATION.NO_MESSAGE_1') }} {{ $t('CONVERSATION.NO_MESSAGE_1') }}
<br> <br />
<a :href="linkToMessage" target="_blank"> <a :href="linkToMessage" target="_blank">
{{ $t('CONVERSATION.CLICK_HERE') }} {{ $t('CONVERSATION.CLICK_HERE') }}
</a> </a>
@ -54,18 +74,15 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
/* eslint no-console: 0 */ /* eslint no-console: 0 */
/* eslint no-extra-boolean-cast: 0 */ /* eslint no-extra-boolean-cast: 0 */
/* global bus */ /* global bus */
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import Thumbnail from '../Thumbnail';
import ConversationHeader from './ConversationHeader'; import ConversationHeader from './ConversationHeader';
import ReplyBox from './ReplyBox'; import ReplyBox from './ReplyBox';
import Conversation from './Conversation'; import Conversation from './Conversation';
@ -73,8 +90,21 @@ import conversationMixin from '../../../mixins/conversations';
import adminMixin from '../../../mixins/isAdmin'; import adminMixin from '../../../mixins/isAdmin';
export default { export default {
props: ['user', 'inboxId'], components: {
ConversationHeader,
Conversation,
ReplyBox,
},
mixins: [conversationMixin, adminMixin], mixins: [conversationMixin, adminMixin],
props: {
inboxId: {
type: String,
required: true,
},
},
data() { data() {
return { return {
isLoadingPrevious: true, isLoadingPrevious: true,
@ -83,13 +113,6 @@ export default {
}; };
}, },
created() {
bus.$on('scrollToMessage', () => {
this.focusLastMessage();
this.makeMessagesRead();
});
},
computed: { computed: {
...mapGetters({ ...mapGetters({
currentChat: 'getSelectedChat', currentChat: 'getSelectedChat',
@ -109,7 +132,9 @@ export default {
return this.$t('CONVERSATION.LOADING_CONVERSATIONS'); return this.$t('CONVERSATION.LOADING_CONVERSATIONS');
}, },
getMessages() { getMessages() {
const [chat] = this.allConversations.filter(c => c.id === this.currentChat.id); const [chat] = this.allConversations.filter(
c => c.id === this.currentChat.id
);
return chat; return chat;
}, },
// Get current FB Page ID // Get current FB Page ID
@ -117,7 +142,9 @@ export default {
let stateInbox; let stateInbox;
if (this.inboxId) { if (this.inboxId) {
const inboxId = Number(this.inboxId); const inboxId = Number(this.inboxId);
[stateInbox] = this.inboxesList.filter(inbox => inbox.channel_id === inboxId); [stateInbox] = this.inboxesList.filter(
inbox => inbox.channel_id === inboxId
);
} else { } else {
[stateInbox] = this.inboxesList; [stateInbox] = this.inboxesList;
} }
@ -134,13 +161,12 @@ export default {
getUnReadMessages() { getUnReadMessages() {
const chat = this.getMessages; const chat = this.getMessages;
return chat === undefined ? null : this.unReadMessages(chat); return chat === undefined ? null : this.unReadMessages(chat);
},
showUnreadToast() {
}, },
shouldShowSpinner() { shouldShowSpinner() {
return this.getMessages.dataFetched === undefined || return (
(!this.listLoadingStatus && this.isLoadingPrevious); this.getMessages.dataFetched === undefined ||
(!this.listLoadingStatus && this.isLoadingPrevious)
);
}, },
shouldLoadMoreChats() { shouldLoadMoreChats() {
@ -148,8 +174,14 @@ export default {
}, },
}, },
methods: { created() {
bus.$on('scrollToMessage', () => {
this.focusLastMessage();
this.makeMessagesRead();
});
},
methods: {
focusLastMessage() { focusLastMessage() {
setTimeout(() => { setTimeout(() => {
this.attachListner(); this.attachListner();
@ -158,26 +190,40 @@ export default {
attachListner() { attachListner() {
this.conversationPanel = this.$el.querySelector('.conversation-panel'); this.conversationPanel = this.$el.querySelector('.conversation-panel');
this.heightBeforeLoad = this.getUnreadCount === 0 ? this.heightBeforeLoad =
this.conversationPanel.scrollHeight : this.$el.querySelector('.conversation-panel .unread--toast').offsetTop - 56; this.getUnreadCount === 0
? this.conversationPanel.scrollHeight
: this.$el.querySelector('.conversation-panel .unread--toast')
.offsetTop - 56;
this.conversationPanel.scrollTop = this.heightBeforeLoad; this.conversationPanel.scrollTop = this.heightBeforeLoad;
this.conversationPanel.addEventListener('scroll', this.handleScroll); this.conversationPanel.addEventListener('scroll', this.handleScroll);
this.isLoadingPrevious = false; this.isLoadingPrevious = false;
}, },
handleScroll(e) { handleScroll(e) {
const dataFetchCheck = (this.getMessages.dataFetched === true && this.shouldLoadMoreChats); const dataFetchCheck =
if (e.target.scrollTop < 100 && !this.isLoadingPrevious && dataFetchCheck) { this.getMessages.dataFetched === true && this.shouldLoadMoreChats;
if (
e.target.scrollTop < 100 &&
!this.isLoadingPrevious &&
dataFetchCheck
) {
this.isLoadingPrevious = true; this.isLoadingPrevious = true;
this.$store.dispatch('fetchPreviousMessages', { this.$store
.dispatch('fetchPreviousMessages', {
id: this.currentChat.id, id: this.currentChat.id,
before: this.getMessages.messages[0].id, before: this.getMessages.messages[0].id,
}).then(() => { })
this.conversationPanel.scrollTop = this.conversationPanel.scrollHeight - ( .then(() => {
this.heightBeforeLoad - this.conversationPanel.scrollTop); this.conversationPanel.scrollTop =
this.conversationPanel.scrollHeight -
(this.heightBeforeLoad - this.conversationPanel.scrollTop);
this.isLoadingPrevious = false; this.isLoadingPrevious = false;
this.heightBeforeLoad = this.getUnreadCount === 0 ? this.heightBeforeLoad =
this.conversationPanel.scrollHeight : this.$el.querySelector('.conversation-panel .unread--toast').offsetTop - 56; this.getUnreadCount === 0
? this.conversationPanel.scrollHeight
: this.$el.querySelector('.conversation-panel .unread--toast')
.offsetTop - 56;
}); });
} }
}, },
@ -191,12 +237,5 @@ export default {
} }
}, },
}, },
components: {
Thumbnail,
ConversationHeader,
Conversation,
ReplyBox,
},
}; };
</script> </script>

View file

@ -5,7 +5,11 @@
:header-content="$t('INBOX_MGMT.ADD.AUTH.DESC')" :header-content="$t('INBOX_MGMT.ADD.AUTH.DESC')"
/> />
<div class="row channels"> <div class="row channels">
<channel-item v-for="channel in channelList" :channel="channel" /> <channel-item
v-for="channel in channelList"
:key="channel"
:channel="channel"
/>
</div> </div>
</div> </div>
</template> </template>
@ -23,26 +27,23 @@ export default {
}, },
data() { data() {
return { return {
channelList: [ channelList: ['facebook', 'twitter', 'telegram', 'line'],
'facebook',
'twitter',
'telegram',
'line',
],
}; };
}, },
created() { created() {
bus.$on('channelItemClick', (channel) => { bus.$on('channelItemClick', channel => {
this.initChannelAuth(channel); this.initChannelAuth(channel);
}); });
}, },
methods: { methods: {
initChannelAuth(channel) { initChannelAuth(channel) {
if (channel === 'facebook') { if (channel === 'facebook') {
router.push({ name: 'settings_inboxes_page_channel', params: { page: 'new', sub_page: 'facebook' } }); router.push({
name: 'settings_inboxes_page_channel',
params: { page: 'new', sub_page: 'facebook' },
});
} }
}, },
}, },
}; };
</script> </script>

View file

@ -5,37 +5,41 @@
v-model="currentDateRangeSelection" v-model="currentDateRangeSelection"
track-by="name" track-by="name"
label="name" label="name"
@select="changeDateSelection"
placeholder="Select one" placeholder="Select one"
:options="dateRange" :options="dateRange"
:searchable="false" :searchable="false"
:allow-empty="true" :allow-empty="true"
@select="changeDateSelection"
/> />
</div> </div>
<div class="row"> <div class="row">
<woot-report-stats-card <woot-report-stats-card
v-for="(metric, index) in metrics" v-for="(metric, index) in metrics"
:heading="metric.NAME" :key="metric.NAME"
:point="accountSummary[metric.KEY]"
:desc="metric.DESC" :desc="metric.DESC"
:heading="metric.NAME"
:index="index" :index="index"
:selected="index === currentSelection"
:on-click="changeSelection" :on-click="changeSelection"
:point="accountSummary[metric.KEY]"
:selected="index === currentSelection"
/> />
</div> </div>
<div class="report-bar"> <div class="report-bar">
<woot-loading-state :message="$t('REPORT.LOADING_CHART')" v-if="accountReport.isFetching"></woot-loading-state> <woot-loading-state
v-if="accountReport.isFetching"
:message="$t('REPORT.LOADING_CHART')"
/>
<div v-else class="chart-container"> <div v-else class="chart-container">
<woot-bar :collection="collection" v-if="accountReport.data.length"/> <woot-bar v-if="accountReport.data.length" :collection="collection" />
<span class="empty-state" v-else v-html="$t('REPORT.NO_ENOUGH_DATA')" /> <span v-else class="empty-state">
{{ $t('REPORT.NO_ENOUGH_DATA') }}
</span>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import moment from 'moment'; import moment from 'moment';
@ -68,7 +72,9 @@ export default {
return {}; return {};
} }
if (!this.accountReport.data.length) return {}; if (!this.accountReport.data.length) return {};
const labels = this.accountReport.data.map(element => moment.unix(element.timestamp).format('DD/MMM')); const labels = this.accountReport.data.map(element =>
moment.unix(element.timestamp).format('DD/MMM')
);
const data = this.accountReport.data.map(element => element.value); const data = this.accountReport.data.map(element => element.value);
return { return {
labels, labels,

View file

@ -4,11 +4,11 @@
"dependencies": { "dependencies": {
"@rails/webpacker": "^4.0.7", "@rails/webpacker": "^4.0.7",
"axios": "^0.19.0", "axios": "^0.19.0",
"bourbon": "~4.2.7",
"babel-helper-vue-jsx-merge-props": "^2.0.3", "babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-vue-jsx": "^3.7.0", "babel-plugin-transform-vue-jsx": "^3.7.0",
"babel-preset-env": "^1.7.0", "babel-preset-env": "^1.7.0",
"bourbon": "~4.2.7",
"chart.js": "~2.5.0", "chart.js": "~2.5.0",
"dotenv": "^8.0.0", "dotenv": "^8.0.0",
"emojione": "~2.2.7", "emojione": "~2.2.7",
@ -74,6 +74,6 @@
] ]
}, },
"scripts": { "scripts": {
"eslint": "eslint app/javascript" "eslint": "eslint app/javascript --fix"
} }
} }