@bildvitta/quasar-ui-asteroid 3.5.0-beta.9 → 3.6.0-beta.0

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 (69) hide show
  1. package/package.json +1 -1
  2. package/src/components/actions/QasActions.vue +32 -6
  3. package/src/components/actions/QasActions.yml +11 -1
  4. package/src/components/actions-menu/QasActionsMenu.vue +28 -11
  5. package/src/components/actions-menu/QasActionsMenu.yml +13 -4
  6. package/src/components/alert/QasAlert.vue +1 -1
  7. package/src/components/app-bar/QasAppBar.vue +7 -3
  8. package/src/components/app-menu/QasAppMenu.vue +55 -10
  9. package/src/components/app-user/QasAppUser.vue +8 -4
  10. package/src/components/avatar/QasAvatar.vue +1 -1
  11. package/src/components/avatar/QasAvatar.yml +1 -1
  12. package/src/components/badge/QasBadge.vue +34 -0
  13. package/src/components/badge/QasBadge.yml +28 -0
  14. package/src/components/card/QasCard.vue +2 -2
  15. package/src/components/copy/QasCopy.vue +1 -1
  16. package/src/components/copy/QasCopy.yml +1 -1
  17. package/src/components/date-time-input/QasDateTimeInput.vue +92 -10
  18. package/src/components/delete/QasDelete.vue +0 -1
  19. package/src/components/dialog/QasDialog.vue +56 -28
  20. package/src/components/dialog/QasDialog.yml +0 -9
  21. package/src/components/filters/QasFilters.vue +82 -67
  22. package/src/components/form-view/QasFormView.vue +0 -1
  23. package/src/components/gallery/QasGallery.vue +3 -3
  24. package/src/components/gallery/private/PvGalleryCarouselDialog.vue +3 -3
  25. package/src/components/header-actions/QasHeaderActions.vue +62 -0
  26. package/src/components/header-actions/QasHeaderActions.yml +26 -0
  27. package/src/components/list-items/QasListItems.vue +1 -1
  28. package/src/components/list-items/QasListItems.yml +1 -1
  29. package/src/components/nested-fields/QasNestedFields.vue +4 -4
  30. package/src/components/nested-fields/QasNestedFields.yml +2 -2
  31. package/src/components/numeric-input/QasNumericInput.vue +9 -0
  32. package/src/components/page-header/QasPageHeader.vue +92 -17
  33. package/src/components/page-header/QasPageHeader.yml +19 -1
  34. package/src/components/pagination/QasPagination.vue +12 -1
  35. package/src/components/password-input/QasPasswordInput.vue +1 -1
  36. package/src/components/search-box/QasSearchBox.vue +3 -4
  37. package/src/components/search-box/QasSearchBox.yml +1 -1
  38. package/src/components/select/QasSelect.vue +6 -6
  39. package/src/components/select/QasSelect.yml +1 -1
  40. package/src/components/select-list/QasSelectList.vue +1 -1
  41. package/src/components/signature-pad/QasSignaturePad.vue +1 -1
  42. package/src/components/signature-uploader/QasSignatureUploader.vue +7 -8
  43. package/src/components/single-view/QasSingleView.vue +1 -1
  44. package/src/components/status/QasStatus.vue +32 -0
  45. package/src/components/status/QasStatus.yml +10 -0
  46. package/src/components/table-generator/QasTableGenerator.vue +29 -4
  47. package/src/components/tabs-generator/QasTabsGenerator.vue +140 -37
  48. package/src/components/tabs-generator/QasTabsGenerator.yml +4 -24
  49. package/src/components/text-truncate/QasTextTruncate.vue +24 -10
  50. package/src/components/transfer/QasTransfer.vue +2 -2
  51. package/src/components/tree-generator/QasTreeGenerator.vue +4 -5
  52. package/src/components/uploader/QasUploader.vue +8 -8
  53. package/src/components/welcome/QasWelcome.vue +108 -0
  54. package/src/components/welcome/QasWelcome.yml +14 -0
  55. package/src/components/welcome/private/PvWelcomeShortcutCard.vue +58 -0
  56. package/src/css/components/base.scss +8 -0
  57. package/src/css/components/item.scss +8 -3
  58. package/src/css/mixins/index.scss +1 -0
  59. package/src/css/mixins/set-typography.scss +8 -0
  60. package/src/css/variables/index.scss +1 -0
  61. package/src/css/variables/shadow.scss +3 -0
  62. package/src/css/variables/spacing.scss +15 -0
  63. package/src/css/variables/typography.scss +12 -12
  64. package/src/index.scss +1 -1
  65. package/src/mixins/delete.js +0 -1
  66. package/src/plugins/notify-error/NotifyError.js +1 -1
  67. package/src/plugins/notify-success/NotifySuccess.js +1 -1
  68. package/src/shared/date-config.js +26 -0
  69. package/src/vue-plugin.js +12 -0
@@ -1,52 +1,46 @@
1
1
  <template>
2
- <q-tabs v-model="model" :active-color="activeColor" :indicator-color="indicatorColor" outside-arrows>
3
- <slot v-for="(tab, key) in formattedTabs" :item="tab" :name="`tab-${tab.value}`">
4
- <q-tab :key="key" v-bind="tab" :class="tabClass" :label="tab.label" :name="tab.value">
5
- <slot :item="tab" :name="`tab-after-${tab.value}`">
6
- <q-badge v-if="counters[tab.value]" :label="counters[tab.value]" v-bind="defaultCounterProps" />
7
- </slot>
8
- </q-tab>
9
- </slot>
10
- </q-tabs>
2
+ <div class="qas-tabs-generator">
3
+ <q-tabs v-model="model" active-color="primary" align="left" :breakpoint="0" content-class="text-grey-8" dense inline-label left-icon="sym_r_chevron_left" outside-arrows right-icon="sym_r_chevron_right">
4
+ <slot v-for="(tab, key) in formattedTabs" :item="tab" :name="`tab-${tab.value}`">
5
+ <q-tab :key="key" v-bind="getTabProps(tab)" class="text-body1" :name="tab.value" no-caps :ripple="false">
6
+ <slot :item="tab" :name="`tab-after-${tab.value}`">
7
+ <q-icon v-if="tab.icon" :name="tab.icon" size="sm" />
8
+
9
+ <qas-status v-if="tab.status" :color="tab.status" />
10
+
11
+ <div class="q-ml-xs">
12
+ {{ getFormattedLabel(tab) }}
13
+ </div>
14
+ </slot>
15
+ </q-tab>
16
+ </slot>
17
+ </q-tabs>
18
+ </div>
11
19
  </template>
12
20
 
13
21
  <script>
22
+ import QasStatus from '../status/QasStatus.vue'
23
+
14
24
  import { extend } from 'quasar'
15
25
 
16
26
  export default {
17
27
  name: 'QasTabsGenerator',
18
28
 
19
- props: {
20
- activeColor: {
21
- default: 'primary',
22
- type: String
23
- },
24
-
25
- counterProps: {
26
- default: () => ({}),
27
- type: Object
28
- },
29
+ components: {
30
+ QasStatus
31
+ },
29
32
 
33
+ props: {
30
34
  counters: {
31
35
  default: () => ({}),
32
36
  type: Object
33
37
  },
34
38
 
35
- indicatorColor: {
36
- default: 'primary',
37
- type: String
38
- },
39
-
40
39
  modelValue: {
41
40
  default: '',
42
41
  type: [String, Number]
43
42
  },
44
43
 
45
- tabClass: {
46
- default: 'text-primary',
47
- type: String
48
- },
49
-
50
44
  tabs: {
51
45
  default: () => ({}),
52
46
  required: true,
@@ -57,14 +51,6 @@ export default {
57
51
  emits: ['update:modelValue'],
58
52
 
59
53
  computed: {
60
- defaultCounterProps () {
61
- return {
62
- color: 'negative',
63
- floating: true,
64
- ...this.counterProps
65
- }
66
- },
67
-
68
54
  formattedTabs () {
69
55
  const tabs = extend(true, {}, this.tabs)
70
56
 
@@ -83,9 +69,126 @@ export default {
83
69
  },
84
70
 
85
71
  set (value) {
72
+ const currentTab = Array.isArray(this.tabs)
73
+ ? this.tabs.find(tab => tab?.value === value)
74
+ : this.formattedTabs[value]
75
+
76
+ if (currentTab?.disabled) return
77
+
86
78
  this.$emit('update:modelValue', value)
87
79
  }
88
80
  }
81
+ },
82
+
83
+ methods: {
84
+ getFormattedLabel ({ label, counter, value }) {
85
+ const normalizedCount = this.counters[value] || counter
86
+
87
+ if (!normalizedCount) return label
88
+
89
+ const countString = String(normalizedCount)
90
+
91
+ return `${label} (${countString.padStart(2, '0')})`
92
+ },
93
+
94
+ getTabProps (tab) {
95
+ const { icon, label, ...payload } = tab
96
+ return payload
97
+ }
89
98
  }
90
99
  }
91
100
  </script>
101
+
102
+ <style lang="scss">
103
+ .qas-tabs-generator {
104
+ .q-tabs {
105
+ &--scrollable {
106
+ .q-tab {
107
+ &:first-child {
108
+ padding-left: var(--qas-spacing-xs);
109
+ }
110
+
111
+ &:last-child {
112
+ padding-right: var(--qas-spacing-xs);
113
+ }
114
+ }
115
+ }
116
+
117
+ .q-tab {
118
+ &--inactive {
119
+ opacity: 1;
120
+ }
121
+
122
+ &__content {
123
+ position: relative;
124
+
125
+ &::before {
126
+ background: var(--q-primary);
127
+ bottom: 0;
128
+ content: '';
129
+ height: 2px;
130
+ left: 0;
131
+ position: absolute;
132
+ right: 0;
133
+ transform: scale(0);
134
+ transition: transform var(--qas-generic-transition);
135
+ }
136
+ }
137
+
138
+ &--active {
139
+ font-weight: 600;
140
+
141
+ .q-tab__content {
142
+ position: relative;
143
+
144
+ &::before {
145
+ transform: scale(100%);
146
+ }
147
+ }
148
+ }
149
+
150
+ &:not(.q-tabs--scrollable .q-tab):first-child {
151
+ padding-left: 0;
152
+ }
153
+
154
+ &:not(.q-tabs--scrollable .q-tab):last-child {
155
+ padding-right: 0;
156
+ }
157
+
158
+ &:not(&--active) {
159
+ transition: color var(--qas-generic-transition);
160
+
161
+ &:not([disabled]):hover {
162
+ color: var(--q-primary-contrast) !important;
163
+ }
164
+ }
165
+
166
+ &__icon {
167
+ font-size: 24px;
168
+ }
169
+
170
+ &__arrow--faded {
171
+ color: $grey-6;
172
+ opacity: 1 !important;
173
+ }
174
+
175
+ &__indicator {
176
+ display: none;
177
+ }
178
+ }
179
+
180
+ &__arrow:not(&--faded) {
181
+ color: $grey-9;
182
+ transition: color var(--qas-generic-transition);
183
+
184
+ &:hover {
185
+ color: var(--q-primary-contrast);
186
+ }
187
+ }
188
+ }
189
+
190
+ .q-focus-helper {
191
+ display: none;
192
+ }
193
+ }
194
+ </style>
@@ -4,40 +4,20 @@ mixins:
4
4
  - quasar/dist/api/QTabs.json
5
5
 
6
6
  meta:
7
- desc: Componente para gerar tab dinamicamente, implementa o QTab e Qtabs.
7
+ desc: Componente para gerar tabs dinamicamente, implementa o QTab e QTabs.
8
8
 
9
9
  props:
10
- active-color:
11
- desc: Cor da tab quando ela está ativa.
12
- type: String
13
- examples: ['primary', 'negative', 'positive']
14
-
15
- counter-props:
16
- desc: Contador de cada tags, funciona como um "notificação"
10
+ counters:
11
+ desc: Contador que ficará junto a label "Todos (24)"
17
12
  default: {}
18
13
  type: Object
19
- examples: ["{ tab: 2 }"]
20
-
21
- fuse-options:
22
- desc: Configurações do [fuse.js](https://fusejs.io/api/options.html).
23
- default: { keys: ['label'] }
24
- type: Object
25
-
26
- indicator-color:
27
- desc: Cor do indicador.
28
- default: primary
29
- type: String
14
+ examples: ["{ all: 24 }"]
30
15
 
31
16
  model-value:
32
17
  desc: Model do componente, controla qual é a tab atual selecionada.
33
18
  type: [String, Number]
34
19
  model: true
35
20
 
36
- tab-class:
37
- desc: Classe do QTab
38
- default: text-primary
39
- type: String
40
-
41
21
  tabs:
42
22
  desc: Objeto ou Array contendo todas as tabs a serem geradas.
43
23
  default: {}
@@ -4,16 +4,13 @@
4
4
  <div ref="truncate" :class="truncateTextClass">
5
5
  <slot>{{ text }}</slot>
6
6
  </div>
7
- <div v-if="isTruncated" class="cursor-pointer text-primary" @click.stop="toggleDialog">{{ seeMoreLabel }}</div>
7
+
8
+ <div v-if="isTruncated" class="cursor-pointer text-primary" @click.stop="toggleDialog">
9
+ {{ seeMoreLabel }}
10
+ </div>
8
11
  </div>
9
12
 
10
- <qas-dialog v-model="showDialog" v-bind="defaultDialogProps">
11
- <template #description>
12
- <slot>
13
- <div>{{ text }}</div>
14
- </slot>
15
- </template>
16
- </qas-dialog>
13
+ <qas-dialog v-model="showDialog" v-bind="defaultDialogProps" aria-label="Diálogo de texto completo" role="dialog" />
17
14
  </div>
18
15
  </template>
19
16
 
@@ -60,7 +57,8 @@ export default {
60
57
  return {
61
58
  maxPossibleWidth: '',
62
59
  showDialog: false,
63
- textWidth: ''
60
+ textWidth: '',
61
+ observer: null
64
62
  }
65
63
  },
66
64
 
@@ -81,7 +79,6 @@ export default {
81
79
  return {
82
80
  cancel: false,
83
81
  ok: false,
84
- useCloseButton: true,
85
82
  ...this.dialogProps,
86
83
  card: {
87
84
  title: this.dialogTitle,
@@ -99,6 +96,11 @@ export default {
99
96
 
100
97
  mounted () {
101
98
  this.truncateText()
99
+ this.observeContentChange()
100
+ },
101
+
102
+ unmounted () {
103
+ this.observer.disconnect()
102
104
  },
103
105
 
104
106
  methods: {
@@ -111,6 +113,18 @@ export default {
111
113
 
112
114
  toggleDialog () {
113
115
  this.showDialog = !this.showDialog
116
+ },
117
+
118
+ observeContentChange () {
119
+ const element = this.$refs.truncate
120
+ const config = { childList: true, subtree: true, characterData: true }
121
+
122
+ const callback = mutationList => {
123
+ mutationList.forEach(() => this.truncateText())
124
+ }
125
+
126
+ this.observer = new MutationObserver(callback)
127
+ this.observer.observe(element, config)
114
128
  }
115
129
  }
116
130
  }
@@ -19,12 +19,12 @@
19
19
 
20
20
  <div class="col-12 col-sm-auto items-center justify-center q-col-gutter-md row" :class="actionsClass">
21
21
  <div>
22
- <qas-btn :class="iconClass" dense :disabled="!firstQueue.length" flat icon="o_arrow_circle_down" rounded @click="setSelectedFromClick(true)" />
22
+ <qas-btn :class="iconClass" dense :disabled="!firstQueue.length" flat icon="sym_r_arrow_circle_down" rounded @click="setSelectedFromClick(true)" />
23
23
  <q-tooltip anchor="top middle" self="center middle">Selecionar</q-tooltip>
24
24
  </div>
25
25
  <div>
26
26
  <div>
27
- <qas-btn :class="iconClass" dense :disabled="!secondQueue.length" flat icon="o_arrow_circle_up" rounded @click="setSelectedFromClick()" />
27
+ <qas-btn :class="iconClass" dense :disabled="!secondQueue.length" flat icon="sym_r_arrow_circle_up" rounded @click="setSelectedFromClick()" />
28
28
  <q-tooltip anchor="bottom middle" self="center middle">Remover</q-tooltip>
29
29
  </div>
30
30
  </div>
@@ -8,12 +8,12 @@
8
8
  </span>
9
9
 
10
10
  <span v-if="hasMenuButton(node)" class="q-ml-sm">
11
- <qas-btn dense flat icon="o_more_vert" round @click.stop>
11
+ <qas-btn dense flat icon="sym_r_more_vert" round @click.stop>
12
12
  <q-menu auto-close>
13
13
  <q-list separator>
14
14
  <q-item v-if="useAddButton" v-ripple class="qas-tree-generator__item" clickable @click="handleTreeFormDialog(node, true, tree)">
15
15
  <q-item-section avatar>
16
- <q-icon name="o_add_circle_outline" />
16
+ <q-icon name="sym_r_add_circle_outline" />
17
17
  </q-item-section>
18
18
 
19
19
  <q-item-section>Adicionar subnível</q-item-section>
@@ -21,7 +21,7 @@
21
21
 
22
22
  <q-item v-if="useEditButton" v-ripple class="qas-tree-generator__item" clickable @click="handleTreeFormDialog(node)">
23
23
  <q-item-section avatar>
24
- <q-icon name="o_edit" />
24
+ <q-icon name="sym_r_edit" />
25
25
  </q-item-section>
26
26
 
27
27
  <q-item-section>Editar</q-item-section>
@@ -29,7 +29,7 @@
29
29
 
30
30
  <q-item v-if="hasDestroyButton(node)" v-ripple class="qas-tree-generator__item" clickable @click="onDestroy(node)">
31
31
  <q-item-section avatar>
32
- <q-icon name="o_highlight_off" />
32
+ <q-icon name="sym_r_highlight_off" />
33
33
  </q-item-section>
34
34
 
35
35
  <q-item-section>Excluir</q-item-section>
@@ -169,7 +169,6 @@ export default {
169
169
  destroyDialogConfig () {
170
170
  return {
171
171
  card: {
172
- title: 'Excluir ramo da árvore?',
173
172
  description: 'Todas as informações serão perdidas. Deseja realmente continuar?'
174
173
  },
175
174
  ok: {
@@ -13,13 +13,13 @@
13
13
  </div>
14
14
  </div>
15
15
 
16
- <qas-btn v-if="showAddFile" ref="buttonUpload" color="white" dense flat icon="o_add" round @click="$refs.hiddenInput.click()" />
16
+ <qas-btn v-if="showAddFile" ref="buttonUpload" color="white" dense flat icon="sym_r_add" round @click="$refs.hiddenInput.click()" />
17
17
 
18
18
  <input ref="hiddenInput" :accept="attributes.accept" class="qas-uploader__input" :multiple="isMultiple" type="file">
19
19
 
20
20
  <qas-btn ref="buttonCleanFiles" class="hidden" color="white" @click="scope.removeUploadedFiles" />
21
- <qas-btn v-if="scope.canUpload" color="white" dense flat icon="o_cloud_upload" round @click="scope.upload" />
22
- <qas-btn v-if="scope.isUploading" color="white" dense flat icon="o_clear" round @click="scope.abort" />
21
+ <qas-btn v-if="scope.canUpload" color="white" dense flat icon="sym_r_cloud_upload" round @click="scope.upload" />
22
+ <qas-btn v-if="scope.isUploading" color="white" dense flat icon="sym_r_clear" round @click="scope.abort" />
23
23
  </div>
24
24
  </slot>
25
25
  </template>
@@ -28,7 +28,7 @@
28
28
  <slot name="list" :scope="scope">
29
29
  <div class="col-12 q-col-gutter-md row">
30
30
  <div v-for="(file, index) in getFilesList(scope.files, scope)" :key="index" class="row" :class="itemClass">
31
- <qas-avatar class="q-mr-sm" color="contrast-primary" icon="o_attach_file" :image="file.url" rounded :text-color="getColorFileIcon(file)" />
31
+ <qas-avatar class="q-mr-sm" color="primary" icon="sym_r_attach_file" :image="file.url" rounded :text-color="getColorFileIcon(file)" />
32
32
 
33
33
  <div class="col items-center no-wrap row">
34
34
  <div class="column no-wrap" :class="{ col: isMultiple }">
@@ -36,8 +36,8 @@
36
36
  <div v-if="file.isUploaded" class="text-caption">{{ file.progressLabel }} ({{ file.sizeLabel }})</div>
37
37
  </div>
38
38
  <div class="items-center q-ml-sm row">
39
- <q-icon v-if="file.isFailed" color="negative" name="o_warning" size="20px" />
40
- <qas-btn v-if="!scope.readonly" dense flat icon="o_delete" round @click="removeItem(index, scope, file)" />
39
+ <q-icon v-if="file.isFailed" color="negative" name="sym_r_warning" size="20px" />
40
+ <qas-btn v-if="!scope.readonly" dense flat icon="sym_r_delete" round @click="removeItem(index, scope, file)" />
41
41
  </div>
42
42
  </div>
43
43
  </div>
@@ -49,7 +49,7 @@
49
49
  <slot :context="self" name="custom-upload" />
50
50
 
51
51
  <template v-if="hasErrorMessage" #after>
52
- <q-icon color="negative" name="o_error" />
52
+ <q-icon color="negative" name="sym_r_error" />
53
53
  </template>
54
54
  </q-field>
55
55
  </template>
@@ -370,7 +370,7 @@ export default {
370
370
  },
371
371
 
372
372
  getColorFileIcon (file) {
373
- return this.isFailed(file) ? 'negative' : 'primary'
373
+ return this.isFailed(file) ? 'negative' : 'white'
374
374
  },
375
375
 
376
376
  async addFiles () {
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <div class="q-mb-xl qas-welcome text-left">
3
+ <h3 class="text-grey-9 text-h3">
4
+ {{ welcomeMessage }}<span v-if="firstName">, {{ firstName }}</span>
5
+ </h3>
6
+
7
+ <div class="text-caption text-grey-8">{{ currentDay }}</div>
8
+
9
+ <div v-if="hasShortcuts">
10
+ <div class="q-mb-md q-mt-md text-grey-9 text-subtitle2">Atalhos</div>
11
+
12
+ <div class="qas-welcome__container">
13
+ <div ref="scrollArea" class="row" :class="contentClasses">
14
+ <div v-for="(shortcut, index) in shortcuts" :key="index" :class="shortcutClasses">
15
+ <pv-welcome-shortcut-card :shortcut="shortcut" />
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import PvWelcomeShortcutCard from './private/PvWelcomeShortcutCard.vue'
25
+
26
+ import { date } from 'quasar'
27
+ import dateConfig from '../../shared/date-config.js'
28
+
29
+ export default {
30
+ name: 'QasWelcome',
31
+
32
+ components: {
33
+ PvWelcomeShortcutCard
34
+ },
35
+
36
+ props: {
37
+ name: {
38
+ default: '',
39
+ type: String
40
+ },
41
+
42
+ shortcuts: {
43
+ type: Array,
44
+ default: () => []
45
+ }
46
+ },
47
+
48
+ computed: {
49
+ contentClasses () {
50
+ return this.$qas.screen.isSmall
51
+ ? 'no-wrap overflow-hidden-y q-gutter-x-md q-pb-md q-pt-xs qas-welcome__scroll-area'
52
+ : 'q-col-gutter-md'
53
+ },
54
+
55
+ currentDay () {
56
+ const timeStamp = Date.now()
57
+ const { daysList, monthsList } = dateConfig
58
+
59
+ // exemplo: Quarta-feira, 11 de janeiro de 2023
60
+ return date.formatDate(
61
+ timeStamp, 'dddd, DDD [de] MMMM [de] YYYY', { days: daysList, months: monthsList }
62
+ )
63
+ },
64
+
65
+ firstName () {
66
+ if (!this.name) return ''
67
+
68
+ return this.name.split(' ')?.[0]
69
+ },
70
+
71
+ hasShortcuts () {
72
+ return !!this.shortcuts.length
73
+ },
74
+
75
+ shortcutClasses () {
76
+ return !this.$qas.screen.isSmall && 'col-3 col-lg-2'
77
+ },
78
+
79
+ welcomeMessage () {
80
+ const today = new Date()
81
+ const time = date.formatDate(today, 'HH:mm')
82
+
83
+ if (time >= '05:00' && time < '11:59') return 'Bom dia'
84
+
85
+ if (time >= '12:00' && time < '18:59') return 'Boa tarde'
86
+
87
+ return 'Boa noite'
88
+ }
89
+ }
90
+ }
91
+ </script>
92
+
93
+ <style lang="scss">
94
+ .qas-welcome {
95
+ &__scroll-area {
96
+ -ms-overflow-style: none;
97
+ scrollbar-width: none;
98
+
99
+ &::-webkit-scrollbar {
100
+ display: none;
101
+ }
102
+
103
+ > *:last-child {
104
+ margin-right: var(--qas-spacing-sm);
105
+ }
106
+ }
107
+ }
108
+ </style>
@@ -0,0 +1,14 @@
1
+ type: component
2
+
3
+ meta:
4
+ desc: Componente de boas-vindas para ser usado na Home dos sistemas.
5
+
6
+ props:
7
+ name:
8
+ desc: Nome do usuário a ser mostrado na tela.
9
+ type: String
10
+
11
+ shortcuts:
12
+ desc: Lista de cards de atalhos.
13
+ default: []
14
+ type: Array
@@ -0,0 +1,58 @@
1
+ <template>
2
+ <component :is="component.is" v-bind="component.props" class="bg-white column pv-welcome-shortcut-card q-pa-md rounded-borders shadow-2 text-no-decoration text-primary">
3
+ <q-icon class="q-pr-xs" :name="shortcut.icon" size="md" />
4
+
5
+ <div class="q-mt-md text-subtitle1">
6
+ {{ shortcut.title }}
7
+ </div>
8
+ </component>
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ name: 'PvWelcomeShortcutCard',
14
+
15
+ props: {
16
+ shortcut: {
17
+ type: Object,
18
+ default: () => ({})
19
+ }
20
+ },
21
+
22
+ computed: {
23
+ isExternal () {
24
+ return !!this.shortcut.externalLink
25
+ },
26
+
27
+ component () {
28
+ return {
29
+ is: this.isExternal ? 'a' : 'router-link',
30
+ props: {
31
+ ...(!this.isExternal && { to: this.shortcut.to }),
32
+ ...(this.isExternal && { href: this.shortcut.externalLink })
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ </script>
39
+
40
+ <style lang="scss">
41
+ .pv-welcome-shortcut-card {
42
+ border: 2px solid transparent;
43
+ display: block;
44
+ height: 100%;
45
+ min-height: 124px;
46
+ transition: border-color var(--qas-generic-transition), color var(--qas-generic-transition);
47
+ word-wrap: break-word;
48
+
49
+ &:hover {
50
+ border-color: var(--q-primary-contrast);
51
+ color: var(--q-primary-contrast) !important;
52
+ }
53
+
54
+ @media (max-width: $breakpoint-xs) {
55
+ min-width: 154px;
56
+ }
57
+ }
58
+ </style>
@@ -1,3 +1,11 @@
1
1
  body {
2
2
  background-color: $background-color;
3
3
  }
4
+
5
+ .material-symbols-rounded {
6
+ font-variation-settings:
7
+ 'FILL' 0,
8
+ 'wght' 300,
9
+ 'GRAD' 0,
10
+ 'opsz' 24;
11
+ }
@@ -5,6 +5,10 @@
5
5
  font-weight: 600;
6
6
  }
7
7
 
8
+ &:not(&--clickable) {
9
+ color: $grey-8;
10
+ }
11
+
8
12
  &.q-router-link--active {
9
13
  background-color: transparent !important;
10
14
  font-weight: 600;
@@ -21,11 +25,12 @@
21
25
  }
22
26
  }
23
27
 
24
- &--clickable {
28
+ &--clickable:not(&--active) {
29
+ color: $grey-9;
25
30
  transition: color 300ms;
26
31
 
27
- &:hover {
28
- color: var(--q-primary);
32
+ &:not(&.q-router-link--active):hover {
33
+ color: var(--q-primary-contrast);
29
34
  }
30
35
  }
31
36
 
@@ -1 +1,2 @@
1
1
  @import './set-brand';
2
+ @import './set-typography';
@@ -0,0 +1,8 @@
1
+ @use 'sass:map';
2
+
3
+ @mixin set-typography($name, $important: false) {
4
+ font-size: if($important, map.get($name, 'size') !important, map.get($name, 'size'));
5
+ font-weight: if($important, map.get($name, 'weight') !important, map.get($name, 'weight'));
6
+ letter-spacing: if($important, map.get($name, 'letter-spacing') !important, map.get($name, 'letter-spacing'));
7
+ line-height: if($important, map.get($name, 'line-height') !important, map.get($name, 'line-height'));
8
+ }
@@ -1,3 +1,4 @@
1
1
  @import './button';
2
+ @import './shadow';
2
3
  @import './spacing';
3
4
  @import './typography';