@7365admin1/layer-common 4.35.1-staging.450 → 4.35.1-staging.451
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.
|
@@ -75,8 +75,8 @@
|
|
|
75
75
|
</v-toolbar>
|
|
76
76
|
<v-card-text>
|
|
77
77
|
<p class="text-caption mb-3">
|
|
78
|
-
Only active {{ adding === "members" ? "members" : "service
|
|
79
|
-
yet are listed.
|
|
78
|
+
Only active {{ adding === "members" ? "members" : "service provider people" }} that are not assigned to a
|
|
79
|
+
unit yet are listed.
|
|
80
80
|
</p>
|
|
81
81
|
<v-autocomplete v-model="selected" v-model:search="candidateSearch" :items="candidates"
|
|
82
82
|
:loading="candidatesLoading" item-title="name" item-value="_id" multiple chips closable-chips
|
|
@@ -103,12 +103,22 @@
|
|
|
103
103
|
<script setup lang="ts">
|
|
104
104
|
/**
|
|
105
105
|
* A building unit's Management tab: the management members and the service
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
106
|
+
* provider people (Members > Service Providers, not the provider companies)
|
|
107
|
+
* attached to this unit. Each can be on one unit at a time, and only while
|
|
108
|
+
* active - the server detaches them the moment they are suspended or deleted,
|
|
109
|
+
* so they simply drop off this list.
|
|
109
110
|
*/
|
|
110
111
|
type TSection = "members" | "providers";
|
|
111
|
-
type TRow = {
|
|
112
|
+
type TRow = {
|
|
113
|
+
_id: string;
|
|
114
|
+
name: string;
|
|
115
|
+
email?: string;
|
|
116
|
+
roleName?: string;
|
|
117
|
+
type?: string;
|
|
118
|
+
company?: string;
|
|
119
|
+
role?: string;
|
|
120
|
+
status?: string;
|
|
121
|
+
};
|
|
112
122
|
|
|
113
123
|
const props = defineProps({
|
|
114
124
|
unitId: {
|
|
@@ -136,7 +146,7 @@ const org = computed(() => (route.params.org as string) ?? "");
|
|
|
136
146
|
const site = computed(() => props.siteId || ((route.params.site as string) ?? ""));
|
|
137
147
|
|
|
138
148
|
const { getAll: getMembers, updateMemberUnit } = useMember();
|
|
139
|
-
const {
|
|
149
|
+
const { getSiteMembers: getProviderPeople, updateSiteMemberUnit: updateProviderUnit } = useServiceProvider();
|
|
140
150
|
const { debounce } = useUtils();
|
|
141
151
|
|
|
142
152
|
const panels = ref<TSection[]>(["members", "providers"]);
|
|
@@ -147,8 +157,17 @@ function membersQuery(unit: string, search = "") {
|
|
|
147
157
|
return getMembers({ org: org.value, siteId: site.value, type: props.managementType, status: "active", unit, search, limit: 50 });
|
|
148
158
|
}
|
|
149
159
|
|
|
150
|
-
|
|
151
|
-
|
|
160
|
+
/**
|
|
161
|
+
* The site's provider people on `unit`, active only. The endpoint returns the
|
|
162
|
+
* whole list (no paging or search), so `search` is matched here.
|
|
163
|
+
*/
|
|
164
|
+
async function providersQuery(unit: string, search = "") {
|
|
165
|
+
const res = await getProviderPeople(site.value, unit);
|
|
166
|
+
const q = search.toLowerCase();
|
|
167
|
+
const items = (res?.items ?? []).filter(
|
|
168
|
+
(p) => p.status === "active" && (!q || [p.name, p.email, p.company].some((v) => v?.toLowerCase().includes(q))),
|
|
169
|
+
);
|
|
170
|
+
return { items };
|
|
152
171
|
}
|
|
153
172
|
|
|
154
173
|
const { data: memberRes, pending: membersLoading, refresh: refreshMembers } = useLazyAsyncData(
|
|
@@ -161,7 +180,9 @@ const { data: providerRes, pending: providersLoading, refresh: refreshProviders
|
|
|
161
180
|
);
|
|
162
181
|
|
|
163
182
|
function subtitleOf(row: TRow) {
|
|
164
|
-
return [row.roleName || row.type?.replace(/_/g, " "), row.email]
|
|
183
|
+
return [row.company, row.roleName || row.role || row.type?.replace(/_/g, " "), row.email]
|
|
184
|
+
.filter(Boolean)
|
|
185
|
+
.join(" · ");
|
|
165
186
|
}
|
|
166
187
|
|
|
167
188
|
const sections = computed(() => [
|
|
@@ -15,6 +15,9 @@ export type TSiteProviderMember = {
|
|
|
15
15
|
lastLoginAt?: string | null;
|
|
16
16
|
/** a subcontractor: the provider that brought its company onto the site */
|
|
17
17
|
invitedVia?: string;
|
|
18
|
+
/** The building unit this person is attached to (a unit's Management tab). */
|
|
19
|
+
unit?: string | null;
|
|
20
|
+
unitName?: string;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export type TSiteProviderCompany = {
|
|
@@ -307,17 +310,29 @@ export default function useServiceProvider() {
|
|
|
307
310
|
* Members > Service Providers: the provider people with access to this
|
|
308
311
|
* site, and one entry per provider company with its head count. The
|
|
309
312
|
* site's own organisation only - the server refuses anyone else.
|
|
313
|
+
* `unit`: a building unit id, or "none" (people on no unit yet).
|
|
310
314
|
*/
|
|
311
|
-
function getSiteMembers(siteId: string): Promise<{
|
|
315
|
+
function getSiteMembers(siteId: string, unit = ""): Promise<{
|
|
312
316
|
items: TSiteProviderMember[];
|
|
313
317
|
companies: TSiteProviderCompany[];
|
|
314
318
|
}> {
|
|
315
319
|
return useNuxtApp().$api("/api/service-providers/site-members", {
|
|
316
320
|
method: "GET",
|
|
317
|
-
query: { siteId },
|
|
321
|
+
query: { siteId, ...(unit ? { unit } : {}) },
|
|
318
322
|
});
|
|
319
323
|
}
|
|
320
324
|
|
|
325
|
+
/** Attach one of those people to a building unit, or detach them (`unit` ""). */
|
|
326
|
+
function updateSiteMemberUnit(id: string, unit: string) {
|
|
327
|
+
return useNuxtApp().$api<Record<string, any>>(
|
|
328
|
+
`/api/service-providers/site-members/${id}/unit`,
|
|
329
|
+
{
|
|
330
|
+
method: "PATCH",
|
|
331
|
+
body: { unit },
|
|
332
|
+
}
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
321
336
|
/** The same list as an Excel file, under the same filters. */
|
|
322
337
|
function exportSiteMembers(
|
|
323
338
|
siteId: string,
|
|
@@ -334,6 +349,7 @@ export default function useServiceProvider() {
|
|
|
334
349
|
|
|
335
350
|
return {
|
|
336
351
|
getSiteMembers,
|
|
352
|
+
updateSiteMemberUnit,
|
|
337
353
|
exportSiteMembers,
|
|
338
354
|
serviceProviders,
|
|
339
355
|
serviceProvider,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@7365admin1/layer-common",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "4.35.1-staging.
|
|
5
|
+
"version": "4.35.1-staging.451",
|
|
6
6
|
"author": "7365admin1",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
8
8
|
"//files": "What a consumer extending this layer actually loads. Without this npm ships the whole working tree - the changesets, the CI workflows, the render harness in tools/ and any scratch directory that happened to exist at publish time. Nuxt resolves a layer by directory, so every runtime directory below has to stay listed; adding a new top-level runtime directory means adding it here too.",
|