@decido/plugin-frubeala-ui 1.0.0
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/dist/assets/__federation_expose_Plugin-WvTCD-o4.js +8665 -0
- package/dist/assets/__federation_fn_import-eohqPj63.js +423 -0
- package/dist/assets/__federation_shared_react-B_Erx0pB.js +4 -0
- package/dist/assets/__federation_shared_react-dom-BYCW6Jpt.js +6672 -0
- package/dist/assets/__federation_shared_zustand-BE2cJPMx.js +194 -0
- package/dist/assets/core-Bo9SoPMG.js +142 -0
- package/dist/assets/event-CGIJhKma.js +63 -0
- package/dist/assets/index-DLaxava2.js +65 -0
- package/dist/assets/index-Daqo0uNT.js +122 -0
- package/dist/assets/index-S0MgceH3.js +272 -0
- package/dist/assets/remoteEntry.js +80 -0
- package/dist/index.html +14 -0
- package/index.html +14 -0
- package/package.json +32 -0
- package/src/index.ts +27 -0
- package/src/manifest.ts +25 -0
- package/src/widgets/MainWidget.tsx +187 -0
- package/tsconfig.json +14 -0
- package/vite.config.ts +38 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
function getDefaultExportFromCjs(x2) {
|
|
2
|
+
return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2;
|
|
3
|
+
}
|
|
4
|
+
var react = { exports: {} };
|
|
5
|
+
var react_production_min = {};
|
|
6
|
+
/**
|
|
7
|
+
* @license React
|
|
8
|
+
* react.production.min.js
|
|
9
|
+
*
|
|
10
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
11
|
+
*
|
|
12
|
+
* This source code is licensed under the MIT license found in the
|
|
13
|
+
* LICENSE file in the root directory of this source tree.
|
|
14
|
+
*/
|
|
15
|
+
var l = /* @__PURE__ */ Symbol.for("react.element"), n = /* @__PURE__ */ Symbol.for("react.portal"), p = /* @__PURE__ */ Symbol.for("react.fragment"), q = /* @__PURE__ */ Symbol.for("react.strict_mode"), r = /* @__PURE__ */ Symbol.for("react.profiler"), t = /* @__PURE__ */ Symbol.for("react.provider"), u = /* @__PURE__ */ Symbol.for("react.context"), v = /* @__PURE__ */ Symbol.for("react.forward_ref"), w = /* @__PURE__ */ Symbol.for("react.suspense"), x = /* @__PURE__ */ Symbol.for("react.memo"), y = /* @__PURE__ */ Symbol.for("react.lazy"), z = Symbol.iterator;
|
|
16
|
+
function A(a) {
|
|
17
|
+
if (null === a || "object" !== typeof a) return null;
|
|
18
|
+
a = z && a[z] || a["@@iterator"];
|
|
19
|
+
return "function" === typeof a ? a : null;
|
|
20
|
+
}
|
|
21
|
+
var B = { isMounted: function() {
|
|
22
|
+
return false;
|
|
23
|
+
}, enqueueForceUpdate: function() {
|
|
24
|
+
}, enqueueReplaceState: function() {
|
|
25
|
+
}, enqueueSetState: function() {
|
|
26
|
+
} }, C = Object.assign, D = {};
|
|
27
|
+
function E(a, b, e) {
|
|
28
|
+
this.props = a;
|
|
29
|
+
this.context = b;
|
|
30
|
+
this.refs = D;
|
|
31
|
+
this.updater = e || B;
|
|
32
|
+
}
|
|
33
|
+
E.prototype.isReactComponent = {};
|
|
34
|
+
E.prototype.setState = function(a, b) {
|
|
35
|
+
if ("object" !== typeof a && "function" !== typeof a && null != a) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
|
|
36
|
+
this.updater.enqueueSetState(this, a, b, "setState");
|
|
37
|
+
};
|
|
38
|
+
E.prototype.forceUpdate = function(a) {
|
|
39
|
+
this.updater.enqueueForceUpdate(this, a, "forceUpdate");
|
|
40
|
+
};
|
|
41
|
+
function F() {
|
|
42
|
+
}
|
|
43
|
+
F.prototype = E.prototype;
|
|
44
|
+
function G(a, b, e) {
|
|
45
|
+
this.props = a;
|
|
46
|
+
this.context = b;
|
|
47
|
+
this.refs = D;
|
|
48
|
+
this.updater = e || B;
|
|
49
|
+
}
|
|
50
|
+
var H = G.prototype = new F();
|
|
51
|
+
H.constructor = G;
|
|
52
|
+
C(H, E.prototype);
|
|
53
|
+
H.isPureReactComponent = true;
|
|
54
|
+
var I = Array.isArray, J = Object.prototype.hasOwnProperty, K = { current: null }, L = { key: true, ref: true, __self: true, __source: true };
|
|
55
|
+
function M(a, b, e) {
|
|
56
|
+
var d, c = {}, k = null, h = null;
|
|
57
|
+
if (null != b) for (d in void 0 !== b.ref && (h = b.ref), void 0 !== b.key && (k = "" + b.key), b) J.call(b, d) && !L.hasOwnProperty(d) && (c[d] = b[d]);
|
|
58
|
+
var g = arguments.length - 2;
|
|
59
|
+
if (1 === g) c.children = e;
|
|
60
|
+
else if (1 < g) {
|
|
61
|
+
for (var f = Array(g), m = 0; m < g; m++) f[m] = arguments[m + 2];
|
|
62
|
+
c.children = f;
|
|
63
|
+
}
|
|
64
|
+
if (a && a.defaultProps) for (d in g = a.defaultProps, g) void 0 === c[d] && (c[d] = g[d]);
|
|
65
|
+
return { $$typeof: l, type: a, key: k, ref: h, props: c, _owner: K.current };
|
|
66
|
+
}
|
|
67
|
+
function N(a, b) {
|
|
68
|
+
return { $$typeof: l, type: a.type, key: b, ref: a.ref, props: a.props, _owner: a._owner };
|
|
69
|
+
}
|
|
70
|
+
function O(a) {
|
|
71
|
+
return "object" === typeof a && null !== a && a.$$typeof === l;
|
|
72
|
+
}
|
|
73
|
+
function escape(a) {
|
|
74
|
+
var b = { "=": "=0", ":": "=2" };
|
|
75
|
+
return "$" + a.replace(/[=:]/g, function(a2) {
|
|
76
|
+
return b[a2];
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
var P = /\/+/g;
|
|
80
|
+
function Q(a, b) {
|
|
81
|
+
return "object" === typeof a && null !== a && null != a.key ? escape("" + a.key) : b.toString(36);
|
|
82
|
+
}
|
|
83
|
+
function R(a, b, e, d, c) {
|
|
84
|
+
var k = typeof a;
|
|
85
|
+
if ("undefined" === k || "boolean" === k) a = null;
|
|
86
|
+
var h = false;
|
|
87
|
+
if (null === a) h = true;
|
|
88
|
+
else switch (k) {
|
|
89
|
+
case "string":
|
|
90
|
+
case "number":
|
|
91
|
+
h = true;
|
|
92
|
+
break;
|
|
93
|
+
case "object":
|
|
94
|
+
switch (a.$$typeof) {
|
|
95
|
+
case l:
|
|
96
|
+
case n:
|
|
97
|
+
h = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (h) return h = a, c = c(h), a = "" === d ? "." + Q(h, 0) : d, I(c) ? (e = "", null != a && (e = a.replace(P, "$&/") + "/"), R(c, b, e, "", function(a2) {
|
|
101
|
+
return a2;
|
|
102
|
+
})) : null != c && (O(c) && (c = N(c, e + (!c.key || h && h.key === c.key ? "" : ("" + c.key).replace(P, "$&/") + "/") + a)), b.push(c)), 1;
|
|
103
|
+
h = 0;
|
|
104
|
+
d = "" === d ? "." : d + ":";
|
|
105
|
+
if (I(a)) for (var g = 0; g < a.length; g++) {
|
|
106
|
+
k = a[g];
|
|
107
|
+
var f = d + Q(k, g);
|
|
108
|
+
h += R(k, b, e, f, c);
|
|
109
|
+
}
|
|
110
|
+
else if (f = A(a), "function" === typeof f) for (a = f.call(a), g = 0; !(k = a.next()).done; ) k = k.value, f = d + Q(k, g++), h += R(k, b, e, f, c);
|
|
111
|
+
else if ("object" === k) throw b = String(a), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b ? "object with keys {" + Object.keys(a).join(", ") + "}" : b) + "). If you meant to render a collection of children, use an array instead.");
|
|
112
|
+
return h;
|
|
113
|
+
}
|
|
114
|
+
function S(a, b, e) {
|
|
115
|
+
if (null == a) return a;
|
|
116
|
+
var d = [], c = 0;
|
|
117
|
+
R(a, d, "", "", function(a2) {
|
|
118
|
+
return b.call(e, a2, c++);
|
|
119
|
+
});
|
|
120
|
+
return d;
|
|
121
|
+
}
|
|
122
|
+
function T(a) {
|
|
123
|
+
if (-1 === a._status) {
|
|
124
|
+
var b = a._result;
|
|
125
|
+
b = b();
|
|
126
|
+
b.then(function(b2) {
|
|
127
|
+
if (0 === a._status || -1 === a._status) a._status = 1, a._result = b2;
|
|
128
|
+
}, function(b2) {
|
|
129
|
+
if (0 === a._status || -1 === a._status) a._status = 2, a._result = b2;
|
|
130
|
+
});
|
|
131
|
+
-1 === a._status && (a._status = 0, a._result = b);
|
|
132
|
+
}
|
|
133
|
+
if (1 === a._status) return a._result.default;
|
|
134
|
+
throw a._result;
|
|
135
|
+
}
|
|
136
|
+
var U = { current: null }, V = { transition: null }, W = { ReactCurrentDispatcher: U, ReactCurrentBatchConfig: V, ReactCurrentOwner: K };
|
|
137
|
+
function X() {
|
|
138
|
+
throw Error("act(...) is not supported in production builds of React.");
|
|
139
|
+
}
|
|
140
|
+
react_production_min.Children = { map: S, forEach: function(a, b, e) {
|
|
141
|
+
S(a, function() {
|
|
142
|
+
b.apply(this, arguments);
|
|
143
|
+
}, e);
|
|
144
|
+
}, count: function(a) {
|
|
145
|
+
var b = 0;
|
|
146
|
+
S(a, function() {
|
|
147
|
+
b++;
|
|
148
|
+
});
|
|
149
|
+
return b;
|
|
150
|
+
}, toArray: function(a) {
|
|
151
|
+
return S(a, function(a2) {
|
|
152
|
+
return a2;
|
|
153
|
+
}) || [];
|
|
154
|
+
}, only: function(a) {
|
|
155
|
+
if (!O(a)) throw Error("React.Children.only expected to receive a single React element child.");
|
|
156
|
+
return a;
|
|
157
|
+
} };
|
|
158
|
+
react_production_min.Component = E;
|
|
159
|
+
react_production_min.Fragment = p;
|
|
160
|
+
react_production_min.Profiler = r;
|
|
161
|
+
react_production_min.PureComponent = G;
|
|
162
|
+
react_production_min.StrictMode = q;
|
|
163
|
+
react_production_min.Suspense = w;
|
|
164
|
+
react_production_min.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W;
|
|
165
|
+
react_production_min.act = X;
|
|
166
|
+
react_production_min.cloneElement = function(a, b, e) {
|
|
167
|
+
if (null === a || void 0 === a) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a + ".");
|
|
168
|
+
var d = C({}, a.props), c = a.key, k = a.ref, h = a._owner;
|
|
169
|
+
if (null != b) {
|
|
170
|
+
void 0 !== b.ref && (k = b.ref, h = K.current);
|
|
171
|
+
void 0 !== b.key && (c = "" + b.key);
|
|
172
|
+
if (a.type && a.type.defaultProps) var g = a.type.defaultProps;
|
|
173
|
+
for (f in b) J.call(b, f) && !L.hasOwnProperty(f) && (d[f] = void 0 === b[f] && void 0 !== g ? g[f] : b[f]);
|
|
174
|
+
}
|
|
175
|
+
var f = arguments.length - 2;
|
|
176
|
+
if (1 === f) d.children = e;
|
|
177
|
+
else if (1 < f) {
|
|
178
|
+
g = Array(f);
|
|
179
|
+
for (var m = 0; m < f; m++) g[m] = arguments[m + 2];
|
|
180
|
+
d.children = g;
|
|
181
|
+
}
|
|
182
|
+
return { $$typeof: l, type: a.type, key: c, ref: k, props: d, _owner: h };
|
|
183
|
+
};
|
|
184
|
+
react_production_min.createContext = function(a) {
|
|
185
|
+
a = { $$typeof: u, _currentValue: a, _currentValue2: a, _threadCount: 0, Provider: null, Consumer: null, _defaultValue: null, _globalName: null };
|
|
186
|
+
a.Provider = { $$typeof: t, _context: a };
|
|
187
|
+
return a.Consumer = a;
|
|
188
|
+
};
|
|
189
|
+
react_production_min.createElement = M;
|
|
190
|
+
react_production_min.createFactory = function(a) {
|
|
191
|
+
var b = M.bind(null, a);
|
|
192
|
+
b.type = a;
|
|
193
|
+
return b;
|
|
194
|
+
};
|
|
195
|
+
react_production_min.createRef = function() {
|
|
196
|
+
return { current: null };
|
|
197
|
+
};
|
|
198
|
+
react_production_min.forwardRef = function(a) {
|
|
199
|
+
return { $$typeof: v, render: a };
|
|
200
|
+
};
|
|
201
|
+
react_production_min.isValidElement = O;
|
|
202
|
+
react_production_min.lazy = function(a) {
|
|
203
|
+
return { $$typeof: y, _payload: { _status: -1, _result: a }, _init: T };
|
|
204
|
+
};
|
|
205
|
+
react_production_min.memo = function(a, b) {
|
|
206
|
+
return { $$typeof: x, type: a, compare: void 0 === b ? null : b };
|
|
207
|
+
};
|
|
208
|
+
react_production_min.startTransition = function(a) {
|
|
209
|
+
var b = V.transition;
|
|
210
|
+
V.transition = {};
|
|
211
|
+
try {
|
|
212
|
+
a();
|
|
213
|
+
} finally {
|
|
214
|
+
V.transition = b;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
react_production_min.unstable_act = X;
|
|
218
|
+
react_production_min.useCallback = function(a, b) {
|
|
219
|
+
return U.current.useCallback(a, b);
|
|
220
|
+
};
|
|
221
|
+
react_production_min.useContext = function(a) {
|
|
222
|
+
return U.current.useContext(a);
|
|
223
|
+
};
|
|
224
|
+
react_production_min.useDebugValue = function() {
|
|
225
|
+
};
|
|
226
|
+
react_production_min.useDeferredValue = function(a) {
|
|
227
|
+
return U.current.useDeferredValue(a);
|
|
228
|
+
};
|
|
229
|
+
react_production_min.useEffect = function(a, b) {
|
|
230
|
+
return U.current.useEffect(a, b);
|
|
231
|
+
};
|
|
232
|
+
react_production_min.useId = function() {
|
|
233
|
+
return U.current.useId();
|
|
234
|
+
};
|
|
235
|
+
react_production_min.useImperativeHandle = function(a, b, e) {
|
|
236
|
+
return U.current.useImperativeHandle(a, b, e);
|
|
237
|
+
};
|
|
238
|
+
react_production_min.useInsertionEffect = function(a, b) {
|
|
239
|
+
return U.current.useInsertionEffect(a, b);
|
|
240
|
+
};
|
|
241
|
+
react_production_min.useLayoutEffect = function(a, b) {
|
|
242
|
+
return U.current.useLayoutEffect(a, b);
|
|
243
|
+
};
|
|
244
|
+
react_production_min.useMemo = function(a, b) {
|
|
245
|
+
return U.current.useMemo(a, b);
|
|
246
|
+
};
|
|
247
|
+
react_production_min.useReducer = function(a, b, e) {
|
|
248
|
+
return U.current.useReducer(a, b, e);
|
|
249
|
+
};
|
|
250
|
+
react_production_min.useRef = function(a) {
|
|
251
|
+
return U.current.useRef(a);
|
|
252
|
+
};
|
|
253
|
+
react_production_min.useState = function(a) {
|
|
254
|
+
return U.current.useState(a);
|
|
255
|
+
};
|
|
256
|
+
react_production_min.useSyncExternalStore = function(a, b, e) {
|
|
257
|
+
return U.current.useSyncExternalStore(a, b, e);
|
|
258
|
+
};
|
|
259
|
+
react_production_min.useTransition = function() {
|
|
260
|
+
return U.current.useTransition();
|
|
261
|
+
};
|
|
262
|
+
react_production_min.version = "18.3.1";
|
|
263
|
+
{
|
|
264
|
+
react.exports = react_production_min;
|
|
265
|
+
}
|
|
266
|
+
var reactExports = react.exports;
|
|
267
|
+
const index = /* @__PURE__ */ getDefaultExportFromCjs(reactExports);
|
|
268
|
+
export {
|
|
269
|
+
getDefaultExportFromCjs as g,
|
|
270
|
+
index as i,
|
|
271
|
+
reactExports as r
|
|
272
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const currentImports = {};
|
|
2
|
+
const exportSet = /* @__PURE__ */ new Set(["Module", "__esModule", "default", "_export_sfc"]);
|
|
3
|
+
let moduleMap = {
|
|
4
|
+
"./Plugin": () => {
|
|
5
|
+
dynamicLoadingCss([], false, "./Plugin");
|
|
6
|
+
return __federation_import("http://127.0.0.1:5010/assets/__federation_expose_Plugin-WvTCD-o4.js").then((module) => Object.keys(module).every((item) => exportSet.has(item)) ? () => module.default : () => module);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
const seen = {};
|
|
10
|
+
const dynamicLoadingCss = (cssFilePaths, dontAppendStylesToHead, exposeItemName) => {
|
|
11
|
+
const metaUrl = import.meta.url;
|
|
12
|
+
if (typeof metaUrl === "undefined") {
|
|
13
|
+
console.warn('The remote style takes effect only when the build.target option in the vite.config.ts file is higher than that of "es2020".');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const curUrl = metaUrl.substring(0, metaUrl.lastIndexOf("remoteEntry.js"));
|
|
17
|
+
const base = 'http://127.0.0.1:5010/';
|
|
18
|
+
'assets';
|
|
19
|
+
cssFilePaths.forEach((cssPath) => {
|
|
20
|
+
let href = "";
|
|
21
|
+
const baseUrl = base || curUrl;
|
|
22
|
+
if (baseUrl) {
|
|
23
|
+
const trimmer = {
|
|
24
|
+
trailing: (path) => path.endsWith("/") ? path.slice(0, -1) : path,
|
|
25
|
+
leading: (path) => path.startsWith("/") ? path.slice(1) : path
|
|
26
|
+
};
|
|
27
|
+
const isAbsoluteUrl = (url) => url.startsWith("http") || url.startsWith("//");
|
|
28
|
+
const cleanBaseUrl = trimmer.trailing(baseUrl);
|
|
29
|
+
const cleanCssPath = trimmer.leading(cssPath);
|
|
30
|
+
const cleanCurUrl = trimmer.trailing(curUrl);
|
|
31
|
+
if (isAbsoluteUrl(baseUrl)) {
|
|
32
|
+
href = [cleanBaseUrl, cleanCssPath].filter(Boolean).join("/");
|
|
33
|
+
} else {
|
|
34
|
+
if (cleanCurUrl.includes(cleanBaseUrl)) {
|
|
35
|
+
href = [cleanCurUrl, cleanCssPath].filter(Boolean).join("/");
|
|
36
|
+
} else {
|
|
37
|
+
href = [cleanCurUrl + cleanBaseUrl, cleanCssPath].filter(Boolean).join("/");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
} else {
|
|
41
|
+
href = cssPath;
|
|
42
|
+
}
|
|
43
|
+
if (dontAppendStylesToHead) {
|
|
44
|
+
const key = "css__frubeala_ui__" + exposeItemName;
|
|
45
|
+
window[key] = window[key] || [];
|
|
46
|
+
window[key].push(href);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (href in seen) return;
|
|
50
|
+
seen[href] = true;
|
|
51
|
+
const element = document.createElement("link");
|
|
52
|
+
element.rel = "stylesheet";
|
|
53
|
+
element.href = href;
|
|
54
|
+
document.head.appendChild(element);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
async function __federation_import(name) {
|
|
58
|
+
currentImports[name] ??= import(name);
|
|
59
|
+
return currentImports[name];
|
|
60
|
+
}
|
|
61
|
+
const get = (module) => {
|
|
62
|
+
if (!moduleMap[module]) throw new Error("Can not find remote module " + module);
|
|
63
|
+
return moduleMap[module]();
|
|
64
|
+
};
|
|
65
|
+
const init = (shareScope) => {
|
|
66
|
+
globalThis.__federation_shared__ = globalThis.__federation_shared__ || {};
|
|
67
|
+
Object.entries(shareScope).forEach(([key, value]) => {
|
|
68
|
+
for (const [versionKey, versionValue] of Object.entries(value)) {
|
|
69
|
+
const scope = versionValue.scope || "default";
|
|
70
|
+
globalThis.__federation_shared__[scope] = globalThis.__federation_shared__[scope] || {};
|
|
71
|
+
const shared = globalThis.__federation_shared__[scope];
|
|
72
|
+
(shared[key] = shared[key] || {})[versionKey] = versionValue;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
export {
|
|
77
|
+
dynamicLoadingCss,
|
|
78
|
+
get,
|
|
79
|
+
init
|
|
80
|
+
};
|
package/dist/index.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Frubeala UI Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
|
|
14
|
+
</html>
|
package/index.html
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Frubeala UI Plugin</title>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
|
|
14
|
+
</html>
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@decido/plugin-frubeala-ui",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Frubeala Ui plugin for Decido OS",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"lucide-react": "^0.575.0",
|
|
9
|
+
"zustand": "4.5.2"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@originjs/vite-plugin-federation": "^1.4.1",
|
|
13
|
+
"@types/react": "^18.2.0",
|
|
14
|
+
"@types/react-dom": "^18.2.0",
|
|
15
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
16
|
+
"typescript": "^5.0.0",
|
|
17
|
+
"vite": "^5.1.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "^18.3.1",
|
|
21
|
+
"react-dom": "^18.3.1",
|
|
22
|
+
"@decido/kernel-bridge": "1.0.0",
|
|
23
|
+
"@decido/shell": "1.0.0"
|
|
24
|
+
},
|
|
25
|
+
"license": "UNLICENSED",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"dev": "pnpm run build && pnpm run preview",
|
|
28
|
+
"build": "vite build",
|
|
29
|
+
"preview": "vite preview --port 5010 --strictPort",
|
|
30
|
+
"lint": "eslint src --ext ts,tsx"
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { MaciaPlugin } from '@decido/shell';
|
|
2
|
+
import { MainWidget } from './widgets/MainWidget';
|
|
3
|
+
|
|
4
|
+
const FrubealaUiPlugin: MaciaPlugin = {
|
|
5
|
+
id: 'decido-plugin-frubeala-ui',
|
|
6
|
+
name: 'Frubeala Ui',
|
|
7
|
+
version: '1.0.0',
|
|
8
|
+
description: 'Frubeala Ui plugin for Decido OS',
|
|
9
|
+
|
|
10
|
+
widgets: [
|
|
11
|
+
{
|
|
12
|
+
id: 'frubeala-ui-main',
|
|
13
|
+
pluginId: 'decido-plugin-frubeala-ui',
|
|
14
|
+
name: 'Frubeala Ui',
|
|
15
|
+
placement: 'panel',
|
|
16
|
+
component: MainWidget,
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
intents: [],
|
|
21
|
+
|
|
22
|
+
onRegister: async () => {
|
|
23
|
+
console.log('[Frubeala Ui] Plugin registered ✓');
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export default FrubealaUiPlugin;
|
package/src/manifest.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { MaciaPlugin, useShellStore } from '@decido/shell';
|
|
2
|
+
import { MainWidget } from './widgets/MainWidget';
|
|
3
|
+
|
|
4
|
+
export const FrubealaUiPlugin: MaciaPlugin = {
|
|
5
|
+
id: 'decido-plugin-frubeala-ui',
|
|
6
|
+
name: 'Frubeala Ui',
|
|
7
|
+
version: '1.0.0',
|
|
8
|
+
description: 'Frubeala Ui plugin for Decido OS',
|
|
9
|
+
|
|
10
|
+
widgets: [
|
|
11
|
+
{
|
|
12
|
+
id: 'frubeala-ui-main',
|
|
13
|
+
pluginId: 'decido-plugin-frubeala-ui',
|
|
14
|
+
name: 'Frubeala Ui',
|
|
15
|
+
placement: 'panel',
|
|
16
|
+
component: MainWidget,
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
|
|
20
|
+
intents: [],
|
|
21
|
+
|
|
22
|
+
onRegister: async () => {
|
|
23
|
+
console.log('[Frubeala Ui] Plugin registered ✓');
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { kernel } from '@decido/kernel-bridge';
|
|
3
|
+
import { Activity, Server, Network, Cpu, Database, Thermometer, ShieldAlert, Zap, RefreshCw } from 'lucide-react';
|
|
4
|
+
|
|
5
|
+
interface MainWidgetProps {
|
|
6
|
+
context?: any;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const MainWidget: React.FC<MainWidgetProps> = ({ context }) => {
|
|
10
|
+
const [systemStatus, setSystemStatus] = useState<any>(null);
|
|
11
|
+
const [networkState, setNetworkState] = useState<any>(null);
|
|
12
|
+
const [equipmentData, setEquipmentData] = useState<any>({});
|
|
13
|
+
const [loading, setLoading] = useState(true);
|
|
14
|
+
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
|
|
15
|
+
|
|
16
|
+
const fetchData = useCallback(async () => {
|
|
17
|
+
setLoading(true);
|
|
18
|
+
try {
|
|
19
|
+
const sysRes = await kernel.execute<any>('call_mcp_tool', {
|
|
20
|
+
serverName: 'frubeala-mcp',
|
|
21
|
+
toolName: 'get_system_status',
|
|
22
|
+
arguments: {}
|
|
23
|
+
});
|
|
24
|
+
if (sysRes && sysRes.content && sysRes.content.length > 0) {
|
|
25
|
+
setSystemStatus(JSON.parse(sysRes.content[0].text));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const netRes = await kernel.execute<any>('call_mcp_tool', {
|
|
29
|
+
serverName: 'frubeala-mcp',
|
|
30
|
+
toolName: 'check_network',
|
|
31
|
+
arguments: { interface: 'all' }
|
|
32
|
+
});
|
|
33
|
+
if (netRes && netRes.content && netRes.content.length > 0) {
|
|
34
|
+
setNetworkState(JSON.parse(netRes.content[0].text));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Fetch a few known equipment states
|
|
38
|
+
const equipmentIds = ['EQ-101', 'EQ-204'];
|
|
39
|
+
const eqData: any = {};
|
|
40
|
+
for (const id of equipmentIds) {
|
|
41
|
+
const eqRes = await kernel.execute<any>('call_mcp_tool', {
|
|
42
|
+
serverName: 'frubeala-mcp',
|
|
43
|
+
toolName: 'get_equipment_state',
|
|
44
|
+
arguments: { equipment_id: id }
|
|
45
|
+
});
|
|
46
|
+
if (eqRes && eqRes.content && eqRes.content.length > 0) {
|
|
47
|
+
eqData[id] = JSON.parse(eqRes.content[0].text);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
setEquipmentData(eqData);
|
|
51
|
+
setLastUpdated(new Date());
|
|
52
|
+
} catch (e) {
|
|
53
|
+
console.error("[Frubeala UI] Failed to fetch data via MCP:", e);
|
|
54
|
+
} finally {
|
|
55
|
+
setLoading(false);
|
|
56
|
+
}
|
|
57
|
+
}, []);
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
fetchData();
|
|
61
|
+
const interval = setInterval(fetchData, 30000); // Auto refresh every 30s
|
|
62
|
+
return () => clearInterval(interval);
|
|
63
|
+
}, [fetchData]);
|
|
64
|
+
|
|
65
|
+
const renderCard = (title: string, icon: React.ReactNode, value: React.ReactNode, subtext?: string, statusColor: string = 'text-cyan-400', borderColor: string = 'border-cyan-500/20') => (
|
|
66
|
+
<div className={`bg-zinc-900/40 backdrop-blur-md border ${borderColor} rounded-xl p-5 flex flex-col relative overflow-hidden group`}>
|
|
67
|
+
<div className="absolute top-0 right-0 w-24 h-24 bg-gradient-to-br from-white/5 to-transparent rounded-bl-full pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity" />
|
|
68
|
+
<div className="flex items-center justify-between mb-4">
|
|
69
|
+
<span className="text-zinc-400 text-xs uppercase tracking-widest font-bold">{title}</span>
|
|
70
|
+
<div className={`p-2 rounded-lg bg-zinc-800/50 ${statusColor}`}>{icon}</div>
|
|
71
|
+
</div>
|
|
72
|
+
<div className="text-2xl font-black text-white tracking-tight mb-1">{value}</div>
|
|
73
|
+
{subtext && <div className="text-zinc-500 text-xs">{subtext}</div>}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<div className="w-full h-full p-6 bg-[#09090b] text-white flex flex-col gap-6 font-['Inter',system-ui,sans-serif] overflow-y-auto">
|
|
79
|
+
{/* Header */}
|
|
80
|
+
<div className="flex justify-between items-end border-b border-white/5 pb-4">
|
|
81
|
+
<div>
|
|
82
|
+
<h1 className="text-3xl font-black tracking-tighter bg-gradient-to-r from-emerald-400 via-cyan-400 to-blue-500 bg-clip-text text-transparent flex items-center gap-3">
|
|
83
|
+
<Activity className="w-8 h-8 text-emerald-400" />
|
|
84
|
+
Frubeala Control Tower
|
|
85
|
+
</h1>
|
|
86
|
+
<p className="text-zinc-500 text-sm mt-1">Real-time Industrial IoT Telemetry & Agent Operations</p>
|
|
87
|
+
</div>
|
|
88
|
+
<div className="flex items-center gap-4">
|
|
89
|
+
{lastUpdated && (
|
|
90
|
+
<div className="text-xs text-zinc-500 font-mono">
|
|
91
|
+
Last Sync: {lastUpdated.toLocaleTimeString()}
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
<button
|
|
95
|
+
onClick={fetchData}
|
|
96
|
+
disabled={loading}
|
|
97
|
+
className="p-2 bg-white/5 hover:bg-white/10 border border-white/10 rounded-lg text-zinc-300 transition-all flex items-center gap-2"
|
|
98
|
+
>
|
|
99
|
+
<RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
|
|
100
|
+
</button>
|
|
101
|
+
<div className={`px-3 py-1.5 rounded-full text-xs font-bold uppercase tracking-wider flex items-center gap-2 border ${systemStatus?.status === 'OK' ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30' : 'bg-amber-500/10 text-amber-400 border-amber-500/30'}`}>
|
|
102
|
+
<div className={`w-2 h-2 rounded-full ${systemStatus?.status === 'OK' ? 'bg-emerald-400 animate-pulse' : 'bg-amber-400'}`} />
|
|
103
|
+
{systemStatus?.status || 'Unknown'}
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
{loading && !systemStatus && (
|
|
109
|
+
<div className="flex-1 flex items-center justify-center flex-col gap-4">
|
|
110
|
+
<div className="w-8 h-8 border-4 border-cyan-500/30 border-t-cyan-400 rounded-full animate-spin" />
|
|
111
|
+
<p className="text-cyan-400 text-sm font-mono tracking-widest animate-pulse">ESTABLISHING SECURE MCP LINK...</p>
|
|
112
|
+
</div>
|
|
113
|
+
)}
|
|
114
|
+
|
|
115
|
+
{systemStatus && (
|
|
116
|
+
<>
|
|
117
|
+
{/* System Metrics */}
|
|
118
|
+
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
119
|
+
{renderCard('CPU Load', <Cpu className="w-5 h-5" />, `${systemStatus.cpu_usage_percent}%`, 'Compute footprint')}
|
|
120
|
+
{renderCard('Memory Usage', <Database className="w-5 h-5" />, `${systemStatus.memory_usage_percent}%`, 'Volatile footprint')}
|
|
121
|
+
{renderCard('Active Connections', <Network className="w-5 h-5" />, networkState?.connections || '0', 'Socket streams', 'text-blue-400')}
|
|
122
|
+
{renderCard('Uptime', <Server className="w-5 h-5" />, `${Math.floor((systemStatus.uptime_seconds || 0) / 3600)}h`, 'Continuous operation', 'text-purple-400')}
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
{/* Equipment Status */}
|
|
126
|
+
<div className="mt-4">
|
|
127
|
+
<h3 className="text-xs font-bold text-zinc-400 uppercase tracking-widest mb-4 flex items-center gap-2">
|
|
128
|
+
<Server className="w-4 h-4" />
|
|
129
|
+
Industrial Equipment Status
|
|
130
|
+
</h3>
|
|
131
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
132
|
+
{Object.entries(equipmentData).length === 0 ? (
|
|
133
|
+
<div className="col-span-2 p-8 border border-white/5 rounded-xl border-dashed flex flex-col items-center justify-center text-zinc-500">
|
|
134
|
+
<p>No equipment telemetry available via MCP.</p>
|
|
135
|
+
</div>
|
|
136
|
+
) : (
|
|
137
|
+
Object.entries(equipmentData).map(([id, data]: [string, any]) => (
|
|
138
|
+
<div key={id} className="bg-zinc-900/60 border border-white/5 p-4 rounded-xl">
|
|
139
|
+
<div className="flex justify-between items-center mb-6">
|
|
140
|
+
<div className="flex items-center gap-3">
|
|
141
|
+
<div className="w-10 h-10 rounded-lg bg-indigo-500/10 border border-indigo-500/20 flex items-center justify-center text-indigo-400">
|
|
142
|
+
<Zap className="w-5 h-5" />
|
|
143
|
+
</div>
|
|
144
|
+
<div>
|
|
145
|
+
<h4 className="font-bold text-white text-lg tracking-tight">{data.equipment_id}</h4>
|
|
146
|
+
<p className="text-zinc-500 text-xs">Lathe Station</p>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
<div className={`px-2.5 py-1 rounded text-[10px] font-bold uppercase tracking-widest ${data.state === 'running' ? 'bg-emerald-500/20 text-emerald-400' : 'bg-red-500/20 text-red-400'}`}>
|
|
150
|
+
{data.state}
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<div className="grid grid-cols-2 gap-3 mb-4">
|
|
155
|
+
<div className="bg-black/40 rounded-lg p-3">
|
|
156
|
+
<div className="flex items-center gap-2 text-zinc-500 mb-1">
|
|
157
|
+
<Thermometer className="w-3.5 h-3.5" />
|
|
158
|
+
<span className="text-[10px] uppercase font-bold tracking-wider">Temperature</span>
|
|
159
|
+
</div>
|
|
160
|
+
<div className="text-lg font-mono text-amber-400">{data.temperature}°C</div>
|
|
161
|
+
</div>
|
|
162
|
+
<div className="bg-black/40 rounded-lg p-3">
|
|
163
|
+
<div className="flex items-center gap-2 text-zinc-500 mb-1">
|
|
164
|
+
<Activity className="w-3.5 h-3.5" />
|
|
165
|
+
<span className="text-[10px] uppercase font-bold tracking-wider">Vibration</span>
|
|
166
|
+
</div>
|
|
167
|
+
<div className="text-lg font-mono text-cyan-400">{data.vibration} <span className="text-xs text-zinc-600">mm/s</span></div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
{/* Error Alert if any */}
|
|
172
|
+
{data.state === 'error' && (
|
|
173
|
+
<div className="mt-3 p-3 rounded-lg bg-red-500/10 border border-red-500/20 flex gap-3 items-start">
|
|
174
|
+
<ShieldAlert className="w-4 h-4 text-red-400 shrink-0 mt-0.5" />
|
|
175
|
+
<p className="text-xs text-red-300">Anomalous reading detected. Recommend preventive maintenance cycle immediately.</p>
|
|
176
|
+
</div>
|
|
177
|
+
)}
|
|
178
|
+
</div>
|
|
179
|
+
))
|
|
180
|
+
)}
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</>
|
|
184
|
+
)}
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
};
|