Custom App Connect components

Hi there!

Is it possible to have the ability to develop custom components? I’ve searched around but found nothing related to custom app connect components.

For example, let’s assume I need a custom chartjs chart where I want to draw an arbitrary vertical line somewhere similar to this one. The current chart component generates code similar to:

<dmx-chart id="chart1" nogrid="true" stacked="true" colors="colors1" legend="left" dmx-bind:data="sc_get_cars.data.cars" dataset-1:value="year" dataset-1:label="model"></dmx-chart>

Which does not let me customize the chartjs code.

I’d like to write my own code and bundle it in a component, so that I don’t need to copy/paste for each instance of chart in my app. When using my custom component, I guess it would generate something like:

<dmx-my-custom-chart ...></dmx-chart>

In a platform like Bubble, if I have a need for a completely custom chart, I write a plugin with a custom element containing all the chartjs code/config.

Would it make sense?

Thanks a lot!

It has been confirmed by the team that this is coming as part of the extensibility features. No ETA yet though.

2 Likes

We don’t have documentation for it, but it looks like:

dmx.Component('my-custom-chart', {

  // attributes for the component (accessed by this.props)
  attributes: {
    type: {
      type: String,
      default: 'bar'
    },

    data: {
      type: Array,
      default: []
    }
  },

  // render method
  render: function(node) {
    // render chart here
    $(node).chart({
      type: this.props.type,
      data: this.props.data
    });
  },

  // update
  update: function(props) {
    // this.props contains the new properties
    // props argument were the previous properties
    // check here if something was changed and needs updating
    if (this.props.type !== props.type) {
      // update chart type
    }
  }

});

Above is then usable like:

<dmx-my-custom-chart type="pie" dmx-bind:data="query1"></dmx-my-custom-chart>

There is currently no integration with Wappler UI, so you need to edit your component within code view. Simple components can be created, more complex will need more knowledge about the internal working of App Connect. You can give it a try or wait until we integrate it with Wappler, have no ETA for that.

3 Likes

Wow, interesting! Yeah, it looks like a good workaround for now. I’ll be happy to test that soon. I was thinking about wrapping my custom code in page fragments to avoid copy/paste for new instances, but building component your way seems much cleaner.

I believe giving this sample somewhere in the doc will be valuable for people willing to structure their app custom components (which I guess happens quite frequently when building a significant app).

I might get back here if I face an issue with a syntax I can’t figure out on my own, for example if I need the component to interact with the rest of the app :wink: (I don’t have the use case in my hands yet)

Thanks a lot for the quick reply, both of you.

EDIT: it seems App Connect has a documentation here, but I’m not sure it provides the doc about declaring custom components.

EDIT 2: my personal opinon is that documenting this part should come before integrating with Wappler UI so that, in the low-code mindset, developers are able to code whatever components they want, and developing it is then made easier and easier over Wappler updates :slight_smile:

1 Like

I agree. Was just trying to create a custom timepicker using the example code above and was unsuccessful rendering the element on the page. Probably missing something simple and docs on this would be awesome.

@patrick is there any difference in AC between

<dmx-my-component attribute1...></dmx-my-component>

and

<div is=dmx-my-component attribute1...></div>

Except for the obvious fact that I’m actually adding a div to the DOM.

Is it just a matter of the actual purpose of the component?

So if the component is going to render html I would be better of using the is attribute and if it’s just data manipulation or similar I should use the dmx-my-component tag.

Or are there any other differences I should be aware of before choosing?

No there is no difference between using tag name ot IS attribute. It results in the same component.

However recognizing in Wappler App Structure might be different depending on the usage,

1 Like

Thanks for the confirmation George.

I’m working on a few components at the moment and hopefully for the time they are mature enough to be released you already have implemented a way to add hjson files so they can be managed from the UI.

Also I’m porting my i18next implementation to be more AC friendly.
Right now I’m implementing it as a custom formatter so when the formatter is called it will run the translation.

But I was thinking that instead of a custom formmater I should use two custom DMX attributes i.e. dmx-i18n="key" and dmx-i18n-options="{}". Similar approach to dmx-html and dmx-text.

What approach do you think makes more sense? Custom formatter or custom attributes?

1 Like

Hey @george I’m loving so far developing components for App Connect. Before I started dabbling with this I handled frontend libraries with flows.

At first with page flows and recently with app flows. This was convenient to certain extent as it didn’t come without caveats. For instance, you can’t run more than one flow of the same type at the same time. A flow needs to end before you can run it again and this was inconvenient for some libraries.

After a few days of reverse engineering all the DMX components to understand and learn the possibilities I can now say that flows are not the way to handle third party js libraries. It’s via DMX components, Attributes and Actions. Flows are ok as a workaround.

So my ask(another one). After you guys deliver 4.0 can you give some additional love to AC extensibility?

a) Some documentation
b) UI support.

I know this is not as easy as the SC extension support because of all the implications and places you can access components(flows, bindings, events, attributes, etc) and also how they can interact between each and other and where they can be shown and where not.

It’s just so easy to write something like this:

dmx.Component("swal2", {
  attributes: {
    toast: { type: Boolean, default: !1 }
  },
  methods: {
    show: function (t) {
      if (this.props.toast) {
        let o = {
          position: 'top-end',
          showConfirmButton: false,
          timer: 5000,
          timerProgressBar: true,
          onOpen: (toast) => {
            toast.addEventListener('mouseenter', Swal.stopTimer)
            toast.addEventListener('mouseleave', Swal.resumeTimer)
          }
        }
        t.text = ''
        t = Object.assign(t, o)
      }
      t = Object.assign(t, this.props)
      Swal.fire(t)
    },
  },
});

and

<dmx-swal2 id="swal2" toast></dmx-swal2>

<dmx-serverconnect id="serverconnect1" noload url="/api/example1" 
dmx-on:error="swal2.show({title: 'generic-error'.t(), icon : 'error'})" 
dmx-on:success="swal2.show({title: 'leave-success'.t(), icon : 'success'})">
</dmx-serverconnect>

To get a library like Sweetalert2 working with almost no effort and not having to write workarounds because appConnect.js is not loaded before the library is executed and all that.

The only thing remaining to put the icing on the cake is being able to access all this from the UI. And some documentation to make sure we are not screwing up anything. Reverse engineering can only take you so far if you don’t understand all the implications of the standard methods that App Connect(render, update, etc) has.

Maybe it is wiser to wait a bit before diving development of app connect components. We haven’t made it public yet for a reason.

Our api structure can change and we might even go for complete new structure for app connect v2

So we will be too much bound with backwards compatibility if we commit to the current structure.

Currently we can easily tweak and rewrite our components because it is all under our control. That won’t be the case if we publish and commit to the current structure.

So we are highly evaluating the decision and hope to get to it soon after we have rounded up Wappler 4 and its core UI in workflows.

3 Likes

I understand. Makes sense “in a sense”.

On the other side it’s also responsability of the extension developers to keep up with API changes for any framework(not just App Connect).

Buit it’s true that compatibility would need to be addressed somehow.

I’m thinking of two options:

  1. Create an extension framework and an interface that you can always use to “translate” into App Connect requirements. So you define an independent framework for custom extensions and you handle App Connect library and the interface.

  2. Provide some sort of App Connect compatibility version support. So users can select what App Connect version they are using at each time and they have control over when to upgrade it. But the users then could be missing on features and probably there should be an independent channel for bugs.

Both have quite the overhead for you guys. So I understand patience is needed on our end.

Based on this I will not release custom components for the time being for App Connect 1.x and use them solely for myself.

Thanks for the update!

As a Wappler user, and having gone down the Dreamweaver path where to do anything at all you needed extensions, the extensions route in Wappler is one I hope to and will avoid.

I seriously hope that Wappler does not turn into a Dreamweaver and be reliant on third party extensions.

Not a knock on your obvious skillset which indeed is at a high level. It’s just a path that Wappler does not need to take in my opinion.

1 Like

I understand your concern, but there is so much a team of 3 can do in a 24 hour day considering we know they don’t sleep :slight_smile:

Thankfully using custom extensions is optional and nobody has to use them if they don’t want to. And since we have access to our own code anyone can build his/her own extension if they want to. This way nobody has to rely on 3rd parties.

But still If you want to grow your app beyond what’s possible you need to be able to extend it somehow.

2 Likes

As long as Wappler doesn’t become reliant on them like Dreamweaver has. Not saying they shouldn’t open it up at all. That’s great if they do. Just don’t make it a necessity ike Adobe did.

Now if you would write some Cordova plugins for Wappler I might have a change of heart. :wink: :beers:

I have never used Dreamweaver so I don’t know the history there. But it seems to me that you are telling me that Adobe got lazy on developing new features because they just let 3rd parties do their work and it was all commercial extensions right? So you had to pay for Dreamweaver plus the extensions. Am I close?

And that’s how you met these guys and how Wappler was born! So in a way you need to thank Adobe for doing that pro move :joy:

It’s just a standard thing in the industry. Evolve software by leveraging other software.

Wappler wouldn’t exist as it is without using 3rd party libraries(Bootstrap, Express, nodejs, php, fullcalendar, etc).

We all build on top of something. And I just have the need to build on top of Wappler :slight_smile:

1 Like

That looks amazing. I have just used custom formatters so far. But this also sounds great for third-party library integration.
I hope it would not cause any performance issues if it adds to already a lot of things AppConnect has to do on a page to manage dynamic bindings and stuff.

AppConnect v2 sounds amazing though - maybe we will get an even more powerful and lighter framework.

1 Like

I think it would do the contrary. Being able to declare all the logic in App Connect context avoids us having to do all sort of workarounds to sort out the fact that AC is not loaded before the library is called which adds overhead.

When adding libraries via standard JS I ended up with a mix of js code, ready events, wappler variables, static and dynamic events just to make everything work in sync.

I found myself often calling dmx.parse or querying directly dmx.app.data.

You can forget about that declaring dmx components :slight_smile:

1 Like

OK Jon - you convinced us :slight_smile:

We will see what we can do to open App Connect extensibility on the short term

@patrick will be adding some descriptions how the App Connect Component and Formatters are structured and I will work on the hjson UI implementation in a similar way as Server Connect - per project definitions.

4 Likes

I’m so excited for this @george :slight_smile:

When SC and AC extensibility is finished(SC still needs a tiny bit of tweaking) it would be great to put this screen to great use.

Separating Core extensions(App Connect, Server Connect), Wappler extensions(FullCalendar, Medium) and Custom extensions(User’s extensions)

But in a tab of course :joy:

So people can keep ‘tabs’ of which extensions they have loaded in their project, be able to remove them, force update them if needed(sometimes they don’t) and load custom ones into their projects in an easy way.

I’m thinking of a section to add git repositories so people can load extensions from there(via release tag?). That way you can also deal with @brad concern about commercial extensions as they have to be public to be imported in an easy way.

And on top of the .js and .hjson files I would add the requirement of another file which contains metadata like release information(version, number, date, etc), server model if it applies, tested against Wappler versions, helpful info, hyperlinks, dependencies, etc, which would be read by the new extensions module to show important information to Wappler user when browsing/Installing.