@caido-utils/frontend 0.1.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,64 @@
1
+ type __VLS_Props = {
2
+ title: string;
3
+ width: string;
4
+ showBack?: boolean;
5
+ showFooter?: boolean;
6
+ actionLabel?: string;
7
+ actionIcon?: string;
8
+ actionDisabled?: boolean;
9
+ actionLoading?: boolean;
10
+ cancelLabel?: string;
11
+ contentClass?: string;
12
+ };
13
+ declare var __VLS_26: {}, __VLS_28: {};
14
+ type __VLS_Slots = {} & {
15
+ default?: (props: typeof __VLS_26) => any;
16
+ } & {
17
+ footer?: (props: typeof __VLS_28) => any;
18
+ };
19
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
20
+ showBack: boolean;
21
+ showFooter: boolean;
22
+ actionLabel: string;
23
+ actionDisabled: boolean;
24
+ actionLoading: boolean;
25
+ cancelLabel: string;
26
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
27
+ showBack: boolean;
28
+ showFooter: boolean;
29
+ actionLabel: string;
30
+ actionDisabled: boolean;
31
+ actionLoading: boolean;
32
+ cancelLabel: string;
33
+ }>>>, {
34
+ showBack: boolean;
35
+ showFooter: boolean;
36
+ actionLabel: string;
37
+ actionDisabled: boolean;
38
+ actionLoading: boolean;
39
+ cancelLabel: string;
40
+ }, {}>;
41
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
42
+ export default _default;
43
+ type __VLS_WithDefaults<P, D> = {
44
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
45
+ default: D[K];
46
+ }> : P[K];
47
+ };
48
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
49
+ type __VLS_TypePropsToOption<T> = {
50
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
51
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
52
+ } : {
53
+ type: import('vue').PropType<T[K]>;
54
+ required: true;
55
+ };
56
+ };
57
+ type __VLS_WithSlots<T, S> = T & {
58
+ new (): {
59
+ $slots: S;
60
+ };
61
+ };
62
+ type __VLS_PrettifyLocal<T> = {
63
+ [K in keyof T]: T[K];
64
+ } & {};
@@ -0,0 +1,89 @@
1
+ <script setup lang="ts">
2
+ import Button from "primevue/button";
3
+ import Dialog from "primevue/dialog";
4
+
5
+ withDefaults(
6
+ defineProps<{
7
+ title: string;
8
+ width: string;
9
+ showBack?: boolean;
10
+ showFooter?: boolean;
11
+ actionLabel?: string;
12
+ actionIcon?: string;
13
+ actionDisabled?: boolean;
14
+ actionLoading?: boolean;
15
+ cancelLabel?: string;
16
+ contentClass?: string;
17
+ }>(),
18
+ {
19
+ showBack: false,
20
+ showFooter: true,
21
+ actionLabel: "Confirm",
22
+ actionDisabled: false,
23
+ actionLoading: false,
24
+ cancelLabel: "Cancel",
25
+ },
26
+ );
27
+
28
+ const emit = defineEmits<{
29
+ close: [];
30
+ back: [];
31
+ action: [];
32
+ }>();
33
+ </script>
34
+
35
+ <template>
36
+ <Dialog
37
+ :visible="true"
38
+ modal
39
+ :closable="false"
40
+ :style="{ width }"
41
+ :content-class="contentClass"
42
+ @update:visible="emit('close')"
43
+ >
44
+ <template #header>
45
+ <div class="flex items-center justify-between w-full">
46
+ <div class="flex items-center gap-3">
47
+ <Button
48
+ v-if="showBack"
49
+ icon="fas fa-arrow-left"
50
+ text
51
+ severity="secondary"
52
+ size="small"
53
+ @click="emit('back')"
54
+ />
55
+ <span class="font-semibold text-lg">{{ title }}</span>
56
+ </div>
57
+ <Button
58
+ icon="fas fa-times"
59
+ text
60
+ severity="secondary"
61
+ size="small"
62
+ @click="emit('close')"
63
+ />
64
+ </div>
65
+ </template>
66
+
67
+ <slot />
68
+
69
+ <template v-if="showFooter" #footer>
70
+ <slot name="footer">
71
+ <div class="flex justify-end gap-2">
72
+ <Button
73
+ :label="cancelLabel"
74
+ severity="secondary"
75
+ text
76
+ @click="emit('close')"
77
+ />
78
+ <Button
79
+ :label="actionLabel"
80
+ :icon="actionIcon"
81
+ :disabled="actionDisabled"
82
+ :loading="actionLoading"
83
+ @click="emit('action')"
84
+ />
85
+ </div>
86
+ </slot>
87
+ </template>
88
+ </Dialog>
89
+ </template>
@@ -0,0 +1,64 @@
1
+ type __VLS_Props = {
2
+ title: string;
3
+ width: string;
4
+ showBack?: boolean;
5
+ showFooter?: boolean;
6
+ actionLabel?: string;
7
+ actionIcon?: string;
8
+ actionDisabled?: boolean;
9
+ actionLoading?: boolean;
10
+ cancelLabel?: string;
11
+ contentClass?: string;
12
+ };
13
+ declare var __VLS_26: {}, __VLS_28: {};
14
+ type __VLS_Slots = {} & {
15
+ default?: (props: typeof __VLS_26) => any;
16
+ } & {
17
+ footer?: (props: typeof __VLS_28) => any;
18
+ };
19
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
20
+ showBack: boolean;
21
+ showFooter: boolean;
22
+ actionLabel: string;
23
+ actionDisabled: boolean;
24
+ actionLoading: boolean;
25
+ cancelLabel: string;
26
+ }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<__VLS_Props>, {
27
+ showBack: boolean;
28
+ showFooter: boolean;
29
+ actionLabel: string;
30
+ actionDisabled: boolean;
31
+ actionLoading: boolean;
32
+ cancelLabel: string;
33
+ }>>>, {
34
+ showBack: boolean;
35
+ showFooter: boolean;
36
+ actionLabel: string;
37
+ actionDisabled: boolean;
38
+ actionLoading: boolean;
39
+ cancelLabel: string;
40
+ }, {}>;
41
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
42
+ export default _default;
43
+ type __VLS_WithDefaults<P, D> = {
44
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_PrettifyLocal<P[K] & {
45
+ default: D[K];
46
+ }> : P[K];
47
+ };
48
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
49
+ type __VLS_TypePropsToOption<T> = {
50
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
51
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
52
+ } : {
53
+ type: import('vue').PropType<T[K]>;
54
+ required: true;
55
+ };
56
+ };
57
+ type __VLS_WithSlots<T, S> = T & {
58
+ new (): {
59
+ $slots: S;
60
+ };
61
+ };
62
+ type __VLS_PrettifyLocal<T> = {
63
+ [K in keyof T]: T[K];
64
+ } & {};
@@ -0,0 +1,12 @@
1
+ declare var __VLS_7: any, __VLS_8: any;
2
+ type __VLS_Slots = {} & {
3
+ [K in NonNullable<typeof __VLS_7>]?: (props: typeof __VLS_8) => any;
4
+ };
5
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
6
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
7
+ export default _default;
8
+ type __VLS_WithSlots<T, S> = T & {
9
+ new (): {
10
+ $slots: S;
11
+ };
12
+ };
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import PrimeCard from "primevue/card";
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+ </script>
8
+
9
+ <template>
10
+ <PrimeCard
11
+ v-bind="$attrs"
12
+ :pt="{
13
+ body: { class: 'h-full p-0' },
14
+ content: { class: 'h-full flex flex-col' },
15
+ }"
16
+ >
17
+ <template v-for="(_, slot) in $slots" #[slot]="scope">
18
+ <slot :name="slot" v-bind="scope || {}" />
19
+ </template>
20
+ </PrimeCard>
21
+ </template>
@@ -0,0 +1,12 @@
1
+ declare var __VLS_7: any, __VLS_8: any;
2
+ type __VLS_Slots = {} & {
3
+ [K in NonNullable<typeof __VLS_7>]?: (props: typeof __VLS_8) => any;
4
+ };
5
+ declare const __VLS_component: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}, {}>;
6
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
7
+ export default _default;
8
+ type __VLS_WithSlots<T, S> = T & {
9
+ new (): {
10
+ $slots: S;
11
+ };
12
+ };
@@ -0,0 +1,32 @@
1
+ declare const _default: <T extends Record<string, unknown>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
2
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & Readonly<import("vue").ExtractPropTypes<{}>>, never>, never> & {
3
+ items: T[];
4
+ selected: T[];
5
+ columns: {
6
+ key: string;
7
+ header: string;
8
+ width: string;
9
+ sortable?: boolean;
10
+ sortType?: "string" | "number" | "date";
11
+ }[];
12
+ rowKey: (item: T) => string;
13
+ activeKey?: string;
14
+ emptyMessage?: string;
15
+ selectable?: boolean;
16
+ } & Partial<{}>> & import("vue").PublicProps;
17
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
18
+ attrs: any;
19
+ slots: {
20
+ [x: string]: ((props: {
21
+ item: any;
22
+ value: any;
23
+ }) => any) | undefined;
24
+ };
25
+ emit: ((evt: "update:selected", value: T[]) => void) & ((evt: "row-click", item: T) => void);
26
+ }>) => import("vue").VNode & {
27
+ __ctx?: Awaited<typeof __VLS_setup>;
28
+ };
29
+ export default _default;
30
+ type __VLS_PrettifyLocal<T> = {
31
+ [K in keyof T]: T[K];
32
+ } & {};
@@ -0,0 +1,320 @@
1
+ <script setup lang="ts" generic="T extends Record<string, unknown>">
2
+ import VirtualScroller from "primevue/virtualscroller";
3
+ import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
4
+
5
+ type SortType = "string" | "number" | "date";
6
+
7
+ type Column = {
8
+ key: string;
9
+ header: string;
10
+ width: string;
11
+ sortable?: boolean;
12
+ sortType?: SortType;
13
+ };
14
+
15
+ type SortOrder = "asc" | "desc" | undefined;
16
+
17
+ const props = withDefaults(
18
+ defineProps<{
19
+ items: T[];
20
+ selected: T[];
21
+ columns: Column[];
22
+ rowKey: (item: T) => string;
23
+ activeKey?: string;
24
+ emptyMessage?: string;
25
+ selectable?: boolean;
26
+ }>(),
27
+ { selectable: false },
28
+ );
29
+
30
+ const emit = defineEmits<{
31
+ "update:selected": [value: T[]];
32
+ "row-click": [item: T];
33
+ }>();
34
+
35
+ const selectedKeys = ref(new Set<string>());
36
+
37
+ watch(
38
+ () => props.selected,
39
+ (val) => {
40
+ const keys = new Set<string>();
41
+ for (const item of val) {
42
+ keys.add(props.rowKey(item));
43
+ }
44
+ selectedKeys.value = keys;
45
+ },
46
+ { immediate: true },
47
+ );
48
+
49
+ function syncSelection() {
50
+ const result: T[] = [];
51
+ for (const item of props.items) {
52
+ if (selectedKeys.value.has(props.rowKey(item))) {
53
+ result.push(item);
54
+ }
55
+ }
56
+ emit("update:selected", result);
57
+ }
58
+
59
+ function toggleSelection(item: T) {
60
+ const key = props.rowKey(item);
61
+ if (selectedKeys.value.has(key)) {
62
+ selectedKeys.value.delete(key);
63
+ } else {
64
+ selectedKeys.value.add(key);
65
+ }
66
+ syncSelection();
67
+ }
68
+
69
+ function toggleAll() {
70
+ if (selectedKeys.value.size === props.items.length) {
71
+ selectedKeys.value.clear();
72
+ } else {
73
+ for (const item of props.items) {
74
+ selectedKeys.value.add(props.rowKey(item));
75
+ }
76
+ }
77
+ syncSelection();
78
+ }
79
+
80
+ const allSelected = computed(
81
+ () =>
82
+ props.items.length > 0 && selectedKeys.value.size === props.items.length,
83
+ );
84
+
85
+ function onRowClick(item: T) {
86
+ emit("row-click", item);
87
+ }
88
+
89
+ function isSelected(item: T): boolean {
90
+ return selectedKeys.value.has(props.rowKey(item));
91
+ }
92
+
93
+ function isActive(item: T): boolean {
94
+ if (props.activeKey === undefined) return false;
95
+ return props.rowKey(item) === props.activeKey;
96
+ }
97
+
98
+ const sortKey = ref<string | undefined>(undefined);
99
+ const sortOrder = ref<SortOrder>(undefined);
100
+
101
+ function toggleSort(col: Column) {
102
+ if (!col.sortable) return;
103
+
104
+ if (sortKey.value !== col.key) {
105
+ sortKey.value = col.key;
106
+ sortOrder.value = "asc";
107
+ } else if (sortOrder.value === "asc") {
108
+ sortOrder.value = "desc";
109
+ } else {
110
+ sortKey.value = undefined;
111
+ sortOrder.value = undefined;
112
+ }
113
+ }
114
+
115
+ const sortedItems = computed(() => {
116
+ if (sortKey.value === undefined || sortOrder.value === undefined) {
117
+ return props.items;
118
+ }
119
+
120
+ const key = sortKey.value;
121
+ const col = props.columns.find((c) => c.key === key);
122
+ const type = col?.sortType ?? "string";
123
+ const dir = sortOrder.value === "asc" ? 1 : -1;
124
+ const sorted = [...props.items];
125
+
126
+ sorted.sort((a, b) => {
127
+ const aVal = a[key];
128
+ const bVal = b[key];
129
+
130
+ if (aVal === undefined || aVal === "") return 1;
131
+ if (bVal === undefined || bVal === "") return -1;
132
+
133
+ if (type === "number") {
134
+ return (Number(aVal) - Number(bVal)) * dir;
135
+ }
136
+
137
+ if (type === "date") {
138
+ return (
139
+ (new Date(String(aVal)).getTime() - new Date(String(bVal)).getTime()) *
140
+ dir
141
+ );
142
+ }
143
+
144
+ return String(aVal).localeCompare(String(bVal)) * dir;
145
+ });
146
+
147
+ return sorted;
148
+ });
149
+
150
+ const VIRTUAL_THRESHOLD = 100;
151
+ const useVirtual = computed(
152
+ () => sortedItems.value.length >= VIRTUAL_THRESHOLD,
153
+ );
154
+
155
+ const scrollerKey = ref(0);
156
+ const containerRef = ref<HTMLElement>();
157
+ let resizeObserver: ResizeObserver | undefined;
158
+
159
+ onMounted(() => {
160
+ if (containerRef.value === undefined) return;
161
+ resizeObserver = new ResizeObserver((entries) => {
162
+ const entry = entries[0];
163
+ if (entry !== undefined && entry.contentRect.height > 0) {
164
+ scrollerKey.value++;
165
+ }
166
+ });
167
+ resizeObserver.observe(containerRef.value);
168
+ });
169
+
170
+ onBeforeUnmount(() => {
171
+ resizeObserver?.disconnect();
172
+ });
173
+ </script>
174
+
175
+ <template>
176
+ <div class="h-full flex flex-col min-h-0">
177
+ <table class="w-full border-collapse" :style="{ tableLayout: 'fixed' }">
178
+ <thead>
179
+ <tr>
180
+ <th
181
+ v-if="selectable"
182
+ class="w-8 px-2 py-1.5 bg-surface-900 sticky top-0 z-10"
183
+ >
184
+ <div
185
+ class="w-3.5 h-3.5 rounded-sm border cursor-pointer flex items-center justify-center transition-colors"
186
+ :class="
187
+ allSelected
188
+ ? 'bg-amber-500 border-amber-500'
189
+ : 'border-surface-500 hover:border-surface-300'
190
+ "
191
+ @click="toggleAll()"
192
+ >
193
+ <i
194
+ v-if="allSelected"
195
+ class="fas fa-check text-[8px] text-white"
196
+ />
197
+ </div>
198
+ </th>
199
+ <th
200
+ v-for="col in columns"
201
+ :key="col.key"
202
+ class="px-2.5 py-1.5 font-mono text-sm font-semibold text-surface-300 text-left bg-surface-900 border-b border-surface-700/50 sticky top-0 z-10 select-none"
203
+ :class="
204
+ col.sortable
205
+ ? 'cursor-pointer hover:text-surface-100 transition-colors'
206
+ : ''
207
+ "
208
+ :style="{ width: col.width }"
209
+ @click="toggleSort(col)"
210
+ >
211
+ <span class="flex items-center gap-1.5">
212
+ {{ col.header }}
213
+ <i
214
+ v-if="col.sortable && sortKey === col.key"
215
+ :class="[
216
+ 'fas text-[9px]',
217
+ sortOrder === 'asc' ? 'fa-chevron-up' : 'fa-chevron-down',
218
+ ]"
219
+ />
220
+ </span>
221
+ </th>
222
+ </tr>
223
+ </thead>
224
+ </table>
225
+ <div
226
+ ref="containerRef"
227
+ class="flex-1 min-h-0"
228
+ :class="useVirtual ? 'overflow-hidden' : 'overflow-y-auto'"
229
+ >
230
+ <div
231
+ v-if="sortedItems.length === 0"
232
+ class="flex flex-col items-center justify-center h-full gap-3 text-surface-500"
233
+ >
234
+ <i class="fas fa-inbox text-3xl text-surface-600" />
235
+ <span class="text-sm">{{ emptyMessage ?? "No data" }}</span>
236
+ </div>
237
+ <VirtualScroller
238
+ v-else
239
+ :key="scrollerKey"
240
+ :items="sortedItems"
241
+ :item-size="33"
242
+ :disabled="!useVirtual"
243
+ class="h-full"
244
+ >
245
+ <template
246
+ #content="{
247
+ items: visibleItems,
248
+ styleClass,
249
+ contentRef,
250
+ contentStyle,
251
+ }"
252
+ >
253
+ <table
254
+ :ref="contentRef"
255
+ :class="styleClass"
256
+ class="w-full border-collapse"
257
+ :style="{ tableLayout: 'fixed', ...contentStyle }"
258
+ >
259
+ <colgroup>
260
+ <col v-if="selectable" style="width: 32px" />
261
+ <col
262
+ v-for="col in columns"
263
+ :key="col.key"
264
+ :style="{ width: col.width }"
265
+ />
266
+ </colgroup>
267
+ <tbody>
268
+ <tr
269
+ v-for="item in visibleItems as T[]"
270
+ :key="rowKey(item)"
271
+ class="cursor-pointer transition-colors"
272
+ :class="[
273
+ isActive(item)
274
+ ? 'bg-amber-400/15 hover:bg-amber-400/25'
275
+ : isSelected(item)
276
+ ? 'bg-amber-400/10 hover:bg-amber-400/15'
277
+ : 'even:bg-white/[0.02] hover:bg-white/[0.04]',
278
+ ]"
279
+ @click="onRowClick(item)"
280
+ >
281
+ <td
282
+ v-if="selectable"
283
+ class="px-2 py-1.5 border-b border-surface-700/50"
284
+ @click.stop="toggleSelection(item)"
285
+ >
286
+ <div
287
+ class="w-3.5 h-3.5 rounded-sm border cursor-pointer flex items-center justify-center transition-colors"
288
+ :class="
289
+ isSelected(item)
290
+ ? 'bg-amber-500 border-amber-500'
291
+ : 'border-surface-600 hover:border-surface-400'
292
+ "
293
+ >
294
+ <i
295
+ v-if="isSelected(item)"
296
+ class="fas fa-check text-[8px] text-white"
297
+ />
298
+ </div>
299
+ </td>
300
+ <td
301
+ v-for="col in columns"
302
+ :key="col.key"
303
+ class="px-2.5 py-1.5 font-mono text-[13px] font-medium text-surface-200 overflow-hidden text-ellipsis whitespace-nowrap border-b border-surface-700/50"
304
+ >
305
+ <slot
306
+ :name="`cell-${col.key}`"
307
+ :item="item"
308
+ :value="item[col.key]"
309
+ >
310
+ <span class="truncate block">{{ item[col.key] }}</span>
311
+ </slot>
312
+ </td>
313
+ </tr>
314
+ </tbody>
315
+ </table>
316
+ </template>
317
+ </VirtualScroller>
318
+ </div>
319
+ </div>
320
+ </template>
@@ -0,0 +1,32 @@
1
+ declare const _default: <T extends Record<string, unknown>>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
2
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & Readonly<import("vue").ExtractPropTypes<{}>>, never>, never> & {
3
+ items: T[];
4
+ selected: T[];
5
+ columns: {
6
+ key: string;
7
+ header: string;
8
+ width: string;
9
+ sortable?: boolean;
10
+ sortType?: "string" | "number" | "date";
11
+ }[];
12
+ rowKey: (item: T) => string;
13
+ activeKey?: string;
14
+ emptyMessage?: string;
15
+ selectable?: boolean;
16
+ } & Partial<{}>> & import("vue").PublicProps;
17
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
18
+ attrs: any;
19
+ slots: {
20
+ [x: string]: ((props: {
21
+ item: any;
22
+ value: any;
23
+ }) => any) | undefined;
24
+ };
25
+ emit: ((evt: "update:selected", value: T[]) => void) & ((evt: "row-click", item: T) => void);
26
+ }>) => import("vue").VNode & {
27
+ __ctx?: Awaited<typeof __VLS_setup>;
28
+ };
29
+ export default _default;
30
+ type __VLS_PrettifyLocal<T> = {
31
+ [K in keyof T]: T[K];
32
+ } & {};
@@ -0,0 +1,3 @@
1
+ export { default as BaseDialog } from "./BaseDialog.vue";
2
+ export { default as Card } from "./Card.vue";
3
+ export { default as Table } from "./Table.vue";
@@ -0,0 +1,3 @@
1
+ export { default as BaseDialog } from "./BaseDialog.vue";
2
+ export { default as Card } from "./Card.vue";
3
+ export { default as Table } from "./Table.vue";
@@ -0,0 +1,2 @@
1
+ export { useDialogManager } from "./useDialogManager";
2
+ export { useFrontend } from "./useFrontend";
@@ -0,0 +1,2 @@
1
+ export { useDialogManager } from "./useDialogManager.js";
2
+ export { useFrontend } from "./useFrontend.js";
@@ -0,0 +1,14 @@
1
+ import { type Ref } from "vue";
2
+ interface DialogState<TType extends string> {
3
+ type: TType;
4
+ data: unknown;
5
+ }
6
+ interface DialogManager<TType extends string> {
7
+ activeDialog: Ref<DialogState<TType> | undefined>;
8
+ openDialog: <T = void>(type: TType, data?: T) => void;
9
+ closeDialog: () => void;
10
+ isDialogOpen: (type: TType) => boolean;
11
+ getDialogData: <T>() => T | undefined;
12
+ }
13
+ export declare function useDialogManager<TType extends string>(): DialogManager<TType>;
14
+ export {};
@@ -0,0 +1,23 @@
1
+ import { ref } from "vue";
2
+ export function useDialogManager() {
3
+ const activeDialog = ref();
4
+ const openDialog = (type, data) => {
5
+ activeDialog.value = { type, data };
6
+ };
7
+ const closeDialog = () => {
8
+ activeDialog.value = void 0;
9
+ };
10
+ const isDialogOpen = (type) => {
11
+ return activeDialog.value?.type === type;
12
+ };
13
+ const getDialogData = () => {
14
+ return activeDialog.value?.data;
15
+ };
16
+ return {
17
+ activeDialog,
18
+ openDialog,
19
+ closeDialog,
20
+ isDialogOpen,
21
+ getDialogData
22
+ };
23
+ }
@@ -0,0 +1,9 @@
1
+ import type { Caido } from "@caido/sdk-frontend";
2
+ import type { EditorView } from "@codemirror/view";
3
+ export declare function useFrontend(sdk: Caido): {
4
+ getEditorView: (showErrors?: boolean) => EditorView | undefined;
5
+ getEditorContent: () => string | undefined;
6
+ getSelectedText: () => string | undefined;
7
+ setEditorContent: (content: string, showErrors?: boolean) => boolean;
8
+ getReplayRequestId: () => string | undefined;
9
+ };
@@ -0,0 +1,64 @@
1
+ export function useFrontend(sdk) {
2
+ const getEditorView = (showErrors = false) => {
3
+ const editor = sdk.window.getActiveEditor();
4
+ if (editor === void 0) {
5
+ if (showErrors) {
6
+ sdk.window.showToast("No active editor", { variant: "error" });
7
+ }
8
+ return void 0;
9
+ }
10
+ const view = editor.getEditorView();
11
+ if (view === void 0) {
12
+ if (showErrors) {
13
+ sdk.window.showToast("Could not access editor view", {
14
+ variant: "error"
15
+ });
16
+ }
17
+ return void 0;
18
+ }
19
+ return view;
20
+ };
21
+ const getEditorContent = () => {
22
+ const view = getEditorView();
23
+ if (view === void 0) return void 0;
24
+ return view.state.doc.toString();
25
+ };
26
+ const getSelectedText = () => {
27
+ const view = getEditorView();
28
+ if (view === void 0) return void 0;
29
+ const { from, to } = view.state.selection.main;
30
+ if (from === to) return void 0;
31
+ return view.state.sliceDoc(from, to);
32
+ };
33
+ const setEditorContent = (content, showErrors = false) => {
34
+ const view = getEditorView(showErrors);
35
+ if (view === void 0) return false;
36
+ view.dispatch({
37
+ changes: {
38
+ from: 0,
39
+ to: view.state.doc.length,
40
+ insert: content
41
+ }
42
+ });
43
+ return true;
44
+ };
45
+ const getReplayRequestId = () => {
46
+ const session = sdk.replay.getCurrentSession();
47
+ if (!session || session.entryIds.length === 0) {
48
+ return void 0;
49
+ }
50
+ const lastEntryId = session.entryIds[session.entryIds.length - 1];
51
+ if (lastEntryId === void 0) {
52
+ return void 0;
53
+ }
54
+ const entry = sdk.replay.getEntry(lastEntryId);
55
+ return entry?.requestId;
56
+ };
57
+ return {
58
+ getEditorView,
59
+ getEditorContent,
60
+ getSelectedText,
61
+ setEditorContent,
62
+ getReplayRequestId
63
+ };
64
+ }
@@ -0,0 +1,8 @@
1
+ import type { CommandContext } from "@caido/sdk-frontend";
2
+ /**
3
+ * Get the request ID from a command context.
4
+ * Works with RequestContext (replay), RequestRowContext (http history),
5
+ * and ResponseContext.
6
+ * Throws if the context doesn't contain a request or the request hasn't been sent yet.
7
+ */
8
+ export declare function getRequestId(context: CommandContext): string;
@@ -0,0 +1,21 @@
1
+ export function getRequestId(context) {
2
+ switch (context.type) {
3
+ case "RequestContext": {
4
+ if (!context.request.id) {
5
+ throw new Error("Request must be sent first");
6
+ }
7
+ return context.request.id;
8
+ }
9
+ case "RequestRowContext": {
10
+ if (context.requests.length === 0) {
11
+ throw new Error("No request selected");
12
+ }
13
+ return context.requests[0].id;
14
+ }
15
+ case "ResponseContext": {
16
+ return context.request.id;
17
+ }
18
+ default:
19
+ throw new Error("Can't get request ID from this context");
20
+ }
21
+ }
@@ -0,0 +1 @@
1
+ export { getRequestId } from "./ctx";
@@ -0,0 +1 @@
1
+ export { getRequestId } from "./ctx.js";
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@caido-utils/frontend",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "exports": {
9
+ "./utils": {
10
+ "types": "./dist/utils/index.d.ts",
11
+ "import": "./dist/utils/index.js"
12
+ },
13
+ "./components": {
14
+ "types": "./dist/components/index.d.ts",
15
+ "import": "./dist/components/index.js"
16
+ },
17
+ "./composables": {
18
+ "types": "./dist/composables/index.d.ts",
19
+ "import": "./dist/composables/index.js"
20
+ }
21
+ },
22
+ "peerDependencies": {
23
+ "@caido/sdk-frontend": ">=0.54.0",
24
+ "@codemirror/view": ">=6.0.0",
25
+ "primevue": ">=4.0.0",
26
+ "vue": ">=3.4.0"
27
+ },
28
+ "devDependencies": {
29
+ "@caido/sdk-frontend": "0.54.2-beta.15",
30
+ "@codemirror/view": "6.28.1",
31
+ "primevue": "4.1.0",
32
+ "typescript": "^5.5.4",
33
+ "unbuild": "^3.6.1",
34
+ "vue": "3.4.37",
35
+ "vue-tsc": "^2.0.29"
36
+ },
37
+ "scripts": {
38
+ "build": "unbuild"
39
+ }
40
+ }