@rlse/widget 0.1.5 → 0.2.0

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.
@@ -0,0 +1,376 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
36
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
+ };
39
+ import { Component, Input } from '@angular/core';
40
+ import { Subject } from 'rxjs';
41
+ import { takeUntil } from 'rxjs/operators';
42
+ import { markAllChangesAsSeen, getUnreadCount, getReleaseNotesUrl, renderDescription, formatChangeDate, } from '@rlse/widget-core';
43
+ import { DEFAULT_CONFIG } from '@rlse/widget-core';
44
+ let RlseWidgetComponent = (() => {
45
+ let _classDecorators = [Component({
46
+ selector: 'rlse-widget',
47
+ template: `
48
+ <div *ngIf="config.trigger !== 'auto'">
49
+ <button
50
+ (click)="isOpen = true"
51
+ [attr.aria-label]="config.triggerLabel"
52
+ [style]="triggerStyle"
53
+ >
54
+ <svg
55
+ xmlns="http://www.w3.org/2000/svg"
56
+ width="24"
57
+ height="24"
58
+ viewBox="0 0 24 24"
59
+ fill="none"
60
+ stroke="currentColor"
61
+ stroke-width="2"
62
+ stroke-linecap="round"
63
+ stroke-linejoin="round"
64
+ >
65
+ <path
66
+ d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275z"
67
+ />
68
+ <path d="M5 3v4" />
69
+ <path d="M19 17v4" />
70
+ <path d="M3 5h4" />
71
+ <path d="M17 19h4" />
72
+ </svg>
73
+ <span *ngIf="unreadCount > 0" [style]="badgeStyle">
74
+ {{ unreadCount > 99 ? '99+' : unreadCount }}
75
+ </span>
76
+ </button>
77
+ </div>
78
+
79
+ <div
80
+ *ngIf="isOpen"
81
+ (click)="onOverlayClick($event)"
82
+ [style]="overlayStyle"
83
+ role="dialog"
84
+ aria-modal="true"
85
+ >
86
+ <div [style]="modalStyle">
87
+ <div [style]="headerStyle">
88
+ <h2 [style]="titleStyle">{{ config.modalTitle }}</h2>
89
+ <button
90
+ (click)="isOpen = false"
91
+ [style]="closeButtonStyle"
92
+ aria-label="Close"
93
+ >
94
+ <svg
95
+ xmlns="http://www.w3.org/2000/svg"
96
+ width="20"
97
+ height="20"
98
+ viewBox="0 0 24 24"
99
+ fill="none"
100
+ stroke="currentColor"
101
+ stroke-width="2"
102
+ stroke-linecap="round"
103
+ stroke-linejoin="round"
104
+ >
105
+ <path d="M18 6 6 18" />
106
+ <path d="m6 6 12 12" />
107
+ </svg>
108
+ </button>
109
+ </div>
110
+
111
+ <div [style]="contentStyle">
112
+ <div *ngIf="isLoading" [style]="centeredStyle">
113
+ <svg
114
+ xmlns="http://www.w3.org/2000/svg"
115
+ width="24"
116
+ height="24"
117
+ viewBox="0 0 24 24"
118
+ fill="none"
119
+ stroke="currentColor"
120
+ stroke-width="2"
121
+ stroke-linecap="round"
122
+ stroke-linejoin="round"
123
+ >
124
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
125
+ </svg>
126
+ </div>
127
+
128
+ <div *ngIf="!isLoading && changes.length === 0" [style]="emptyStyle">
129
+ <p>No release notes yet. Check back soon!</p>
130
+ </div>
131
+
132
+ <article *ngFor="let change of changes" [style]="changeCardStyle">
133
+ <div [style]="changeHeaderStyle">
134
+ <h3 [style]="changeTitleStyle">{{ change.changeName }}</h3>
135
+ <span *ngIf="config.showStatus" [style]="statusBadgeStyle">{{
136
+ change.currentStatus
137
+ }}</span>
138
+ </div>
139
+ <p [style]="summaryStyle">{{ change.changeSummary }}</p>
140
+ <div
141
+ [style]="descriptionStyle"
142
+ [innerHTML]="renderDescription(change.changeDescription)"
143
+ ></div>
144
+ <div *ngIf="config.showDates" [style]="dateStyle">
145
+ {{ formatDate(change._creationTime) }}
146
+ </div>
147
+ </article>
148
+ </div>
149
+
150
+ <div *ngIf="!isLoading && changes.length > 0" [style]="footerStyle">
151
+ <button
152
+ (click)="markAsRead()"
153
+ [disabled]="unreadCount === 0"
154
+ [style]="markReadButtonStyle"
155
+ >
156
+ {{ unreadCount === 0 ? 'All caught up' : 'Mark all as read' }}
157
+ </button>
158
+ <a
159
+ [href]="releaseNotesUrl"
160
+ target="_blank"
161
+ rel="noopener"
162
+ [style]="viewAllLinkStyle"
163
+ >View all →</a
164
+ >
165
+ </div>
166
+ </div>
167
+ </div>
168
+ `,
169
+ })];
170
+ let _classDescriptor;
171
+ let _classExtraInitializers = [];
172
+ let _classThis;
173
+ let _orgSlug_decorators;
174
+ let _orgSlug_initializers = [];
175
+ let _orgSlug_extraInitializers = [];
176
+ let _appSlug_decorators;
177
+ let _appSlug_initializers = [];
178
+ let _appSlug_extraInitializers = [];
179
+ let _trigger_decorators;
180
+ let _trigger_initializers = [];
181
+ let _trigger_extraInitializers = [];
182
+ let _limit_decorators;
183
+ let _limit_initializers = [];
184
+ let _limit_extraInitializers = [];
185
+ let _showStatus_decorators;
186
+ let _showStatus_initializers = [];
187
+ let _showStatus_extraInitializers = [];
188
+ let _showDates_decorators;
189
+ let _showDates_initializers = [];
190
+ let _showDates_extraInitializers = [];
191
+ let _position_decorators;
192
+ let _position_initializers = [];
193
+ let _position_extraInitializers = [];
194
+ let _theme_decorators;
195
+ let _theme_initializers = [];
196
+ let _theme_extraInitializers = [];
197
+ let _primaryColor_decorators;
198
+ let _primaryColor_initializers = [];
199
+ let _primaryColor_extraInitializers = [];
200
+ let _triggerLabel_decorators;
201
+ let _triggerLabel_initializers = [];
202
+ let _triggerLabel_extraInitializers = [];
203
+ let _modalTitle_decorators;
204
+ let _modalTitle_initializers = [];
205
+ let _modalTitle_extraInitializers = [];
206
+ let _baseUrl_decorators;
207
+ let _baseUrl_initializers = [];
208
+ let _baseUrl_extraInitializers = [];
209
+ var RlseWidgetComponent = _classThis = class {
210
+ constructor(widgetDataService) {
211
+ this.widgetDataService = widgetDataService;
212
+ this.orgSlug = __runInitializers(this, _orgSlug_initializers, void 0);
213
+ this.appSlug = (__runInitializers(this, _orgSlug_extraInitializers), __runInitializers(this, _appSlug_initializers, void 0));
214
+ this.trigger = (__runInitializers(this, _appSlug_extraInitializers), __runInitializers(this, _trigger_initializers, 'manual'));
215
+ this.limit = (__runInitializers(this, _trigger_extraInitializers), __runInitializers(this, _limit_initializers, 10));
216
+ this.showStatus = (__runInitializers(this, _limit_extraInitializers), __runInitializers(this, _showStatus_initializers, true));
217
+ this.showDates = (__runInitializers(this, _showStatus_extraInitializers), __runInitializers(this, _showDates_initializers, true));
218
+ this.position = (__runInitializers(this, _showDates_extraInitializers), __runInitializers(this, _position_initializers, 'bottom-right'));
219
+ this.theme = (__runInitializers(this, _position_extraInitializers), __runInitializers(this, _theme_initializers, 'auto'));
220
+ this.primaryColor = (__runInitializers(this, _theme_extraInitializers), __runInitializers(this, _primaryColor_initializers, void 0));
221
+ this.triggerLabel = (__runInitializers(this, _primaryColor_extraInitializers), __runInitializers(this, _triggerLabel_initializers, "What's New"));
222
+ this.modalTitle = (__runInitializers(this, _triggerLabel_extraInitializers), __runInitializers(this, _modalTitle_initializers, 'Release Notes'));
223
+ this.baseUrl = (__runInitializers(this, _modalTitle_extraInitializers), __runInitializers(this, _baseUrl_initializers, 'https://rlse.dev'));
224
+ this.config = __runInitializers(this, _baseUrl_extraInitializers);
225
+ this.changes = [];
226
+ this.isLoading = false;
227
+ this.isOpen = false;
228
+ this.unreadCount = 0;
229
+ this.releaseNotesUrl = '';
230
+ this.destroy$ = new Subject();
231
+ // Angular service injection
232
+ }
233
+ ngOnInit() {
234
+ this.config = { ...DEFAULT_CONFIG, ...this };
235
+ this.loadChanges();
236
+ this.releaseNotesUrl = getReleaseNotesUrl(this.config.baseUrl, this.config.orgSlug, this.config.appSlug);
237
+ }
238
+ ngOnDestroy() {
239
+ this.destroy$.next();
240
+ this.destroy$.complete();
241
+ }
242
+ loadChanges() {
243
+ this.isLoading = true;
244
+ this.widgetDataService
245
+ .fetchChanges(this.config.orgSlug, this.config.appSlug, this.config.limit, this.config.baseUrl)
246
+ .pipe(takeUntil(this.destroy$))
247
+ .subscribe({
248
+ next: (result) => {
249
+ this.changes = result.changes;
250
+ this.unreadCount = getUnreadCount(this.config.orgSlug, this.changes);
251
+ this.isLoading = false;
252
+ },
253
+ error: () => {
254
+ this.changes = [];
255
+ this.isLoading = false;
256
+ },
257
+ });
258
+ }
259
+ markAsRead() {
260
+ markAllChangesAsSeen(this.config.orgSlug, this.changes.map((c) => c._id));
261
+ this.unreadCount = 0;
262
+ }
263
+ onOverlayClick(event) {
264
+ if (event.target === event.currentTarget) {
265
+ this.isOpen = false;
266
+ }
267
+ }
268
+ renderDescription(content) {
269
+ return renderDescription(content);
270
+ }
271
+ formatDate(timestamp) {
272
+ return formatChangeDate(timestamp);
273
+ }
274
+ // Styles
275
+ get triggerStyle() {
276
+ const positionMap = {
277
+ 'bottom-right': 'bottom: 20px; right: 20px;',
278
+ 'bottom-left': 'bottom: 20px; left: 20px;',
279
+ 'top-right': 'top: 20px; right: 20px;',
280
+ 'top-left': 'top: 20px; left: 20px;',
281
+ };
282
+ return `position: fixed; z-index: 9998; width: 56px; height: 56px; border-radius: 50%; border: none; cursor: pointer; display: flex; align-items: center; justify-content: center; background: ${this.config.primaryColor || '#3b82f6'}; color: white; box-shadow: 0 4px 14px 0 rgba(59, 130, 246, 0.39); ${positionMap[this.config.position]}`;
283
+ }
284
+ get badgeStyle() {
285
+ return `position: absolute; top: -2px; right: -2px; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px; background: #ef4444; color: white; font-size: 12px; font-weight: 600; display: flex; align-items: center; justify-content: center; border: 2px solid white;`;
286
+ }
287
+ get overlayStyle() {
288
+ return 'position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 9999; display: flex; align-items: center; justify-content: center; padding: 20px;';
289
+ }
290
+ get modalStyle() {
291
+ return 'background: var(--background, white); border-radius: 12px; width: 100%; max-width: 600px; max-height: 80vh; display: flex; flex-direction: column; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);';
292
+ }
293
+ get headerStyle() {
294
+ return 'display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--border, #e2e8f0);';
295
+ }
296
+ get titleStyle() {
297
+ return 'margin: 0; font-size: 18px; font-weight: 600;';
298
+ }
299
+ get closeButtonStyle() {
300
+ return 'background: none; border: none; cursor: pointer; padding: 8px; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #64748b;';
301
+ }
302
+ get contentStyle() {
303
+ return 'overflow-y: auto; padding: 0 24px 24px; flex: 1;';
304
+ }
305
+ get centeredStyle() {
306
+ return 'padding: 40px; text-align: center;';
307
+ }
308
+ get emptyStyle() {
309
+ return 'padding: 40px; text-align: center; color: #64748b;';
310
+ }
311
+ get changeCardStyle() {
312
+ return 'padding: 20px 0; border-bottom: 1px solid var(--border, #e2e8f0);';
313
+ }
314
+ get changeHeaderStyle() {
315
+ return 'display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 8px;';
316
+ }
317
+ get changeTitleStyle() {
318
+ return 'margin: 0; font-size: 16px; font-weight: 600; flex: 1;';
319
+ }
320
+ get statusBadgeStyle() {
321
+ return `font-size: 12px; font-weight: 500; padding: 4px 10px; border-radius: 20px; background: rgba(59, 130, 246, 0.1); color: ${this.config.primaryColor || '#3b82f6'}; border: 1px solid ${this.config.primaryColor || '#3b82f6'}; white-space: nowrap;`;
322
+ }
323
+ get summaryStyle() {
324
+ return 'margin: 8px 0; font-size: 14px; color: #64748b; line-height: 1.5;';
325
+ }
326
+ get descriptionStyle() {
327
+ return 'margin: 12px 0 0; font-size: 14px; line-height: 1.6;';
328
+ }
329
+ get dateStyle() {
330
+ return 'margin-top: 12px; font-size: 12px; color: #64748b;';
331
+ }
332
+ get footerStyle() {
333
+ return 'display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; border-top: 1px solid var(--border, #e2e8f0); gap: 12px;';
334
+ }
335
+ get markReadButtonStyle() {
336
+ return `font-size: 14px; padding: 8px 16px; border-radius: 8px; border: none; background: ${this.config.primaryColor || '#3b82f6'}; color: white; cursor: ${this.unreadCount === 0 ? 'default' : 'pointer'}; font-weight: 500; opacity: ${this.unreadCount === 0 ? 0.5 : 1};`;
337
+ }
338
+ get viewAllLinkStyle() {
339
+ return `font-size: 14px; color: ${this.config.primaryColor || '#3b82f6'}; text-decoration: none; font-weight: 500;`;
340
+ }
341
+ };
342
+ __setFunctionName(_classThis, "RlseWidgetComponent");
343
+ (() => {
344
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
345
+ _orgSlug_decorators = [Input()];
346
+ _appSlug_decorators = [Input()];
347
+ _trigger_decorators = [Input()];
348
+ _limit_decorators = [Input()];
349
+ _showStatus_decorators = [Input()];
350
+ _showDates_decorators = [Input()];
351
+ _position_decorators = [Input()];
352
+ _theme_decorators = [Input()];
353
+ _primaryColor_decorators = [Input()];
354
+ _triggerLabel_decorators = [Input()];
355
+ _modalTitle_decorators = [Input()];
356
+ _baseUrl_decorators = [Input()];
357
+ __esDecorate(null, null, _orgSlug_decorators, { kind: "field", name: "orgSlug", static: false, private: false, access: { has: obj => "orgSlug" in obj, get: obj => obj.orgSlug, set: (obj, value) => { obj.orgSlug = value; } }, metadata: _metadata }, _orgSlug_initializers, _orgSlug_extraInitializers);
358
+ __esDecorate(null, null, _appSlug_decorators, { kind: "field", name: "appSlug", static: false, private: false, access: { has: obj => "appSlug" in obj, get: obj => obj.appSlug, set: (obj, value) => { obj.appSlug = value; } }, metadata: _metadata }, _appSlug_initializers, _appSlug_extraInitializers);
359
+ __esDecorate(null, null, _trigger_decorators, { kind: "field", name: "trigger", static: false, private: false, access: { has: obj => "trigger" in obj, get: obj => obj.trigger, set: (obj, value) => { obj.trigger = value; } }, metadata: _metadata }, _trigger_initializers, _trigger_extraInitializers);
360
+ __esDecorate(null, null, _limit_decorators, { kind: "field", name: "limit", static: false, private: false, access: { has: obj => "limit" in obj, get: obj => obj.limit, set: (obj, value) => { obj.limit = value; } }, metadata: _metadata }, _limit_initializers, _limit_extraInitializers);
361
+ __esDecorate(null, null, _showStatus_decorators, { kind: "field", name: "showStatus", static: false, private: false, access: { has: obj => "showStatus" in obj, get: obj => obj.showStatus, set: (obj, value) => { obj.showStatus = value; } }, metadata: _metadata }, _showStatus_initializers, _showStatus_extraInitializers);
362
+ __esDecorate(null, null, _showDates_decorators, { kind: "field", name: "showDates", static: false, private: false, access: { has: obj => "showDates" in obj, get: obj => obj.showDates, set: (obj, value) => { obj.showDates = value; } }, metadata: _metadata }, _showDates_initializers, _showDates_extraInitializers);
363
+ __esDecorate(null, null, _position_decorators, { kind: "field", name: "position", static: false, private: false, access: { has: obj => "position" in obj, get: obj => obj.position, set: (obj, value) => { obj.position = value; } }, metadata: _metadata }, _position_initializers, _position_extraInitializers);
364
+ __esDecorate(null, null, _theme_decorators, { kind: "field", name: "theme", static: false, private: false, access: { has: obj => "theme" in obj, get: obj => obj.theme, set: (obj, value) => { obj.theme = value; } }, metadata: _metadata }, _theme_initializers, _theme_extraInitializers);
365
+ __esDecorate(null, null, _primaryColor_decorators, { kind: "field", name: "primaryColor", static: false, private: false, access: { has: obj => "primaryColor" in obj, get: obj => obj.primaryColor, set: (obj, value) => { obj.primaryColor = value; } }, metadata: _metadata }, _primaryColor_initializers, _primaryColor_extraInitializers);
366
+ __esDecorate(null, null, _triggerLabel_decorators, { kind: "field", name: "triggerLabel", static: false, private: false, access: { has: obj => "triggerLabel" in obj, get: obj => obj.triggerLabel, set: (obj, value) => { obj.triggerLabel = value; } }, metadata: _metadata }, _triggerLabel_initializers, _triggerLabel_extraInitializers);
367
+ __esDecorate(null, null, _modalTitle_decorators, { kind: "field", name: "modalTitle", static: false, private: false, access: { has: obj => "modalTitle" in obj, get: obj => obj.modalTitle, set: (obj, value) => { obj.modalTitle = value; } }, metadata: _metadata }, _modalTitle_initializers, _modalTitle_extraInitializers);
368
+ __esDecorate(null, null, _baseUrl_decorators, { kind: "field", name: "baseUrl", static: false, private: false, access: { has: obj => "baseUrl" in obj, get: obj => obj.baseUrl, set: (obj, value) => { obj.baseUrl = value; } }, metadata: _metadata }, _baseUrl_initializers, _baseUrl_extraInitializers);
369
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
370
+ RlseWidgetComponent = _classThis = _classDescriptor.value;
371
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
372
+ __runInitializers(_classThis, _classExtraInitializers);
373
+ })();
374
+ return RlseWidgetComponent = _classThis;
375
+ })();
376
+ export { RlseWidgetComponent };
@@ -0,0 +1,4 @@
1
+ export { RlseWidgetComponent } from './components/rlse-widget.component';
2
+ export { WidgetDataService, type WidgetDataState } from './services/widget-data.service';
3
+ export type { WidgetConfig, Change, WidgetChangesResponse, } from '@rlse/widget-core';
4
+ export { DEFAULT_CONFIG } from '@rlse/widget-core';
@@ -0,0 +1,5 @@
1
+ // Angular Components
2
+ export { RlseWidgetComponent } from './components/rlse-widget.component';
3
+ // Angular Services
4
+ export { WidgetDataService } from './services/widget-data.service';
5
+ export { DEFAULT_CONFIG } from '@rlse/widget-core';
@@ -0,0 +1,14 @@
1
+ import { OnDestroy } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
+ import { type FetchChangesResult } from '@rlse/widget-core';
4
+ import type { Change } from '@rlse/widget-core';
5
+ export interface WidgetDataState {
6
+ changes: Change[];
7
+ isLoading: boolean;
8
+ error: Error | null;
9
+ }
10
+ export declare class WidgetDataService implements OnDestroy {
11
+ private abortController;
12
+ fetchChanges(orgSlug: string, appSlug: string | undefined, limit: number, baseUrl: string): Observable<FetchChangesResult>;
13
+ ngOnDestroy(): void;
14
+ }
@@ -0,0 +1,93 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
36
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
+ };
39
+ import { Injectable } from '@angular/core';
40
+ import { Observable } from 'rxjs';
41
+ import { fetchChanges } from '@rlse/widget-core';
42
+ let WidgetDataService = (() => {
43
+ let _classDecorators = [Injectable({
44
+ providedIn: 'root',
45
+ })];
46
+ let _classDescriptor;
47
+ let _classExtraInitializers = [];
48
+ let _classThis;
49
+ var WidgetDataService = _classThis = class {
50
+ constructor() {
51
+ this.abortController = null;
52
+ }
53
+ fetchChanges(orgSlug, appSlug, limit, baseUrl) {
54
+ // Cancel any in-flight request
55
+ if (this.abortController) {
56
+ this.abortController.abort();
57
+ }
58
+ this.abortController = new AbortController();
59
+ return new Observable((observer) => {
60
+ fetchChanges({
61
+ orgSlug,
62
+ appSlug,
63
+ limit,
64
+ baseUrl,
65
+ signal: this.abortController?.signal,
66
+ })
67
+ .then((result) => {
68
+ observer.next(result);
69
+ observer.complete();
70
+ })
71
+ .catch((err) => {
72
+ observer.error(err);
73
+ });
74
+ return () => {
75
+ this.abortController?.abort();
76
+ };
77
+ });
78
+ }
79
+ ngOnDestroy() {
80
+ this.abortController?.abort();
81
+ }
82
+ };
83
+ __setFunctionName(_classThis, "WidgetDataService");
84
+ (() => {
85
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
86
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
87
+ WidgetDataService = _classThis = _classDescriptor.value;
88
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
89
+ __runInitializers(_classThis, _classExtraInitializers);
90
+ })();
91
+ return WidgetDataService = _classThis;
92
+ })();
93
+ export { WidgetDataService };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  export { RlseWidget } from './RlseWidget';
2
2
  export type { RlseWidgetProps } from './RlseWidget';
3
+ export { RlseWidgetEmbed } from './RlseWidgetEmbed';
4
+ export type { RlseWidgetEmbedProps } from './RlseWidgetEmbed';
5
+ export { RlseWidgetMenu } from './RlseWidgetMenu';
6
+ export type { RlseWidgetMenuProps } from './RlseWidgetMenu';
3
7
  export type { WidgetConfig, Change, WidgetChangesResponse } from './types';
package/dist/index.js CHANGED
@@ -1 +1,6 @@
1
+ // Main floating widget (default export)
1
2
  export { RlseWidget } from './RlseWidget';
3
+ // Embedded widget for header/sidenav
4
+ export { RlseWidgetEmbed } from './RlseWidgetEmbed';
5
+ // Menu widget for dropdowns
6
+ export { RlseWidgetMenu } from './RlseWidgetMenu';
package/dist/storage.d.ts CHANGED
@@ -1,11 +1 @@
1
- export declare function getStorageKey(orgSlug: string): string;
2
- export declare function getLastVisitKey(orgSlug: string): string;
3
- export declare function getSeenChangesKey(orgSlug: string): string;
4
- export declare function getLastVisit(orgSlug: string): number | null;
5
- export declare function setLastVisit(orgSlug: string): void;
6
- export declare function getSeenChanges(orgSlug: string): string[];
7
- export declare function markAllChangesAsSeen(orgSlug: string, changeIds: string[]): void;
8
- export declare function getUnreadCount(orgSlug: string, changes: {
9
- _id: string;
10
- }[]): number;
11
- export declare function shouldAutoShow(orgSlug: string, autoShowAfter: number): boolean;
1
+ export { getStorageKey, getLastVisitKey, getSeenChangesKey, getLastVisit, setLastVisit, getSeenChanges, markAllChangesAsSeen, getUnreadCount, shouldAutoShow, } from '@rlse/widget-core';
package/dist/storage.js CHANGED
@@ -1,80 +1,2 @@
1
- const STORAGE_KEY_PREFIX = 'rlse_widget_';
2
- const LAST_VISIT_KEY_SUFFIX = '_last_visit';
3
- const SEEN_CHANGES_KEY_SUFFIX = '_seen';
4
- export function getStorageKey(orgSlug) {
5
- return `${STORAGE_KEY_PREFIX}${orgSlug}`;
6
- }
7
- export function getLastVisitKey(orgSlug) {
8
- return `${getStorageKey(orgSlug)}${LAST_VISIT_KEY_SUFFIX}`;
9
- }
10
- export function getSeenChangesKey(orgSlug) {
11
- return `${getStorageKey(orgSlug)}${SEEN_CHANGES_KEY_SUFFIX}`;
12
- }
13
- export function getLastVisit(orgSlug) {
14
- if (typeof window === 'undefined')
15
- return null;
16
- try {
17
- const value = localStorage.getItem(getLastVisitKey(orgSlug));
18
- if (!value)
19
- return null;
20
- const parsed = parseInt(value, 10);
21
- return Number.isNaN(parsed) ? null : parsed;
22
- }
23
- catch {
24
- return null;
25
- }
26
- }
27
- export function setLastVisit(orgSlug) {
28
- if (typeof window === 'undefined')
29
- return;
30
- try {
31
- localStorage.setItem(getLastVisitKey(orgSlug), Date.now().toString());
32
- }
33
- catch {
34
- // Ignore storage errors
35
- }
36
- }
37
- export function getSeenChanges(orgSlug) {
38
- if (typeof window === 'undefined')
39
- return [];
40
- try {
41
- const value = localStorage.getItem(getSeenChangesKey(orgSlug));
42
- if (!value)
43
- return [];
44
- const parsed = JSON.parse(value);
45
- // Validate that parsed is an array of strings
46
- if (!Array.isArray(parsed) ||
47
- !parsed.every((item) => typeof item === 'string')) {
48
- return [];
49
- }
50
- return parsed;
51
- }
52
- catch {
53
- return [];
54
- }
55
- }
56
- export function markAllChangesAsSeen(orgSlug, changeIds) {
57
- if (typeof window === 'undefined')
58
- return;
59
- try {
60
- localStorage.setItem(getSeenChangesKey(orgSlug), JSON.stringify(changeIds));
61
- }
62
- catch {
63
- // Ignore storage errors
64
- }
65
- }
66
- export function getUnreadCount(orgSlug, changes) {
67
- if (typeof window === 'undefined')
68
- return 0;
69
- const seen = getSeenChanges(orgSlug);
70
- return changes.filter((c) => !seen.includes(c._id)).length;
71
- }
72
- export function shouldAutoShow(orgSlug, autoShowAfter) {
73
- if (typeof window === 'undefined')
74
- return false;
75
- const lastVisit = getLastVisit(orgSlug);
76
- if (!lastVisit)
77
- return true; // First visit
78
- const daysSinceVisit = (Date.now() - lastVisit) / (1000 * 60 * 60 * 24);
79
- return daysSinceVisit >= autoShowAfter;
80
- }
1
+ // Re-export all storage functions from core
2
+ export { getStorageKey, getLastVisitKey, getSeenChangesKey, getLastVisit, setLastVisit, getSeenChanges, markAllChangesAsSeen, getUnreadCount, shouldAutoShow, } from '@rlse/widget-core';
@@ -0,0 +1,5 @@
1
+ export { default as RlseWidget } from './components/RlseWidget.svelte';
2
+ export { default as RlseWidgetEmbed } from './components/RlseWidgetEmbed.svelte';
3
+ export { default as RlseWidgetMenu } from './components/RlseWidgetMenu.svelte';
4
+ export type { WidgetConfig, Change, WidgetChangesResponse, } from '@rlse/widget-core';
5
+ export { DEFAULT_CONFIG } from '@rlse/widget-core';
@@ -0,0 +1,5 @@
1
+ // Svelte Components
2
+ export { default as RlseWidget } from './components/RlseWidget.svelte';
3
+ export { default as RlseWidgetEmbed } from './components/RlseWidgetEmbed.svelte';
4
+ export { default as RlseWidgetMenu } from './components/RlseWidgetMenu.svelte';
5
+ export { DEFAULT_CONFIG } from '@rlse/widget-core';