Add customizable enterprise build
This commit is contained in:
parent
fd8df2a035
commit
ac0f56325b
@ -166,6 +166,7 @@
|
|||||||
"src/resources",
|
"src/resources",
|
||||||
"src/robots.txt",
|
"src/robots.txt",
|
||||||
"src/config.js",
|
"src/config.js",
|
||||||
|
"src/customize.js",
|
||||||
"src/config.template.js"
|
"src/config.template.js"
|
||||||
],
|
],
|
||||||
"styles": [
|
"styles": [
|
||||||
|
32
frontend/custom-sv-config.json
Normal file
32
frontend/custom-sv-config.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"theme": "contrast",
|
||||||
|
"enterprise": "elsalvador",
|
||||||
|
"dashboard": {
|
||||||
|
"widgets": [
|
||||||
|
{
|
||||||
|
"component": "fees"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"component": "balance",
|
||||||
|
"props": {
|
||||||
|
"address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"component": "goggles"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"component": "address",
|
||||||
|
"props": {
|
||||||
|
"address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"component": "blocks"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"component": "transactions"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ const { spawnSync } = require('child_process');
|
|||||||
const CONFIG_FILE_NAME = 'mempool-frontend-config.json';
|
const CONFIG_FILE_NAME = 'mempool-frontend-config.json';
|
||||||
const GENERATED_CONFIG_FILE_NAME = 'src/resources/config.js';
|
const GENERATED_CONFIG_FILE_NAME = 'src/resources/config.js';
|
||||||
const GENERATED_TEMPLATE_CONFIG_FILE_NAME = 'src/resources/config.template.js';
|
const GENERATED_TEMPLATE_CONFIG_FILE_NAME = 'src/resources/config.template.js';
|
||||||
|
const GENERATED_CUSTOMIZATION_FILE_NAME = 'src/resources/customize.js';
|
||||||
|
|
||||||
let settings = [];
|
let settings = [];
|
||||||
let configContent = {};
|
let configContent = {};
|
||||||
@ -109,6 +110,23 @@ writeConfigTemplate(GENERATED_TEMPLATE_CONFIG_FILE_NAME, newConfigTemplate);
|
|||||||
|
|
||||||
const currentConfig = readConfig(GENERATED_CONFIG_FILE_NAME);
|
const currentConfig = readConfig(GENERATED_CONFIG_FILE_NAME);
|
||||||
|
|
||||||
|
let customConfigJs = '';
|
||||||
|
if (configContent && configContent.CUSTOMIZATION) {
|
||||||
|
const customConfig = readConfig(configContent.CUSTOMIZATION);
|
||||||
|
if (customConfig) {
|
||||||
|
console.log(`Customizing frontend using ${configContent.CUSTOMIZATION}`);
|
||||||
|
customConfigJs = `(function (window) {
|
||||||
|
window.__env = window.__env || {};
|
||||||
|
window.__env.customize = ${customConfig};
|
||||||
|
}((typeof global !== 'undefined') ? global : this));
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
throw new Error('Failed to load customization file');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeConfig(GENERATED_CUSTOMIZATION_FILE_NAME, customConfigJs);
|
||||||
|
|
||||||
if (currentConfig && currentConfig === newConfig) {
|
if (currentConfig && currentConfig === newConfig) {
|
||||||
console.log(`No configuration updates, skipping ${GENERATED_CONFIG_FILE_NAME} file update`);
|
console.log(`No configuration updates, skipping ${GENERATED_CONFIG_FILE_NAME} file update`);
|
||||||
return;
|
return;
|
||||||
|
@ -23,7 +23,7 @@ export class EnterpriseService {
|
|||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
private activatedRoute: ActivatedRoute,
|
private activatedRoute: ActivatedRoute,
|
||||||
) {
|
) {
|
||||||
const subdomain = this.document.location.hostname.indexOf(this.exclusiveHostName) > -1
|
const subdomain = this.stateService.env.customize.enterprise || this.document.location.hostname.indexOf(this.exclusiveHostName) > -1
|
||||||
&& this.document.location.hostname.split(this.exclusiveHostName)[0] || false;
|
&& this.document.location.hostname.split(this.exclusiveHostName)[0] || false;
|
||||||
if (subdomain && subdomain.match(/^[A-z0-9-_]+$/)) {
|
if (subdomain && subdomain.match(/^[A-z0-9-_]+$/)) {
|
||||||
this.subdomain = subdomain;
|
this.subdomain = subdomain;
|
||||||
|
@ -20,6 +20,17 @@ export interface MarkBlockState {
|
|||||||
|
|
||||||
export interface ILoadingIndicators { [name: string]: number; }
|
export interface ILoadingIndicators { [name: string]: number; }
|
||||||
|
|
||||||
|
export interface Customization {
|
||||||
|
theme: string;
|
||||||
|
enterprise?: string;
|
||||||
|
dashboard: {
|
||||||
|
widgets: {
|
||||||
|
component: string;
|
||||||
|
props: { [key: string]: any };
|
||||||
|
}[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface Env {
|
export interface Env {
|
||||||
TESTNET_ENABLED: boolean;
|
TESTNET_ENABLED: boolean;
|
||||||
SIGNET_ENABLED: boolean;
|
SIGNET_ENABLED: boolean;
|
||||||
@ -50,6 +61,7 @@ export interface Env {
|
|||||||
ADDITIONAL_CURRENCIES: boolean;
|
ADDITIONAL_CURRENCIES: boolean;
|
||||||
GIT_COMMIT_HASH_MEMPOOL_SPACE?: string;
|
GIT_COMMIT_HASH_MEMPOOL_SPACE?: string;
|
||||||
PACKAGE_JSON_VERSION_MEMPOOL_SPACE?: string;
|
PACKAGE_JSON_VERSION_MEMPOOL_SPACE?: string;
|
||||||
|
customize?: Customization;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultEnv: Env = {
|
const defaultEnv: Env = {
|
||||||
|
@ -2,6 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { Subject } from 'rxjs';
|
import { Subject } from 'rxjs';
|
||||||
import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants';
|
import { defaultMempoolFeeColors, contrastMempoolFeeColors } from '../app.constants';
|
||||||
import { StorageService } from './storage.service';
|
import { StorageService } from './storage.service';
|
||||||
|
import { StateService } from './state.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@ -14,8 +15,9 @@ export class ThemeService {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private storageService: StorageService,
|
private storageService: StorageService,
|
||||||
|
private stateService: StateService,
|
||||||
) {
|
) {
|
||||||
const theme = this.storageService.getValue('theme-preference') || 'default';
|
const theme = this.storageService.getValue('theme-preference') || this.stateService.env.customize?.theme || 'default';
|
||||||
this.apply(theme);
|
this.apply(theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>mempool - Bitcoin Explorer</title>
|
<title>mempool - Bitcoin Explorer</title>
|
||||||
<script src="/resources/config.js"></script>
|
<script src="/resources/config.js"></script>
|
||||||
|
<script src="/resources/customize.js"></script>
|
||||||
<base href="/">
|
<base href="/">
|
||||||
|
|
||||||
<meta name="description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
|
<meta name="description" content="Explore the full Bitcoin ecosystem with The Mempool Open Source Project®. See the real-time status of your transactions, get network info, and more." />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user