Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Enhance import process #2728

Merged
merged 67 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
d8759fc
feat: adjust open file dialog filter to only show .opossum files
PhilippMa Jan 20, 2025
e25ef82
chore: add .gitconfig to .gitignore
PhilippMa Jan 20, 2025
12ddb12
feat: add function for showing open file dialog for non-.opossum files
PhilippMa Jan 21, 2025
8006e5e
feat: add menu&submenu items for file import
PhilippMa Jan 21, 2025
4cadbbd
chore: remove unused ipc channel
PhilippMa Jan 21, 2025
db9e306
feat: add ipc channel for triggering import dialog from menu
PhilippMa Jan 21, 2025
f992b75
feat: add dialog for import file action
PhilippMa Jan 23, 2025
34df851
fix: change error handling for listener callbacks
PhilippMa Jan 23, 2025
9d6df81
feat: receive file format for import dialog from backend
PhilippMa Jan 23, 2025
a0e1e13
feat: improve input validation in import dialog
PhilippMa Jan 23, 2025
a479011
feat: start convert&load from import dialog
PhilippMa Jan 23, 2025
09dda7b
refactor: extract file input into reusable component FilePathInput
PhilippMa Jan 23, 2025
506bec7
feat: add line for opossum file save location to import dialog
PhilippMa Jan 24, 2025
e560c82
feat: connect opossum file location selection to save file dialog
PhilippMa Jan 24, 2025
508a79a
fix: bug with detection of file extensions
PhilippMa Jan 24, 2025
dc2cade
feat: improve file path validation
PhilippMa Jan 24, 2025
da1befc
feat: add explanatory text to import dialog
PhilippMa Jan 24, 2025
d73198d
refactor: delete old import logic
PhilippMa Jan 24, 2025
ea5afa9
feat: check in import dialog if file paths exist on filesystem
PhilippMa Jan 24, 2025
99d12bd
feat: display warning text if existing opossum file would be overwrit…
PhilippMa Jan 27, 2025
e37800b
feat: validate import file paths in backend before starting convert&load
PhilippMa Jan 27, 2025
4bdbd26
refactor: change structure of file format constant object
PhilippMa Jan 27, 2025
6b8298b
refactor: introduce named type for file format info
PhilippMa Jan 27, 2025
4e2401e
refactor: improve typing for file format constants object
PhilippMa Jan 27, 2025
0b086d6
test: add test checking that ImportDialog opens correctly
PhilippMa Jan 27, 2025
36e265c
test: delete e2e test for file support popup
PhilippMa Jan 27, 2025
2ab4f45
refactor: change structure of file format constant
PhilippMa Jan 27, 2025
78e3b41
refactor: reuse custom text field and icon button in import dialog
PhilippMa Jan 27, 2025
da9317b
refactor: move all file path validation logic to backend
PhilippMa Jan 28, 2025
d580615
feat: improve import file path validation UX
PhilippMa Jan 28, 2025
5760377
feat: display loading state directly in import dialog without Process…
PhilippMa Jan 28, 2025
c5412b6
feat: set import button to loading state while import process is running
PhilippMa Jan 28, 2025
cb199d9
fix: fix two bugs regarding file path validation in import dialog
PhilippMa Jan 28, 2025
14a95a6
feat: check complete file path validity in confirm button onClick
PhilippMa Jan 28, 2025
a6c361d
fix: don't let overwrite warning block import
PhilippMa Jan 28, 2025
8d37578
feat: improve loading state display
PhilippMa Jan 28, 2025
4893d5b
fix: add mock necessary to test opening of import dialog
PhilippMa Jan 29, 2025
06ce958
test: add unit tests for new listeners
PhilippMa Jan 29, 2025
b6a95a1
test: add e2e test for import dialog
PhilippMa Jan 29, 2025
ed43569
fix: fix issue in test setup for import dialog
PhilippMa Jan 29, 2025
2732f1c
refactor: implement multiple small review suggestions
PhilippMa Jan 29, 2025
c6870dd
test: remove implementation details from test for getImportFileSelect…
PhilippMa Jan 30, 2025
25f2ff4
refactor: elevate FileFormatInfo type from tuple to interface
PhilippMa Jan 30, 2025
e3c9394
refactor: move user-facing texts from import dialog to text.ts
PhilippMa Jan 30, 2025
209bd8b
refactor: give better name to setup function in listeners testsuite
PhilippMa Jan 30, 2025
093149d
refactor: break circular dependency between menu.ts and listeners.ts
PhilippMa Jan 30, 2025
d8c1b3b
fix: fix tests broken by last refactoring
PhilippMa Jan 30, 2025
4dbeeb4
feat: improve typing for function parameters in errorHandling
PhilippMa Jan 30, 2025
513d354
refactor: manage import dialog independent from deprecated GlobalPopu…
PhilippMa Jan 30, 2025
10076cb
feat: only validate on import and move error display from helper text…
PhilippMa Jan 31, 2025
0a44398
refactor: rename prop in LogDisplay
PhilippMa Jan 31, 2025
778d1e4
refactor: remove unused props from FilePathInput
PhilippMa Jan 31, 2025
f84b792
feat: make textbox itself clickable instead of using a separate button
PhilippMa Jan 31, 2025
9a9099b
fix: bug in LogDisplay
PhilippMa Jan 31, 2025
a309462
test: adapt e2e tests to import dialog changes
PhilippMa Jan 31, 2025
68aa24c
feat: give more precise type to TextBox cursor prop
PhilippMa Feb 3, 2025
44a9ce4
fix: make TextBox in FilePathInput readOnly again
PhilippMa Feb 3, 2025
a780dab
feat: apply clickableIcon class to icon in FilePathInput
PhilippMa Feb 3, 2025
5d1b4b5
feat: bug where import dialog width changed on button click
PhilippMa Feb 3, 2025
bc27a34
fix: typing of css cursor property
PhilippMa Feb 3, 2025
7752fbe
feat: show tooltip with full path when hovering over file path input
PhilippMa Feb 4, 2025
fcf5bea
refactor: fix some nits
PhilippMa Feb 4, 2025
3700f72
feat: improve FilePathInput styling
PhilippMa Feb 4, 2025
98061c2
fix: fix failing e2e test for import dialog
PhilippMa Feb 4, 2025
0e05ed1
feat: clean up styles for TextBoxes in FilePathInput
PhilippMa Feb 4, 2025
20035d4
fix: fix some padding issues in TextBox
PhilippMa Feb 4, 2025
e5b841a
test: fix playwright locators to reflect recent import dialog changes
PhilippMa Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ yarn-error.log*
/.run

.env

.gitconfig
Binary file added public/assets/icons/import-black.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/icons/import-white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { AllowedFrontendChannels } from '../../../shared/ipc-channels';
import { SendErrorInformationArgs } from '../../../shared/shared-types';
import { loadInputAndOutputFromFilePath } from '../../input/importFromFile';
import {
createListenerCallbackWithErrorHandling,
createVoidListenerCallbackWithErrorHandling,
getMessageBoxContentForErrorsWrapper,
getMessageBoxForErrors,
} from '../errorHandling';
Expand Down Expand Up @@ -46,7 +46,7 @@ describe('error handling', () => {
arg2: true,
};

await createListenerCallbackWithErrorHandling(
await createVoidListenerCallbackWithErrorHandling(
mainWindow,
testFunction,
)(testArgs);
Expand All @@ -65,7 +65,10 @@ describe('error handling', () => {
throw new Error('TEST_ERROR');
}

await createListenerCallbackWithErrorHandling(mainWindow, testFunction)();
await createVoidListenerCallbackWithErrorHandling(
mainWindow,
testFunction,
)();

expect(dialog.showMessageBox).toHaveBeenCalledWith(
expect.objectContaining({
Expand Down
75 changes: 53 additions & 22 deletions src/ElectronBackend/errorHandling/errorHandling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,63 @@ import { getGlobalBackendState } from '../main/globalBackendState';
import logger from '../main/logger';
import { getLoadedFilePath } from '../utils/getLoadedFile';

export function createListenerCallbackWithErrorHandling(
async function reportListenerError(
mainWindow: BrowserWindow,
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
func: Function,
): (...args: Array<unknown>) => Promise<void> {
return async (...args: Array<unknown>): Promise<void> => {
error: unknown,
): Promise<void> {
if (error instanceof Error) {
logger.info(`Failed executing callback function: ${error.message}`);
await getMessageBoxForErrors(
error.message,
error.stack ?? '',
mainWindow,
true,
);
} else {
logger.info('Failed executing callback function.');
await getMessageBoxForErrors(
'Unexpected internal error',
'',
mainWindow,
true,
);
}
}

type FuncType<T> = T extends (...args: infer P) => infer R
? (...args: P) => R
: never;

type RemovePromise<A> = A extends Promise<infer B> ? B : A;
type ReturnTypeWithoutPromise<A> =
A extends FuncType<A> ? RemovePromise<ReturnType<A>> : never;
type FTParameters<A> = A extends FuncType<A> ? Parameters<A> : never;

export function createVoidListenerCallbackWithErrorHandling<F>(
mainWindow: BrowserWindow,
func: F & FuncType<F>,
): (...args: FTParameters<F>) => Promise<void> {
return async (...args: FTParameters<F>): Promise<void> => {
try {
await func(...args);
} catch (error: unknown) {
if (error instanceof Error) {
logger.info(`Failed executing callback function: ${error.message}`);
await getMessageBoxForErrors(
error.message,
error.stack ?? '',
mainWindow,
true,
);
} else {
logger.info('Failed executing callback function.');
await getMessageBoxForErrors(
'Unexpected internal error',
'',
mainWindow,
true,
);
}
await reportListenerError(mainWindow, error);
}
};
}

export function createListenerCallbackWithErrorHandling<F>(
mainWindow: BrowserWindow,
func: F & FuncType<F>,
): (...args: FTParameters<F>) => Promise<ReturnTypeWithoutPromise<F> | null> {
return async (
...args: FTParameters<F>
): Promise<ReturnTypeWithoutPromise<F> | null> => {
try {
return (await func(...args)) as ReturnTypeWithoutPromise<F>;
} catch (error: unknown) {
await reportListenerError(mainWindow, error);
return Promise.resolve(null);
}
};
}
Expand Down
Loading
Loading