feat(extensions): code-first frontend contributions (#38346)

This commit is contained in:
Michael S. Molina
2026-03-02 18:51:29 -03:00
committed by GitHub
parent 01d5245cd2
commit a74d32ab44
56 changed files with 1430 additions and 2403 deletions

View File

@@ -91,39 +91,24 @@ The `README.md` file provides documentation and instructions for using the exten
## Extension Metadata
The `extension.json` file contains all metadata necessary for the host application to understand and manage the extension:
The `extension.json` file contains the metadata necessary for the host application to identify and load the extension. Backend contributions (entry points and files) are declared here. Frontend contributions are registered directly in code from `frontend/src/index.tsx`.
```json
{
"id": "dataset-references",
"name": "Dataset References",
"publisher": "my-org",
"name": "dataset-references",
"displayName": "Dataset References",
"version": "1.0.0",
"frontend": {
"contributions": {
"views": {
"sqllab": {
"panels": [
{
"id": "dataset-references.main",
"name": "Dataset References"
}
]
}
}
},
"moduleFederation": {
"exposes": ["./index"],
"name": "datasetReferences"
}
},
"license": "Apache-2.0",
"backend": {
"entryPoints": ["superset_extensions.dataset_references.entrypoint"],
"files": ["backend/src/superset_extensions/dataset_references/**/*.py"]
}
},
"permissions": []
}
```
The `contributions` section declares how the extension extends Superset's functionality through views, commands, menus, and other contribution types. The `backend` section specifies entry points and files to include in the bundle.
The `backend` section specifies Python entry points to load eagerly when the extension starts, and glob patterns for source files to include in the bundle.
## Interacting with the Host
@@ -154,34 +139,38 @@ export const onDidQueryStop: Event<QueryContext>;
The following code demonstrates more examples of the existing frontend APIs:
```typescript
import { core, commands, sqlLab, authentication, Button } from '@apache-superset/core';
import React from 'react';
import { views, commands, sqlLab, authentication, Button } from '@apache-superset/core';
import MyPanel from './MyPanel';
export function activate(context) {
// Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code
const panelDisposable = core.registerView('my_extension.panel', <MyPanel><Button/></MyPanel>);
// Register a new panel (view) in SQL Lab and use shared UI components in your extension's React code
views.registerView(
{ id: 'my-extension.panel', name: 'My Panel' },
'sqllab.panels',
() => <MyPanel><Button /></MyPanel>,
);
// Register a custom command
const commandDisposable = commands.registerCommand(
'my_extension.copy_query',
() => {
// Command logic here
},
);
// Register a custom command
commands.registerCommand(
{
id: 'my-extension.copy-query',
title: 'Copy Query',
description: 'Copy the current query to clipboard',
},
() => {
// Command logic here
},
);
// Listen for query run events in SQL Lab
const eventDisposable = sqlLab.onDidQueryRun(queryContext => {
console.log('Query started on database:', queryContext.tab.databaseId);
});
// Listen for query run events in SQL Lab
sqlLab.onDidQueryRun(queryContext => {
console.log('Query started on database:', queryContext.tab.databaseId);
});
// Access a CSRF token for secure API requests
authentication.getCSRFToken().then(token => {
// Use token as needed
});
// Add all disposables for automatic cleanup on deactivation
context.subscriptions.push(panelDisposable, commandDisposable, eventDisposable);
}
// Access a CSRF token for secure API requests
authentication.getCSRFToken().then(token => {
// Use token as needed
});
```
### Backend APIs