@webitel/ui-sdk 24.10.73 → 24.10.75

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.73",
3
+ "version": "24.10.75",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -64,6 +64,9 @@ import WtTextarea from './wt-textarea/wt-textarea.vue';
64
64
  import WtTimeInput from './wt-time-input/wt-time-input.vue';
65
65
  import WtTimepicker from './wt-timepicker/wt-timepicker.vue';
66
66
  import WtTooltip from './wt-tooltip/wt-tooltip.vue';
67
+ import WtNavigationMenu
68
+ from './on-demand/wt-navigation-menu/components/wt-navigation-menu.vue';
69
+ import WtStartPage from './on-demand/wt-start-page/components/wt-start-page.vue';
67
70
 
68
71
  const Components = {
69
72
  WtActionBar,
@@ -128,6 +131,8 @@ const Components = {
128
131
  WtDummy,
129
132
  WtStepper,
130
133
  WtExpansionPanel,
134
+ WtNavigationMenu,
135
+ WtStartPage,
131
136
  };
132
137
 
133
138
  export default Components;
@@ -0,0 +1,73 @@
1
+ <template>
2
+ <ul class="nav-menu__category nav-menu-lvl-1">
3
+ <li
4
+ v-for="(category, key) of categories"
5
+ :key="key"
6
+ class="nav-menu__option"
7
+ >
8
+ <button
9
+ :class="{ 'nav-menu__item--selected': selected.value === category.value }"
10
+ class="nav-menu__item nav-menu__item--active"
11
+ @click="select(category)"
12
+ >
13
+ <wt-icon
14
+ :color="selected.value === category.value ? 'on-primary' : 'default'"
15
+ :icon="icons.find((icon) => icon.includes(category.value))"
16
+ />
17
+ {{ category.name }}
18
+ </button>
19
+ <div v-show="selected.value === category.value">
20
+ <slot />
21
+ </div>
22
+ </li>
23
+ </ul>
24
+ </template>
25
+
26
+ <script setup>
27
+ import { defineProps, defineEmits } from 'vue';
28
+
29
+ const props = defineProps({
30
+ categories: {
31
+ type: Array,
32
+ default: () => [],
33
+ },
34
+ selected: {
35
+ type: Object,
36
+ default: () => ({}),
37
+ },
38
+ icons: {
39
+ type: Array,
40
+ default: () => ([]),
41
+ },
42
+ });
43
+
44
+ const emit = defineEmits(['select']);
45
+
46
+ function select(category) {
47
+ emit('select', category);
48
+ }
49
+ </script>
50
+
51
+ <style lang="scss" scoped>
52
+ @import '../../css/nav-menu';
53
+
54
+ .nav-menu__item {
55
+ &--active {
56
+ background: var(--secondary-color);
57
+
58
+ &:hover {
59
+ background: var(--secondary-hover-color);
60
+ }
61
+ }
62
+
63
+ &--selected {
64
+ color: var(--primary-on-color);
65
+ background: var(--primary-color);
66
+
67
+ &:hover {
68
+ color: var(--primary-on-color);
69
+ background: var(--primary-color);
70
+ }
71
+ }
72
+ }
73
+ </style>
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <ul class="nav-menu__category nav-menu-lvl-2">
3
+ <li
4
+ v-for="(category, key) of categories"
5
+ :key="key"
6
+ class="nav-menu__option
7
+ nav-menu__item
8
+ nav-menu-lvl-2--inner"
9
+ >
10
+ <span class="nav-menu-lvl-2__indicator" />
11
+ <router-link
12
+ :to="category.route"
13
+ class="nav-menu-lvl-2__link"
14
+ >
15
+ {{ category.name }}
16
+ </router-link>
17
+ </li>
18
+ </ul>
19
+ </template>
20
+
21
+ <script setup>
22
+ import { defineProps } from 'vue';
23
+
24
+ const props = defineProps({
25
+ categories: {
26
+ type: Array,
27
+ default: () => [],
28
+ },
29
+ });
30
+ </script>
31
+
32
+ <style lang="scss" scoped>
33
+ @import '../../css/nav-menu';
34
+
35
+ .nav-menu-lvl-2 {
36
+ @extend %wt-scrollbar;
37
+ overflow-y: auto;
38
+
39
+ .nav-menu-lvl-2__indicator {
40
+ position: relative;
41
+ display: block;
42
+ width: var(--spacing-md);
43
+ height: var(--spacing-md);
44
+
45
+ &:after {
46
+ position: absolute;
47
+ top: 50%;
48
+ left: 50%;
49
+ width: var(--spacing-2xs);
50
+ height: var(--spacing-2xs);
51
+ content: '';
52
+ transform: translate(-50%, -50%);
53
+ border-radius: 50%;
54
+ background: var(--text-main-color);
55
+ }
56
+ }
57
+
58
+ &__link {
59
+ color: var(--text-main-color);
60
+
61
+ &:hover, &:active {
62
+ text-decoration: underline;
63
+ }
64
+ }
65
+ }
66
+ </style>
@@ -0,0 +1,141 @@
1
+ <template>
2
+ <section class="wt-navigation-menu">
3
+ <article class="wt-navigation-menu__wrapper">
4
+ <nav-menu-lvl-1
5
+ :categories="categories"
6
+ :icons="icons"
7
+ :selected="selected"
8
+ @select="select"
9
+ >
10
+ <nav-menu-lvl-2
11
+ :categories="subcategories"
12
+ class="wt-navigation-menu__categories--display"
13
+ />
14
+ </nav-menu-lvl-1>
15
+ <nav-menu-lvl-2
16
+ :categories="subcategories"
17
+ class="wt-navigation-menu__categories--hidden"
18
+ />
19
+ </article>
20
+ </section>
21
+ </template>
22
+
23
+ <script setup>
24
+ import { ref, computed, onMounted } from 'vue';
25
+ import NavMenuLvl1 from './_internals/nav-menu-lvl-1.vue';
26
+ import NavMenuLvl2 from './_internals/nav-menu-lvl-2.vue';
27
+
28
+ const props = defineProps({
29
+
30
+ /** entire navigation hierarchy. Value: `{ value: string, name: string, subNav: [{ value: string, route: string, name: string}] }`
31
+ **/
32
+
33
+ nav: {
34
+ type: Array,
35
+ required: true,
36
+ },
37
+
38
+ /** array icons to display in 1 level menu
39
+ */
40
+
41
+ icons: {
42
+ type: Array,
43
+ default: () => ([]),
44
+ },
45
+ });
46
+
47
+ const selected = ref({});
48
+
49
+ const categories = computed(() => {
50
+ return props.nav.map((navItem) => ({
51
+ ...navItem,
52
+ name: navItem.name,
53
+ }));
54
+ });
55
+
56
+ const subcategories = computed(() => {
57
+ if (!selected.value.subNav) return [];
58
+ return selected.value.subNav.map((subNav) => {
59
+ const route = selected.value.route ? `${selected.value.route}/${subNav.route}` : subNav.route;
60
+ const name = subNav.name;
61
+ return {
62
+ ...subNav,
63
+ name,
64
+ route,
65
+ };
66
+ });
67
+ });
68
+
69
+ onMounted(() => {
70
+ initSelected();
71
+ });
72
+
73
+ function initSelected() {
74
+ select(categories.value[0]);
75
+ }
76
+
77
+ function select(category) {
78
+ selected.value = category;
79
+ }
80
+ </script>
81
+
82
+ <style lang="scss" scoped>
83
+ @import '../../../../css/main.scss';
84
+ @import '../../../../css/styleguide/viewport-breakpoints/_viewport-breakpoints.scss';
85
+ .wt-navigation-menu {
86
+ display: flex;
87
+ align-items: center;
88
+ flex-grow: 1;
89
+ justify-content: center;
90
+ height: 100%;
91
+
92
+ --button-min-height: 60px;
93
+ --wrapper-width: 60%;
94
+ --wrapper-height: calc(
95
+ var(--spacing-sm) * 2
96
+ + var(--button-min-height) * 7
97
+ + var(--spacing-2xs) * 6
98
+ );
99
+
100
+ @media only screen and (max-width: $viewport-sm) {
101
+ --wrapper-width: 80%;
102
+ }
103
+
104
+ @media only screen and (max-width: $viewport-xs) {
105
+ --wrapper-width: 100%;
106
+ --wrapper-height: 100%;
107
+ }
108
+
109
+ &__wrapper {
110
+ @extend %wt-scrollbar;
111
+ display: grid;
112
+ box-sizing: border-box;
113
+ width: var(--wrapper-width);
114
+ height: var(--wrapper-height);
115
+ margin: auto;
116
+ padding: var(--spacing-sm);
117
+ border-radius: var(--spacing-xs);
118
+ background: var(--content-wrapper-color);
119
+ grid-template-columns: repeat(2, 1fr);
120
+ grid-gap: var(--spacing-sm);
121
+
122
+ @media only screen and (max-width: $viewport-xs) {
123
+ grid-template-columns: 1fr;
124
+ }
125
+ }
126
+
127
+ &__categories--display {
128
+ display: none;
129
+
130
+ @media only screen and (max-width: $viewport-xs) {
131
+ display: block;
132
+ }
133
+ }
134
+
135
+ &__categories--hidden {
136
+ @media only screen and (max-width: $viewport-xs) {
137
+ display: none;
138
+ }
139
+ }
140
+ }
141
+ </style>
@@ -0,0 +1,32 @@
1
+ @import '../../../../css/main.scss';
2
+
3
+ .nav-menu {
4
+ &__category {
5
+ height: 100%;
6
+ border-radius: var(--border-radius);
7
+ }
8
+
9
+ &__option {
10
+ &:not(:last-child) {
11
+ margin-bottom: var(--spacing-2xs);
12
+ }
13
+ }
14
+
15
+ &__item {
16
+ @extend %typo-body-1;
17
+ display: flex;
18
+ align-items: center;
19
+ box-sizing: border-box;
20
+ width: 100%;
21
+ min-height: var(--button-min-height);
22
+ padding: 18px 20px;
23
+ transition: var(--transition);
24
+ text-align: left;
25
+ color: var(--text-main-color);
26
+ border-radius: var(--border-radius);
27
+
28
+ .wt-icon {
29
+ margin-right: var(--spacing-xs);
30
+ }
31
+ }
32
+ }
@@ -1,19 +1,23 @@
1
1
  <template>
2
2
  <article class="start-page-card">
3
3
  <header class="start-page-card__header">
4
- <wt-icon v-if="card.disabled" icon="lock"/>
4
+ <wt-icon
5
+ v-if="card.disabled"
6
+ icon="lock" />
5
7
  {{ card.name }}
6
8
  </header>
7
9
  <section class="start-page-card__main-section">
8
- <img :src="card.image" :alt="card.name">
10
+ <img
11
+ :alt="card.name"
12
+ :src="card.image">
9
13
  <p class="start-page-card__description">
10
14
  {{ card.text }}
11
15
  </p>
12
16
  </section>
13
17
  <footer>
14
18
  <wt-button
15
- class="start-page-card__button"
16
19
  :disabled="card.disabled"
20
+ class="start-page-card__button"
17
21
  color="secondary"
18
22
  wide
19
23
  @click="open"
@@ -25,31 +29,32 @@
25
29
  </template>
26
30
 
27
31
  <script setup>
28
- import { useRouter } from 'vue-router';
32
+ import { useRouter } from 'vue-router';
29
33
 
30
- const router = useRouter();
31
- const props = defineProps({
32
- card: {
33
- type: Object,
34
- required: true,
35
- },
36
- });
34
+ const router = useRouter();
35
+ const props = defineProps({
36
+ card: {
37
+ type: Object,
38
+ required: true,
39
+ },
40
+ });
37
41
 
38
- const open = () => {
39
- return router.push(props.card.route);
40
- };
42
+ const open = () => {
43
+ return router.push(props.card.route);
44
+ };
41
45
  </script>
42
46
 
43
47
  <style lang="scss" scoped>
48
+ @import '../../../../css/main.scss';
44
49
  .start-page-card {
45
50
  display: flex;
46
51
  flex-direction: column;
47
- gap: var(--spacing-xs);
48
52
  width: 264px;
49
53
  padding: var(--spacing-xs);
54
+ color: var(--text-main-color);
50
55
  border-radius: var(--border-radius);
51
56
  background-color: var(--content-wrapper-color);
52
- color: var(--text-main-color);
57
+ gap: var(--spacing-xs);
53
58
 
54
59
  &__header {
55
60
  @extend %typo-heading-4;
@@ -57,17 +62,16 @@
57
62
  align-items: center;
58
63
  justify-content: center;
59
64
  }
65
+
60
66
  &__description {
61
67
  @extend %typo-body-1;
62
- height: 78px;
63
- //in order to cut text after 3rd line:
68
+ display: -webkit-box;
64
69
  overflow: hidden;
65
- text-overflow: ellipsis;
70
+ height: 78px; //in order to cut text after 3rd line:
66
71
  text-align: center;
67
- display: -webkit-box;
72
+ text-overflow: ellipsis;
68
73
  -webkit-line-clamp: 3;
69
74
  -webkit-box-orient: vertical;
70
75
  }
71
76
  }
72
-
73
77
  </style>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div class="start-page-logo">
3
+ <img :src="logo">
4
+ </div>
5
+ </template>
6
+
7
+ <script setup>
8
+ const props = defineProps({
9
+ logo: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ });
14
+ </script>
15
+
16
+ <style lang="scss" scoped>
17
+ .start-page-logo {
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ min-height: 200px;
22
+ }
23
+ </style>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <div class="wt-start-page">
3
+ <start-page-logo
4
+ v-if="appLogo"
5
+ :logo="logo" />
6
+
7
+ <div class="wt-start-page__wrapper">
8
+ <start-page-card
9
+ v-for="card of navCards"
10
+ :key="card.value"
11
+ :card="card"
12
+ />
13
+ </div>
14
+
15
+ </div>
16
+ </template>
17
+
18
+ <script setup>
19
+ import { computed } from 'vue';
20
+ import StartPageCard from './start-page-card.vue';
21
+ import StartPageLogo from './start-page-logo.vue';
22
+
23
+ const props = defineProps({
24
+
25
+ /** entire navigation hierarchy. Value: `{ value: string, route: string, name: string, text: string, images: object - { light: string, dark: string } }`
26
+ **/
27
+
28
+ nav: {
29
+ type: Array,
30
+ required: true,
31
+ },
32
+ appLogo: {
33
+ type: Object,
34
+ },
35
+ darkMode: {
36
+ type: Boolean,
37
+ default: false,
38
+ },
39
+ });
40
+
41
+ const logo = computed(() => {
42
+ return props.darkMode ? props.appLogo.dark : props.appLogo.light;
43
+ });
44
+
45
+ const navCards = computed(() => {
46
+ return props.nav.map((navItem) => ({
47
+ ...navItem,
48
+ image: props.darkMode ? navItem.images.dark : navItem.images.light,
49
+ }));
50
+ });
51
+ </script>
52
+
53
+ <style scoped>
54
+ .wt-start-page__wrapper {
55
+ display: grid;
56
+ justify-content: center;
57
+ box-sizing: border-box;
58
+ min-width: 264px;
59
+ padding: var(--spacing-sm);
60
+ grid-template-columns: repeat(auto-fit, 264px);
61
+ grid-gap: var(--spacing-sm);
62
+ }
63
+ </style>
@@ -27,7 +27,7 @@ export const useCardComponent = (params) => {
27
27
  });
28
28
 
29
29
  const saveText = computed(() => {
30
- return isNew.value || itemInstance.value._dirty ? t('objects.save') : t('objects.saved');
30
+ return isNew.value || itemInstance.value._dirty ? t('reusable.save') : t('reusable.saved');
31
31
  });
32
32
 
33
33
  const redirectToEdit = () => {
@@ -1,65 +0,0 @@
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>
@@ -1,77 +0,0 @@
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>