Skip to content

Commit 56b1c63

Browse files
authored
Merge pull request #90 from buggregator/issue/#83-lock-events
Issue/#83 lock events
2 parents 3b626c5 + a622584 commit 56b1c63

File tree

10 files changed

+220
-24
lines changed

10 files changed

+220
-24
lines changed

plugins/events.client.ts

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,25 @@ import { useApiTransport } from '~/src/shared/lib/use-api-transport'
33
import type { EventId, EventType, ServerEvent } from '~/src/shared/types';
44
import { useCachedIdsStore } from "~/stores/cached-ids";
55
import { useEventStore } from "~/stores/events";
6+
import { useLockedIdsStore } from "~/stores/locked-ids";
67

78
export default defineNuxtPlugin(() => {
89
const eventsStore = useEventStore();
910
const cachedIdsStore = useCachedIdsStore();
11+
const lockedIdsStore = useLockedIdsStore();
12+
13+
const {
14+
lockedIds,
15+
} = storeToRefs(lockedIdsStore)
16+
17+
const {
18+
events,
19+
} = storeToRefs(eventsStore)
1020

1121
const {
1222
deleteEvent,
1323
deleteEventsAll,
24+
deleteEventsList,
1425
deleteEventsByType,
1526
getEventsAll,
1627
getEvent,
@@ -19,7 +30,36 @@ export default defineNuxtPlugin(() => {
1930
rayStopExecution,
2031
} = useApiTransport();
2132

33+
const removeList = async (uuids: EventId[]) => {
34+
if (uuids.length === 1) {
35+
const res = await deleteEvent(uuids[0])
36+
37+
if (res) {
38+
eventsStore.removeById(uuids[0]);
39+
cachedIdsStore.removeById(uuids[0]);
40+
}
41+
42+
return
43+
}
44+
45+
const res = await deleteEventsList(uuids)
46+
47+
if (res) {
48+
eventsStore.removeByIds(uuids);
49+
cachedIdsStore.removeByIds(uuids);
50+
}
51+
}
2252
const removeAll = async () => {
53+
if (lockedIds.value.length) {
54+
const removedIds = events.value
55+
.filter(({ uuid }) => !lockedIds.value.includes(uuid))
56+
.map(({ uuid }) => uuid)
57+
58+
await removeList(removedIds)
59+
60+
return
61+
}
62+
2363
const res = await deleteEventsAll()
2464

2565
if (res) {
@@ -29,20 +69,25 @@ export default defineNuxtPlugin(() => {
2969
}
3070

3171
const removeById = async (eventId: EventId) => {
32-
const res = await deleteEvent(eventId)
72+
await removeList([eventId])
73+
}
3374

34-
if (res) {
35-
eventsStore.removeById(eventId);
36-
cachedIdsStore.removeById(eventId);
75+
const removeByType = async (eventType: EventType) => {
76+
if (lockedIds.value.length) {
77+
const removedIds = events.value
78+
.filter(({ type, uuid }) => type !== eventType || lockedIds.value.includes(uuid))
79+
.map(({ uuid }) => uuid)
80+
81+
await removeList(removedIds)
82+
83+
return
3784
}
38-
}
3985

40-
const removeByType = async (type: EventType) => {
41-
const res = await deleteEventsByType(type)
86+
const res = await deleteEventsByType(eventType)
4287

4388
if (res) {
44-
eventsStore.removeByType(type);
45-
cachedIdsStore.removeByType(type);
89+
eventsStore.removeByType(eventType);
90+
cachedIdsStore.removeByType(eventType);
4691
}
4792
}
4893

@@ -61,10 +106,6 @@ export default defineNuxtPlugin(() => {
61106
})
62107
}
63108

64-
const {
65-
events,
66-
} = storeToRefs(eventsStore)
67-
68109
const {
69110
cachedIds,
70111
} = storeToRefs(cachedIdsStore)
@@ -88,6 +129,11 @@ export default defineNuxtPlugin(() => {
88129
rayExecution: {
89130
continue: rayContinueExecution,
90131
stop: rayStopExecution,
132+
},
133+
lockedIds: {
134+
items: lockedIds,
135+
add: lockedIdsStore.add,
136+
remove: lockedIdsStore.remove,
91137
}
92138
}
93139
}

src/shared/lib/io/use-events-requests.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type TUseEventsRequests = () => {
55
getAll: () => Promise<ServerEvent<unknown>[]>,
66
getSingle: (id: EventId) => Promise<ServerEvent<unknown> | null>,
77
deleteAll: () => Promise<void | Response>,
8+
deleteList: (uuids: EventId[]) => Promise<void | Response>,
89
deleteSingle: (id: EventId) => Promise<void | Response>,
910
deleteByType: (type: EventType) => Promise<void | Response>,
1011
getEventRestUrl: (param: EventId | undefined) => string
@@ -45,6 +46,11 @@ export const useEventsRequests: TUseEventsRequests = () => {
4546
console.error('Fetch Error', err)
4647
})
4748

49+
const deleteList = (uuids: EventId[]) => fetch(getEventRestUrl(), { method: 'DELETE', body: JSON.stringify({ uuids }) })
50+
.catch((err) => {
51+
console.error('Fetch Error', err)
52+
})
53+
4854
const deleteByType = (type: EventType) => fetch(getEventRestUrl(), { method: 'DELETE', body: JSON.stringify({type}) })
4955
.catch((err) => {
5056
console.error('Fetch Error', err)
@@ -54,6 +60,7 @@ export const useEventsRequests: TUseEventsRequests = () => {
5460
getAll,
5561
getSingle,
5662
deleteAll,
63+
deleteList,
5764
deleteSingle,
5865
deleteByType,
5966
getEventRestUrl

src/shared/lib/use-api-transport/use-api-transport.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const useApiTransport = () => {
1212
getAll,
1313
getSingle,
1414
deleteAll,
15+
deleteList,
1516
deleteSingle,
1617
deleteByType,
1718
getEventRestUrl
@@ -73,6 +74,14 @@ export const useApiTransport = () => {
7374
return deleteAll();
7475
}
7576

77+
const deleteEventsList = (uuids: EventId[]) => {
78+
if (getWSConnection()) {
79+
return centrifuge.rpc(`delete:api/events`, { uuids })
80+
}
81+
82+
return deleteList(uuids);
83+
}
84+
7685
const deleteEventsByType = (type: EventType) => {
7786
if (getWSConnection()) {
7887
return centrifuge.rpc(`delete:api/events`, {type})
@@ -98,6 +107,7 @@ export const useApiTransport = () => {
98107
getEvent: getSingle,
99108
deleteEvent,
100109
deleteEventsAll,
110+
deleteEventsList,
101111
deleteEventsByType,
102112
rayStopExecution,
103113
rayContinueExecution,

src/shared/types/events.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface ServerEvent<T> {
2828

2929
export interface NormalizedEvent<T> {
3030
id: EventId,
31-
type: EventType | string,
31+
type: EventType,
3232
labels: string[],
3333
origin: object | null,
3434
serverName: string,

src/shared/types/local-storage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
export enum LOCAL_STORAGE_KEYS {
33
CACHED_EVENTS = "cached_events",
4+
LOCKED_EVENTS = "locked_events",
45
THEME = "theme",
56
NAVBAR = "navbar",
67
}

src/shared/ui/preview-card/preview-card-header.vue

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type Props = {
99
eventUrl: string;
1010
tags: string[];
1111
isOpen: boolean;
12+
isLocked: boolean;
1213
isVisibleControls: boolean;
1314
};
1415
@@ -17,6 +18,7 @@ type Emits = {
1718
toggleView: [value: boolean];
1819
copy: [value: boolean];
1920
download: [value: boolean];
21+
lock: [value: boolean];
2022
};
2123
2224
const props = withDefaults(defineProps<Props>(), {
@@ -30,18 +32,22 @@ const changeView = () => {
3032
emit("toggleView", true);
3133
};
3234
33-
const onDeleteButtonClick = () => {
35+
const deleteEvent = () => {
3436
emit("delete", true);
3537
};
3638
37-
const onCopyButtonRightClick = () => {
39+
const copyEvent = () => {
3840
emit("copy", true);
3941
};
4042
41-
const onCopyButtonClick = () => {
43+
const downloadEvent = () => {
4244
emit("download", true);
4345
};
4446
47+
const lockEvent = () => {
48+
emit("lock", true);
49+
};
50+
4551
const isVisibleTags = computed(() => props.tags.length > 0);
4652
</script>
4753

@@ -73,8 +79,8 @@ const isVisibleTags = computed(() => props.tags.length > 0);
7379
<div v-if="isVisibleControls" class="preview-card-header__container">
7480
<button
7581
class="preview-card-header__button preview-card-header__button--copy"
76-
@click="onCopyButtonClick"
77-
@click.right.prevent="onCopyButtonRightClick"
82+
@click="downloadEvent"
83+
@click.right.prevent="copyEvent"
7884
>
7985
<IconSvg name="copy" class="preview-card-header__button-icon" />
8086
</button>
@@ -98,10 +104,21 @@ const isVisibleTags = computed(() => props.tags.length > 0);
98104

99105
<button
100106
class="preview-card-header__button preview-card-header__button--delete"
101-
@click="onDeleteButtonClick"
107+
:disabled="isLocked"
108+
@click="deleteEvent"
102109
>
103110
<IconSvg name="times" class="preview-card-header__button-icon" />
104111
</button>
112+
113+
<button
114+
class="preview-card-header__button preview-card-header__button--lock"
115+
:class="{
116+
'preview-card-header__button--locked': isLocked,
117+
}"
118+
@click="lockEvent"
119+
>
120+
<IconSvg name="lock" class="preview-card-header__button-icon" />
121+
</button>
105122
</div>
106123
</div>
107124
</template>
@@ -177,6 +194,10 @@ $eventTypeColorsMap: (
177194
@apply bg-#{$color}-600 ring-#{$color}-300;
178195
}
179196
}
197+
198+
&:disabled {
199+
@apply opacity-50 cursor-not-allowed;
200+
}
180201
}
181202
182203
.preview-card-header__button--collapse {
@@ -191,7 +212,19 @@ $eventTypeColorsMap: (
191212
@apply text-red-700 bg-white dark:bg-red-700 hover:bg-red-700 hover:text-white;
192213
}
193214
215+
.preview-card-header__button--lock {
216+
@apply text-gray-700 dark:bg-gray-400 bg-gray-200 hover:bg-green-700 hover:text-white;
217+
}
218+
219+
.preview-card-header__button--locked {
220+
@apply text-white dark:text-white bg-green-700 dark:bg-green-700 ring-2 ring-green-700 hover:bg-green-800 dark:hover:bg-green-500;
221+
}
222+
194223
.preview-card-header__button-icon {
195224
@apply p-1 dark:fill-white;
225+
226+
.preview-card-header__button--lock & {
227+
@apply p-0.5;
228+
}
196229
}
197230
</style>

src/shared/ui/preview-card/preview-card.vue

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ type Props = {
1717
1818
const props = defineProps<Props>();
1919
20+
const {
21+
$lockedIds: { items },
22+
} = useNuxtApp();
23+
2024
const isCollapsed = ref(false);
25+
const isLocked = ref((items || []).value.includes(props.event.id));
2126
const isOptimized = ref(false);
2227
const isVisibleControls = ref(true);
2328
@@ -54,6 +59,20 @@ const deleteEvent = () => {
5459
return $events?.removeById(props.event.id);
5560
};
5661
62+
const toggleEventLock = () => {
63+
const { $lockedIds } = useNuxtApp();
64+
65+
if (($lockedIds?.items.value || []).includes(props.event.id)) {
66+
$lockedIds?.remove(props.event.id);
67+
68+
isLocked.value = false;
69+
} else {
70+
$lockedIds?.add(props.event.id);
71+
72+
isLocked.value = true;
73+
}
74+
};
75+
5776
const downloadImage = () => {
5877
changeVisibleControls(false);
5978
@@ -129,11 +148,13 @@ onBeforeUnmount(() => {
129148
:event-id="event.id"
130149
:tags="normalizedTags"
131150
:is-open="!isCollapsed && !isOptimized"
151+
:is-locked="isLocked"
132152
:is-visible-controls="isVisibleControls && !isOptimized"
133153
@toggle-view="toggleView"
134154
@delete="deleteEvent"
135155
@copy="copyCode"
136156
@download="downloadImage"
157+
@lock="toggleEventLock"
137158
/>
138159

139160
<div

stores/cached-ids.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,18 @@ export const useCachedIdsStore = defineStore("useCachedIdsStore", {
6161
this.cachedIds[type].length = 0;
6262
syncLocalStorage(this.cachedIds);
6363
},
64-
removeById(eventUuid: EventId) {
64+
removeByIds(uuids: EventId[]) {
6565
this.cachedTypesList.forEach((type) => {
6666
this.cachedIds[type] = this.cachedIds[type].filter(
67-
(uuid: EventId) => uuid !== eventUuid
67+
(uuid: EventId) => uuids.includes(uuid)
6868
);
6969
});
7070

7171
syncLocalStorage(this.cachedIds);
7272
},
73+
removeById(eventUuid: EventId) {
74+
this.removeByIds([eventUuid]);
75+
},
7376
removeAll() {
7477
this.cachedIds = initialCachedIds;
7578
syncLocalStorage(this.cachedIds);

0 commit comments

Comments
 (0)