shared-ritm 1.2.52 → 1.2.54

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 (73) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/shared-ritm.es.js +4971 -4952
  3. package/dist/shared-ritm.umd.js +7 -7
  4. package/package.json +1 -1
  5. package/src/App.vue +2461 -2461
  6. package/src/api/services/AuthService.ts +58 -58
  7. package/src/api/services/ControlsService.ts +64 -64
  8. package/src/api/services/FileService.ts +15 -15
  9. package/src/api/services/TasksService.ts +137 -137
  10. package/src/api/settings/ApiService.ts +128 -128
  11. package/src/api/types/Api_Controls.ts +72 -72
  12. package/src/common/app-button/AppButton.vue +173 -173
  13. package/src/common/app-date-picker/AppDatePicker.vue +81 -81
  14. package/src/common/app-icon/AppIcon.vue +108 -108
  15. package/src/common/app-input/AppInput.vue +147 -147
  16. package/src/common/app-input-search/AppInputSearch.vue +174 -174
  17. package/src/common/app-layout/AppLayout.vue +84 -84
  18. package/src/common/app-layout/components/AppLayoutHeader.vue +246 -246
  19. package/src/common/app-layout/components/AppLayoutPage.vue +16 -16
  20. package/src/common/app-loader/index.vue +43 -43
  21. package/src/common/app-page-layout/AppPageLayout.vue +122 -122
  22. package/src/common/app-sidebar/AppSidebar.vue +168 -168
  23. package/src/common/app-sidebar/components/SidebarMenu.vue +37 -37
  24. package/src/common/app-table/AppTable.vue +2 -2
  25. package/src/common/app-table/AppTableLayout.vue +24 -24
  26. package/src/common/app-table/components/ModalSelect.vue +264 -215
  27. package/src/common/app-table/components/TableModal.vue +357 -357
  28. package/src/common/app-table/controllers/useBaseTable.ts +42 -42
  29. package/src/global.d.ts +1 -1
  30. package/src/icons/components/arrow-down-icon.vue +25 -25
  31. package/src/icons/components/arrow-frame-icon.vue +19 -19
  32. package/src/icons/components/arrow-square.vue +22 -22
  33. package/src/icons/header/NotificationIcon.vue +18 -18
  34. package/src/icons/header/PersonIcon.vue +11 -11
  35. package/src/icons/header/SettingIcon.vue +14 -14
  36. package/src/icons/header/flashIcon.vue +24 -24
  37. package/src/icons/header/searchStatusIcon.vue +24 -24
  38. package/src/icons/header/smallCapsIcon.vue +34 -34
  39. package/src/icons/sidebar/assign-module-icon.vue +36 -36
  40. package/src/icons/sidebar/instrument-history-icon.vue +32 -32
  41. package/src/icons/sidebar/instrument-order-icon.vue +38 -38
  42. package/src/icons/sidebar/instrument-work-zone-icon.vue +18 -18
  43. package/src/icons/sidebar/instruments-icon.vue +45 -45
  44. package/src/icons/sidebar/logo-icon.vue +15 -15
  45. package/src/icons/sidebar/logout-icon.vue +13 -13
  46. package/src/icons/sidebar/modules-icon.vue +16 -16
  47. package/src/icons/sidebar/notifications-icon.vue +24 -24
  48. package/src/icons/sidebar/order-icon.vue +44 -44
  49. package/src/icons/sidebar/pass-icon.vue +38 -38
  50. package/src/icons/sidebar/positions-icon.vue +42 -42
  51. package/src/icons/sidebar/preorder-icon.vue +19 -19
  52. package/src/icons/sidebar/projects-icon.vue +31 -31
  53. package/src/icons/sidebar/repair-object-icon.vue +18 -18
  54. package/src/icons/sidebar/repairs-icon.vue +20 -20
  55. package/src/icons/sidebar/roles-icon.vue +26 -26
  56. package/src/icons/sidebar/status-history-icon.vue +24 -24
  57. package/src/icons/sidebar/tasks-icon.vue +28 -28
  58. package/src/icons/sidebar/tasks_tasks-icon.vue +39 -39
  59. package/src/icons/sidebar/tasks_today-icon.vue +27 -27
  60. package/src/icons/sidebar/teams-icon.vue +32 -32
  61. package/src/icons/sidebar/user-icon.vue +18 -18
  62. package/src/icons/sidebar/users-icon.vue +46 -46
  63. package/src/icons/sidebar/videosources-icon.vue +19 -19
  64. package/src/icons/sidebar/videowall-icon.vue +13 -13
  65. package/src/icons/sidebar/videozones-icon.vue +21 -21
  66. package/src/icons/sidebar/warehouses-icon.vue +43 -43
  67. package/src/icons/sidebar/workshop-icon.vue +100 -100
  68. package/src/icons/sidebar/workzones-icon.vue +22 -22
  69. package/src/index.ts +84 -84
  70. package/src/main.ts +28 -28
  71. package/src/quasar-user-options.ts +17 -17
  72. package/src/router/index.ts +10 -10
  73. package/src/shims-vue.d.ts +5 -5
@@ -1,27 +1,3 @@
1
- <script setup lang="ts">
2
- import AppTable from './AppTable.vue'
3
- import AppTablePagination from '../app-table/components/TablePagination.vue'
4
- import AppTableSearch from '../app-table/components/TableSearch.vue'
5
- import { defineProps, defineEmits } from 'vue'
6
-
7
- const emit = defineEmits<{
8
- 'update:selectedRows': [rows: any[]]
9
- }>()
10
- const props = defineProps<{
11
- search: string
12
- loading: boolean
13
- currentPage: number
14
- totalPages: number
15
- tableProps: any
16
- tableEvents: any
17
- onSearch: (val: string) => void
18
- onPageChange: (page: number) => void
19
- actionsSlot?: boolean
20
- modalSlot?: boolean
21
- selectedRows: any[]
22
- }>()
23
- </script>
24
-
25
1
  <template>
26
2
  <div class="table-layout">
27
3
  <div class="table-controls">
@@ -56,6 +32,30 @@ const props = defineProps<{
56
32
  </div>
57
33
  </template>
58
34
 
35
+ <script setup lang="ts">
36
+ import AppTable from './AppTable.vue'
37
+ import AppTablePagination from '../app-table/components/TablePagination.vue'
38
+ import AppTableSearch from '../app-table/components/TableSearch.vue'
39
+ import { defineProps, defineEmits } from 'vue'
40
+
41
+ const emit = defineEmits<{
42
+ 'update:selectedRows': [rows: any[]]
43
+ }>()
44
+ const props = defineProps<{
45
+ search: string
46
+ loading: boolean
47
+ currentPage: number
48
+ totalPages: number
49
+ tableProps: any
50
+ tableEvents: any
51
+ onSearch: (val: string) => void
52
+ onPageChange: (page: number) => void
53
+ actionsSlot?: boolean
54
+ modalSlot?: boolean
55
+ selectedRows: any[]
56
+ }>()
57
+ </script>
58
+
59
59
  <style scoped lang="scss">
60
60
  .table-layout {
61
61
  height: calc(100vh - 100px);
@@ -1,215 +1,264 @@
1
- <template>
2
- <label class="field-label">
3
- {{ label }}
4
- <span v-if="rules?.length && isShowRequired" class="required">*</span>
5
- </label>
6
- <q-select
7
- ref="select"
8
- v-model="selected"
9
- :options="filteredOptions"
10
- :disable="isDisabled"
11
- :multiple="multiple"
12
- :popup-content-class="'custom-select-menu'"
13
- :hide-selected="!showChip"
14
- :placeholder="placeholder"
15
- :loading="loading"
16
- :option-value="optionValue || 'value'"
17
- :option-label="optionLabel || 'label'"
18
- emit-value
19
- filled
20
- map-options
21
- stack-label
22
- use-input
23
- use-chips
24
- input-debounce="100"
25
- autocomplete=""
26
- :rules="rules"
27
- @virtual-scroll="onScroll"
28
- @filter="filterFn"
29
- >
30
- <template v-if="multiple || showChip" #selected-item="scope">
31
- <q-chip
32
- v-if="scope.opt"
33
- removable
34
- :tabindex="scope.tabindex"
35
- :style="{ backgroundColor: chipColor }"
36
- icon-remove="close"
37
- text-color="secondary"
38
- @remove="scope.removeAtIndex(scope.index)"
39
- >
40
- {{ scope.opt[optionLabel || 'label'] }}
41
- </q-chip>
42
- </template>
43
-
44
- <template #append>
45
- <q-icon
46
- v-if="!isDisabled && selected && selected.length"
47
- name="close"
48
- class="cursor-pointer clear-input"
49
- @click.stop="handleClear"
50
- />
51
- </template>
52
-
53
- <template #no-option>
54
- <q-item>{{ emptyText }}</q-item>
55
- </template>
56
-
57
- <template #option="scope">
58
- <q-item v-if="scope.opt.__loading" class="q-py-md q-ml-md">
59
- <q-spinner-dots size="24px" color="primary" />
60
- </q-item>
61
- <q-item v-else v-bind="scope.itemProps">
62
- <q-item-section>{{ scope.opt[optionLabel || 'label'] }}</q-item-section>
63
- </q-item>
64
- </template>
65
- </q-select>
66
- </template>
67
-
68
- <script setup lang="ts">
69
- import { computed, defineEmits, defineProps, ref, Ref } from 'vue'
70
-
71
- type Option = Record<string, any>
72
-
73
- interface AppQSelectProps {
74
- modelValue: any
75
- options: Option[]
76
- placeholder: string | undefined
77
- emptyText: string
78
- optionLabel?: string
79
- optionValue?: string
80
- label?: string
81
- multiple?: boolean
82
- loading?: boolean
83
- isShowRequired?: boolean
84
- isDisabled?: boolean
85
- isSearch?: boolean
86
- showChip?: boolean
87
- chipColor?: string
88
- height?: string
89
- borderColor?: string
90
- borderRadius?: string
91
- menuWidth?: string
92
- rules?: ((val: any) => boolean | string)[]
93
- }
94
-
95
- const props = defineProps<AppQSelectProps>()
96
- const emit = defineEmits(['update:modelValue', 'update:scroll', 'update:search', 'clear'])
97
-
98
- const select = ref({})
99
- const lcText: Ref<string> = ref('')
100
-
101
- const selected = computed({
102
- get() {
103
- return props.modelValue
104
- },
105
- set(value) {
106
- emit('update:modelValue', value)
107
- },
108
- })
109
-
110
- function handleClear() {
111
- selected.value = props.multiple ? [] : null
112
- lcText.value = ''
113
- emit('update:modelValue', selected.value)
114
- emit('clear')
115
- }
116
-
117
- const filteredOptions = computed(() => {
118
- const baseOptions = props.options.filter(x => x[props?.optionLabel || 'label'].toLowerCase().includes(lcText.value))
119
-
120
- if (props.loading) {
121
- return [
122
- ...baseOptions,
123
- {
124
- __loading: true,
125
- label: '__loading__',
126
- value: '__loading__',
127
- },
128
- ]
129
- }
130
-
131
- return baseOptions
132
- })
133
-
134
- function filterFn(val: string, update: (cb: () => void) => void) {
135
- debouncedFilter(val, update)
136
- }
137
-
138
- const debouncedFilter = debounce((val: string, update: (cb: () => void) => void) => {
139
- emit('update:search', val)
140
- update(() => {
141
- lcText.value = val.toLowerCase()
142
- })
143
- }, 500)
144
-
145
- function onScroll({ to, ref: qSelectRef }) {
146
- const totalOptions = qSelectRef.options.length
147
- if (to >= totalOptions - 1 && !lcText.value) {
148
- emit('update:scroll')
149
- }
150
- }
151
-
152
- function debounce<T>(fn: T, ms) {
153
- let timeoutId
154
-
155
- return function (...args) {
156
- clearTimeout(timeoutId)
157
-
158
- return new Promise(resolve => {
159
- timeoutId = setTimeout(() => {
160
- resolve(fn(...args))
161
- }, ms)
162
- })
163
- }
164
- }
165
- </script>
166
-
167
- <style lang="scss" scoped>
168
- .field-label {
169
- font-size: 14px;
170
- font-weight: 700;
171
- color: #7d8592;
172
- }
173
- .required {
174
- color: #f65160;
175
- font-weight: bold;
176
- }
177
-
178
- ::v-deep(.q-placeholder) {
179
- color: #7d8592;
180
- }
181
- ::v-deep(.q-field__control) {
182
- border-radius: 8px;
183
- border: 1px solid #d8e0f0;
184
- background: #fff;
185
- box-shadow: 0px 1px 2px 0px rgba(184, 200, 224, 0.22);
186
- }
187
- ::v-deep(.q-field--filled.q-field--highlighted .q-field__control:before),
188
- ::v-deep(.q-field--filled .q-field__control:before) {
189
- background: #fff !important;
190
- border: none;
191
- }
192
- ::v-deep(.q-field--with-bottom) {
193
- padding-bottom: 0;
194
- }
195
- ::v-deep(.q-field__bottom) {
196
- padding: 0;
197
- }
198
- .clear-input {
199
- color: #d8e0f0;
200
- }
201
- ::v-deep(.q-chip) {
202
- border-radius: 4px;
203
- background: #e9eff9;
204
- color: #1d425d;
205
- font-family: NunitoSansFont, sans-serif;
206
- font-size: 14px;
207
- height: 30px;
208
- line-height: 30px;
209
- padding: 0 15px;
210
- .q-chip__icon {
211
- color: #3f8cff;
212
- margin-left: 5px;
213
- }
214
- }
215
- </style>
1
+ <template>
2
+ <label class="field-label">
3
+ {{ label }}
4
+ <span v-if="rules?.length && isShowRequired" class="required">*</span>
5
+ </label>
6
+
7
+ <q-select
8
+ ref="select"
9
+ v-model="selected"
10
+ :options="filteredOptions"
11
+ :disable="isDisabled"
12
+ :multiple="multiple"
13
+ :popup-content-class="'custom-select-menu'"
14
+ :hide-selected="!showChip"
15
+ :placeholder="placeholder"
16
+ :loading="loading"
17
+ :option-value="optionValue || 'value'"
18
+ :option-label="optionLabel || 'label'"
19
+ emit-value
20
+ filled
21
+ map-options
22
+ stack-label
23
+ use-input
24
+ use-chips
25
+ input-debounce="100"
26
+ autocomplete=""
27
+ :rules="rules"
28
+ @virtual-scroll="onScroll"
29
+ @filter="filterFn"
30
+ >
31
+ <template v-if="multiple || showChip" #selected-item="scope">
32
+ <q-chip
33
+ v-if="scope.opt"
34
+ removable
35
+ :tabindex="scope.tabindex"
36
+ :style="{ backgroundColor: chipColor }"
37
+ icon-remove="close"
38
+ text-color="secondary"
39
+ @remove="scope.removeAtIndex(scope.index)"
40
+ >
41
+ {{ scope.opt[optionLabel || 'label'] }}
42
+ </q-chip>
43
+ </template>
44
+
45
+ <template #append>
46
+ <q-icon
47
+ v-if="!isDisabled && selected && selected.length"
48
+ name="close"
49
+ class="cursor-pointer clear-input"
50
+ @click.stop="handleClear"
51
+ />
52
+ </template>
53
+
54
+ <template #no-option>
55
+ <div class="q-pa-sm">
56
+ <q-item>
57
+ <q-item-section class="wrapper-empty-text">
58
+ {{ emptyText }}
59
+ <button
60
+ v-if="allowCreate && internalSearch && internalSearch.trim()"
61
+ class="add-new-items"
62
+ @click="handleCreateFromSearch"
63
+ >
64
+ Добавить
65
+ </button>
66
+ </q-item-section>
67
+ </q-item>
68
+ </div>
69
+ </template>
70
+
71
+ <template #option="scope">
72
+ <q-item v-if="scope.opt.__loading" class="q-py-md q-ml-md">
73
+ <q-spinner-dots size="24px" color="primary" />
74
+ </q-item>
75
+ <q-item v-else v-bind="scope.itemProps">
76
+ <q-item-section>{{ scope.opt[optionLabel || 'label'] }}</q-item-section>
77
+ </q-item>
78
+ </template>
79
+ </q-select>
80
+ </template>
81
+
82
+ <script setup lang="ts">
83
+ import { computed, defineEmits, defineProps, ref, Ref } from 'vue'
84
+ type Option = Record<string, any>
85
+
86
+ interface AppQSelectProps {
87
+ modelValue: any
88
+ options: Option[]
89
+ placeholder: string | undefined
90
+ emptyText: string
91
+ optionLabel?: string
92
+ optionValue?: string
93
+ label?: string
94
+ multiple?: boolean
95
+ loading?: boolean
96
+ isShowRequired?: boolean
97
+ isDisabled?: boolean
98
+ allowCreate?: boolean
99
+ isSearch?: boolean
100
+ showChip?: boolean
101
+ chipColor?: string
102
+ height?: string
103
+ borderColor?: string
104
+ borderRadius?: string
105
+ menuWidth?: string
106
+ rules?: ((val: any) => boolean | string)[]
107
+ }
108
+
109
+ const props = defineProps<AppQSelectProps>()
110
+ const emit = defineEmits(['update:modelValue', 'update:scroll', 'update:search', 'clear', 'create'])
111
+
112
+ const select = ref({})
113
+ const lcText: Ref<string> = ref('')
114
+ const internalSearch = ref('')
115
+
116
+ const selected = computed({
117
+ get() {
118
+ return props.modelValue
119
+ },
120
+ set(value) {
121
+ emit('update:modelValue', value)
122
+ },
123
+ })
124
+
125
+ function handleClear() {
126
+ selected.value = props.multiple ? [] : null
127
+ lcText.value = ''
128
+ emit('update:modelValue', selected.value)
129
+ emit('clear')
130
+ }
131
+
132
+ const filteredOptions = computed(() => {
133
+ const labelKey = props.optionLabel || 'label'
134
+
135
+ const baseOptions = props.options.filter(x => {
136
+ const label = x[labelKey]
137
+ return typeof label === 'string' && label.toLowerCase().includes(lcText.value)
138
+ })
139
+
140
+ if (props.loading) {
141
+ return [
142
+ ...baseOptions,
143
+ {
144
+ __loading: true,
145
+ label: '__loading__',
146
+ value: '__loading__',
147
+ },
148
+ ]
149
+ }
150
+
151
+ return baseOptions
152
+ })
153
+
154
+ function handleCreateFromSearch() {
155
+ const labelKey = props.optionLabel || 'label'
156
+ const valueKey = props.optionValue || 'value'
157
+
158
+ const trimmed = internalSearch.value?.trim()
159
+ if (!trimmed) return
160
+
161
+ const newOption = {
162
+ [labelKey]: trimmed,
163
+ [valueKey]: trimmed,
164
+ }
165
+ emit('create', newOption)
166
+ handleClear()
167
+ }
168
+
169
+ function filterFn(val: string, update: (cb: () => void) => void) {
170
+ debouncedFilter(val, update)
171
+ }
172
+
173
+ const debouncedFilter = debounce((val: string, update: (cb: () => void) => void) => {
174
+ internalSearch.value = val
175
+ emit('update:search', val)
176
+ update(() => {
177
+ lcText.value = val.toLowerCase()
178
+ })
179
+ }, 500)
180
+
181
+ function onScroll({ to, ref: qSelectRef }) {
182
+ const totalOptions = qSelectRef.options.length
183
+ if (to >= totalOptions - 1 && !lcText.value) {
184
+ emit('update:scroll')
185
+ }
186
+ }
187
+
188
+ function debounce<T>(fn: T, ms) {
189
+ let timeoutId
190
+ return function (...args) {
191
+ clearTimeout(timeoutId)
192
+ return new Promise(resolve => {
193
+ timeoutId = setTimeout(() => {
194
+ resolve(fn(...args))
195
+ }, ms)
196
+ })
197
+ }
198
+ }
199
+ </script>
200
+
201
+ <style lang="scss" scoped>
202
+ .wrapper-empty-text {
203
+ display: flex;
204
+ align-items: center;
205
+ justify-content: space-between;
206
+ flex-direction: row;
207
+ .add-new-items {
208
+ background: #3f8cff;
209
+ color: #fff;
210
+ outline: none;
211
+ border: none;
212
+ border-radius: 4px;
213
+ padding: 5px 10px;
214
+ cursor: pointer;
215
+ }
216
+ }
217
+ .field-label {
218
+ font-size: 14px;
219
+ font-weight: 700;
220
+ color: #7d8592;
221
+ }
222
+ .required {
223
+ color: #f65160;
224
+ font-weight: bold;
225
+ }
226
+
227
+ ::v-deep(.q-placeholder) {
228
+ color: #7d8592;
229
+ }
230
+ ::v-deep(.q-field__control) {
231
+ border-radius: 8px;
232
+ border: 1px solid #d8e0f0;
233
+ background: #fff;
234
+ box-shadow: 0px 1px 2px 0px rgba(184, 200, 224, 0.22);
235
+ }
236
+ ::v-deep(.q-field--filled.q-field--highlighted .q-field__control:before),
237
+ ::v-deep(.q-field--filled .q-field__control:before) {
238
+ background: #fff !important;
239
+ border: none;
240
+ }
241
+ ::v-deep(.q-field--with-bottom) {
242
+ padding-bottom: 0;
243
+ }
244
+ ::v-deep(.q-field__bottom) {
245
+ padding: 0;
246
+ }
247
+ .clear-input {
248
+ color: #d8e0f0;
249
+ }
250
+ ::v-deep(.q-chip) {
251
+ border-radius: 4px;
252
+ background: #e9eff9;
253
+ color: #1d425d;
254
+ font-family: NunitoSansFont, sans-serif;
255
+ font-size: 14px;
256
+ height: 30px;
257
+ line-height: 30px;
258
+ padding: 0 15px;
259
+ .q-chip__icon {
260
+ color: #3f8cff;
261
+ margin-left: 5px;
262
+ }
263
+ }
264
+ </style>