mirror of
https://github.com/stan-smith/FossFLOW.git
synced 2025-12-23 22:48:57 -05:00
* feat: add dismissible drag-drop hint with persistent user preference in iconImport section * feat: reorder import section below kubernetes for improved layout (#125)
This commit is contained in:
@@ -27,6 +27,11 @@ export const IconSelectionControls = () => {
|
||||
const { iconCategories } = useIconCategories();
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [treatAsIsometric, setTreatAsIsometric] = useState(true);
|
||||
const [showAlert, setShowAlert] = useState(() => {
|
||||
// Check localStorage to see if user has dismissed the alert
|
||||
return localStorage.getItem('fossflow-show-drag-hint') !== 'false';
|
||||
});
|
||||
|
||||
|
||||
const onMouseDown = useCallback(
|
||||
(icon: Icon) => {
|
||||
@@ -45,6 +50,11 @@ export const IconSelectionControls = () => {
|
||||
fileInputRef.current?.click();
|
||||
}, []);
|
||||
|
||||
const dismissAlert = useCallback(() => {
|
||||
setShowAlert(false);
|
||||
localStorage.setItem('fossflow-show-drag-hint', 'false');
|
||||
}, []);
|
||||
|
||||
const handleFileSelect = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const files = event.target.files;
|
||||
if (!files || files.length === 0) return;
|
||||
@@ -196,50 +206,6 @@ export const IconSelectionControls = () => {
|
||||
<Box sx={{ marginTop: '8px' }}>
|
||||
<Searchbox value={filter} onChange={setFilter} />
|
||||
</Box>
|
||||
<Box sx={{
|
||||
border: '1px solid #e0e0e0',
|
||||
borderRadius: 1,
|
||||
p: 1.5,
|
||||
backgroundColor: '#f5f5f5'
|
||||
}}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<FileUploadIcon />}
|
||||
onClick={handleImportClick}
|
||||
fullWidth
|
||||
>
|
||||
Import Icons
|
||||
</Button>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={treatAsIsometric}
|
||||
onChange={(e) => setTreatAsIsometric(e.target.checked)}
|
||||
size="small"
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography variant="body2">
|
||||
Treat as isometric (3D view)
|
||||
</Typography>
|
||||
}
|
||||
sx={{ mt: 1, ml: 0 }}
|
||||
/>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
|
||||
Uncheck for flat icons (logos, UI elements)
|
||||
</Typography>
|
||||
</Box>
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
multiple
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileSelect}
|
||||
/>
|
||||
<Alert severity="info">
|
||||
You can drag and drop any item below onto the canvas.
|
||||
</Alert>
|
||||
</Stack>
|
||||
</Section>
|
||||
}
|
||||
@@ -252,6 +218,61 @@ export const IconSelectionControls = () => {
|
||||
{!filteredIcons && (
|
||||
<Icons iconCategories={iconCategories} onMouseDown={onMouseDown} />
|
||||
)}
|
||||
|
||||
<Section>
|
||||
<Box sx={{
|
||||
border: '1px solid #e0e0e0',
|
||||
borderRadius: 1,
|
||||
p: 1.5,
|
||||
backgroundColor: '#f5f5f5'
|
||||
}}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
startIcon={<FileUploadIcon />}
|
||||
onClick={handleImportClick}
|
||||
fullWidth
|
||||
>
|
||||
Import Icons
|
||||
</Button>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Checkbox
|
||||
checked={treatAsIsometric}
|
||||
onChange={(e) => setTreatAsIsometric(e.target.checked)}
|
||||
size="small"
|
||||
/>
|
||||
}
|
||||
label={
|
||||
<Typography variant="body2">
|
||||
Treat as isometric (3D view)
|
||||
</Typography>
|
||||
}
|
||||
sx={{ mt: 1, ml: 0 }}
|
||||
/>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 0.5 }}>
|
||||
Uncheck for flat icons (logos, UI elements)
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
<input
|
||||
ref={fileInputRef}
|
||||
type="file"
|
||||
accept="image/*"
|
||||
multiple
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileSelect}
|
||||
/>
|
||||
|
||||
{showAlert && (
|
||||
<Alert
|
||||
severity="info"
|
||||
onClose={dismissAlert}
|
||||
sx={{ cursor: 'pointer', mt: 1 }}
|
||||
>
|
||||
You can drag and drop any item below onto the canvas.
|
||||
</Alert>
|
||||
)}
|
||||
</Section>
|
||||
</ControlsContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
DeleteOutline as DeleteOutlineIcon,
|
||||
Undo as UndoIcon,
|
||||
Redo as RedoIcon,
|
||||
Settings as SettingsIcon
|
||||
Settings as SettingsIcon,
|
||||
|
||||
} from '@mui/icons-material';
|
||||
import { UiElement } from 'src/components/UiElement/UiElement';
|
||||
import { IconButton } from 'src/components/IconButton/IconButton';
|
||||
@@ -133,6 +134,9 @@ export const MainMenu = () => {
|
||||
uiStateActions.setDialog(DialogTypeEnum.SETTINGS);
|
||||
}, [uiStateActions]);
|
||||
|
||||
|
||||
|
||||
|
||||
const sectionVisibility = useMemo(() => {
|
||||
return {
|
||||
actions: Boolean(
|
||||
@@ -197,6 +201,7 @@ export const MainMenu = () => {
|
||||
{t('redo')}
|
||||
</MenuItem>
|
||||
|
||||
|
||||
{(canUndo || canRedo) && sectionVisibility.actions && <Divider />}
|
||||
|
||||
{/* File Actions */}
|
||||
|
||||
@@ -35,6 +35,7 @@ const initialState = () => {
|
||||
hotkeyProfile: DEFAULT_HOTKEY_PROFILE,
|
||||
panSettings: DEFAULT_PAN_SETTINGS,
|
||||
connectorInteractionMode: 'click', // Default to click mode
|
||||
|
||||
actions: {
|
||||
setView: (view) => {
|
||||
set({ view });
|
||||
@@ -94,10 +95,10 @@ const initialState = () => {
|
||||
setEnableDebugTools: (enableDebugTools) => {
|
||||
set({ enableDebugTools });
|
||||
},
|
||||
setRendererEl: (el) => {
|
||||
setRendererEl: (el: HTMLDivElement) => {
|
||||
set({ rendererEl: el });
|
||||
},
|
||||
setHotkeyProfile: (hotkeyProfile) => {
|
||||
setHotkeyProfile: (hotkeyProfile: any) => {
|
||||
set({ hotkeyProfile });
|
||||
},
|
||||
setPanSettings: (panSettings) => {
|
||||
|
||||
@@ -154,6 +154,7 @@ export interface UiState {
|
||||
hotkeyProfile: HotkeyProfile;
|
||||
panSettings: PanSettings;
|
||||
connectorInteractionMode: ConnectorInteractionMode;
|
||||
|
||||
}
|
||||
|
||||
export interface UiStateActions {
|
||||
@@ -177,6 +178,7 @@ export interface UiStateActions {
|
||||
setHotkeyProfile: (profile: HotkeyProfile) => void;
|
||||
setPanSettings: (settings: PanSettings) => void;
|
||||
setConnectorInteractionMode: (mode: ConnectorInteractionMode) => void;
|
||||
|
||||
}
|
||||
|
||||
export type UiStateStore = UiState & {
|
||||
|
||||
Reference in New Issue
Block a user