Skip to content

Loading Components: Multiple Modal Applications

The stage block is a, so named blocking stage, like the stage error that we will explore soon. These blocking stages have some special features. The first one is that in these stages only one component will be visible.

As we know stages will already hide unfronted components if their position is not absolute or fixed. But in blocking stages all unfronted components will be hidden, regardless of it's position. Thus also all application components.

What are we learning here?

  • Blocking stages will show only the fronted component

Let's add one more button into our HTML structure:

src/demo/widgets/loading-components/index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<div class="border rounded d-inline-block p-1 mr-2 mt-2">
  Blocking
  <button class="btn btn-xs btn-info" data-role="modal-app">
    <i class="fas fa-check-circle"></i> App
  </button>
  <button class="btn btn-xs btn-info" data-role="modal-multi-app">
    <i class="fas fa-check-circle"></i> MultiApp
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 mt-2">
  App
  <button class="btn btn-xs btn-info" data-role="inline-app-noid">
    <i class="fas fa-times-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="inline-app-id">
    <i class="fas fa-check-circle"></i>
  </button>

And attach some handlers:

src/demo/widgets/loading-components/index.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { Box, MockApplication } from "@codecoupler/cc-ui";
import template from "./index.html";
export default class extends Box {
  async finalize() {
    super.finalize();
    this.$box.html(template);
    let $this = this.options.target || this.env.parent;
    this.$box.find("[data-role=modal-multi-app]").on("click", async () => {
      let firstApp = await $this.getStage("root").load({
        component: MockApplication,
        id: "first-app",
        level: "block",
        options: {
          "@codecoupler": {
            application: {
              panel: { position: "left-center left-center 70px" }
            }
          }
        }
      });
      await new Promise((r) => setTimeout(() => r(), 2000));
      let secondApp = await $this.getStage("root").load({
        component: MockApplication,
        id: "second-app",
        level: "block",
        options: {
          "@codecoupler": {
            application: {
              panel: { position: "right-center right-center -70px" }
            }
          }
        }
      });
      await new Promise((r) => setTimeout(() => r(), 2000));
      firstApp.front();
      await new Promise((r) => setTimeout(() => r(), 2000));
      firstApp.destroy();
      await new Promise((r) => setTimeout(() => r(), 2000));
      secondApp.destroy();
    });
    this.$box.find("[data-role=modal-app]").on("click", async () => {
      await $this.getStage("root").load({
        component: MockApplication,
        level: "block"
      });
    });
    this.$box.find("[data-role=inline-app-noid]").on("click", async () => {
      await $this.stage.load(MockApplication);
    });
    this.$box.find("[data-role=inline-app-id]").on("click", async () => {
      await $this.stage.load(MockApplication, "some-id");
    });
  }
}

Now click on the button "MultiApp", sit back and enjoy the show:

  • "first-app" will be loaded. As a result, the widget will be blocked.
  • After 2 seconds the "second-app" will be loaded. As a result, "first-app" is hidden.
  • After 2 seconds the "first-app" will be fronted. As a result, "second-app" is hidden.
  • After 2 seconds the "second-app" will be destroyed. As a result, "first-app" appears.
  • After 2 seconds the "first-app" will be destroyed. As a result, the widget will be unblocked.

Furthermore we have placed the application panels to the left and right side. This can be done with the namespaced options located under @codecoupler.application.