Merge pull request #447 from buster-so/big-nate/bus-1232-update-users-list-immediately-after-new-user-request-is-made

Move organization user to a server type
This commit is contained in:
Nate Kelley 2025-07-08 15:07:00 -06:00 committed by GitHub
commit f5bdb9d8da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 56 additions and 37 deletions

View File

@ -1,2 +1 @@
export * from './interfaces';
export * from './permissionInterfaces'; export * from './permissionInterfaces';

View File

@ -1,22 +0,0 @@
import type { OrganizationRole } from '@buster/server-shared/organization';
export interface OrganizationUser {
id: string;
email: string;
name: string;
avatar_url: string | null;
status: 'active' | 'inactive';
role: OrganizationRole;
datasets: OrganizationUserDataset[];
}
export interface OrganizationUserDataset {
can_query: boolean;
id: string;
name: string;
lineage: {
name: string;
id: string;
type: 'user' | 'datasets' | 'permissionGroups';
}[][];
}

View File

@ -1,7 +1,6 @@
import type { OrganizationUser } from '@/api/asset_interfaces/users';
import { serverFetch } from '../../createServerInstance'; import { serverFetch } from '../../createServerInstance';
import { mainApi } from '../instances'; import { mainApi } from '../instances';
import type { Organization } from '@buster/server-shared/organization'; import type { Organization, OrganizationUser } from '@buster/server-shared/organization';
export const getOrganizationUsers = async ({ export const getOrganizationUsers = async ({
organizationId organizationId

View File

@ -1,5 +1,5 @@
import type { ShareAssetType } from '@buster/server-shared/share'; import type { ShareAssetType } from '@buster/server-shared/share';
import type { OrganizationUser } from '@/api/asset_interfaces/users'; import type { OrganizationUser } from '@buster/server-shared/organization';
import { BASE_URL } from '../config'; import { BASE_URL } from '../config';
import { serverFetch } from '../../createServerInstance'; import { serverFetch } from '../../createServerInstance';
import { mainApi } from '../instances'; import { mainApi } from '../instances';

View File

@ -1,5 +1,5 @@
import { queryOptions } from '@tanstack/react-query'; import { queryOptions } from '@tanstack/react-query';
import type { OrganizationUser } from '@/api/asset_interfaces/users'; import type { OrganizationUser } from '@buster/server-shared/organization';
const organizationUsers = (organizationId: string) => const organizationUsers = (organizationId: string) =>
queryOptions<OrganizationUser[]>({ queryOptions<OrganizationUser[]>({

View File

@ -4,9 +4,9 @@ import type {
BusterUserDataset, BusterUserDataset,
BusterUserDatasetGroup, BusterUserDatasetGroup,
BusterUserPermissionGroup, BusterUserPermissionGroup,
BusterUserTeamListItem, BusterUserTeamListItem
OrganizationUser
} from '@/api/asset_interfaces/users'; } from '@/api/asset_interfaces/users';
import type { OrganizationUser } from '@buster/server-shared/organization';
import type { import type {
UserFavoriteResponse, UserFavoriteResponse,
UserResponse, UserResponse,

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import type { OrganizationUser } from '@/api/asset_interfaces/users'; import type { OrganizationUser } from '@buster/server-shared/organization';
import { ListUserItem } from '@/components/features/list/ListUserItem'; import { ListUserItem } from '@/components/features/list/ListUserItem';
import { import {
type BusterListColumn, type BusterListColumn,

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import type { OrganizationUser } from '@/api/asset_interfaces'; import type { OrganizationUser } from '@buster/server-shared/organization';
import { Avatar } from '@/components/ui/avatar'; import { Avatar } from '@/components/ui/avatar';
import { Text, Title } from '@/components/ui/typography'; import { Text, Title } from '@/components/ui/typography';

View File

@ -1,5 +1,5 @@
import React, { useMemo } from 'react'; import React, { useMemo } from 'react';
import type { OrganizationUserDataset } from '@/api/asset_interfaces'; import type { OrganizationUserDataset } from '@buster/server-shared/organization';
import { PermissionLineageBreadcrumb } from '@/components/features/PermissionComponents'; import { PermissionLineageBreadcrumb } from '@/components/features/PermissionComponents';
import { import {
type BusterListColumn, type BusterListColumn,
@ -102,7 +102,12 @@ export const UserDatasetListContainer = React.memo(
rows={rows} rows={rows}
showHeader={false} showHeader={false}
showSelectAll={false} showSelectAll={false}
emptyState={useMemo(() => <EmptyStateList text="No datasets found" />, [])} emptyState={useMemo(
() => (
<EmptyStateList text="No datasets found" />
),
[]
)}
/> />
</InfiniteListContainer> </InfiniteListContainer>
); );

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import type { OrganizationUser } from '@/api/asset_interfaces'; import type { OrganizationUser } from '@buster/server-shared/organization';
import { PermissionSearchAndListWrapper } from '@/components/features/PermissionComponents'; import { PermissionSearchAndListWrapper } from '@/components/features/PermissionComponents';
import { useDebounceSearch } from '@/hooks'; import { useDebounceSearch } from '@/hooks';
import { UserDatasetListContainer } from './UserDatasetListContainer'; import { UserDatasetListContainer } from './UserDatasetListContainer';

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { BusterOrganizationRoleLabels, type OrganizationUser } from '@/api/asset_interfaces'; import { BusterOrganizationRoleLabels } from '@/api/asset_interfaces';
import { useUpdateUser } from '@/api/buster_rest/users'; import { useUpdateUser } from '@/api/buster_rest/users';
import { import {
Card, Card,
@ -13,6 +13,7 @@ import { AppTooltip } from '@/components/ui/tooltip';
import { Text } from '@/components/ui/typography'; import { Text } from '@/components/ui/typography';
import { useMemoizedFn } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { User } from '@buster/server-shared/user'; import { User } from '@buster/server-shared/user';
import type { OrganizationUser } from '@buster/server-shared/organization';
export const UserDefaultAccess: React.FC<{ export const UserDefaultAccess: React.FC<{
user: OrganizationUser; user: OrganizationUser;

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import type { OrganizationUser } from '@/api/asset_interfaces/users'; import type { OrganizationUser } from '@buster/server-shared/organization';
import { HeaderExplanation } from '@/components/features/PermissionComponents'; import { HeaderExplanation } from '@/components/features/PermissionComponents';
export const UserLineageHeader = React.memo( export const UserLineageHeader = React.memo(

View File

@ -1,4 +1,4 @@
import type { OrganizationUser } from '@/api/asset_interfaces'; import type { OrganizationUser } from '@buster/server-shared/organization';
export const OrganizationUserStatusText: Record<OrganizationUser['status'], string> = { export const OrganizationUserStatusText: Record<OrganizationUser['status'], string> = {
active: 'Active', active: 'Active',

View File

@ -1,2 +1,3 @@
export * from './organization.types'; export * from './organization.types';
export * from './roles.types'; export * from './roles.types';
export * from './user.types';

View File

@ -0,0 +1,36 @@
import { z } from 'zod/v4';
import { OrganizationRoleSchema } from './roles.types';
export const LineageUserItemTypeSchema = z.enum(['user', 'datasets', 'permissionGroups']);
// Zod schema for lineage item
const LineageItemSchema = z.object({
name: z.string(),
id: z.string(),
type: LineageUserItemTypeSchema,
});
// Zod schema for OrganizationUserDataset
export const OrganizationUserDatasetSchema = z.object({
can_query: z.boolean(),
id: z.string(),
name: z.string(),
lineage: z.array(z.array(LineageItemSchema)),
});
// Zod schema for OrganizationUser
export const OrganizationUserSchema = z.object({
id: z.string(),
email: z.string(),
name: z.string(),
avatar_url: z.string().nullable(),
status: z.enum(['active', 'inactive']),
role: OrganizationRoleSchema,
datasets: z.array(OrganizationUserDatasetSchema),
});
// Export inferred types
export type OrganizationUser = z.infer<typeof OrganizationUserSchema>;
export type OrganizationUserDataset = z.infer<typeof OrganizationUserDatasetSchema>;
export type LinageUserItemType = z.infer<typeof LineageUserItemTypeSchema>;
export type LinageUserItem = z.infer<typeof LineageItemSchema>;