How-tos

You can read about general customization rules in the corresponding article.

Adding Context Menu

To add a custom content menu for apps, take the following steps:

1. Create a new class called MyContextMenu and inherit it from desktop.views.JetView. This is the menu itself with custom GetOptions() and AttachTo() methods.

class MyContextMenu extends desktop.views.JetView {
    config() {
        return {
            view: "contextmenu",
            data: this.GetOptions(),
        };
    }
    init() {
        this.Menu = this.getRoot();
        this.on(this.Menu, "onItemClick", id => {
            const ctx = this.Menu.getContext();
            this.app.callEvent("onMyMenuClick", 
            [id, ctx.id, ctx.obj]);
        });
    }
    GetOptions() {
        return [{
                id: "1",
                value: "Action 1"
            },
            {
                id: "2",
                value: "Action 2"
            },
            {
                id: "3",
                value: "Action 3"
            },
        ];
    }
    AttachTo(master) {
        this.Menu.attachTo(master);
    }
}

2. Create a new class called MyDesk and MyMenu and inherit them from the "desk" and "menu" views respectively. With the help of AttachTo() method the context menu is attached to the components:

class MyDesk extends desktop.views["desk"] {
    init() {
        super.init();
        this.MyMenu = this.ui(MyContextMenu);
        this.MyMenu.AttachTo(this.Tiles);
    }
}
class MyMenu extends desktop.views["menu"] {
    init() {
        super.init();
        this.MyMenu = this.ui(MyContextMenu);
        this.MyMenu.AttachTo(this.Tiles);
    }
}

3. Create a new class called MyDesk and inherit it from the "top" view. Custom MyAction() method handles selected menu actions.

class MyTop extends desktop.views["top"] {
    init() {
        super.init();
        this.on(this.app, "onMyMenuClick", (id, appId, master) =>
            this.MyAction(id, appId, master)
        );
    }
    MyAction(action, appId, master) {
        webix.message(`Action '${action}' for '${appId}'`);
    }
}

4. Finally, replace the default classes with a custom ones via the override map:

app = new desktop.App({
    systemParams: user,
    apps: myApps,
    override: new Map([
        [desktop.views["top"], MyTop],
        [desktop.views["menu"], MyMenu],
        [desktop.views["desk"], MyDesk],
    ]),
});
app.render(document.body);

Related sample:  Desktop: Context Menu

Adding New Button to the Toolbar

To add a new button to the toolbar, take the following steps:

1. Create a new class MyToolbar by inheriting it from the desktop.views["toolbar"].
2. Configure a button.
3. Add your button to the "cols" collection:

class MyToolbar extends desktop.views["toolbar"] {
    config() {
        const ui = super.config();
        const myButton = {
            view: "button",
            autowidth: true,
            css: "webix_primary",
            label: "My button",
            click: () => webix.message("My button clicked"),
        };
        // adding the button in "cols" collection as a layout part to apply paddings
        ui.cols.push({
            padding: {
                right: 10
            },
            rows: [{}, myButton, {}],
        });
        return ui;
    }
}

4. Override the default class:

app = new desktop.App({
    systemParams: user,
    apps: myApps,
    override: new Map([
        [desktop.views["toolbar"], MyToolbar]
    ]),
});

Related sample:  Desktop: New Toolbar Button

Signout Customization

This example shows how to customize the "signout" view. You will be able to choose a user from the list, log in, and log out using the menu. To achieve this result, take the following steps:

1. Create a DataCollection to store users.
2. Create functions for interacting with the DataCollection:

  • loadUsers() - to load the user list from the DataCollection;
  • setParams() - to save the user and his token to the DataCollection ;
  • getParams()- to get the user from the DataCollection based on his token.
const UserCollection = new webix.DataCollection({});
 
function loadUsers() {
    return Promise.resolve([{
            name: "Alex Brown",
            id: 1
        },
        {
            name: "Sinister Alpha",
            id: 2
        },
        {
            name: "Alan Raichu",
            id: 3
        },
    ]).then(data => {
        return UserCollection.parse(data);
    });
}
 
function setParams(token, user) {
    sessionStorage.setItem("login-token", token);
    localStorage.setItem("desktop-user", user);
}
 
function getParams() {
    var token = sessionStorage.getItem("login-token");
    if (token)
        return {
            token,
            user: localStorage.getItem("desktop-user")
        };
    return null;
}

3. Create a new class MySignout by inheriting it from the desktop.views["signout"]. This will be a login screen with a list of users. Custom MyDoLogin() method logs user in and sets systemParams state property.

    class MySignout extends desktop.views["signout"] {
        config() {
            return {
                css: "sign-in",
                rows: [{},
                    {
                        cols: [{},
                            {
                                type: "form",
                                css: "signin_form",
                                borderless: true,
                                maxWidth: 400,
                                minWidth: 250,
                                rows: [{
                                    view: "list",
                                    localId: "users",
                                    autoheight: true,
                                    template: "#name#",
                                }, ],
                            },
                            {},
                        ],
                    },
                    {},
                ],
            };
        }
        init() {
            super.init();
            this.List = this.$$("users");
            this.List.parse(UserCollection);
            this.on(this.List, "onItemClick", id => this.MyDoLogin(id));
        }
        MyDoLogin(user) {
            this.MyGetToken("someurl").then(raw => {
                var token = "mytoken";
                setParams(token, user);
                this.app.getState().systemParams = {
                    user,
                    token
                };
            });
        }
        MyGetToken(url) {
            //return webix.ajax(url + "login?id=" + this.config.user);
            return Promise.resolve("");
        }
    }

4. Create a new class MyMenu by inheriting it from the desktop.views["menu"]. Using the config() method, you can add the logout icon and the user name. The current user can be changed using the MyUserUpdate() method. The MyLogout() method clears systemParams object and logs the user out.

class MyMenu extends desktop.views["menu"] {
    config() {
        const ui = super.config();
        const bottomToolbar = {
            padding: {
                left: 10
            },
            margin: 5,
            borderless: true,
            cols: [{
                    view: "icon",
                    localId: "logout",
                    icon: "dsi-logout-variant",
                    click: () => this.MyLogout(),
                },
                {
                    view: "label",
                    localId: "MyUserName",
                    label: "",
                    css: "my_user_label",
                },
                {},
            ],
        };
        ui.body.rows.push(bottomToolbar);
        return ui;
    }
    init() {
        super.init();
        // on systemParams change handler
        this.on(this.app.getState().$changes, "systemParams", () =>
            this.MyUserUpdate()
        );
        // set user name after user data loading
        UserCollection.waitData.then(() => this.MyUserUpdate());
    }
    MyUserUpdate() {
        const params = this.app.getState().systemParams;
        if (params) {
            const userId = params.user;
            const user = UserCollection.getItem(userId);
            this.$$("MyUserName").config.label = user.name;
            this.$$("MyUserName").refresh();
        }
    }
    MyLogout() {
        this.app.getState().systemParams = null;
    }
}
 
loadUsers();

5. At the end, replace the default classes with a custom one via the override map:

app = new desktop.App({
    apps: myApps,
    systemParams: getParams(),
    override: new Map([
        [desktop.views["signout"], MySignout],
        [desktop.views["menu"], MyMenu],
    ]),
});
 
app.render(document.body);

Related sample:  Desktop: Custom Signout View

Back to top