mirror of
https://github.com/logto-io/logto.git
synced 2024-12-16 20:26:19 -05:00
feat(console,schemas): add new db config to record organization creation status (#4785)
This commit is contained in:
parent
161f012bc0
commit
cee5717423
7 changed files with 86 additions and 1 deletions
|
@ -13,6 +13,7 @@ import OverlayScrollbar from '@/ds-components/OverlayScrollbar';
|
|||
import TextInput from '@/ds-components/TextInput';
|
||||
import TextLink from '@/ds-components/TextLink';
|
||||
import useApi from '@/hooks/use-api';
|
||||
import useConfigs from '@/hooks/use-configs';
|
||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||
import useTheme from '@/hooks/use-theme';
|
||||
import { trySubmitSafe } from '@/utils/form';
|
||||
|
@ -30,6 +31,7 @@ function CreateOrganization() {
|
|||
const Icon = theme === Theme.Light ? OrganizationFeature : OrganizationFeatureDark;
|
||||
const { navigate } = useTenantPathname();
|
||||
const api = useApi();
|
||||
const { updateConfigs } = useConfigs();
|
||||
|
||||
const {
|
||||
register,
|
||||
|
@ -43,6 +45,7 @@ function CreateOrganization() {
|
|||
const onSubmit = handleSubmit(
|
||||
trySubmitSafe(async (json) => {
|
||||
await api.post(`api/organizations`, { json });
|
||||
void updateConfigs({ organizationCreated: true });
|
||||
navigate(`/organizations`);
|
||||
})
|
||||
);
|
||||
|
|
|
@ -6,6 +6,7 @@ import PageMeta from '@/components/PageMeta';
|
|||
import Button from '@/ds-components/Button';
|
||||
import CardTitle from '@/ds-components/CardTitle';
|
||||
import TabNav, { TabNavItem } from '@/ds-components/TabNav';
|
||||
import useConfigs from '@/hooks/use-configs';
|
||||
import useTenantPathname from '@/hooks/use-tenant-pathname';
|
||||
import * as pageLayout from '@/scss/page-layout.module.scss';
|
||||
|
||||
|
@ -16,6 +17,7 @@ import * as styles from './index.module.scss';
|
|||
|
||||
const organizationsPathname = '/organizations';
|
||||
const createPathname = `${organizationsPathname}/create`;
|
||||
const organizationGuidePathname = '/organization-guide';
|
||||
|
||||
const tabs = Object.freeze({
|
||||
settings: 'settings',
|
||||
|
@ -29,6 +31,7 @@ function Organizations({ tab }: Props) {
|
|||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const { navigate, match } = useTenantPathname();
|
||||
const isCreating = match(createPathname);
|
||||
const { configs } = useConfigs();
|
||||
|
||||
return (
|
||||
<div className={pageLayout.container}>
|
||||
|
@ -47,7 +50,7 @@ function Organizations({ tab }: Props) {
|
|||
size="large"
|
||||
title="organizations.create_organization"
|
||||
onClick={() => {
|
||||
navigate('/organization-guide');
|
||||
navigate(configs?.organizationCreated ? createPathname : organizationGuidePathname);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -98,6 +98,7 @@ export const mockAdminUserRole3: Role = {
|
|||
|
||||
export const mockAdminConsoleData: AdminConsoleData = {
|
||||
signInExperienceCustomized: false,
|
||||
organizationCreated: false,
|
||||
};
|
||||
|
||||
export const mockPrivateKeys: OidcConfigKey[] = [
|
||||
|
|
|
@ -15,6 +15,7 @@ import { expectRejects } from '#src/helpers/index.js';
|
|||
|
||||
const defaultAdminConsoleConfig: AdminConsoleData = {
|
||||
signInExperienceCustomized: false,
|
||||
organizationCreated: false,
|
||||
};
|
||||
|
||||
describe('admin console sign-in experience', () => {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
import type { DatabaseTransactionConnection } from 'slonik';
|
||||
import { sql } from 'slonik';
|
||||
|
||||
import type { AlterationScript } from '../lib/types/alteration.js';
|
||||
|
||||
const adminConsoleConfigKey = 'adminConsole';
|
||||
|
||||
type OldAdminConsoleData = {
|
||||
signInExperienceCustomized: boolean;
|
||||
} & Record<string, unknown>;
|
||||
|
||||
type OldLogtoAdminConsoleConfig = {
|
||||
tenantId: string;
|
||||
value: OldAdminConsoleData;
|
||||
};
|
||||
|
||||
type NewAdminConsoleData = {
|
||||
signInExperienceCustomized: boolean;
|
||||
organizationCreated: boolean;
|
||||
} & Record<string, unknown>;
|
||||
|
||||
type NewLogtoAdminConsoleConfig = {
|
||||
tenantId: string;
|
||||
value: NewAdminConsoleData;
|
||||
};
|
||||
|
||||
const alterAdminConsoleData = async (
|
||||
logtoConfig: OldLogtoAdminConsoleConfig,
|
||||
pool: DatabaseTransactionConnection
|
||||
) => {
|
||||
const { tenantId, value: oldAdminConsoleConfig } = logtoConfig;
|
||||
|
||||
const newAdminConsoleData: NewAdminConsoleData = {
|
||||
...oldAdminConsoleConfig,
|
||||
organizationCreated: false,
|
||||
};
|
||||
|
||||
await pool.query(
|
||||
sql`update logto_configs set value = ${JSON.stringify(
|
||||
newAdminConsoleData
|
||||
)} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`
|
||||
);
|
||||
};
|
||||
|
||||
const rollbackAdminConsoleData = async (
|
||||
logtoConfig: NewLogtoAdminConsoleConfig,
|
||||
pool: DatabaseTransactionConnection
|
||||
) => {
|
||||
const { tenantId, value: newAdminConsoleConfig } = logtoConfig;
|
||||
|
||||
const { organizationCreated, ...oldAdminConsoleData } = newAdminConsoleConfig;
|
||||
|
||||
await pool.query(
|
||||
sql`update logto_configs set value = ${JSON.stringify(
|
||||
oldAdminConsoleData
|
||||
)} where tenant_id = ${tenantId} and key = ${adminConsoleConfigKey}`
|
||||
);
|
||||
};
|
||||
|
||||
const alteration: AlterationScript = {
|
||||
up: async (pool) => {
|
||||
const rows = await pool.many<OldLogtoAdminConsoleConfig>(
|
||||
sql`select * from logto_configs where key = ${adminConsoleConfigKey}`
|
||||
);
|
||||
await Promise.all(rows.map(async (row) => alterAdminConsoleData(row, pool)));
|
||||
},
|
||||
down: async (pool) => {
|
||||
const rows = await pool.many<NewLogtoAdminConsoleConfig>(
|
||||
sql`select * from logto_configs where key = ${adminConsoleConfigKey}`
|
||||
);
|
||||
await Promise.all(rows.map(async (row) => rollbackAdminConsoleData(row, pool)));
|
||||
},
|
||||
};
|
||||
|
||||
export default alteration;
|
|
@ -16,6 +16,7 @@ export const createDefaultAdminConsoleConfig = (
|
|||
key: LogtoTenantConfigKey.AdminConsole,
|
||||
value: {
|
||||
signInExperienceCustomized: false,
|
||||
organizationCreated: false,
|
||||
},
|
||||
} satisfies CreateLogtoConfig);
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ export const logtoOidcConfigGuard: Readonly<{
|
|||
/* --- Logto tenant configs --- */
|
||||
export const adminConsoleDataGuard = z.object({
|
||||
signInExperienceCustomized: z.boolean(),
|
||||
organizationCreated: z.boolean(),
|
||||
});
|
||||
|
||||
export type AdminConsoleData = z.infer<typeof adminConsoleDataGuard>;
|
||||
|
|
Loading…
Reference in a new issue