@it-enterprise/forcebpm-ui-kit 1.0.2-beta.3 → 1.0.2-beta.30

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.
Files changed (86) hide show
  1. package/README.md +81 -65
  2. package/index.js +48 -1
  3. package/package.json +35 -15
  4. package/plugin.js +117 -0
  5. package/src/FActionSnackbar.vue +107 -0
  6. package/src/FAvatar.vue +10 -8
  7. package/src/{FConfirmModal.vue → FConfirmDialog.vue} +38 -28
  8. package/src/FContextMenu.vue +87 -0
  9. package/src/FDialog.vue +264 -0
  10. package/src/FLangSwitcher.vue +47 -0
  11. package/src/FNoData.vue +80 -0
  12. package/src/FNotify.vue +257 -0
  13. package/src/FPagination.vue +163 -0
  14. package/src/FPreLoader.vue +105 -0
  15. package/src/FSearchPanel.vue +191 -0
  16. package/src/FShare.vue +134 -0
  17. package/src/FTruncate.vue +121 -0
  18. package/src/FUserGroupPicker.vue +634 -0
  19. package/src/FUserRoles.vue +195 -0
  20. package/src/assets/fonts/ProximaNova-Bold.woff +0 -0
  21. package/src/assets/fonts/ProximaNova-Bold.woff2 +0 -0
  22. package/src/assets/fonts/ProximaNova-Regular.woff +0 -0
  23. package/src/assets/fonts/ProximaNova-Regular.woff2 +0 -0
  24. package/src/assets/fonts/ProximaNova-Semibold.woff +0 -0
  25. package/src/assets/fonts/ProximaNova-Semibold.woff2 +0 -0
  26. package/src/assets/fonts/loadFonts.js +55 -0
  27. package/src/assets/icons/bell-mute.svg +4 -0
  28. package/src/assets/icons/bell.svg +3 -0
  29. package/src/assets/icons/check.svg +3 -0
  30. package/src/assets/icons/checkbox-false.svg +3 -0
  31. package/src/assets/icons/checkbox-true.svg +4 -0
  32. package/src/assets/icons/chevron.svg +3 -0
  33. package/src/assets/icons/color-radio-active.svg +4 -0
  34. package/src/assets/icons/color-radio.svg +3 -0
  35. package/src/assets/icons/ctx-arrow.svg +3 -0
  36. package/src/assets/icons/ctx-delete.svg +6 -0
  37. package/src/assets/icons/ctx-link.svg +5 -0
  38. package/src/assets/icons/ctx-more.svg +5 -0
  39. package/src/assets/icons/ctx-pen.svg +4 -0
  40. package/src/assets/icons/delete.svg +6 -0
  41. package/src/assets/icons/dots.svg +5 -0
  42. package/src/assets/icons/filter.svg +3 -0
  43. package/src/assets/icons/folder.svg +3 -0
  44. package/src/assets/icons/open-envelope.svg +6 -0
  45. package/src/assets/icons/pass-eye-close.svg +3 -0
  46. package/src/assets/icons/pass-eye-open.svg +4 -0
  47. package/src/assets/icons/plus-solid.svg +4 -0
  48. package/src/assets/icons/plus.svg +4 -0
  49. package/src/assets/icons/radio-false.svg +3 -0
  50. package/src/assets/icons/radio-true.svg +4 -0
  51. package/src/assets/icons/search.svg +3 -0
  52. package/src/assets/icons/sort-solid.svg +3 -0
  53. package/src/assets/icons/sort.svg +6 -0
  54. package/src/assets/icons/star-line.svg +3 -0
  55. package/src/assets/icons/star.svg +3 -0
  56. package/src/assets/icons/times.svg +4 -0
  57. package/src/assets/images/0.gif +0 -0
  58. package/src/assets/images/0.svg +4 -0
  59. package/src/assets/images/3.svg +4 -0
  60. package/src/assets/images/4.svg +4 -0
  61. package/src/assets/images/5.svg +4 -0
  62. package/src/assets/scss/buttons.scss +60 -0
  63. package/src/assets/scss/card.scss +11 -0
  64. package/src/assets/scss/expansion.scss +45 -0
  65. package/src/assets/scss/icons.scss +273 -0
  66. package/src/assets/scss/index.scss +10 -0
  67. package/src/assets/scss/input.scss +344 -0
  68. package/src/assets/scss/overlay.scss +69 -0
  69. package/src/assets/scss/skeleton.scss +22 -0
  70. package/src/assets/scss/tables.scss +143 -0
  71. package/src/assets/scss/tabs.scss +42 -0
  72. package/src/assets/scss/utilities.scss +167 -0
  73. package/src/f-date-picker/FDatePicker.vue +322 -0
  74. package/src/f-date-picker/FMenuDatePicker.vue +337 -0
  75. package/src/f-date-picker/FTextFieldDate.vue +498 -0
  76. package/src/f-toolbar/FFilterPanel.vue +62 -0
  77. package/src/f-toolbar/FSortPanel.vue +55 -0
  78. package/src/f-toolbar/FTabPanel.vue +123 -0
  79. package/src/f-toolbar/FToolbar.vue +131 -0
  80. package/src/f-toolbar/FViewerPanel.vue +71 -0
  81. package/src/forcebpmIcon.js +69 -0
  82. package/src/locales/en.json +115 -0
  83. package/src/locales/index.js +7 -0
  84. package/src/locales/ru.json +116 -0
  85. package/src/locales/uk.json +116 -0
  86. package/src/utils/color.js +38 -0
@@ -0,0 +1,123 @@
1
+ <script setup>
2
+ // FTabPanel
3
+
4
+ defineProps({
5
+ tabs: {
6
+ type: Array,
7
+ default: () => [],
8
+ validator: value => {
9
+ const values = value.map(i => i.value)
10
+ const isUnique = new Set(values).size === values.length
11
+ return (
12
+ isUnique &&
13
+ value.every(
14
+ i =>
15
+ 'name' in i &&
16
+ typeof i.name === 'string' &&
17
+ 'value' in i &&
18
+ (typeof i.value === 'number' || typeof i.value === 'string') &&
19
+ (i.count === undefined || i.count === null || typeof i.count === 'number') &&
20
+ (i.loading === undefined || typeof i.loading === 'boolean') &&
21
+ (i.hide === undefined || typeof i.hide === 'boolean')
22
+ )
23
+ )
24
+ }
25
+ // Example:
26
+ // {
27
+ // name: String,
28
+ // value: Number | String,
29
+ // count: Number,
30
+ // loading: Boolean,
31
+ // hide: Boolean,
32
+ // }
33
+ },
34
+ slider: {
35
+ type: Boolean,
36
+ default: false
37
+ }
38
+ })
39
+
40
+ const modelValue = defineModel({
41
+ type: [Number, String],
42
+ default: 0
43
+ })
44
+ </script>
45
+
46
+ <template>
47
+ <v-tabs v-model="modelValue" :hide-slider="!slider" height="32" class="f-tab-panel" :class="{ 'is-slider': slider }">
48
+ <template v-for="t in tabs">
49
+ <v-tab v-if="!t.hide" :key="t.value" :value="t.value">
50
+ <!-- Loading -->
51
+ <v-skeleton-loader v-if="t.loading" width="120px" height="24px" class="f-skeleton-loader" :class="{ 'pt-2': !slider }" type="text" />
52
+
53
+ <!-- Tab name -->
54
+ <div v-else class="d-flex align-center justify-center f-tab-panel-name">
55
+ <FTruncate location="top" offset="6, 6" :text="t.name" />
56
+ &nbsp;
57
+ <span v-if="typeof t.count === 'number'" class="lh-11">({{ t.count }})</span>
58
+ </div>
59
+ </v-tab>
60
+ </template>
61
+ </v-tabs>
62
+ </template>
63
+
64
+ <style lang="scss" scoped>
65
+ .f-tab-panel {
66
+ position: relative;
67
+ bottom: -1px;
68
+ &.is-slider {
69
+ :deep(.v-slide-group__container) {
70
+ .v-slide-group__content {
71
+ .v-btn {
72
+ .v-btn__content {
73
+ .v-tab__slider {
74
+ height: 2px;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ :deep(.v-slide-group__container) {
82
+ &::after {
83
+ content: none;
84
+ }
85
+ }
86
+ .f-tab-panel-name {
87
+ max-width: 320px;
88
+ }
89
+ &:not(.is-slider) {
90
+ :deep(.v-slide-group__container) {
91
+ .v-slide-group__content {
92
+ .v-tab {
93
+ border-bottom: 0 !important;
94
+ border-bottom-right-radius: 0 !important;
95
+ border-bottom-left-radius: 0 !important;
96
+ border-top-right-radius: 10.8px !important;
97
+ border-top-left-radius: 10.8px !important;
98
+ &::before {
99
+ content: '';
100
+ position: absolute;
101
+ bottom: 0;
102
+ left: 0;
103
+ width: 100%;
104
+ height: 1px;
105
+ background: rgb(var(--v-theme-line));
106
+ }
107
+ &.v-tab-item--selected {
108
+ background: rgb(var(--v-theme-fields));
109
+ border: 0.5px solid rgb(var(--v-theme-primary));
110
+ position: relative;
111
+ &::before {
112
+ content: none;
113
+ }
114
+ }
115
+ :deep(.v-btn__content) {
116
+ white-space: initial;
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ </style>
@@ -0,0 +1,131 @@
1
+ <script setup>
2
+ // FToolbar
3
+
4
+ defineProps({
5
+ tabs: {
6
+ type: Array,
7
+ default: () => []
8
+ },
9
+ viewers: {
10
+ type: Array,
11
+ default: () => []
12
+ },
13
+ config: {
14
+ type: Object,
15
+ default: () => ({
16
+ search: true,
17
+ sort: true,
18
+ filter: true,
19
+ menuFilter: false,
20
+ favorites: false
21
+ }),
22
+ validator: value => {
23
+ if (value.filter && value.menuFilter) {
24
+ console.warn('"filter" and "menuFilter" cannot both be true')
25
+ return false
26
+ }
27
+ return true
28
+ }
29
+ },
30
+ sortBadge: {
31
+ type: Boolean,
32
+ default: false
33
+ },
34
+ filterBadge: {
35
+ type: Boolean,
36
+ default: false
37
+ },
38
+ slider: {
39
+ type: Boolean,
40
+ default: false
41
+ }
42
+ })
43
+
44
+ const emit = defineEmits(['filterActivator'])
45
+
46
+ const activeTab = defineModel('activeTab', {
47
+ type: [Number, String],
48
+ default: 0
49
+ })
50
+ const activeViewer = defineModel('activeViewer', {
51
+ type: [Number, String],
52
+ default: 0
53
+ })
54
+ const search = defineModel('search', {
55
+ type: String,
56
+ default: ''
57
+ })
58
+ const filter = defineModel('filter', {
59
+ type: Boolean,
60
+ default: false
61
+ })
62
+ const sort = defineModel('sort', {
63
+ type: Boolean,
64
+ default: false
65
+ })
66
+ const favorites = defineModel('favorites', {
67
+ type: Boolean,
68
+ default: false
69
+ })
70
+ </script>
71
+
72
+ <template>
73
+ <div class="f-toolbar d-flex">
74
+ <slot name="prependActions"></slot>
75
+ <!-- Tabs -->
76
+ <FTabPanel v-if="tabs.length" v-model="activeTab" :slider="slider" :tabs="tabs" />
77
+
78
+ <v-spacer />
79
+
80
+ <!-- Viewers -->
81
+ <FViewerPanel v-if="viewers.length" v-model="activeViewer" :viewers="viewers" />
82
+
83
+ <!-- Actions -->
84
+ <div class="d-flex f-toolbar-actions">
85
+ <!-- Search -->
86
+ <FSearchPanel v-if="config.search" v-model="search" search-on-blur :tooltip-props="{ location: 'top', offset: '10' }" />
87
+
88
+ <!-- Dialog filter activator -->
89
+ <v-tooltip v-if="config.filter && !config.menuFilter" :text="$t('tooltip.filter')">
90
+ <template #activator="{ props: tooltipProps }">
91
+ <v-btn class="f-filter-activator" variant="text" size="30" v-bind="tooltipProps" @click="emit('filterActivator')">
92
+ <v-badge dot color="primary" :model-value="Boolean(filterBadge)" offset-x="-4" offset-y="-2">
93
+ <FIcon icon="filter" color="text" size="18" />
94
+ </v-badge>
95
+ </v-btn>
96
+ </template>
97
+ </v-tooltip>
98
+
99
+ <!-- Menu filter -->
100
+ <FFilterPanel v-if="!config.filter && config.menuFilter" v-model="filter" :badge="filterBadge">
101
+ <slot name="filter"></slot>
102
+ </FFilterPanel>
103
+
104
+ <!-- Sort -->
105
+ <FSortPanel v-if="config.sort" v-model="sort" :badge="sortBadge">
106
+ <slot name="sort"></slot>
107
+ </FSortPanel>
108
+
109
+ <!-- Favorites -->
110
+ <v-tooltip v-if="config.favorites" :text="$t('tooltip.favoritesFilter')">
111
+ <template #activator="{ props: tooltipProps }">
112
+ <v-btn variant="text" v-bind="tooltipProps" size="30" @click="favorites = !favorites">
113
+ <FIcon :icon="favorites ? 'star' : 'star-line'" color="text" />
114
+ </v-btn>
115
+ </template>
116
+ </v-tooltip>
117
+
118
+ <!-- Custom actions -->
119
+ <slot name="customActions"></slot>
120
+ </div>
121
+ </div>
122
+ </template>
123
+
124
+ <style lang="scss" scoped>
125
+ .f-toolbar {
126
+ max-height: 32px;
127
+ width: 100%;
128
+ position: relative;
129
+ border-bottom: 1px solid rgb(var(--v-theme-disabled));
130
+ }
131
+ </style>
@@ -0,0 +1,71 @@
1
+ <script setup>
2
+ // FViewerPanel
3
+ defineProps({
4
+ viewers: {
5
+ type: Array,
6
+ default: () => [],
7
+ validator: value => {
8
+ const values = value.map(i => i.value)
9
+ const isUnique = new Set(values).size === values.length
10
+
11
+ return (
12
+ isUnique &&
13
+ value.every(
14
+ i =>
15
+ 'name' in i &&
16
+ typeof i.name === 'string' &&
17
+ 'value' in i &&
18
+ (typeof i.value === 'number' || typeof i.value === 'string') &&
19
+ (i.loading === undefined || typeof i.loading === 'boolean') &&
20
+ (i.hide === undefined || typeof i.hide === 'boolean')
21
+ )
22
+ )
23
+ }
24
+ // Example:
25
+ // {
26
+ // name: String,
27
+ // value: Number | String,
28
+ // loading: Boolean,
29
+ // hide: Boolean,
30
+ // }
31
+ }
32
+ })
33
+
34
+ const modelValue = defineModel({
35
+ type: [Number, String],
36
+ default: 0
37
+ })
38
+ </script>
39
+ <template>
40
+ <v-tabs v-model="modelValue" hide-slider height="32" class="f-viewer-panel">
41
+ <template v-for="v in viewers">
42
+ <v-tab v-if="!v.hide" :key="v.value" :value="v.value" :ripple="false">
43
+ <!-- Loading -->
44
+ <v-skeleton-loader v-if="v.loading" width="120px" height="24px" class="pt-2 f-skeleton-loader" type="text" />
45
+
46
+ <!-- Viewer name -->
47
+ <template v-else>{{ v.name }}</template>
48
+ </v-tab>
49
+ </template>
50
+ </v-tabs>
51
+ </template>
52
+
53
+ <style lang="scss" scoped>
54
+ .f-viewer-panel {
55
+ background: transparent;
56
+ :deep(.v-slide-group__container) {
57
+ &::after {
58
+ content: none;
59
+ }
60
+ .v-slide-group__content {
61
+ .v-tab {
62
+ padding-left: 13.5px;
63
+ padding-right: 13.5px;
64
+ .v-btn__overlay {
65
+ display: none;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ </style>
@@ -0,0 +1,69 @@
1
+ import { h } from 'vue'
2
+
3
+ // Component for using as <f-icon> or <FIcon>
4
+ export const FIcon = {
5
+ name: 'FIcon',
6
+ props: {
7
+ icon: {
8
+ type: String,
9
+ required: true
10
+ },
11
+ color: {
12
+ type: String,
13
+ default: 'primary'
14
+ },
15
+ size: {
16
+ type: [String, Number],
17
+ default: 20
18
+ },
19
+ height: {
20
+ type: [String, Number],
21
+ default: null
22
+ },
23
+ width: {
24
+ type: [String, Number],
25
+ default: null
26
+ }
27
+ },
28
+ render() {
29
+ const formatSize = value => {
30
+ if (typeof value === 'string') {
31
+ // If already contains unit (em, rem, px), use as is
32
+ if (value.includes('em') || value.includes('rem') || value.includes('px')) {
33
+ return value
34
+ }
35
+ // If string but no unit, treat as number
36
+ return `${parseFloat(value)}px`
37
+ }
38
+ // If number, add px
39
+ return `${value}px`
40
+ }
41
+
42
+ const height = this.height || this.size
43
+ const width = this.width || this.size
44
+
45
+ return h('i', {
46
+ class: ['f-icon', this.icon, `bg-${this.color}`],
47
+ style: {
48
+ height: formatSize(height),
49
+ width: formatSize(width),
50
+ minHeight: formatSize(height),
51
+ minWidth: formatSize(width)
52
+ }
53
+ })
54
+ }
55
+ }
56
+
57
+ // Custom icon component for Vuetify
58
+ export const forcebpmIcon = {
59
+ component: props => {
60
+ // Extract icon name from props.icon
61
+ // Example: 'f-icon:chevron-left' -> 'chevron-left'
62
+ const iconName = props.icon.replace('f-icon:', '')
63
+
64
+ return h('i', {
65
+ class: ['f-icon', iconName, props.class],
66
+ style: props.style
67
+ })
68
+ }
69
+ }
@@ -0,0 +1,115 @@
1
+ {
2
+ "tokenRefresh": "Session is refreshing... Please wait",
3
+ "login": {
4
+ "title": "Sign In",
5
+ "welcome": "Welcome! Please select a login method",
6
+ "subTitle": "Enter your login and password to access the system",
7
+ "rememberMe": "Remember me",
8
+ "login": "Login",
9
+ "loginPlaceholder": "Enter your login",
10
+ "password": "Password",
11
+ "passwordPlaceholder": "Type password",
12
+ "loggedIn": "You are already logged in!",
13
+ "loginSuccess": "Login successful",
14
+ "loginFail": "Failed to login, try again",
15
+ "loginError": "Error trying to login, contact support",
16
+ "forgotPassword": "Forgot password?",
17
+ "errorLoginOrPass": "Wrong login or password",
18
+ "loginConfirmation": "Login confirmation",
19
+ "confirmationCode": "Confirmation code"
20
+ },
21
+ "errorPage": {
22
+ "title": "Oops... Something went wrong :(",
23
+ "youCan": "however, you can",
24
+ "checkConnection": "check your internet connection and try again",
25
+ "networkError": "No connection to the server",
26
+ "error400": "Bad request",
27
+ "error404": "Page not found",
28
+ "error500": "Server error, please contact support",
29
+ "error503": "Service unavailable, please try again later",
30
+ "errorUnknown": "An unknown error occurred, please contact support"
31
+ },
32
+ "buttons": {
33
+ "share": "Share",
34
+ "collect": "Collect",
35
+ "select": "Select",
36
+ "apply": "Apply",
37
+ "cancel": "Cancel",
38
+ "login": "Sign in",
39
+ "smartID": "Smart ID",
40
+ "logout": "Logout",
41
+ "refresh": "Refresh",
42
+ "edit": "Edit",
43
+ "editParams": "Edit parameters",
44
+ "delete": "Delete",
45
+ "save": "Save",
46
+ "close": "Close",
47
+ "toBack": "Back",
48
+ "rename": "Rename",
49
+ "yes": "Yes",
50
+ "no": "No",
51
+ "home": "Go to home",
52
+ "reload": "Reload"
53
+ },
54
+ "user": {
55
+ "telephone": "Phone number",
56
+ "position": "Position",
57
+ "department": "Department",
58
+ "executor": "Executor",
59
+ "executors": "Executors",
60
+ "initiator": "Initiator",
61
+ "candidates": "Candidates",
62
+ "inform": "To attention",
63
+ "executorLists": "Executor lists",
64
+ "usersByGroup": "Users by groups",
65
+ "usersByPosition": "Users by job title",
66
+ "allUsers": "All users",
67
+ "allUsersAndGroups": "All users and groups",
68
+ "selectGroup": "Select group",
69
+ "selectAllFromList": "Select all from list",
70
+ "colorTheme": "Color theme",
71
+ "darkTheme": "Dark theme",
72
+ "version": "Version",
73
+ "delegateRights": "Delegate rights",
74
+ "delegatedRights": "Delegation of rights"
75
+ },
76
+ "notification": {
77
+ "title": "Notifications",
78
+ "unmute": "Enable pop-up notifications",
79
+ "mute": "Disable pop-up notifications",
80
+ "read": "Read",
81
+ "unread": "Unread",
82
+ "markAllAsRead": "Mark all as read",
83
+ "markAsRead": "Mark as read"
84
+ },
85
+ "tooltip": {
86
+ "actions": "Additional actions",
87
+ "filter": "Filter",
88
+ "sort": "Sort",
89
+ "search": "Search",
90
+ "calendar": "Calendar",
91
+ "clearDate": "Clear date"
92
+ },
93
+ "noData": {
94
+ "title": "No data available",
95
+ "matches": "No matches found",
96
+ "notification": "No notifications"
97
+ },
98
+ "pickers": {
99
+ "from": "From",
100
+ "to": "To",
101
+ "time": "Time",
102
+ "periodName": "Period",
103
+ "dFormat": "dd",
104
+ "mFormat": "mm",
105
+ "yFormat": "yyyy",
106
+ "hFormat": "hh",
107
+ "minFormat": "mm"
108
+ },
109
+ "pagination": {
110
+ "itemsPerPage": "Items per page",
111
+ "total": "Total items",
112
+ "of": "of",
113
+ "all": "All"
114
+ }
115
+ }
@@ -0,0 +1,7 @@
1
+ import en from './en.json'
2
+ import uk from './uk.json'
3
+ import ru from './ru.json'
4
+
5
+ export const defaultMessages = { en, uk, ru }
6
+
7
+ export { en, uk, ru }
@@ -0,0 +1,116 @@
1
+ {
2
+ "tokenRefresh": "Сеанс обновляется... Пожалуйста, подождите",
3
+ "login": {
4
+ "title": "Вход",
5
+ "welcome": "Добро пожаловать! Пожалуйста, выберите способ входа в систему",
6
+ "subTitle": "Введите ваши логин и пароль для входа в систему",
7
+ "rememberMe": "Запомнить меня",
8
+ "login": "Логин",
9
+ "loginPlaceholder": "Введите логин",
10
+ "password": "Пароль",
11
+ "passwordPlaceholder": "Введите пароль",
12
+ "loggedIn": "Вы уже вошли в систему!",
13
+ "loginSuccess": "Вход выполнен успешно",
14
+ "loginFail": "Не удалось войти в систему, попробуйте еще раз",
15
+ "loginError": "Ошибка при попытке входа в систему, обратитесь в поддержку",
16
+ "forgotPassword": "Забыли пароль?",
17
+ "errorLoginOrPass": "Неверный логин или пароль",
18
+ "loginConfirmation": "Подтверждение входа",
19
+ "confirmationCode": "Код подтверждения"
20
+ },
21
+ "errorPage": {
22
+ "title": "Упс... Что-то пошло не так :(",
23
+ "youCan": "однако вы можете",
24
+ "checkConnection": "проверьте интернет-соединение и попробуйте снова",
25
+ "networkError": "Нет подключения к серверу",
26
+ "error400": "Плохой запрос",
27
+ "error404": "Такой страницы не существует",
28
+ "error500": "Ошибка сервера, обратитесь в поддержку",
29
+ "error503": "Сервис недоступен, попробуйте позже",
30
+ "errorUnknown": "Произошла неизвестная ошибка, обратитесь в поддержку"
31
+ },
32
+ "buttons": {
33
+ "share": "Поделиться",
34
+ "collect": "Отобрать",
35
+ "select": "Выбрать",
36
+ "apply": "Применить",
37
+ "cancel": "Отмена",
38
+ "login": "Вход",
39
+ "smartID": "Smart ID",
40
+ "logout": "Выход",
41
+ "refresh": "Обновить",
42
+ "edit": "Редактировать",
43
+ "editParams": "Редактировать параметры",
44
+ "delete": "Удалить",
45
+ "save": "Сохранить",
46
+ "close": "Закрыть",
47
+ "toBack": "Назад",
48
+ "rename": "Переименовать",
49
+ "yes": "Да",
50
+ "no": "Нет",
51
+ "home": "Вернуться на главную",
52
+ "reload": "Перезагрузить"
53
+ },
54
+ "user": {
55
+ "telephone": "Номер телефона",
56
+ "position": "Должность",
57
+ "department": "Департамент",
58
+ "executor": "Исполнитель",
59
+ "executors": "Исполнители",
60
+ "candidate": "Кандидат",
61
+ "candidates": "Кандидаты",
62
+ "initiator": "Инициатор",
63
+ "inform": "К сведению",
64
+ "executorLists": "Списки исполнителей",
65
+ "usersByGroup": "Пользователи по группам",
66
+ "usersByPosition": "Пользователи по должностям",
67
+ "allUsers": "Все пользователи",
68
+ "allUsersAndGroups": "Все пользователи и группы",
69
+ "selectGroup": "Выбрать группу",
70
+ "selectAllFromList": "Выбрать всех из списка",
71
+ "colorTheme": "Цветовая тема",
72
+ "darkTheme": "Темная тема",
73
+ "version": "Версия",
74
+ "delegateRights": "Делегировать права",
75
+ "delegatedRights": "Делегирование прав"
76
+ },
77
+ "notification": {
78
+ "title": "Уведомления",
79
+ "unmute": "Включить всплывающие уведомления",
80
+ "mute": "Отключить всплывающие уведомления",
81
+ "read": "Прочитанные",
82
+ "unread": "Непрочитанные",
83
+ "markAllAsRead": "Отметить все как прочитанные",
84
+ "markAsRead": "Отметить как прочитанное"
85
+ },
86
+ "tooltip": {
87
+ "actions": "Дополнительные действия",
88
+ "filter": "Фильтр",
89
+ "sort": "Сортировка",
90
+ "search": "Поиск",
91
+ "calendar": "Календарь",
92
+ "clearDate": "Очистить дату"
93
+ },
94
+ "noData": {
95
+ "title": "Нет доступных данных",
96
+ "matches": "Совпадений не найдено",
97
+ "notification": "Нет уведомлений"
98
+ },
99
+ "pickers": {
100
+ "from": "От",
101
+ "to": "До",
102
+ "time": "Время",
103
+ "periodName": "Период",
104
+ "dFormat": "дд",
105
+ "mFormat": "мм",
106
+ "yFormat": "гггг",
107
+ "hFormat": "чч",
108
+ "minFormat": "мм"
109
+ },
110
+ "pagination": {
111
+ "itemsPerPage": "Элементов на странице",
112
+ "total": "Всего элементов",
113
+ "of": "из",
114
+ "all": "Все"
115
+ }
116
+ }