@7365admin1/layer-common 4.97.1-staging.597 → 4.97.1-staging.599

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.
@@ -8,6 +8,11 @@
8
8
  <h3 class="screen-card-title">
9
9
  {{ type === "workOrder" ? "Work Order" : "Feedback" }} Chat
10
10
  </h3>
11
+ <div class="text-body-2 text-medium-emphasis">
12
+ Between the Managing Agent and the service provider on this
13
+ {{ type === "workOrder" ? "work order" : "feedback" }}. The other side
14
+ is notified of each new message.
15
+ </div>
11
16
  </div>
12
17
 
13
18
  <v-sheet
@@ -23,7 +28,7 @@
23
28
  v-else-if="!days.length"
24
29
  class="text-center text-medium-emphasis py-6"
25
30
  >
26
- No messages yet
31
+ No messages yet. Send a message or a photo below to start.
27
32
  </div>
28
33
 
29
34
  <template v-for="group in days" :key="group.day">
@@ -48,7 +53,7 @@
48
53
  :message="msg.comment"
49
54
  :timestamp="formatTime(msg.createdAt)"
50
55
  :senderName="isMine(msg) ? 'You' : msg.createdByName || 'User'"
51
- :role="msg.createdByType"
56
+ :role="senderSideLabel(msg.createdByMemberType) || msg.createdByType"
52
57
  :attachments="msg.attachments"
53
58
  :avatarId="msg.createdByProfile"
54
59
  @preview="openPreview"
@@ -186,7 +191,7 @@
186
191
  </template>
187
192
 
188
193
  <script setup lang="ts">
189
- import { groupChatByDay } from "../../utils/chat-sender.ts";
194
+ import { groupChatByDay, senderSideLabel } from "../../utils/chat-sender.ts";
190
195
 
191
196
  /**
192
197
  * The comment thread under a feedback or a work order.
@@ -16,8 +16,11 @@
16
16
  </button>
17
17
  </template>
18
18
 
19
- <template v-if="error" #no-data>
20
- <DashboardEmptyState error />
19
+ <template #no-data>
20
+ <DashboardEmptyState v-if="error" error />
21
+ <div v-else class="tc-ro-empty" data-test="task-calendar-agent-empty">
22
+ {{ EMPTY_TEXT[status] || EMPTY_TEXT.planned }}
23
+ </div>
21
24
  </template>
22
25
 
23
26
  <template v-slot:item.dateTime="{ item }">{{ dueDate(item.dateTime) }}</template>
@@ -59,6 +62,12 @@ const props = defineProps({
59
62
  });
60
63
 
61
64
  const LIMIT = 20;
65
+ // Per tab, in plain words (owner 24 Oct): never a bare "No data available".
66
+ const EMPTY_TEXT: Record<string, string> = {
67
+ planned: "No jobs from the managing agent yet. When they give your company a job at this site, it shows here.",
68
+ overdue: "Nothing overdue. Jobs from the managing agent that pass their due date show here.",
69
+ completed: "No finished jobs yet. Jobs the managing agent marks done show here.",
70
+ };
62
71
  const TABS = [
63
72
  { name: "Open", status: "planned" },
64
73
  { name: "Overdue", status: "overdue" },
@@ -115,3 +124,11 @@ function taskState(task: Record<string, any>) {
115
124
  return { label: "Upcoming", color: "primary" };
116
125
  }
117
126
  </script>
127
+
128
+ <style scoped>
129
+ .tc-ro-empty {
130
+ padding: 24px 16px;
131
+ font-size: var(--fs-cell);
132
+ color: var(--text2);
133
+ }
134
+ </style>
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.97.1-staging.597",
5
+ "version": "4.97.1-staging.599",
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.",
@@ -9,6 +9,8 @@ declare type TCommentChat = {
9
9
  updatedAt?: string;
10
10
  createdByName?: string;
11
11
  createdByType?: string;
12
+ /** The sender's membership type at the site, stamped by the server (e.g. "property_management_agency"). */
13
+ createdByMemberType?: string;
12
14
  /** The sender's avatar file id. The API has always returned it. */
13
15
  createdByProfile?: string;
14
16
  justify?: string;
@@ -25,6 +25,23 @@ export function formatSenderRole(
25
25
  .join(" ");
26
26
  }
27
27
 
28
+ /**
29
+ * Which side of the conversation wrote a message, from the membership type the
30
+ * server stamps on it (`createdByMemberType`): "Managing Agent", "Service
31
+ * Provider", "Security" or "Resident"; "" when the type says nothing useful
32
+ * (the panel then falls back to `formatSenderRole`). Kept in step with
33
+ * `senderSide` in the mobile apps.
34
+ */
35
+ export function senderSideLabel(memberType: string | undefined | null): string {
36
+ const t = (memberType ?? "").trim().toLowerCase();
37
+ if (!t) return "";
38
+ if (t === "property_management_agency") return "Managing Agent";
39
+ if (t === "security_agency") return "Security";
40
+ if (t === "resident") return "Resident";
41
+ if (t.endsWith("_services") || t === "service-provider" || t === "service_provider") return "Service Provider";
42
+ return "";
43
+ }
44
+
28
45
  /**
29
46
  * A thread already in reading order (oldest first, as `useComment.setComments`
30
47
  * sorts it), split into one group per day so the panel can draw a single day