@luckydye/calendar 1.1.2 → 1.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luckydye/calendar",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "author": "Tim Havlicek",
5
5
  "contributors": [],
6
6
  "description": "",
@@ -11,6 +11,7 @@ interface CalDAVSourceConfig extends CalendarSource {
11
11
  username: string;
12
12
  password: string;
13
13
  };
14
+ locked?: boolean;
14
15
  }
15
16
 
16
17
  interface ICalSource extends CalendarSource {
@@ -18,6 +19,7 @@ interface ICalSource extends CalendarSource {
18
19
  credentials: {
19
20
  url: string;
20
21
  };
22
+ locked?: boolean;
21
23
  }
22
24
 
23
25
  interface GoogleSource extends CalendarSource {
@@ -28,6 +30,7 @@ interface GoogleSource extends CalendarSource {
28
30
  tokenExpiry?: string;
29
31
  calendarId?: string;
30
32
  };
33
+ locked?: boolean;
31
34
  }
32
35
 
33
36
  interface InhouseSource extends CalendarSource {
@@ -37,6 +40,7 @@ interface InhouseSource extends CalendarSource {
37
40
  employeeId: string;
38
41
  unitId?: string;
39
42
  };
43
+ locked?: boolean;
40
44
  }
41
45
 
42
46
  type ConfigurableSource = CalDAVSourceConfig | ICalSource | GoogleSource | InhouseSource;
@@ -132,6 +136,11 @@ export class CalDAVConfigElement extends LitElement {
132
136
  cursor: pointer;
133
137
  }
134
138
 
139
+ .source-locked {
140
+ cursor: pointer;
141
+ margin-left: 8px;
142
+ }
143
+
135
144
  .source-actions {
136
145
  display: flex;
137
146
  gap: 8px;
@@ -463,6 +472,11 @@ export class CalDAVConfigElement extends LitElement {
463
472
  this.saveSources();
464
473
  }
465
474
 
475
+ toggleLocked(source: ConfigurableSource) {
476
+ source.locked = !source.locked;
477
+ this.saveSources();
478
+ }
479
+
466
480
  saveForm() {
467
481
  if (!this.formData.name?.trim()) {
468
482
  alert('Please enter a calendar name');
@@ -496,6 +510,7 @@ export class CalDAVConfigElement extends LitElement {
496
510
  },
497
511
  color: this.formData.color || "#FF6E68",
498
512
  enabled: this.formData.enabled ?? true,
513
+ locked: this.formData.locked ?? false,
499
514
  } as CalDAVSourceConfig;
500
515
  } else if (this.formData.type === "ical") {
501
516
  if (!this.formData.credentials?.url) {
@@ -511,6 +526,7 @@ export class CalDAVConfigElement extends LitElement {
511
526
  },
512
527
  color: this.formData.color || "#FF6E68",
513
528
  enabled: this.formData.enabled ?? true,
529
+ locked: this.formData.locked ?? false,
514
530
  } as ICalSource;
515
531
  } else if (this.formData.type === "google") {
516
532
  if (!this.formData.credentials?.accessToken) {
@@ -530,6 +546,7 @@ export class CalDAVConfigElement extends LitElement {
530
546
  },
531
547
  color: this.formData.color || "#4285F4",
532
548
  enabled: this.formData.enabled ?? true,
549
+ locked: this.formData.locked ?? false,
533
550
  } as GoogleSource;
534
551
  } else if (this.formData.type === "inhouse") {
535
552
  if (!this.formData.credentials?.sessionCookie || !this.formData.credentials?.employeeId) {
@@ -548,6 +565,7 @@ export class CalDAVConfigElement extends LitElement {
548
565
  },
549
566
  color: this.formData.color || "#FF6E68",
550
567
  enabled: this.formData.enabled ?? true,
568
+ locked: this.formData.locked ?? false,
551
569
  } as InhouseSource;
552
570
  } else {
553
571
  return;
@@ -754,6 +772,13 @@ export class CalDAVConfigElement extends LitElement {
754
772
  @change=${() => this.toggleEnabled(source)}
755
773
  title="${source.enabled ? "Disable" : "Enable"} sync"
756
774
  />
775
+ <input
776
+ type="checkbox"
777
+ class="source-locked"
778
+ .checked=${source.locked}
779
+ @change=${() => this.toggleLocked(source)}
780
+ title="${source.locked ? "Unlock (allow editing)" : "Lock (read-only)"}"
781
+ />
757
782
  <div class="source-actions">
758
783
  <button
759
784
  class="icon-btn"
@@ -5,13 +5,13 @@ export interface Calendar {
5
5
  name: string;
6
6
  color: string;
7
7
  enabled: boolean;
8
+ locked?: boolean;
8
9
  sourceId: string;
9
10
  sourceType: string;
10
11
  calendarUrl?: string;
11
12
  fetchEvents(): Promise<CalendarEvent[]>;
12
13
  createEvent?(event: Omit<CalendarEvent, 'calendar' | 'color'>): Promise<CalendarEvent>;
13
14
  updateEvent?(id: string, updates: Partial<CalendarEvent>): Promise<CalendarEvent>;
14
- moveEvent?(id: string, newStart: Date, newEnd: Date): Promise<CalendarEvent>;
15
15
  deleteEvent?(id: string): Promise<void>;
16
16
  }
17
17
 
@@ -29,7 +29,6 @@ export interface CalendarSource {
29
29
  fetchEvents(): Promise<CalendarEvent[]>;
30
30
  createEvent?(event: Omit<CalendarEvent, 'calendar' | 'color'>): Promise<CalendarEvent>;
31
31
  updateEvent?(id: string, updates: Partial<CalendarEvent>): Promise<CalendarEvent>;
32
- moveEvent?(id: string, newStart: Date, newEnd: Date): Promise<CalendarEvent>;
33
32
  deleteEvent?(id: string): Promise<void>;
34
33
  }
35
34
 
@@ -101,6 +101,8 @@ export class CalendarInternal {
101
101
 
102
102
  enabledCalendars: Set<string> = new Set();
103
103
 
104
+ lockedCalendars: Set<string> = new Set();
105
+
104
106
  storage?: CalendarStorage;
105
107
  initPromise: Promise<void>;
106
108
 
@@ -193,6 +195,11 @@ export class CalendarInternal {
193
195
  this.sendEvents();
194
196
  }
195
197
 
198
+ setLockedCalendars(calendarIds: string[]) {
199
+ this.lockedCalendars = new Set(calendarIds);
200
+ this.sendEvents();
201
+ }
202
+
196
203
  expandRecurringEvent(event: CalendarEvent): CalendarEvent[] {
197
204
  if (!event.rrule) {
198
205
  return [event];
@@ -252,8 +259,20 @@ export class CalendarInternal {
252
259
  })
253
260
  : baseEvents;
254
261
 
262
+ // Mark events from locked calendars as read-only
263
+ const lockedEvents = this.lockedCalendars.size > 0
264
+ ? enabledEvents.map(e => {
265
+ const isLocked = (e.calendarId && this.lockedCalendars.has(e.calendarId)) ||
266
+ (e.sourceId && this.lockedCalendars.has(e.sourceId));
267
+ if (isLocked) {
268
+ return { ...e, readOnly: true };
269
+ }
270
+ return e;
271
+ })
272
+ : enabledEvents;
273
+
255
274
  const expandedEvents: CalendarEvent[] = [];
256
- for (const event of enabledEvents) {
275
+ for (const event of lockedEvents) {
257
276
  const instances = this.expandRecurringEvent(event);
258
277
  expandedEvents.push(...instances);
259
278
  }