@jupyterlab/services
Version:
Client APIs for the Jupyter services REST APIs
188 lines • 5.91 kB
JavaScript
"use strict";
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserManager = void 0;
const coreutils_1 = require("@jupyterlab/coreutils");
const coreutils_2 = require("@lumino/coreutils");
const polling_1 = require("@lumino/polling");
const signaling_1 = require("@lumino/signaling");
const serverconnection_1 = require("../serverconnection");
const basemanager_1 = require("../basemanager");
/**
* The url for the lab workspaces service.
*/
const SERVICE_USER_URL = 'api/me';
/**
* The service's ID.
* Used to uniquely identify the poll, and
* the item in local storage.
*/
const SERVICE_ID = '@jupyterlab/services:UserManager#user';
/**
* The user API service manager.
*/
class UserManager extends basemanager_1.BaseManager {
/**
* Create a new user manager.
*/
constructor(options = {}) {
var _a;
super(options);
this._isReady = false;
this._userChanged = new signaling_1.Signal(this);
this._connectionFailure = new signaling_1.Signal(this);
// Initialize internal data.
this._ready = this.requestUser()
.then(() => {
if (this.isDisposed) {
return;
}
this._isReady = true;
})
.catch(_ =>
// Return a promise that will never resolve, so user service is never ready
// This typically occurs when the backend has no user service
new Promise(() => {
// no-op
}));
this._pollSpecs = new polling_1.Poll({
auto: false,
factory: () => this.requestUser(),
frequency: {
interval: 61 * 1000,
backoff: true,
max: 300 * 1000
},
name: SERVICE_ID,
standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'
});
void this.ready.then(() => {
void this._pollSpecs.start();
});
}
/**
* Test whether the manager is ready.
*/
get isReady() {
return this._isReady;
}
/**
* A promise that fulfills when the manager is ready.
*/
get ready() {
return this._ready;
}
/**
* Get the most recently fetched identity.
*/
get identity() {
return this._identity;
}
/**
* Get the most recently fetched permissions.
*/
get permissions() {
return this._permissions;
}
/**
* A signal emitted when the user changes.
*/
get userChanged() {
return this._userChanged;
}
/**
* A signal emitted when there is a connection failure.
*/
get connectionFailure() {
return this._connectionFailure;
}
/**
* Dispose of the resources used by the manager.
*/
dispose() {
this._pollSpecs.dispose();
super.dispose();
}
/**
* Force a refresh of the specs from the server.
*
* @returns A promise that resolves when the specs are fetched.
*
* #### Notes
* This is intended to be called only in response to a user action,
* since the manager maintains its internal state.
*/
async refreshUser() {
await this._pollSpecs.refresh();
await this._pollSpecs.tick;
}
/**
* Execute a request to the server to poll the user and update state.
*/
async requestUser() {
if (this.isDisposed) {
return;
}
const { baseUrl } = this.serverSettings;
const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;
const url = coreutils_1.URLExt.join(baseUrl, SERVICE_USER_URL);
const response = await makeRequest(url, {}, this.serverSettings);
if (response.status !== 200) {
const err = await ResponseError.create(response);
throw err;
}
const oldUser = {
identity: this._identity,
permissions: this._permissions
};
const newUser = await response.json();
const identity = newUser.identity;
// store the color and initials for the user
// this info is not provided by the server
const { localStorage } = window;
const data = localStorage.getItem(SERVICE_ID);
if (data && (!identity.initials || !identity.color)) {
const localUser = JSON.parse(data);
identity.initials =
identity.initials ||
localUser.initials ||
identity.name.substring(0, 1);
identity.color =
identity.color || localUser.color || Private.getRandomColor();
}
if (!coreutils_2.JSONExt.deepEqual(newUser, oldUser)) {
this._identity = identity;
this._permissions = newUser.permissions;
localStorage.setItem(SERVICE_ID, JSON.stringify(identity));
this._userChanged.emit(newUser);
}
}
}
exports.UserManager = UserManager;
/**
* A namespace for module-private functionality.
*
* Note: We do not want to export this function
* to move it to css variables in the Theme.
*/
var Private;
(function (Private) {
/**
* Predefined colors for users
*/
const userColors = [
'var(--jp-collaborator-color1)',
'var(--jp-collaborator-color2)',
'var(--jp-collaborator-color3)',
'var(--jp-collaborator-color4)',
'var(--jp-collaborator-color5)',
'var(--jp-collaborator-color6)',
'var(--jp-collaborator-color7)'
];
/**
* Get a random color from the list of colors.
*/
Private.getRandomColor = () => userColors[Math.floor(Math.random() * userColors.length)];
})(Private || (Private = {}));
//# sourceMappingURL=index.js.map