Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/ lookups - router, plugins, store, dummy [WTEL-4740] #138

Open
wants to merge 1 commit into
base: feat/lookups-pr
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/app/composables/useDummy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import IsEmpty from '@webitel/ui-sdk/src/scripts/isEmpty';
import getNamespacedState from '@webitel/ui-sdk/src/store/helpers/getNamespacedState';
import { computed, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useStore } from 'vuex';
import defaultDummyPicAfterSearchDark from '../assets/dummy-dark.svg';
import defaultDummyPicAfterSearchLight from '../assets/dummy-light.svg';

export function useDummy({
namespace,
showAction,
hiddenText,
dummyPic,
dummyText,
dummyPicAfterSearch,
dummyTextAfterSearch = 'objects.emptyResultSearch',
}) {
const store = useStore();
const route = useRoute();

const dummy = ref('');

const dataList = computed(() => getNamespacedState(store.state, namespace).dataList);
const search = computed(() => getNamespacedState(store.state, namespace).search);

const darkMode = computed(() => store.getters['appearance/DARK_MODE']);
const dummyImgAfterSearch = computed(() => {
if (dummyPicAfterSearch) return dummyPicAfterSearch;
return darkMode.value ? defaultDummyPicAfterSearchDark : defaultDummyPicAfterSearchLight;
});

watch(
() => dataList,
() => {
if (!dataList.value.length) {
if (
IsEmpty(route?.query)
? search.value
: Object.values(route.query).some((query) => query.length)
) {
return (dummy.value = {
src: dummyImgAfterSearch,
text: dummyTextAfterSearch,
});
}
return (dummy.value = {
src: dummyPic,
text: dummyText,
showAction,
hiddenText,
});
}
return (dummy.value = '');
},
{ deep: true },
);
return { dummy };
}
11 changes: 8 additions & 3 deletions src/app/plugins/webitel-ui.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
// import styles
import '@webitel/ui-sdk/dist/ui-sdk.css';
import WebitelUI from '@webitel/ui-sdk/dist/ui-sdk.js';

// import locale
import WebitelUIEn from '@webitel/ui-sdk/src/locale/en/en.js';
import WebitelUIKz from '@webitel/ui-sdk/src/locale/kz/kz.js';
import WebitelUIRu from '@webitel/ui-sdk/src/locale/ru/ru.js';
import WebitelUIUa from '@webitel/ui-sdk/src/locale/ua/ua.js';
import eventBus from '@webitel/ui-sdk/src/scripts/eventBus.js';
import i18n from '../locale/i18n.js';
import '@webitel/ui-sdk/dist/ui-sdk.css';

const globals = {
$baseURL: import.meta.env.BASE_URL,
};

// init plugin
export default [WebitelUI, { eventBus, globals }];
// add plugin locales to main i18n

i18n.global.mergeLocaleMessage('en', WebitelUIEn);
i18n.global.mergeLocaleMessage('ru', WebitelUIRu);
i18n.global.mergeLocaleMessage('ua', WebitelUIUa);
i18n.global.mergeLocaleMessage('kz', WebitelUIKz);

export default [WebitelUI, { eventBus, globals }];
58 changes: 58 additions & 0 deletions src/app/router/_internals/RouteNames.enum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
export default Object.freeze({
AUTH: 'auth',
APPLICATION_HUB: 'application-hub',
HOME: 'home',
START: 'start',

// DIRECTORY
LICENSE: 'license',
USERS: 'users',
DEVICES: 'devices',

// ROUTING
FLOW: 'flow',
DIALPLAN: 'dialplan',
GATEWAYS: 'gateways',
CHATPLAN: 'chatplan',
CHAT_GATEWAYS: 'chat-gateways',

// LOOKUPS
SKILLS: 'skills',
BUCKETS: 'buckets',
BLACKLIST: 'blacklists',
REGIONS: 'regions',
CALENDARS: 'calendars',
COMMUNICATIONS: 'communications',
PAUSE_CAUSE: 'agent-pause-cause',
MEDIA: 'media',
CONTACT_GROUPS: 'contact-groups',

// CONTACT-CENTER
AGENTS: 'agents',
TEAMS: 'teams',
RESOURCES: 'resources',
RESOURCE_GROUPS: 'resource-groups',
QUEUES: 'queues',
MEMBERS: 'queues-members',

// INTEGRATIONS
STORAGE: 'storage',
COGNITIVE_PROFILES: 'cognitive-profiles',
EMAIL_PROFILES: 'email-profiles',
SINGLE_SIGN_ON: 'single-sign-on',
IMPORT_CSV: 'import-csv',
TRIGGERS: 'triggers',

// PERMISSIONS
OBJECTS: 'objects',
ROLES: 'roles',

// SYSTEM
CHANGELOGS: 'changelogs',
CONFIGURATION: 'configuration',
GLOBAL_VARIABLES: 'global-variables',

SETTINGS_PAGE: 'settings',
PAGE_403: 'access-denied',
PAGE_404: '',
});
25 changes: 25 additions & 0 deletions src/app/router/_internals/guards.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import store from "../../store/index.js";

export const checkAppAccess = (to, from, next) => {
// check for === false because it can be undefined
if (to.meta.requiresAccess === false) next();

const hasReadAccess = store.getters['userinfo/CHECK_APP_ACCESS'](store.getters['userinfo/THIS_APP']);
if (hasReadAccess) {
next();
} else {
next();
// next('/access-denied');
}
};

export const checkRouteAccess = (to, from, next) => {
const hasReadAccess = store.getters['userinfo/HAS_READ_ACCESS']({ route: to });
if (hasReadAccess) {
next();
} else {
next();
console.log('error?')
// next('/access-denied');
}
};
27 changes: 25 additions & 2 deletions src/app/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import ContactCommunications
from '../../modules/contacts/components/opened-contact-communications.vue';
import OpenedContact
from '../../modules/contacts/components/opened-contact.vue';
import TheContacts from '../../modules/contacts/components/the-contacts.vue';
import ContactPermissions
from '../../modules/contacts/modules/permissions/components/the-permissions.vue';
import ContactTimeline
Expand All @@ -14,6 +13,14 @@ import ContactVariables
from '../../modules/contacts/modules/variables/components/the-variables.vue';
import TheCrmWorkspace from '../components/the-crm-workspace.vue';
import AccessDenied from '../components/utils/access-denied-component.vue';
import TheStartPage
from '../../modules/start-page/components/the-start-page.vue';
import TheContacts from '../../modules/contacts/components/the-contacts.vue';
import TheConfiguration from '../../modules/configuration/components/the-configuration.vue';

import ContactGroupsRoutes from "../../modules/lookups/modules/contact-groups/modules/cgroups/router/contact-groups.js";


import store from '../store';

const checkAppAccess = (to, from, next) => {
Expand All @@ -40,16 +47,30 @@ const routes = [
{
path: '/',
name: 'crm-workspace',
redirect: { name: CrmSections.CONTACTS },
redirect: { name: 'the-start-page' },
component: TheCrmWorkspace,
beforeEnter: checkAppAccess,
children: [
{
path: 'start-page',
name: 'the-start-page',
component: TheStartPage,
},
{
path: 'contacts',
name: CrmSections.CONTACTS,
component: TheContacts,
beforeEnter: checkRouteAccess,
// redirect: { name: `the-start-page` },
},
{
path: 'configuration',
name: CrmSections.CONFIGURATION,
component: TheConfiguration,
// beforeEnter: checkRouteAccess,
// redirect: { name: `the-start-page` },
},

{
path: 'contacts/:id',
name: `${CrmSections.CONTACTS}-card`,
Expand Down Expand Up @@ -99,13 +120,15 @@ const routes = [
},
],
},
...ContactGroupsRoutes,
],
},
{
path: '/access-denied',
name: 'access-denied',
component: AccessDenied,
},

];

const router = createRouter({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import deepCopy from 'deep-copy';
import set from 'lodash/set';

const state = {
itemId: 0,
itemInstance: {},
};

const actions = {
SET_PARENT_ITEM_ID: (context, id) => {
context.commit('SET_PARENT_ITEM_ID', id);
},
SET_ITEM_ID: (context, id) => {
if (id !== 'new') context.commit('SET_ITEM_ID', id);
else context.commit('SET_ITEM_ID', 0);
},
LOAD_ITEM: async (context) => {
if (context.state.itemId) {
const item = await context.dispatch('GET_ITEM');
context.commit('SET_ITEM', item);
}
},
SET_ITEM_PROPERTY: (context, payload) => {
context.commit('SET_ITEM_PROPERTY', payload);
context.commit('SET_ITEM_PROPERTY', {
prop: '_dirty',
value: true,
});
},
RESET_ITEM_STATE: async (context) => {
context.commit('RESET_ITEM_STATE');
},
};

const mutations = {
SET_PARENT_ITEM_ID: (state, id) => {
state.parentId = id;
},
SET_ITEM_ID: (state, id) => {
state.itemId = id;
},
SET_ITEM_PROPERTY: (state, { prop, value, path }) => {
if (path) {
set(state.itemInstance, path, value);
} else {
// DEPRECATED, LEGACY CODE
state.itemInstance[prop] = value;
}
},
SET_ITEM: (state, item) => {
state.itemInstance = item;
},
};

export default {
getActions: () => actions,
getMutations: () => mutations,
generateState: () => deepCopy(state),
};
Loading