pascalw / dashbling

Hackable React based dashboards for developers, inspired by Dashing.

Home Page:https://dashbling.fly.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Multiple widgets of the same "type"

musicbyjing opened this issue · comments

In Dashing (the framework I'm coming from) it's possible to have multiple widgets of the same type, all generated from one HTML, CSS, and CoffeeScript file, which together define a certain type of widget. For example, you could use a JIRA sprint progress widget type to show progress for multiple sprints, using one format. I'm relatively new to this project so I'm just wondering what the best way to accomplish this is. Thanks!

Thanks for your question. I'm not entirely sure I understand what it is you want to achieve.

In general though, data in Dashbling resolves around events. The server generates events using periodically ran functions, or by subscribing to an event stream of sorts (for example a Twitter stream).

Each event has an id field, that can be used in the frontend to consume specific events and bind the data to Widgets (React components). How you structure events is up to you.

You could for example send one event from the server and consume the data in multiple widgets:

//dashbling.config.js
module.exports = {
  jobs: [
    {
      schedule: "*/5 * * * *",
      fn: sendEvent =>
        // fetch Jira tickets here
        sendEvent("jira-tickets", {
          tickets: [{ id: 1, status: "open" }, { id: 2, status: "closed" }]
        })
    }
  ]
};
const JiraTicketsWidget = props => {
  if (!props.tickets) return null;
  const tickets = props.tickets.filter(props.filter);

  return (
    <Widget style={{ backgroundColor: "#FB8C00" }}>
      <h2>{props.title}</h2>
      <p>{tickets.length}</p>
    </Widget>
  );
};

// bind 'jira-tickets' event to the JiraTicketsWidget
const JiraTickets = connect("jira-tickets")(JiraTicketsWidget);

// Dashboard.js
export default props => {
  return (
    <Dashboard>
      <JiraTickets title="Open tickets" filter={ticket => ticket.status == "open"} />
      <JiraTickets title="Closed tickets" filter={ticket => ticket.status == "closed"} />
    </Dashboard>
  );
};

Or you could generate multiple events from the server:

//dashbling.config.js
module.exports = {
  jobs: [
     {
      schedule: "*/5 * * * *",
      fn: sendEvent => {
        const tickets = fetchJiraTickets();

        sendEvent("open-jira-tickets", tickets.filter(t => t.status == "open"));
        sendEvent("closed-jira-tickets", tickets.filter(t => t.status == "closed"));
      }
    }
  ]
};

And bind those events to specific Widget (instances):

// bind 'open-jira-tickets' event to the JiraTicketsWidget
const OpenJiraTickets = connect("open-jira-tickets")(JiraTicketsWidget);
const ClosedJiraTickets = connect("closed-jira-tickets")(JiraTicketsWidget);

// Dashboard.js
export default props => {
  return (
    <Dashboard>
      <OpenJiraTickets title="Open tickets" />
      <ClosedJiraTickets title="Closed tickets" />
    </Dashboard>
  );
};

As you can see this is very flexible and you can use the full power of React and Redux.
In the example project you can find some more examples of parameterized jobs and binding data to widgets.

I hope this makes sense!
Let me know if you have any other questions.

This is exactly what I was looking for. I'm fairly new to React so I'm still learning the ropes but this has been tremendously helpful, so thanks very much!

You're welcome @musicbyjing! The docs are currently written assuming you know React (and Redux) already. I'll see if I can take some of this issue content and turn it into docs some time.