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

Write documentation for JavaScript plugin mechanism #2250

Closed
simonw opened this issue Feb 3, 2024 · 2 comments
Closed

Write documentation for JavaScript plugin mechanism #2250

simonw opened this issue Feb 3, 2024 · 2 comments

Comments

@simonw
Copy link
Owner

simonw commented Feb 3, 2024

Refs:

Added in 452a587

@simonw simonw added this to the Datasette 1.0a8 milestone Feb 3, 2024
@simonw
Copy link
Owner Author

simonw commented Feb 3, 2024

Tried this as initial inspiration, worked pretty well!

curl 'https://github.com/simonw/datasette/commit/452a587e236ef642cbc6ae345b58767ea8420cb5.diff' | \
  llm -m 4 \
  --system 'Write detailed end-user documentation explaining how to write JavaScript that interacts with Datasette based on this diff'

Output:

User Documentation: Interacting with Datasette via JavaScript

Datasette now provides a JavaScript client with different methods and APIs allowing plugins developers and front-end developers to interact with Datasette in a more interactive manner.

JS Manager

The main JavaScript class provided by Datasette is datasetteManager. This class provides the methods to interact with Datasette from other JavaScript modules/files.

Event

The Manager emits a CustomEvent named "datasette_init" when it is ready.

The detail attribute of this CustomEvent contains the Datasette Manager instance:

document.addEventListener("datasette_init", function (evt) {
  const { detail: manager } = evt;
  // You can start using the manager here
});

Registering a Plugin

You can register a plugin using the registerPlugin(name, pluginMetadata) method. For example:

manager.registerPlugin("myPlugin", {
  version: 1.0,
  customFunc: () => console.log("This is a custom function!"),
});

You can later get the plugin Metadata using the provided name:

var myPlugin = manager.plugins.get("myPlugin");
myPlugin.customFunc();

Core Methods (makeColumnActions and renderAboveTablePanel)

Those methods are meant to be used as hooks by other plugins or tools interacting with Datasette.

The Manager uses the makeColumnActions(columnMeta) function as a callback to create new DOM elements. The renderAboveTablePanel() will enable to render content after the table panel. Both methods are used in the table.js file to create dynamic content within the tables.

The makeColumnActions function is used to customize menu items in the column headers. It provides metadata which you can use to generate more actions. For example:

//...
makeColumnActions: (columnMeta) => {
  const { columnName } = columnMeta;
  
  return [{
    label: "Show columnName in the console",
    onClick: (evt) => console.log(columnName),
  },]
},
//...

The renderAboveTablePanel function allows the creation of panels with custom content above the table. For example, you can create a new panel with an image:

//...
makeAboveTablePanelConfigs: () => {
  return [{
    id: 'first-map-panel',
    label: "image-panel",
    render: node => {
      const img = document.createElement('img');
      img.src = 'my-image-url'
      node.appendChild(img);
    },
  }]
},
//...

In the configurable panel, each configuration object should include the id, label and render method for rendering the content.

Core DOM Selectors

The datasetteManager provides a set of DOM Selectors to help plugins attach to the appropriate elements. These selectors are stored in the property manager.selectors.

Table Interactions

The datasette also provides interactivity within table elements. The table.js file includes functionalities that interact with the datasetteManager. These functionalities include creating menus for table headers, filtering rows, and adding autocomplete for filter values. Make sure to use the selectors from the manager when developing new functionalities in the table.

@simonw
Copy link
Owner Author

simonw commented Feb 5, 2024

It would be good if the buttons showed which one had been most recently selected here:

first-second

That's from this plugin:

document.addEventListener('datasette_init', function(ev) {
  ev.detail.registerPlugin('panel-plugin', {
    version: 0.1,
    makeAboveTablePanelConfigs: () => {
      return [
        {
          id: 'first-panel',
          label: 'First panel',
          render: node => {
            node.innerHTML = '<h2>My 1st panel</h2><p>This is a custom panel that I added using a JavaScript plugin</p>';
          }
        },
        {
          id: 'second-panel',
          label: 'Second panel',
          render: node => {
            node.innerHTML = '<h2>My 2nd panel</h2><p>This is a custom panel that I added using a JavaScript plugin</p>';
          }
        }
      ]
    }
  });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant