Merge branch 'staging' into dallin/bus-920-feature-finish-rest-of-permissions

This commit is contained in:
Nate Kelley 2025-01-17 09:47:08 -07:00
commit e7f08f9997
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
346 changed files with 1106 additions and 407 deletions

View File

@ -1,4 +1,4 @@
import mainApi, { BASE_URL } from '@/api/buster/instances';
import mainApi, { BASE_URL } from '@/api/buster-rest/instances';
import { BusterApiKeyListItem } from './interfaces';
export const getApiKeys = async (): Promise<{

View File

@ -1,4 +1,4 @@
import { BASE_URL } from '@/api/buster/instances';
import { BASE_URL } from '@/api/buster-rest/instances';
import { PublicAssetResponse } from './interface';
export const getAssetCheck = async ({

View File

@ -1,4 +1,4 @@
import { mainApi } from '../../buster';
import { mainApi } from '../instances';
import { DatasetGroup } from './responseInterfaces';
export const listDatasetGroups = async () => {

View File

@ -22,7 +22,8 @@ export const useGetDatasetPermissionsOverview = (dataset_id: string) => {
return useCreateReactQuery({
queryKey: ['dataset_permissions_overview', dataset_id],
queryFn
queryFn,
staleTime: 1000 * 10
});
};
@ -45,8 +46,7 @@ export const useDatasetListPermissionGroups = (dataset_id: string) => {
return useCreateReactQuery({
queryKey: [PERMISSION_GROUP_QUERY_KEY, dataset_id],
queryFn,
staleTime: 1000 * 5 // 5 seconds
queryFn
});
};

View File

@ -1,4 +1,4 @@
import { mainApi } from '../../../buster';
import { mainApi } from '../../instances';
import {
DatasetPermissionsOverviewResponse,
ListDatasetGroupsResponse,

View File

@ -49,8 +49,7 @@ export const useGetDatasetData = (datasetId: string) => {
queryKey: ['datasetData', datasetId],
queryFn,
enabled: !!datasetId,
refetchOnMount: false,
staleTime: 1000 * 60 * 10 // 10 minutes
refetchOnMount: false
});
};
@ -59,7 +58,8 @@ export const useGetDatasetMetadata = (datasetId: string) => {
const res = useCreateReactQuery<BusterDataset>({
queryKey: ['datasetMetadata', datasetId],
queryFn,
enabled: !!datasetId
enabled: !!datasetId,
staleTime: 1000 * 10
});
return res;
};

View File

@ -1,5 +1,5 @@
import { BusterDataset, BusterDatasetData, BusterDatasetListItem } from './responseInterfaces';
import { mainApi } from '../../buster';
import { mainApi } from '../instances';
import * as config from './config';
export const getDatasets = async (params?: {

View File

@ -10,3 +10,4 @@ export * from './sql';
export * from './datasets';
export * from './dataset_groups';
export * from './permission_groups';
export * from './organizations';

View File

@ -0,0 +1,3 @@
export * from './requests';
export * from './queryRequests';
export * from './responseInterfaces';

View File

@ -0,0 +1,16 @@
import { useCreateReactQuery } from '@/api/createReactQuery';
import { getOrganizationUsers } from './requests';
import { useMemoizedFn } from 'ahooks';
export const useGetOrganizationUsers = (organizationId: string) => {
const queryFn = useMemoizedFn(() => {
return getOrganizationUsers({ organizationId });
});
return useCreateReactQuery({
queryKey: ['organizationUsers', organizationId],
queryFn,
enabled: !!organizationId,
initialData: []
});
};

View File

@ -0,0 +1,12 @@
import { mainApi } from '../instances';
import { OrganizationUser } from './responseInterfaces';
export const getOrganizationUsers = async ({
organizationId
}: {
organizationId: string;
}): Promise<OrganizationUser[]> => {
return mainApi
.get<OrganizationUser[]>(`/organizations/${organizationId}/users`)
.then((response) => response.data);
};

View File

@ -0,0 +1,7 @@
export interface OrganizationUser {
id: string;
email: string;
name: string;
status: 'active' | 'inactive';
role: 'dataAdmin' | 'workspaceAdmin' | 'querier' | 'restrictedQuerier' | 'viewer';
}

View File

@ -1,4 +1,4 @@
import { mainApi } from '../../buster';
import { mainApi } from '../instances';
import { CreatePermissionGroupResponse, GetPermissionGroupResponse } from './responseInterfaces';
export const listAllPermissionGroups = async (): Promise<GetPermissionGroupResponse[]> => {

View File

@ -1,4 +1,4 @@
import { mainApi } from '../../buster';
import { mainApi } from '../instances';
import { RunSQLResponse } from './responseInterfaces';
export const runSQL = (params: { data_source_id: string; sql: string }) => {

View File

@ -1,4 +1,4 @@
import type { IBusterThreadMessageChartConfig } from '../../../api/busterv2/threads/threadConfigInterfaces';
import type { IBusterThreadMessageChartConfig } from './threadConfigInterfaces';
import type { ColumnSettings } from '../../../components/charts/interfaces/columnInterfaces';
import { ChartType, ViewType } from '../../../components/charts/interfaces/enum';
import { DEFAULT_CHART_THEME } from '../../../components/charts/configColors';

View File

@ -0,0 +1,2 @@
export const USER_QUERY_KEY = 'users';
export const USER_QUERY_KEY_ID = (userId: string) => [USER_QUERY_KEY, userId];

View File

@ -1,2 +1,3 @@
export * from './interfaces';
export * from './requests';
export * from './queryRequests';

View File

@ -0,0 +1,48 @@
import { useCreateReactMutation, useCreateReactQuery } from '@/api/createReactQuery';
import { getUser, getUser_server, updateOrganizationUser } from './requests';
import { useMemoizedFn } from 'ahooks';
import { QueryClient, useQueryClient } from '@tanstack/react-query';
import * as config from './config';
import { OrganizationUser } from '../organizations';
export const useGetUser = (params: Parameters<typeof getUser>[0]) => {
const queryFn = useMemoizedFn(() => {
return getUser(params);
});
return useCreateReactQuery({
queryKey: config.USER_QUERY_KEY_ID(params.userId),
queryFn,
staleTime: 1000 * 3
});
};
export const useUpdateUser = () => {
const queryClient = useQueryClient();
const mutationFn = useMemoizedFn(async (params: Parameters<typeof updateOrganizationUser>[0]) => {
queryClient.setQueryData(
config.USER_QUERY_KEY_ID(params.userId),
(oldData: OrganizationUser) => {
return {
...oldData,
...params
};
}
);
const res = await updateOrganizationUser(params);
return res;
});
return useCreateReactMutation({
mutationFn: mutationFn
});
};
export const prefetchGetUser = async (userId: string, queryClientProp?: QueryClient) => {
const queryClient = queryClientProp || new QueryClient();
await queryClient.prefetchQuery({
queryKey: config.USER_QUERY_KEY_ID(userId),
queryFn: () => getUser_server({ userId })
});
return queryClient;
};

View File

@ -0,0 +1,54 @@
import { BASE_URL } from '@/api/buster-rest/instances';
import { BusterUserResponse } from './interfaces';
import { mainApi } from '../instances';
import { serverFetch } from '../../createServerInstance';
import { OrganizationUser } from '../organizations';
export const getUserInfo = async ({
jwtToken
}: {
jwtToken: string | undefined;
}): Promise<BusterUserResponse | undefined> => {
if (!jwtToken) {
const res = await serverFetch<BusterUserResponse>(`/users`, {
method: 'GET'
});
return res;
}
//use fetch instead of serverFetch because...
return fetch(`${BASE_URL}/users`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwtToken}`
}
})
.then((response) => {
return response.json();
})
.catch((error) => {
return undefined;
});
};
export const getUser = async ({ userId }: { userId: string }) => {
return mainApi.get<OrganizationUser>(`/users/${userId}`).then((response) => response.data);
};
export const getUser_server = async ({ userId }: { userId: string }) => {
return serverFetch<BusterUserResponse>(`/users/${userId}`);
};
export const updateOrganizationUser = async ({
userId,
...params
}: {
userId: string;
name?: string;
role: OrganizationUser['role'];
}) => {
return mainApi
.put<OrganizationUser>(`/users/${userId}`, params)
.then((response) => response.data);
};

View File

@ -1,4 +1,4 @@
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { BusterSocketRequestBase } from '../baseInterfaces';
import { ShareRequest } from '../dashboards';

View File

@ -1,4 +1,4 @@
import { BusterCollection, BusterCollectionListItem } from '@/api/busterv2/collection';
import { BusterCollection, BusterCollectionListItem } from '@/api/buster-rest/collection';
export enum CollectionResponses {
'/collections/list:listCollections' = '/collections/list:listCollections',

View File

@ -1,4 +1,4 @@
import { BusterVerificationStatus } from '@/api/busterv2';
import { BusterVerificationStatus } from '@/api/buster-rest';
import { BusterSocketRequestBase } from '../baseInterfaces';
import { ShareRole } from '../threads';
import { DashboardConfig } from './dashboardConfigInterfaces';

View File

@ -3,7 +3,7 @@ import {
BusterDashboardListItem,
BusterDashboardResponse,
BusterMetricDataResponse
} from '@/api/busterv2';
} from '@/api/buster-rest';
export enum DashboardResponses {
'/dashboards/get:getDashboardState' = '/dashboards/get:getDashboardState',

View File

@ -1,4 +1,4 @@
import { BusterDataset, BusterDatasetListItem } from '@/api/busterv2/datasets';
import { BusterDataset, BusterDatasetListItem } from '@/api/buster-rest/datasets';
export enum DatasetResponses {
'/datasets/list:listDatasetsAdmin' = '/datasets/list:listDatasetsAdmin',

View File

@ -1,4 +1,4 @@
import { DataSourceTypes } from '@/api/busterv2';
import { DataSourceTypes } from '@/api/buster-rest';
import { BusterSocketRequestBase } from '../baseInterfaces';
import { DatasourceCreateCredentials } from './interface';

View File

@ -1,4 +1,4 @@
import { DataSource, DataSourceListItem } from '@/api/busterv2';
import { DataSource, DataSourceListItem } from '@/api/buster-rest';
export enum DatasourceResponses {
'/data_sources/list:listDataSources' = '/data_sources/list:listDataSources',

View File

@ -1,4 +1,4 @@
import { BusterOrganization } from '@/api/busterv2';
import { BusterOrganization } from '@/api/buster-rest';
export enum OrganizationResponses {
'/organizations/post:post' = '/organizations/post:post'

View File

@ -1,6 +1,6 @@
import { BusterOrganizationRole } from '@/api/busterv2';
import { BusterOrganizationRole } from '@/api/buster-rest';
import { BusterSocketRequestBase } from '../baseInterfaces';
import { BusterPermissionUser } from '@/api/busterv2/permissions';
import { BusterPermissionUser } from '@/api/buster-rest/permissions';
export type PermissionsListUsersRequest = BusterSocketRequestBase<
'/permissions/users/list',

View File

@ -5,7 +5,7 @@ import {
BusterPermissionListUser,
BusterPermissionTeam,
BusterPermissionUser
} from '@/api/busterv2/permissions';
} from '@/api/buster-rest/permissions';
export enum PermissionsResponses {
'/permissions/users/list:listUserPermissions' = '/permissions/users/list:listUserPermissions',

View File

@ -1,4 +1,4 @@
import { BusterSearchResult } from '@/api/busterv2/search';
import { BusterSearchResult } from '@/api/buster-rest/search';
export enum SearchResponses {
'/search:search' = '/search:search'

View File

@ -1,4 +1,4 @@
import { RunSQLResponse } from '@/api/busterv2/sql';
import { RunSQLResponse } from '@/api/buster-rest/sql';
export enum SQLResponses {
'/sql/run:runSql' = '/sql/run:runSql'

View File

@ -1,4 +1,4 @@
import { BusterTerm, BusterTermListItem } from '@/api/busterv2';
import { BusterTerm, BusterTermListItem } from '@/api/buster-rest';
export enum TermsResponses {
'/terms/list:ListTerms' = '/terms/list:ListTerms',

View File

@ -1,7 +1,7 @@
import { BusterThreadMessageConfig } from '@/api/busterv2/threads/threadConfigInterfaces';
import { BusterThreadMessageConfig } from '@/api/buster-rest/threads/threadConfigInterfaces';
import { BusterSocketRequestBase } from '../baseInterfaces';
import { ShareRequest } from '../dashboards';
import { BusterVerificationStatus } from '@/api/busterv2';
import { BusterVerificationStatus } from '@/api/buster-rest';
export type ThreadListEmitPayload = BusterSocketRequestBase<
'/threads/list',

View File

@ -11,7 +11,7 @@ import {
BusterThreadStepEvent_Thought,
BusterThreadStepEvent_SqlEvaluation,
BusterThreadUser
} from '@/api/busterv2';
} from '@/api/buster-rest';
export enum ThreadResponses {
'/threads/list:getThreadsList' = '/threads/list:getThreadsList',

View File

@ -1,4 +1,4 @@
import { BusterUserTeam } from '@/api/busterv2';
import { BusterUserTeam } from '@/api/buster-rest';
export enum TeamResponses {
'/teams/list:listTeams' = '/teams/list:listTeams'

View File

@ -1,4 +1,4 @@
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { BusterSocketRequestBase } from '../baseInterfaces';
export type UserColorsList = BusterSocketRequestBase<'/users/colors/list', {}>;

View File

@ -4,7 +4,7 @@ import {
BusterUserPalette,
BusterUserResponse,
BusterUserTeamListItem
} from '@/api/busterv2';
} from '@/api/buster-rest';
export enum UserResponses {
'/users/colors/list:listUserColorPalettes' = '/users/colors/list:listUserColorPalettes',

View File

@ -1 +0,0 @@
export * from './instances';

View File

@ -1,22 +0,0 @@
import { BASE_URL } from '@/api/buster/instances';
import { BusterUserResponse } from './interfaces';
export const getUserInfo = async ({
jwtToken
}: {
jwtToken: string | undefined;
}): Promise<BusterUserResponse | undefined> => {
return fetch(`${BASE_URL}/users`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${jwtToken}`
}
})
.then((response) => {
return response.json();
})
.catch((error) => {
return undefined;
});
};

View File

@ -1,6 +1,6 @@
import { BusterRoutes } from '@/routes/busterRoutes/busterRoutes';
import axios, { AxiosError } from 'axios';
import { rustErrorHandler } from './buster/errors';
import { rustErrorHandler } from './buster-rest/errors';
import { AxiosRequestHeaders } from 'axios';
import { isServer } from '@tanstack/react-query';
import { ReadonlyRequestCookies } from 'next/dist/server/web/spec-extension/adapters/request-cookies';

View File

@ -11,7 +11,7 @@ import {
} from '@tanstack/react-query';
import { useEffect } from 'react';
import { useBusterNotifications } from '@/context/BusterNotifications';
import { RustApiError } from './buster/errors';
import { RustApiError } from './buster-rest/errors';
import { useMemoizedFn } from 'ahooks';
export interface BaseCreateQueryProps {
@ -36,6 +36,7 @@ export const useCreateReactQuery = <T>({
refetchOnWindowFocus = false,
refetchOnMount = true,
useErrorNotification = true,
staleTime = 0,
...rest
}: CreateQueryProps<T> & BaseCreateQueryProps) => {
const { openErrorNotification } = useBusterNotifications();
@ -50,6 +51,7 @@ export const useCreateReactQuery = <T>({
retry: 1,
refetchOnWindowFocus,
refetchOnMount,
staleTime,
...rest
});

View File

@ -1,6 +1,6 @@
'use server';
import { BASE_URL } from './buster/instances';
import { BASE_URL } from './buster-rest/instances';
import type { RequestInit } from 'next/dist/server/web/spec-extension/request';
import { createClient } from '../context/Supabase/server';

View File

@ -1 +1 @@
export * from './buster';
export * from './buster-rest';

View File

@ -1,10 +1,10 @@
import { BusterShareAssetType } from "@/api/busterv2";
import { AppMaterialIcons } from "@/components";
import { BusterShareAssetType } from '@/api/buster-rest';
import { AppMaterialIcons } from '@/components';
const iconRecord: Record<BusterShareAssetType, string> = {
[BusterShareAssetType.COLLECTION]: "note_stack",
[BusterShareAssetType.DASHBOARD]: "grid_view",
[BusterShareAssetType.THREAD]: "monitoring",
[BusterShareAssetType.COLLECTION]: 'note_stack',
[BusterShareAssetType.DASHBOARD]: 'grid_view',
[BusterShareAssetType.THREAD]: 'monitoring'
};
export const asset_typeToIcon = (
@ -13,14 +13,14 @@ export const asset_typeToIcon = (
) => {
const { open, size } = props || {};
const iconString = iconRecord[type];
return <AppMaterialIcons icon={iconString as "grid_view"} size={size} />;
return <AppMaterialIcons icon={iconString as 'grid_view'} size={size} />;
};
export const asset_typeToTranslation = (type: BusterShareAssetType) => {
const asset_typeTranslation: Record<BusterShareAssetType, string> = {
[BusterShareAssetType.COLLECTION]: "collection",
[BusterShareAssetType.DASHBOARD]: "dashboard",
[BusterShareAssetType.THREAD]: "thread",
[BusterShareAssetType.COLLECTION]: 'collection',
[BusterShareAssetType.DASHBOARD]: 'dashboard',
[BusterShareAssetType.THREAD]: 'thread'
};
return asset_typeTranslation[type];
};

View File

@ -4,10 +4,14 @@ import { AppMaterialIcons, AppSegmented, Text } from '@/components';
import { BusterList, BusterListColumn, BusterListRow } from '@/components/list';
import { useMemoizedFn, useThrottleFn } from 'ahooks';
import { boldHighlights, formatDate } from '@/utils';
import { BusterDashboardResponse, BusterSearchResult, BusterShareAssetType } from '@/api/busterv2';
import {
BusterDashboardResponse,
BusterSearchResult,
BusterShareAssetType
} from '@/api/buster-rest';
import { asset_typeToIcon } from '@/app/_helpers';
import { CircleSpinnerLoaderContainer } from '@/components/loaders';
import { BusterCollection } from '@/api/busterv2/collection';
import { BusterCollection } from '@/api/buster-rest/collection';
import { useBusterSearchContextSelector } from '@/context/Search';
import isEmpty from 'lodash/isEmpty';
import { useDashboardContextSelector } from '@/context/Dashboards';

View File

@ -1,4 +1,4 @@
import { BusterCollectionListItem } from '@/api/busterv2/collection';
import { BusterCollectionListItem } from '@/api/buster-rest/collection';
import { NewCollectionModal } from '@/app/app/collections/_NewCollectionModal';
import { AppMaterialIcons, AppTooltip } from '@/components';
import { AppDropdownSelect } from '@/components/dropdown';

View File

@ -1,4 +1,4 @@
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { AppMaterialIcons, AppTooltip } from '@/components';
import { useUserConfigContextSelector } from '@/context/Users';
import React, { useCallback, useMemo } from 'react';

View File

@ -1,6 +1,6 @@
'use client';
import { BusterThreadListItem, BusterVerificationStatus } from '@/api/busterv2';
import { BusterThreadListItem, BusterVerificationStatus } from '@/api/buster-rest';
import { AppMaterialIcons, AppPopoverMenu, AppTooltip } from '@/components';
import { useDashboardContextSelector } from '@/context/Dashboards';
import { useUserConfigContextSelector } from '@/context/Users';

View File

@ -6,7 +6,7 @@ import { useAntToken } from '@/styles/useAntToken';
import { useBusterNewThreadsContextSelector } from '@/context/Threads';
import { inputHasText } from '@/utils';
import { useBusterSearchContextSelector } from '@/context/Search';
import { BusterSearchResult } from '@/api/busterv2';
import { BusterSearchResult } from '@/api/buster-rest';
import { useBusterNotifications } from '@/context/BusterNotifications';
import { NewThreadModalDataSourceSelect } from './NewThreadModalDatasourceSelect';
import { SuggestedPromptsContainer } from './SuggestedPromptsContainer';
@ -14,7 +14,7 @@ import { NoDatasets } from './NoDatasets';
import { useParams } from 'next/navigation';
import { useAppLayoutContextSelector } from '@/context/BusterAppLayout';
import { BusterRoutes } from '@/routes';
import { useGetDatasets } from '@/api/busterv2/datasets';
import { useGetDatasets } from '@/api/buster-rest/datasets';
const themeConfig: ThemeConfig = {
components: {

View File

@ -1,4 +1,4 @@
import { BusterDatasetListItem } from '@/api/busterv2/datasets';
import { BusterDatasetListItem } from '@/api/buster-rest/datasets';
import { AppMaterialIcons } from '@/components';
import { SelectProps, Select } from 'antd';
import isEmpty from 'lodash/isEmpty';

View File

@ -1,4 +1,4 @@
import { BusterSearchResult } from '@/api/busterv2';
import { BusterSearchResult } from '@/api/buster-rest';
import { CircleSpinnerLoader } from '@/components';
import { boldHighlights } from '@/utils/element';
import { createStyles } from 'antd-style';

View File

@ -15,12 +15,12 @@ import { ShareMenuContentPublish } from './ShareMenuContentPublish';
import { ShareMenuContentEmbed } from './ShareMenuContentEmbed';
import { IBusterThread } from '@/context/Threads/interfaces';
import { BusterRoutes, createBusterRoute } from '@/routes';
import { BusterDashboardResponse, BusterShare, BusterShareAssetType } from '@/api/busterv2';
import { BusterDashboardResponse, BusterShare, BusterShareAssetType } from '@/api/buster-rest';
import { useBusterThreadsContextSelector } from '@/context/Threads';
import { AccessDropdown } from './AccessDropdown';
import { ShareRole } from '@/api/buster-socket/threads';
import { ShareRequest } from '@/api/buster-socket/dashboards';
import { BusterCollection } from '@/api/busterv2/collection';
import { BusterCollection } from '@/api/buster-rest/collection';
import { useCollectionsContextSelector } from '@/context/Collections';
import { Text } from '@/components';
import { useDashboardContextSelector } from '@/context/Dashboards';

View File

@ -1,4 +1,4 @@
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { AppMaterialIcons } from '@/components';
import { useCollectionsContextSelector } from '@/context/Collections';
import { useDashboardContextSelector } from '@/context/Dashboards';

View File

@ -10,7 +10,7 @@ import { useDashboardContextSelector } from '@/context/Dashboards';
import { useBusterThreadsContextSelector } from '@/context/Threads';
import { BusterRoutes, createBusterRoute } from '@/routes';
import { useCollectionsContextSelector } from '@/context/Collections';
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { Text } from '@/components';
import { useBusterNotifications } from '@/context/BusterNotifications';
import { Dayjs } from 'dayjs';

View File

@ -1,7 +1,7 @@
import { AppSegmented, AppSegmentedProps } from '@/components';
import React, { useMemo } from 'react';
import { CopyLinkButton } from './CopyLinkButton';
import { BusterShareAssetType } from '@/api/busterv2';
import { BusterShareAssetType } from '@/api/buster-rest';
import { ShareRole } from '@/api/buster-socket/threads';
import { useMemoizedFn } from 'ahooks';
import { SegmentedValue } from 'antd/es/segmented';

Some files were not shown because too many files have changed in this diff Show More