NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name OctopusEnvFilter
// @namespace https://github.com/EbenZhang/OctopusEnvironmentFilterScript
// @version 0.6
// @description Improve Octopus UI rendering performance by filtering the environments to display
// @include /https?://.*/app.*/
// @license MIT
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addStyle
// @grant GM_registerMenuCommand
// ==/UserScript==
'use strict';
(function () {
const env_config_key = "environments";
const configId = "OctopusEnvFilterConfig";
const env_config_elementId = configId + "_field_" + env_config_key;
var cfg = new GM_configStruct(
{
id: configId,
fields:
{
"environments":
{
label: "Display only environments matches these regular expressions:",
type: 'text',
default: ''
}
},
css: "#" + env_config_elementId + "{ Width : 60em; } .config_var {margin-top: 10px !important;} .field_label {font-weight: inherit !important;font-size: 14px !important;}",
events: {
open: function (doc) {
var config = this;
var envElement = doc.getElementById(env_config_elementId);
envElement.placeholder = "regular expressions, separate by comma, e.g.: Production.*,Staging.*";
}
},
title: "Octopus Environment Filtering Configuration"
});
GM_registerMenuCommand('Configure Octopus Environment Filtering!', function () {
cfg.open();
});
try {
cfg.get(env_config_key);
} catch (error) {
cfg.set(env_config_key, "");
}
function isProjectOverviewPage() {
return window.location.href.match(/https?:\/\/.*\/app#\/Spaces\-\d+\/projects\/.*\/deployments\/?/i)
}
function isProjectResponse(respUrl) {
return respUrl.match(/https?:\/\/.*\/api\/Spaces\-\d+\/progression\/Projects-\/?/i)
}
function isEnvironmentPage() {
return window.location.href.match(/https?:\/\/.*\/app#\/Spaces\-\d+\/infrastructure\/environments/);
}
function isEnvironmentPageResponse(respUrl) {
return respUrl.match(/https?:\/\/.*\/api\/Spaces\-\d+\/environments\/all\/?/i);
}
function isEnvironmentPageSummaryResponse(respUrl) {
return respUrl.match(/https?:\/\/.*\/api\/Spaces\-\d+\/environments\/summary\/?/i);
}
function getEnvRegexes() {
var envsRegexStr = cfg.get(env_config_key);
var envRegexes = envsRegexStr.split(',').map(function (x) { return new RegExp(x, "i"); });
return envRegexes;
}
function modifyResponseForProjectOverviewPage(respText) {
var resp = JSON.parse(respText);
var envRegexes = getEnvRegexes();
var envIds = [];
if (resp.Environments) {
resp.Environments = resp.Environments.filter(function (env) {
return envRegexes.some(function (rx) { return rx.test(env.Name); });
});
console.log("Filtered environments:" + resp.Environments.map(function (x) { return x.Name; }));
envIds = resp.Environments.map(function (x) { return x.Id; });
}
if (resp.ChannelEnvironments) {
for (var channelEnv in resp.ChannelEnvironments) {
resp.ChannelEnvironments[channelEnv] = resp.ChannelEnvironments[channelEnv].filter(function (env) {
return envIds.includes(env.Id);
});
}
}
if (resp.Releases) {
for (var release of resp.Releases) {
if (release.Deployments) {
var envsToDelete = Object.getOwnPropertyNames(release.Deployments).filter(function (r) {
return !envIds.includes(r);
});
for (var del in envsToDelete) {
delete release.Deployments[del];
}
}
if (release.NextDeployments) {
release.NextDeployments = release.NextDeployments.filter(function (dep) {
return envIds.includes(dep);
});
}
}
}
return resp
}
function modifyResponseForEnvironmentsPage(respText) {
var resp = JSON.parse(respText);
var envRegexes = getEnvRegexes();
var newResp = resp.filter(function (env) {
return envRegexes.some(function (rx) {
return rx.test(env.Name);
});
});
return newResp;
}
function modifyResponseForEnvironmentsPageSummary(respText) {
var resp = JSON.parse(respText);
var envRegexes = getEnvRegexes();
resp.EnvironmentSummaries = resp.EnvironmentSummaries.filter(function (summary) {
return envRegexes.some(function (rx) {
return rx.test(summary.Environment.Name);
});
});
return resp;
}
function modifyResponse(response) {
if (!cfg.get(env_config_key)) {
return;
}
if (this.readyState !== 4) {
return;
}
if(!response.target.responseText) return; // octopus web site is a single page app, empty string when navigating inside
var newResp = undefined;
if (isProjectOverviewPage() && isProjectResponse(this.responseURL)) {
newResp = modifyResponseForProjectOverviewPage(response.target.responseText);
}
if (isEnvironmentPage()) {
if (isEnvironmentPageResponse(this.responseURL)) {
newResp = modifyResponseForEnvironmentsPage(response.target.responseText);
} else if (isEnvironmentPageSummaryResponse(this.responseURL)) {
newResp = modifyResponseForEnvironmentsPageSummary(response.target.responseText);
}
}
if (newResp !== undefined) {
Object.defineProperty(this, "responseText", { writable: true });
Object.defineProperty(this, "response", { writable: true });
this.responseText = JSON.stringify(newResp);
this.repsonse = newResp;
}
}
function hookAjaxOpen(originalOpen) {
return function (method, url, async) {
this.addEventListener("readystatechange", modifyResponse);
return originalOpen.apply(this, arguments);
};
}
XMLHttpRequest.prototype.open = hookAjaxOpen(XMLHttpRequest.prototype.open);
})();