Skip to content

Enable metadata editing and server sync for online objects#226

Merged
LeftofZen merged 17 commits intomasterfrom
copilot/enable-metadata-editing
Jan 11, 2026
Merged

Enable metadata editing and server sync for online objects#226
LeftofZen merged 17 commits intomasterfrom
copilot/enable-metadata-editing

Conversation

Copy link
Contributor

Copilot AI commented Dec 29, 2025

Metadata Editing Complete ✅

All metadata fields are now editable in the UI and can be saved to the server when in online mode.

Recent Updates (PR Review Feedback)

  • ✅ Added logging to exception handlers for better error visibility
  • ✅ Fixed fire-and-forget Task patterns to observe exceptions
  • ✅ Added comprehensive tests for Licence, Authors, Tags, and ObjectPacks updates
  • ✅ All 5 PutAsync tests passing

Editable Properties (Saved to Server)

  • Description (TextBox)
  • Licence (ComboBox with server-fetched values + "None" option)
  • CreatedDate (DatePicker)
  • ModifiedDate (DatePicker)
  • Authors (editable collection with add/remove)
  • Tags (editable collection with add/remove)
  • ObjectPacks (editable collection with add/remove)

Readonly Properties

  • UniqueObjectId (system-managed)
  • InternalName (init-only)
  • UploadedDate (server-managed)
  • Availability (user cannot change)

Server API

  • Implemented UpdateAsync PUT endpoint in ObjectRouteHandler
  • Updates all editable fields: Description, CreatedDate, ModifiedDate, Availability, Licence, Authors, Tags, ObjectPacks
  • Single-pass query with proper collection relationship management
  • Comprehensive test coverage validating all update scenarios

Client Integration

  • ObjectEditorViewModel.Save() uploads all editable metadata for online objects
  • Fire-and-forget async properly handled with exception observation
  • Collections sync changes back to Metadata model
  • Works in offline mode (empty lists if server unavailable)
  • Logging for debugging and error visibility

Collection Editing Features

  • Authors Tab: ComboBox to select from available authors, Add/Remove buttons
  • Tags Tab: ComboBox to select from available tags, Add/Remove buttons
  • ObjectPacks Tab: ComboBox to select from available object packs, Add/Remove buttons
  • All collections use ReactiveCommand for add/remove operations
  • Changes automatically sync to underlying Metadata model
Original prompt

The user needs to be able to edit the metadata for objects; currently it's readonly. When in online mode, when the user saves the object the editor should upload the new metadata/object to the server


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits December 29, 2025 13:52
- Made metadata fields editable in MetadataView.axaml (Description, CreatedDate, ModifiedDate)
- Added two-way binding support in LocoObjectMetadataViewModel with ReactiveUI
- Implemented server-side UpdateAsync endpoint in ObjectRouteHandler.cs
- Added client-side UpdateObjectAsync method in Client.cs and ObjectServiceClient.cs
- Integrated metadata upload in ObjectEditorViewModel.Save() for online mode

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
- Updated ObjectRoutesTest to test the PUT endpoint for metadata updates
- Test verifies that Description, CreatedDate, ModifiedDate, and Availability fields can be updated
- Test passes successfully

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
- Eliminated redundant database query in UpdateAsync endpoint
- Added null check for CurrentObject.DatInfo before accessing
- Improved error logging format
- Removed unnecessary Task.Run wrapper

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
Copilot AI changed the title [WIP] Allow users to edit metadata for objects Enable metadata editing and server sync for online objects Dec 29, 2025
Copilot AI requested a review from LeftofZen December 29, 2025 14:02
@LeftofZen
Copy link
Collaborator

@copilot this is a good start but only a few of the metadata properties are exposed in ObjectMetadataViewModel. All of them need to be exposed, editable and saveable to the server

- Added Availability property to ObjectMetadataViewModel with two-way binding
- Added InternalName property (readonly) to ViewModel
- Added UploadedDate property to ViewModel
- Updated MetadataView.axaml to show all properties with appropriate controls
- Changed Availability from readonly TextBox to editable ComboBox
- Added InternalName field display
- Fixed DataContext binding to use ViewModel properties instead of direct Metadata binding
- Updated type references from LocoObjectMetadataViewModel to ObjectMetadataViewModel

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 30, 2025

@copilot this is a good start but only a few of the metadata properties are exposed in ObjectMetadataViewModel. All of them need to be exposed, editable and saveable to the server

All metadata properties from ObjectMetadata are now exposed in ObjectMetadataViewModel and displayed in the UI:

Editable properties (saved to server):

  • Description (TextBox)
  • Availability (ComboBox with enum values - changed from readonly to editable)
  • CreatedDate (DatePicker)
  • ModifiedDate (DatePicker)

Readonly properties (displayed but not editable):

  • UniqueObjectId (system-managed)
  • InternalName (init-only property)
  • UploadedDate (server-managed)
  • Licence (readonly for now)

Collection properties (displayed in separate tabs):

  • Authors, Tags, ObjectPacks, DatObjects

All editable properties are uploaded to the server when saving in online mode. Fixed in commit ae4edac.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • av-build-tel-api-v1.avaloniaui.net
    • Triggering command: /usr/share/dotnet/dotnet dotnet exec --runtimeconfig /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/runtimeconfig.json /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/Avalonia.BuildServices.Collector.dll Entry .cs ep Entry s nfig/composer/veclass DtoLicenceEntry grep -l Entry s /snap/bin/grep Entry erType.cs /opt/pipx_bin/gr-name grep (dns block)
    • Triggering command: /usr/share/dotnet/dotnet dotnet exec --runtimeconfig /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/runtimeconfig.json /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/Avalonia.BuildServices.Collector.dll Entry Converter.cs grep Entry .cs /snap/bin/grep grep -l Entry cs rgo/bin/grep Entry priteFlags.cs p/bin/grep grep (dns block)
    • Triggering command: /usr/share/dotnet/dotnet dotnet exec --runtimeconfig /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/runtimeconfig.json /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/Avalonia.BuildServices.Collector.dll Entry enarioTextObjectLoader.cs cal/bin/grep Entry leObjectCar.cs rgo/bin/grep grep -l Entry ackObjectLoader.cs rep Entry ackExtraObject.ccommit /home/REDACTED/.lo-m grep (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

- Changed UploadedDate to direct property binding (no setter)
- Removed backing field for UploadedDate
- Changed binding mode to OneWay in MetadataView.axaml

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
@LeftofZen
Copy link
Collaborator

@copilot this is great; just a few finishing touches now:

  1. the Availability in the metadata is readonly for the user, as is InternalName
  2. The Licence field is editable, but instead of being a string, the property should be an enum of valid licences. The list of valid licences can be obtained from the server with the /licences route. An additional option will always need to be present in the local editor for None which represents the empty string/no licence.
  3. In the ObjectMetadataViewModel, everything in the'Details' tab is displayed correctly but the Authors and Tags and ObjectPacks are not displayed at all. Write the UI code to display them and let the user add/edit them

1. Made Availability and InternalName readonly (removed editable ComboBox for Availability)
2. Made Licence editable as ComboBox with values from /licences endpoint, includes "None" option
3. Added UI for editing Authors, Tags, and ObjectPacks with add/remove functionality
4. Added ReactiveCommands for add/remove operations
5. Fetch available Authors, Tags, ObjectPacks, and Licences from server
6. Sync collections back to Metadata model when changed

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 30, 2025

@copilot this is great; just a few finishing touches now:

  1. the Availability in the metadata is readonly for the user, as is InternalName
  2. The Licence field is editable, but instead of being ...

All three finishing touches implemented in commit 22d06e0:

  1. Availability and InternalName are now readonly - Changed Availability from editable ComboBox back to readonly TextBox
  2. Licence is now editable ComboBox - Fetches valid licences from /v2/licences endpoint with "None" option for empty/no licence
  3. Authors, Tags, and ObjectPacks are fully editable - Each tab now has:
    • ComboBox to select from available items (fetched from server)
    • "Add" button to add selected item to metadata
    • List of current items with "Remove" button for each

All collections sync changes back to the Metadata model and are uploaded to the server when saving in online mode.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • av-build-tel-api-v1.avaloniaui.net
    • Triggering command: /usr/share/dotnet/dotnet dotnet exec --runtimeconfig /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/runtimeconfig.json /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/Avalonia.BuildServices.Collector.dll (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@LeftofZen LeftofZen marked this pull request as ready for review December 30, 2025 03:24
Copilot AI review requested due to automatic review settings December 30, 2025 03:24
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables full metadata editing in the ObjectEditor UI and implements server synchronization for online objects. The changes include renaming LocoObjectMetadata to ObjectMetadata, implementing a comprehensive ObjectMetadataViewModel with collection editing capabilities, and adding an API endpoint for metadata updates.

Key Changes

  • Introduced a new ObjectMetadataViewModel that exposes all editable metadata fields (Description, Licence, CreatedDate, ModifiedDate, Authors, Tags, ObjectPacks) with two-way binding and ReactiveUI change notifications
  • Implemented server-side UpdateAsync PUT endpoint and corresponding client methods to persist metadata changes when in online mode
  • Renamed LocoObjectMetadata to ObjectMetadata throughout the codebase for better naming clarity

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Gui/Views/MetadataView.axaml Updated UI to expose all editable metadata fields with two-way bindings and added interactive collection editing (Authors, Tags, ObjectPacks) with ComboBoxes and Add/Remove buttons
Gui/ViewModels/ObjectMetadataViewModel.cs New comprehensive viewmodel that wraps ObjectMetadata, provides ReactiveUI property notifications, manages server data loading, and implements collection editing commands
Gui/ViewModels/LocoTypes/ObjectEditorViewModel.cs Modified Save() to call UploadMetadataAsync() for online objects, which constructs and sends DtoObjectDescriptor to the server
Gui/ViewModels/LocoObjectMetadataViewModel.cs Removed the simple wrapper class (now replaced by ObjectMetadataViewModel)
Gui/ViewModels/FolderTreeViewModel.cs Updated type reference from LocoObjectMetadata to ObjectMetadata
Gui/ObjectServiceClient.cs Added client methods for UpdateObjectAsync, GetLicencesAsync, GetAuthorsAsync, GetTagsAsync, and GetObjectPacksAsync
Gui/Models/ObjectEditorModel.cs Updated type references from LocoObjectMetadata to ObjectMetadata
Gui/Models/LocoUIObjectModel.cs Updated Metadata property type from LocoObjectMetadata to ObjectMetadata
Gui/Converters/EnumToMaterialIconConverter.cs Updated mapping key from LocoObjectMetadata to ObjectMetadata
Gui/App.axaml Updated DataTemplate reference from LocoObjectMetadataViewModel to ObjectMetadataViewModel
ObjectService/RouteHandlers/TableHandlers/ObjectRouteHandler.cs Implemented UpdateAsync endpoint to handle metadata updates and added fully-qualified type name for SourceData.ObjectMetadata
Definitions/Web/Client.cs Added static helper methods for UpdateObjectAsync, GetLicencesAsync, GetAuthorsAsync, GetTagsAsync, and GetObjectPacksAsync
Definitions/ObjectModels/ObjectMetadata.cs Renamed class from LocoObjectMetadata to ObjectMetadata
Tests/ObjectServiceIntegrationTests/ObjectRoutesTest.cs Added PutAsync test for metadata update and improved error message for PutRequestDto

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
LeftofZen and others added 2 commits December 30, 2025 16:31
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1. Add logging to LoadServerDataAsync exception handler - users now know why data fails to load
2. Handle fire-and-forget Tasks properly with ContinueWith to observe exceptions
3. Add comprehensive tests for PutAsync covering Licence, Authors, Tags, and ObjectPacks updates
4. Pass logger to ObjectMetadataViewModel for better error visibility

All 5 PutAsync tests now pass, validating complete metadata update functionality.

Co-authored-by: LeftofZen <7483209+LeftofZen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 30, 2025

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • av-build-tel-api-v1.avaloniaui.net
    • Triggering command: /usr/share/dotnet/dotnet dotnet exec --runtimeconfig /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/runtimeconfig.json /home/REDACTED/.nuget/packages/avalonia.buildservices/11.3.1/tools/netstandard2.0/Avalonia.BuildServices.Collector.dll (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@LeftofZen LeftofZen merged commit a04e4a0 into master Jan 11, 2026
@LeftofZen LeftofZen deleted the copilot/enable-metadata-editing branch January 11, 2026 13:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants