mirror of
https://github.com/OutlineFoundation/outline-server.git
synced 2026-08-04 14:37:34 +00:00
Add types to Javascript
This commit is contained in:
parent
c02fdec396
commit
e152d80f6d
7 changed files with 113 additions and 39 deletions
|
|
@ -21,7 +21,9 @@ import {Surveys} from '../model/survey';
|
|||
|
||||
import {App} from './app';
|
||||
import {TokenManager} from './digitalocean_oauth';
|
||||
import {DisplayServer, DisplayServerRepository, makeDisplayServer} from './display_server';
|
||||
import {DisplayServerRepository, makeDisplayServer} from './display_server';
|
||||
import {AppRoot, DisplayServer} from './ui_components/app-root.js';
|
||||
import {ServerView} from './ui_components/outline-server-view.js';
|
||||
|
||||
const TOKEN_WITH_NO_SERVERS = 'no-server-token';
|
||||
const TOKEN_WITH_ONE_SERVER = 'one-server-token';
|
||||
|
|
@ -257,11 +259,12 @@ enum AppRootScreen {
|
|||
DIALOG
|
||||
}
|
||||
|
||||
class FakePolymerAppRoot implements polymer.Base {
|
||||
class FakePolymerAppRoot extends AppRoot {
|
||||
events = new EventEmitter();
|
||||
backgroundScreen = AppRootScreen.NONE;
|
||||
currentScreen = AppRootScreen.NONE;
|
||||
serverView = {setServerTransferredData: () => {}, serverId: '', initHelpBubbles: () => {}};
|
||||
serverView = {setServerTransferredData: () => {}, serverId: '', initHelpBubbles: () => {}} as
|
||||
unknown as ServerView;
|
||||
serverList: DisplayServer[] = [];
|
||||
is: 'fake-polymer-app-root';
|
||||
|
||||
|
|
@ -304,7 +307,7 @@ class FakePolymerAppRoot implements polymer.Base {
|
|||
this.backgroundScreen = AppRootScreen.NONE;
|
||||
}
|
||||
|
||||
getServerView() {
|
||||
getServerView(serverId: string): ServerView {
|
||||
return this.serverView;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,12 @@ import {Surveys} from '../model/survey';
|
|||
|
||||
import {TokenManager} from './digitalocean_oauth';
|
||||
import * as digitalocean_server from './digitalocean_server';
|
||||
import {DisplayServer, DisplayServerRepository, makeDisplayServer} from './display_server';
|
||||
import {DisplayServerRepository, makeDisplayServer} from './display_server';
|
||||
import {parseManualServerConfig} from './management_urls';
|
||||
|
||||
import {AppRoot, DisplayServer} from './ui_components/app-root.js';
|
||||
import {ServerView} from './ui_components/outline-server-view.js';
|
||||
|
||||
// The Outline DigitalOcean team's referral code:
|
||||
// https://www.digitalocean.com/help/referral-program/
|
||||
const UNUSED_DIGITALOCEAN_REFERRAL_CODE = '5ddb4219b716';
|
||||
|
|
@ -99,7 +102,7 @@ async function computeDefaultAccessKeyDataLimit(
|
|||
}
|
||||
}
|
||||
|
||||
async function showHelpBubblesOnce(serverView: polymer.Base) {
|
||||
async function showHelpBubblesOnce(serverView: ServerView) {
|
||||
if (!window.localStorage.getItem('addAccessKeyHelpBubble-dismissed')) {
|
||||
await serverView.showAddAccessKeyHelpBubble();
|
||||
window.localStorage.setItem('addAccessKeyHelpBubble-dismissed', 'true');
|
||||
|
|
@ -137,7 +140,7 @@ export class App {
|
|||
private serverBeingCreated: server.ManagedServer;
|
||||
|
||||
constructor(
|
||||
private appRoot: polymer.Base, private readonly version: string,
|
||||
private appRoot: AppRoot, private readonly version: string,
|
||||
private createDigitalOceanSession: DigitalOceanSessionFactory,
|
||||
private createDigitalOceanServerRepository: DigitalOceanServerRepositoryFactory,
|
||||
private manualServerRepository: server.ManualServerRepository,
|
||||
|
|
@ -565,7 +568,7 @@ export class App {
|
|||
});
|
||||
} else {
|
||||
// Display the unreachable server state within the server view.
|
||||
const serverView = this.appRoot.getServerView(displayServer.id);
|
||||
const serverView = this.appRoot.getServerView(displayServer.id) as ServerView;
|
||||
serverView.isServerReachable = false;
|
||||
serverView.isServerManaged = isManagedServer(server);
|
||||
serverView.serverName = displayServer.name; // Don't get the name from the remote server.
|
||||
|
|
@ -892,7 +895,7 @@ export class App {
|
|||
this.showTransferStats(selectedServer, view);
|
||||
}
|
||||
|
||||
private showMetricsOptInWhenNeeded(selectedServer: server.Server, serverView: polymer.Base) {
|
||||
private showMetricsOptInWhenNeeded(selectedServer: server.Server, serverView: ServerView) {
|
||||
const showMetricsOptInOnce = () => {
|
||||
// Sanity check to make sure the running server is still displayed, i.e.
|
||||
// it hasn't been deleted.
|
||||
|
|
@ -922,7 +925,7 @@ export class App {
|
|||
}
|
||||
}
|
||||
|
||||
private async refreshTransferStats(selectedServer: server.Server, serverView: polymer.Base) {
|
||||
private async refreshTransferStats(selectedServer: server.Server, serverView: ServerView) {
|
||||
try {
|
||||
const stats = await selectedServer.getDataUsage();
|
||||
let totalBytes = 0;
|
||||
|
|
@ -963,7 +966,7 @@ export class App {
|
|||
}
|
||||
}
|
||||
|
||||
private showTransferStats(selectedServer: server.Server, serverView: polymer.Base) {
|
||||
private showTransferStats(selectedServer: server.Server, serverView: ServerView) {
|
||||
this.refreshTransferStats(selectedServer, serverView);
|
||||
// Get transfer stats once per minute for as long as server is selected.
|
||||
const statsRefreshRateMs = 60 * 1000;
|
||||
|
|
@ -1224,7 +1227,8 @@ export class App {
|
|||
this.appRoot.showError(this.appRoot.localize('error-server-rename'));
|
||||
const oldName = this.selectedServer.getName();
|
||||
view.serverName = oldName;
|
||||
view.$.serverSettings.serverName = oldName;
|
||||
// tslint:disable-next-line:no-any
|
||||
(view.$.serverSettings as any).serverName = oldName;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,7 @@
|
|||
// limitations under the License.
|
||||
|
||||
import * as server from '../model/server';
|
||||
|
||||
export interface DisplayServer {
|
||||
id: string;
|
||||
name: string;
|
||||
isManaged: boolean;
|
||||
isSynced?: boolean;
|
||||
}
|
||||
import {DisplayServer} from './ui_components/app-root.js';
|
||||
|
||||
// Returns a `DisplayServer` corresponding to `server`.
|
||||
export async function makeDisplayServer(server: server.Server) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import * as digitalocean_server from './digitalocean_server';
|
|||
import {DisplayServerRepository} from './display_server';
|
||||
import {ManualServerRepository} from './manual_server';
|
||||
import {DEFAULT_PROMPT_IMPRESSION_DELAY_MS, OutlineSurveys} from './survey';
|
||||
import {AppRoot} from './ui_components/app-root.js';
|
||||
|
||||
const SUPPORTED_LANGUAGES: {[key: string]: {id: string, dir: string}} = {
|
||||
'am': {id: 'am', dir: 'ltr'},
|
||||
|
|
@ -101,7 +102,7 @@ document.addEventListener('WebComponentsReady', () => {
|
|||
document.documentElement.setAttribute('dir', languageDirection);
|
||||
// NOTE: this cast is safe and allows us to leverage Polymer typings since we haven't migrated to
|
||||
// Polymer 3, which adds typescript support.
|
||||
const appRoot = document.getElementById('appRoot') as unknown as polymer.Base;
|
||||
const appRoot = document.getElementById('appRoot') as unknown as AppRoot;
|
||||
appRoot.setLanguage(language.string(), languageDirection);
|
||||
new App(
|
||||
appRoot, version, digitalocean_api.createDigitalOceanSession,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import './outline-manual-server-entry.js';
|
|||
import './outline-modal-dialog.js';
|
||||
import './outline-region-picker-step.js';
|
||||
import './outline-server-progress-step.js';
|
||||
import './outline-server-view.js';
|
||||
import './outline-tos-view.js';
|
||||
|
||||
import {AppLocalizeBehavior} from '@polymer/app-localize-behavior/app-localize-behavior.js';
|
||||
|
|
@ -44,9 +43,20 @@ import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js';
|
|||
import {html} from '@polymer/polymer/lib/utils/html-tag.js';
|
||||
import {PolymerElement} from '@polymer/polymer/polymer-element.js';
|
||||
|
||||
import {ServerView} from './outline-server-view.js';
|
||||
|
||||
const TOS_ACK_LOCAL_STORAGE_KEY = 'tos-ack';
|
||||
|
||||
class AppRoot extends mixinBehaviors
|
||||
/**
|
||||
* A server to be displayed
|
||||
* @typedef {Object} DisplayServer
|
||||
* @property {string} id - The id of the server
|
||||
* @property {string} name - The display name of the server
|
||||
* @property {boolean} isManaged - Whether the server host is managed by the Outline Manager
|
||||
* @property {boolean=} isSynced - Whether the server information is updated
|
||||
*/
|
||||
|
||||
export class AppRoot extends mixinBehaviors
|
||||
([AppLocalizeBehavior], PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
|
|
@ -522,6 +532,8 @@ class AppRoot extends mixinBehaviors
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
/** @type {DisplayServer} */
|
||||
this.selectedServer = undefined;
|
||||
this.addEventListener('RegionSelected', this.handleRegionSelected);
|
||||
this.addEventListener(
|
||||
'SetUpGenericCloudProviderRequested', this.handleSetUpGenericCloudProviderRequested);
|
||||
|
|
@ -530,6 +542,11 @@ class AppRoot extends mixinBehaviors
|
|||
this.addEventListener('ManualServerEntryCancelled', this.handleManualCancelled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the language and direction for the application
|
||||
* @param {string} newLanguage
|
||||
* @param {string} langDir
|
||||
*/
|
||||
setLanguage(newLanguage, langDir) {
|
||||
const messagesUrl = `./messages/${newLanguage}.json`;
|
||||
this.loadResources(messagesUrl, newLanguage);
|
||||
|
|
@ -585,6 +602,11 @@ class AppRoot extends mixinBehaviors
|
|||
this.currentPage = 'serverView';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ServerView for the server given by its id
|
||||
* @param {string} displayServerId
|
||||
* @returns {ServerView}
|
||||
*/
|
||||
getServerView(displayServerId) {
|
||||
if (!displayServerId) {
|
||||
return null;
|
||||
|
|
@ -629,6 +651,11 @@ class AppRoot extends mixinBehaviors
|
|||
this.showToast(message, durationMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a toast with a message
|
||||
* @param {string} message
|
||||
* @param {number} duration in seconds
|
||||
*/
|
||||
showToast(message, duration) {
|
||||
const toast = this.$.toast;
|
||||
toast.close();
|
||||
|
|
|
|||
|
|
@ -55,6 +55,23 @@ function makePublicEvent(eventName, detail) {
|
|||
return new CustomEvent(eventName, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* An access key to be displayed
|
||||
* @typedef {Object} DisplayAccessKey
|
||||
* @prop {string} id
|
||||
* @prop {string} placeholderName
|
||||
* @prop {string} name
|
||||
* @prop {string} accessUrl
|
||||
* @prop {number} transferredBytes
|
||||
* @prop {number} relativeTraffic
|
||||
*/
|
||||
|
||||
/**
|
||||
* An access key data limit
|
||||
* @typedef {Object} DataLimit
|
||||
* @readonly @prop {number} bytes
|
||||
*/
|
||||
|
||||
export class ServerView extends DirMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
|
|
@ -629,23 +646,50 @@ export class ServerView extends DirMixin(PolymerElement) {
|
|||
];
|
||||
}
|
||||
|
||||
// Parameter `accessKey` has the format {
|
||||
// id: string,
|
||||
// placeholderName: string,
|
||||
// name: string,
|
||||
// accessUrl: string,
|
||||
// transferredBytes: number;
|
||||
// relativeTraffic: number;
|
||||
// }
|
||||
addAccessKey(accessKey) {
|
||||
// TODO(fortuna): Restore loading animation.
|
||||
// TODO(fortuna): Restore highlighting.
|
||||
this.push('accessKeyRows', accessKey);
|
||||
// Force render the access key list so that the input is present in the DOM
|
||||
this.$.accessKeysContainer.querySelector('dom-repeat').render();
|
||||
const input = this.shadowRoot.querySelector(`#access-key-${accessKey.id}`);
|
||||
input.select();
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.serverId = '';
|
||||
this.serverName = '';
|
||||
this.serverHostname = '';
|
||||
this.serverVersion = '';
|
||||
this.isHostnameEditable = false;
|
||||
this.serverManagementApiUrl = '';
|
||||
/** @type {number} */
|
||||
this.serverPortForNewAccessKeys = null;
|
||||
this.isAccessKeyPortEditable = false;
|
||||
this.serverCreationDate = '';
|
||||
this.serverLocation = '';
|
||||
/** @type {DataLimit} */
|
||||
this.accessKeyDataLimit = null;
|
||||
this.isAccessKeyDataLimitEnabled = false;
|
||||
this.supportsAccessKeyDataLimit = false;
|
||||
this.dataLimitsAvailabilityDate = '';
|
||||
this.isServerManaged = false;
|
||||
this.isServerReachable = false;
|
||||
/** @type {Function} */
|
||||
this.retryDisplayingServer = null;
|
||||
// myConnection: Object,
|
||||
this.totalInboundBytes = 0;
|
||||
/** @type {DisplayAccessKey[]} */
|
||||
this.accessKeyRows = [];
|
||||
this.hasNonAdminAccessKeys = false;
|
||||
this.metricsEnabled = true;
|
||||
this.monthlyOutboundTransferBytes = 0;
|
||||
this.monthlyCost = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {DisplayAccessKey} accessKey
|
||||
*/
|
||||
addAccessKey(accessKey) {
|
||||
// TODO(fortuna): Restore loading animation.
|
||||
// TODO(fortuna): Restore highlighting.
|
||||
this.push('accessKeyRows', accessKey);
|
||||
// Force render the access key list so that the input is present in the DOM
|
||||
this.$.accessKeysContainer.querySelector('dom-repeat').render();
|
||||
const input = this.shadowRoot.querySelector(`#access-key-${accessKey.id}`);
|
||||
input.select();
|
||||
}
|
||||
|
||||
removeAccessKey(accessKeyId) {
|
||||
for (let ui in this.accessKeyRows) {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
"outDir": "build/server_manager/web_app/js",
|
||||
"sourceMap": true,
|
||||
"experimentalDecorators":true,
|
||||
"allowJs": true,
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue