Update database types and relationships

The commit removes semicolons at the ends of lines and makes updates to the Database object in the `database.types.ts` file. This better aligns the syntax with TypeScript norms. It also affects many database relationships, including but not limited to `Accounts`, `Roles`, and `Subscriptions`.
This commit is contained in:
giancarlo
2024-04-16 22:17:28 +08:00
parent 1cb0470ce0
commit 8dd4b594d2
10 changed files with 2200 additions and 1904 deletions

View File

@@ -20,7 +20,7 @@ import pathsConfig from '~/config/paths.config';
export const loadTeamWorkspace = cache(async (accountSlug: string) => {
const client = getSupabaseServerComponentClient();
const accountPromise = client.rpc('organization_account_workspace', {
const accountPromise = client.rpc('team_account_workspace', {
account_slug: accountSlug,
});

View File

@@ -16,7 +16,7 @@ import { loadUserWorkspace } from '../_lib/load-user-workspace';
export function HomeSidebar() {
const collapsed = getSidebarCollapsed();
const { accounts, user } = use(loadUserWorkspace());
const { accounts, user, workspace } = use(loadUserWorkspace());
return (
<Sidebar collapsed={collapsed}>
@@ -38,7 +38,11 @@ export function HomeSidebar() {
<div className={'absolute bottom-4 left-0 w-full'}>
<SidebarContent>
<ProfileAccountDropdownContainer collapsed={collapsed} user={user} />
<ProfileAccountDropdownContainer
collapsed={collapsed}
user={user}
account={workspace}
/>
</SidebarContent>
</div>
</Sidebar>

View File

@@ -9,27 +9,37 @@ import { useUser } from '@kit/supabase/hooks/use-user';
import featuresFlagConfig from '~/config/feature-flags.config';
import pathsConfig from '~/config/paths.config';
const paths = {
home: pathsConfig.app.home,
};
const features = {
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
};
export function ProfileAccountDropdownContainer(props: {
collapsed: boolean;
user: User | null;
account?: {
id: string | null;
name: string | null;
picture_url: string | null;
};
}) {
const signOut = useSignOut();
const user = useUser(props.user);
const userData = user.data ?? props.user ?? null;
return (
<div className={props.collapsed ? '' : 'w-full animate-in fade-in-90'}>
<div className={props.collapsed ? '' : 'w-full'}>
<PersonalAccountDropdown
paths={{
home: pathsConfig.app.home,
}}
features={{
enableThemeToggle: featuresFlagConfig.enableThemeToggle,
}}
className={'w-full'}
paths={paths}
features={features}
showProfileName={!props.collapsed}
user={userData}
account={props.account}
signOutRequested={() => signOut.mutateAsync()}
/>
</div>

View File

@@ -1,26 +1,62 @@
import { cache } from 'react';
import { SupabaseClient } from '@supabase/supabase-js';
import { getSupabaseServerComponentClient } from '@kit/supabase/server-component-client';
import featureFlagsConfig from '~/config/feature-flags.config';
import { Database } from '~/lib/database.types';
/**
* @name loadUserWorkspace
* @description
* Load the user workspace data. It's a cached per-request function that fetches the user workspace data.
* It can be used across the server components to load the user workspace data.
*/
export const loadUserWorkspace = cache(async () => {
const client = getSupabaseServerComponentClient();
const loadAccounts = featureFlagsConfig.enableTeamAccounts;
const accounts = loadAccounts ? await loadUserAccounts(client) : [];
const { data } = await client.auth.getUser();
const accountsPromise = loadAccounts
? loadUserAccounts(client)
: Promise.resolve([]);
const workspacePromise = loadUserAccountWorkspace(client);
const userPromise = client.auth.getUser();
const [accounts, workspace, userResult] = await Promise.all([
accountsPromise,
workspacePromise,
userPromise,
]);
const user = userResult.data.user;
if (!user) {
throw new Error('User is not logged in');
}
return {
accounts,
user: data.user,
workspace,
user,
};
});
async function loadUserAccounts(
client: ReturnType<typeof getSupabaseServerComponentClient<Database>>,
) {
async function loadUserAccountWorkspace(client: SupabaseClient<Database>) {
const { data, error } = await client
.from('user_account_workspace')
.select(`*`)
.single();
if (error) {
throw error;
}
return data;
}
async function loadUserAccounts(client: SupabaseClient<Database>) {
const { data: accounts, error } = await client
.from('user_accounts')
.select(`name, slug, picture_url`);

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -1781,19 +1781,21 @@ language plpgsql;
--
-- VIEW "user_account_workspace":
-- we create a view to load the general app data for the authenticated
-- user which includes the user's accounts, memberships, and roles, and relative subscription status
-- user which includes the user accounts and memberships
create or replace view public.user_account_workspace as
select
accounts.id as id,
accounts.name as name,
accounts.picture_url as picture_url,
accounts.public_data as public_data,
subscriptions.status as subscription_status
from
public.accounts
left join public.subscriptions on accounts.id = subscriptions.account_id
where
primary_owner_user_id = auth.uid()
and accounts.is_personal_account = true;
and accounts.is_personal_account = true
limit 1;
grant select on public.user_account_workspace to authenticated, service_role;
@@ -1822,7 +1824,7 @@ grant select on public.user_accounts to authenticated, service_role;
-- Function: get the account workspace for an organization account
-- to load all the required data for the authenticated user within the account scope
create or replace function
public.organization_account_workspace(account_slug text)
public.team_account_workspace(account_slug text)
returns table(
id uuid,
name varchar(255),
@@ -1869,7 +1871,7 @@ end;
$$
language plpgsql;
grant execute on function public.organization_account_workspace(text)
grant execute on function public.team_account_workspace(text)
to authenticated, service_role;
-- Functions: get account members

View File

@@ -36,19 +36,29 @@ export function PersonalAccountDropdown({
showProfileName,
paths,
features,
account,
}: {
className?: string;
user: User | null;
account?: {
id: string | null;
name: string | null;
picture_url: string | null;
};
signOutRequested: () => unknown;
showProfileName?: boolean;
paths: {
home: string;
};
features: {
enableThemeToggle: boolean;
};
}) {
const { data: personalAccountData } = usePersonalAccountData();
const { data: personalAccountData } = usePersonalAccountData(account);
const signedInAsLabel = useMemo(() => {
const email = user?.email ?? undefined;
@@ -57,7 +67,8 @@ export function PersonalAccountDropdown({
return email ?? phone;
}, [user?.email, user?.phone]);
const displayName = personalAccountData?.name ?? user?.email ?? '';
const displayName =
account?.name ?? personalAccountData?.name ?? user?.email ?? '';
const isSuperAdmin = useMemo(() => {
return user?.app_metadata.role === 'super-admin';

View File

@@ -5,7 +5,15 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
import { useSupabase } from '@kit/supabase/hooks/use-supabase';
import { useUser } from '@kit/supabase/hooks/use-user';
export function usePersonalAccountData() {
export function usePersonalAccountData(
partialAccount?:
| {
id: string | null;
name: string | null;
picture_url: string | null;
}
| undefined,
) {
const client = useSupabase();
const user = useUser();
const userId = user.data?.id;
@@ -43,6 +51,7 @@ export function usePersonalAccountData() {
enabled: !!userId,
refetchOnWindowFocus: false,
refetchOnMount: false,
initialData: partialAccount,
});
}

File diff suppressed because it is too large Load Diff