From 3404684a61ed0977e68e09a5d9e4da93a727e1b2 Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 17 Mar 2023 14:19:29 +0800 Subject: [PATCH] refactor(console): update get-started tasks (#3439) --- .../src/assets/images/create-role-dark.svg | 26 ++++ .../console/src/assets/images/create-role.svg | 26 ++++ .../hooks/use-user-onboarding-data.ts | 9 +- .../src/onboarding/pages/About/index.tsx | 7 +- packages/console/src/pages/GetStarted/hook.ts | 127 ++++++++++++------ .../Roles/components/CreateRoleForm/index.tsx | 3 + packages/core/src/__mocks__/index.ts | 3 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- .../translation/admin-console/get-started.ts | 9 +- ...78953179-update-get-started-task-config.ts | 102 ++++++++++++++ packages/schemas/src/seeds/logto-config.ts | 3 +- packages/schemas/src/types/logto-config.ts | 3 +- 18 files changed, 305 insertions(+), 76 deletions(-) create mode 100644 packages/console/src/assets/images/create-role-dark.svg create mode 100644 packages/console/src/assets/images/create-role.svg create mode 100644 packages/schemas/alterations/next-1678953179-update-get-started-task-config.ts diff --git a/packages/console/src/assets/images/create-role-dark.svg b/packages/console/src/assets/images/create-role-dark.svg new file mode 100644 index 000000000..e1c2c5226 --- /dev/null +++ b/packages/console/src/assets/images/create-role-dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/console/src/assets/images/create-role.svg b/packages/console/src/assets/images/create-role.svg new file mode 100644 index 000000000..76c552a6b --- /dev/null +++ b/packages/console/src/assets/images/create-role.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/console/src/onboarding/hooks/use-user-onboarding-data.ts b/packages/console/src/onboarding/hooks/use-user-onboarding-data.ts index ffab94a14..ebe18d77d 100644 --- a/packages/console/src/onboarding/hooks/use-user-onboarding-data.ts +++ b/packages/console/src/onboarding/hooks/use-user-onboarding-data.ts @@ -1,10 +1,11 @@ import { useCallback, useMemo } from 'react'; import { z } from 'zod'; +import { isCloud } from '@/consts/cloud'; import useMeCustomData from '@/hooks/use-me-custom-data'; import type { UserOnboardingData } from '../types'; -import { userOnboardingDataGuard } from '../types'; +import { Project, userOnboardingDataGuard } from '../types'; const userOnboardingDataKey = 'onboarding'; @@ -17,6 +18,10 @@ const useUserOnboardingData = () => { return parsed.success ? parsed.data[userOnboardingDataKey] : {}; }, [data]); + const isBusinessPlan = useMemo(() => { + return isCloud && userOnboardingData.questionnaire?.project === Project.Company; + }, [userOnboardingData]); + const update = useCallback( async (data: Partial) => { await updateMeCustomData({ @@ -29,7 +34,7 @@ const useUserOnboardingData = () => { [updateMeCustomData, userOnboardingData] ); - return { data: userOnboardingData, error, isLoading, isLoaded, update }; + return { data: userOnboardingData, error, isLoading, isLoaded, isBusinessPlan, update }; }; export default useUserOnboardingData; diff --git a/packages/console/src/onboarding/pages/About/index.tsx b/packages/console/src/onboarding/pages/About/index.tsx index de5be4a21..10263d628 100644 --- a/packages/console/src/onboarding/pages/About/index.tsx +++ b/packages/console/src/onboarding/pages/About/index.tsx @@ -15,7 +15,7 @@ import * as pageLayout from '@/onboarding/scss/layout.module.scss'; import ActionBar from '../../components/ActionBar'; import { CardSelector, MultiCardSelector } from '../../components/CardSelector'; import type { Questionnaire } from '../../types'; -import { Project, OnboardingPage } from '../../types'; +import { OnboardingPage } from '../../types'; import { getOnboardingPage } from '../../utils'; import * as styles from './index.module.scss'; import { titleOptions, companySizeOptions, reasonOptions } from './options'; @@ -26,11 +26,10 @@ const About = () => { const { data: { questionnaire }, + isBusinessPlan, update, } = useUserOnboardingData(); - const isCompanyProject = questionnaire?.project === Project.Company; - const { control, register, handleSubmit, reset } = useForm({ mode: 'onChange', }); @@ -60,7 +59,7 @@ const About = () => {
{t('cloud.about.title')}
{t('cloud.about.description')}
- {isCompanyProject && ( + {isBusinessPlan && ( <> { const theme = useTheme(); const isLightMode = theme === Theme.Light; const navigate = useNavigate(); + const { isBusinessPlan } = useUserOnboardingData(); + const { getDocumentationUrl } = useDocumentationUrl(); - const data = useMemo(() => { - const metadataItems: GetStartedMetadata[] = [ + const basicMetadata: GetStartedMetadata[] = useMemo( + () => [ { id: 'checkLivePreview', title: 'get_started.check_preview_title', @@ -89,30 +94,21 @@ const useGetStartedMetadata = () => { navigate('/sign-in-experience'); }, }, - isCloud - ? { - id: 'interactWithManagementAPI', - title: 'get_started.management_api_title', - subtitle: 'get_started.management_api_subtitle', - icon: isLightMode ? MachineToMachine : MachineToMachineDark, - buttonText: 'general.create', - isComplete: configs?.m2mApplicationCreated, - onClick: () => { - navigate('/applications/create'); - }, - } - : { - id: 'checkOutSelfHostingOptions', - title: 'get_started.self_hosting_title', - subtitle: 'get_started.self_hosting_subtitle', - icon: isLightMode ? Github : GithubDark, - buttonText: 'general.visit', - isComplete: configs?.selfHostingChecked, - onClick: () => { - void updateConfigs({ selfHostingChecked: true }); - window.open(githubLink, '_blank'); - }, - }, + ], + [ + configs?.applicationCreated, + configs?.livePreviewChecked, + configs?.passwordlessConfigured, + configs?.signInExperienceCustomized, + isLightMode, + navigate, + updateConfigs, + userEndpoint, + ] + ); + + const personalPlanMetadata: GetStartedMetadata[] = useMemo( + () => [ { id: 'joinCommunity', title: 'get_started.community_title', @@ -125,22 +121,67 @@ const useGetStartedMetadata = () => { window.open(discordLink, '_blank'); }, }, + { + id: 'checkOutFurtherReadings', + title: 'get_started.further_readings_title', + subtitle: 'get_started.further_readings_subtitle', + icon: isLightMode ? FurtherReadings : FurtherReadingsDark, + buttonText: 'general.check_out', + isComplete: configs?.furtherReadingsChecked, + onClick: () => { + void updateConfigs({ furtherReadingsChecked: true }); + window.open( + getDocumentationUrl('/docs/tutorials/get-started/further-readings'), + '_blank' + ); + }, + }, + ], + [ + configs?.communityChecked, + configs?.furtherReadingsChecked, + getDocumentationUrl, + isLightMode, + updateConfigs, + ] + ); + + const businessPlanMetadata: GetStartedMetadata[] = useMemo( + () => [ + { + id: 'interactWithManagementAPI', + title: 'get_started.management_api_title', + subtitle: 'get_started.management_api_subtitle', + icon: isLightMode ? MachineToMachine : MachineToMachineDark, + buttonText: 'general.create', + isComplete: configs?.m2mApplicationCreated, + onClick: () => { + navigate('/applications/create'); + }, + }, + { + id: 'addRbac', + title: 'get_started.add_rbac_title', + subtitle: 'get_started.add_rbac_subtitle', + icon: isLightMode ? CreateRole : CreateRoleDark, + buttonText: 'general.create', + isComplete: configs?.roleCreated, + onClick: () => { + navigate('/roles/create'); + }, + }, + ], + [configs?.m2mApplicationCreated, configs?.roleCreated, isLightMode, navigate] + ); + + const data = useMemo(() => { + const metadataItems: GetStartedMetadata[] = [ + ...basicMetadata, + ...(isBusinessPlan ? businessPlanMetadata : personalPlanMetadata), ]; return metadataItems.filter(({ isHidden }) => !isHidden); - }, [ - isLightMode, - configs?.livePreviewChecked, - configs?.applicationCreated, - configs?.passwordlessConfigured, - configs?.signInExperienceCustomized, - configs?.m2mApplicationCreated, - configs?.selfHostingChecked, - configs?.communityChecked, - updateConfigs, - userEndpoint, - navigate, - ]); + }, [basicMetadata, isBusinessPlan, businessPlanMetadata, personalPlanMetadata]); return { data, diff --git a/packages/console/src/pages/Roles/components/CreateRoleForm/index.tsx b/packages/console/src/pages/Roles/components/CreateRoleForm/index.tsx index 6f7400507..ee5ada71a 100644 --- a/packages/console/src/pages/Roles/components/CreateRoleForm/index.tsx +++ b/packages/console/src/pages/Roles/components/CreateRoleForm/index.tsx @@ -10,6 +10,7 @@ import ModalLayout from '@/components/ModalLayout'; import RoleScopesTransfer from '@/components/RoleScopesTransfer'; import TextInput from '@/components/TextInput'; import useApi from '@/hooks/use-api'; +import useConfigs from '@/hooks/use-configs'; export type Props = { onClose: (createdRole?: Role) => void; @@ -33,6 +34,7 @@ const CreateRoleForm = ({ onClose }: Props) => { } = useForm(); const api = useApi(); + const { updateConfigs } = useConfigs(); const onSubmit = handleSubmit(async ({ name, description, scopes }) => { if (isSubmitting) { @@ -46,6 +48,7 @@ const CreateRoleForm = ({ onClose }: Props) => { }; const createdRole = await api.post('api/roles', { json: payload }).json(); + await updateConfigs({ roleCreated: true }); onClose(createdRole); }); diff --git a/packages/core/src/__mocks__/index.ts b/packages/core/src/__mocks__/index.ts index 7488c1d94..e70784bdd 100644 --- a/packages/core/src/__mocks__/index.ts +++ b/packages/core/src/__mocks__/index.ts @@ -85,7 +85,8 @@ export const mockAdminConsoleData: AdminConsoleData = { applicationCreated: false, signInExperienceCustomized: false, passwordlessConfigured: false, - selfHostingChecked: false, + furtherReadingsChecked: false, + roleCreated: false, communityChecked: false, m2mApplicationCreated: false, }; diff --git a/packages/phrases/src/locales/de/translation/admin-console/get-started.ts b/packages/phrases/src/locales/de/translation/admin-console/get-started.ts index 946b04baa..b13c8d4b5 100644 --- a/packages/phrases/src/locales/de/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/de/translation/admin-console/get-started.ts @@ -18,14 +18,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/en/translation/admin-console/get-started.ts b/packages/phrases/src/locales/en/translation/admin-console/get-started.ts index 220cbc178..20643e275 100644 --- a/packages/phrases/src/locales/en/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/en/translation/admin-console/get-started.ts @@ -16,14 +16,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', - self_hosting_title: 'Check Github for self-hosting options', - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', community_title: 'Join our discord community', community_subtitle: 'Join our public channel to chat with other developers', management_api_title: 'Interact with Management API', management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', + further_readings_title: 'Further readings', + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', + add_rbac_title: 'Add role-based access control to protect your resources', + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', }; export default get_started; diff --git a/packages/phrases/src/locales/fr/translation/admin-console/get-started.ts b/packages/phrases/src/locales/fr/translation/admin-console/get-started.ts index 6e17d6c3c..4afd90772 100644 --- a/packages/phrases/src/locales/fr/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/fr/translation/admin-console/get-started.ts @@ -19,14 +19,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/ko/translation/admin-console/get-started.ts b/packages/phrases/src/locales/ko/translation/admin-console/get-started.ts index e61f4868e..bce121a5d 100644 --- a/packages/phrases/src/locales/ko/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/ko/translation/admin-console/get-started.ts @@ -16,14 +16,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/pt-br/translation/admin-console/get-started.ts b/packages/phrases/src/locales/pt-br/translation/admin-console/get-started.ts index da774a041..6bc69982b 100644 --- a/packages/phrases/src/locales/pt-br/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/pt-br/translation/admin-console/get-started.ts @@ -17,14 +17,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/get-started.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/get-started.ts index 07fe08a03..6338c255f 100644 --- a/packages/phrases/src/locales/pt-pt/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/get-started.ts @@ -17,14 +17,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/get-started.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/get-started.ts index 2d2c34e8d..b8a0bf5a5 100644 --- a/packages/phrases/src/locales/tr-tr/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/get-started.ts @@ -17,14 +17,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/get-started.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/get-started.ts index e2a95b075..a7cd6be5d 100644 --- a/packages/phrases/src/locales/zh-cn/translation/admin-console/get-started.ts +++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/get-started.ts @@ -16,14 +16,17 @@ const get_started = { passwordless_title: 'Scale passwordless sign in by adding your own connectors', // UNTRANSLATED passwordless_subtitle: 'Try passwordless sign in and enable a secure and frictionless experience for your customer', // UNTRANSLATED - self_hosting_title: 'Check Github for self-hosting options', // UNTRANSLATED - self_hosting_subtitle: - 'Efficiently deploy by visiting the Github homepage in a matter of minutes', // UNTRANSLATED community_title: 'Join our discord community', // UNTRANSLATED community_subtitle: 'Join our public channel to chat with other developers', // UNTRANSLATED management_api_title: 'Interact with Management API', // UNTRANSLATED management_api_subtitle: 'Build a machine to machine app for API access and your product tech infrastructure setup', // UNTRANSLATED + further_readings_title: 'Further readings', // UNTRANSLATED + further_readings_subtitle: + 'Check out our step-by-step, scenario-based docs without tedious concepts', // UNTRANSLATED + add_rbac_title: 'Add role-based access control to protect your resources', // UNTRANSLATED + add_rbac_subtitle: + 'Control your resource through scalable role authorization for diverse use cases.', // UNTRANSLATED }; export default get_started; diff --git a/packages/schemas/alterations/next-1678953179-update-get-started-task-config.ts b/packages/schemas/alterations/next-1678953179-update-get-started-task-config.ts new file mode 100644 index 000000000..eebe53a76 --- /dev/null +++ b/packages/schemas/alterations/next-1678953179-update-get-started-task-config.ts @@ -0,0 +1,102 @@ +import type { DatabaseTransactionConnection } from 'slonik'; +import { sql } from 'slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +const adminConsoleConfigKey = 'adminConsole'; + +type OldAdminConsoleData = { + livePreviewChecked: boolean; + applicationCreated: boolean; + signInExperienceCustomized: boolean; + passwordlessConfigured: boolean; + selfHostingChecked: boolean; + communityChecked: boolean; + m2mApplicationCreated: boolean; +} & Record; + +type OldLogtoAdminConsoleConfig = { + tenantId: string; + value: OldAdminConsoleData; +}; + +type NewAdminConsoleData = { + livePreviewChecked: boolean; + applicationCreated: boolean; + signInExperienceCustomized: boolean; + passwordlessConfigured: boolean; + furtherReadingsChecked: boolean; + roleCreated: boolean; + communityChecked: boolean; + m2mApplicationCreated: boolean; +} & Record; + +type NewLogtoAdminConsoleConfig = { + tenantId: string; + value: NewAdminConsoleData; +}; + +const alterAdminConsoleData = async ( + logtoConfig: OldLogtoAdminConsoleConfig, + pool: DatabaseTransactionConnection +) => { + const { tenantId, value: oldAdminConsoleConfig } = logtoConfig; + + const { + selfHostingChecked, // Extract to remove from config + ...others + } = oldAdminConsoleConfig; + + const newAdminConsoleData: NewAdminConsoleData = { + ...others, + furtherReadingsChecked: false, + roleCreated: 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 { + furtherReadingsChecked, // Extract to remove from config + roleCreated, // Extract to remove from config + ...others + } = newAdminConsoleConfig; + + const oldAdminConsoleData: OldAdminConsoleData = { + ...others, + selfHostingChecked: false, + }; + + 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( + 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( + sql`select * from logto_configs where key = ${adminConsoleConfigKey}` + ); + await Promise.all(rows.map(async (row) => rollbackAdminConsoleData(row, pool))); + }, +}; + +export default alteration; diff --git a/packages/schemas/src/seeds/logto-config.ts b/packages/schemas/src/seeds/logto-config.ts index b5500303b..bc9c08c6d 100644 --- a/packages/schemas/src/seeds/logto-config.ts +++ b/packages/schemas/src/seeds/logto-config.ts @@ -17,7 +17,8 @@ export const createDefaultAdminConsoleConfig = ( applicationCreated: false, signInExperienceCustomized: false, passwordlessConfigured: false, - selfHostingChecked: false, + furtherReadingsChecked: false, + roleCreated: false, communityChecked: false, m2mApplicationCreated: false, }, diff --git a/packages/schemas/src/types/logto-config.ts b/packages/schemas/src/types/logto-config.ts index 8830d03ef..944c162b1 100644 --- a/packages/schemas/src/types/logto-config.ts +++ b/packages/schemas/src/types/logto-config.ts @@ -26,8 +26,9 @@ export const adminConsoleDataGuard = z.object({ applicationCreated: z.boolean(), signInExperienceCustomized: z.boolean(), passwordlessConfigured: z.boolean(), - selfHostingChecked: z.boolean(), communityChecked: z.boolean(), + furtherReadingsChecked: z.boolean(), + roleCreated: z.boolean(), m2mApplicationCreated: z.boolean(), });