@apptegy/nuxt-navigation 0.1.111 → 1.0.0-alpha.1

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 (28) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/module.mjs +3 -2
  3. package/dist/runtime/components/Nav/Header.vue +108 -321
  4. package/dist/runtime/components/Nav/Header.vue.d.ts +12 -39
  5. package/dist/runtime/components/Nav/OrgSelect.vue +8 -8
  6. package/dist/runtime/components/Nav/Sidebar.vue +118 -207
  7. package/dist/runtime/components/Nav/Sidebar.vue.d.ts +7 -15
  8. package/dist/runtime/components/Nav/SidebarItem.vue +19 -22
  9. package/dist/runtime/components/Nav/SidebarSection.vue +28 -35
  10. package/dist/runtime/components/Nav/SidebarSection.vue.d.ts +2 -2
  11. package/dist/runtime/components/Nav/SubMenuItem.vue +1 -1
  12. package/dist/runtime/types/index.d.ts +0 -1
  13. package/locale/en.json +1 -22
  14. package/package.json +25 -29
  15. package/dist/runtime/components/Nav/NotificationItem.vue +0 -337
  16. package/dist/runtime/components/Nav/NotificationItem.vue.d.ts +0 -12
  17. package/dist/runtime/components/Nav/NotificationsPanel.vue +0 -513
  18. package/dist/runtime/components/Nav/NotificationsPanel.vue.d.ts +0 -53
  19. package/dist/runtime/constants/notification-types.d.ts +0 -19
  20. package/dist/runtime/constants/notification-types.js +0 -48
  21. package/dist/runtime/types/notifications.d.ts +0 -79
  22. package/dist/runtime/types/notifications.js +0 -0
  23. package/dist/runtime/utils/notification-api.d.ts +0 -26
  24. package/dist/runtime/utils/notification-api.js +0 -84
  25. package/dist/runtime/utils/notification-dates.d.ts +0 -15
  26. package/dist/runtime/utils/notification-dates.js +0 -81
  27. package/dist/runtime/utils/notifications.d.ts +0 -21
  28. package/dist/runtime/utils/notifications.js +0 -117
@@ -11,4 +11,3 @@ export interface IUser {
11
11
  client: string;
12
12
  admin_email: string;
13
13
  }
14
- export type { NotificationType, NotificationApiState, INotificationApiActor, INotificationApiRecord, INotificationsPagination, INotificationsApiResponse, INotificationActor, INotificationItem, INotificationGroup, INotificationTab, INotificationFilter, INotificationsPanelData, } from './notifications.js';
package/locale/en.json CHANGED
@@ -15,27 +15,6 @@
15
15
  "userDropdown": "User settings",
16
16
  "logoAlt": "Thrillshare - Return Home",
17
17
  "brandLogoAlt": "Logo",
18
- "website": "School Website",
19
- "notifications": "Notifications",
20
- "notificationsPanel": {
21
- "retentionLabel": "Kept 30 days",
22
- "tabs": {
23
- "new": "New",
24
- "all": "All"
25
- },
26
- "tabsLabel": "Notification views",
27
- "scrollFilters": "Scroll filters",
28
- "clearAll": "Clear all",
29
- "dismiss": "Dismiss notification",
30
- "close": "Close notifications",
31
- "loading": "Loading notifications...",
32
- "empty": "You're all caught up.",
33
- "justNow": "just now",
34
- "yesterday": "Yesterday",
35
- "dateGroups": {
36
- "today": "TODAY",
37
- "yesterday": "YESTERDAY"
38
- }
39
- }
18
+ "website": "School Website"
40
19
  }
41
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apptegy/nuxt-navigation",
3
- "version": "0.1.111",
3
+ "version": "1.0.0-alpha.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -14,8 +14,30 @@
14
14
  "dist",
15
15
  "locale"
16
16
  ],
17
+ "dependencies": {
18
+ "@apptegy/nuxt-intl": "^2.4.3",
19
+ "@nuxt/icon": "^1.0.0",
20
+ "@nuxt/kit": "^3.17.0",
21
+ "@vueuse/components": "^12.0.0",
22
+ "@vueuse/core": "^12.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "@nuxt/devtools": "^2.6.2",
26
+ "@nuxt/eslint-config": "^1.6.0",
27
+ "@nuxt/module-builder": "^1.0.1",
28
+ "@nuxt/schema": "^3.17.0",
29
+ "@nuxt/test-utils": "^3.17.0",
30
+ "@types/node": "^22.0.0",
31
+ "eslint": "^9.31.0",
32
+ "nuxt": "^3.17.0",
33
+ "sass": "^1.89.2",
34
+ "typescript": "~5.8.0",
35
+ "vitest": "^3.2.4",
36
+ "vue": "^3.5.13",
37
+ "vue-tsc": "^3.0.3"
38
+ },
17
39
  "scripts": {
18
- "prepack": "nuxt-module-build build",
40
+ "build": "nuxt-module-build build --watch",
19
41
  "dev": "nuxi dev playground",
20
42
  "dev:build": "nuxi build playground",
21
43
  "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
@@ -24,31 +46,5 @@
24
46
  "test": "vitest run",
25
47
  "test:watch": "vitest watch",
26
48
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
27
- },
28
- "dependencies": {
29
- "@apptegy/nuxt-intl": "^2.4.3",
30
- "@nuxt/kit": "^3.17.0",
31
- "@vueuse/components": "^12.0.0",
32
- "@vueuse/core": "^12.0.0"
33
- },
34
- "peerDependencies": {
35
- "@nuxt/icon": "^1.0.0 || ^2.0.0",
36
- "primevue": "^4.2.5"
37
- },
38
- "devDependencies": {
39
- "@nuxt/devtools": "catalog:",
40
- "@nuxt/eslint-config": "catalog:",
41
- "@nuxt/module-builder": "catalog:",
42
- "@nuxt/schema": "catalog:",
43
- "@nuxt/test-utils": "catalog:",
44
- "@types/node": "catalog:",
45
- "eslint": "catalog:",
46
- "nuxt": "catalog:",
47
- "primevue": "^4.5.4",
48
- "sass": "catalog:",
49
- "typescript": "catalog:",
50
- "vitest": "catalog:",
51
- "vue": "catalog:",
52
- "vue-tsc": "catalog:"
53
49
  }
54
- }
50
+ }
@@ -1,337 +0,0 @@
1
- <template>
2
- <div
3
- class="notification-item"
4
- :class="{ 'notification-item--in-badge': showBadgeActions }"
5
- >
6
- <div
7
- class="notification-item__main"
8
- role="button"
9
- tabindex="0"
10
- @click="handleClick"
11
- @keydown.enter.prevent="handleClick"
12
- >
13
- <div
14
- class="notification-item__avatar"
15
- :style="{ '--type-accent': typeAccent }"
16
- >
17
- <div class="notification-item__avatar-ring">
18
- <NavAvatar
19
- :name="primaryActor.name"
20
- :src="primaryActor.avatarUrl"
21
- class="notification-item__avatar-image"
22
- />
23
- </div>
24
- <span
25
- v-if="groupBadgeLabel"
26
- class="notification-item__group-badge"
27
- aria-hidden="true"
28
- >
29
- {{ groupBadgeLabel }}
30
- </span>
31
- <span
32
- class="notification-item__type-badge"
33
- aria-hidden="true"
34
- >
35
- <component :is="typeIcon" />
36
- </span>
37
- </div>
38
-
39
- <div class="notification-item__content">
40
- <p class="notification-item__message">
41
- <strong>{{ primaryActor.name }}</strong>
42
- <template v-if="additionalActorsLabel">
43
- {{ additionalActorsLabel }}
44
- </template>
45
- {{ item.actionText }}
46
- </p>
47
- <p class="notification-item__meta">
48
- <span>{{ item.timestampLabel }}</span>
49
- <template v-if="item.contextLabel">
50
- <span
51
- class="notification-item__meta-separator"
52
- aria-hidden="true"
53
- >·</span
54
- >
55
- <span>{{ item.contextLabel }}</span>
56
- </template>
57
- </p>
58
- <Tag
59
- v-if="item.stateLabel"
60
- :value="item.stateLabel"
61
- severity="secondary"
62
- class="notification-item__state-chip"
63
- />
64
- </div>
65
- </div>
66
-
67
- <div class="notification-item__actions">
68
- <span
69
- v-if="showBadgeActions"
70
- class="notification-item__unread-dot"
71
- aria-hidden="true"
72
- />
73
- <Button
74
- v-if="showBadgeActions"
75
- type="button"
76
- severity="secondary"
77
- text
78
- rounded
79
- class="notification-item__dismiss"
80
- :aria-label="$t('navigation.notificationsPanel.dismiss')"
81
- @click="handleDismiss"
82
- >
83
- <Icon
84
- name="lucide:x"
85
- size="16"
86
- aria-hidden="true"
87
- />
88
- </Button>
89
- </div>
90
- </div>
91
- </template>
92
-
93
- <script setup>
94
- import { computed, h } from "vue";
95
- import Button from "primevue/button";
96
- import Tag from "primevue/tag";
97
- import { getTypeAccent, isInBadge } from "../../utils/notifications";
98
- const props = defineProps({
99
- item: { type: Object, required: true }
100
- });
101
- const emit = defineEmits(["dismiss", "select"]);
102
- const primaryActor = computed(() => props.item.actors[0] || { name: "" });
103
- const typeAccent = computed(() => getTypeAccent(props.item.type));
104
- const showBadgeActions = computed(() => isInBadge(props.item));
105
- const groupBadgeLabel = computed(() => {
106
- const count = props.item.groupCount ?? Math.max(props.item.actors.length - 1, 0);
107
- return count > 0 ? `+${count}` : "";
108
- });
109
- const additionalActorsLabel = computed(() => {
110
- if (props.item.groupCount && props.item.groupCount > 0) {
111
- return ` and ${props.item.groupCount} others`;
112
- }
113
- if (props.item.actors.length <= 1) {
114
- return "";
115
- }
116
- const names = props.item.actors.slice(1).map((actor) => actor.name);
117
- return `, ${names.join(", ")}`;
118
- });
119
- function svgIcon(paths) {
120
- return h(
121
- "svg",
122
- {
123
- xmlns: "http://www.w3.org/2000/svg",
124
- width: 12,
125
- height: 12,
126
- viewBox: "0 0 24 24",
127
- fill: "none",
128
- stroke: "currentColor",
129
- "stroke-width": 2,
130
- "stroke-linecap": "round",
131
- "stroke-linejoin": "round"
132
- },
133
- paths
134
- );
135
- }
136
- const typeIcon = computed(() => {
137
- switch (props.item.type) {
138
- case "announcement":
139
- return svgIcon([h("path", { d: "m3 11 18-5v12L3 14v-3z" }), h("path", { d: "M11.6 16.8a3 3 0 1 1-5.8-1.6" })]);
140
- case "message":
141
- return svgIcon([h("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })]);
142
- case "comment":
143
- return svgIcon([h("path", { d: "M7.9 20A9 9 0 1 0 4 16.1L2 22Z" })]);
144
- case "mention":
145
- return svgIcon([
146
- h("circle", { cx: 12, cy: 12, r: 4 }),
147
- h("path", { d: "M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8" })
148
- ]);
149
- case "reply":
150
- return svgIcon([
151
- h("path", { d: "M9 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-5l-5 5z" }),
152
- h("path", { d: "m10 9-3 3 3 3" })
153
- ]);
154
- case "reaction":
155
- return svgIcon([
156
- h("path", {
157
- d: "M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"
158
- })
159
- ]);
160
- case "school-post":
161
- return svgIcon([
162
- h("path", {
163
- d: "M4 22h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-2 2Zm0 0a2 2 0 0 1-2-2v-9c0-1.1.9-2 2-2h2"
164
- }),
165
- h("path", { d: "M18 14h-8" }),
166
- h("path", { d: "M15 18h-5" }),
167
- h("path", { d: "M10 6h8v4h-8V6Z" })
168
- ]);
169
- case "system":
170
- return svgIcon([
171
- h("circle", { cx: 12, cy: 12, r: 10 }),
172
- h("path", { d: "M12 16v-4" }),
173
- h("path", { d: "M12 8h.01" })
174
- ]);
175
- default:
176
- return svgIcon([
177
- h("path", { d: "M10.268 21a2 2 0 0 0 3.464 0" }),
178
- h("path", {
179
- d: "M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"
180
- })
181
- ]);
182
- }
183
- });
184
- function handleClick() {
185
- emit("select", props.item);
186
- }
187
- function handleDismiss(event) {
188
- event.preventDefault();
189
- event.stopPropagation();
190
- emit("dismiss", props.item.id);
191
- }
192
- </script>
193
-
194
- <style scoped>
195
- .notification-item {
196
- display: grid;
197
- grid-template-columns: 1fr auto;
198
- gap: 12px;
199
- align-items: start;
200
- width: 100%;
201
- padding: 12px;
202
- border: 1px solid rgb(232, 232, 236);
203
- border-radius: 8px;
204
- background: var(--primary-white, #fff);
205
- text-align: left;
206
- color: inherit;
207
- box-shadow: none;
208
- transition: border-color 0.15s ease, box-shadow 0.15s ease;
209
- }
210
- .notification-item__main {
211
- display: grid;
212
- grid-template-columns: auto 1fr;
213
- gap: 12px;
214
- align-items: start;
215
- min-width: 0;
216
- cursor: pointer;
217
- border: none;
218
- background: transparent;
219
- padding: 0;
220
- text-align: left;
221
- color: inherit;
222
- }
223
- .notification-item__main:hover .notification-item__message strong {
224
- color: var(--purple-60, #662e80);
225
- }
226
- .notification-item__main:focus-visible {
227
- outline: 2px solid var(--purple-60, #662e80);
228
- outline-offset: 2px;
229
- border-radius: 4px;
230
- }
231
- .notification-item:hover {
232
- border-color: rgb(209, 209, 214);
233
- box-shadow: rgba(0, 0, 0, 0.06) 0 2px 10px;
234
- }
235
- .notification-item__avatar {
236
- position: relative;
237
- width: 44px;
238
- height: 44px;
239
- flex-shrink: 0;
240
- }
241
- .notification-item__avatar-ring {
242
- width: 44px;
243
- height: 44px;
244
- padding: 2px;
245
- border-radius: 50%;
246
- background: var(--type-accent);
247
- box-sizing: border-box;
248
- }
249
- .notification-item__avatar-image :deep(span) {
250
- background-color: #f3e6d4;
251
- color: var(--purple-40, #ab8cb9);
252
- border: 1px solid var(--primary-white, #fff);
253
- }
254
- .notification-item__avatar-image :deep(.avatar-container), .notification-item__avatar-image :deep(img), .notification-item__avatar-image :deep(span) {
255
- width: 40px;
256
- height: 40px;
257
- }
258
- .notification-item__group-badge {
259
- position: absolute;
260
- right: -4px;
261
- bottom: 0;
262
- min-width: 22px;
263
- height: 22px;
264
- padding: 0 4px;
265
- border: 2px solid var(--primary-white, #fff);
266
- border-radius: 999px;
267
- background: var(--grey-80, #374151);
268
- color: var(--primary-white, #fff);
269
- font-size: 10px;
270
- font-weight: 600;
271
- line-height: 18px;
272
- text-align: center;
273
- z-index: 1;
274
- }
275
- .notification-item__type-badge {
276
- position: absolute;
277
- right: -2px;
278
- bottom: -2px;
279
- display: flex;
280
- align-items: center;
281
- justify-content: center;
282
- width: 22px;
283
- height: 22px;
284
- border: 2px solid var(--primary-white, #fff);
285
- border-radius: 999px;
286
- background: var(--type-accent);
287
- color: var(--primary-white, #fff);
288
- z-index: 2;
289
- }
290
- .notification-item__content {
291
- min-width: 0;
292
- }
293
- .notification-item__message {
294
- margin: 0;
295
- font-size: 14.5px;
296
- font-weight: 600;
297
- line-height: 20px;
298
- color: var(--grey-90, #111827);
299
- }
300
- .notification-item__message strong {
301
- font-weight: 600;
302
- }
303
- .notification-item__meta {
304
- display: flex;
305
- flex-wrap: wrap;
306
- gap: 4px;
307
- margin: 4px 0 0;
308
- font-size: 12.5px;
309
- line-height: 16px;
310
- color: var(--grey-50, #747474);
311
- }
312
- .notification-item__meta-separator {
313
- padding: 0 2px;
314
- }
315
- .notification-item__state-chip {
316
- margin-top: 8px;
317
- }
318
- .notification-item__actions {
319
- display: flex;
320
- align-items: center;
321
- gap: 8px;
322
- padding-top: 2px;
323
- }
324
- .notification-item__unread-dot {
325
- width: 8px;
326
- height: 8px;
327
- border-radius: 50%;
328
- background: #c84b31;
329
- flex-shrink: 0;
330
- }
331
- .notification-item__dismiss {
332
- width: 24px;
333
- height: 24px;
334
- padding: 0;
335
- color: var(--grey-50, #9ca3af);
336
- }
337
- </style>
@@ -1,12 +0,0 @@
1
- import type { INotificationItem } from '../../types/index.js';
2
- type __VLS_Props = {
3
- item: INotificationItem;
4
- };
5
- declare const _default: import("vue").DefineComponent<__VLS_Props, void, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
- select: (item: INotificationItem) => any;
7
- dismiss: (id: string) => any;
8
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
- onSelect?: ((item: INotificationItem) => any) | undefined;
10
- onDismiss?: ((id: string) => any) | undefined;
11
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
- export default _default;