@7365admin1/layer-common 3.1.2-staging.30 → 3.1.2-staging.31
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/components/EntryPassMain.vue +364 -304
- package/package.json +1 -1
|
@@ -5,169 +5,128 @@
|
|
|
5
5
|
:height="'200px'"
|
|
6
6
|
v-if="loading"
|
|
7
7
|
/>
|
|
8
|
-
<v-row no-gutters
|
|
8
|
+
<v-row no-gutters v-if="!loading">
|
|
9
9
|
<v-col cols="12" elevation="3" class="border">
|
|
10
|
-
<v-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
</
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
placed in close proximity (typically within 4 cm).
|
|
38
|
-
</span>
|
|
39
|
-
</p>
|
|
40
|
-
<v-switch
|
|
41
|
-
color="success"
|
|
42
|
-
hide-details
|
|
43
|
-
v-model="currentEntryPassSettings.nfcPass"
|
|
44
|
-
@update:modelValue="updateEntryPassSettingsNfcPass()"
|
|
45
|
-
></v-switch>
|
|
46
|
-
</div>
|
|
47
|
-
<v-divider thickness="1"></v-divider>
|
|
48
|
-
<div class="d-flex w-100 mt-7 pb-10">
|
|
49
|
-
<p class="font-weight-medium flex-grow-1">
|
|
50
|
-
Upload Access Cards Template
|
|
51
|
-
<span class="d-block text-caption text-grey-darken-1 mt-1">
|
|
52
|
-
<a
|
|
53
|
-
v-if="currentEntryPassSettings.template?.id"
|
|
54
|
-
href="#"
|
|
55
|
-
class="text-truncate d-flex items-center text-decoration-none"
|
|
56
|
-
@click.prevent="downloadTemplate"
|
|
57
|
-
>
|
|
58
|
-
<v-icon class="mr-2" size="24px">mdi-paperclip</v-icon>
|
|
59
|
-
{{ currentEntryPassSettings.template.name }}
|
|
60
|
-
</a>
|
|
61
|
-
</span>
|
|
62
|
-
</p>
|
|
63
|
-
<div class="d-flex align-center" style="margin-left: auto; gap: 8px">
|
|
64
|
-
<v-btn
|
|
65
|
-
v-if="!currentEntryPassSettings.template?.id"
|
|
66
|
-
variant="flat"
|
|
67
|
-
color="primary"
|
|
68
|
-
size="small"
|
|
69
|
-
style="height: 40px"
|
|
70
|
-
prepend-icon="mdi-tray-arrow-up"
|
|
71
|
-
:loading="uploadingTemplate"
|
|
72
|
-
@click="triggerTemplateUpload"
|
|
73
|
-
>
|
|
74
|
-
Upload
|
|
75
|
-
</v-btn>
|
|
76
|
-
<v-btn
|
|
77
|
-
v-if="currentEntryPassSettings.template?.id"
|
|
78
|
-
variant="flat"
|
|
79
|
-
color="error"
|
|
80
|
-
size="small"
|
|
81
|
-
style="height: 40px"
|
|
82
|
-
prepend-icon="mdi-file-document-remove-outline"
|
|
83
|
-
:loading="uploadingTemplate"
|
|
84
|
-
@click="removeTemplate"
|
|
85
|
-
>
|
|
86
|
-
Remove
|
|
87
|
-
</v-btn>
|
|
88
|
-
</div>
|
|
89
|
-
<input
|
|
90
|
-
type="file"
|
|
91
|
-
ref="templateFileInput"
|
|
92
|
-
accept=".xlsx,.xls"
|
|
93
|
-
style="display: none"
|
|
94
|
-
@change="handleTemplateUpload"
|
|
95
|
-
/>
|
|
96
|
-
</div>
|
|
97
|
-
<v-divider thickness="1"></v-divider>
|
|
98
|
-
<div class="d-flex w-100 mt-7 pb-10">
|
|
99
|
-
<p class="font-weight-medium flex-grow-1">
|
|
100
|
-
Printer Setup
|
|
10
|
+
<v-tabs v-model="activeTab" color="primary" class="px-2">
|
|
11
|
+
<v-tab value="general">
|
|
12
|
+
<v-icon start>mdi-cog-outline</v-icon>
|
|
13
|
+
General
|
|
14
|
+
</v-tab>
|
|
15
|
+
<v-tab value="qrcode">
|
|
16
|
+
<v-icon start>mdi-qrcode</v-icon>
|
|
17
|
+
QR Code
|
|
18
|
+
</v-tab>
|
|
19
|
+
<v-tab value="printer">
|
|
20
|
+
<v-icon start>mdi-printer</v-icon>
|
|
21
|
+
Printer
|
|
22
|
+
</v-tab>
|
|
23
|
+
<v-tab value="entrypass">
|
|
24
|
+
<v-icon start>mdi-link-variant</v-icon>
|
|
25
|
+
Entrypass
|
|
26
|
+
</v-tab>
|
|
27
|
+
</v-tabs>
|
|
28
|
+
|
|
29
|
+
<v-divider />
|
|
30
|
+
|
|
31
|
+
<v-window v-model="activeTab">
|
|
32
|
+
<!-- ─── Tab 1: General ─────────────────────────────────── -->
|
|
33
|
+
<v-window-item value="general">
|
|
34
|
+
<v-row no-gutters class="px-6 pt-4">
|
|
35
|
+
|
|
36
|
+
<!-- NFC / QR Code Pass -->
|
|
101
37
|
<v-col cols="12">
|
|
102
|
-
<
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
38
|
+
<div class="d-flex mt-3 pb-5 pr-5">
|
|
39
|
+
<p class="mr-6 font-weight-medium flex-grow-1">
|
|
40
|
+
NFC / QR Code Pass
|
|
41
|
+
<span class="d-block text-caption text-grey-darken-1 mt-1">
|
|
42
|
+
NFC Card Pass uses Near Field Communication (NFC) technology
|
|
43
|
+
to enable secure and convenient entry within ~4 cm proximity.
|
|
44
|
+
</span>
|
|
45
|
+
</p>
|
|
46
|
+
<v-switch
|
|
47
|
+
color="success"
|
|
48
|
+
hide-details
|
|
49
|
+
v-model="currentEntryPassSettings.nfcPass"
|
|
50
|
+
@update:modelValue="updateEntryPassSettingsNfcPass()"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
53
|
+
</v-col>
|
|
54
|
+
|
|
55
|
+
<v-divider />
|
|
56
|
+
|
|
57
|
+
<!-- Access Door / Lift -->
|
|
58
|
+
<v-col cols="12">
|
|
59
|
+
<div class="mt-5 pb-5">
|
|
60
|
+
<p class="font-weight-medium mb-1">
|
|
61
|
+
Access Door / Lift
|
|
62
|
+
<span class="d-block text-caption text-grey-darken-1 mt-1">
|
|
63
|
+
Choose the access method(s) for door and lift control.
|
|
64
|
+
At least one method must be enabled.
|
|
65
|
+
</span>
|
|
66
|
+
</p>
|
|
67
|
+
|
|
68
|
+
<v-alert
|
|
69
|
+
v-if="accessDoorSaveAttempted && !accessDoorValid"
|
|
70
|
+
type="error"
|
|
71
|
+
variant="tonal"
|
|
72
|
+
density="compact"
|
|
73
|
+
class="my-3"
|
|
74
|
+
>
|
|
75
|
+
At least one access method (QR Code or Bluetooth) must be enabled.
|
|
76
|
+
</v-alert>
|
|
77
|
+
|
|
78
|
+
<div class="d-flex align-center py-3 pr-5">
|
|
79
|
+
<v-icon class="mr-3" color="primary">mdi-qrcode-scan</v-icon>
|
|
80
|
+
<span class="flex-grow-1 font-weight-medium">QR Code</span>
|
|
81
|
+
<v-switch
|
|
82
|
+
color="success"
|
|
114
83
|
hide-details
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<v-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
height="48"
|
|
126
|
-
:loading="scanningPrinter"
|
|
127
|
-
@click="scanPrinter()"
|
|
128
|
-
>
|
|
129
|
-
Scan Printer
|
|
130
|
-
</v-btn>
|
|
131
|
-
</v-col>
|
|
132
|
-
<v-col cols="3" class="d-flex align-end pr-0">
|
|
133
|
-
<v-btn
|
|
84
|
+
v-model="currentEntryPassSettings.accessDoorQrCode"
|
|
85
|
+
/>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<v-divider />
|
|
89
|
+
|
|
90
|
+
<div class="d-flex align-center py-3 pr-5">
|
|
91
|
+
<v-icon class="mr-3" color="primary">mdi-bluetooth</v-icon>
|
|
92
|
+
<span class="flex-grow-1 font-weight-medium">Bluetooth</span>
|
|
93
|
+
<v-switch
|
|
134
94
|
color="success"
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
>
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
>
|
|
155
|
-
Save Settings
|
|
156
|
-
</v-btn>
|
|
157
|
-
</v-col>
|
|
158
|
-
</v-row>
|
|
95
|
+
hide-details
|
|
96
|
+
v-model="currentEntryPassSettings.accessDoorBluetooth"
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<v-row class="mt-2">
|
|
101
|
+
<v-col cols="12" md="3">
|
|
102
|
+
<v-btn
|
|
103
|
+
color="primary"
|
|
104
|
+
variant="flat"
|
|
105
|
+
prepend-icon="mdi-content-save"
|
|
106
|
+
block
|
|
107
|
+
@click="saveAccessDoorSettings()"
|
|
108
|
+
>
|
|
109
|
+
Save
|
|
110
|
+
</v-btn>
|
|
111
|
+
</v-col>
|
|
112
|
+
</v-row>
|
|
113
|
+
</div>
|
|
159
114
|
</v-col>
|
|
160
|
-
</p>
|
|
161
|
-
</div>
|
|
162
115
|
|
|
163
|
-
|
|
116
|
+
</v-row>
|
|
117
|
+
</v-window-item>
|
|
118
|
+
|
|
119
|
+
<!-- ─── Tab 2: QR Code ────────────────────────────────── -->
|
|
120
|
+
<v-window-item value="qrcode">
|
|
121
|
+
<v-row no-gutters class="px-6 pt-4">
|
|
164
122
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
123
|
+
<!-- QR Code Template -->
|
|
124
|
+
<v-col cols="12">
|
|
125
|
+
<div class="mt-3 pb-5">
|
|
126
|
+
<p class="font-weight-medium mb-3">
|
|
127
|
+
QR Code Template
|
|
128
|
+
</p>
|
|
129
|
+
<v-row no-gutters>
|
|
171
130
|
<v-col cols="12" class="pr-0">
|
|
172
131
|
<v-text-field
|
|
173
132
|
label="Header"
|
|
@@ -176,131 +135,188 @@
|
|
|
176
135
|
density="comfortable"
|
|
177
136
|
clearable
|
|
178
137
|
v-model="currentEntryPassSettings.qrCodeTemplateHeader"
|
|
179
|
-
|
|
138
|
+
/>
|
|
180
139
|
</v-col>
|
|
181
|
-
<v-col cols="12" class="pr-0">
|
|
140
|
+
<v-col cols="12" class="pr-0 mt-3">
|
|
182
141
|
<v-text-field
|
|
183
142
|
label="Subtext"
|
|
184
|
-
placeholder="Enter
|
|
143
|
+
placeholder="Enter QR code sub header"
|
|
185
144
|
hide-details
|
|
186
145
|
density="comfortable"
|
|
187
146
|
clearable
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
147
|
+
v-model="currentEntryPassSettings.qrCodeTemplateHeaderSubText"
|
|
148
|
+
/>
|
|
149
|
+
</v-col>
|
|
150
|
+
<v-col cols="12">
|
|
151
|
+
<v-row class="mt-3">
|
|
152
|
+
<v-col cols="12" md="3">
|
|
153
|
+
<v-btn
|
|
154
|
+
color="success"
|
|
155
|
+
variant="flat"
|
|
156
|
+
prepend-icon="mdi-eye"
|
|
157
|
+
block
|
|
158
|
+
@click="isShowTemplatePreview = true"
|
|
159
|
+
>
|
|
160
|
+
Preview
|
|
161
|
+
</v-btn>
|
|
162
|
+
</v-col>
|
|
163
|
+
<v-col cols="12" md="3">
|
|
164
|
+
<v-btn
|
|
165
|
+
color="primary"
|
|
166
|
+
variant="flat"
|
|
167
|
+
prepend-icon="mdi-content-save"
|
|
168
|
+
block
|
|
169
|
+
@click="saveQrCodeTemplate()"
|
|
170
|
+
>
|
|
171
|
+
Save
|
|
172
|
+
</v-btn>
|
|
173
|
+
</v-col>
|
|
174
|
+
</v-row>
|
|
193
175
|
</v-col>
|
|
194
|
-
<v-row class="mt-3">
|
|
195
|
-
<v-col cols="12" md="3">
|
|
196
|
-
<v-btn color="success" variant="flat" prepend-icon="mdi-eye" block @click="isShowTemplatePreview = true">
|
|
197
|
-
Preview
|
|
198
|
-
</v-btn>
|
|
199
|
-
</v-col>
|
|
200
|
-
<v-col cols="12" md="3">
|
|
201
|
-
<v-btn
|
|
202
|
-
color="primary"
|
|
203
|
-
variant="flat"
|
|
204
|
-
prepend-icon="mdi-qrcode"
|
|
205
|
-
block
|
|
206
|
-
@click="saveQrCodeTemplate()"
|
|
207
|
-
>
|
|
208
|
-
Save
|
|
209
|
-
</v-btn>
|
|
210
|
-
</v-col>
|
|
211
|
-
</v-row>
|
|
212
176
|
</v-row>
|
|
213
|
-
</
|
|
214
|
-
</
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
<v-col cols="12" md="3">
|
|
177
|
+
</div>
|
|
178
|
+
</v-col>
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
</v-row>
|
|
182
|
+
</v-window-item>
|
|
183
|
+
|
|
184
|
+
<!-- ─── Tab 3: Printer ────────────────────────────────── -->
|
|
185
|
+
<v-window-item value="printer">
|
|
186
|
+
<v-row no-gutters class="px-6 pt-4">
|
|
187
|
+
|
|
188
|
+
<!-- Upload Access Cards Template -->
|
|
189
|
+
<v-col cols="12">
|
|
190
|
+
<div class="d-flex mt-3 pb-5">
|
|
191
|
+
<p class="font-weight-medium flex-grow-1">
|
|
192
|
+
Upload Access Cards Template
|
|
193
|
+
<span class="d-block text-caption text-grey-darken-1 mt-1">
|
|
194
|
+
<a
|
|
195
|
+
v-if="currentEntryPassSettings.template?.id"
|
|
196
|
+
href="#"
|
|
197
|
+
class="text-truncate d-flex items-center text-decoration-none"
|
|
198
|
+
@click.prevent="downloadTemplate"
|
|
199
|
+
>
|
|
200
|
+
<v-icon class="mr-2" size="24px">mdi-paperclip</v-icon>
|
|
201
|
+
{{ currentEntryPassSettings.template.name }}
|
|
202
|
+
</a>
|
|
203
|
+
</span>
|
|
204
|
+
</p>
|
|
205
|
+
<div class="d-flex align-center" style="margin-left: auto; gap: 8px">
|
|
243
206
|
<v-btn
|
|
207
|
+
v-if="!currentEntryPassSettings.template?.id"
|
|
208
|
+
variant="flat"
|
|
244
209
|
color="primary"
|
|
210
|
+
size="small"
|
|
211
|
+
style="height: 40px"
|
|
212
|
+
prepend-icon="mdi-tray-arrow-up"
|
|
213
|
+
:loading="uploadingTemplate"
|
|
214
|
+
@click="triggerTemplateUpload"
|
|
215
|
+
>
|
|
216
|
+
Upload
|
|
217
|
+
</v-btn>
|
|
218
|
+
<v-btn
|
|
219
|
+
v-if="currentEntryPassSettings.template?.id"
|
|
245
220
|
variant="flat"
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
221
|
+
color="error"
|
|
222
|
+
size="small"
|
|
223
|
+
style="height: 40px"
|
|
224
|
+
prepend-icon="mdi-file-document-remove-outline"
|
|
225
|
+
:loading="uploadingTemplate"
|
|
226
|
+
@click="removeTemplate"
|
|
249
227
|
>
|
|
250
|
-
|
|
228
|
+
Remove
|
|
251
229
|
</v-btn>
|
|
252
|
-
</
|
|
253
|
-
|
|
230
|
+
</div>
|
|
231
|
+
<input
|
|
232
|
+
type="file"
|
|
233
|
+
ref="templateFileInput"
|
|
234
|
+
accept=".xlsx,.xls"
|
|
235
|
+
style="display: none"
|
|
236
|
+
@change="handleTemplateUpload"
|
|
237
|
+
/>
|
|
238
|
+
</div>
|
|
254
239
|
</v-col>
|
|
255
|
-
</p>
|
|
256
|
-
</div>
|
|
257
240
|
|
|
258
|
-
|
|
241
|
+
<v-divider />
|
|
259
242
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
label="Disclaimer Message"
|
|
269
|
-
placeholder="Enter disclaimer message for resident app"
|
|
243
|
+
<!-- Printer Setup -->
|
|
244
|
+
<v-col cols="12">
|
|
245
|
+
<div class="mt-5 pb-5">
|
|
246
|
+
<p class="font-weight-medium mb-3">Printer Setup</p>
|
|
247
|
+
<v-row align="center">
|
|
248
|
+
<v-col cols="12" md="3">
|
|
249
|
+
<v-text-field
|
|
250
|
+
label="Vendor ID"
|
|
270
251
|
hide-details
|
|
271
|
-
density="comfortable"
|
|
272
252
|
clearable
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
253
|
+
v-model="currentEntryPassSettings.printerVendorId"
|
|
254
|
+
/>
|
|
255
|
+
</v-col>
|
|
256
|
+
<v-col cols="12" md="3">
|
|
257
|
+
<v-text-field
|
|
258
|
+
label="Product ID"
|
|
259
|
+
hide-details
|
|
260
|
+
clearable
|
|
261
|
+
v-model="currentEntryPassSettings.printerProductId"
|
|
262
|
+
/>
|
|
263
|
+
</v-col>
|
|
264
|
+
<v-col cols="12" md="3" class="d-flex align-end">
|
|
265
|
+
<v-btn
|
|
266
|
+
color="primary"
|
|
267
|
+
variant="outlined"
|
|
268
|
+
prepend-icon="mdi-magnify"
|
|
269
|
+
block
|
|
270
|
+
height="48"
|
|
271
|
+
:loading="scanningPrinter"
|
|
272
|
+
@click="scanPrinter()"
|
|
273
|
+
>
|
|
274
|
+
Scan Printer
|
|
275
|
+
</v-btn>
|
|
276
|
+
</v-col>
|
|
277
|
+
<v-col cols="12" md="3" class="d-flex align-end pr-0">
|
|
278
|
+
<v-btn
|
|
279
|
+
color="success"
|
|
280
|
+
variant="outlined"
|
|
281
|
+
prepend-icon="mdi-printer-check"
|
|
282
|
+
block
|
|
283
|
+
height="48"
|
|
284
|
+
:loading="testingPrinter"
|
|
285
|
+
@click="testAndPrint()"
|
|
286
|
+
>
|
|
287
|
+
Test & Print
|
|
288
|
+
</v-btn>
|
|
277
289
|
</v-col>
|
|
278
|
-
<v-row class="mt-3">
|
|
279
|
-
<v-col cols="12" md="3">
|
|
280
|
-
<v-btn
|
|
281
|
-
color="primary"
|
|
282
|
-
variant="flat"
|
|
283
|
-
prepend-icon="mdi-message-text-outline"
|
|
284
|
-
block
|
|
285
|
-
@click="saveResidentAppDisclaimerMsg()"
|
|
286
|
-
>
|
|
287
|
-
Save
|
|
288
|
-
</v-btn>
|
|
289
|
-
</v-col>
|
|
290
|
-
</v-row>
|
|
291
290
|
</v-row>
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
291
|
+
<v-row class="mt-4">
|
|
292
|
+
<v-col cols="12" md="3">
|
|
293
|
+
<v-btn
|
|
294
|
+
color="primary"
|
|
295
|
+
variant="flat"
|
|
296
|
+
prepend-icon="mdi-content-save"
|
|
297
|
+
block
|
|
298
|
+
@click="savePrinterSettings()"
|
|
299
|
+
>
|
|
300
|
+
Save Settings
|
|
301
|
+
</v-btn>
|
|
302
|
+
</v-col>
|
|
303
|
+
</v-row>
|
|
304
|
+
</div>
|
|
305
|
+
</v-col>
|
|
306
|
+
|
|
307
|
+
</v-row>
|
|
308
|
+
</v-window-item>
|
|
309
|
+
|
|
310
|
+
<!-- ─── Tab 4: Entrypass ──────────────────────────────── -->
|
|
311
|
+
<v-window-item value="entrypass">
|
|
312
|
+
<v-row no-gutters class="px-6 pt-4">
|
|
313
|
+
|
|
314
|
+
<!-- Entrypass URL -->
|
|
315
|
+
<v-col cols="12">
|
|
316
|
+
<div class="mt-3 pb-5">
|
|
317
|
+
<p class="font-weight-medium mb-3">
|
|
318
|
+
Entrypass URL
|
|
319
|
+
</p>
|
|
304
320
|
<v-text-field
|
|
305
321
|
label="Enter entrypass URL"
|
|
306
322
|
placeholder="https://your-entrypass-socket-url.com"
|
|
@@ -309,14 +325,60 @@
|
|
|
309
325
|
hide-details
|
|
310
326
|
v-model="currentEntryPassSettings.url"
|
|
311
327
|
/>
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
328
|
+
<v-row class="mt-3">
|
|
329
|
+
<v-col cols="12" md="3">
|
|
330
|
+
<v-btn
|
|
331
|
+
color="primary"
|
|
332
|
+
variant="flat"
|
|
333
|
+
prepend-icon="mdi-link-variant"
|
|
334
|
+
block
|
|
335
|
+
@click="saveEntryPassUrl()"
|
|
336
|
+
>
|
|
337
|
+
Save
|
|
338
|
+
</v-btn>
|
|
339
|
+
</v-col>
|
|
340
|
+
</v-row>
|
|
341
|
+
</div>
|
|
342
|
+
</v-col>
|
|
343
|
+
|
|
344
|
+
<v-divider />
|
|
345
|
+
|
|
346
|
+
<!-- Resident-app Disclaimer Message -->
|
|
347
|
+
<v-col cols="12">
|
|
348
|
+
<div class="mt-5 pb-5">
|
|
349
|
+
<p class="font-weight-medium mb-1">
|
|
350
|
+
Resident-app Disclaimer Message
|
|
351
|
+
</p>
|
|
352
|
+
<v-textarea
|
|
353
|
+
label="Disclaimer Message"
|
|
354
|
+
placeholder="Enter disclaimer message for resident app"
|
|
355
|
+
hide-details
|
|
356
|
+
density="comfortable"
|
|
357
|
+
clearable
|
|
358
|
+
rows="5"
|
|
359
|
+
auto-grow
|
|
360
|
+
class="mt-3"
|
|
361
|
+
v-model="currentEntryPassSettings.disclaimerMessage"
|
|
362
|
+
/>
|
|
363
|
+
<v-row class="mt-3">
|
|
364
|
+
<v-col cols="12" md="3">
|
|
365
|
+
<v-btn
|
|
366
|
+
color="primary"
|
|
367
|
+
variant="flat"
|
|
368
|
+
prepend-icon="mdi-content-save"
|
|
369
|
+
block
|
|
370
|
+
@click="saveResidentAppDisclaimerMsg()"
|
|
371
|
+
>
|
|
372
|
+
Save
|
|
373
|
+
</v-btn>
|
|
374
|
+
</v-col>
|
|
375
|
+
</v-row>
|
|
376
|
+
</div>
|
|
377
|
+
</v-col>
|
|
378
|
+
|
|
379
|
+
</v-row>
|
|
380
|
+
</v-window-item>
|
|
381
|
+
</v-window>
|
|
320
382
|
</v-col>
|
|
321
383
|
|
|
322
384
|
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
@@ -328,27 +390,16 @@
|
|
|
328
390
|
/>
|
|
329
391
|
</v-row>
|
|
330
392
|
</template>
|
|
393
|
+
|
|
331
394
|
<script lang="ts" setup>
|
|
332
|
-
definePageMeta({
|
|
333
|
-
middleware: ["01-auth", "02-org"],
|
|
334
|
-
memberOnly: true,
|
|
335
|
-
});
|
|
336
395
|
const prop = defineProps({
|
|
337
|
-
site: {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
},
|
|
341
|
-
siteName: {
|
|
342
|
-
type: String,
|
|
343
|
-
required: true,
|
|
344
|
-
},
|
|
345
|
-
|
|
346
|
-
orgId: {
|
|
347
|
-
type: String,
|
|
348
|
-
required: true,
|
|
349
|
-
},
|
|
396
|
+
site: { type: String, required: true },
|
|
397
|
+
siteName: { type: String, required: true },
|
|
398
|
+
orgId: { type: String, required: true },
|
|
350
399
|
});
|
|
351
400
|
|
|
401
|
+
const activeTab = ref("general");
|
|
402
|
+
|
|
352
403
|
const currentEntryPassSettings = ref<Record<string, any>>({
|
|
353
404
|
_id: "",
|
|
354
405
|
site: "",
|
|
@@ -361,6 +412,8 @@ const currentEntryPassSettings = ref<Record<string, any>>({
|
|
|
361
412
|
nfcPass: false,
|
|
362
413
|
qrPass: false,
|
|
363
414
|
keyPass: false,
|
|
415
|
+
accessDoorQrCode: false,
|
|
416
|
+
accessDoorBluetooth: false,
|
|
364
417
|
printerVendorId: "",
|
|
365
418
|
printerProductId: "",
|
|
366
419
|
qrCodeTemplateHeader: "",
|
|
@@ -378,6 +431,13 @@ const currentEntryPassSettings = ref<Record<string, any>>({
|
|
|
378
431
|
deletedAt: "",
|
|
379
432
|
});
|
|
380
433
|
|
|
434
|
+
const accessDoorSaveAttempted = ref(false);
|
|
435
|
+
const accessDoorValid = computed(
|
|
436
|
+
() =>
|
|
437
|
+
currentEntryPassSettings.value.accessDoorQrCode ||
|
|
438
|
+
currentEntryPassSettings.value.accessDoorBluetooth
|
|
439
|
+
);
|
|
440
|
+
|
|
381
441
|
const {
|
|
382
442
|
getBySiteId: _getSiteEntryPassSettings,
|
|
383
443
|
save: _save,
|
|
@@ -479,10 +539,7 @@ async function testAndPrint() {
|
|
|
479
539
|
try {
|
|
480
540
|
testingPrinter.value = true;
|
|
481
541
|
const result = await testConnection(vendorId, productId);
|
|
482
|
-
showMessage(
|
|
483
|
-
result.message,
|
|
484
|
-
result.success ? "success" : "error",
|
|
485
|
-
);
|
|
542
|
+
showMessage(result.message, result.success ? "success" : "error");
|
|
486
543
|
} catch (error: any) {
|
|
487
544
|
showMessage(error.message || "Test print failed", "error");
|
|
488
545
|
} finally {
|
|
@@ -492,7 +549,6 @@ async function testAndPrint() {
|
|
|
492
549
|
|
|
493
550
|
const route = useRoute();
|
|
494
551
|
const siteId = route.params.site as string;
|
|
495
|
-
const orgId = route.params.org as string;
|
|
496
552
|
|
|
497
553
|
const message = ref("");
|
|
498
554
|
const messageSnackbar = ref(false);
|
|
@@ -525,12 +581,15 @@ watchEffect(() => {
|
|
|
525
581
|
nfcPass: data.settings?.nfcPass ?? false,
|
|
526
582
|
qrPass: data.settings?.qrPass ?? false,
|
|
527
583
|
keyPass: data.settings?.keyPass ?? false,
|
|
584
|
+
accessDoorQrCode: data.settings?.accessDoor?.qrCode ?? false,
|
|
585
|
+
accessDoorBluetooth: data.settings?.accessDoor?.bluetooth ?? false,
|
|
528
586
|
printerVendorId: data.settings?.printer?.vendorId ? String(data.settings.printer.vendorId) : "",
|
|
529
587
|
printerProductId: data.settings?.printer?.productId ? String(data.settings.printer.productId) : "",
|
|
530
588
|
qrCodeTemplateHeader: data.settings?.qrTemplate?.header ?? "",
|
|
531
589
|
qrCodeTemplateHeaderSubText: data.settings?.qrTemplate?.subText ?? "",
|
|
532
590
|
qrCodeTemplateDate: data.settings?.qrTemplate?.date ?? "",
|
|
533
591
|
qrCodeValidityMinutes: data.settings?.validityMinutes ?? null,
|
|
592
|
+
disclaimerMessage: data.settings?.disclaimerMessage ?? "",
|
|
534
593
|
url: data.settings?.url ?? "",
|
|
535
594
|
template: data.settings?.template ?? { id: "", name: "" },
|
|
536
595
|
createdAt: data.createdAt ?? "",
|
|
@@ -551,6 +610,10 @@ function buildPayload() {
|
|
|
551
610
|
nfcPass: currentEntryPassSettings.value.nfcPass,
|
|
552
611
|
qrPass: currentEntryPassSettings.value.qrPass ?? false,
|
|
553
612
|
keyPass: currentEntryPassSettings.value.keyPass ?? false,
|
|
613
|
+
accessDoor: {
|
|
614
|
+
qrCode: currentEntryPassSettings.value.accessDoorQrCode,
|
|
615
|
+
bluetooth: currentEntryPassSettings.value.accessDoorBluetooth,
|
|
616
|
+
},
|
|
554
617
|
printer: {
|
|
555
618
|
vendorId: Number(currentEntryPassSettings.value.printerVendorId) || null,
|
|
556
619
|
productId: Number(currentEntryPassSettings.value.printerProductId) || null,
|
|
@@ -561,6 +624,7 @@ function buildPayload() {
|
|
|
561
624
|
date: currentEntryPassSettings.value.qrCodeTemplateDate || null,
|
|
562
625
|
},
|
|
563
626
|
validityMinutes: currentEntryPassSettings.value.qrCodeValidityMinutes || null,
|
|
627
|
+
disclaimerMessage: currentEntryPassSettings.value.disclaimerMessage || "",
|
|
564
628
|
url: currentEntryPassSettings.value.url,
|
|
565
629
|
template: currentEntryPassSettings.value.template?.id
|
|
566
630
|
? currentEntryPassSettings.value.template
|
|
@@ -569,45 +633,41 @@ function buildPayload() {
|
|
|
569
633
|
};
|
|
570
634
|
}
|
|
571
635
|
|
|
572
|
-
async function
|
|
636
|
+
async function updateEntryPassSettingsNfcPass() {
|
|
573
637
|
await _save(buildPayload());
|
|
574
638
|
showMessage("Entry Pass Settings updated successfully!", "success");
|
|
575
639
|
getSiteEntryPassSettings();
|
|
576
640
|
}
|
|
577
641
|
|
|
578
|
-
async function
|
|
642
|
+
async function saveAccessDoorSettings() {
|
|
643
|
+
accessDoorSaveAttempted.value = true;
|
|
644
|
+
if (!accessDoorValid.value) return;
|
|
579
645
|
await _save(buildPayload());
|
|
580
|
-
showMessage("
|
|
646
|
+
showMessage("Access door settings saved successfully!", "success");
|
|
581
647
|
getSiteEntryPassSettings();
|
|
582
648
|
}
|
|
583
649
|
|
|
584
650
|
async function savePrinterSettings() {
|
|
585
651
|
await _save(buildPayload());
|
|
586
|
-
showMessage("
|
|
652
|
+
showMessage("Printer settings saved successfully!", "success");
|
|
587
653
|
getSiteEntryPassSettings();
|
|
588
654
|
}
|
|
589
655
|
|
|
590
656
|
async function saveQrCodeTemplate() {
|
|
591
657
|
await _save(buildPayload());
|
|
592
|
-
showMessage("
|
|
593
|
-
getSiteEntryPassSettings();
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
async function saveQrCodeValidity() {
|
|
597
|
-
await _save(buildPayload());
|
|
598
|
-
showMessage("Entry Pass Settings updated successfully!", "success");
|
|
658
|
+
showMessage("QR code template saved successfully!", "success");
|
|
599
659
|
getSiteEntryPassSettings();
|
|
600
660
|
}
|
|
601
661
|
|
|
602
662
|
async function saveResidentAppDisclaimerMsg() {
|
|
603
663
|
await _save(buildPayload());
|
|
604
|
-
showMessage("
|
|
664
|
+
showMessage("Disclaimer message saved successfully!", "success");
|
|
605
665
|
getSiteEntryPassSettings();
|
|
606
666
|
}
|
|
607
667
|
|
|
608
668
|
async function saveEntryPassUrl() {
|
|
609
669
|
await _save(buildPayload());
|
|
610
|
-
showMessage("
|
|
670
|
+
showMessage("Entrypass URL saved successfully!", "success");
|
|
611
671
|
getSiteEntryPassSettings();
|
|
612
672
|
}
|
|
613
673
|
|