Compare commits

...

3 Commits

Author SHA1 Message Date
ramki-bruno
228d73c7a4 Improved error-toast for creating and importing collections
- Added a util for formatting the error form IPC
- Updated Toast global styles to prevent text overflow.
  Whenever long file paths are shown, it overflows the Toast container.
2025-04-22 02:43:03 +05:30
ramki-bruno
4d4b375f78 Fix: Import-collection select-location Modal closes on error 2025-04-22 02:11:59 +05:30
ramki-bruno
531b89fb60 Fix: Improve UX for selecting location when create/import collection
Allow editing the input path where previously the `<input>` is marked
`readonly`.
Also this will allow automating test using Playwright.
2025-04-22 02:11:36 +05:30
6 changed files with 33 additions and 6 deletions

View File

@@ -11,6 +11,8 @@ import PathDisplay from 'components/PathDisplay/index';
import { useState } from 'react';
import { IconArrowBackUp, IconEdit } from '@tabler/icons';
import Help from 'components/Help';
import { multiLineMsg } from "utils/common";
import { formatIpcError } from "utils/common/error";
const CreateCollection = ({ onClose }) => {
const inputRef = useRef();
@@ -45,7 +47,7 @@ const CreateCollection = ({ onClose }) => {
toast.success('Collection created!');
onClose();
})
.catch((e) => toast.error('An error occurred while creating the collection - ' + e));
.catch((e) => toast.error(multiLineMsg('An error occurred while creating the collection', formatIpcError(e))));
}
});
@@ -113,7 +115,6 @@ const CreateCollection = ({ onClose }) => {
id="collection-location"
type="text"
name="collectionLocation"
readOnly={true}
className="block textbox mt-2 w-full cursor-pointer"
autoComplete="off"
autoCorrect="off"
@@ -121,6 +122,9 @@ const CreateCollection = ({ onClose }) => {
spellCheck="false"
value={formik.values.collectionLocation || ''}
onClick={browse}
onChange={e => {
formik.setFieldValue('collectionLocation', e.target.value);
}}
/>
{formik.touched.collectionLocation && formik.errors.collectionLocation ? (
<div className="text-red-500">{formik.errors.collectionLocation}</div>

View File

@@ -61,7 +61,6 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, collectionName }) =>
id="collection-location"
type="text"
name="collectionLocation"
readOnly={true}
className="block textbox mt-2 w-full cursor-pointer"
autoComplete="off"
autoCorrect="off"
@@ -69,6 +68,9 @@ const ImportCollectionLocation = ({ onClose, handleSubmit, collectionName }) =>
spellCheck="false"
value={formik.values.collectionLocation || ''}
onClick={browse}
onChange={e => {
formik.setFieldValue('collectionLocation', e.target.value);
}}
/>
</>
{formik.touched.collectionLocation && formik.errors.collectionLocation ? (

View File

@@ -11,6 +11,8 @@ import { useDispatch } from 'react-redux';
import { showHomePage } from 'providers/ReduxStore/slices/app';
import { openCollection, importCollection } from 'providers/ReduxStore/slices/collections/actions';
import StyledWrapper from './StyledWrapper';
import { multiLineMsg } from "utils/common";
import { formatIpcError } from "utils/common/error";
const TitleBar = () => {
const [importedCollection, setImportedCollection] = useState(null);
@@ -34,9 +36,8 @@ const TitleBar = () => {
toast.success('Collection imported successfully');
})
.catch((err) => {
setImportCollectionLocationModalOpen(false);
console.error(err);
toast.error('An error occurred while importing the collection. Check the logs for more information.');
toast.error(multiLineMsg('An error occurred while importing the collection.', formatIpcError(err)));
});
};

View File

@@ -7,9 +7,17 @@ export const ToastContext = React.createContext();
export const ToastProvider = (props) => {
const { storedTheme } = useTheme();
const toastOptions = { duration: 2000 };
const toastOptions = {
duration: 2000,
style: {
// Break long word like file-path, URL etc. to prevent overflow
overflowWrap: 'anywhere'
}
};
if (storedTheme === 'dark') {
toastOptions.style = {
...toastOptions.style,
borderRadius: '10px',
background: '#3d3d3d',
color: '#fff'

View File

@@ -34,3 +34,11 @@ export const toastError = (error, defaultErrorMsg = 'An error occurred') => {
return toast.error(errorMsg);
};
export function formatIpcError(error) {
if (!(error instanceof Error)) return error;
if (!error?.message) return ''; // Avoid returning `null` or `undefined`
// https://github.com/electron/electron/blob/659e79fc08c6ffc2f7506dd1358918d97d240147/lib/renderer/api/ipc-renderer.ts#L24-L30
// There is no other way to get rid of this error prefix as of now.
return error.message.replace(/^Error invoking remote method '.+?': (Error: )?/, '');
}

View File

@@ -181,4 +181,8 @@ export const getEncoding = (headers) => {
// Parse the charset from content type: https://stackoverflow.com/a/33192813
const charsetMatch = /charset=([^()<>@,;:"/[\]?.=\s]*)/i.exec(headers?.['content-type'] || '');
return charsetMatch?.[1];
}
export const multiLineMsg = (...messages) => {
return messages.filter(m => m !== undefined && m !== null && m !== '').join('\n');
}