mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Automation tolltip + new operations + copy to saved (#4292)
# Description of Changes <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## Checklist ### General - [ ] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [ ] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md) (if applicable) - [ ] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md) (if applicable) - [ ] I have performed a self-review of my own code - [ ] My changes generate no new warnings ### Documentation - [ ] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed) - [ ] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [ ] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [ ] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: ConnorYoh <[email protected]>
This commit is contained in:
co-authored by
ConnorYoh
parent
4b70ef1298
commit
95b3e22229
@@ -4,10 +4,14 @@ import { Button, Group, Text, ActionIcon, Menu, Box } from '@mantine/core';
|
||||
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import { Tooltip } from '../../shared/Tooltip';
|
||||
|
||||
interface AutomationEntryProps {
|
||||
/** Optional title for the automation (usually for custom ones) */
|
||||
title?: string;
|
||||
/** Optional description for tooltip */
|
||||
description?: string;
|
||||
/** MUI Icon component for the badge */
|
||||
badgeIcon?: React.ComponentType<any>;
|
||||
/** Array of tool operation names in the workflow */
|
||||
@@ -22,17 +26,21 @@ interface AutomationEntryProps {
|
||||
onEdit?: () => void;
|
||||
/** Delete handler */
|
||||
onDelete?: () => void;
|
||||
/** Copy handler (for suggested automations) */
|
||||
onCopy?: () => void;
|
||||
}
|
||||
|
||||
export default function AutomationEntry({
|
||||
title,
|
||||
description,
|
||||
badgeIcon: BadgeIcon,
|
||||
operations,
|
||||
onClick,
|
||||
keepIconColor = false,
|
||||
showMenu = false,
|
||||
onEdit,
|
||||
onDelete
|
||||
onDelete,
|
||||
onCopy
|
||||
}: AutomationEntryProps) {
|
||||
const { t } = useTranslation();
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
@@ -41,6 +49,47 @@ export default function AutomationEntry({
|
||||
// Keep item in hovered state if menu is open
|
||||
const shouldShowHovered = isHovered || isMenuOpen;
|
||||
|
||||
// Create tooltip content with description and tool chain
|
||||
const createTooltipContent = () => {
|
||||
if (!description) return null;
|
||||
|
||||
const toolChain = operations.map((op, index) => (
|
||||
<React.Fragment key={`${op}-${index}`}>
|
||||
<Text
|
||||
component="span"
|
||||
size="sm"
|
||||
fw={600}
|
||||
style={{
|
||||
color: 'var(--mantine-primary-color-filled)',
|
||||
background: 'var(--mantine-primary-color-light)',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '0.75rem',
|
||||
whiteSpace: 'nowrap'
|
||||
}}
|
||||
>
|
||||
{t(`${op}.title`, op)}
|
||||
</Text>
|
||||
{index < operations.length - 1 && (
|
||||
<Text component="span" size="sm" mx={4}>
|
||||
→
|
||||
</Text>
|
||||
)}
|
||||
</React.Fragment>
|
||||
));
|
||||
|
||||
return (
|
||||
<div style={{ minWidth: '400px', width: 'auto' }}>
|
||||
<Text size="sm" mb={8} style={{ whiteSpace: 'normal', wordWrap: 'break-word' }}>
|
||||
{description}
|
||||
</Text>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', whiteSpace: 'nowrap' }}>
|
||||
{toolChain}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const renderContent = () => {
|
||||
if (title) {
|
||||
// Custom automation with title
|
||||
@@ -89,7 +138,7 @@ export default function AutomationEntry({
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
const boxContent = (
|
||||
<Box
|
||||
style={{
|
||||
backgroundColor: shouldShowHovered ? 'var(--mantine-color-gray-1)' : 'transparent',
|
||||
@@ -132,6 +181,17 @@ export default function AutomationEntry({
|
||||
</Menu.Target>
|
||||
|
||||
<Menu.Dropdown>
|
||||
{onCopy && (
|
||||
<Menu.Item
|
||||
leftSection={<ContentCopyIcon style={{ fontSize: 16 }} />}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onCopy();
|
||||
}}
|
||||
>
|
||||
{t('automate.copyToSaved', 'Copy to Saved')}
|
||||
</Menu.Item>
|
||||
)}
|
||||
{onEdit && (
|
||||
<Menu.Item
|
||||
leftSection={<EditIcon style={{ fontSize: 16 }} />}
|
||||
@@ -160,4 +220,18 @@ export default function AutomationEntry({
|
||||
</Group>
|
||||
</Box>
|
||||
);
|
||||
|
||||
// Only show tooltip if description exists, otherwise return plain content
|
||||
return description ? (
|
||||
<Tooltip
|
||||
content={createTooltipContent()}
|
||||
position="right"
|
||||
arrow={true}
|
||||
delay={500}
|
||||
>
|
||||
{boxContent}
|
||||
</Tooltip>
|
||||
) : (
|
||||
boxContent
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import AddCircleOutline from "@mui/icons-material/AddCircleOutline";
|
||||
import SettingsIcon from "@mui/icons-material/Settings";
|
||||
import AutomationEntry from "./AutomationEntry";
|
||||
import { useSuggestedAutomations } from "../../../hooks/tools/automate/useSuggestedAutomations";
|
||||
import { AutomationConfig } from "../../../types/automation";
|
||||
import { AutomationConfig, SuggestedAutomation } from "../../../types/automation";
|
||||
|
||||
interface AutomationSelectionProps {
|
||||
savedAutomations: AutomationConfig[];
|
||||
@@ -13,6 +13,7 @@ interface AutomationSelectionProps {
|
||||
onRun: (automation: AutomationConfig) => void;
|
||||
onEdit: (automation: AutomationConfig) => void;
|
||||
onDelete: (automation: AutomationConfig) => void;
|
||||
onCopyFromSuggested: (automation: SuggestedAutomation) => void;
|
||||
}
|
||||
|
||||
export default function AutomationSelection({
|
||||
@@ -20,7 +21,8 @@ export default function AutomationSelection({
|
||||
onCreateNew,
|
||||
onRun,
|
||||
onEdit,
|
||||
onDelete
|
||||
onDelete,
|
||||
onCopyFromSuggested
|
||||
}: AutomationSelectionProps) {
|
||||
const { t } = useTranslation();
|
||||
const suggestedAutomations = useSuggestedAutomations();
|
||||
@@ -63,9 +65,13 @@ export default function AutomationSelection({
|
||||
{suggestedAutomations.map((automation) => (
|
||||
<AutomationEntry
|
||||
key={automation.id}
|
||||
title={automation.name}
|
||||
description={automation.description}
|
||||
badgeIcon={automation.icon}
|
||||
operations={automation.operations.map(op => op.operation)}
|
||||
onClick={() => onRun(automation)}
|
||||
showMenu={true}
|
||||
onCopy={() => onCopyFromSuggested(automation)}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user