make welcome into a general help modal

merge-requests/3361/merge^2
Siddharth Singh 2025-04-12 03:29:13 +05:30
rodzic a258707d5c
commit 564fc606c8
Nie znaleziono w bazie danych klucza dla tego podpisu
1 zmienionych plików z 99 dodań i 55 usunięć

Wyświetl plik

@ -22,46 +22,57 @@ const messages = defineMessages({
removeValue: { id: 'admin.policies.remove_value', defaultMessage: 'Remove value' }, removeValue: { id: 'admin.policies.remove_value', defaultMessage: 'Remove value' },
welcomeTitle: { id: 'admin.policies.welcome.title', defaultMessage: 'Welcome to Policy Manager' }, welcomeTitle: { id: 'admin.policies.welcome.title', defaultMessage: 'Welcome to Policy Manager' },
welcomeGetStarted: { id: 'admin.policies.welcome.get_started', defaultMessage: 'Get Started' }, welcomeGetStarted: { id: 'admin.policies.welcome.get_started', defaultMessage: 'Get Started' },
welcomeDescription: { id: 'admin.policies.welcome.description', defaultMessage: 'Policy Manager allows you to configure moderation and content policies for your instance.' }, helpTitle: { id: 'admin.policies.help.title', defaultMessage: 'Help' },
welcomeStep1: { id: 'admin.policies.welcome.step1', defaultMessage: '1. Use the search bar to find policies you want to add' }, helpButton: { id: 'admin.policies.help.button', defaultMessage: 'Help' },
welcomeStep2: { id: 'admin.policies.welcome.step2', defaultMessage: '2. Configure each policy with your desired settings' }, welcomeDescription: { id: 'admin.policies.help.description', defaultMessage: 'Policy Manager allows you to configure moderation and content policies for your instance.' },
welcomeStep3: { id: 'admin.policies.welcome.step3', defaultMessage: '3. Click Save to apply the changes' }, welcomeStep1: { id: 'admin.policies.help.step1', defaultMessage: '1. Use the search bar to find policies you want to add' },
welcomeTip: { id: 'admin.policies.welcome.tip', defaultMessage: 'Tip: You can add multiple policies to create a comprehensive moderation strategy' }, welcomeStep2: { id: 'admin.policies.help.step2', defaultMessage: '2. Configure each policy with your desired settings' },
welcomeStep3: { id: 'admin.policies.help.step3', defaultMessage: '3. Click Save to apply the changes' },
welcomeTip: { id: 'admin.policies.help.tip', defaultMessage: 'Tip: You can add multiple policies to create a comprehensive moderation strategy' },
okay: { id: 'admin.policies.help.okay', defaultMessage: 'Okay' },
}); });
const WelcomeDialog: FC<{ onClose: () => void }> = ({ onClose }) => { interface PolicyHelpModalProps {
title: string;
onClose: () => void;
confirmText: string;
}
const PolicyHelpModal: FC<PolicyHelpModalProps> = ({ title, onClose, confirmText }) => {
const intl = useIntl(); const intl = useIntl();
return ( return (
<div className='fixed inset-0 z-50 flex items-center justify-center bg-gray-800/80'> <div className='fixed inset-0 z-50 flex items-center justify-center bg-gray-800/80'>
<Modal <div className='w-auto max-w-2xl'>
title={intl.formatMessage(messages.welcomeTitle)} <Modal
confirmationAction={onClose} title={title}
confirmationText={intl.formatMessage(messages.welcomeGetStarted)} confirmationAction={onClose}
width='md' confirmationText={confirmText}
> width='md'
<div className='space-y-4'> >
<p className='text-base'> <div className='space-y-4'>
{intl.formatMessage(messages.welcomeDescription)} <p className='text-base'>
</p> {intl.formatMessage(messages.welcomeDescription)}
</p>
<div className='space-y-2 rounded-lg bg-gray-100 p-4 dark:bg-gray-800'> <div className='space-y-2 rounded-lg bg-gray-100 p-4 dark:bg-gray-800'>
<p className='font-semibold'> <p className='font-semibold'>
{intl.formatMessage(messages.welcomeStep1)} {intl.formatMessage(messages.welcomeStep1)}
</p> </p>
<p className='font-semibold'> <p className='font-semibold'>
{intl.formatMessage(messages.welcomeStep2)} {intl.formatMessage(messages.welcomeStep2)}
</p> </p>
<p className='font-semibold'> <p className='font-semibold'>
{intl.formatMessage(messages.welcomeStep3)} {intl.formatMessage(messages.welcomeStep3)}
</p> </p>
</div> </div>
<div className='rounded-lg bg-blue-50 p-4 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'> <div className='rounded-lg bg-blue-50 p-4 text-blue-700 dark:bg-blue-900/30 dark:text-blue-200'>
{intl.formatMessage(messages.welcomeTip)} {intl.formatMessage(messages.welcomeTip)}
</div>
</div> </div>
</div> </Modal>
</Modal> </div>
</div> </div>
); );
}; };
@ -77,7 +88,8 @@ const PolicySuggestion: FC<{ item: PolicyItem }> = ({ item }) => {
const PolicyManager: FC = () => { const PolicyManager: FC = () => {
const intl = useIntl(); const intl = useIntl();
const [showWelcomeDialog, setShowWelcomeDialog] = useState<boolean>(false); const [showHelpModal, setShowHelpModal] = useState<boolean>(false);
const [isWelcomeDialog, setIsWelcomeDialog] = useState<boolean>(false);
const { allPolicies = [], isLoading, isFetched, storedPolicies, updatePolicy, isUpdating } = useModerationPolicies(); const { allPolicies = [], isLoading, isFetched, storedPolicies, updatePolicy, isUpdating } = useModerationPolicies();
// get the current set of policies out of the API response // get the current set of policies out of the API response
const initialPolicies = storedPolicies?.spec?.policies ?? []; const initialPolicies = storedPolicies?.spec?.policies ?? [];
@ -129,30 +141,42 @@ const PolicyManager: FC = () => {
if (isFetched && !isLoading) { if (isFetched && !isLoading) {
try { try {
// Check if the user has seen the welcome dialog before // Check if the user has seen the welcome dialog before
const hasSeenWelcome = localStorage.getItem('policy_manager_welcome_shown'); const hasSeenWelcome = localStorage.getItem('soapbox:policies:welcome_shown');
if (!hasSeenWelcome) { if (!hasSeenWelcome) {
setShowWelcomeDialog(true); setShowHelpModal(true);
setIsWelcomeDialog(true);
} }
} catch (error) { } catch (error) {
// localStorage is unavailable, default to showing welcome // localStorage is unavailable, default to showing welcome
setShowWelcomeDialog(true); setShowHelpModal(true);
setIsWelcomeDialog(true);
} }
} }
}, [isFetched, isLoading]); }, [isFetched, isLoading]);
// Function to handle welcome dialog close // Function to handle help dialog close
const handleWelcomeClose = () => { const handleHelpClose = () => {
setShowWelcomeDialog(false); setShowHelpModal(false);
// Store that the user has seen the welcome dialog
try { // If this was the welcome dialog, store that the user has seen it
localStorage.setItem('policy_manager_welcome_shown', 'true'); if (isWelcomeDialog) {
} catch (error) { setIsWelcomeDialog(false);
// Ignore localStorage errors try {
console.warn('Could not store welcome dialog state in localStorage', error); localStorage.setItem('policy_manager_welcome_shown', 'true');
} catch (error) {
// Ignore localStorage errors
console.warn('Could not store welcome dialog state in localStorage', error);
}
} }
}; };
// Function to show help dialog
const showHelp = () => {
setIsWelcomeDialog(false); // Not the welcome dialog
setShowHelpModal(true);
};
// Initialize fields when storedPolicies loads // Initialize fields when storedPolicies loads
const prevInitialFields = useRef<Record<string, PolicyParam>>(); const prevInitialFields = useRef<Record<string, PolicyParam>>();
@ -250,19 +274,39 @@ const PolicyManager: FC = () => {
return ( return (
<Column className='mb-8' label={intl.formatMessage(messages.heading)}> <Column className='mb-8' label={intl.formatMessage(messages.heading)}>
{showWelcomeDialog && ( {showHelpModal && (
<WelcomeDialog onClose={handleWelcomeClose} /> <PolicyHelpModal
title={isWelcomeDialog
? intl.formatMessage(messages.welcomeTitle)
: intl.formatMessage(messages.helpTitle)
}
confirmText={isWelcomeDialog
? intl.formatMessage(messages.welcomeGetStarted)
: intl.formatMessage(messages.okay)
}
onClose={handleHelpClose}
/>
)} )}
<div className='p-4'> <div className='p-4'>
<FuzzySearchInput<PolicyItem> <div className='mb-2 flex w-full justify-between'>
data={allPolicies} <div className='grow'>
keys={['name', 'description']} <FuzzySearchInput<PolicyItem>
onSelection={handleSelection} data={allPolicies}
displayKey='name' keys={['name', 'description']}
placeholder={intl.formatMessage(messages.searchPlaceholder)} onSelection={handleSelection}
className='w-full' displayKey='name'
renderSuggestion={PolicySuggestion} placeholder={intl.formatMessage(messages.searchPlaceholder)}
/> className='w-full'
renderSuggestion={PolicySuggestion}
/>
</div>
<Button
className='ml-2'
onClick={showHelp}
theme='secondary'
text={intl.formatMessage(messages.helpButton)}
/>
</div>
</div> </div>
{renderPolicies()} {renderPolicies()}
<div className='m-2 flex w-full flex-row items-center justify-end px-6'> <div className='m-2 flex w-full flex-row items-center justify-end px-6'>