shared-ritm 1.2.55 → 1.2.56

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 (74) hide show
  1. package/dist/index.css +1 -1
  2. package/dist/shared-ritm.es.js +4770 -4777
  3. package/dist/shared-ritm.umd.js +7 -7
  4. package/dist/types/api/types/Api_Controls.d.ts +6 -6
  5. package/package.json +1 -1
  6. package/src/App.vue +2461 -2461
  7. package/src/api/services/AuthService.ts +58 -58
  8. package/src/api/services/ControlsService.ts +64 -64
  9. package/src/api/services/FileService.ts +15 -15
  10. package/src/api/services/TasksService.ts +137 -137
  11. package/src/api/settings/ApiService.ts +128 -128
  12. package/src/api/types/Api_Controls.ts +3 -3
  13. package/src/common/app-button/AppButton.vue +173 -173
  14. package/src/common/app-date-picker/AppDatePicker.vue +81 -81
  15. package/src/common/app-icon/AppIcon.vue +108 -108
  16. package/src/common/app-input/AppInput.vue +147 -147
  17. package/src/common/app-input-search/AppInputSearch.vue +174 -174
  18. package/src/common/app-layout/AppLayout.vue +84 -84
  19. package/src/common/app-layout/components/AppLayoutHeader.vue +246 -246
  20. package/src/common/app-layout/components/AppLayoutPage.vue +16 -16
  21. package/src/common/app-loader/index.vue +43 -43
  22. package/src/common/app-page-layout/AppPageLayout.vue +122 -122
  23. package/src/common/app-sidebar/AppSidebar.vue +168 -168
  24. package/src/common/app-sidebar/components/SidebarMenu.vue +37 -37
  25. package/src/common/app-table/AppTable.vue +244 -244
  26. package/src/common/app-table/AppTableLayout.vue +104 -104
  27. package/src/common/app-table/components/ModalSelect.vue +264 -264
  28. package/src/common/app-table/components/TableModal.vue +357 -357
  29. package/src/common/app-table/controllers/useBaseTable.ts +42 -42
  30. package/src/global.d.ts +1 -1
  31. package/src/icons/components/arrow-down-icon.vue +25 -25
  32. package/src/icons/components/arrow-frame-icon.vue +19 -19
  33. package/src/icons/components/arrow-square.vue +22 -22
  34. package/src/icons/header/NotificationIcon.vue +18 -18
  35. package/src/icons/header/PersonIcon.vue +11 -11
  36. package/src/icons/header/SettingIcon.vue +14 -14
  37. package/src/icons/header/flashIcon.vue +24 -24
  38. package/src/icons/header/searchStatusIcon.vue +24 -24
  39. package/src/icons/header/smallCapsIcon.vue +34 -34
  40. package/src/icons/sidebar/assign-module-icon.vue +36 -36
  41. package/src/icons/sidebar/instrument-history-icon.vue +32 -32
  42. package/src/icons/sidebar/instrument-order-icon.vue +38 -38
  43. package/src/icons/sidebar/instrument-work-zone-icon.vue +18 -18
  44. package/src/icons/sidebar/instruments-icon.vue +45 -45
  45. package/src/icons/sidebar/logo-icon.vue +15 -15
  46. package/src/icons/sidebar/logout-icon.vue +13 -13
  47. package/src/icons/sidebar/modules-icon.vue +16 -16
  48. package/src/icons/sidebar/notifications-icon.vue +24 -24
  49. package/src/icons/sidebar/order-icon.vue +44 -44
  50. package/src/icons/sidebar/pass-icon.vue +38 -38
  51. package/src/icons/sidebar/positions-icon.vue +42 -42
  52. package/src/icons/sidebar/preorder-icon.vue +19 -19
  53. package/src/icons/sidebar/projects-icon.vue +31 -31
  54. package/src/icons/sidebar/repair-object-icon.vue +18 -18
  55. package/src/icons/sidebar/repairs-icon.vue +20 -20
  56. package/src/icons/sidebar/roles-icon.vue +26 -26
  57. package/src/icons/sidebar/status-history-icon.vue +24 -24
  58. package/src/icons/sidebar/tasks-icon.vue +28 -28
  59. package/src/icons/sidebar/tasks_tasks-icon.vue +39 -39
  60. package/src/icons/sidebar/tasks_today-icon.vue +27 -27
  61. package/src/icons/sidebar/teams-icon.vue +32 -32
  62. package/src/icons/sidebar/user-icon.vue +18 -18
  63. package/src/icons/sidebar/users-icon.vue +46 -46
  64. package/src/icons/sidebar/videosources-icon.vue +19 -19
  65. package/src/icons/sidebar/videowall-icon.vue +13 -13
  66. package/src/icons/sidebar/videozones-icon.vue +21 -21
  67. package/src/icons/sidebar/warehouses-icon.vue +43 -43
  68. package/src/icons/sidebar/workshop-icon.vue +100 -100
  69. package/src/icons/sidebar/workzones-icon.vue +22 -22
  70. package/src/index.ts +84 -84
  71. package/src/main.ts +28 -28
  72. package/src/quasar-user-options.ts +17 -17
  73. package/src/router/index.ts +10 -10
  74. package/src/shims-vue.d.ts +5 -5
@@ -1,264 +1,264 @@
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>
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>