@freteclick/quasar-financial-ui 1.0.113 → 1.0.115

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freteclick/quasar-financial-ui",
3
- "version": "1.0.113",
3
+ "version": "1.0.115",
4
4
  "author": "FreteClick",
5
5
  "description": "FreteClick financial Quasar UI Component",
6
6
  "license": "MIT",
@@ -1,12 +1,36 @@
1
1
  <template>
2
- <q-card class="row q-pa-md">
3
- <div class="col-xs-12 q-pb-md text-h6">Faturas</div>
4
- <div class="col-sm-6 col-xs-12 q-pa-md">
5
- <q-input stack-label label="Buscar por" debounce="1000" v-model="filters.text" class="full-width" />
2
+ <q-card
3
+ class="row q-pa-md invoice-filters"
4
+ :class="{ 'invoice-filters--inline': variant === 'filter-box' }"
5
+ >
6
+ <div v-if="variant !== 'filter-box'" class="col-xs-12 q-pb-md text-h6">
7
+ Faturas
6
8
  </div>
7
- <div class="col-sm-6 col-xs-12 q-pa-md">
8
- <q-select stack-label label="Status da fatura" v-model="filters.status" :options="statuses" class="full-width"
9
- :loading="loadingStatuses">
9
+
10
+ <div class="col-sm-6 col-xs-12 q-pa-md invoice-filters__field">
11
+ <q-input
12
+ v-model="filters.text"
13
+ stack-label
14
+ label="Buscar por"
15
+ :debounce="variant === 'filter-box' ? 0 : 1000"
16
+ @blur="onTextBlur"
17
+ :outlined="variant === 'filter-box'"
18
+ :dense="variant === 'filter-box'"
19
+ clearable
20
+ class="full-width"
21
+ />
22
+ </div>
23
+ <div class="col-sm-6 col-xs-12 q-pa-md invoice-filters__field">
24
+ <q-select
25
+ v-model="filters.status"
26
+ :options="statuses"
27
+ stack-label
28
+ label="Status da fatura"
29
+ :outlined="variant === 'filter-box'"
30
+ :dense="variant === 'filter-box'"
31
+ :loading="loadingStatuses"
32
+ class="full-width"
33
+ >
10
34
  <template v-slot:no-option>
11
35
  <q-item>
12
36
  <q-item-section class="text-grey"> Sem resultados </q-item-section>
@@ -14,9 +38,35 @@
14
38
  </template>
15
39
  </q-select>
16
40
  </div>
17
- <div class="col-6">
18
- <q-select stack-label label="Tipo de Fatura" v-model="filters.orderType" :options="orderType" class="full-width"
19
- :loading="loadingOrderType">
41
+ <div v-if="showCategory" class="col-sm-6 col-xs-12 q-pa-md invoice-filters__field">
42
+ <q-select
43
+ v-model="filters.category"
44
+ :options="categories"
45
+ stack-label
46
+ label="Categoria"
47
+ :outlined="variant === 'filter-box'"
48
+ :dense="variant === 'filter-box'"
49
+ :loading="loadingCategories"
50
+ class="full-width"
51
+ >
52
+ <template v-slot:no-option>
53
+ <q-item>
54
+ <q-item-section class="text-grey">Sem categorias</q-item-section>
55
+ </q-item>
56
+ </template>
57
+ </q-select>
58
+ </div>
59
+ <div class="col-6 q-pa-md invoice-filters__field">
60
+ <q-select
61
+ v-model="filters.orderType"
62
+ :options="orderType"
63
+ stack-label
64
+ label="Tipo de Fatura"
65
+ :outlined="variant === 'filter-box'"
66
+ :dense="variant === 'filter-box'"
67
+ :loading="loadingOrderType"
68
+ class="full-width"
69
+ >
20
70
  <template v-slot:no-option>
21
71
  <q-item>
22
72
  <q-item-section class="text-grey"> Sem resultados </q-item-section>
@@ -24,8 +74,9 @@
24
74
  </template>
25
75
  </q-select>
26
76
  </div>
27
- <div class="col-6">
77
+ <div class="col-6 q-pa-md invoice-filters__field invoice-filters__date">
28
78
  <DataFilter :fromDate="filters.date.from" :toDate="filters.date.to" :showButton="false"
79
+ :emitOnBlur="variant === 'filter-box'"
29
80
  @dateChanged="dateChanged" />
30
81
  </div>
31
82
  </q-card>
@@ -45,10 +96,19 @@ export default {
45
96
  type: Object,
46
97
  required: true,
47
98
  },
99
+ variant: {
100
+ type: String,
101
+ default: "default",
102
+ },
103
+ showCategory: {
104
+ type: Boolean,
105
+ default: false,
106
+ },
48
107
  },
49
108
 
50
109
  created() {
51
110
  this.requestStatuses();
111
+ if (this.showCategory) this.requestCategories(this.filters.company);
52
112
  },
53
113
 
54
114
  data() {
@@ -56,7 +116,9 @@ export default {
56
116
 
57
117
  return {
58
118
  statuses: statuses,
119
+ categories: [{ label: "Todas", value: null }],
59
120
  loadingStatuses: false,
121
+ loadingCategories: false,
60
122
  loadingOrderType: false,
61
123
  orderType: [
62
124
  {
@@ -87,7 +149,7 @@ export default {
87
149
 
88
150
  watch: {
89
151
  "filters.text"() {
90
- this.$emit("onRequest");
152
+ if (this.variant !== "filter-box") this.$emit("onRequest");
91
153
  },
92
154
  "filters.orderType"() {
93
155
  this.$emit("onRequest");
@@ -95,39 +157,84 @@ export default {
95
157
  "filters.status"() {
96
158
  this.$emit("onRequest");
97
159
  },
160
+ "filters.category"() {
161
+ if (this.showCategory) this.$emit("onRequest");
162
+ },
163
+ "filters.company"(company) {
164
+ if (this.showCategory) this.requestCategories(company);
165
+ },
98
166
  },
99
167
 
100
168
  methods: {
101
169
  ...mapActions({
102
170
  getStatuses: "receiveInvoice/getStatuses",
171
+ getCategories: "categories/getCategories",
103
172
  }),
104
173
 
174
+ onTextBlur() {
175
+ if (this.variant === "filter-box") this.$emit("onRequest");
176
+ },
177
+
178
+ requestCategories(company) {
179
+ if (!company || !company.id) {
180
+ this.categories = [{ label: "Todas", value: null }];
181
+ return Promise.resolve(this.categories);
182
+ }
183
+
184
+ this.loadingCategories = true;
185
+ return this.getCategories({
186
+ params: {
187
+ context: "expense",
188
+ company: company.id,
189
+ },
190
+ })
191
+ .then((members) => {
192
+ const options = [{ label: "Todas", value: null }];
193
+ (members || []).forEach((category) => {
194
+ const idFromIri = String(category["@id"] || "").match(/\/categories\/(\d+)$/);
195
+ const id = Number(category.id || (idFromIri && idFromIri[1]));
196
+
197
+ if (id) options.push({ label: category.name, value: id });
198
+ });
199
+ this.categories = options;
200
+ return options;
201
+ })
202
+ .catch(() => {
203
+ this.categories = [{ label: "Todas", value: null }];
204
+ return this.categories;
205
+ })
206
+ .finally(() => {
207
+ this.loadingCategories = false;
208
+ });
209
+ },
210
+
105
211
  requestStatuses() {
106
212
  this.loadingStatuses = true;
107
- this.getStatuses({
213
+ return this.getStatuses({
108
214
  visibility: "public",
109
215
  context: "invoice",
110
216
  realStatus: ["open", "pending", "canceled", "closed"],
111
- }).then((statuses) => {
112
- if (statuses.length) {
113
- let data = [];
114
-
115
- data.push({
116
- label: "Todos",
117
- value: null,
118
- });
217
+ })
218
+ .then((statuses) => {
219
+ const data = [{ label: "Todos", value: null }];
220
+ (Array.isArray(statuses) ? statuses : []).forEach((status) => {
221
+ const id = String(status["@id"] || "").replace(/[^0-9]/g, "");
222
+ if (!id) return;
119
223
 
120
- for (let index in statuses) {
121
224
  data.push({
122
- label: this.$t(`invoice.statuses.${statuses[index].status}`),
123
- value: statuses[index]["@id"].replace(/[^0-9]/g, ""),
225
+ label: this.$t(`invoice.statuses.${status.status}`),
226
+ value: id,
124
227
  });
125
- }
228
+ });
126
229
 
127
230
  this.statuses = data;
128
- }
129
- this.loadingStatuses = false;
130
- });
231
+ })
232
+ .catch(() => {
233
+ this.statuses = [{ label: "Todos", value: null }];
234
+ })
235
+ .finally(() => {
236
+ this.loadingStatuses = false;
237
+ });
131
238
  },
132
239
  dateChanged(item) {
133
240
  this.filters.date = item;
@@ -135,4 +242,68 @@ export default {
135
242
  },
136
243
  },
137
244
  };
138
- </script>
245
+ </script>
246
+
247
+ <style lang="scss" scoped>
248
+ .invoice-filters--inline {
249
+ display: flex;
250
+ width: max-content;
251
+ min-width: 100%;
252
+ max-width: none;
253
+ flex-flow: row nowrap;
254
+ align-items: flex-end;
255
+ justify-content: flex-start;
256
+ gap: 12px;
257
+ padding: 0 !important;
258
+ border: 0;
259
+ border-radius: 0;
260
+ background: transparent;
261
+ box-shadow: none;
262
+ }
263
+
264
+ .invoice-filters--inline > .invoice-filters__field {
265
+ flex: 1 0 190px;
266
+ width: 190px;
267
+ min-width: 190px;
268
+ max-width: none;
269
+ margin: 0;
270
+ padding: 0 !important;
271
+ }
272
+
273
+ .invoice-filters--inline > .invoice-filters__date {
274
+ flex: 2 0 360px;
275
+ width: 360px;
276
+ min-width: 360px;
277
+ }
278
+
279
+ .invoice-filters--inline :deep(.q-field) {
280
+ width: 100%;
281
+ min-width: 0;
282
+ }
283
+
284
+ .invoice-filters--inline :deep(.q-field__control),
285
+ .invoice-filters--inline :deep(.q-field__control:before),
286
+ .invoice-filters--inline :deep(.q-field__control:after) {
287
+ min-height: 42px;
288
+ border-radius: 10px;
289
+ }
290
+
291
+ .invoice-filters--inline :deep(.container-filter) {
292
+ flex-direction: row;
293
+ flex-wrap: nowrap;
294
+ align-items: center;
295
+ justify-content: flex-start;
296
+ gap: 10px;
297
+ padding: 0;
298
+ }
299
+
300
+ .invoice-filters--inline :deep(.date-filter__field) {
301
+ flex: 1 1 0;
302
+ width: 100%;
303
+ max-width: none !important;
304
+ min-width: 150px;
305
+ min-height: 0;
306
+ margin: 0;
307
+ }
308
+
309
+ </style>