shared-ritm 1.2.54 → 1.2.55

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 +4778 -4771
  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 +72 -72
  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 +8 -5
  26. package/src/common/app-table/AppTableLayout.vue +24 -24
  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
@@ -19,7 +19,7 @@ interface TableEmits {
19
19
  const emit = defineEmits<TableEmits>()
20
20
 
21
21
  const props = defineProps<{
22
- rows: any[]
22
+ rows: Ref<any[]>
23
23
  columns: any[]
24
24
  columnFilters: Ref<Record<string, string | string[] | undefined>>
25
25
  filterMenus: Ref<Record<string, boolean>>
@@ -63,7 +63,7 @@ watch(
63
63
  <q-page class="flex flex-col" style="min-height: 100%">
64
64
  <q-table
65
65
  v-model:selected="selected"
66
- :rows="rows"
66
+ :rows="rows.value"
67
67
  :columns="columns"
68
68
  row-key="id"
69
69
  flat
@@ -97,9 +97,12 @@ watch(
97
97
  >
98
98
  <filter-icon class="q-mr-xs" />
99
99
  <span>{{ col.label }}</span>
100
- <template v-if="col.filterType === 'multi' && columnFilters.value[col.name]?.length">
101
- <div class="label-length">- {{ columnFilters.value[col.name]?.length }}</div>
102
- </template>
100
+ <div
101
+ v-if="['multi', 'single'].includes(col.filterType) && columnFilters.value[col.name]?.length"
102
+ class="label-length"
103
+ >
104
+ - {{ col.filterType === 'multi' ? columnFilters.value[col.name]?.length : 1 }}
105
+ </div>
103
106
  </div>
104
107
  <div v-else>{{ col.label }}</div>
105
108
 
@@ -1,3 +1,27 @@
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
+
1
25
  <template>
2
26
  <div class="table-layout">
3
27
  <div class="table-controls">
@@ -32,30 +56,6 @@
32
56
  </div>
33
57
  </template>
34
58
 
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,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>