-
Notifications
You must be signed in to change notification settings - Fork 0
General Panel tweaks #39
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -67,7 +67,6 @@ def load_from(self, filename): | |||||||||
| self.config['images']['path'] = { 'pictures': self.config['images']['path'] } | ||||||||||
| except Exception: | ||||||||||
| # Non-fatal; leave config as-is on error | ||||||||||
| logger.warning(f"Failed to normalize images.path: {e}") | ||||||||||
| pass | ||||||||||
|
loriab marked this conversation as resolved.
|
||||||||||
|
|
||||||||||
| self._init_paths_and_files(filename) | ||||||||||
|
|
@@ -172,35 +171,39 @@ def _init_paths_and_files(self, filename): | |||||||||
| ) | ||||||||||
|
|
||||||||||
| if isinstance(self['images']['path'], dict): | ||||||||||
| image_paths = list(self['images']['path'].values())[0] | ||||||||||
| image_paths = list(self['images']['path'].values()) | ||||||||||
| else: | ||||||||||
| image_paths = self['images']['path'] | ||||||||||
|
|
||||||||||
| # We will need to extract the image id by using regex. Compile it here | ||||||||||
| # to get a better perfomance: | ||||||||||
| before, id_str, after = image_paths.partition("{id}") | ||||||||||
| if not id_str: | ||||||||||
| raise Exception('[CONFIG] images:path must contain exactly one placeholder "{id}"!') | ||||||||||
| escaped_path = re.escape(before) | ||||||||||
| escaped_path += "(?P<id>.+)" | ||||||||||
| escaped_path += re.escape(after) | ||||||||||
| regex_images = re.compile(escaped_path) | ||||||||||
|
|
||||||||||
| images = glob(image_paths.format(id="*")) | ||||||||||
| if not images: | ||||||||||
| raise Exception( | ||||||||||
| f"[CONFIG] No images found in '{image_paths.format(id='*')}'.\n" | ||||||||||
| "Did you set images:path to a valid, existing path?") | ||||||||||
| image_paths = [self['images']['path']] | ||||||||||
|
|
||||||||||
| for ip_idx, image_path in enumerate(image_paths): | ||||||||||
| # We will need to extract the image id by using regex. Compile it here | ||||||||||
| # to get a better performance: | ||||||||||
| before, id_str, after = image_path.partition("{id}") | ||||||||||
| if not id_str: | ||||||||||
| raise Exception(f'[CONFIG] images:path {ip_idx+1} must contain exactly one placeholder "{{id}}"!') | ||||||||||
| escaped_path = re.escape(before) | ||||||||||
| escaped_path += "(?P<id>.+)" | ||||||||||
| escaped_path += re.escape(after) | ||||||||||
| regex_images = re.compile(escaped_path) | ||||||||||
|
|
||||||||||
| images = glob(image_path.format(id="*")) | ||||||||||
| if not images: | ||||||||||
| raise Exception( | ||||||||||
| f"[CONFIG] No images found in '{image_path.format(id='*')}'.\n" | ||||||||||
| "Did you set images:path to a valid, existing path?") | ||||||||||
|
|
||||||||||
| try: | ||||||||||
| self.image_ids = list(sorted([ | ||||||||||
| regex_images.match(image_path).groups()[0] | ||||||||||
| for image_path in images | ||||||||||
| ])) | ||||||||||
| except Exception as error: | ||||||||||
| raise Exception( | ||||||||||
| f'[ERROR] Could not extract id\nfrom path"{image_paths}"\nwith regex "{regex_images}"!' | ||||||||||
| ) | ||||||||||
| try: | ||||||||||
| image_ids = list(sorted([ | ||||||||||
| regex_images.match(image_path).groups()[0] | ||||||||||
| for image_path in images | ||||||||||
|
Comment on lines
+197
to
+198
|
||||||||||
| regex_images.match(image_path).groups()[0] | |
| for image_path in images | |
| regex_images.match(img_file).groups()[0] | |
| for img_file in images |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -264,10 +264,20 @@ const ProjectConfigTab: React.FC<ProjectConfigTabProps> = ({ onStateChange }) => | |
| const validationResult = await validateProjectConfig(config); | ||
|
|
||
| if (!validationResult.valid) { | ||
| setError(`Validation failed: ${validationResult.errors.join(', ')}`); | ||
| const msg = `Validation failed: ${validationResult.errors.join('\n')}`; | ||
| setError(msg); | ||
|
Comment on lines
+267
to
+268
|
||
| return; | ||
| } | ||
|
|
||
| // Only log the full configuration if the project was started in debug mode | ||
| if (loadedConfig && (loadedConfig as any).debug) { | ||
| try { | ||
| console.log('Save Complete Configuration - full config:', JSON.stringify(config, null, 2)); | ||
| } catch (e) { | ||
| console.log('Save Complete Configuration - full config (object):', config); | ||
| } | ||
| } | ||
|
|
||
| // Save to backend | ||
| const response = await updateProjectConfig(config); | ||
|
|
||
|
|
@@ -281,7 +291,8 @@ const ProjectConfigTab: React.FC<ProjectConfigTabProps> = ({ onStateChange }) => | |
|
|
||
| } catch (err: any) { | ||
| console.error('[ProjectConfigTab] Failed to save configuration:', err); | ||
| setError(err.message || 'Failed to save configuration'); | ||
| const msg = err?.message || 'Failed to save configuration'; | ||
| setError(msg); | ||
| } finally { | ||
| setSaving(false); | ||
| } | ||
|
|
@@ -336,6 +347,19 @@ const ProjectConfigTab: React.FC<ProjectConfigTabProps> = ({ onStateChange }) => | |
| <SegmentationSection ref={segmentationRef} /> | ||
|
|
||
| <div style={{ padding: '20px', borderTop: '2px solid #ddd', marginTop: '20px', background: '#f8f9fa' }}> | ||
| {/* Duplicate error banner near the Save button for better visibility */} | ||
| {error && ( | ||
| <div style={{ | ||
| padding: '10px 14px', | ||
| margin: '0 0 12px 0', | ||
| background: '#f8d7da', | ||
| color: '#721c24', | ||
| border: '1px solid #f5c6cb', | ||
| borderRadius: '4px', | ||
| }}> | ||
| <strong>Error:</strong> {error} | ||
| </div> | ||
| )} | ||
| <button | ||
| onClick={handleSaveAll} | ||
| disabled={saving} | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.