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

Widgets: add support for Widget discovery from BlueOS #1499

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Williangalvani
Copy link
Member

@Williangalvani Williangalvani commented Dec 10, 2024

Edit:

Current discovery method:

A new field "extras" is added to /register_service:

{
   "name":"Ping Viewer Next",
   "description":"A ping protocol extension for expose devices to web.",
   "icon":"mdi-compass-outline",
   "company":"BlueRobotics",
   "version":"0.0.0",
   "new_page":false,
   "webpage":"https://github.com/RaulTrombin/navigator-assistant",
   "api":"/docs",
   "extras":{
      "cockpit":"/cockpit_extras.json"
   }
}

/cockpit_extras.json looks like this:

{
   "target_system":"Cockpit",
   "target_cockpit_api_version":"1.0.0",
   "widgets":[
      {
         "name":"ping360",
         "config_iframe_url":null,
         "iframe_url":"/addons/widget/ping360/?uuid=00000000-0000-0000-d9fb-222b5f8a865d",
         "version":"1.0.0"
      }
   ]
}

The consumer (in this case cockpit), should validate the file target_system and integration api version (in this case, cockpit's widget api). The rest of it is defined by the consumer.

In cockpit we need a name, an iframe url, and optionally an iframe for the configuration interface. The version can be used for (in)validating widget settings.

@Williangalvani
Copy link
Member Author

requires bluerobotics/BlueOS#3028

@joaoantoniocardoso
Copy link
Member

  1. We should define a widget-system/cockpit version because the implied protocol can change in the future.
  2. The widget itself should provide a version

@Williangalvani Williangalvani force-pushed the widget-discovery branch 3 times, most recently from dcfe920 to 37fdcc2 Compare December 11, 2024 21:28
@Williangalvani Williangalvani marked this pull request as ready for review December 13, 2024 16:42
Comment on lines +65 to +89
// first we gather all the extra jsons with the cockpit key
const extraWidgets = await services.reduce(
async (accPromise: Promise<BlueOsWidget[]>, service: Record<string, any>) => {
const acc = await accPromise
const worksInRelativePaths = service.metadata?.works_in_relative_paths
if (service.metadata?.extras?.cockpit === undefined) {
return acc
}
const baseUrl = worksInRelativePaths
? `http://${vehicleStore.globalAddress}/extensionv2/${service.metadata.sanitized_name}`
: `http://${vehicleStore.globalAddress}:${service.port}`
const fullUrl = baseUrl + service.metadata?.extras?.cockpit

const extraJson: ExtrasJson = await ky.get(fullUrl, options).json()
const widgets: BlueOsWidget[] = extraJson.widgets.map((widget) => {
return {
...widget,
iframe_url: baseUrl + widget.iframe_url,
iframe_icon: baseUrl + widget.iframe_icon,
}
})
return acc.concat(widgets)
},
Promise.resolve([] as BlueOsWidget[])
)
Copy link
Member

Choose a reason for hiding this comment

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

this filtering code could live on the backend under an endpoint like get_extras(key: string) -> HttpResponse([json]) and the Cockpit would ask for the key "Cockpit".

Copy link
Member

@rafaellehmkuhl rafaellehmkuhl left a comment

Choose a reason for hiding this comment

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

Besides the overall naming suggestions, I just need to be able to test this PR.

Comment on lines +5 to +46
/**
* Widget configuration object as received from BlueOS
*/
export interface BlueOsWidget {
/**
* Name of the widget, this is displayed on edit mode widget browser
*/
name: string
/**
* The URL at which the widget is located
* This is expected to be an absolute url
*/
iframe_url: string

/**
* The icon of the widget, this is displayed on the widget browser
*/
iframe_icon: string
}

/**
* Widget type on steroids. This is the WidgetType with added Custom name and options
*/
export interface ExtendedWidget {
/**
* Widget type
*/
component: WidgetType
/**
* Widget name, this will be displayed on edit mode
*/
name: string
/**
* Widget options, this is the configuration that will be passed to the widget when it is created
*/
options: Record<string, unknown>
/**
* Widget icon, this is the icon that will be displayed on the widget browser
*/
icon: string
}

Copy link
Member

Choose a reason for hiding this comment

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

Sugestion: to have a "BaseWidget" class, with just the name, and those two extend from it. Also, instead of "ExtendedWidget", I think "InternalWidget" would make it more clear what we are talking about.

Edit: actually, shouldn't we inherit from the "Widget" type? Maybe restrict it a little bit so the BlueOsWidget works fine?

Comment on lines +746 to +755
const availableWidgetTypes = computed(() =>
Object.values(WidgetType).map((widgetType) => {
return {
component: widgetType,
name: widgetType,
icon: widgetImages[widgetType] as string,
options: {},
}
})
)
Copy link
Member

Choose a reason for hiding this comment

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

As we are now returning "Widgets", and now "WidgetTypes" anymore, this computed should be renamed to "availableInternalWidgets".

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.

3 participants