@microsoft/windows-admin-center-sdk
Version:
Microsoft - Windows Admin Center Shell
185 lines (183 loc) • 6.8 kB
JavaScript
import { EMPTY, from, Observable } from 'rxjs';
import { expand, filter, map } from 'rxjs/operators';
import { Dom } from '../dom/dom';
import { RpcDialogClient } from '../rpc/dialog/rpc-dialog-client';
import { RpcDialogState, RpcDialogType } from '../rpc/dialog/rpc-dialog-model';
import { RpcOverlayOpenClient } from '../rpc/overlay/rpc-overlay-open-client';
import { RpcReportClient } from '../rpc/report/rpc-report-client';
import { RpcUpdateDataClient } from '../rpc/update-data/rpc-update-data-client';
import { ShellNavigationConnection } from './shell-navigation-connection';
/**
* Frame connection class.
*/
export class FrameConnection {
rpc;
shellNavigationInternal;
/**
* Active dialog origina data.
*/
activeRpcDialogsOrigins;
/**
* Gets the shell navigation functions.
*/
get navigation() {
return this.shellNavigationInternal;
}
/**
* Initializes a new instance of the FrameConnection class.
*
* @param rpc the RPC object.
*/
constructor(rpc) {
this.rpc = rpc;
this.activeRpcDialogsOrigins = new Map();
this.shellNavigationInternal = new ShellNavigationConnection(this.rpc);
}
/**
* Open a choice dialog and wait for completion through RPC.
* To close the dialog before user input, unsubscribe the observable.
*
* @param request the request object of rpc based dialog message.
*/
showDialogChoice(request) {
return this.showDialog(request, RpcDialogType.OpenChoiceDialog);
}
/**
* Open a message dialog and wait for completion through RPC.
* To close the dialog before user input, unsubscribe the observable.
*
* @param request the request object of rpc based dialog message.
*/
showDialogMessage(request) {
return this.showDialog(request, RpcDialogType.OpenMessageDialog);
}
/**
* Open a confirmation dialog and wait for completion through RPC.
* To close the dialog before user input, unsubscribe the observable.
*
* @param request the request object of rpc based dialog confirmation.
*/
showDialogConfirmation(request) {
return this.showDialog(request, RpcDialogType.OpenConfirmationDialog);
}
/**
* Open a confirmation list dialog and wait for completion through RPC.
* To close the dialog before user input, unsubscribe the observable.
*
* @param request the request object of rpc based dialog confirmation list.
*/
showDialogConfirmationList(request) {
return this.showDialog(request, RpcDialogType.OpenConfirmationListDialog);
}
/**
* Call rpc for overlay command and create an observable
* @param overlayData true add overlay, false remove
* @param id id of dialog
*/
overlayOpen(overlayData, id) {
const data = {
overlay: overlayData,
dialogId: id
};
return from(RpcOverlayOpenClient.overlayOpen(this.rpc, data));
}
/**
* Report location change of module to shell.
*/
report(data) {
return RpcReportClient.report(this.rpc, data);
}
/**
* Update data of new connection information to shell.
*
* @param name the module name.
* @param subName the sub name of module.
* @param data the update data object.
* @return Promise<void> the promise object.
*/
updateData(name, subName, data) {
return RpcUpdateDataClient.updateData(this.rpc, name, subName, data);
}
/**
* Open a message dialog and wait for completion through RPC.
*
* @param request the request object of rpc based dialog message.
*/
showDialog(request, type) {
const data = {
dialogId: MsftSme.getUniqueId(),
type: type,
request
};
this.activeRpcDialogsOrigins.set(data.dialogId, document.activeElement);
return new Observable((observer) => {
const subscription = this.openAndLongPolling(data)
.pipe(map((value) => {
switch (value.state) {
case RpcDialogState.Closed:
this.removeActiveDialog(data.dialogId);
observer.next(value.response);
observer.complete();
break;
case RpcDialogState.Failed:
this.removeActiveDialog(data.dialogId);
observer.error(new Error(value.failedMessage));
break;
case RpcDialogState.ForcedTerminated:
this.removeActiveDialog(data.dialogId);
observer.error(new Error('forced terminated'));
break;
}
}))
.subscribe();
return () => {
if (!subscription.closed) {
// sending close request to the shell/dialog if not closed yet.
subscription.unsubscribe();
data.request = null;
data.type = RpcDialogType.Close;
RpcDialogClient.dialog(this.rpc, data);
this.removeActiveDialog(data.dialogId);
}
};
});
}
removeActiveDialog(dialogId) {
if (this.activeRpcDialogsOrigins.has(dialogId)) {
const focusOn = this.activeRpcDialogsOrigins.get(dialogId);
if (focusOn) {
// setTimeout to give the button elements time to update either as disabled or not
setTimeout(() => {
if (focusOn.disabled) {
const nextZoneElement = Dom.getNextZoneElement(focusOn);
if (nextZoneElement) {
nextZoneElement.focus();
}
}
else {
focusOn.focus();
}
});
}
this.activeRpcDialogsOrigins.delete(dialogId);
}
}
openAndLongPolling(data) {
return this.requestDialog(data)
.pipe(expand((result) => {
if (result.state === RpcDialogState.Opened) {
// status polling...
const newData = {
dialogId: data.dialogId,
type: RpcDialogType.PollingStatus
};
return this.requestDialog(newData);
}
return EMPTY;
}), filter(result => result.state !== RpcDialogState.Opened));
}
requestDialog(data) {
return from(RpcDialogClient.dialog(this.rpc, data));
}
}
//# sourceMappingURL=frame-connection.js.map