c0ckp1t 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Config.mjs ADDED
@@ -0,0 +1,248 @@
1
+ import {deepMerge, DEFAULTS} from "CoreUtils";
2
+ /**
3
+ * Configuration Factory for C0ckp1t Applications
4
+ *
5
+ * Usage:
6
+ * import { createConfig } from './Config.mjs';
7
+ *
8
+ * // Local mode (all defaults)
9
+ * const config = createConfig();
10
+ *
11
+ * // CDN mode
12
+ * const config = createConfig({
13
+ * appEndpoint: "https://cdn.jsdelivr.net/npm/c0ckp1t@latest"
14
+ * });
15
+ *
16
+ * // Custom instance
17
+ * const config = createConfig({
18
+ * instanceId: "myapp",
19
+ * appName: "My App",
20
+ * isDev: false,
21
+ * });
22
+ */
23
+ // ________________________________________________________________________________
24
+ // Default Nav Tree Builder
25
+ // ________________________________________________________________________________
26
+ function buildNavTree(instanceId) {
27
+ return {
28
+ icon: "fa-house",
29
+ depth: 0,
30
+ endpoint: "/",
31
+ isLeaf: false,
32
+ isRoot: true,
33
+ name: "",
34
+ path: [],
35
+ children: [
36
+ {
37
+ depth: 1,
38
+ endpoint: `/${instanceId}/connections`,
39
+ isLeaf: true,
40
+ isRoot: false,
41
+ path: ["connections"],
42
+ name: "Connections",
43
+ children: []
44
+ },
45
+ {
46
+ depth: 1,
47
+ endpoint: `/${instanceId}/cache`,
48
+ isLeaf: true,
49
+ isRoot: false,
50
+ path: ["cache"],
51
+ name: "Cache",
52
+ children: []
53
+ },
54
+ {
55
+ icon: "fa-network-wired",
56
+ depth: 1,
57
+ endpoint: `/${instanceId}/traffic`,
58
+ isLeaf: true,
59
+ isRoot: false,
60
+ path: ["traffic"],
61
+ name: "Traffic",
62
+ children: []
63
+ },
64
+ {
65
+ icon: "fa-bell",
66
+ depth: 1,
67
+ endpoint: `/${instanceId}/notifies`,
68
+ isLeaf: true,
69
+ isRoot: false,
70
+ path: ["notifies"],
71
+ name: "Notifies",
72
+ children: []
73
+ },
74
+ {
75
+ icon: "fa-info",
76
+ depth: 1,
77
+ endpoint: `/${instanceId}/docs`,
78
+ isLeaf: true,
79
+ isRoot: false,
80
+ path: ["docs"],
81
+ name: "Documentation",
82
+ children: []
83
+ },
84
+ {
85
+ icon: "fa-info",
86
+ depth: 1,
87
+ endpoint: `/${instanceId}/components`,
88
+ isLeaf: true,
89
+ isRoot: false,
90
+ path: ["components"],
91
+ name: "Components",
92
+ children: [
93
+ {
94
+ icon: "fa-info",
95
+ depth: 2,
96
+ endpoint: `/${instanceId}/components/bootstrap`,
97
+ isLeaf: true,
98
+ isRoot: false,
99
+ path: ["bootstrap"],
100
+ name: "Bootstrap",
101
+ children: []
102
+ },
103
+ {
104
+ icon: "fa-info",
105
+ depth: 2,
106
+ endpoint: `/${instanceId}/components/basic`,
107
+ isLeaf: true,
108
+ isRoot: false,
109
+ path: ["basic"],
110
+ name: "Basic",
111
+ children: []
112
+ },
113
+ {
114
+ icon: "fa-info",
115
+ depth: 2,
116
+ endpoint: `/${instanceId}/components/advanced`,
117
+ isLeaf: true,
118
+ isRoot: false,
119
+ path: ["advanced"],
120
+ name: "Advanced",
121
+ children: []
122
+ },
123
+ {
124
+ icon: "fa-info",
125
+ depth: 2,
126
+ endpoint: `/${instanceId}/components/theme`,
127
+ isLeaf: true,
128
+ isRoot: false,
129
+ path: ["theme"],
130
+ name: "Theme",
131
+ children: []
132
+ },
133
+ ]
134
+ }
135
+ ]
136
+ };
137
+ }
138
+
139
+ // ________________________________________________________________________________
140
+ // Routes Builder
141
+ // ________________________________________________________________________________
142
+ function buildRoutes(instanceId = "default", prefix = "") {
143
+ return [
144
+ { path: '/', name: 'root', children: [
145
+ {path: '', redirect: `/${instanceId}/docs/Introduction.md`},
146
+ {path: `${instanceId}`, children: [
147
+ {path: 'docs', redirect: `/${instanceId}/docs/Introduction.md`},
148
+ {path: 'docs/:pathMatch(.*)*', location: `${prefix}/core/pages/Documentation.vue`},
149
+ {path: 'connections', location: `${prefix}/core/pages/Connections.vue`},
150
+ {path: 'connections/:id', location: `${prefix}/core/pages/Connection.vue`},
151
+ {path: 'cache', location: `${prefix}/core/pages/Cache.vue`},
152
+ {path: 'traffic', location: `${prefix}/core/pages/Traffic.vue`},
153
+ {path: 'notifies', location: `${prefix}/core/pages/Notifies.vue`},
154
+ {path: 'components', location: `${prefix}/core/pages/frontend/Components.vue`, children: [
155
+ {path: 'basic', location: `${prefix}/core/pages/frontend/ComponentsBasic.vue`},
156
+ {path: 'advanced', location: `${prefix}/core/pages/frontend/ComponentsAdv.vue`},
157
+ {path: 'theme', location: `${prefix}/core/pages/frontend/Theme.vue`},
158
+ {path: 'bootstrap', location: `${prefix}/core/pages/frontend/Bootstrap.vue`},
159
+ ]},
160
+ ]}
161
+ ] },
162
+ { path: '/:pathMatch(.*)*', name: '404', location: `${prefix}/core/Page404.vue` }
163
+ ];
164
+ }
165
+
166
+ // ________________________________________________________________________________
167
+ // Components
168
+ // ________________________________________________________________________________
169
+ /**
170
+ * Return the default Vue components
171
+ * using sha1 hashes
172
+ * @returns {Object}
173
+ */
174
+ export function defaultVueComponents(prefix = "") {
175
+ return {
176
+ ExecButton: { path: `${prefix}/components/ExecButton.vue`, hash: `97e3d2ce89808c5a69f41404e1337f743015f0cc` },
177
+ XInput: { path: `${prefix}/components/xinput.vue`, hash: `cd47d7d038316367df6fd7e265aa3625b72a7777` },
178
+ XInput2: { path: `${prefix}/components/xinput2.vue`, hash: `320e52ac991baebded7c2a9f52a4cfc2cde47b55` },
179
+ XLabel: { path: `${prefix}/components/xlabel.vue`, hash: `90a9837aa8e06f1d3a5b7601337afd78a872d181` },
180
+ XDropdown: { path: `${prefix}/components/xdropdown.vue`, hash: `52b29b72fd6512eefccd9caa76e26dd91d9f9f9e` },
181
+ XDropdown2: { path: `${prefix}/components/xdropdown2.vue`, hash: `e7b163eda42fb7e1a6f07b011c423f8f275eb65d` },
182
+ XSection: { path: `${prefix}/components/xsection.vue`, hash: `27285d606f57d13f80156bb11cd34449f88df950` },
183
+ XTableOpen: { path: `${prefix}/components/xtable-open.vue`, hash: `a1b9a4f670817978022a4c596e2e2f89dd4568c2` },
184
+ XCollapse: { path: `${prefix}/components/xcollapse.vue`, hash: `ba1479bd1080a4fa5abdf6c91c7328ae679f78e6` },
185
+ XToggle: { path: `${prefix}/components/xtoggle.vue`, hash: `2f6871d2d3069ac8f35b6bf76de6c2109f42d9d1` },
186
+ XToggle3: { path: `${prefix}/components/xtoggle3.vue`, hash: `61d0464e6ed9983e817eb0cde928dceb7c0fdc75` },
187
+ XCheck: { path: `${prefix}/components/xcheck.vue`, hash: `ee0d6b30600fb41589123f6d66f2791f1332d4f7` },
188
+ XCheckbox: { path: `${prefix}/components/xcheckbox.vue`, hash: `a290c0cbb7bffce83c235dd5a1c98ed9c441a5b0` },
189
+ XTextarea: { path: `${prefix}/components/xtextarea.vue`, hash: `f8bb08419082aa5443630ab07172674b50c7a248` },
190
+ XHidden: { path: `${prefix}/components/xhidden.vue`, hash: `ecb396e12dd894040e715c0854275e4d5016fcb9` },
191
+ XCode: { path: `${prefix}/components/xcode.vue`, hash: `4d9d9165fea0539c9a983fcdffae8dedcfd537ae` },
192
+ XButton: { path: `${prefix}/components/xbutton.vue`, hash: `2e956caa47e46377ea5a809f7438d0fc38be73b9` },
193
+ XTabs: { path: `${prefix}/components/xtabs.vue`, hash: `83dc219106bdc86ae86dcd16cf95ebd7f11bc952` },
194
+ XKv: { path: `${prefix}/components/xkv.vue`, hash: `8951d3a5e3786cfc9c705b13c1f71e3f90dd2552` },
195
+ XNav: { path: `${prefix}/components/xnav.vue`, hash: `8d51c73e5716deed3577652e362c50526ddbe4e1` },
196
+ XMap: { path: `${prefix}/components/xmap.vue`, hash: `daee357d9e2ef96df0166dd7add0339d46a1cc01` },
197
+ XList: { path: `${prefix}/components/xlist.vue`, hash: `217ced04a333238d169c300a721b75f0ddd5e95b` },
198
+ XJson: { path: `${prefix}/components/xjson.vue`, hash: `0a3ef6265b4070b0f002d659776c02756cc1da5a` },
199
+ XCard: { path: `${prefix}/components/xcard.vue`, hash: `de3fbb23ae7b00d4c90a717dd361cb9315e9ded6` },
200
+ XCardH: { path: `${prefix}/components/xcard-h.vue`, hash: `de4d42f1056c5d2b8431f15e6b1180d9f9898ac2` },
201
+ XColor: { path: `${prefix}/components/xcolor.vue`, hash: `9bf9497ff66e213277f17af290c21c0a35752510` },
202
+ "v-ace-editor": { path: `${prefix}/components/vue3-ace-editor.vue`, hash: `70ce4a39152af5cf0f7cb6b1d4fdafc8b6225edc` },
203
+ XMarkdown: { path: `${prefix}/components/xmarkdown.vue`, hash: `15f835547fab8a8c8aad47d72640c8e918a7b9da` },
204
+ XSound: { path: `${prefix}/components/xsound.vue`, hash: `3e8ad4aa3c767f757dd49b99aa6f961547caf970` },
205
+ XUpload: { path: `${prefix}/components/xupload.vue`, hash: `7a872277e0047fca11e950efe08f2bffa670abdb` },
206
+ XTree: { path: `${prefix}/components/xtree.vue`, hash: `3b6534e86996c48ab05072a9b793ecc78d83a0eb` },
207
+ CodeMirror: { path: `${prefix}/components/code-mirror.vue`, hash: `3ce1028adb75831e01c4264d5764c14f60a1bd00` },
208
+ XTerminal: { path: `${prefix}/components/xterminal.vue`, hash: `1c01f92c0a08bd4937f9768a1d49f12a9a84feea` },
209
+ }
210
+ }
211
+
212
+
213
+ // ________________________________________________________________________________
214
+ // Factory
215
+ // ________________________________________________________________________________
216
+ /**
217
+ * Create a C0ckp1t configuration object.
218
+ *
219
+ * @param {Object} overrides - Properties to override.
220
+ * @returns {Object} The configuration object.
221
+ */
222
+ export function createConfig(overrides = {}) {
223
+ // 1. Separate root/routes from scalar overrides so deepMerge handles scalars
224
+ const { root: rootOverride, components: componentsOverride, routes: routesOverride, ...scalarOverrides } = overrides;
225
+
226
+ // 2. Merge scalar defaults with overrides
227
+ const merged = deepMerge(DEFAULTS, scalarOverrides);
228
+
229
+ // 3. Resolve the key variables that nav/routes depend on
230
+ const { instanceId, routePrefix, componentPrefix } = merged;
231
+
232
+ // 4. Build or use provided root nav tree
233
+ const root = rootOverride !== undefined ? rootOverride : buildNavTree(instanceId);
234
+
235
+ // 5. Build or use provided routes
236
+ const routes = routesOverride !== undefined ? routesOverride : buildRoutes(instanceId, routePrefix);
237
+
238
+ const components = componentsOverride !== undefined ? componentsOverride : defaultVueComponents(componentPrefix);
239
+ // 6. Assemble final config
240
+ return {
241
+ ...merged,
242
+ root,
243
+ routes,
244
+ components
245
+ };
246
+ }
247
+
248
+ export default createConfig;
package/README.md CHANGED
@@ -45,12 +45,15 @@ tar -zxvf c0ckp1t-1.0.2.tgz
45
45
  # package/js_ext/Makefile
46
46
  # package/css/bootstrap-c0ckp1t.css
47
47
  # ...
48
+
49
+ # to expand to webroot directory
50
+ tar -zxvf c0ckp1t-1.0.2.tgz --strip-components=1 -C webroot
48
51
  ```
49
52
 
50
53
 
51
54
  ## Releases
52
55
 
53
- * 1.0.10 - Beta: fixing cdn index-cdn.html making sure it works with jsfiddle.net
56
+ * 1.0.12 - Beta: fixing cdn index-cdn.html making sure it works with jsfiddle.net
54
57
  * Had to publish many times to get CDN working with different configurations
55
58
  * 1.0.2 - Beta: fixing cdn index-cdn.html example
56
59
  * 1.0.1 - Beta: removing `Constants.mjs` dependencies
@@ -73,6 +73,9 @@ let _ro = null;
73
73
  let _contentBackup = '';
74
74
  let _isSettingContent = false;
75
75
 
76
+ let _mounted = false;
77
+ let _initAborted = false;
78
+
76
79
  // CodeMirror modules - loaded dynamically
77
80
  let EditorView = null;
78
81
  let EditorState = null;
@@ -215,6 +218,12 @@ watch(() => local.currentReadonly, (val) => {
215
218
  });
216
219
 
217
220
  onMounted(async () => {
221
+ _mounted = true;
222
+ // --- guard helper ---
223
+ const alive = () => _mounted && root.value != null;
224
+ if (!alive()) return;
225
+
226
+
218
227
  // Load core CodeMirror modules
219
228
  const [stateModule, viewModule, basicSetupModule] = await Promise.all([
220
229
  import('https://esm.sh/@codemirror/state'),
@@ -222,6 +231,9 @@ onMounted(async () => {
222
231
  import('https://esm.sh/codemirror'),
223
232
  ]);
224
233
 
234
+ // Bail if component unmounted during async load
235
+ if (!alive()) return;
236
+
225
237
  EditorState = stateModule.EditorState;
226
238
  Compartment = stateModule.Compartment;
227
239
  EditorView = viewModule.EditorView;
@@ -239,6 +251,9 @@ onMounted(async () => {
239
251
  getThemeExtension(props.theme),
240
252
  ]);
241
253
 
254
+ // Bail again after second async gap
255
+ if (!alive()) return;
256
+
242
257
  const extensions = [
243
258
  basicSetup,
244
259
  languageCompartment.of(langExt),
@@ -301,14 +316,14 @@ onMounted(async () => {
301
316
  });
302
317
 
303
318
  onBeforeUnmount(() => {
304
- if (_ro) {
305
- _ro.disconnect();
306
- _ro = null;
307
- }
308
- if (_editor) {
309
- _editor.destroy();
310
- _editor = null;
311
- }
319
+ _mounted = false;
320
+
321
+ _ro?.disconnect();
322
+ _ro = null;
323
+
324
+ _editor?.destroy();
325
+ _editor = null;
326
+
312
327
  });
313
328
 
314
329
  // Public methods
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # tools.sh - Compute the SHA-1 hash of each file in this directory (non-recursive).
4
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5
+
6
+ for file in "$SCRIPT_DIR"/*; do
7
+ [ -f "$file" ] || continue
8
+ sha1sum "$file"
9
+ done
@@ -17,7 +17,7 @@ import {reactive, ref, markRaw, onMounted, watch, computed, onErrorCaptured, de
17
17
  import {getLogger} from "Logging"
18
18
  import {md} from "./Markdown.mjs"
19
19
 
20
- import CodeItem from "/core/sfc/code-item.vue"
20
+ import CodeItem from "../core/sfc/code-item.vue"
21
21
 
22
22
  import {
23
23
  replaceHrefLinks,
@@ -11,6 +11,9 @@ export function findHostnamePortProtocol() {
11
11
  return {hostname, port, protocol, isSecure, serverUrl}
12
12
  }
13
13
 
14
+ // ________________________________________________________________________________
15
+ // Island Configuration
16
+ // ________________________________________________________________________________
14
17
  /**
15
18
  * Validate and set defaults for the island config object.
16
19
  * @param config
@@ -35,43 +38,108 @@ export function validateIslandConfig(config) {
35
38
  return config
36
39
  }
37
40
 
41
+ // ________________________________________________________________________________
42
+ // Application Configuration
43
+ // ________________________________________________________________________________
44
+ export const DEFAULTS = {
45
+ isDev: true,
46
+ // XMLHttpRequest from a different domain cannot set cookie values for their own
47
+ // domain unless withCredentials is set to true before making the request.
48
+ // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
49
+ WITH_CREDENTIALS: false,
50
+
51
+ defaultInstanceId: "default",
52
+ instanceId: "default",
53
+ type: "LOCAL",
54
+ // Determines GlobalStore.name
55
+ appName: "C0ckp1t Application",
56
+ // Used for default routes prefix (used only in config)
57
+ routePrefix: "",
58
+ // Used for default components prefix (used only in config)
59
+ componentPrefix: "",
60
+ // Main entry point
61
+ appMainComponent: "/core/PageMain.vue",
62
+ // Used for requestion app components and files (GlobalStore.appEndpoint)
63
+ appEndpoint: "",
64
+
65
+ // Nav Configuration
66
+ navCloseLogo: "/core/img/logo_v1.svg",
67
+ navOpenLogo: "/core/img/logo_v2.svg",
68
+ navHasSearch: false,
69
+ navHasThemeSel: true,
70
+
71
+ // Determine if VueRouter is createWebHashHistory or createWebHistory
72
+ vueRouterModeIsHash: true,
73
+
74
+ // Logger Config (see Logging.mjs)
75
+ defaultLogLevel: "INFO",
76
+ defaultLoggerLevels: {
77
+ "GlobalStore.mjs": "INFO",
78
+ "VueUtils.mjs": "INFO",
79
+ "Connection.mjs": "INFO",
80
+ "default": "INFO",
81
+ "anonymous": "INFO",
82
+ "demo": "INFO"
83
+ },
84
+ };
85
+
86
+
38
87
  /**
39
- * Return the default Vue components
40
- * @returns {Object}
88
+ * Validate and set defaults for the config object.
89
+ * @param config
90
+ * @returns {*}
41
91
  */
42
- export function defaultVueComponents() {
43
- return {
44
- ExecButton: `/components/ExecButton.vue`,
45
- XInput: `/components/xinput.vue`,
46
- XLabel: `/components/xlabel.vue`,
47
- XDropdown: `/components/xdropdown.vue`,
48
- XDropdown2: `/components/xdropdown2.vue`,
49
- XSection: `/components/xsection.vue`,
50
- XTableOpen: `/components/xtable-open.vue`,
51
- XCollapse: `/components/xcollapse.vue`,
52
- XToggle: `/components/xtoggle.vue`,
53
- XToggle3: `/components/xtoggle3.vue`,
54
- XCheck: `/components/xcheck.vue`,
55
- XCheckbox: `/components/xcheckbox.vue`,
56
- XTextarea: `/components/xtextarea.vue`,
57
- XHidden: `/components/xhidden.vue`,
58
-
59
- XTabs: `/components/xtabs.vue`,
60
- XKv: `/components/xkv.vue`,
61
- XNav: `/components/xnav.vue`,
62
- XMap: `/components/xmap.vue`,
63
- XList: `/components/xlist.vue`,
64
- XJson: `/components/xjson.vue`,
65
- XCard: `/components/xcard.vue`,
66
- XCardH: `/components/xcard-h.vue`,
67
- XColor: `/components/xcolor.vue`,
92
+ export function validateAppConfig(config) {
93
+ if (!config) {
94
+ throw new Error("config is required")
95
+ }
96
+ if (typeof config !== 'object') {
97
+ throw new Error("Config must be an object must was `" + typeof config + "`")
98
+ }
99
+ if (!Array.isArray(config?.routes) || config.routes.length === 0) {
100
+ config.routes = []
101
+ }
102
+ if (typeof config.components !== 'object' || config.components === null) {
103
+ config.components = {}
104
+ }
68
105
 
69
- "v-ace-editor": `/components/vue3-ace-editor.vue`,
70
- XMarkdown: `/components/xmarkdown.vue`,
71
- XSound: `/components/xsound.vue`,
72
- XUpload: `/components/xupload.vue`,
73
- XTree: `/components/xtree.vue`,
74
- CodeMirror: `/components/CodeMirror.vue`,
75
- XTerminal: `/components/XTerminal.vue`,
106
+ if (typeof config.instanceId !== `string` || config.instanceId.trim() === ``) {
107
+ config.instanceId = DEFAULTS.instanceId
108
+ }
109
+ if (typeof config.type !== `string` || config.type.trim() === ``) {
110
+ config.type = DEFAULTS.type
76
111
  }
112
+
113
+ return config
77
114
  }
115
+
116
+
117
+ // ________________________________________________________________________________
118
+ // Deep Merge Utility
119
+ // ________________________________________________________________________________
120
+ /**
121
+ * Deep merge source into target. Returns a new object.
122
+ * - Objects are recursively merged (source keys override target keys)
123
+ * - Arrays are replaced entirely (source array wins)
124
+ * - Scalars are replaced (source wins)
125
+ */
126
+ export function deepMerge(target, source) {
127
+ const result = { ...target };
128
+ for (const key of Object.keys(source)) {
129
+ const sourceVal = source[key];
130
+ const targetVal = target[key];
131
+ if (
132
+ sourceVal !== null &&
133
+ typeof sourceVal === 'object' &&
134
+ !Array.isArray(sourceVal) &&
135
+ targetVal !== null &&
136
+ typeof targetVal === 'object' &&
137
+ !Array.isArray(targetVal)
138
+ ) {
139
+ result[key] = deepMerge(targetVal, sourceVal);
140
+ } else {
141
+ result[key] = sourceVal;
142
+ }
143
+ }
144
+ return result;
145
+ }
@@ -8,8 +8,8 @@ import {markRaw, reactive, watch, defineAsyncComponent, createApp} from 'vue'
8
8
  import * as VueRouter from 'vue-router'
9
9
  import {getLogger} from 'Logging';
10
10
  import {transformRoutes, loadModule, options} from "VueUtils";
11
- import {validateIslandConfig, findHostnamePortProtocol, defaultVueComponents} from 'CoreUtils'
12
- import {substrAfterFirstSlash} from "JsUtils";
11
+ import {validateIslandConfig, findHostnamePortProtocol, validateAppConfig} from 'CoreUtils'
12
+ import {substrAfterFirstSlash, extractLastPath} from "JsUtils";
13
13
 
14
14
  import IslandDefault from 'IslandDefault'
15
15
  import Island from 'Island'
@@ -46,6 +46,7 @@ export const store = reactive({
46
46
  name: "C0ckp1t",
47
47
  id: LOG_HEADER,
48
48
  config: null,
49
+ appEndpoint: "",
49
50
  serverInfo: findHostnamePortProtocol(),
50
51
 
51
52
  // ________________________________________________________________________________
@@ -217,8 +218,15 @@ export const api = {
217
218
  },
218
219
 
219
220
  routeByEndpoint: async (endpoint) => {
220
- logger.info(`[routeByEndpoint] - endpoint=${endpoint}`)
221
+ const path = endpoint.split("/")
222
+ logger.info(`[routeByEndpoint] - endpoint=${endpoint}, path=${path}`)
221
223
  try {
224
+ if(path.length > 3) {
225
+ extractLastPath(endpoint)
226
+ document.title = `${path[2]}-${path[3]}`
227
+ } else if (path.length === 3) {
228
+ document.title = `${path[2]}`
229
+ }
222
230
  await store.router.push(endpoint)
223
231
  } catch (err) {
224
232
  console.error("Failed to navigate:", err)
@@ -283,7 +291,7 @@ export const api = {
283
291
  return null
284
292
  }
285
293
 
286
- validateIslandConfig(config)
294
+ validateAppConfig(config)
287
295
  //________________________________________________________________________________
288
296
  // Create Vue Application
289
297
  //________________________________________________________________________________
@@ -301,21 +309,21 @@ export const api = {
301
309
  //________________________________________________________________________________
302
310
  // Create Default Island
303
311
  //________________________________________________________________________________
312
+ config.routes ??= []
304
313
  if(config.routes.length === 0) {
305
314
  logger.warn(`config.routes is empty`)
306
315
  }
307
- config.appEndpoint = config.appEndpoint ?? ""
316
+ store.appEndpoint = config.appEndpoint ?? ""
308
317
  store.defaultInstanceId = config.instanceId ?? "default"
309
318
  store.name = config.appName ?? "C0ckp1t"
310
319
  store.config = config
311
320
  const vueRouterModeIsHash = config.vueRouterModeIsHash ?? true
312
321
 
322
+ // Load default island
313
323
  const decoratedIslandConfig = {
314
324
  ...config,
315
325
  SERVER_API_URL: store.serverInfo.serverUrl,
316
326
  }
317
-
318
- // Load default island first
319
327
  const islandDefault = new IslandDefault(api, decoratedIslandConfig)
320
328
  store.r[islandDefault.instanceId] = islandDefault
321
329
  await islandDefault.init()
@@ -328,12 +336,12 @@ export const api = {
328
336
  store.router = markRaw(router)
329
337
 
330
338
  // Main entry point for the app, this will load the main application
331
- app.component('app-main', createAsyncComponent(() => api.loadModule(`${config.appEndpoint}/core/PageMain.vue`)))
339
+ app.component('app-main', createAsyncComponent(() => api.loadModule(config.appMainComponent)))
332
340
 
333
341
  // Configure C0ckp1t Vue Components
334
- const vueComponents = defaultVueComponents()
342
+ const vueComponents = config.components ?? {}
335
343
  for (const [key, value] of Object.entries(vueComponents)) {
336
- app.component(key, defineAsyncComponent(() => api.loadModule(`${config.appEndpoint}${value}`)))
344
+ app.component(key, defineAsyncComponent(() => api.loadModule(`${value.path}`)))
337
345
  }
338
346
 
339
347
  app.use(router)
package/core/Island.mjs CHANGED
@@ -39,6 +39,7 @@ export default class Island {
39
39
  constructor(apiMain, config) {
40
40
 
41
41
  this.instanceId = config.instanceId
42
+ this.SERVER_API_URL = config.SERVER_API_URL
42
43
 
43
44
  this.LOG_HEADER = `${this.instanceId}`;
44
45
  this.logger = getLogger(this.LOG_HEADER);
@@ -184,6 +185,7 @@ export default class Island {
184
185
  await this.apiMain.insertRoutes(`/${this.instanceId}${node.endpoint}`, config)
185
186
  } else {
186
187
  this.logger.warn(`[node=${node.name}] - failed to load config`)
188
+ this.logger.warn(`path=${node.config.path}`)
187
189
  this.logger.warn(`endpoint=/${this.instanceId}${node.endpoint}`)
188
190
  this.logger.warn(`depth=${node.depth}`)
189
191
  this.logger.warn(`accessLevel=${this.store.context.accessLevel}`)
@@ -199,6 +201,11 @@ export default class Island {
199
201
  [{"path": node.name, "location": "/core/nodes/_api.vue"}]
200
202
  )
201
203
  }
204
+ } else if(node.depth === 2 && node.endpoint.startsWith(`/wf/`)) {
205
+ this.logger.warn(`insert admin`)
206
+ await this.apiMain.insertRoutes(`/${this.instanceId}${node.endpoint}`,
207
+ [{"path": node.name, "location": `/${this.instanceId}/v3/actions/root/admin/_admin.vue`}],
208
+ )
202
209
  }
203
210
  }
204
211
  // NO CONFIG FOUND
@@ -214,6 +221,11 @@ export default class Island {
214
221
  )
215
222
  }
216
223
  }
224
+ if(node.name === "api") {
225
+ await this.apiMain.insertRoutes(`/${this.instanceId}${node.endpoint}`,
226
+ [{"path": node.name, "location": "/core/nodes/place-holder.vue"}]
227
+ )
228
+ }
217
229
  }
218
230
 
219
231
  if (node.children) {
@@ -298,11 +310,11 @@ export default class Island {
298
310
  // HTTP
299
311
  // ________________________________________________________________________________
300
312
  resolver = async (endpoint, type) => {
301
- this.logger.info(`[resolver] - endpoint=${endpoint}`)
313
+ this.logger.debug(`[resolver] - endpoint=${endpoint}`)
302
314
 
303
315
  if (endpoint.startsWith('/c0ckp1t/')) {
304
316
  const endpointAdjusted = endpoint.replace("/c0ckp1t/", `/`)
305
- const path = `${this.config.SERVER_API_URL}${endpointAdjusted}`;
317
+ const path = `${this.SERVER_API_URL}${endpointAdjusted}`;
306
318
  this.logger.debug(`[resolver] - endpointAdjusted=${path}`);
307
319
  const res = await Http.getText(path)
308
320
  if (res.isOk) {
@@ -407,7 +419,7 @@ export default class Island {
407
419
  // HELPER METHODS
408
420
  // ________________________________________________________________________________
409
421
  function adjustNode(node) {
410
- node._expanded = true;
422
+ node._expanded ??= true;
411
423
  node.children.forEach((child) => {
412
424
  adjustNode(child);
413
425
  });
@@ -210,7 +210,7 @@ export default class IslandDefault {
210
210
  // HELPER METHODS
211
211
  // ________________________________________________________________________________
212
212
  function adjustNode(node) {
213
- node._expanded = true;
213
+ node._expanded ??= true;
214
214
  node.children.forEach((child) => {
215
215
  adjustNode(child);
216
216
  });
package/core/PageMain.vue CHANGED
@@ -13,7 +13,7 @@ import {getLogger} from "Logging";
13
13
  import {api as apiTheme, store as storeTheme} from "./Theme.mjs"
14
14
  import PageFallback from "./PageFallback.vue"
15
15
  import MainOffcanvas from "./main-offcanvas.vue";
16
-
16
+ import NotifyToast from "./notify/toast.vue";
17
17
 
18
18
  // ________________________________________________________________________________
19
19
  // LOGGING
@@ -29,8 +29,12 @@ logger.debug("[INIT]")
29
29
  const local = reactive({
30
30
  id: LOG_HEADER,
31
31
  toggle: false,
32
- items: [
33
- ]
32
+ items: [ ],
33
+
34
+ navCloseLogo: storeMain.config?.navCloseLogo ?? "/img/logo_v1.svg",
35
+ navOpenLogo: storeMain.config?.navOpenLogo ?? "/img/logo_v2.svg",
36
+ navHasSearch: storeMain.config?.navHasSearch ?? true,
37
+ navHasThemeSel: storeMain.config?.navHasThemeSel ?? true,
34
38
  })
35
39
 
36
40
 
@@ -95,8 +99,8 @@ const mainContentStyle = computed(() => ({
95
99
 
96
100
  <a class="navbar-brand" @click.prevent="apiMain.selectLogo()" >
97
101
  <span class="me-2 text-warning" v-if="storeMain.showSidebar"><<</span>
98
- <img src="./img/logo_v1.svg" alt="Logo" height="24" class="d-inline-block align-text-top" v-if="!storeMain.showSidebar">
99
- <img src="./img/logo_v2.svg" alt="Logo" height="24" class="d-inline-block align-text-top" v-else>
102
+ <img :src="local.navCloseLogo" alt="Logo" height="24" class="d-inline-block align-text-top" v-if="!storeMain.showSidebar && local.navCloseLogo">
103
+ <img :src="local.navOpenLogo" alt="Logo" height="24" class="d-inline-block align-text-top" v-if="storeMain.showSidebar && local.navOpenLogo">
100
104
  <span class="text-warning fw-bold ms-2 brand-text">{{ storeMain.name }}</span>
101
105
  </a>
102
106
 
@@ -116,13 +120,13 @@ const mainContentStyle = computed(() => ({
116
120
  </ul>
117
121
 
118
122
  <form class="d-flex">
119
- <input class="form-control me-2" type="search" placeholder="Search" v-model="local.searchQuery">
120
- <button class="btn btn-outline-secondary me-2" type="button" @click="storeTheme.theme = storeTheme.theme === 'dark' ? 'light' : 'dark'" title="Toggle theme">
121
- <i class="fa-solid" :class="storeTheme.theme === 'dark' ? 'fa-sun' : 'fa-moon'"></i>
122
- </button>
123
- <button class="btn btn-outline-secondary" type="submit">
123
+ <input v-if="local.navHasSearch" class="form-control me-2" type="search" placeholder="Search" v-model="local.searchQuery">
124
+ <button v-if="local.navHasSearch" class="btn btn-outline-secondary" type="submit">
124
125
  <i class="fa-solid fa-search"></i>
125
126
  </button>
127
+ <button v-if="local.navHasThemeSel" class="btn btn-outline-secondary me-2" type="button" @click="storeTheme.theme = storeTheme.theme === 'dark' ? 'light' : 'dark'" title="Toggle theme">
128
+ <i class="fa-solid" :class="storeTheme.theme === 'dark' ? 'fa-sun' : 'fa-moon'"></i>
129
+ </button>
126
130
  </form>
127
131
 
128
132
  </div>
@@ -135,6 +139,7 @@ const mainContentStyle = computed(() => ({
135
139
  <RouterView/>
136
140
  </main>
137
141
 
142
+ <NotifyToast/>
138
143
  <!-- ========== FOOTER ========== -->
139
144
  <footer class="container-fluid p-4 bg-body-tertiary border-top">
140
145
  <div class="row mt-4 align-items-center justify-content-center">
@@ -58,7 +58,7 @@
58
58
  cy="129.01283"
59
59
  cx="97.967125"
60
60
  id="head"
61
- style="fill:#ffdf11;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583;stroke-opacity:1" />
61
+ style="fill:#c4a900;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.264583;stroke-opacity:1" />
62
62
  <path
63
63
  id="lefEye2"
64
64
  d="M 62.802996,126.14677 C 83.82199,101.23898 83.964978,101.06953 83.964978,101.06953"
@@ -86,9 +86,9 @@
86
86
  height="8.6218405"
87
87
  width="19.292933"
88
88
  id="neck1"
89
- style="fill:#ffdf11;fill-opacity:1;stroke:#000000;stroke-width:0.264951;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
89
+ style="fill:#c4a900;fill-opacity:1;stroke:#000000;stroke-width:0.264951;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
90
90
  <rect
91
- style="fill:#ffdf11;fill-opacity:1;stroke:#000000;stroke-width:0.222;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
91
+ style="fill:#c4a900;fill-opacity:1;stroke:#000000;stroke-width:0.222;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
92
92
  id="neck2"
93
93
  width="12.705888"
94
94
  height="6.1260414"
@@ -51,7 +51,7 @@ const local = reactive({
51
51
  <template>
52
52
 
53
53
  <div class="_api" >
54
- <x-section extra="fs-4" :visible="true" :k="`API Node for endpoint=${adminEndpoint}`" v-if="selectedNode">
54
+ <x-section :level="4" :visible="true" :k="`API Node for endpoint=${adminEndpoint}`" v-if="selectedNode">
55
55
 
56
56
  <template v-slot:header>
57
57
  <ExecButton icon="fa-info" @callback="apiMain.selectDocumentation(storeMain.documentation)"></ExecButton>
@@ -7,7 +7,7 @@
7
7
  import {reactive, onMounted, onUnmounted, defineAsyncComponent, watch, onErrorCaptured, computed} from 'vue'
8
8
  import {store as storeMain, api as apiMain} from 'GlobalStore'
9
9
 
10
- const InfoApi = defineAsyncComponent(() => import("../components/info-api.vue"))
10
+ const InfoApi = defineAsyncComponent(() => import("./_api.vue"))
11
11
 
12
12
  const selectedNode = computed(() => {
13
13
  return storeMain.r[storeMain.selectedInstId]?.store?.selectedNode
@@ -17,22 +17,13 @@ const selectedNode = computed(() => {
17
17
 
18
18
 
19
19
  <template>
20
+ <div class="place-holder">
21
+ <x-section :level="3" :visible="true" :k="`Place Holder Node (endpoint=${selectedNode.endpoint})`" v-if="selectedNode">
20
22
 
21
- <div class="place-holder" v-if="selectedNode">
22
- <x-section extra="fs-4" :visible="true" :k="`Place Holder Node (endpoint=${selectedNode.endpoint})`">
23
-
24
- <template v-slot:header>
25
- <x-button icon="fa-info" @callback="apiMain.selectDocumentation(storeMain.documentation)"></x-button>
26
- </template>
27
-
28
- <x-section extra="fs-4" :visible="false" :k="`API Information`">
29
- <info-api :endpoint="selectedNode.endpoint" :instanceId="storeMain.selectedInstId"></info-api>
30
- </x-section>
31
-
32
- <x-section extra="fs-4" :visible="false" :k="`Node Information`">
23
+ <x-section :level="4" :visible="true" :k="`Node Information`">
33
24
  <div class="row mt-4 mb-4">
34
- <x-collapse k="Node Entity">
35
- <x-json :obj="selectedNode"></x-json>
25
+ <x-collapse k="Node Entity" :modelValue="true">
26
+ <x-json :obj="selectedNode" :expanded="true"></x-json>
36
27
  </x-collapse>
37
28
  </div>
38
29
  </x-section>
@@ -136,7 +136,7 @@ onMounted(async () => { await init() })
136
136
 
137
137
  <style scoped>
138
138
  .toast {
139
- background-color: rgba(255,255,255,.95);
139
+
140
140
  }
141
141
 
142
142
  /** NOTIFY */
@@ -13,8 +13,6 @@ import {reactive, computed, ref, onMounted, onUnmounted, defineAsyncComponent, w
13
13
  import {getLogger} from "Logging";
14
14
  // !# C0CKP1T_START imports
15
15
  import ComponentView from "./component-view.vue";
16
- import XTerminal from "/components/xterminal.vue";
17
- import CodeMirror from "/components/code-mirror.vue";
18
16
  // !# C0CKP1T_END imports
19
17
 
20
18
  // ________________________________________________________________________________
@@ -146,12 +146,12 @@ onMounted(async () => { init() })
146
146
  .functions {
147
147
  border: 2px solid black;
148
148
  padding: 4px;
149
- background-color: #d0d7dd;
149
+ background-color: var(--bs-secondary-bg)
150
150
  }
151
151
 
152
152
  .functions2 {
153
153
  border: 2px solid black;
154
154
  padding: 4px;
155
- background-color: #d4c9c3;
155
+ background-color: var(--bs-secondary-bg)
156
156
  }
157
157
  </style>
package/docs/Issues.md ADDED
@@ -0,0 +1,13 @@
1
+
2
+
3
+ if cannot read PageMain
4
+
5
+ because it returns gargabe I.e
6
+
7
+ ```json
8
+ <!doctype html>
9
+ <html lang="en">
10
+ <head>
11
+ ```
12
+
13
+ the app does throw error and doesn't work. Need better error checking
package/index.html CHANGED
@@ -57,15 +57,18 @@
57
57
 
58
58
  <script type="module">
59
59
  import {init as initLogger} from 'Logging';
60
- import {api as apiMain} from 'GlobalStore'
61
- import DefaultConfig from './DefaultConfig.mjs'
60
+ import {api as apiMain} from 'GlobalStore';
61
+ // Application Configuration
62
+ import { createConfig } from './Config.mjs';
63
+ // Islands
62
64
  import ConfigAdmin from './ConfigAdmin.mjs'
63
65
  import ConfigAnonymous from './ConfigAnonymous.mjs'
64
66
  import ConfigDemo from './c0ckp1t-demo/C0ckp1tConfig.mjs'
65
-
66
- initLogger(DefaultConfig)
67
- await apiMain.init("app-default", DefaultConfig)
68
-
67
+ // Create Application
68
+ const config = createConfig();
69
+ initLogger(config)
70
+ await apiMain.init("app-default", config)
71
+ // Create Islands
69
72
  await apiMain.registerIsland( ConfigAdmin)
70
73
  await apiMain.registerIsland(ConfigAnonymous)
71
74
  await apiMain.registerIsland(ConfigDemo)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c0ckp1t",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "A Vue 3 zero-build web dashboard framework with Islands architecture, WebSocket backends, and reusable UI components",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -26,6 +26,7 @@
26
26
  "index-cdn.html",
27
27
  "index.html",
28
28
  "style.css",
29
+ "Config.mjs",
29
30
  "DefaultConfig.mjs",
30
31
  "CdnConfig.mjs",
31
32
  "favicon.ico",
package/CdnConfig.mjs DELETED
@@ -1,177 +0,0 @@
1
- /**
2
- * Default Configuration for a C0ckp1t Application
3
- */
4
- // ________________________________________________________________________________
5
- // Properties
6
- // ________________________________________________________________________________
7
- // XMLHttpRequest from a different domain cannot set cookie values for their own
8
- // domain unless withCredentials is set to true before making the request.
9
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
10
- const WITH_CREDENTIALS = false
11
- // Note: VueUtils requires this to be 'default'
12
- const instanceId = "default";
13
- // Used for requestion app components and files
14
- const appEndpoint = "https://cdn.jsdelivr.net/npm/c0ckp1t@latest";
15
-
16
- // ________________________________________________________________________________
17
- // GLOBAL CONSTANTS
18
- // ________________________________________________________________________________
19
- export default {
20
- isDev: true,
21
- WITH_CREDENTIALS: WITH_CREDENTIALS,
22
-
23
- // logger config
24
- defaultLogLevel: "INFO",
25
- defaultLoggerLevels: {
26
- "GlobalStore.mjs": "INFO",
27
- "VueUtils.mjs": "INFO",
28
- "Connection.mjs": "INFO",
29
- "default": "INFO",
30
- "anonymous": "INFO",
31
- "demo": "INFO"
32
- },
33
-
34
- instanceId: instanceId,
35
- type: "LOCAL",
36
- appName: "C0ckp1t App",
37
- appEndpoint: appEndpoint,
38
-
39
- // This creates the navigation tree
40
- root: {
41
- icon: "fa-house",
42
- depth: 0,
43
- endpoint: "/",
44
- isLeaf: false,
45
- isRoot: true,
46
- name: "",
47
- path: [],
48
- children: [
49
- {
50
- depth: 1,
51
- endpoint: `/${instanceId}/connections`,
52
- isLeaf: true,
53
- isRoot: false,
54
- path: ["connections"],
55
- name: "Connections",
56
- children: []
57
- },
58
- {
59
- depth: 1,
60
- endpoint: `/${instanceId}/cache`,
61
- isLeaf: true,
62
- isRoot: false,
63
- path: ["cache"],
64
- name: "Cache",
65
- children: []
66
- },
67
- {
68
- icon: "fa-network-wired",
69
- depth: 1,
70
- endpoint: `/${instanceId}/traffic`,
71
- isLeaf: true,
72
- isRoot: false,
73
- path: ["traffic"],
74
- name: "Traffic",
75
- children: []
76
- },
77
- {
78
- icon: "fa-bell",
79
- depth: 1,
80
- endpoint: `/${instanceId}/notifies`,
81
- isLeaf: true,
82
- isRoot: false,
83
- path: ["notifies"],
84
- name: "Notifies",
85
- children: []
86
- },
87
- {
88
- icon: "fa-info",
89
- depth: 1,
90
- endpoint: `/${instanceId}/docs`,
91
- isLeaf: true,
92
- isRoot: false,
93
- path: ["docs"],
94
- name: "Documentation",
95
- children: []
96
- },
97
- {
98
- icon: "fa-info",
99
- depth: 1,
100
- endpoint: `/${instanceId}/components`,
101
- isLeaf: true,
102
- isRoot: false,
103
- path: ["components"],
104
- name: "Components",
105
- children: [
106
- {
107
- icon: "fa-info",
108
- depth: 2,
109
- endpoint: `/${instanceId}/components/bootstrap`,
110
- isLeaf: true,
111
- isRoot: false,
112
- path: ["bootstrap"],
113
- name: "Bootstrap",
114
- children: []
115
- },
116
- {
117
- icon: "fa-info",
118
- depth: 2,
119
- endpoint: `/${instanceId}/components/basic`,
120
- isLeaf: true,
121
- isRoot: false,
122
- path: ["basic"],
123
- name: "Basic",
124
- children: []
125
- },
126
- {
127
- icon: "fa-info",
128
- depth: 2,
129
- endpoint: `/${instanceId}/components/advanced`,
130
- isLeaf: true,
131
- isRoot: false,
132
- path: ["advanced"],
133
- name: "Advanced",
134
- children: []
135
- },
136
- {
137
- icon: "fa-info",
138
- depth: 2,
139
- endpoint: `/${instanceId}/components/theme`,
140
- isLeaf: true,
141
- isRoot: false,
142
- path: ["theme"],
143
- name: "Theme",
144
- children: []
145
- },
146
- ]
147
- }
148
- ]
149
- },
150
-
151
- // This is used to create routes for the vue router
152
- routes: [
153
- { path: '/', name: 'root', children: [
154
- {path: '', redirect: '/default/docs/Introduction.md'},
155
- {path: `${instanceId}`, children :[
156
- {path: 'docs', redirect: `/${instanceId}/docs/Introduction.md`},
157
- {path: 'docs/:pathMatch(.*)*', location: `${appEndpoint}/core/pages/Documentation.vue`},
158
- {path: 'connections', location: `${appEndpoint}/core/pages/Connections.vue`},
159
- {path: 'connections/:id', location: `${appEndpoint}/core/pages/Connection.vue`},
160
- {path: 'cache', location: `${appEndpoint}/core/pages/Cache.vue`},
161
- {path: 'traffic', location: `${appEndpoint}/core/pages/Traffic.vue`},
162
- {path: 'notifies', location: `${appEndpoint}/core/pages/Notifies.vue`},
163
- {path: 'components', location: `${appEndpoint}/core/pages/frontend/Components.vue`, children: [
164
- {path: 'basic', location: `${appEndpoint}/core/pages/frontend/ComponentsBasic.vue`},
165
- {path: 'advanced', location: `${appEndpoint}/core/pages/frontend/ComponentsAdv.vue`},
166
- {path: 'theme', location: `${appEndpoint}/core/pages/frontend/Theme.vue`},
167
- {path: 'bootstrap', location: `${appEndpoint}/core/pages/frontend/Bootstrap.vue`},
168
- ]},
169
- ]}
170
- ] },
171
- { path: '/:pathMatch(.*)*', name: '404', location: `${appEndpoint}/core/Page404.vue` }
172
-
173
- ]
174
-
175
-
176
- } // end of Constants
177
-
package/DefaultConfig.mjs DELETED
@@ -1,177 +0,0 @@
1
- /**
2
- * Default Configuration for a C0ckp1t Application
3
- */
4
- // ________________________________________________________________________________
5
- // Properties
6
- // ________________________________________________________________________________
7
- // XMLHttpRequest from a different domain cannot set cookie values for their own
8
- // domain unless withCredentials is set to true before making the request.
9
- // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
10
- const WITH_CREDENTIALS = false
11
- // Note: VueUtils requires this to be 'default'
12
- const instanceId = "default";
13
- // Used for requestion app components and files
14
- const appEndpoint = "";
15
-
16
- // ________________________________________________________________________________
17
- // GLOBAL CONSTANTS
18
- // ________________________________________________________________________________
19
- export default {
20
- isDev: true,
21
- WITH_CREDENTIALS: WITH_CREDENTIALS,
22
-
23
- // logger config
24
- defaultLogLevel: "INFO",
25
- defaultLoggerLevels: {
26
- "GlobalStore.mjs": "INFO",
27
- "VueUtils.mjs": "INFO",
28
- "Connection.mjs": "INFO",
29
- "default": "INFO",
30
- "anonymous": "INFO",
31
- "demo": "INFO"
32
- },
33
-
34
- instanceId: instanceId,
35
- type: "LOCAL",
36
- appName: "C0ckp1t App",
37
- appEndpoint: appEndpoint,
38
-
39
- // This creates the navigation tree
40
- root: {
41
- icon: "fa-house",
42
- depth: 0,
43
- endpoint: "/",
44
- isLeaf: false,
45
- isRoot: true,
46
- name: "",
47
- path: [],
48
- children: [
49
- {
50
- depth: 1,
51
- endpoint: `/${instanceId}/connections`,
52
- isLeaf: true,
53
- isRoot: false,
54
- path: ["connections"],
55
- name: "Connections",
56
- children: []
57
- },
58
- {
59
- depth: 1,
60
- endpoint: `/${instanceId}/cache`,
61
- isLeaf: true,
62
- isRoot: false,
63
- path: ["cache"],
64
- name: "Cache",
65
- children: []
66
- },
67
- {
68
- icon: "fa-network-wired",
69
- depth: 1,
70
- endpoint: `/${instanceId}/traffic`,
71
- isLeaf: true,
72
- isRoot: false,
73
- path: ["traffic"],
74
- name: "Traffic",
75
- children: []
76
- },
77
- {
78
- icon: "fa-bell",
79
- depth: 1,
80
- endpoint: `/${instanceId}/notifies`,
81
- isLeaf: true,
82
- isRoot: false,
83
- path: ["notifies"],
84
- name: "Notifies",
85
- children: []
86
- },
87
- {
88
- icon: "fa-info",
89
- depth: 1,
90
- endpoint: `/${instanceId}/docs`,
91
- isLeaf: true,
92
- isRoot: false,
93
- path: ["docs"],
94
- name: "Documentation",
95
- children: []
96
- },
97
- {
98
- icon: "fa-info",
99
- depth: 1,
100
- endpoint: `/${instanceId}/components`,
101
- isLeaf: true,
102
- isRoot: false,
103
- path: ["components"],
104
- name: "Components",
105
- children: [
106
- {
107
- icon: "fa-info",
108
- depth: 2,
109
- endpoint: `/${instanceId}/components/bootstrap`,
110
- isLeaf: true,
111
- isRoot: false,
112
- path: ["bootstrap"],
113
- name: "Bootstrap",
114
- children: []
115
- },
116
- {
117
- icon: "fa-info",
118
- depth: 2,
119
- endpoint: `/${instanceId}/components/basic`,
120
- isLeaf: true,
121
- isRoot: false,
122
- path: ["basic"],
123
- name: "Basic",
124
- children: []
125
- },
126
- {
127
- icon: "fa-info",
128
- depth: 2,
129
- endpoint: `/${instanceId}/components/advanced`,
130
- isLeaf: true,
131
- isRoot: false,
132
- path: ["advanced"],
133
- name: "Advanced",
134
- children: []
135
- },
136
- {
137
- icon: "fa-info",
138
- depth: 2,
139
- endpoint: `/${instanceId}/components/theme`,
140
- isLeaf: true,
141
- isRoot: false,
142
- path: ["theme"],
143
- name: "Theme",
144
- children: []
145
- },
146
- ]
147
- }
148
- ]
149
- },
150
-
151
- // This is used to create routes for the vue router
152
- routes: [
153
- { path: '/', name: 'root', children: [
154
- {path: '', redirect: '/default/docs/Introduction.md'},
155
- {path: `${instanceId}`, children :[
156
- {path: 'docs', redirect: `/${instanceId}/docs/Introduction.md`},
157
- {path: 'docs/:pathMatch(.*)*', location: `${appEndpoint}/core/pages/Documentation.vue`},
158
- {path: 'connections', location: `${appEndpoint}/core/pages/Connections.vue`},
159
- {path: 'connections/:id', location: `${appEndpoint}/core/pages/Connection.vue`},
160
- {path: 'cache', location: `${appEndpoint}/core/pages/Cache.vue`},
161
- {path: 'traffic', location: `${appEndpoint}/core/pages/Traffic.vue`},
162
- {path: 'notifies', location: `${appEndpoint}/core/pages/Notifies.vue`},
163
- {path: 'components', location: `${appEndpoint}/core/pages/frontend/Components.vue`, children: [
164
- {path: 'basic', location: `${appEndpoint}/core/pages/frontend/ComponentsBasic.vue`},
165
- {path: 'advanced', location: `${appEndpoint}/core/pages/frontend/ComponentsAdv.vue`},
166
- {path: 'theme', location: `${appEndpoint}/core/pages/frontend/Theme.vue`},
167
- {path: 'bootstrap', location: `${appEndpoint}/core/pages/frontend/Bootstrap.vue`},
168
- ]},
169
- ]}
170
- ] },
171
- { path: '/:pathMatch(.*)*', name: '404', location: `${appEndpoint}/core/Page404.vue` }
172
-
173
- ]
174
-
175
-
176
- } // end of Constants
177
-