@webitel/ui-sdk 24.10.34 → 24.10.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webitel/ui-sdk",
3
- "version": "24.10.34",
3
+ "version": "24.10.37",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -4,6 +4,7 @@ const CrmConfigurationSections = Object.freeze({
4
4
  SERVICE_CATALOG: 'service-catalog',
5
5
  PRIORITIES: 'priorities',
6
6
  STATUSES: 'statuses',
7
+ SOURCES: 'sources',
7
8
  CLOSURE_REASONS: 'closure-reasons',
8
9
  CONTACT_GROUPS: 'contact-groups',
9
10
  CASE_SOURCES: 'case-sources',
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <ul class="nav-menu__category nav-menu__category--lvl-1">
3
+ <li
4
+ v-for="(category, key) of categories"
5
+ :key="key"
6
+ class="nav-menu__category-option__wrapper"
7
+ >
8
+ <button
9
+ :class="{ 'nav-menu__category-option--selected': selected.value === category.value }"
10
+ class="nav-menu__category-option nav-menu__category-option--lvl-1"
11
+ @click="select(category)"
12
+ >
13
+ <wt-icon
14
+ :color="selected.value === category.value ? 'on-primary' : 'default'"
15
+ :icon="category.value"
16
+ icon-prefix="nav"
17
+ />
18
+ {{ category.name }}
19
+ </button>
20
+ <div v-show="selected.value === category.value">
21
+ <slot />
22
+ </div>
23
+ </li>
24
+ </ul>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { defineProps, defineEmits } from 'vue';
29
+
30
+ const props = defineProps({
31
+ categories: {
32
+ type: Array,
33
+ default: () => [],
34
+ },
35
+ selected: {
36
+ type: Object,
37
+ default: () => ({}),
38
+ },
39
+ });
40
+
41
+ const emit = defineEmits(['select']);
42
+
43
+ function select(category) {
44
+ emit('select', category);
45
+ }
46
+ </script>
47
+
48
+ <style lang="scss" scoped>
49
+ @import '../../css/navMenu';
50
+
51
+ .nav-menu__category-option--lvl-1 {
52
+ background: var(--lvl-1-bg);
53
+ text-transform: uppercase;
54
+ padding: var(--spacing-xs) var(--spacing-sm);
55
+
56
+ &:hover {
57
+ background: var(--lvl-1-bg--hover);
58
+ }
59
+
60
+ &.nav-menu__category-option--selected {
61
+ color: var(--lvl-1-text--selected);
62
+ background: var(--lvl-1-bg--selected);
63
+ }
64
+ }
65
+ </style>
@@ -0,0 +1,77 @@
1
+ <template>
2
+ <ul class="nav-menu__category nav-menu__category--lvl-2">
3
+ <li
4
+ v-for="(category, key) of categories"
5
+ :key="key"
6
+ class="nav-menu__category-option__wrapper nav-menu__category-option
7
+ nav-menu__category-option--lvl-2"
8
+ >
9
+ <span class="nav-menu__category-indicator" />
10
+ <router-link
11
+ :to="category.route"
12
+ class="nav-menu__link"
13
+ >
14
+ {{ category.name }}
15
+ </router-link>
16
+ </li>
17
+ </ul>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { defineProps } from 'vue';
22
+
23
+ const props = defineProps({
24
+ categories: {
25
+ type: Array,
26
+ default: () => [],
27
+ },
28
+ });
29
+ </script>
30
+
31
+ <style lang="scss" scoped>
32
+ @import '../../css/navMenu';
33
+
34
+ .nav-menu{
35
+ &__category{
36
+ &--lvl-2 {
37
+ display: flex;
38
+ flex-direction: column;
39
+ overflow-y: scroll;
40
+ padding: var(--spacing-xs);
41
+ box-shadow: var(--elevation-6);
42
+ border-radius: var(--spacing-xs);
43
+ gap: var(--spacing-xs);
44
+ }
45
+ &-option{
46
+ @extend %typo-subtitle-1;
47
+ }
48
+ &-indicator {
49
+ position: relative;
50
+ display: block;
51
+ width: var(--icon-md-size);
52
+ height: var(--icon-md-size);
53
+
54
+ &:after {
55
+ content: '';
56
+ position: absolute;
57
+ top: 50%;
58
+ left: 50%;
59
+ width: var(--headline-nav-indicator-size);
60
+ height: var(--headline-nav-indicator-size);
61
+ background: var(--text-main-color);
62
+ transform: translate(-50%, -50%);
63
+ border-radius: 50%;
64
+ }
65
+ }
66
+
67
+ }
68
+ &__link {
69
+ @extend %typo-subtitle-1;
70
+ color: var(--text-main-color);
71
+
72
+ &:hover, &:active {
73
+ text-decoration: underline;
74
+ }
75
+ }
76
+ }
77
+ </style>
@@ -0,0 +1,125 @@
1
+ <template>
2
+ <section class="nav-menu">
3
+ <article class="nav-menu__wrapper">
4
+ <nav-menu-lvl-1
5
+ :categories="categories"
6
+ :selected="selected"
7
+ @select="select"
8
+ >
9
+ <nav-menu-lvl-2
10
+ :categories="subcategories"
11
+ class="nav-menu__inner-lvl-2"
12
+ />
13
+ </nav-menu-lvl-1>
14
+ <nav-menu-lvl-2
15
+ :categories="subcategories"
16
+ class="nav-menu__outer-lvl-2"
17
+ />
18
+ </article>
19
+ </section>
20
+ </template>
21
+
22
+ <script setup>
23
+ import { ref, computed, onMounted } from 'vue';
24
+ import NavMenuLvl1 from './_internals/nav-menu-lvl-1.vue';
25
+ import NavMenuLvl2 from './_internals/nav-menu-lvl-2.vue';
26
+
27
+ const props = defineProps({
28
+ navItems: {
29
+ type: Array,
30
+ required: true,
31
+ },
32
+ });
33
+
34
+ const selected = ref({});
35
+ const categories = computed(() => {
36
+ return props.navItems.map((navItem) => ({
37
+ ...navItem,
38
+ name: navItem.name,
39
+ }));
40
+ });
41
+
42
+ const subcategories = computed(() => {
43
+ if (!selected.value.subNav) return [];
44
+ return selected.value.subNav.map((subNav) => {
45
+ const route = `${subNav.route}`;
46
+ const name = subNav.name;
47
+ return {
48
+ ...subNav,
49
+ name,
50
+ route,
51
+ };
52
+ });
53
+ });
54
+
55
+ onMounted(() => {
56
+ initSelected();
57
+ });
58
+
59
+ function initSelected() {
60
+ select(categories.value[0]);
61
+ }
62
+
63
+ function select(category) {
64
+ selected.value = category;
65
+ }
66
+ </script>
67
+
68
+ <style lang="scss" scoped>
69
+ .nav-menu {
70
+ display: flex;
71
+ align-items: center;
72
+ flex-grow: 1;
73
+ justify-content: center;
74
+ height: 100%;
75
+
76
+ --button-min-height: 60px;
77
+ --wrapper-width: 60%;
78
+ --wrapper-height: calc(
79
+ var(--spacing-sm) * 2
80
+ + var(--button-min-height) * 7
81
+ + var(--spacing-2xs) * 6
82
+ );
83
+ --lvl-1-bg: var(--dp-18-surface-color);
84
+ --lvl-1-bg--hover: var(--dp-20-surface-color);
85
+ --lvl-1-bg--selected: var(--primary-color);
86
+ --lvl-1-text--selected: var(--primary-on-color);
87
+
88
+ @media (#{$media} and #{$media-width-xs}) {
89
+ --wrapper-width: 100%;
90
+ --wrapper-height: 100%;
91
+ }
92
+
93
+ &__wrapper {
94
+ @extend %wt-scrollbar;
95
+
96
+ display: grid;
97
+ box-sizing: border-box;
98
+ width: var(--wrapper-width);
99
+ height: var(--wrapper-height);
100
+ margin: auto;
101
+ padding: var(--spacing-xs);
102
+ border-radius: var(--spacing-xs);
103
+ background: var(--dp-20-surface-color);
104
+ grid-template-columns: repeat(2, 1fr);
105
+ grid-gap: var(--spacing-sm);
106
+
107
+ @media (#{$media} and #{$media-width-xs}) {
108
+ grid-template-columns: 1fr;
109
+ }
110
+ }
111
+
112
+ &__inner-lvl-2{
113
+ display: none;
114
+
115
+ @media (#{$media} and #{$media-width-xs}) {
116
+ display: block;
117
+ }
118
+ }
119
+ &__outer-lvl-2{
120
+ @media (#{$media} and #{$media-width-xs}) {
121
+ display: none;
122
+ }
123
+ }
124
+ }
125
+ </style>
@@ -0,0 +1,20 @@
1
+ .nav-menu__category {
2
+ height: 100%;
3
+ border-radius: var(--border-radius);
4
+
5
+ &-option {
6
+ @extend %typo-subtitle-2;
7
+
8
+ display: flex;
9
+ align-items: center;
10
+ width: 100%;
11
+ transition: var(--transition);
12
+ text-align: left;
13
+ color: var(--text-main-color);
14
+ border-radius: var(--spacing-xs);
15
+
16
+ .wt-icon {
17
+ margin-right: var(--spacing-xs);
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <article class="start-page-card">
3
+ <header class="start-page-card__header">
4
+ <wt-icon v-if="card.disabled" icon="lock"/>
5
+ {{ card.name }}
6
+ </header>
7
+ <section class="start-page-card__main-section">
8
+ <img :src="card.image" :alt="card.name">
9
+ <p class="start-page-card__description">
10
+ {{ card.text }}
11
+ </p>
12
+ </section>
13
+ <footer>
14
+ <wt-button
15
+ class="start-page-card__button"
16
+ :disabled="card.disabled"
17
+ color="secondary"
18
+ wide
19
+ @click="open"
20
+ >
21
+ {{ $t('reusable.open') }}
22
+ </wt-button>
23
+ </footer>
24
+ </article>
25
+ </template>
26
+
27
+ <script setup>
28
+ import { useRouter } from 'vue-router';
29
+
30
+ const router = useRouter();
31
+ const props = defineProps({
32
+ card: {
33
+ type: Object,
34
+ required: true,
35
+ },
36
+ });
37
+
38
+ const open = () => {
39
+ return router.push(props.card.route);
40
+ };
41
+ </script>
42
+
43
+ <style lang="scss" scoped>
44
+ .start-page-card {
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: var(--spacing-xs);
48
+ width: 264px;
49
+ padding: var(--spacing-xs);
50
+ border-radius: var(--border-radius);
51
+ background-color: var(--content-wrapper-color);
52
+ color: var(--text-main-color);
53
+
54
+ &__header {
55
+ @extend %typo-heading-4;
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: center;
59
+ }
60
+ &__description {
61
+ @extend %typo-body-1;
62
+ height: 78px;
63
+ //in order to cut text after 3rd line:
64
+ overflow: hidden;
65
+ text-overflow: ellipsis;
66
+ text-align: center;
67
+ display: -webkit-box;
68
+ -webkit-line-clamp: 3;
69
+ -webkit-box-orient: vertical;
70
+ }
71
+ }
72
+
73
+ </style>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div class="start-page-logo">
3
+ <img :src="image">
4
+ </div>
5
+ </template>
6
+
7
+ <script setup>
8
+ const props = defineProps({
9
+ image: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ });
14
+ </script>
15
+
16
+ <style lang="scss" scoped>
17
+ .start-page-logo{
18
+ min-height: 200px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ }
23
+ </style>
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <start-page-logo :image="logo"/>
3
+ <div class="start-page-wrapper">
4
+ <start-page-card
5
+ v-for="(card) of navCards"
6
+ :key="card.value"
7
+ :card="card"
8
+ />
9
+ </div>
10
+ </template>
11
+
12
+ <script setup>
13
+ import { computed } from 'vue';
14
+ import { useI18n } from 'vue-i18n';
15
+ import { useStore } from 'vuex';
16
+ import StartPageCard from './start-page-card.vue';
17
+ import StartPageLogo from './start-page-logo.vue';
18
+
19
+ // Vuex store access
20
+ const store = useStore();
21
+
22
+ const { t } = useI18n();
23
+
24
+ const props = defineProps({
25
+ nav: {
26
+ type: Array,
27
+ required: true,
28
+ },
29
+ appLogo: {
30
+ type: Object,
31
+ required: true,
32
+ }
33
+ });
34
+
35
+ const darkMode = computed(() => store.getters['appearance/DARK_MODE']);
36
+
37
+ const logo = computed(() => {
38
+ return darkMode.value ? props.appLogo.dark : props.appLogo.light;
39
+ });
40
+
41
+ const navCards = computed(() => {
42
+ return props.nav.map((navItem) => ({
43
+ ...navItem,
44
+ image: darkMode.value ? navItem.images.dark : navItem.images.light,
45
+ }));
46
+ });
47
+ </script>
48
+
49
+ <style scoped>
50
+ .start-page-wrapper {
51
+ box-sizing: border-box;
52
+ min-width: 264px;
53
+ display: grid;
54
+ grid-template-columns: repeat(auto-fit, 264px);
55
+ justify-content: center;
56
+ grid-gap: var(--spacing-sm);
57
+ padding: var(--spacing-sm);
58
+ }
59
+ </style>