0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-31 22:51:25 -05:00

feat(console): display unsaved alert on custom phrases changed (#1994)

This commit is contained in:
Xiao Yijun 2022-09-26 13:46:57 +08:00
parent 48832e5054
commit 0679a6a67c
No known key found for this signature in database
GPG key ID: 6F648FC1262DB420
8 changed files with 70 additions and 5 deletions

View file

@ -20,11 +20,12 @@ import { CustomPhraseResponse } from './types';
type LanguageEditorProps = {
selectedLanguageKey: LanguageKey;
onFormStateChange: (isDirty: boolean) => void;
};
const emptyUiTranslation = createEmptyUiTranslation();
const LanguageEditor = ({ selectedLanguageKey }: LanguageEditorProps) => {
const LanguageEditor = ({ selectedLanguageKey, onFormStateChange }: LanguageEditorProps) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const isBuiltInLanguage = Object.keys(resource).includes(selectedLanguageKey);
@ -53,9 +54,13 @@ const LanguageEditor = ({ selectedLanguageKey }: LanguageEditorProps) => {
const {
handleSubmit,
reset,
formState: { isSubmitting },
formState: { isSubmitting, isDirty },
} = formMethods;
useEffect(() => {
onFormStateChange(isDirty);
}, [isDirty, onFormStateChange]);
const onSubmit = handleSubmit(async (formData: UiTranslation) => {
const updatedCustomPhrase = await api
.put(`/api/custom-phrases/${selectedLanguageKey}`, {

View file

@ -1,9 +1,11 @@
import { getDefaultLanguage, LanguageKey } from '@logto/core-kit';
import { languageOptions as uiLanguageOptions } from '@logto/phrases-ui';
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Modal from 'react-modal';
import useSWR from 'swr';
import ConfirmModal from '@/components/ConfirmModal';
import ModalLayout from '@/components/ModalLayout';
import { RequestError } from '@/hooks/use-api';
import * as modalStyles from '@/scss/modal.module.scss';
@ -19,6 +21,7 @@ type ManageLanguageModalProps = {
};
const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => {
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
const { data: customPhraseResponses } = useSWR<CustomPhraseResponse[], RequestError>(
'/api/custom-phrases'
);
@ -38,6 +41,11 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => {
const [selectedLanguageKey, setSelectedLanguageKey] = useState<LanguageKey>(defaultLanguageKey);
const [isLanguageEditorDirty, setIsLanguageEditorDirty] = useState(false);
const [isUnsavedAlertOpen, setIsUnsavedAlertOpen] = useState(false);
const [preselectedLanguageKey, setPreselectedLanguageKey] = useState<LanguageKey>();
useEffect(() => {
if (!isOpen) {
setSelectedLanguageKey(defaultLanguageKey);
@ -50,17 +58,57 @@ const ManageLanguageModal = ({ isOpen, onClose }: ManageLanguageModalProps) => {
title="sign_in_exp.others.manage_language.title"
subtitle="sign_in_exp.others.manage_language.subtitle"
size="xlarge"
onClose={onClose}
onClose={() => {
if (isLanguageEditorDirty) {
setPreselectedLanguageKey(undefined);
setIsUnsavedAlertOpen(true);
return;
}
onClose();
}}
>
<div className={style.container}>
<LanguageNav
languageKeys={allLanguageKeys}
selectedLanguage={selectedLanguageKey}
onSelect={setSelectedLanguageKey}
onSelect={(languageKey) => {
if (isLanguageEditorDirty) {
setPreselectedLanguageKey(languageKey);
setIsUnsavedAlertOpen(true);
return;
}
setSelectedLanguageKey(languageKey);
}}
/>
<LanguageEditor
selectedLanguageKey={selectedLanguageKey}
onFormStateChange={setIsLanguageEditorDirty}
/>
<LanguageEditor selectedLanguageKey={selectedLanguageKey} />
</div>
</ModalLayout>
<ConfirmModal
isOpen={isUnsavedAlertOpen}
cancelButtonText="general.stay_on_page"
onCancel={() => {
setIsUnsavedAlertOpen(false);
}}
onConfirm={() => {
setIsUnsavedAlertOpen(false);
if (preselectedLanguageKey) {
setSelectedLanguageKey(preselectedLanguageKey);
setPreselectedLanguageKey(undefined);
return;
}
onClose();
}}
>
{t('sign_in_exp.others.manage_language.unsaved_description')}
</ConfirmModal>
</Modal>
);
};

View file

@ -91,6 +91,7 @@ const sign_in_exp = {
logto_source_language: 'Logto source language',
custom_values: 'Custom values',
clear_all: 'Clear all',
unsaved_description: 'Changes wont be saved if you leave this page without saving.',
},
authentication: {
title: 'AUTHENTICATION',

View file

@ -93,6 +93,7 @@ const sign_in_exp = {
logto_source_language: 'Logto source language', // UNTRANSLATED
custom_values: 'Custom values', // UNTRANSLATED
clear_all: 'Clear all', // UNTRANSLATED
unsaved_description: 'Changes wont be saved if you leave this page without saving.', // UNTRANSLATED
},
authentication: {
title: 'AUTHENTICATION',

View file

@ -88,6 +88,7 @@ const sign_in_exp = {
logto_source_language: 'Logto source language', // UNTRANSLATED
custom_values: 'Custom values', // UNTRANSLATED
clear_all: 'Clear all', // UNTRANSLATED
unsaved_description: 'Changes wont be saved if you leave this page without saving.', // UNTRANSLATED
},
authentication: {
title: 'AUTHENTICATION',

View file

@ -91,6 +91,7 @@ const sign_in_exp = {
logto_source_language: 'Logto source language', // UNTRANSLATED
custom_values: 'Custom values', // UNTRANSLATED
clear_all: 'Clear all', // UNTRANSLATED
unsaved_description: 'Changes wont be saved if you leave this page without saving.', // UNTRANSLATED
},
authentication: {
title: 'AUTENTICAÇÃO',

View file

@ -92,6 +92,13 @@ const sign_in_exp = {
logto_source_language: 'Logto source language', // UNTRANSLATED
custom_values: 'Custom values', // UNTRANSLATED
clear_all: 'Clear all', // UNTRANSLATED
unsaved_description: 'Changes wont be saved if you leave this page without saving.', // UNTRANSLATED
deletion_title: 'Do you want to delete the added language?', // UNTRANSLATED
deletion_description:
'After deletion, your users wont be able to browse in that language again.', // UNTRANSLATED
default_language_deletion_title: 'Default language cant be deleted.', // UNTRANSLATED
default_language_deletion_description:
'{{language}} is set as your default language and cant be deleted. ', // UNTRANSLATED
},
authentication: {
title: 'AUTHENTICATION',

View file

@ -88,6 +88,7 @@ const sign_in_exp = {
logto_source_language: 'Logto source language', // UNTRANSLATED
custom_values: 'Custom values', // UNTRANSLATED
clear_all: 'Clear all', // UNTRANSLATED
unsaved_description: 'Changes wont be saved if you leave this page without saving.', // UNTRANSLATED
},
authentication: {
title: '身份验证',