better-auth-ui-svelte 0.6.2 → 0.7.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.
- package/dist/components/admin/admin-view.svelte +3 -2
- package/dist/components/admin/organizations-admin-table.svelte +47 -19
- package/dist/components/admin/organizations-admin-table.svelte.d.ts +11 -1
- package/dist/components/organization/organization-name-form.svelte +5 -1
- package/dist/components/settings/security/change-email-card.svelte +5 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -0
- package/dist/types/admin.d.ts +27 -0
- package/package.json +1 -1
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
pathname,
|
|
25
25
|
view: viewProp,
|
|
26
26
|
hideNav,
|
|
27
|
-
organizationCustomActions
|
|
27
|
+
organizationCustomActions,
|
|
28
|
+
fetchOrganizations
|
|
28
29
|
}: Props = $props();
|
|
29
30
|
|
|
30
31
|
const { localization: contextLocalization, Link, adminBasePath } = getAuthUIConfig();
|
|
@@ -76,7 +77,7 @@
|
|
|
76
77
|
{:else if view === 'USERS'}
|
|
77
78
|
<UsersAdminTable syncWithUrl={true} />
|
|
78
79
|
{:else if view === 'ORGANIZATIONS'}
|
|
79
|
-
<OrganizationsAdminTable syncWithUrl={true} customActions={organizationCustomActions} />
|
|
80
|
+
<OrganizationsAdminTable syncWithUrl={true} customActions={organizationCustomActions} {fetchOrganizations} />
|
|
80
81
|
{/if}
|
|
81
82
|
</div>
|
|
82
83
|
</div>
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
SortingState
|
|
18
18
|
} from '@tanstack/table-core';
|
|
19
19
|
import { getCoreRowModel, getPaginationRowModel, getSortedRowModel } from '@tanstack/table-core';
|
|
20
|
-
import type { Organization, AdminTableAction } from '../../types/admin.js';
|
|
20
|
+
import type { Organization, AdminTableAction, FetchOrganizationsResponse } from '../../types/admin.js';
|
|
21
21
|
import { createRawSnippet } from 'svelte';
|
|
22
22
|
import {
|
|
23
23
|
getAuthClient,
|
|
@@ -46,13 +46,24 @@
|
|
|
46
46
|
initialPageSize = 10,
|
|
47
47
|
syncWithUrl = false,
|
|
48
48
|
onViewMembers,
|
|
49
|
-
customActions = []
|
|
49
|
+
customActions = [],
|
|
50
|
+
fetchOrganizations: fetchOrganizationsProp
|
|
50
51
|
}: {
|
|
51
52
|
initialPageSize?: number;
|
|
52
53
|
syncWithUrl?: boolean;
|
|
53
54
|
onViewMembers?: (organizationId: string) => void | Promise<void>;
|
|
54
55
|
/** Custom actions to add to the dropdown menu */
|
|
55
56
|
customActions?: AdminTableAction<Organization>[];
|
|
57
|
+
/**
|
|
58
|
+
* Custom function to fetch organizations. Use this to provide admin-level
|
|
59
|
+
* access to all organizations (e.g., via a custom API route that queries
|
|
60
|
+
* the database directly), since Better Auth's `organization.list()` only
|
|
61
|
+
* returns organizations the current user belongs to.
|
|
62
|
+
*/
|
|
63
|
+
fetchOrganizations?: (params: {
|
|
64
|
+
limit: number;
|
|
65
|
+
offset: number;
|
|
66
|
+
}) => Promise<FetchOrganizationsResponse>;
|
|
56
67
|
} = $props();
|
|
57
68
|
|
|
58
69
|
// Get Better Auth client and config
|
|
@@ -95,34 +106,51 @@
|
|
|
95
106
|
}
|
|
96
107
|
});
|
|
97
108
|
|
|
98
|
-
// Fetch organizations
|
|
109
|
+
// Fetch organizations
|
|
99
110
|
async function fetchOrganizations() {
|
|
100
111
|
isLoading = true;
|
|
101
112
|
try {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
113
|
+
if (fetchOrganizationsProp) {
|
|
114
|
+
// Use custom fetch function (recommended for admin access to all orgs)
|
|
115
|
+
const response = await fetchOrganizationsProp({
|
|
116
|
+
limit: pagination.pageSize,
|
|
117
|
+
offset: pagination.pageIndex * pagination.pageSize
|
|
118
|
+
});
|
|
108
119
|
|
|
109
|
-
|
|
110
|
-
// Better Auth organization.list doesn't support pagination params yet
|
|
111
|
-
// so we'll do client-side pagination for now
|
|
112
|
-
const allOrgs = (response as any[]).map((org) => ({
|
|
120
|
+
data = response.organizations.map((org) => ({
|
|
113
121
|
id: org.id,
|
|
114
122
|
name: org.name,
|
|
115
123
|
slug: org.slug,
|
|
116
124
|
logo: org.logo,
|
|
117
|
-
createdAt: org.createdAt ? new Date(org.createdAt) : null,
|
|
125
|
+
createdAt: org.createdAt ? new Date(org.createdAt as string) : null,
|
|
118
126
|
metadata: org.metadata
|
|
119
127
|
}));
|
|
128
|
+
pageCount = Math.ceil(response.total / pagination.pageSize);
|
|
129
|
+
} else {
|
|
130
|
+
// Fallback: Better Auth organization.list only returns orgs the user belongs to
|
|
131
|
+
const { data: response, error } = await authClient.organization.list({});
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
133
|
+
if (error) {
|
|
134
|
+
toast.error(error.message ?? 'Failed to fetch organizations');
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (response) {
|
|
139
|
+
const allOrgs = (response as any[]).map((org) => ({
|
|
140
|
+
id: org.id,
|
|
141
|
+
name: org.name,
|
|
142
|
+
slug: org.slug,
|
|
143
|
+
logo: org.logo,
|
|
144
|
+
createdAt: org.createdAt ? new Date(org.createdAt) : null,
|
|
145
|
+
metadata: org.metadata
|
|
146
|
+
}));
|
|
147
|
+
|
|
148
|
+
// Client-side pagination (organization.list doesn't support pagination)
|
|
149
|
+
const start = pagination.pageIndex * pagination.pageSize;
|
|
150
|
+
const end = start + pagination.pageSize;
|
|
151
|
+
data = allOrgs.slice(start, end);
|
|
152
|
+
pageCount = Math.ceil(allOrgs.length / pagination.pageSize);
|
|
153
|
+
}
|
|
126
154
|
}
|
|
127
155
|
} catch (err) {
|
|
128
156
|
toast.error('Failed to fetch organizations');
|
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import type { Organization, AdminTableAction } from '../../types/admin.js';
|
|
1
|
+
import type { Organization, AdminTableAction, FetchOrganizationsResponse } from '../../types/admin.js';
|
|
2
2
|
type $$ComponentProps = {
|
|
3
3
|
initialPageSize?: number;
|
|
4
4
|
syncWithUrl?: boolean;
|
|
5
5
|
onViewMembers?: (organizationId: string) => void | Promise<void>;
|
|
6
6
|
/** Custom actions to add to the dropdown menu */
|
|
7
7
|
customActions?: AdminTableAction<Organization>[];
|
|
8
|
+
/**
|
|
9
|
+
* Custom function to fetch organizations. Use this to provide admin-level
|
|
10
|
+
* access to all organizations (e.g., via a custom API route that queries
|
|
11
|
+
* the database directly), since Better Auth's `organization.list()` only
|
|
12
|
+
* returns organizations the current user belongs to.
|
|
13
|
+
*/
|
|
14
|
+
fetchOrganizations?: (params: {
|
|
15
|
+
limit: number;
|
|
16
|
+
offset: number;
|
|
17
|
+
}) => Promise<FetchOrganizationsResponse>;
|
|
8
18
|
};
|
|
9
19
|
declare const OrganizationsAdminTable: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
10
20
|
type OrganizationsAdminTable = ReturnType<typeof OrganizationsAdminTable>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Organization } from 'better-auth/plugins/organization';
|
|
3
|
+
import { untrack } from 'svelte';
|
|
3
4
|
import { createForm } from '@tanstack/svelte-form';
|
|
4
5
|
import { getAuthUIConfig } from '../../context/auth-ui-config.svelte.js';
|
|
5
6
|
import { cn, getLocalizedError } from '../../utils/utils.js';
|
|
@@ -92,9 +93,12 @@
|
|
|
92
93
|
const isSubmitting = $derived(form.state.isSubmitting);
|
|
93
94
|
|
|
94
95
|
// Update form values when organization changes
|
|
96
|
+
// Use untrack to prevent infinite loop from form state updates
|
|
95
97
|
$effect(() => {
|
|
96
98
|
if (organization?.name !== undefined) {
|
|
97
|
-
|
|
99
|
+
untrack(() => {
|
|
100
|
+
form.setFieldValue('name', organization.name || '');
|
|
101
|
+
});
|
|
98
102
|
}
|
|
99
103
|
});
|
|
100
104
|
</script>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
2
3
|
import { createForm } from '@tanstack/svelte-form';
|
|
3
4
|
import * as z from 'zod';
|
|
4
5
|
import { getAuthUIConfig } from '../../../context/auth-ui-config.svelte.js';
|
|
@@ -113,9 +114,12 @@
|
|
|
113
114
|
}));
|
|
114
115
|
|
|
115
116
|
// Update form values when session data changes
|
|
117
|
+
// Use untrack to prevent infinite loop from form state updates
|
|
116
118
|
$effect(() => {
|
|
117
119
|
if (sessionData?.user.email !== undefined) {
|
|
118
|
-
|
|
120
|
+
untrack(() => {
|
|
121
|
+
form.setFieldValue('email', sessionData.user.email || '');
|
|
122
|
+
});
|
|
119
123
|
}
|
|
120
124
|
});
|
|
121
125
|
</script>
|
package/dist/index.d.ts
CHANGED
|
@@ -98,7 +98,7 @@ export * from './utils/get-paths.js';
|
|
|
98
98
|
export { getAuthUIConfig, getAuthClient, getLocalization } from './context/auth-ui-config.svelte.js';
|
|
99
99
|
export { authLocalization } from './localization/auth-localization.js';
|
|
100
100
|
export type { AuthUIConfig, User, Session, AuthLocalization } from './types/index.js';
|
|
101
|
-
export type { UserWithRole, Organization, OrganizationMember, OrganizationWithMembers, OrganizationInvitation, AdminTableAction, UsersAdminTableProps, OrganizationsAdminTableProps, OrganizationMembersDetailProps, BanUserDialogProps, UpdateRoleDialogProps, ImpersonateUserDialogProps, AdminViewProps } from './types/admin.js';
|
|
101
|
+
export type { UserWithRole, Organization, OrganizationMember, OrganizationWithMembers, OrganizationInvitation, AdminTableAction, UsersAdminTableProps, OrganizationsAdminTableProps, FetchOrganizationsResponse, OrganizationMembersDetailProps, BanUserDialogProps, UpdateRoleDialogProps, ImpersonateUserDialogProps, AdminViewProps } from './types/admin.js';
|
|
102
102
|
import AuthFormComponent from './components/auth/auth-form.svelte';
|
|
103
103
|
import UserButtonComponent from './components/user-button.svelte';
|
|
104
104
|
import UserViewComponent from './components/user-view.svelte';
|
|
@@ -137,3 +137,4 @@ export type UserInvitationsCardProps = ComponentProps<typeof UserInvitationsCard
|
|
|
137
137
|
export type SettingsCardClassNames = ComponentProps<typeof SettingsCardComponent>;
|
|
138
138
|
export * from './types/auth-hooks.js';
|
|
139
139
|
export * from './types/auth-mutators.js';
|
|
140
|
+
export { fromStore } from './utils/store-to-rune.svelte.js';
|
package/dist/index.js
CHANGED
|
@@ -136,3 +136,4 @@ import UserInvitationsCardComponent from './components/organization/user-invitat
|
|
|
136
136
|
import SettingsCardComponent from './components/settings/shared/settings-card.svelte';
|
|
137
137
|
export * from './types/auth-hooks.js';
|
|
138
138
|
export * from './types/auth-mutators.js';
|
|
139
|
+
export { fromStore } from './utils/store-to-rune.svelte.js';
|
package/dist/types/admin.d.ts
CHANGED
|
@@ -107,6 +107,13 @@ export interface UsersAdminTableProps {
|
|
|
107
107
|
onResetPassword?: (userId: string) => void | Promise<void>;
|
|
108
108
|
onRevokeSessions?: (userId: string) => void | Promise<void>;
|
|
109
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Response type for the fetchOrganizations callback
|
|
112
|
+
*/
|
|
113
|
+
export interface FetchOrganizationsResponse {
|
|
114
|
+
organizations: Organization[];
|
|
115
|
+
total: number;
|
|
116
|
+
}
|
|
110
117
|
/**
|
|
111
118
|
* Props for organizations admin table
|
|
112
119
|
*/
|
|
@@ -122,6 +129,16 @@ export interface OrganizationsAdminTableProps {
|
|
|
122
129
|
onDeleteOrganization?: (organizationId: string) => void | Promise<void>;
|
|
123
130
|
/** Custom actions to add to the dropdown menu */
|
|
124
131
|
customActions?: AdminTableAction<Organization>[];
|
|
132
|
+
/**
|
|
133
|
+
* Custom function to fetch organizations. Use this to provide admin-level
|
|
134
|
+
* access to all organizations (e.g., via a custom API route that queries
|
|
135
|
+
* the database directly), since Better Auth's `organization.list()` only
|
|
136
|
+
* returns organizations the current user belongs to.
|
|
137
|
+
*/
|
|
138
|
+
fetchOrganizations?: (params: {
|
|
139
|
+
limit: number;
|
|
140
|
+
offset: number;
|
|
141
|
+
}) => Promise<FetchOrganizationsResponse>;
|
|
125
142
|
}
|
|
126
143
|
/**
|
|
127
144
|
* Props for organization members detail dialog
|
|
@@ -184,4 +201,14 @@ export interface AdminViewProps {
|
|
|
184
201
|
hideNav?: boolean;
|
|
185
202
|
/** Custom actions for organizations table */
|
|
186
203
|
organizationCustomActions?: AdminTableAction<Organization>[];
|
|
204
|
+
/**
|
|
205
|
+
* Custom function to fetch organizations. Use this to provide admin-level
|
|
206
|
+
* access to all organizations (e.g., via a custom API route that queries
|
|
207
|
+
* the database directly), since Better Auth's `organization.list()` only
|
|
208
|
+
* returns organizations the current user belongs to.
|
|
209
|
+
*/
|
|
210
|
+
fetchOrganizations?: (params: {
|
|
211
|
+
limit: number;
|
|
212
|
+
offset: number;
|
|
213
|
+
}) => Promise<FetchOrganizationsResponse>;
|
|
187
214
|
}
|