@nixweb/nixloc-ui 0.0.300 → 0.0.301

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 (158) hide show
  1. package/package.json +1 -1
  2. package/src/App.vue +13 -0
  3. package/src/component/forms/Button.vue +163 -0
  4. package/src/component/forms/ButtonFilter.vue +75 -0
  5. package/src/component/forms/ButtonGroup.vue +67 -0
  6. package/src/component/forms/ButtonSub.vue +98 -0
  7. package/src/component/forms/ButtonToggle.vue +77 -0
  8. package/src/component/forms/CheckboxGroup.vue +69 -0
  9. package/src/component/forms/CheckboxServer.vue +192 -0
  10. package/src/component/forms/CheckboxSimple.vue +60 -0
  11. package/src/component/forms/Color.vue +38 -0
  12. package/src/component/forms/DateTime.vue +170 -0
  13. package/src/component/forms/DateYearMonth.vue +193 -0
  14. package/src/component/forms/Dropdown.vue +236 -0
  15. package/src/component/forms/EditorHtml.vue +132 -0
  16. package/src/component/forms/FileUpload.vue +170 -0
  17. package/src/component/forms/ImageUpload.vue +214 -0
  18. package/src/component/forms/IncrementDecrement.vue +148 -0
  19. package/src/component/forms/InputAddressGoogle.vue +171 -0
  20. package/src/component/forms/InputCallToAction.vue +135 -0
  21. package/src/component/forms/InputDecimal.vue +153 -0
  22. package/src/component/forms/InputDecimalDiscount.vue +78 -0
  23. package/src/component/forms/InputNumber.vue +160 -0
  24. package/src/component/forms/InputPassword.vue +148 -0
  25. package/src/component/forms/InputTag.vue +125 -0
  26. package/src/component/forms/InputText.vue +174 -0
  27. package/src/component/forms/InputTextEdit.vue +69 -0
  28. package/src/component/forms/InputWhatsApp.vue +48 -0
  29. package/src/component/forms/Modal.vue +57 -0
  30. package/src/component/forms/RadioGroup.vue +91 -0
  31. package/src/component/forms/Select.vue +378 -0
  32. package/src/component/forms/SelectStatic.vue +198 -0
  33. package/src/component/forms/SideBar.vue +100 -0
  34. package/src/component/forms/Slider.vue +18 -0
  35. package/src/component/forms/TextArea.vue +138 -0
  36. package/src/component/forms/Toggle.vue +72 -0
  37. package/src/component/layout/Account.vue +131 -0
  38. package/src/component/layout/Alert.vue +88 -0
  39. package/src/component/layout/Badge.vue +111 -0
  40. package/src/component/layout/BarFloating.vue +68 -0
  41. package/src/component/layout/FixedBar.vue +103 -0
  42. package/src/component/layout/Gantt.vue +128 -0
  43. package/src/component/layout/Header.vue +56 -0
  44. package/src/component/layout/HideShow.vue +62 -0
  45. package/src/component/layout/IconMolded.vue +59 -0
  46. package/src/component/layout/LoadingFullPage.vue +27 -0
  47. package/src/component/layout/Menu.vue +287 -0
  48. package/src/component/layout/Molded.vue +30 -0
  49. package/src/component/layout/NewAccount.vue +136 -0
  50. package/src/component/layout/NewHeader.vue +60 -0
  51. package/src/component/layout/NewIconMolded.vue +71 -0
  52. package/src/component/layout/NewMenu.vue +456 -0
  53. package/src/component/layout/Panel.vue +185 -0
  54. package/src/component/layout/Popover.vue +126 -0
  55. package/src/component/layout/ScrollBar.vue +57 -0
  56. package/src/component/layout/Tab.vue +135 -0
  57. package/src/component/layout/Tag.vue +97 -0
  58. package/src/component/layout/Wizard.vue +211 -0
  59. package/src/component/rental/DisplayCalculatePeriod.vue +49 -0
  60. package/src/component/rental/DisplayPeriodRent.vue +55 -0
  61. package/src/component/rental/DisplayTotalization.vue +86 -0
  62. package/src/component/report/Fields.vue +109 -0
  63. package/src/component/report/Report.vue +314 -0
  64. package/src/component/report/ReportTable.vue +112 -0
  65. package/src/component/report/Totalization.vue +34 -0
  66. package/src/component/shared/CodeEditor.vue +128 -0
  67. package/src/component/shared/Collapse.vue +131 -0
  68. package/src/component/shared/Confirmation.vue +74 -0
  69. package/src/component/shared/DocumentEditor.vue +99 -0
  70. package/src/component/shared/DocumentPreview.vue +81 -0
  71. package/src/component/shared/DocumentPublic.vue +33 -0
  72. package/src/component/shared/ExportExcel.vue +56 -0
  73. package/src/component/shared/ExportPDF.vue +116 -0
  74. package/src/component/shared/FullCalendar.vue +174 -0
  75. package/src/component/shared/HeaderReport.vue +47 -0
  76. package/src/component/shared/HorizontalFilter.vue +64 -0
  77. package/src/component/shared/ListNotifications.vue +70 -0
  78. package/src/component/shared/Loading.vue +107 -0
  79. package/src/component/shared/LoadingCard.vue +65 -0
  80. package/src/component/shared/LoadingMoreButton.vue +23 -0
  81. package/src/component/shared/Messages.vue +109 -0
  82. package/src/component/shared/PDFViewer.vue +24 -0
  83. package/src/component/shared/Pagination.vue +108 -0
  84. package/src/component/shared/ParameterLegend.vue +169 -0
  85. package/src/component/shared/ProgressBar.vue +25 -0
  86. package/src/component/shared/QueryButton.vue +66 -0
  87. package/src/component/shared/Report.vue +200 -0
  88. package/src/component/shared/SaveCancel.vue +99 -0
  89. package/src/component/shared/Search.vue +174 -0
  90. package/src/component/shared/SelectOption.vue +162 -0
  91. package/src/component/shared/Table.vue +174 -0
  92. package/src/component/shared/TableButton.vue +36 -0
  93. package/src/component/shared/TableDraggable.vue +117 -0
  94. package/src/component/shared/TableImport.vue +93 -0
  95. package/src/component/shared/TableItem.vue +214 -0
  96. package/src/component/shared/TableTotalPerPage.vue +78 -0
  97. package/src/component/shared/TableTotalRecords.vue +44 -0
  98. package/src/component/shared/TableTotalization.vue +47 -0
  99. package/src/component/shared/TimeLine.vue +42 -0
  100. package/src/component/shared/Timer.vue +78 -0
  101. package/src/component/shared/Tip.vue +42 -0
  102. package/src/component/shared/Toast.vue +69 -0
  103. package/src/component/shared/ToggleTheme.vue +128 -0
  104. package/src/component/shared/TotalizationReport.vue +86 -0
  105. package/src/component/shared/VerticalFilter.vue +97 -0
  106. package/src/component/shared/automation/ActivitiesList.vue +44 -0
  107. package/src/component/shared/automation/AddRule.vue +61 -0
  108. package/src/component/shared/automation/AutomationBuilder.vue +27 -0
  109. package/src/component/shared/automation/DynamicComponentList.vue +86 -0
  110. package/src/component/shared/automation/SelectRule.vue +98 -0
  111. package/src/component/shared/automation/components/BillingByRent.vue +98 -0
  112. package/src/component/shared/automation/components/SendEmail.vue +94 -0
  113. package/src/component/shared/file-manager/FileManager.vue +391 -0
  114. package/src/component/shared/filter-builder/FilterBuilder.vue +221 -0
  115. package/src/component/shared/filter-builder/FilterQuery.vue +94 -0
  116. package/src/component/shared/query-builder/AddRule.vue +203 -0
  117. package/src/component/shared/query-builder/ConvertToOdata.js +86 -0
  118. package/src/component/shared/query-builder/DynamicComponent.vue +161 -0
  119. package/src/component/shared/query-builder/DynamicComponentList.vue +70 -0
  120. package/src/component/shared/query-builder/Fields.vue +93 -0
  121. package/src/component/shared/query-builder/QueryBuilder.vue +69 -0
  122. package/src/component/shared/query-builder/Rules.vue +68 -0
  123. package/src/component/shared/query-builder/SelectRule.vue +97 -0
  124. package/src/component/shared/query-builder/Tags.vue +59 -0
  125. package/src/component/shared/query-builder/utilities.js +22 -0
  126. package/src/component/signature/Payment.vue +161 -0
  127. package/src/component/signature/Warning.vue +76 -0
  128. package/src/component/template/ListViewWithDataHandler.vue +429 -0
  129. package/src/component/template/ReportCreateUpdate.vue +110 -0
  130. package/src/component/template/ViewTemplateConfiguration.vue +64 -0
  131. package/src/component/template/ViewTemplateDocumentView.vue +213 -0
  132. package/src/component/template/ViewTemplateImportFile.vue +347 -0
  133. package/src/component/template/ViewTemplateReportList.vue +217 -0
  134. package/src/component/template/ViewTemplateReportPreview.vue +432 -0
  135. package/src/component/template/ViewTemplateSelectOption.vue +46 -0
  136. package/src/component/template/ViewTemplateWithSalveCancel.vue +32 -0
  137. package/src/component/template/ViewTemplateWithTable.vue +62 -0
  138. package/src/component/template/model/Report.js +6 -0
  139. package/src/component/training/Course.vue +344 -0
  140. package/src/component/training/CourseView.vue +190 -0
  141. package/src/component/value-objects/Address.js +11 -0
  142. package/src/component/value-objects/Address.vue +157 -0
  143. package/src/component/value-objects/Contact.js +7 -0
  144. package/src/component/value-objects/Contact.vue +106 -0
  145. package/src/component/value-objects/Person.js +10 -0
  146. package/src/component/value-objects/Person.vue +129 -0
  147. package/src/config/axios.js +9 -0
  148. package/src/config/dicas.js +15 -0
  149. package/src/config/router.js +14 -0
  150. package/src/config/token.js +15 -0
  151. package/src/main.js +23 -0
  152. package/src/store/modules/automation.js +31 -0
  153. package/src/store/modules/generic.js +816 -0
  154. package/src/store/modules/report.js +278 -0
  155. package/src/store/modules/user.js +67 -0
  156. package/src/store/modules/util.js +26 -0
  157. package/src/store/modules/validation.js +39 -0
  158. package/src/store/store.js +14 -0
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <div>
3
+ <div class="title">
4
+ <i class="fa-solid fa-file-invoice"></i>
5
+ Gerar Faturamento
6
+ </div>
7
+ <div class="div-task">
8
+ <b-row>
9
+ <b-col xs="12" sm="12" md="12" lg="12" xl="4">
10
+ <SelectStatic title="Frequência" :required="true" :data="[
11
+ { content: 'Semanal', id: 'weekly' },
12
+ { content: 'Quinzenal', id: 'fortnightly' },
13
+ { content: 'Mensal', id: 'monthly' },
14
+ { content: 'Anual', id: 'yearly' },
15
+ ]" :markFormDirty="true" v-model="rule.frequency" />
16
+ </b-col>
17
+ <b-col xs="12" sm="12" md="12" lg="12" xl="3">
18
+ <InputDecimal title="Valor" field="value" :required="true" :markFormDirty="true" :maxLength="5"
19
+ type="float" v-model="rule.amount" />
20
+ </b-col>
21
+ <b-col xs="12" sm="12" md="12" lg="12" xl="2">
22
+ <DateTime title="Data Início" :required="true" field="dateStart" format="DD/MM/YYYY" type="date"
23
+ placeholder v-model="rule.dateStart" />
24
+ </b-col>
25
+ <b-col xs="12" sm="12" md="12" lg="12" xl="2">
26
+ <DateTime title="Data Fim" field="dateEnd" format="DD/MM/YYYY" type="date" placeholder
27
+ v-model="rule.dateEnd" />
28
+ </b-col>
29
+ </b-row>
30
+ <b-row>
31
+ <b-col xs="12" sm="12" md="12" lg="8" xl="6">
32
+ <SelectStatic title="Atividade" :data="[
33
+ { content: 'Enviar E-mail', name: 'mail', recipient: '' },
34
+ { content: 'Enviar WhatsApp', name: 'whatsapp', recipient: '' },
35
+ ]" :markFormDirty="false" v-model="activity" />
36
+ </b-col>
37
+ <b-col sm="3">
38
+ <div class="div-btn">
39
+ <i class="fa-solid fa-circle-plus" @click="add"></i>
40
+ </div>
41
+ </b-col>
42
+ </b-row>
43
+ </div>
44
+ </div>
45
+ </template>
46
+ <script>
47
+
48
+ import InputDecimal from "@nixweb/nixloc-ui/src/component/forms/InputDecimal";
49
+ import SelectStatic from "@nixweb/nixloc-ui/src/component/forms/SelectStatic";
50
+ import DateTime from "@nixweb/nixloc-ui/src/component/forms/DateTime";
51
+
52
+ import { mapMutations } from "vuex";
53
+
54
+ export default {
55
+ name: "Teste",
56
+ components: {
57
+ InputDecimal, SelectStatic, DateTime
58
+ },
59
+ props: {
60
+ rule: Object
61
+ },
62
+ data() {
63
+ return {
64
+ activity: {}
65
+ }
66
+ },
67
+ methods: {
68
+ ...mapMutations("automation", ["addActivity"]),
69
+ add() {
70
+ this.activity.id = this.generateId();
71
+ if (this.activity.content) {
72
+ var activity = JSON.parse(JSON.stringify(this.activity));
73
+ this.addActivity({ id: this.rule.id, activity: activity })
74
+ }
75
+
76
+ },
77
+ generateId() {
78
+ return Math.random()
79
+ .toString(36)
80
+ .replace(/[^a-z]+/g, "")
81
+ .substr(0, 5);
82
+ },
83
+ }
84
+ }
85
+ </script>
86
+ <style scoped>
87
+ .title {
88
+ font-size: 16px;
89
+ margin-bottom: 10px;
90
+ }
91
+
92
+ .div-btn {
93
+ margin-top: 30px;
94
+ font-size: 25px;
95
+ color: #577696;
96
+ cursor: pointer;
97
+ }
98
+ </style>
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <div>
3
+ <b-row>
4
+ <b-col sm="1">
5
+ <div class="icon-mail">
6
+ <i class="fa-solid fa-envelope"></i>
7
+ </div>
8
+ </b-col>
9
+ <b-col sm="9">
10
+ <InputText title="Digite o E-mail e tecle enter" :maxLength="100" :enter="addEmail" v-model="email" />
11
+ <div class="side-by-side" v-for="email in emails ">
12
+ <div class="tag">
13
+ <div class="side-by-side">
14
+ {{ email }}
15
+ </div>
16
+ <div class="side-by-side">
17
+ <i class="icon-close fa-solid fa-circle-xmark"></i>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </b-col>
22
+ <b-col sm="2">
23
+ <div class="text-right div-icon-close" @click="remove">
24
+ <i class="fa-solid fa-xmark"></i>
25
+ </div>
26
+ </b-col>
27
+ </b-row>
28
+ </div>
29
+ </template>
30
+ <script>
31
+
32
+ import InputText from "@nixweb/nixloc-ui/src/component/forms/InputText";
33
+ import { mapMutations } from "vuex";
34
+
35
+ export default {
36
+ name: "SendMail",
37
+ props: ["activity", "value"],
38
+ components: {
39
+ InputText
40
+ },
41
+ data() {
42
+ return {
43
+ email: "",
44
+ emails: []
45
+ }
46
+ },
47
+ methods: {
48
+ ...mapMutations("automation", ["removeActivity"]),
49
+ addEmail() {
50
+ this.emails.push(this.email);
51
+ this.email = "";
52
+ },
53
+ remove() {
54
+ this.removeActivity(this.activity.id);
55
+ }
56
+ },
57
+ watch: {
58
+ emails: {
59
+ handler(emails) {
60
+ this.$emit("input", emails);
61
+ },
62
+ deep: true,
63
+ },
64
+ },
65
+ }
66
+
67
+ </script>
68
+ <style scoped>
69
+ .icon-mail {
70
+ margin-left: 20px;
71
+ margin-top: 8px;
72
+ font-size: 20px;
73
+ }
74
+
75
+ .tag {
76
+ background-color: #E0E0E0;
77
+ margin-right: 10px;
78
+ padding: 3px;
79
+ font-size: 13px;
80
+ border-radius: 20px;
81
+ }
82
+
83
+ .icon-close {
84
+ color: darkgrey;
85
+ font-size: 20px;
86
+ }
87
+
88
+ .div-icon-close {
89
+ font-size: 16px;
90
+ color: red;
91
+ margin-right: 10px;
92
+ cursor: pointer;
93
+ }
94
+ </style>
@@ -0,0 +1,391 @@
1
+ <template>
2
+ <div>
3
+ <Alert v-if="!success" type="danger">
4
+ Não é permitido enviar arquivos com mais de 5 megabytes.
5
+ </Alert>
6
+ <div v-if="loading">
7
+ <Loading type="line" :center="false" />
8
+ </div>
9
+ <div>
10
+ <b-row>
11
+ <b-col sm="3">
12
+ <div class="file">
13
+ <button class="button small primary" @click="openCamera">
14
+ <span><i class="fa-regular fa-camera-web"></i> Câmera</span>
15
+ </button>
16
+ </div>
17
+ <div class="file">
18
+ <button class="button small primary">
19
+ <span><i class="fa-solid fa-upload"></i> Carregar</span>
20
+ </button>
21
+ <input type="file" name="myfile" ref="file" @change="confirm" multiple />
22
+ </div>
23
+ </b-col>
24
+ <b-col sm="9" v-if="!showCapture">
25
+ <div class="side-by-side" v-for="attachment in attachments">
26
+ <div class="text-center box-file">
27
+ <div class="div-image"
28
+ v-if="attachment.extension == '.png' || attachment.extension == '.jpg'"
29
+ @click="openImage(baseUrl + attachment.fileName)">
30
+ <img class="img" :src="baseUrl + attachment.fileName">
31
+ </div>
32
+ <div class="icon-generic" v-else>
33
+ <i class="fa-light fa-file"></i>
34
+ <div><span class="name">{{ attachment.name }}</span></div>
35
+ </div>
36
+ <div v-if="idSelected != attachment.id">
37
+ <div class="icon side-by-side">
38
+ <a :href="baseUrl + attachment.fileName">
39
+ <i class="fa-solid fa-download"></i>
40
+ </a>
41
+ </div>
42
+ <div class="icon icon-close side-by-side" @click="confirmRemove(attachment.id)">
43
+ <i class="fa-solid fa-circle-xmark"></i>
44
+ </div>
45
+ </div>
46
+ <div v-else>
47
+ <div class="icon icon-confirm side-by-side" @click="removeSelected(attachment.id)">
48
+ <i class="fa-solid fa-circle-check"></i>
49
+ </div>
50
+ <div class="icon icon-close side-by-side" @click="cancel()">
51
+ <i class="fa-solid fa-xmark"></i>
52
+ </div>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ <div class="title" v-if="attachments.length == 0">
57
+ Nenhum arquivo adicionado!
58
+ </div>
59
+ </b-col>
60
+ </b-row>
61
+ </div>
62
+ <div v-show="showInModal">
63
+ <Modal title="Câmera" :width="600" :height="750" v-if="showModal('webcam')" :onHideModal="stopCamera">
64
+ <div class="text-center">
65
+ <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
66
+ <br>
67
+ <div class="side-by-side">
68
+ <button class="button primary" @click="captureImage">
69
+ <i class="fa-solid fa-camera"></i>
70
+ Capturar
71
+ </button>
72
+ </div>
73
+ </div>
74
+ </Modal>
75
+ <Modal title="Imagem" :width="800" v-show="showModal('image')">
76
+ <div class="text-center">
77
+ <img class="img-selected" :src="imageSelected">
78
+ </div>
79
+ </Modal>
80
+ </div>
81
+ <div v-if="!showInModal && showCapture">
82
+ <div class="text-center">
83
+ <WebCam ref="webcam" :autoplay="false" width="400" height="100%"></WebCam>
84
+ <br>
85
+ <div class="side-by-side">
86
+ <button class="button small primary" @click="captureImage">
87
+ <i class="fa-solid fa-camera"></i>
88
+ Capturar
89
+ </button>
90
+ <button class="button small danger" @click="stopCamera">
91
+ <i class="fa-solid fa-circle-xmark"></i>
92
+ Fechar
93
+ </button>
94
+ </div>
95
+ </div>
96
+ </div>
97
+ </div>
98
+ </template>
99
+ <script>
100
+
101
+ import Modal from "@nixweb/nixloc-ui/src/component/forms/Modal";
102
+ import Loading from "@nixweb/nixloc-ui/src/component/shared/Loading.vue";
103
+ import Confirmation from "@nixweb/nixloc-ui/src/component/shared/Confirmation.vue";
104
+ import Alert from "@nixweb/nixloc-ui/src/component/layout/Alert";
105
+
106
+ import { WebCam } from 'vue-cam-vision'
107
+
108
+ import { mapActions, mapGetters, mapMutations } from "vuex";
109
+
110
+ export default {
111
+ components: {
112
+ WebCam,
113
+ Modal,
114
+ Loading,
115
+ Confirmation,
116
+ Alert,
117
+ },
118
+ props: {
119
+ baseUrl: {
120
+ type: String,
121
+ default: "https://espaco.blob.core.windows.net/nixloc-attachments/",
122
+ },
123
+ showInModal: {
124
+ type: Boolean,
125
+ default: true
126
+ },
127
+ source: String,
128
+ genericId: String
129
+ },
130
+ data() {
131
+ return {
132
+ urlPost: "/api/v1/adm/attachment/upload",
133
+ urlGet: "/api/v1/adm/attachment/get-all",
134
+ urlDelete: "/api/v1/adm/attachment/delete",
135
+ files: [],
136
+ attachments: [],
137
+ captures: [],
138
+ imgReport: [],
139
+ idSelected: "",
140
+ imageSelected: "",
141
+ loading: false,
142
+ success: true,
143
+ showCapture: false,
144
+ };
145
+ },
146
+ mounted() {
147
+ this.getAll();
148
+ },
149
+ methods: {
150
+ ...mapMutations("generic", ["openModal", "hideModal", "removeLoading"]),
151
+ ...mapActions("generic", ["postFileApi", "getApi", "deleteAllApi"]),
152
+ confirm() {
153
+ this.files = Object.values(this.$refs.file.files);
154
+ this.loadFiles();
155
+ },
156
+ confirmRemove(id) {
157
+ this.idSelected = id;
158
+ },
159
+ cancel() {
160
+ this.idSelected = '';
161
+ },
162
+ removeSelected(id) {
163
+ let params = {
164
+ url: this.urlDelete,
165
+ selected: [id],
166
+ };
167
+ this.deleteAllApi(params).then(() => {
168
+ this.getAll();
169
+ });
170
+ },
171
+ async loadFiles() {
172
+ if (this.showInModal) this.hideModal("confirm");
173
+ this.loading = true;
174
+ let self = this;
175
+ for (const file of this.files) {
176
+ await self.upload(file);
177
+ }
178
+
179
+ this.loading = false;
180
+ },
181
+ async upload(file) {
182
+ this.loading = true;
183
+ let params = {
184
+ url: this.urlPost,
185
+ file: file,
186
+ name: this.source,
187
+ container: this.genericId,
188
+ };
189
+ const response = await this.postFileApi(params);
190
+ this.success = response.content == "erro" ? false : true;
191
+ this.loading = false;
192
+ let self = this;
193
+ setTimeout(function () {
194
+ self.success = true;
195
+ }, 5000);
196
+ this.getAll();
197
+ },
198
+ getAll() {
199
+ this.idSelected = "";
200
+ this.loading = true;
201
+ let params = { url: this.urlGet, obj: { any: this.source, id: this.genericId } };
202
+ this.getApi(params).then((response) => {
203
+ this.attachments = response.content.data;
204
+ this.loading = false;
205
+ });
206
+ },
207
+ openImage(url) {
208
+ this.openModal("image");
209
+ this.imageSelected = url;
210
+ },
211
+ openCamera() {
212
+ if (this.showInModal)
213
+ this.openModal("webcam");
214
+ this.showCapture = true;
215
+ this.startCamera();
216
+ },
217
+ startCamera() {
218
+ if (this.$refs.webcam) {
219
+ this.$refs.webcam.start();
220
+ }
221
+ },
222
+ stopCamera() {
223
+ if (this.$refs.webcam) {
224
+ this.$refs.webcam.stop();
225
+ this.showCapture = false;
226
+ if (this.showInModal) this.hideModal();
227
+ }
228
+ },
229
+ captureImage() {
230
+ if (this.$refs.webcam) {
231
+ this.$refs.webcam.capture().then((base64String) => {
232
+ this.upload(this.convertToFile(base64String));
233
+ this.stopCamera();
234
+ this.showCapture = false;
235
+ });
236
+ }
237
+ },
238
+ convertToFile(base64String) {
239
+ const base64Data = base64String.split(',')[1];
240
+ const base64ToByte = (char) => {
241
+ const charCode = char.charCodeAt(0);
242
+
243
+ if (charCode >= 65 && charCode <= 90) {
244
+ return charCode - 65; // A-Z
245
+ } else if (charCode >= 97 && charCode <= 122) {
246
+ return charCode - 71; // a-z
247
+ } else if (charCode >= 48 && charCode <= 57) {
248
+ return charCode + 4; // 0-9
249
+ } else if (charCode === 43) {
250
+ return 62; // +
251
+ } else if (charCode === 47) {
252
+ return 63; // /
253
+ }
254
+
255
+ return 0; // Caracteres inválidos
256
+ };
257
+
258
+ const byteArray = new Uint8Array(base64Data.length / 4 * 3);
259
+ for (let i = 0, j = 0; i < base64Data.length; i += 4, j += 3) {
260
+ const block = (
261
+ (base64ToByte(base64Data[i]) << 18) |
262
+ (base64ToByte(base64Data[i + 1]) << 12) |
263
+ (base64ToByte(base64Data[i + 2]) << 6) |
264
+ base64ToByte(base64Data[i + 3])
265
+ );
266
+
267
+ byteArray[j] = (block >> 16) & 0xff;
268
+ byteArray[j + 1] = (block >> 8) & 0xff;
269
+ byteArray[j + 2] = block & 0xff;
270
+ }
271
+
272
+ const blob = new Blob([byteArray], { type: 'image/png' });
273
+ return new File([blob], "imagem.png", { type: 'image/png' });
274
+
275
+ }
276
+ },
277
+ computed: {
278
+ ...mapGetters("generic", ["showModal"]),
279
+ },
280
+ };
281
+ </script>
282
+
283
+ <style scoped>
284
+ .file {
285
+ position: relative;
286
+ overflow: hidden;
287
+ display: inline-block;
288
+ cursor: pointer;
289
+ }
290
+
291
+ .button {
292
+ padding: 8px 12px;
293
+ cursor: pointer;
294
+ border: none;
295
+ border-radius: 40px !important;
296
+ font-size: 14px;
297
+ font-weight: 400;
298
+ margin-left: 10px;
299
+ }
300
+
301
+ .primary {
302
+ background: #577696;
303
+ border-color: #577696;
304
+ color: #fff;
305
+ }
306
+
307
+ .primary:hover {
308
+ background: #355472;
309
+ }
310
+
311
+ .danger {
312
+ background: red;
313
+ border-color: red;
314
+ color: #fff;
315
+ }
316
+
317
+ .file input[type="file"] {
318
+ font-size: 100px;
319
+ position: absolute;
320
+ left: 0;
321
+ top: 0;
322
+ opacity: 0;
323
+ }
324
+
325
+ .div-image {
326
+ cursor: pointer;
327
+ }
328
+
329
+
330
+ .small {
331
+ padding: 3px 8px;
332
+ font-size: 13px;
333
+ }
334
+
335
+ .box-file {
336
+ width: 120px !important;
337
+ height: 110px !important;
338
+ border: 1px solid #e8eaed;
339
+ background-color: #fff;
340
+ border-radius: 13px;
341
+ margin: 10px;
342
+ font-size: 23px;
343
+ font-weight: 400;
344
+ align-items: center;
345
+ justify-content: center;
346
+ }
347
+
348
+ .img {
349
+ margin: 10px;
350
+ width: 45px;
351
+ height: 45px;
352
+ }
353
+
354
+ .img-selected {
355
+ width: 80%;
356
+ }
357
+
358
+ .icon-generic {
359
+ font-size: 16px;
360
+ }
361
+
362
+ .name {
363
+ font-size: 12px;
364
+ width: 50px;
365
+ white-space: nowrap;
366
+ text-overflow: ellipsis;
367
+ }
368
+
369
+ .icon {
370
+ font-size: 20px;
371
+ cursor: pointer;
372
+ padding: 5px;
373
+ }
374
+
375
+ .icon-close {
376
+ color: red;
377
+ }
378
+
379
+ .icon-confirm {
380
+ color: green;
381
+ }
382
+
383
+ .title-file {
384
+ font-size: 18px;
385
+ margin-bottom: 20px;
386
+ }
387
+
388
+ .div-btn {
389
+ margin-bottom: 50px;
390
+ }
391
+ </style>