@7365admin1/layer-common 3.0.23 → 3.0.25
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/CHANGELOG.md +12 -0
- package/components/AccessCardAddForm.vue +2 -2
- package/components/AccessCardAssignToUnitForm.vue +2 -2
- package/components/AccessManagement.vue +16 -6
- package/components/BuildingUnitFormEdit.vue +1 -1
- package/components/DashboardMain.vue +29 -1
- package/components/DocumentManagement.vue +228 -1
- package/components/Nfc/NFCPatrolReportMain.vue +1 -0
- package/components/Nfc/PatrolReport/PatrolReportTab.vue +2 -1
- package/components/Nfc/PatrolReport/ReportFilters.vue +3 -1
- package/components/RolePermissionMain.vue +25 -2
- package/components/ServiceProviderMain.vue +1 -0
- package/components/VisitorForm.vue +161 -397
- package/composables/useNFCPatrolLog.ts +35 -0
- package/composables/useNFCPatrolReport.ts +37 -4
- package/composables/useNFCPatrolReportFilters.ts +28 -5
- package/composables/useServiceProvider.ts +2 -1
- package/package.json +1 -1
- package/services/nfcPatrolReport.ts +5 -1
- package/types/nfc-patrol-report.ts +7 -1
- package/types/visitor.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -650,7 +650,7 @@ watch(() => card.value.showAssign, async (newVal) => {
|
|
|
650
650
|
const response = await _getBlockLevelUnitList(siteId);
|
|
651
651
|
blockLevelUnitData.value = (response as any)?.data || [];
|
|
652
652
|
buildingItems.value = blockLevelUnitData.value.map((b: any) => ({
|
|
653
|
-
name: b.block
|
|
653
|
+
name: `${b.block} (${b.name})`,
|
|
654
654
|
value: b._id,
|
|
655
655
|
}));
|
|
656
656
|
} catch (error) {
|
|
@@ -676,7 +676,7 @@ watch(() => card.value.assignBuilding, (newVal) => {
|
|
|
676
676
|
if (newVal) {
|
|
677
677
|
const selectedBlock = blockLevelUnitData.value.find((b: any) => b._id === newVal);
|
|
678
678
|
levelItems.value = selectedBlock?.levels?.map((l: any) => ({
|
|
679
|
-
name: l.
|
|
679
|
+
name: l.name,
|
|
680
680
|
value: l._id,
|
|
681
681
|
})) || [];
|
|
682
682
|
} else {
|
|
@@ -309,7 +309,7 @@ onMounted(async () => {
|
|
|
309
309
|
if (blockLevelResult.status === "fulfilled") {
|
|
310
310
|
blockLevelUnitData.value = (blockLevelResult.value as any)?.data || [];
|
|
311
311
|
buildingItems.value = blockLevelUnitData.value.map((b: any) => ({
|
|
312
|
-
name: b.block
|
|
312
|
+
name: `${b.block} (${b.name})`,
|
|
313
313
|
value: b._id,
|
|
314
314
|
}));
|
|
315
315
|
}
|
|
@@ -352,7 +352,7 @@ watch(
|
|
|
352
352
|
const selectedBlock = blockLevelUnitData.value.find((b: any) => b._id === newVal);
|
|
353
353
|
if (selectedBlock?.levels) {
|
|
354
354
|
levelItems.value = selectedBlock.levels.map((l: any) => ({
|
|
355
|
-
name: l.
|
|
355
|
+
name: l.name,
|
|
356
356
|
value: l._id,
|
|
357
357
|
}));
|
|
358
358
|
}
|
|
@@ -152,6 +152,10 @@ const props = defineProps({
|
|
|
152
152
|
headers: {
|
|
153
153
|
type: Array as PropType<Array<Record<string, any>>>,
|
|
154
154
|
default: () => [
|
|
155
|
+
{
|
|
156
|
+
title: "Block Name",
|
|
157
|
+
value: "block.name",
|
|
158
|
+
},
|
|
155
159
|
{
|
|
156
160
|
title: "Block",
|
|
157
161
|
value: "block.block",
|
|
@@ -180,10 +184,6 @@ const props = defineProps({
|
|
|
180
184
|
title: "Asgn. (NP)",
|
|
181
185
|
value: "cardCounts.assigned.non_physical",
|
|
182
186
|
},
|
|
183
|
-
{
|
|
184
|
-
title: "Total",
|
|
185
|
-
value: "totalCardCount",
|
|
186
|
-
},
|
|
187
187
|
// { title: "Action", value: "action-table" },
|
|
188
188
|
],
|
|
189
189
|
},
|
|
@@ -234,6 +234,7 @@ const deleteLoading = ref(false);
|
|
|
234
234
|
const deleteError = ref("");
|
|
235
235
|
const confirmDialog = ref(false);
|
|
236
236
|
const searchText = ref("");
|
|
237
|
+
const debouncedSearch = ref("");
|
|
237
238
|
const replaceDialog = ref(false);
|
|
238
239
|
|
|
239
240
|
const route = useRoute();
|
|
@@ -277,16 +278,25 @@ const {
|
|
|
277
278
|
() =>
|
|
278
279
|
getUserTypeAccessCards({
|
|
279
280
|
page: page.value,
|
|
280
|
-
search:
|
|
281
|
+
search: debouncedSearch.value,
|
|
281
282
|
organization: orgId.value,
|
|
282
283
|
site: siteId.value,
|
|
283
284
|
userType: "Visitor/Resident",
|
|
284
285
|
}),
|
|
285
286
|
{
|
|
286
|
-
watch: [page,
|
|
287
|
+
watch: [page, debouncedSearch],
|
|
287
288
|
}
|
|
288
289
|
);
|
|
289
290
|
|
|
291
|
+
let debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
292
|
+
watch(searchText, (val) => {
|
|
293
|
+
page.value = 1;
|
|
294
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
295
|
+
debounceTimer = setTimeout(() => {
|
|
296
|
+
debouncedSearch.value = val;
|
|
297
|
+
}, 400);
|
|
298
|
+
});
|
|
299
|
+
|
|
290
300
|
const loading = computed(() => getAllReqStatus.value === "pending");
|
|
291
301
|
|
|
292
302
|
watchEffect(() => {
|
|
@@ -427,7 +427,7 @@ watchEffect(() => {
|
|
|
427
427
|
|
|
428
428
|
const { data: getUnitPeople, refresh: getUnitPeopleRefresh, pending: getUnitPeoplePending } = useLazyAsyncData(
|
|
429
429
|
"get-unit-people",
|
|
430
|
-
async () => await getPeopleByUnit(buildingUnit.value._id, { limit: 10, site: prop.site })
|
|
430
|
+
async () => await getPeopleByUnit(buildingUnit.value._id, { limit: 10, site: prop.site, type: "resident,tenant" })
|
|
431
431
|
);
|
|
432
432
|
|
|
433
433
|
watch(getUnitPeople, (newData: TPeople[]) => {
|
|
@@ -1355,7 +1355,16 @@
|
|
|
1355
1355
|
:key="item.status"
|
|
1356
1356
|
class="facility-booking-summary-row"
|
|
1357
1357
|
>
|
|
1358
|
-
<
|
|
1358
|
+
<button
|
|
1359
|
+
v-if="item.status === 'Pending'"
|
|
1360
|
+
class="facility-booking-summary-label facility-booking-summary-label-button"
|
|
1361
|
+
type="button"
|
|
1362
|
+
aria-label="View pending facility bookings"
|
|
1363
|
+
@click="goToFacilityBookingStatus(item.status)"
|
|
1364
|
+
>
|
|
1365
|
+
{{ item.status }}
|
|
1366
|
+
</button>
|
|
1367
|
+
<span v-else class="facility-booking-summary-label">
|
|
1359
1368
|
{{ item.status }}
|
|
1360
1369
|
</span>
|
|
1361
1370
|
<span class="facility-booking-summary-dots" />
|
|
@@ -2294,6 +2303,12 @@ function openFacilityBookingDialog() {
|
|
|
2294
2303
|
facilityBookingDialog.value = true;
|
|
2295
2304
|
}
|
|
2296
2305
|
|
|
2306
|
+
function goToFacilityBookingStatus(status: string) {
|
|
2307
|
+
if (status !== "Pending" || !props.orgId || !props.site) return;
|
|
2308
|
+
facilityBookingDialog.value = false;
|
|
2309
|
+
router.push(`${dashboardPath("facility/bookings")}?tab=Pending`);
|
|
2310
|
+
}
|
|
2311
|
+
|
|
2297
2312
|
function normalizeFacilityBookingStatus(status: unknown) {
|
|
2298
2313
|
const value = String(status || "").trim();
|
|
2299
2314
|
return value === "For Refund" ? "With Refund" : value;
|
|
@@ -4233,6 +4248,19 @@ function formatDashboardTime(value?: string) {
|
|
|
4233
4248
|
line-height: 1.25;
|
|
4234
4249
|
}
|
|
4235
4250
|
|
|
4251
|
+
.facility-booking-summary-label-button {
|
|
4252
|
+
appearance: none;
|
|
4253
|
+
background: transparent;
|
|
4254
|
+
border: 0;
|
|
4255
|
+
cursor: pointer;
|
|
4256
|
+
padding: 0;
|
|
4257
|
+
text-align: left;
|
|
4258
|
+
}
|
|
4259
|
+
|
|
4260
|
+
.facility-booking-summary-label-button:hover {
|
|
4261
|
+
text-decoration: underline;
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4236
4264
|
.facility-booking-summary-dots {
|
|
4237
4265
|
border-bottom: 2px dotted #9aa3ad;
|
|
4238
4266
|
display: block;
|
|
@@ -163,13 +163,47 @@
|
|
|
163
163
|
|
|
164
164
|
<template #item.action="{ item }">
|
|
165
165
|
<v-btn
|
|
166
|
+
v-if="!isFolderItem(item._raw)"
|
|
166
167
|
variant="flat"
|
|
167
168
|
class="table-download-btn text-none"
|
|
168
169
|
@click.stop="downloadDocument(item._raw)"
|
|
169
|
-
:disabled="isFolderItem(item._raw)"
|
|
170
170
|
>
|
|
171
171
|
Download
|
|
172
172
|
</v-btn>
|
|
173
|
+
|
|
174
|
+
<v-menu
|
|
175
|
+
v-else
|
|
176
|
+
v-model="folderActionMenu[item._raw._id]"
|
|
177
|
+
location="bottom end"
|
|
178
|
+
offset="6"
|
|
179
|
+
>
|
|
180
|
+
<template #activator="{ props }">
|
|
181
|
+
<v-btn
|
|
182
|
+
v-bind="props"
|
|
183
|
+
icon="mdi-dots-vertical"
|
|
184
|
+
variant="text"
|
|
185
|
+
size="small"
|
|
186
|
+
density="comfortable"
|
|
187
|
+
class="folder-action-btn"
|
|
188
|
+
@click.stop
|
|
189
|
+
/>
|
|
190
|
+
</template>
|
|
191
|
+
|
|
192
|
+
<v-list class="folder-action-list pa-0">
|
|
193
|
+
<v-list-item
|
|
194
|
+
class="folder-action-item"
|
|
195
|
+
@click.stop="openEditFolderDialog(item._raw)"
|
|
196
|
+
>
|
|
197
|
+
<v-list-item-title class="text-body-2">Edit</v-list-item-title>
|
|
198
|
+
</v-list-item>
|
|
199
|
+
<v-list-item
|
|
200
|
+
class="folder-action-item"
|
|
201
|
+
@click.stop="openDeleteFolderDialog(item._raw)"
|
|
202
|
+
>
|
|
203
|
+
<v-list-item-title class="text-body-2">Delete</v-list-item-title>
|
|
204
|
+
</v-list-item>
|
|
205
|
+
</v-list>
|
|
206
|
+
</v-menu>
|
|
173
207
|
</template>
|
|
174
208
|
</TableV3>
|
|
175
209
|
</v-col>
|
|
@@ -251,6 +285,125 @@
|
|
|
251
285
|
</v-card>
|
|
252
286
|
</v-dialog>
|
|
253
287
|
|
|
288
|
+
<!-- Edit Folder Dialog -->
|
|
289
|
+
<v-dialog v-model="editFolderDialog" width="450" persistent>
|
|
290
|
+
<v-card width="100%" class="folder-dialog-card">
|
|
291
|
+
<v-toolbar class="pa-0 folder-dialog-toolbar" density="compact">
|
|
292
|
+
<v-row no-gutters class="w-100">
|
|
293
|
+
<v-col cols="12" class="pa-4">
|
|
294
|
+
<span class="font-weight-medium text-h6">Edit Folder</span>
|
|
295
|
+
</v-col>
|
|
296
|
+
</v-row>
|
|
297
|
+
</v-toolbar>
|
|
298
|
+
|
|
299
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-0">
|
|
300
|
+
<v-form v-model="validEditFolderForm">
|
|
301
|
+
<v-col cols="12" class="px-6 pt-5">
|
|
302
|
+
<InputLabel title="Folder Title" />
|
|
303
|
+
<v-text-field
|
|
304
|
+
v-model.trim="editFolderTitle"
|
|
305
|
+
density="comfortable"
|
|
306
|
+
variant="outlined"
|
|
307
|
+
:rules="[(v) => !!v || 'Folder title is required']"
|
|
308
|
+
hide-details="auto"
|
|
309
|
+
/>
|
|
310
|
+
</v-col>
|
|
311
|
+
|
|
312
|
+
<v-col cols="12" class="px-6 pb-5">
|
|
313
|
+
<InputLabel title="Remarks (Optional)" />
|
|
314
|
+
<v-textarea
|
|
315
|
+
v-model.trim="editFolderRemarks"
|
|
316
|
+
density="comfortable"
|
|
317
|
+
variant="outlined"
|
|
318
|
+
rows="3"
|
|
319
|
+
placeholder="Enter remarks"
|
|
320
|
+
hide-details
|
|
321
|
+
/>
|
|
322
|
+
</v-col>
|
|
323
|
+
</v-form>
|
|
324
|
+
</v-card-text>
|
|
325
|
+
|
|
326
|
+
<v-toolbar class="pa-0" density="compact">
|
|
327
|
+
<v-row no-gutters class="w-100">
|
|
328
|
+
<v-col cols="6" class="pa-0">
|
|
329
|
+
<v-btn
|
|
330
|
+
block
|
|
331
|
+
variant="text"
|
|
332
|
+
class="text-none"
|
|
333
|
+
size="large"
|
|
334
|
+
@click="editFolderDialog = false"
|
|
335
|
+
height="48"
|
|
336
|
+
>
|
|
337
|
+
Cancel
|
|
338
|
+
</v-btn>
|
|
339
|
+
</v-col>
|
|
340
|
+
<v-col cols="6" class="pa-0">
|
|
341
|
+
<v-btn
|
|
342
|
+
block
|
|
343
|
+
color="black"
|
|
344
|
+
variant="flat"
|
|
345
|
+
class="text-none"
|
|
346
|
+
size="large"
|
|
347
|
+
@click="handleApplyFolderEdit"
|
|
348
|
+
height="48"
|
|
349
|
+
>
|
|
350
|
+
Apply
|
|
351
|
+
</v-btn>
|
|
352
|
+
</v-col>
|
|
353
|
+
</v-row>
|
|
354
|
+
</v-toolbar>
|
|
355
|
+
</v-card>
|
|
356
|
+
</v-dialog>
|
|
357
|
+
|
|
358
|
+
<!-- Delete Folder Dialog -->
|
|
359
|
+
<v-dialog v-model="deleteFolderDialog" width="450" persistent>
|
|
360
|
+
<v-card width="100%" class="folder-dialog-card">
|
|
361
|
+
<v-toolbar density="compact" class="pl-4 folder-dialog-toolbar">
|
|
362
|
+
<span class="font-weight-medium text-h6">Delete Folder</span>
|
|
363
|
+
</v-toolbar>
|
|
364
|
+
|
|
365
|
+
<v-card-text class="px-6 py-5">
|
|
366
|
+
<p class="text-subtitle-2 font-weight-medium mb-4">
|
|
367
|
+
Are you sure you want to permanently delete this folder?
|
|
368
|
+
</p>
|
|
369
|
+
<p class="text-body-2 text-grey-darken-1 mb-0">
|
|
370
|
+
This action cannot be undone and the folder will be removed
|
|
371
|
+
permanently from the system.
|
|
372
|
+
</p>
|
|
373
|
+
</v-card-text>
|
|
374
|
+
|
|
375
|
+
<v-toolbar density="compact" class="pa-0">
|
|
376
|
+
<v-row no-gutters class="w-100">
|
|
377
|
+
<v-col cols="6" class="pa-0">
|
|
378
|
+
<v-btn
|
|
379
|
+
tile
|
|
380
|
+
block
|
|
381
|
+
height="48"
|
|
382
|
+
variant="text"
|
|
383
|
+
class="text-none"
|
|
384
|
+
@click="deleteFolderDialog = false"
|
|
385
|
+
>
|
|
386
|
+
Cancel
|
|
387
|
+
</v-btn>
|
|
388
|
+
</v-col>
|
|
389
|
+
<v-col cols="6" class="pa-0">
|
|
390
|
+
<v-btn
|
|
391
|
+
tile
|
|
392
|
+
block
|
|
393
|
+
height="48"
|
|
394
|
+
color="black"
|
|
395
|
+
variant="flat"
|
|
396
|
+
class="text-none"
|
|
397
|
+
@click="handleDeleteFolderUiConfirm"
|
|
398
|
+
>
|
|
399
|
+
Confirm
|
|
400
|
+
</v-btn>
|
|
401
|
+
</v-col>
|
|
402
|
+
</v-row>
|
|
403
|
+
</v-toolbar>
|
|
404
|
+
</v-card>
|
|
405
|
+
</v-dialog>
|
|
406
|
+
|
|
254
407
|
<!-- Edit Dialog -->
|
|
255
408
|
<v-dialog v-model="editDialog" width="450" persistent>
|
|
256
409
|
<DocumentForm
|
|
@@ -689,6 +842,15 @@ const folderTitle = ref("");
|
|
|
689
842
|
const folderRemarks = ref("");
|
|
690
843
|
const folderLoading = ref(false);
|
|
691
844
|
const validFolderForm = ref(false);
|
|
845
|
+
const folderActionMenu = ref<Record<string, boolean>>({});
|
|
846
|
+
const selectedFolder = ref<(Partial<TDocument> & Record<string, any>) | null>(
|
|
847
|
+
null
|
|
848
|
+
);
|
|
849
|
+
const editFolderDialog = ref(false);
|
|
850
|
+
const deleteFolderDialog = ref(false);
|
|
851
|
+
const editFolderTitle = ref("");
|
|
852
|
+
const editFolderRemarks = ref("");
|
|
853
|
+
const validEditFolderForm = ref(false);
|
|
692
854
|
|
|
693
855
|
// fileTypes and selectedFileType are declared above to allow
|
|
694
856
|
// the fetch to include the selected filter.
|
|
@@ -849,6 +1011,40 @@ function openCreateFolderDialog() {
|
|
|
849
1011
|
createFolderDialog.value = true;
|
|
850
1012
|
}
|
|
851
1013
|
|
|
1014
|
+
function closeFolderActionMenu(folderId?: string) {
|
|
1015
|
+
if (!folderId) {
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
folderActionMenu.value[folderId] = false;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function openEditFolderDialog(
|
|
1023
|
+
folder: Partial<TDocument> & Record<string, any>
|
|
1024
|
+
) {
|
|
1025
|
+
selectedFolder.value = folder;
|
|
1026
|
+
editFolderTitle.value = String(folder.name || "");
|
|
1027
|
+
editFolderRemarks.value = String(folder.remarks || "");
|
|
1028
|
+
editFolderDialog.value = true;
|
|
1029
|
+
closeFolderActionMenu(String(folder._id || ""));
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
function openDeleteFolderDialog(
|
|
1033
|
+
folder: Partial<TDocument> & Record<string, any>
|
|
1034
|
+
) {
|
|
1035
|
+
selectedFolder.value = folder;
|
|
1036
|
+
deleteFolderDialog.value = true;
|
|
1037
|
+
closeFolderActionMenu(String(folder._id || ""));
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
function handleApplyFolderEdit() {
|
|
1041
|
+
editFolderDialog.value = false;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
function handleDeleteFolderUiConfirm() {
|
|
1045
|
+
deleteFolderDialog.value = false;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
852
1048
|
async function handleCreateFolder() {
|
|
853
1049
|
if (!folderTitle.value) {
|
|
854
1050
|
showMessage("Folder title is required", "error");
|
|
@@ -977,4 +1173,35 @@ function selectFileType(type: string) {
|
|
|
977
1173
|
border-radius: 8px;
|
|
978
1174
|
background: #fafafa;
|
|
979
1175
|
}
|
|
1176
|
+
|
|
1177
|
+
.folder-action-btn {
|
|
1178
|
+
color: #38475a;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
.folder-action-list {
|
|
1182
|
+
min-width: 180px;
|
|
1183
|
+
border-radius: 8px;
|
|
1184
|
+
background: #fff;
|
|
1185
|
+
box-shadow: 0 10px 28px rgba(15, 23, 42, 0.22);
|
|
1186
|
+
overflow: hidden;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
.folder-action-item {
|
|
1190
|
+
min-height: 40px;
|
|
1191
|
+
border-bottom: 1px solid #eef0f2;
|
|
1192
|
+
color: #38475a;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
.folder-action-item:last-child {
|
|
1196
|
+
border-bottom: none;
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
.folder-dialog-card {
|
|
1200
|
+
border-radius: 6px;
|
|
1201
|
+
overflow: hidden;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
.folder-dialog-toolbar {
|
|
1205
|
+
border-bottom: 1px solid #eef0f2;
|
|
1206
|
+
}
|
|
980
1207
|
</style>
|
|
@@ -43,6 +43,7 @@ import ReportLocationHeader from "./ReportLocationHeader.vue";
|
|
|
43
43
|
|
|
44
44
|
const props = defineProps<{
|
|
45
45
|
active: boolean;
|
|
46
|
+
site: string;
|
|
46
47
|
filters: NFCPatrolReportFilters;
|
|
47
48
|
options: NFCPatrolReportFilterOptions;
|
|
48
49
|
}>();
|
|
@@ -59,7 +60,7 @@ const {
|
|
|
59
60
|
dialogRemarks,
|
|
60
61
|
fetchReport,
|
|
61
62
|
openRemarksDialog,
|
|
62
|
-
} = useNFCPatrolReport(props.filters);
|
|
63
|
+
} = useNFCPatrolReport(props.filters, props.site);
|
|
63
64
|
|
|
64
65
|
watch(
|
|
65
66
|
() => [props.filters.route, props.filters.timeRange, props.filters.date, props.active],
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
<v-select
|
|
5
5
|
:model-value="modelValue.route"
|
|
6
6
|
:items="options.routes"
|
|
7
|
+
item-title="title"
|
|
8
|
+
item-value="value"
|
|
7
9
|
label="Select Route"
|
|
8
10
|
variant="outlined"
|
|
9
11
|
density="comfortable"
|
|
@@ -18,7 +20,7 @@
|
|
|
18
20
|
<v-select
|
|
19
21
|
:model-value="modelValue.timeRange"
|
|
20
22
|
:items="options.timeRanges"
|
|
21
|
-
label="Time
|
|
23
|
+
label="Start Time"
|
|
22
24
|
variant="outlined"
|
|
23
25
|
density="comfortable"
|
|
24
26
|
rounded="lg"
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
<span class="text-caption font-weight-bold text-capitalize">
|
|
59
59
|
permissions
|
|
60
60
|
</span>
|
|
61
|
-
<v-chip>{{ value
|
|
61
|
+
<v-chip>{{ getPermissionCount(value) }}</v-chip>
|
|
62
62
|
</template>
|
|
63
63
|
|
|
64
64
|
<template #item.action-table="{ item }" v-if="canDeleteRole">
|
|
@@ -145,6 +145,11 @@
|
|
|
145
145
|
</template>
|
|
146
146
|
|
|
147
147
|
<script setup lang="ts">
|
|
148
|
+
import {
|
|
149
|
+
getPermissionCount,
|
|
150
|
+
updateRolePermissionsInList,
|
|
151
|
+
} from "../utils/rolePermissionCounts";
|
|
152
|
+
|
|
148
153
|
const props = defineProps({
|
|
149
154
|
orgId: {
|
|
150
155
|
type: String,
|
|
@@ -324,11 +329,29 @@ const Permissions = computed(() => {
|
|
|
324
329
|
});
|
|
325
330
|
|
|
326
331
|
function successfulUpdate() {
|
|
332
|
+
const savedPermissions = [...selectedPermissions.value];
|
|
333
|
+
|
|
327
334
|
previewDialog.value = false;
|
|
328
|
-
|
|
335
|
+
edit.value = false;
|
|
336
|
+
originalPermissions.value = savedPermissions;
|
|
337
|
+
items.value = updateRolePermissionsInList(
|
|
338
|
+
items.value,
|
|
339
|
+
roleId.value,
|
|
340
|
+
savedPermissions
|
|
341
|
+
);
|
|
342
|
+
void refreshRolesAfterUpdate(savedPermissions);
|
|
329
343
|
useLocalSetup(props.type);
|
|
330
344
|
}
|
|
331
345
|
|
|
346
|
+
async function refreshRolesAfterUpdate(savedPermissions: string[]) {
|
|
347
|
+
await getRoles();
|
|
348
|
+
items.value = updateRolePermissionsInList(
|
|
349
|
+
items.value,
|
|
350
|
+
roleId.value,
|
|
351
|
+
savedPermissions
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
|
|
332
355
|
const confirmDialog = ref(false);
|
|
333
356
|
const selectedRoleId = ref<string | null>(null);
|
|
334
357
|
const deleteLoading = ref(false);
|
|
@@ -1210,6 +1210,7 @@ async function submitServiceProviderInvite() {
|
|
|
1210
1210
|
serviceProviderInvite.value.siteName ||
|
|
1211
1211
|
site.value?.name ||
|
|
1212
1212
|
props.siteName,
|
|
1213
|
+
app: serviceProviderInvite.value.app,
|
|
1213
1214
|
|
|
1214
1215
|
inviteType: existingAccount.value ? "create-org" : "organization-invite",
|
|
1215
1216
|
});
|