Source: component/clients.js

/*! meta-admin/modules/clients */
/*jslint
    browser, long
*/
/*global
*/
/**
 * clients component.
 *
 * @module meta-admin/modules/component/clients
 */
import _ from "underscore";
import ko from "knockout";
import Logger from "js-logger";
import nav from "util-web/modules/nav";
import protocol from "meta-core/modules/protocol";
import template from "./clients.html";

const LOG = Logger.get("meta-admin/clients");

export default Object.freeze({
    template,
    viewModel: {
        createViewModel: function ({viewmodel}) {
            /**
             * @alias module:meta-admin/component/clients
             */
            const vm = {};

            vm.viewmodel = viewmodel;

            vm.isLoading = ko.observable();
            vm.currentClientId = vm.viewmodel.client.clientId;
            vm.clients = ko.observableArray();

            vm.copyClientId = (entry) => navigator.clipboard.writeText(entry.clientId);

            vm.getClientList = function () {
                vm.clients.removeAll();
                vm.isLoading(true);
                LOG.debug("getClientList");
                return vm.viewmodel.client.getClientList(protocol.clientListRequest()).then(function (clientListReply) {
                    vm.clients(clientListReply.clients.sort(function (a, b) {
                        const aTimestamp = a.timestamp;
                        const bTimestamp = b.timestamp;
                        return (
                            aTimestamp === bTimestamp
                            ? 0
                            : (
                                aTimestamp < bTimestamp
                                ? 1
                                : -1
                            )
                        );
                    }).map(vm.viewmodel.clientListEntryVm));
                    LOG.debug(`getClientList, clientsLength=${vm.clients().length}`);
                }, function (exc) {
                    LOG.warn("getClientList failed", exc);
                }).then(function () {
                    vm.isLoading(false);
                });
            };

            vm.onClientNotification = function (clientNotification) {
                if (protocol.CLIENT_STATE_CHANNEL !== clientNotification.channel) {
                    return;
                }
                const entryUpdate = protocol.clientListEntry(Object.assign(
                    clientNotification,
                    clientNotification.data,
                    {state: clientNotification.action}
                ));
                const clientListEntry = _.find(vm.clients(), {clientId: entryUpdate.clientId});
                if (Boolean(clientListEntry) === false) {
                    vm.clients.unshift(vm.viewmodel.clientListEntryVm(entryUpdate));
                } else {
                    ko.mapping.fromJS(entryUpdate, clientListEntry);
                }
            };
            vm[protocol.CLIENT_NOTIFICATION] = vm.onClientNotification;
            const eventHandle = vm.viewmodel.client.registerOnEvent(vm);

            vm.cleanup = function () {
                const removed = vm.clients.remove((client) => protocol.CLIENT_STATE.DISCONNECT === ko.unwrap(client.state));
                LOG.debug(`cleanup, removedLength=${removed.length}`);
            };
            const cleanupIntervalHandle = setInterval(vm.cleanup, 10000);

            nav.register({
                id: vm.viewmodel.COMPONENTS.CLIENTS,
                onUpdate: vm.getClientList
            });

            vm.dispose = function () {
                LOG.debug("dispose");
                vm.viewmodel.client.unregisterOnEvent(eventHandle);
                clearInterval(cleanupIntervalHandle);
            };

            return Object.freeze(vm);
        }
    }
});