mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-04 02:20:19 +01:00
improvement/v2/automate/tweaks (#4293)
- [x] Cleanup Automation output name garbage - [x] Remove Cross button on first two tools - [x] Automation creation name title to make clearer to the user - [x] Colours for dark mode on automation tool settings are bad - [x] Fix tool names not using correct translated ones - [x] suggested Automation Password needs adding to description - [x] Allow different filetypes in automation - [x] Custom Icons for automation - [x] split Tool wasn't working with merge to single pdf --------- Co-authored-by: Connor Yoh <connor@stirlingpdf.com> Co-authored-by: James Brunton <jbrunton96@gmail.com>
This commit is contained in:
@@ -32,9 +32,10 @@ const FileUploadButton = ({
|
||||
onChange={onChange}
|
||||
accept={accept}
|
||||
disabled={disabled}
|
||||
|
||||
>
|
||||
{(props) => (
|
||||
<Button {...props} variant={variant} fullWidth={fullWidth}>
|
||||
<Button {...props} variant={variant} fullWidth={fullWidth} color="blue">
|
||||
{file ? file.name : (placeholder || defaultPlaceholder)}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -22,7 +22,7 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||
const { t } = useTranslation();
|
||||
const { isRainbowMode } = useRainbowThemeContext();
|
||||
const { openFilesModal, isFilesModalOpen } = useFilesModalContext();
|
||||
const { handleReaderToggle, handleBackToTools, handleToolSelect, selectedToolKey, leftPanelView, toolRegistry, readerMode } = useToolWorkflow();
|
||||
const { handleReaderToggle, handleBackToTools, handleToolSelect, selectedToolKey, leftPanelView, toolRegistry, readerMode, resetTool } = useToolWorkflow();
|
||||
const [configModalOpen, setConfigModalOpen] = useState(false);
|
||||
const [activeButton, setActiveButton] = useState<string>('tools');
|
||||
const scrollableRef = useRef<HTMLDivElement>(null);
|
||||
@@ -74,7 +74,12 @@ const QuickAccessBar = forwardRef<HTMLDivElement>(({
|
||||
type: 'navigation',
|
||||
onClick: () => {
|
||||
setActiveButton('automate');
|
||||
handleToolSelect('automate');
|
||||
// If already on automate tool, reset it directly
|
||||
if (selectedToolKey === 'automate') {
|
||||
resetTool('automate');
|
||||
} else {
|
||||
handleToolSelect('automate');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ const WatermarkTypeSettings = ({ watermarkType, onWatermarkTypeChange, disabled
|
||||
<div style={{ display: 'flex', gap: '4px' }}>
|
||||
<Button
|
||||
variant={watermarkType === 'text' ? 'filled' : 'outline'}
|
||||
color={watermarkType === 'text' ? 'blue' : 'gray'}
|
||||
color={watermarkType === 'text' ? 'blue' : 'var(--text-muted)'}
|
||||
onClick={() => onWatermarkTypeChange('text')}
|
||||
disabled={disabled}
|
||||
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
|
||||
@@ -27,7 +27,7 @@ const WatermarkTypeSettings = ({ watermarkType, onWatermarkTypeChange, disabled
|
||||
</Button>
|
||||
<Button
|
||||
variant={watermarkType === 'image' ? 'filled' : 'outline'}
|
||||
color={watermarkType === 'image' ? 'blue' : 'gray'}
|
||||
color={watermarkType === 'image' ? 'blue' : 'var(--text-muted)'}
|
||||
onClick={() => onWatermarkTypeChange('image')}
|
||||
disabled={disabled}
|
||||
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
Stack,
|
||||
Group,
|
||||
TextInput,
|
||||
Textarea,
|
||||
Divider,
|
||||
Modal
|
||||
} from '@mantine/core';
|
||||
@@ -13,6 +14,7 @@ import CheckIcon from '@mui/icons-material/Check';
|
||||
import { ToolRegistryEntry } from '../../../data/toolsTaxonomy';
|
||||
import ToolConfigurationModal from './ToolConfigurationModal';
|
||||
import ToolList from './ToolList';
|
||||
import IconSelector from './IconSelector';
|
||||
import { AutomationConfig, AutomationMode, AutomationTool } from '../../../types/automation';
|
||||
import { useAutomationForm } from '../../../hooks/tools/automate/useAutomationForm';
|
||||
|
||||
@@ -31,6 +33,10 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
|
||||
const {
|
||||
automationName,
|
||||
setAutomationName,
|
||||
automationDescription,
|
||||
setAutomationDescription,
|
||||
automationIcon,
|
||||
setAutomationIcon,
|
||||
selectedTools,
|
||||
addTool,
|
||||
removeTool,
|
||||
@@ -100,7 +106,8 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
|
||||
|
||||
const automationData = {
|
||||
name: automationName.trim(),
|
||||
description: '',
|
||||
description: automationDescription.trim(),
|
||||
icon: automationIcon,
|
||||
operations: selectedTools.map(tool => ({
|
||||
operation: tool.operation,
|
||||
parameters: tool.parameters || {}
|
||||
@@ -114,7 +121,7 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
|
||||
if (mode === AutomationMode.EDIT && existingAutomation) {
|
||||
// For edit mode, check if name has changed
|
||||
const nameChanged = automationName.trim() !== existingAutomation.name;
|
||||
|
||||
|
||||
if (nameChanged) {
|
||||
// Name changed - create new automation
|
||||
savedAutomation = await automationStorage.saveAutomation(automationData);
|
||||
@@ -144,17 +151,39 @@ export default function AutomationCreation({ mode, existingAutomation, onBack, o
|
||||
return (
|
||||
<div>
|
||||
<Text size="sm" mb="md" p="md" style={{borderRadius:'var(--mantine-radius-md)', background: 'var(--color-gray-200)', color: 'var(--mantine-color-text)' }}>
|
||||
{t("automate.creation.description", "Automations run tools sequentially. To get started, add tools in the order you want them to run.")}
|
||||
{t("automate.creation.intro", "Automations run tools sequentially. To get started, add tools in the order you want them to run.")}
|
||||
</Text>
|
||||
<Divider mb="md" />
|
||||
|
||||
<Stack gap="md">
|
||||
{/* Automation Name */}
|
||||
<TextInput
|
||||
placeholder={t('automate.creation.name.placeholder', 'Automation name')}
|
||||
value={automationName}
|
||||
onChange={(e) => setAutomationName(e.currentTarget.value)}
|
||||
{/* Automation Name and Icon */}
|
||||
<Group gap="xs" align="flex-end">
|
||||
<Stack gap="xs" style={{ flex: 1 }}>
|
||||
<TextInput
|
||||
placeholder={t('automate.creation.name.placeholder', 'My Automation')}
|
||||
value={automationName}
|
||||
withAsterisk
|
||||
label={t('automate.creation.name.label', 'Automation Name')}
|
||||
onChange={(e) => setAutomationName(e.currentTarget.value)}
|
||||
size="sm"
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<IconSelector
|
||||
value={automationIcon || 'SettingsIcon'}
|
||||
onChange={setAutomationIcon}
|
||||
size="sm"
|
||||
/>
|
||||
</Group>
|
||||
|
||||
{/* Automation Description */}
|
||||
<Textarea
|
||||
placeholder={t('automate.creation.description.placeholder', 'Describe what this automation does...')}
|
||||
value={automationDescription}
|
||||
label={t('automate.creation.description.label', 'Description')}
|
||||
onChange={(e) => setAutomationDescription(e.currentTarget.value)}
|
||||
size="sm"
|
||||
rows={3}
|
||||
/>
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ 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';
|
||||
import { ToolRegistryEntry } from '../../../data/toolsTaxonomy';
|
||||
|
||||
interface AutomationEntryProps {
|
||||
/** Optional title for the automation (usually for custom ones) */
|
||||
@@ -28,6 +29,8 @@ interface AutomationEntryProps {
|
||||
onDelete?: () => void;
|
||||
/** Copy handler (for suggested automations) */
|
||||
onCopy?: () => void;
|
||||
/** Tool registry to resolve operation names */
|
||||
toolRegistry?: Record<string, ToolRegistryEntry>;
|
||||
}
|
||||
|
||||
export default function AutomationEntry({
|
||||
@@ -40,7 +43,8 @@ export default function AutomationEntry({
|
||||
showMenu = false,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onCopy
|
||||
onCopy,
|
||||
toolRegistry
|
||||
}: AutomationEntryProps) {
|
||||
const { t } = useTranslation();
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
@@ -49,9 +53,19 @@ export default function AutomationEntry({
|
||||
// Keep item in hovered state if menu is open
|
||||
const shouldShowHovered = isHovered || isMenuOpen;
|
||||
|
||||
// Helper function to resolve tool display names
|
||||
const getToolDisplayName = (operation: string): string => {
|
||||
if (toolRegistry?.[operation]?.name) {
|
||||
return toolRegistry[operation].name;
|
||||
}
|
||||
// Fallback to translation or operation key
|
||||
return t(`${operation}.title`, operation);
|
||||
};
|
||||
|
||||
// Create tooltip content with description and tool chain
|
||||
const createTooltipContent = () => {
|
||||
if (!description) return null;
|
||||
// Show tooltip if there's a description OR if there are operations to show in the chain
|
||||
if (!description && operations.length === 0) return null;
|
||||
|
||||
const toolChain = operations.map((op, index) => (
|
||||
<React.Fragment key={`${op}-${index}`}>
|
||||
@@ -68,7 +82,7 @@ export default function AutomationEntry({
|
||||
whiteSpace: 'nowrap'
|
||||
}}
|
||||
>
|
||||
{t(`${op}.title`, op)}
|
||||
{getToolDisplayName(op)}
|
||||
</Text>
|
||||
{index < operations.length - 1 && (
|
||||
<Text component="span" size="sm" mx={4}>
|
||||
@@ -80,12 +94,16 @@ export default function AutomationEntry({
|
||||
|
||||
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>
|
||||
{description && (
|
||||
<Text size="sm" mb={8} style={{ whiteSpace: 'normal', wordWrap: 'break-word' }}>
|
||||
{description}
|
||||
</Text>
|
||||
)}
|
||||
{operations.length > 0 && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '4px', whiteSpace: 'nowrap' }}>
|
||||
{toolChain}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -122,7 +140,7 @@ export default function AutomationEntry({
|
||||
{operations.map((op, index) => (
|
||||
<React.Fragment key={`${op}-${index}`}>
|
||||
<Text size="xs" style={{ color: 'var(--mantine-color-text)' }}>
|
||||
{t(`${op}.title`, op)}
|
||||
{getToolDisplayName(op)}
|
||||
</Text>
|
||||
|
||||
{index < operations.length - 1 && (
|
||||
@@ -221,8 +239,10 @@ export default function AutomationEntry({
|
||||
</Box>
|
||||
);
|
||||
|
||||
// Only show tooltip if description exists, otherwise return plain content
|
||||
return description ? (
|
||||
// Show tooltip if there's a description OR operations to display
|
||||
const shouldShowTooltip = description || operations.length > 0;
|
||||
|
||||
return shouldShowTooltip ? (
|
||||
<Tooltip
|
||||
content={createTooltipContent()}
|
||||
position="right"
|
||||
|
||||
@@ -6,6 +6,8 @@ import SettingsIcon from "@mui/icons-material/Settings";
|
||||
import AutomationEntry from "./AutomationEntry";
|
||||
import { useSuggestedAutomations } from "../../../hooks/tools/automate/useSuggestedAutomations";
|
||||
import { AutomationConfig, SuggestedAutomation } from "../../../types/automation";
|
||||
import { iconMap } from './iconMap';
|
||||
import { ToolRegistryEntry } from '../../../data/toolsTaxonomy';
|
||||
|
||||
interface AutomationSelectionProps {
|
||||
savedAutomations: AutomationConfig[];
|
||||
@@ -14,6 +16,7 @@ interface AutomationSelectionProps {
|
||||
onEdit: (automation: AutomationConfig) => void;
|
||||
onDelete: (automation: AutomationConfig) => void;
|
||||
onCopyFromSuggested: (automation: SuggestedAutomation) => void;
|
||||
toolRegistry: Record<string, ToolRegistryEntry>;
|
||||
}
|
||||
|
||||
export default function AutomationSelection({
|
||||
@@ -22,7 +25,8 @@ export default function AutomationSelection({
|
||||
onRun,
|
||||
onEdit,
|
||||
onDelete,
|
||||
onCopyFromSuggested
|
||||
onCopyFromSuggested,
|
||||
toolRegistry
|
||||
}: AutomationSelectionProps) {
|
||||
const { t } = useTranslation();
|
||||
const suggestedAutomations = useSuggestedAutomations();
|
||||
@@ -40,20 +44,26 @@ export default function AutomationSelection({
|
||||
operations={[]}
|
||||
onClick={onCreateNew}
|
||||
keepIconColor={true}
|
||||
toolRegistry={toolRegistry}
|
||||
/>
|
||||
{/* Saved Automations */}
|
||||
{savedAutomations.map((automation) => (
|
||||
<AutomationEntry
|
||||
key={automation.id}
|
||||
title={automation.name}
|
||||
badgeIcon={SettingsIcon}
|
||||
operations={automation.operations.map(op => typeof op === 'string' ? op : op.operation)}
|
||||
onClick={() => onRun(automation)}
|
||||
showMenu={true}
|
||||
onEdit={() => onEdit(automation)}
|
||||
onDelete={() => onDelete(automation)}
|
||||
/>
|
||||
))}
|
||||
{savedAutomations.map((automation) => {
|
||||
const IconComponent = automation.icon ? iconMap[automation.icon as keyof typeof iconMap] : SettingsIcon;
|
||||
return (
|
||||
<AutomationEntry
|
||||
key={automation.id}
|
||||
title={automation.name}
|
||||
description={automation.description}
|
||||
badgeIcon={IconComponent || SettingsIcon}
|
||||
operations={automation.operations.map(op => typeof op === 'string' ? op : op.operation)}
|
||||
onClick={() => onRun(automation)}
|
||||
showMenu={true}
|
||||
onEdit={() => onEdit(automation)}
|
||||
onDelete={() => onDelete(automation)}
|
||||
toolRegistry={toolRegistry}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<Divider pb='sm' />
|
||||
|
||||
{/* Suggested Automations */}
|
||||
@@ -72,6 +82,7 @@ export default function AutomationSelection({
|
||||
onClick={() => onRun(automation)}
|
||||
showMenu={true}
|
||||
onCopy={() => onCopyFromSuggested(automation)}
|
||||
toolRegistry={toolRegistry}
|
||||
/>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
116
frontend/src/components/tools/automate/IconSelector.tsx
Normal file
116
frontend/src/components/tools/automate/IconSelector.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Box, Text, Stack, Button, SimpleGrid, Tooltip, Popover } from "@mantine/core";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import { iconMap, iconOptions } from './iconMap';
|
||||
|
||||
interface IconSelectorProps {
|
||||
value?: string;
|
||||
onChange?: (iconKey: string) => void;
|
||||
size?: "sm" | "md" | "lg";
|
||||
}
|
||||
|
||||
export default function IconSelector({ value = "SettingsIcon", onChange, size = "sm" }: IconSelectorProps) {
|
||||
const { t } = useTranslation();
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
|
||||
const selectedIconComponent = iconMap[value as keyof typeof iconMap] || iconMap.SettingsIcon;
|
||||
|
||||
const handleIconSelect = (iconKey: string) => {
|
||||
onChange?.(iconKey);
|
||||
setIsDropdownOpen(false);
|
||||
};
|
||||
|
||||
const iconSize = size === "sm" ? 16 : size === "md" ? 18 : 20;
|
||||
|
||||
return (
|
||||
<Stack gap="1px">
|
||||
<Text size="sm" fw={600} style={{ color: "var(--mantine-color-primary)" }}>
|
||||
{t("automate.creation.icon.label", "Icon")}
|
||||
</Text>
|
||||
|
||||
<Popover
|
||||
opened={isDropdownOpen}
|
||||
onClose={() => setIsDropdownOpen(false)}
|
||||
onDismiss={() => setIsDropdownOpen(false)}
|
||||
position="bottom-start"
|
||||
withArrow
|
||||
trapFocus
|
||||
>
|
||||
<Popover.Target>
|
||||
<Button
|
||||
variant="outline"
|
||||
size={size}
|
||||
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
|
||||
style={{
|
||||
width: size === "sm" ? "3.75rem" : "4.375rem",
|
||||
position: "relative",
|
||||
display: "flex",
|
||||
justifyContent: "flex-start",
|
||||
paddingLeft: "0.5rem",
|
||||
borderColor: "var(--mantine-color-gray-3)",
|
||||
color: "var(--mantine-color-text)",
|
||||
|
||||
}}
|
||||
>
|
||||
{React.createElement(selectedIconComponent, { style: { fontSize: iconSize } })}
|
||||
<KeyboardArrowDownIcon
|
||||
style={{
|
||||
fontSize: iconSize * 0.8,
|
||||
position: "absolute",
|
||||
right: "0.25rem",
|
||||
top: "50%",
|
||||
transform: "translateY(-50%)",
|
||||
}}
|
||||
/>
|
||||
</Button>
|
||||
</Popover.Target>
|
||||
|
||||
<Popover.Dropdown>
|
||||
<Stack gap="xs">
|
||||
<SimpleGrid cols={4} spacing="xs">
|
||||
{iconOptions.map((option) => {
|
||||
const IconComponent = iconMap[option.value as keyof typeof iconMap];
|
||||
const isSelected = value === option.value;
|
||||
|
||||
return (
|
||||
<Tooltip key={option.value} label={option.label}>
|
||||
<Box
|
||||
onClick={() => handleIconSelect(option.value)}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
padding: "0.5rem",
|
||||
borderRadius: "0.25rem",
|
||||
cursor: "pointer",
|
||||
backgroundColor: isSelected ? "var(--mantine-color-gray-1)" : "transparent",
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (!isSelected) {
|
||||
e.currentTarget.style.backgroundColor = "var(--mantine-color-gray-0)";
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (!isSelected) {
|
||||
e.currentTarget.style.backgroundColor = "transparent";
|
||||
}
|
||||
}}
|
||||
>
|
||||
<IconComponent
|
||||
style={{
|
||||
fontSize: iconSize,
|
||||
color: isSelected ? "var(--mantine-color-gray-9)" : "var(--mantine-color-gray-7)",
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Tooltip>
|
||||
);
|
||||
})}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -63,22 +63,24 @@ export default function ToolList({
|
||||
borderBottomWidth: tool.operation && !tool.configured ? "0" : "1px",
|
||||
}}
|
||||
>
|
||||
{/* Delete X in top right */}
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
onClick={() => onToolRemove(index)}
|
||||
title={t("automate.creation.tools.remove", "Remove tool")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "4px",
|
||||
right: "4px",
|
||||
zIndex: 1,
|
||||
color: "var(--mantine-color-gray-6)",
|
||||
}}
|
||||
>
|
||||
<CloseIcon style={{ fontSize: 16 }} />
|
||||
</ActionIcon>
|
||||
{/* Delete X in top right - only show for tools after the first 2 */}
|
||||
{index > 1 && (
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
size="xs"
|
||||
onClick={() => onToolRemove(index)}
|
||||
title={t("automate.creation.tools.remove", "Remove tool")}
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "4px",
|
||||
right: "4px",
|
||||
zIndex: 1,
|
||||
color: "var(--mantine-color-gray-6)",
|
||||
}}
|
||||
>
|
||||
<CloseIcon style={{ fontSize: 16 }} />
|
||||
</ActionIcon>
|
||||
)}
|
||||
|
||||
<div style={{ paddingRight: "1.25rem" }}>
|
||||
{/* Tool Selection Dropdown with inline settings cog */}
|
||||
|
||||
92
frontend/src/components/tools/automate/iconMap.ts
Normal file
92
frontend/src/components/tools/automate/iconMap.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import SettingsIcon from '@mui/icons-material/Settings';
|
||||
import CompressIcon from '@mui/icons-material/Compress';
|
||||
import SwapHorizIcon from '@mui/icons-material/SwapHoriz';
|
||||
import CleaningServicesIcon from '@mui/icons-material/CleaningServices';
|
||||
import CropIcon from '@mui/icons-material/Crop';
|
||||
import TextFieldsIcon from '@mui/icons-material/TextFields';
|
||||
import PictureAsPdfIcon from '@mui/icons-material/PictureAsPdf';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import FolderIcon from '@mui/icons-material/Folder';
|
||||
import CloudIcon from '@mui/icons-material/Cloud';
|
||||
import StorageIcon from '@mui/icons-material/Storage';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import DownloadIcon from '@mui/icons-material/Download';
|
||||
import UploadIcon from '@mui/icons-material/Upload';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import RotateLeftIcon from '@mui/icons-material/RotateLeft';
|
||||
import RotateRightIcon from '@mui/icons-material/RotateRight';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
import ContentCutIcon from '@mui/icons-material/ContentCut';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import WorkIcon from '@mui/icons-material/Work';
|
||||
import BuildIcon from '@mui/icons-material/Build';
|
||||
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
|
||||
import SmartToyIcon from '@mui/icons-material/SmartToy';
|
||||
import CheckIcon from '@mui/icons-material/Check';
|
||||
import SecurityIcon from '@mui/icons-material/Security';
|
||||
import StarIcon from '@mui/icons-material/Star';
|
||||
|
||||
export const iconMap = {
|
||||
SettingsIcon,
|
||||
CompressIcon,
|
||||
SwapHorizIcon,
|
||||
CleaningServicesIcon,
|
||||
CropIcon,
|
||||
TextFieldsIcon,
|
||||
PictureAsPdfIcon,
|
||||
EditIcon,
|
||||
DeleteIcon,
|
||||
FolderIcon,
|
||||
CloudIcon,
|
||||
StorageIcon,
|
||||
SearchIcon,
|
||||
DownloadIcon,
|
||||
UploadIcon,
|
||||
PlayArrowIcon,
|
||||
RotateLeftIcon,
|
||||
RotateRightIcon,
|
||||
VisibilityIcon,
|
||||
ContentCutIcon,
|
||||
ContentCopyIcon,
|
||||
WorkIcon,
|
||||
BuildIcon,
|
||||
AutoAwesomeIcon,
|
||||
SmartToyIcon,
|
||||
CheckIcon,
|
||||
SecurityIcon,
|
||||
StarIcon
|
||||
};
|
||||
|
||||
export const iconOptions = [
|
||||
{ value: 'SettingsIcon', label: 'Settings' },
|
||||
{ value: 'CompressIcon', label: 'Compress' },
|
||||
{ value: 'SwapHorizIcon', label: 'Convert' },
|
||||
{ value: 'CleaningServicesIcon', label: 'Clean' },
|
||||
{ value: 'CropIcon', label: 'Crop' },
|
||||
{ value: 'TextFieldsIcon', label: 'Text' },
|
||||
{ value: 'PictureAsPdfIcon', label: 'PDF' },
|
||||
{ value: 'EditIcon', label: 'Edit' },
|
||||
{ value: 'DeleteIcon', label: 'Delete' },
|
||||
{ value: 'FolderIcon', label: 'Folder' },
|
||||
{ value: 'CloudIcon', label: 'Cloud' },
|
||||
{ value: 'StorageIcon', label: 'Storage' },
|
||||
{ value: 'SearchIcon', label: 'Search' },
|
||||
{ value: 'DownloadIcon', label: 'Download' },
|
||||
{ value: 'UploadIcon', label: 'Upload' },
|
||||
{ value: 'PlayArrowIcon', label: 'Play' },
|
||||
{ value: 'RotateLeftIcon', label: 'Rotate Left' },
|
||||
{ value: 'RotateRightIcon', label: 'Rotate Right' },
|
||||
{ value: 'VisibilityIcon', label: 'View' },
|
||||
{ value: 'ContentCutIcon', label: 'Cut' },
|
||||
{ value: 'ContentCopyIcon', label: 'Copy' },
|
||||
{ value: 'WorkIcon', label: 'Work' },
|
||||
{ value: 'BuildIcon', label: 'Build' },
|
||||
{ value: 'AutoAwesomeIcon', label: 'Magic' },
|
||||
{ value: 'SmartToyIcon', label: 'Robot' },
|
||||
{ value: 'CheckIcon', label: 'Check' },
|
||||
{ value: 'SecurityIcon', label: 'Security' },
|
||||
{ value: 'StarIcon', label: 'Star' }
|
||||
];
|
||||
|
||||
export type IconKey = keyof typeof iconMap;
|
||||
@@ -23,7 +23,7 @@ const CompressSettings = ({ parameters, onParameterChange, disabled = false }: C
|
||||
<div style={{ display: 'flex', gap: '4px' }}>
|
||||
<Button
|
||||
variant={parameters.compressionMethod === 'quality' ? 'filled' : 'outline'}
|
||||
color={parameters.compressionMethod === 'quality' ? 'blue' : 'gray'}
|
||||
color={parameters.compressionMethod === 'quality' ? 'blue' : 'var(--text-muted)'}
|
||||
onClick={() => onParameterChange('compressionMethod', 'quality')}
|
||||
disabled={disabled}
|
||||
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
|
||||
@@ -34,7 +34,7 @@ const CompressSettings = ({ parameters, onParameterChange, disabled = false }: C
|
||||
</Button>
|
||||
<Button
|
||||
variant={parameters.compressionMethod === 'filesize' ? 'filled' : 'outline'}
|
||||
color={parameters.compressionMethod === 'filesize' ? 'blue' : 'gray'}
|
||||
color={parameters.compressionMethod === 'filesize' ? 'blue' : 'var(--text-muted)'}
|
||||
onClick={() => onParameterChange('compressionMethod', 'filesize')}
|
||||
disabled={disabled}
|
||||
style={{ flex: 1, height: 'auto', minHeight: '40px', fontSize: '11px' }}
|
||||
|
||||
Reference in New Issue
Block a user