@makolabs/ripple 1.2.3 → 1.2.4
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/README.md +77 -0
- package/dist/adapters/ai/OpenAIAdapter.js +16 -11
- package/dist/adapters/ai/types.d.ts +3 -3
- package/dist/adapters/storage/BaseAdapter.d.ts +1 -1
- package/dist/adapters/storage/BaseAdapter.js +1 -1
- package/dist/adapters/storage/S3Adapter.js +2 -2
- package/dist/ai/AIChatInterface.svelte +32 -34
- package/dist/ai/AIChatInterface.svelte.d.ts +0 -1
- package/dist/ai/AIChatInterfaceTestWrapper.svelte +26 -0
- package/dist/ai/AIChatInterfaceTestWrapper.svelte.d.ts +17 -0
- package/dist/ai/ChatInput.svelte +7 -15
- package/dist/ai/ChatInput.svelte.d.ts +0 -2
- package/dist/ai/CodeRenderer.svelte +25 -12
- package/dist/ai/ComposeDropdown.svelte +17 -14
- package/dist/ai/MermaidRenderer.svelte +21 -17
- package/dist/ai/MermaidRenderer.svelte.d.ts +0 -1
- package/dist/ai/MessageBox.svelte +10 -7
- package/dist/ai/ThinkingDisplay.svelte +67 -43
- package/dist/ai/ai-chat-interface.d.ts +22 -21
- package/dist/ai/ai-chat-interface.js +8 -7
- package/dist/ai/content-detector.js +2 -2
- package/dist/button/ButtonTestWrapper.svelte +10 -0
- package/dist/button/ButtonTestWrapper.svelte.d.ts +7 -0
- package/dist/charts/Chart.svelte +6 -1
- package/dist/config/ai.js +1 -0
- package/dist/drawer/DrawerTestWrapper.svelte +19 -0
- package/dist/drawer/DrawerTestWrapper.svelte.d.ts +9 -0
- package/dist/drawer/drawer.d.ts +19 -18
- package/dist/drawer/drawer.js +7 -6
- package/dist/elements/accordion/Accordion.svelte +1 -1
- package/dist/elements/accordion/Accordion.svelte.d.ts +1 -1
- package/dist/elements/accordion/AccordionTestWrapper.svelte +21 -0
- package/dist/elements/accordion/AccordionTestWrapper.svelte.d.ts +10 -0
- package/dist/elements/badge/Badge.svelte +5 -4
- package/dist/elements/badge/BadgeTestWrapper.svelte +14 -0
- package/dist/elements/badge/BadgeTestWrapper.svelte.d.ts +9 -0
- package/dist/elements/badge/badge.d.ts +40 -39
- package/dist/elements/badge/badge.js +14 -13
- package/dist/elements/dropdown/Dropdown.svelte +0 -1
- package/dist/elements/pagination/Pagination.svelte +20 -26
- package/dist/elements/progress/Progress.svelte +3 -3
- package/dist/elements/timeline/Timeline.svelte +1 -1
- package/dist/file-browser/FileBrowser.svelte +7 -10
- package/dist/filters/CompactFilters.svelte +3 -3
- package/dist/forms/Checkbox.svelte +0 -1
- package/dist/forms/CheckboxTestWrapper.svelte +8 -0
- package/dist/forms/CheckboxTestWrapper.svelte.d.ts +4 -0
- package/dist/forms/DateRange.svelte +186 -198
- package/dist/forms/Form.svelte +1 -0
- package/dist/forms/Input.svelte +14 -5
- package/dist/forms/InputTestWrapper.svelte +8 -0
- package/dist/forms/InputTestWrapper.svelte.d.ts +4 -0
- package/dist/forms/NumberInput.svelte +2 -2
- package/dist/forms/RadioInputs.svelte +1 -1
- package/dist/forms/RadioPill.svelte +1 -1
- package/dist/forms/Slider.svelte +2 -2
- package/dist/forms/Tags.svelte +3 -3
- package/dist/forms/ToggleTestWrapper.svelte +8 -0
- package/dist/forms/ToggleTestWrapper.svelte.d.ts +7 -0
- package/dist/forms/slider.js +1 -1
- package/dist/header/PageHeader.svelte +2 -1
- package/dist/header/breadcrumbs.d.ts +47 -33
- package/dist/header/breadcrumbs.js +12 -11
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -0
- package/dist/layout/activity-list/ActivityList.svelte +9 -11
- package/dist/layout/card/CardTestWrapper.svelte +15 -0
- package/dist/layout/card/CardTestWrapper.svelte.d.ts +7 -0
- package/dist/layout/card/RankedCard.svelte +2 -3
- package/dist/layout/navbar/navbar.d.ts +19 -18
- package/dist/layout/navbar/navbar.js +7 -6
- package/dist/layout/sidebar/NavGroup.svelte +1 -0
- package/dist/layout/table/Cells.svelte +5 -5
- package/dist/layout/table/Table.svelte +8 -8
- package/dist/layout/table/table.d.ts +28 -24
- package/dist/layout/table/table.js +14 -13
- package/dist/modal/Modal.svelte +1 -1
- package/dist/modal/ModalTestWrapper.svelte +20 -0
- package/dist/modal/ModalTestWrapper.svelte.d.ts +8 -0
- package/dist/modal/modal.d.ts +1 -20
- package/dist/pipeline/Pipeline.svelte +29 -17
- package/dist/user-management/README.md +417 -0
- package/dist/user-management/UserManagement.svelte +184 -0
- package/dist/user-management/UserManagement.svelte.d.ts +4 -0
- package/dist/user-management/UserManagementTestWrapper.svelte +47 -0
- package/dist/user-management/UserManagementTestWrapper.svelte.d.ts +7 -0
- package/dist/user-management/UserModal.svelte +303 -0
- package/dist/user-management/UserModal.svelte.d.ts +4 -0
- package/dist/user-management/UserModalTestWrapper.svelte +22 -0
- package/dist/user-management/UserModalTestWrapper.svelte.d.ts +7 -0
- package/dist/user-management/UserTable.svelte +219 -0
- package/dist/user-management/UserTable.svelte.d.ts +4 -0
- package/dist/user-management/UserTableTestWrapper.svelte +41 -0
- package/dist/user-management/UserTableTestWrapper.svelte.d.ts +7 -0
- package/dist/user-management/UserViewModal.svelte +282 -0
- package/dist/user-management/UserViewModal.svelte.d.ts +4 -0
- package/dist/user-management/UserViewModalTestWrapper.svelte +22 -0
- package/dist/user-management/UserViewModalTestWrapper.svelte.d.ts +7 -0
- package/dist/user-management/index.d.ts +10 -0
- package/dist/user-management/index.js +11 -0
- package/dist/user-management/user-management.d.ts +99 -0
- package/dist/user-management/user-management.js +42 -0
- package/package.json +3 -1
- package/dist/types/markdown.d.ts +0 -14
- package/dist/types/variants.d.ts +0 -1
- package/dist/types/variants.js +0 -1
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Modal, Button, TabGroup, TabContent, type TabItem, cn } from '../index.js';
|
|
3
|
+
import type { UserViewModalProps } from './user-management.js';
|
|
4
|
+
import { getUserDisplayName } from './user-management.js';
|
|
5
|
+
import { SvelteDate } from 'svelte/reactivity';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
open = $bindable(),
|
|
9
|
+
user = $bindable(),
|
|
10
|
+
onEdit,
|
|
11
|
+
onClose,
|
|
12
|
+
class: className
|
|
13
|
+
}: UserViewModalProps = $props();
|
|
14
|
+
|
|
15
|
+
// Local state
|
|
16
|
+
let activeTab = $state<'profile' | 'permissions'>('profile');
|
|
17
|
+
|
|
18
|
+
// Define tabs
|
|
19
|
+
const tabs: TabItem[] = [
|
|
20
|
+
{
|
|
21
|
+
value: 'profile',
|
|
22
|
+
label: 'Profile',
|
|
23
|
+
disabled: false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
value: 'permissions',
|
|
27
|
+
label: 'Permissions',
|
|
28
|
+
disabled: false
|
|
29
|
+
}
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
function handleClose() {
|
|
33
|
+
open = false;
|
|
34
|
+
activeTab = 'profile';
|
|
35
|
+
if (onClose) onClose();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function handleEdit() {
|
|
39
|
+
if (onEdit && user) {
|
|
40
|
+
onEdit(user);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getModalTitle() {
|
|
45
|
+
return getUserDisplayName(user);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function formatDate(timestamp?: number) {
|
|
49
|
+
if (!timestamp) return 'Never';
|
|
50
|
+
return new SvelteDate(timestamp).toLocaleDateString('en-US', {
|
|
51
|
+
year: 'numeric',
|
|
52
|
+
month: 'short',
|
|
53
|
+
day: 'numeric'
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
{#snippet MailIcon()}
|
|
59
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
60
|
+
<path
|
|
61
|
+
stroke-linecap="round"
|
|
62
|
+
stroke-linejoin="round"
|
|
63
|
+
stroke-width="2"
|
|
64
|
+
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
|
65
|
+
></path>
|
|
66
|
+
</svg>
|
|
67
|
+
{/snippet}
|
|
68
|
+
|
|
69
|
+
{#snippet PhoneIcon()}
|
|
70
|
+
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
71
|
+
<path
|
|
72
|
+
stroke-linecap="round"
|
|
73
|
+
stroke-linejoin="round"
|
|
74
|
+
stroke-width="2"
|
|
75
|
+
d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"
|
|
76
|
+
></path>
|
|
77
|
+
</svg>
|
|
78
|
+
{/snippet}
|
|
79
|
+
|
|
80
|
+
{#snippet ProfileIcon()}
|
|
81
|
+
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
82
|
+
<path
|
|
83
|
+
stroke-linecap="round"
|
|
84
|
+
stroke-linejoin="round"
|
|
85
|
+
stroke-width="2"
|
|
86
|
+
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
|
87
|
+
></path>
|
|
88
|
+
</svg>
|
|
89
|
+
{/snippet}
|
|
90
|
+
|
|
91
|
+
{#snippet ShieldIcon()}
|
|
92
|
+
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
93
|
+
<path
|
|
94
|
+
stroke-linecap="round"
|
|
95
|
+
stroke-linejoin="round"
|
|
96
|
+
stroke-width="2"
|
|
97
|
+
d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
|
|
98
|
+
></path>
|
|
99
|
+
</svg>
|
|
100
|
+
{/snippet}
|
|
101
|
+
|
|
102
|
+
<Modal
|
|
103
|
+
{open}
|
|
104
|
+
onclose={handleClose}
|
|
105
|
+
title={getModalTitle()}
|
|
106
|
+
contentclass="max-w-4xl"
|
|
107
|
+
bodyclass="flex flex-col min-h-[500px]"
|
|
108
|
+
class={cn(className)}
|
|
109
|
+
>
|
|
110
|
+
<div class="flex h-full grow flex-col space-y-6">
|
|
111
|
+
<!-- Tab Navigation -->
|
|
112
|
+
<TabGroup {tabs} bind:selected={activeTab}>
|
|
113
|
+
<TabContent value="profile" persisted>
|
|
114
|
+
<!-- Profile Information -->
|
|
115
|
+
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
|
116
|
+
<!-- Basic Info -->
|
|
117
|
+
<div class="space-y-4">
|
|
118
|
+
<div class="rounded-lg bg-gray-50 p-4">
|
|
119
|
+
<div class="mb-3 flex items-center gap-2">
|
|
120
|
+
<span class="inline-flex">{@render ProfileIcon()}</span>
|
|
121
|
+
<h4 class="text-sm font-medium text-gray-700">Basic Information</h4>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="space-y-3">
|
|
124
|
+
<div>
|
|
125
|
+
<span class="text-xs text-gray-500">Name</span>
|
|
126
|
+
<p class="text-sm font-medium">
|
|
127
|
+
{getUserDisplayName(user)}
|
|
128
|
+
</p>
|
|
129
|
+
</div>
|
|
130
|
+
{#if user?.username}
|
|
131
|
+
<div>
|
|
132
|
+
<span class="text-xs text-gray-500">Username</span>
|
|
133
|
+
<p class="text-sm">{user.username}</p>
|
|
134
|
+
</div>
|
|
135
|
+
{/if}
|
|
136
|
+
<div>
|
|
137
|
+
<span class="text-xs text-gray-500">User ID</span>
|
|
138
|
+
<p class="font-mono text-xs break-all">{user?.id || 'N/A'}</p>
|
|
139
|
+
</div>
|
|
140
|
+
{#if user?.role}
|
|
141
|
+
<div>
|
|
142
|
+
<span class="text-xs text-gray-500">Role</span>
|
|
143
|
+
<p class="text-sm">
|
|
144
|
+
<span
|
|
145
|
+
class="inline-flex items-center rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800"
|
|
146
|
+
>
|
|
147
|
+
{user.role}
|
|
148
|
+
</span>
|
|
149
|
+
</p>
|
|
150
|
+
</div>
|
|
151
|
+
{/if}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<!-- Contact Info -->
|
|
156
|
+
<div class="rounded-lg bg-gray-50 p-4">
|
|
157
|
+
<h4 class="mb-3 text-sm font-medium text-gray-700">Contact</h4>
|
|
158
|
+
<div class="space-y-2">
|
|
159
|
+
{#if user?.email_addresses?.[0]?.email_address}
|
|
160
|
+
<div class="flex items-center gap-2">
|
|
161
|
+
<span class="inline-flex text-gray-400">{@render MailIcon()}</span>
|
|
162
|
+
<span class="text-sm">{user.email_addresses[0].email_address}</span>
|
|
163
|
+
</div>
|
|
164
|
+
{/if}
|
|
165
|
+
{#if user?.phone_numbers?.[0]?.phone_number}
|
|
166
|
+
<div class="flex items-center gap-2">
|
|
167
|
+
<span class="inline-flex text-gray-400">{@render PhoneIcon()}</span>
|
|
168
|
+
<span class="text-sm">{user.phone_numbers[0].phone_number}</span>
|
|
169
|
+
</div>
|
|
170
|
+
{/if}
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
<!-- Account Status & Metadata -->
|
|
176
|
+
<div class="space-y-4">
|
|
177
|
+
<div class="rounded-lg bg-gray-50 p-4">
|
|
178
|
+
<h4 class="mb-3 text-sm font-medium text-gray-700">Account Status</h4>
|
|
179
|
+
<div class="space-y-3">
|
|
180
|
+
<div>
|
|
181
|
+
<span class="text-xs text-gray-500">Status</span>
|
|
182
|
+
<p class="text-sm">
|
|
183
|
+
<span
|
|
184
|
+
class="inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800"
|
|
185
|
+
>
|
|
186
|
+
Active
|
|
187
|
+
</span>
|
|
188
|
+
</p>
|
|
189
|
+
</div>
|
|
190
|
+
<div>
|
|
191
|
+
<span class="text-xs text-gray-500">Created</span>
|
|
192
|
+
<p class="text-sm">{formatDate(user?.created_at)}</p>
|
|
193
|
+
</div>
|
|
194
|
+
<div>
|
|
195
|
+
<span class="text-xs text-gray-500">Last Sign In</span>
|
|
196
|
+
<p class="text-sm">{formatDate(user?.last_sign_in_at)}</p>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
<!-- Additional Metadata -->
|
|
202
|
+
{#if user?.private_metadata && Object.keys(user.private_metadata).length > 0}
|
|
203
|
+
<div class="rounded-lg bg-gray-50 p-4">
|
|
204
|
+
<h4 class="mb-3 text-sm font-medium text-gray-700">Additional Information</h4>
|
|
205
|
+
<div class="space-y-2">
|
|
206
|
+
{#each Object.entries(user.private_metadata ?? {}) as [key, value] (key + value)}
|
|
207
|
+
<div>
|
|
208
|
+
<span class="text-xs text-gray-500">{key}</span>
|
|
209
|
+
<p class="font-mono text-sm text-gray-700">
|
|
210
|
+
{typeof value === 'string' && value.length > 50
|
|
211
|
+
? `${value.slice(0, 50)}...`
|
|
212
|
+
: String(value)}
|
|
213
|
+
</p>
|
|
214
|
+
</div>
|
|
215
|
+
{/each}
|
|
216
|
+
</div>
|
|
217
|
+
</div>
|
|
218
|
+
{/if}
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
</TabContent>
|
|
222
|
+
|
|
223
|
+
<TabContent value="permissions" persisted>
|
|
224
|
+
<!-- Permissions Information -->
|
|
225
|
+
<div class="space-y-6">
|
|
226
|
+
<!-- Current Role -->
|
|
227
|
+
{#if user?.role}
|
|
228
|
+
<div class="rounded-lg bg-gray-50 p-4">
|
|
229
|
+
<div class="mb-3 flex items-center gap-2">
|
|
230
|
+
<span class="inline-flex text-blue-600">{@render ShieldIcon()}</span>
|
|
231
|
+
<h4 class="text-sm font-medium text-gray-700">Current Role</h4>
|
|
232
|
+
</div>
|
|
233
|
+
<div class="flex items-center justify-between">
|
|
234
|
+
<div>
|
|
235
|
+
<p class="text-sm font-medium text-blue-600">{user.role}</p>
|
|
236
|
+
{#if user.permissions}
|
|
237
|
+
<p class="mt-1 text-xs text-gray-600">
|
|
238
|
+
{user.permissions.length} permission{user.permissions.length === 1 ? '' : 's'}
|
|
239
|
+
</p>
|
|
240
|
+
{/if}
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
{/if}
|
|
245
|
+
|
|
246
|
+
<!-- Permissions List -->
|
|
247
|
+
<div>
|
|
248
|
+
<h4 class="mb-3 text-sm font-medium text-gray-700">Assigned Permissions</h4>
|
|
249
|
+
{#if user?.permissions && user.permissions.length > 0}
|
|
250
|
+
<div class="max-h-80 overflow-y-auto rounded-lg border border-gray-200 bg-white">
|
|
251
|
+
<div class="divide-y divide-gray-100">
|
|
252
|
+
{#each user.permissions as permission (permission)}
|
|
253
|
+
<div class="px-4 py-3">
|
|
254
|
+
<div class="flex items-center gap-2 text-sm">
|
|
255
|
+
<div class="h-1.5 w-1.5 shrink-0 rounded-full bg-green-500"></div>
|
|
256
|
+
<span class="font-mono text-gray-700">{permission}</span>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
{/each}
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
{:else}
|
|
263
|
+
<div class="rounded-lg bg-gray-50 p-6 text-center">
|
|
264
|
+
<p class="text-sm text-gray-500">No permissions assigned</p>
|
|
265
|
+
</div>
|
|
266
|
+
{/if}
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
</TabContent>
|
|
270
|
+
</TabGroup>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<!-- View Mode Actions -->
|
|
274
|
+
{#snippet footer()}
|
|
275
|
+
<div class="flex justify-end gap-3">
|
|
276
|
+
<Button variant="outline" onclick={handleClose}>Close</Button>
|
|
277
|
+
{#if onEdit}
|
|
278
|
+
<Button color="primary" onclick={handleEdit}>Edit User</Button>
|
|
279
|
+
{/if}
|
|
280
|
+
</div>
|
|
281
|
+
{/snippet}
|
|
282
|
+
</Modal>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import UserViewModal from './UserViewModal.svelte';
|
|
3
|
+
import type { UserViewModalProps } from './user-management.js';
|
|
4
|
+
|
|
5
|
+
interface Props extends UserViewModalProps {
|
|
6
|
+
testId?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
open = $bindable(),
|
|
11
|
+
user = $bindable(),
|
|
12
|
+
permissions = [],
|
|
13
|
+
onEdit,
|
|
14
|
+
onClose = () => {},
|
|
15
|
+
testId,
|
|
16
|
+
...rest
|
|
17
|
+
}: Props = $props();
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<div data-testid={testId}>
|
|
21
|
+
<UserViewModal bind:open bind:user {permissions} {onEdit} {onClose} {...rest} />
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UserViewModalProps } from './user-management.js';
|
|
2
|
+
interface Props extends UserViewModalProps {
|
|
3
|
+
testId?: string;
|
|
4
|
+
}
|
|
5
|
+
declare const UserViewModalTestWrapper: import("svelte").Component<Props, {}, "open" | "user">;
|
|
6
|
+
type UserViewModalTestWrapper = ReturnType<typeof UserViewModalTestWrapper>;
|
|
7
|
+
export default UserViewModalTestWrapper;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Management Module
|
|
3
|
+
* Components and utilities for managing users
|
|
4
|
+
*/
|
|
5
|
+
export { default as UserManagement } from './UserManagement.svelte';
|
|
6
|
+
export { default as UserTable } from './UserTable.svelte';
|
|
7
|
+
export { default as UserModal } from './UserModal.svelte';
|
|
8
|
+
export { default as UserViewModal } from './UserViewModal.svelte';
|
|
9
|
+
export type { User, UserEmail, UserPhone, Permission, Role, UserTableProps, UserModalProps, UserViewModalProps, UserManagementProps, FormErrors } from './user-management.js';
|
|
10
|
+
export { createUser, getUserDisplayName, getUserInitials } from './user-management.js';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Management Module
|
|
3
|
+
* Components and utilities for managing users
|
|
4
|
+
*/
|
|
5
|
+
// Components
|
|
6
|
+
export { default as UserManagement } from './UserManagement.svelte';
|
|
7
|
+
export { default as UserTable } from './UserTable.svelte';
|
|
8
|
+
export { default as UserModal } from './UserModal.svelte';
|
|
9
|
+
export { default as UserViewModal } from './UserViewModal.svelte';
|
|
10
|
+
// Utilities
|
|
11
|
+
export { createUser, getUserDisplayName, getUserInitials } from './user-management.js';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Management Types
|
|
3
|
+
* Type definitions for user management components
|
|
4
|
+
*/
|
|
5
|
+
import type { ClassValue } from 'tailwind-variants';
|
|
6
|
+
export interface UserEmail {
|
|
7
|
+
email_address: string;
|
|
8
|
+
verified?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface UserPhone {
|
|
11
|
+
phone_number: string;
|
|
12
|
+
verified?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface User {
|
|
15
|
+
id: string;
|
|
16
|
+
first_name?: string;
|
|
17
|
+
last_name?: string;
|
|
18
|
+
username?: string;
|
|
19
|
+
email_addresses?: UserEmail[];
|
|
20
|
+
phone_numbers?: UserPhone[];
|
|
21
|
+
image_url?: string;
|
|
22
|
+
created_at?: number;
|
|
23
|
+
last_sign_in_at?: number;
|
|
24
|
+
private_metadata?: Record<string, unknown>;
|
|
25
|
+
public_metadata?: Record<string, unknown>;
|
|
26
|
+
permissions?: string[];
|
|
27
|
+
role?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface Permission {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
category?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface Role {
|
|
36
|
+
value: string;
|
|
37
|
+
label: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
permissions: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface UserTableProps {
|
|
42
|
+
users: User[];
|
|
43
|
+
loading?: boolean;
|
|
44
|
+
currentPage?: number;
|
|
45
|
+
pageSize?: number;
|
|
46
|
+
totalUsers?: number;
|
|
47
|
+
onPageChange: (page: number) => void;
|
|
48
|
+
onPageSizeChange: (size: number) => void;
|
|
49
|
+
onSort?: (state: {
|
|
50
|
+
column: string | null;
|
|
51
|
+
direction: 'asc' | 'desc' | null;
|
|
52
|
+
}) => void;
|
|
53
|
+
onView: (user: User) => void;
|
|
54
|
+
onEdit: (user: User) => void;
|
|
55
|
+
onDelete: (userId: string) => void;
|
|
56
|
+
class?: ClassValue;
|
|
57
|
+
}
|
|
58
|
+
export interface UserModalProps {
|
|
59
|
+
open: boolean;
|
|
60
|
+
user: User | null;
|
|
61
|
+
roles?: Role[];
|
|
62
|
+
onSave: (user: User, mode: 'create' | 'edit') => Promise<void>;
|
|
63
|
+
onClose: () => void;
|
|
64
|
+
class?: ClassValue;
|
|
65
|
+
}
|
|
66
|
+
export interface UserViewModalProps {
|
|
67
|
+
open: boolean;
|
|
68
|
+
user: User | null;
|
|
69
|
+
permissions?: Permission[];
|
|
70
|
+
onEdit?: (user: User) => void;
|
|
71
|
+
onClose: () => void;
|
|
72
|
+
class?: ClassValue;
|
|
73
|
+
}
|
|
74
|
+
export interface UserManagementProps {
|
|
75
|
+
users: User[];
|
|
76
|
+
totalUsers: number;
|
|
77
|
+
loading?: boolean;
|
|
78
|
+
currentPage?: number;
|
|
79
|
+
pageSize?: number;
|
|
80
|
+
roles?: Role[];
|
|
81
|
+
permissions?: Permission[];
|
|
82
|
+
onPageChange: (page: number) => void;
|
|
83
|
+
onPageSizeChange: (size: number) => void;
|
|
84
|
+
onSort?: (state: {
|
|
85
|
+
column: string | null;
|
|
86
|
+
direction: 'asc' | 'desc' | null;
|
|
87
|
+
}) => void;
|
|
88
|
+
onCreateUser?: (userData: Partial<User>) => Promise<void>;
|
|
89
|
+
onUpdateUser?: (userId: string, userData: Partial<User>) => Promise<void>;
|
|
90
|
+
onDeleteUser?: (userId: string) => Promise<void>;
|
|
91
|
+
onDeleteUsers?: (userIds: string[]) => Promise<void>;
|
|
92
|
+
class?: ClassValue;
|
|
93
|
+
}
|
|
94
|
+
export interface FormErrors {
|
|
95
|
+
[key: string]: string;
|
|
96
|
+
}
|
|
97
|
+
export declare function createUser(partial?: Partial<User>): User;
|
|
98
|
+
export declare function getUserDisplayName(user: User | null): string;
|
|
99
|
+
export declare function getUserInitials(user: User | null): string;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Management Types
|
|
3
|
+
* Type definitions for user management components
|
|
4
|
+
*/
|
|
5
|
+
// Export convenience function to create a user object
|
|
6
|
+
export function createUser(partial = {}) {
|
|
7
|
+
return {
|
|
8
|
+
id: '',
|
|
9
|
+
first_name: '',
|
|
10
|
+
last_name: '',
|
|
11
|
+
username: '',
|
|
12
|
+
email_addresses: [],
|
|
13
|
+
phone_numbers: [],
|
|
14
|
+
permissions: [],
|
|
15
|
+
...partial
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
// Export convenience function to format user display name
|
|
19
|
+
export function getUserDisplayName(user) {
|
|
20
|
+
if (!user)
|
|
21
|
+
return 'Unknown User';
|
|
22
|
+
if (user.first_name || user.last_name) {
|
|
23
|
+
return `${user.first_name || ''} ${user.last_name || ''}`.trim();
|
|
24
|
+
}
|
|
25
|
+
if (user.username)
|
|
26
|
+
return user.username;
|
|
27
|
+
if (user.email_addresses?.[0]?.email_address) {
|
|
28
|
+
return user.email_addresses[0].email_address;
|
|
29
|
+
}
|
|
30
|
+
return user.id || 'Unknown User';
|
|
31
|
+
}
|
|
32
|
+
// Export convenience function to get user initials
|
|
33
|
+
export function getUserInitials(user) {
|
|
34
|
+
if (!user)
|
|
35
|
+
return '?';
|
|
36
|
+
if (user.first_name)
|
|
37
|
+
return user.first_name[0].toUpperCase();
|
|
38
|
+
if (user.email_addresses?.[0]?.email_address) {
|
|
39
|
+
return user.email_addresses[0].email_address[0].toUpperCase();
|
|
40
|
+
}
|
|
41
|
+
return '?';
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@makolabs/ripple",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "Simple Svelte 5 powered component library ✨",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"repository": {
|
|
@@ -71,7 +71,9 @@
|
|
|
71
71
|
"eslint-plugin-storybook": "^9.0.18",
|
|
72
72
|
"eslint-plugin-svelte": "^3.0.0",
|
|
73
73
|
"globals": "^16.0.0",
|
|
74
|
+
"husky": "^9.1.7",
|
|
74
75
|
"jsdom": "^26.0.0",
|
|
76
|
+
"lint-staged": "^16.2.6",
|
|
75
77
|
"prettier": "^3.4.2",
|
|
76
78
|
"prettier-plugin-svelte": "^3.3.3",
|
|
77
79
|
"prettier-plugin-tailwindcss": "^0.6.11",
|
package/dist/types/markdown.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
declare module 'markdown' {
|
|
2
|
-
export interface MarkdownOptions {
|
|
3
|
-
dialect?: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export interface MarkdownAPI {
|
|
7
|
-
toHTML(markdown: string, options?: MarkdownOptions): string;
|
|
8
|
-
parse(markdown: string): any;
|
|
9
|
-
renderJsonML(jsonml: any): string;
|
|
10
|
-
toHTMLTree(tree: any): any;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const markdown: MarkdownAPI;
|
|
14
|
-
}
|
package/dist/types/variants.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/types/variants.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|