@viasoftbr/shared-ui 0.0.1 → 0.0.2

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.
Files changed (94) hide show
  1. package/dist/components/RemoteModule.d.ts +8 -0
  2. package/dist/components/display/Accordion.d.ts +8 -0
  3. package/dist/components/display/Section.d.ts +19 -0
  4. package/dist/components/display/Skeleton.d.ts +21 -0
  5. package/dist/components/display/index.d.ts +4 -0
  6. package/dist/components/encoder/DvB.d.ts +53 -0
  7. package/dist/components/encoder/Livecast.d.ts +37 -0
  8. package/dist/components/encoder/ViewLog.d.ts +5 -0
  9. package/dist/components/encoder/index.d.ts +4 -0
  10. package/dist/components/general/Copy2Clipboard.d.ts +4 -0
  11. package/dist/components/general/GridSelectionModal.d.ts +24 -0
  12. package/dist/components/general/Modal.d.ts +17 -0
  13. package/dist/components/general/Validation.d.ts +6 -0
  14. package/dist/components/general/index.d.ts +5 -0
  15. package/dist/components/groups/AudioGroup.d.ts +26 -0
  16. package/dist/components/groups/FilterGroup.d.ts +3 -0
  17. package/dist/components/groups/Middleware/Auth.d.ts +14 -0
  18. package/dist/components/groups/Middleware/Channels.d.ts +26 -0
  19. package/dist/components/groups/Middleware/MOS.d.ts +24 -0
  20. package/dist/components/groups/Middleware/Service.d.ts +16 -0
  21. package/dist/components/groups/Middleware/index.d.ts +5 -0
  22. package/dist/components/groups/PreviewGroup.d.ts +3 -0
  23. package/dist/components/groups/ProtocolGroup.d.ts +10 -0
  24. package/dist/components/groups/VideoGroup.d.ts +3 -0
  25. package/dist/components/groups/index.d.ts +7 -0
  26. package/dist/components/index.d.ts +11 -0
  27. package/dist/components/input/CheckboxField.d.ts +9 -0
  28. package/dist/components/input/ColorField.d.ts +9 -0
  29. package/dist/components/input/DatePicker.d.ts +12 -0
  30. package/dist/components/input/EditInPlaceField.d.ts +7 -0
  31. package/dist/components/input/InputField.d.ts +15 -0
  32. package/dist/components/input/Protocol.d.ts +10 -0
  33. package/dist/components/input/RangeField.d.ts +13 -0
  34. package/dist/components/input/SelectField.d.ts +13 -0
  35. package/dist/components/input/SliderField.d.ts +15 -0
  36. package/dist/components/input/SwitchField.d.ts +11 -0
  37. package/dist/components/input/index.d.ts +11 -0
  38. package/dist/components/main/Footer.d.ts +2 -0
  39. package/dist/components/main/Header.d.ts +7 -0
  40. package/dist/components/main/PageHeader.d.ts +14 -0
  41. package/dist/components/main/SaveDiscard.d.ts +13 -0
  42. package/dist/components/main/Sidebar.d.ts +10 -0
  43. package/dist/components/main/index.d.ts +6 -0
  44. package/dist/components/network/AddNetwork.d.ts +6 -0
  45. package/dist/components/network/InterfacesTable.d.ts +19 -0
  46. package/dist/components/network/InterfacesTimeseries.d.ts +21 -0
  47. package/dist/components/network/index.d.ts +4 -0
  48. package/dist/components/network/validators.d.ts +7 -0
  49. package/dist/components/system/RequireAuth.d.ts +8 -0
  50. package/dist/components/system/Wizard.d.ts +6 -0
  51. package/dist/components/system/index.d.ts +3 -0
  52. package/dist/components/xcoder/Fflog.d.ts +5 -0
  53. package/dist/components/xcoder/LiveLog.d.ts +5 -0
  54. package/dist/components/xcoder/Metrics.d.ts +8 -0
  55. package/dist/components/xcoder/Panel.d.ts +6 -0
  56. package/dist/components/xcoder/Preview.d.ts +11 -0
  57. package/dist/components/xcoder/StreamControl.d.ts +5 -0
  58. package/dist/components/xcoder/VUMeter.d.ts +8 -0
  59. package/dist/components/xcoder/VideoPlayer.d.ts +13 -0
  60. package/dist/components/xcoder/index.d.ts +8 -0
  61. package/dist/components.js +182 -117
  62. package/dist/context/AuthContext.d.ts +17 -0
  63. package/dist/context/ThemeContext.d.ts +11 -0
  64. package/dist/context/index.d.ts +3 -0
  65. package/dist/context.js +25 -9
  66. package/dist/hooks/index.d.ts +3 -0
  67. package/dist/hooks/useApi.d.ts +1 -0
  68. package/dist/hooks/useAvailableSubservices.d.ts +13 -0
  69. package/dist/hooks/useSettings.d.ts +45 -0
  70. package/dist/hooks.js +25 -9
  71. package/dist/i18n.d.ts +2 -0
  72. package/dist/index.d.ts +6 -0
  73. package/dist/index.js +55897 -0
  74. package/dist/services/api.d.ts +23 -0
  75. package/dist/services/auth.d.ts +15 -0
  76. package/dist/services/discovery.d.ts +12 -0
  77. package/dist/services/hostConfig.d.ts +20 -0
  78. package/dist/services/index.d.ts +9 -0
  79. package/dist/services/loadRemoteModule.d.ts +9 -0
  80. package/dist/services/metadataLoader.d.ts +9 -0
  81. package/dist/services/registry.d.ts +42 -0
  82. package/dist/services/users.d.ts +18 -0
  83. package/dist/services/wizard.d.ts +3 -0
  84. package/dist/services.js +61 -26
  85. package/dist/types/alarm.d.ts +21 -0
  86. package/dist/types/auth.d.ts +18 -0
  87. package/dist/types/group.d.ts +32 -0
  88. package/dist/types/index.d.ts +6 -0
  89. package/dist/types/module.d.ts +13 -0
  90. package/dist/types/plugin.types.d.ts +30 -0
  91. package/dist/types/protocol.d.ts +12 -0
  92. package/dist/types/websocket.d.ts +27 -0
  93. package/dist/types/wizard.d.ts +12 -0
  94. package/package.json +17 -1
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ export interface NetworkInterface {
3
+ interface_name: string;
4
+ ip: string;
5
+ rx_rate: number;
6
+ tx_rate: number;
7
+ mac?: string;
8
+ operstate?: string;
9
+ speed?: string;
10
+ duplex?: string;
11
+ }
12
+ interface Props {
13
+ snapshot: NetworkInterface[];
14
+ bufferSeconds?: number;
15
+ height?: number;
16
+ mode?: 'download' | 'upload' | 'split';
17
+ minBurnInSnapshots?: number;
18
+ hideOptions?: boolean[];
19
+ }
20
+ declare const InterfacesTimeseries: React.FC<Props>;
21
+ export default InterfacesTimeseries;
@@ -0,0 +1,4 @@
1
+ import AddNetwork from "./AddNetwork.tsx";
2
+ import InterfacesTable from "./InterfacesTable.tsx";
3
+ import InterfacesTimeseries from "./InterfacesTimeseries.tsx";
4
+ export { AddNetwork, InterfacesTable, InterfacesTimeseries, };
@@ -0,0 +1,7 @@
1
+ export declare const isValidIPv4: (ip: string) => boolean;
2
+ export declare const isValidIPv6: (ip: string) => boolean;
3
+ declare const _default: {
4
+ isValidIPv4: (ip: string) => boolean;
5
+ isValidIPv6: (ip: string) => boolean;
6
+ };
7
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import React, { JSX } from 'react';
2
+ import { Role } from '../../types/auth';
3
+ interface RequireAuthProps {
4
+ level?: Role;
5
+ children: JSX.Element;
6
+ }
7
+ declare const RequireAuth: React.FC<RequireAuthProps>;
8
+ export default RequireAuth;
@@ -0,0 +1,6 @@
1
+ export type ConfigWizardProps = {
2
+ basePath?: string;
3
+ onComplete?: () => void;
4
+ };
5
+ declare const ConfigWizard: React.FC<ConfigWizardProps>;
6
+ export default ConfigWizard;
@@ -0,0 +1,3 @@
1
+ import RequireAuth from "./RequireAuth";
2
+ import ConfigWizard from "./Wizard";
3
+ export { ConfigWizard, RequireAuth, };
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ declare const Fflog: React.FC<{
3
+ index: number;
4
+ }>;
5
+ export default Fflog;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ declare const LiveLog: React.FC<{
3
+ encoder: string;
4
+ }>;
5
+ export default LiveLog;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ declare const MetricBar: React.FC<{
3
+ label: string;
4
+ value: number;
5
+ suffix: string;
6
+ color: 'blue' | 'purple' | 'green' | 'cyan' | 'pink';
7
+ }>;
8
+ export default MetricBar;
@@ -0,0 +1,6 @@
1
+ import React from 'react';
2
+ interface PanelProps {
3
+ index: number;
4
+ }
5
+ declare const EncoderDecoderPanel: React.FC<PanelProps>;
6
+ export default EncoderDecoderPanel;
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ interface PreviewProps {
3
+ index: number;
4
+ setVuPts: (value: number) => void;
5
+ showDlog?: boolean;
6
+ showFflog?: boolean;
7
+ showStreamControl?: boolean;
8
+ orientation?: 'horizontal' | 'vertical';
9
+ }
10
+ declare const Preview: React.FC<PreviewProps>;
11
+ export default Preview;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ declare const StreamControl: React.FC<{
3
+ index: number;
4
+ }>;
5
+ export default StreamControl;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ declare const VUBar: React.FC<{
3
+ index: number;
4
+ volume: any[];
5
+ width?: string;
6
+ displayMarks?: boolean;
7
+ }>;
8
+ export default VUBar;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ interface VUChannel {
3
+ left: number;
4
+ right: number;
5
+ }
6
+ interface VideoPlayerProps {
7
+ pgmIndex: number;
8
+ vuChannels: number;
9
+ setVuPts: (value: number) => void;
10
+ setVuChannels: (value: VUChannel[]) => void;
11
+ }
12
+ declare const VideoPlayer: React.FC<VideoPlayerProps>;
13
+ export default VideoPlayer;
@@ -0,0 +1,8 @@
1
+ import Fflog from "./Fflog";
2
+ import MetricBar from "./Metrics";
3
+ import Panel from "./Panel";
4
+ import Preview from "./Preview";
5
+ import StreamControl from "./StreamControl";
6
+ import VideoPlayer from "./VideoPlayer";
7
+ import VUBar from "./VUMeter";
8
+ export { Fflog, MetricBar, Panel, Preview, StreamControl, VideoPlayer, VUBar };
@@ -26178,19 +26178,36 @@ var {
26178
26178
  } = axios_default;
26179
26179
 
26180
26180
  // src/services/api.ts
26181
- var getApiBaseUrl = () => {
26182
- if (typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL) {
26183
- return import.meta.env.VITE_API_BASE_URL;
26181
+ var normalizeOrigin = (raw) => {
26182
+ if (!raw)
26183
+ return "";
26184
+ if (/^https?:\/\//i.test(raw) || /^wss?:\/\//i.test(raw))
26185
+ return raw.replace(/\/$/, "");
26186
+ return `http://${raw.replace(/\/$/, "")}`;
26187
+ };
26188
+ var getApiOrigin = () => {
26189
+ try {
26190
+ if (typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL) {
26191
+ return normalizeOrigin(import.meta.env.VITE_API_BASE_URL);
26192
+ }
26193
+ } catch (e10) {
26184
26194
  }
26185
- return "192.168.100.9:3000";
26195
+ if (typeof window !== "undefined") {
26196
+ const win = window;
26197
+ if (win.__VIASOFT_API_BASE_URL)
26198
+ return normalizeOrigin(win.__VIASOFT_API_BASE_URL);
26199
+ if (window.location && window.location.origin)
26200
+ return window.location.origin.replace(/\/$/, "");
26201
+ }
26202
+ return "http://localhost:3000";
26186
26203
  };
26187
- var serverUrl = getApiBaseUrl();
26204
+ var apiOrigin = getApiOrigin();
26188
26205
  var api = axios_default.create({
26189
- baseURL: `http://${serverUrl}`,
26206
+ baseURL: apiOrigin,
26190
26207
  timeout: 1e4
26191
26208
  });
26192
26209
  var authApi = axios_default.create({
26193
- baseURL: `http://${serverUrl}`,
26210
+ baseURL: apiOrigin,
26194
26211
  timeout: 1e4
26195
26212
  });
26196
26213
  function getAccessToken() {
@@ -26354,7 +26371,7 @@ var fetchApi = {
26354
26371
  }
26355
26372
  }
26356
26373
  };
26357
- var serverOrigin = `http://${serverUrl}`;
26374
+ var serverOrigin = apiOrigin;
26358
26375
  function buildWsUrl(path = "/") {
26359
26376
  try {
26360
26377
  const origin2 = new URL(serverOrigin);
@@ -26364,8 +26381,9 @@ function buildWsUrl(path = "/") {
26364
26381
  origin2.pathname = path;
26365
26382
  return origin2.toString();
26366
26383
  } catch (e10) {
26367
- const proto = serverOrigin.startsWith("https") ? "wss" : "ws";
26368
- return `${proto}://${serverUrl}${path.startsWith("/") ? path : "/" + path}`;
26384
+ const proto = apiOrigin.startsWith("https") ? "wss" : "ws";
26385
+ const host = apiOrigin.replace(/^https?:\/\//, "").replace(/\/$/, "");
26386
+ return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
26369
26387
  }
26370
26388
  }
26371
26389
  async function decodeFfurl(ffurl) {
@@ -26391,7 +26409,6 @@ function subscribeToWebsocket(url, onMessage) {
26391
26409
  // src/services/loadRemoteModule.ts
26392
26410
  import * as React4 from "react";
26393
26411
  import * as ReactDOM2 from "react-dom";
26394
- var loadedContainers = /* @__PURE__ */ new Map();
26395
26412
  var sharedScopeInitialized = false;
26396
26413
  function getSharedScope() {
26397
26414
  if (!globalThis.__federation_shared__) {
@@ -26418,28 +26435,46 @@ function getSharedScope() {
26418
26435
  }
26419
26436
  return globalThis.__federation_shared__;
26420
26437
  }
26438
+ var loadedContainers = /* @__PURE__ */ new Map();
26439
+ var initializedContainers = /* @__PURE__ */ new Set();
26421
26440
  async function loadContainer(url) {
26422
26441
  if (loadedContainers.has(url)) {
26423
- const cached = loadedContainers.get(url);
26424
- if (cached)
26425
- return cached;
26442
+ return loadedContainers.get(url);
26426
26443
  }
26427
- const promise = import(
26428
- /* @vite-ignore */
26429
- url
26430
- );
26431
- loadedContainers.set(url, promise);
26432
- return promise;
26444
+ const loadPromise = (async () => {
26445
+ try {
26446
+ const container = await import(
26447
+ /* @vite-ignore */
26448
+ url
26449
+ );
26450
+ if (container.init && !initializedContainers.has(url)) {
26451
+ await container.init(getSharedScope());
26452
+ initializedContainers.add(url);
26453
+ }
26454
+ return container;
26455
+ } catch (error) {
26456
+ loadedContainers.delete(url);
26457
+ initializedContainers.delete(url);
26458
+ throw error;
26459
+ }
26460
+ })();
26461
+ loadedContainers.set(url, loadPromise);
26462
+ return loadPromise;
26433
26463
  }
26434
26464
  async function loadRemoteModule(config) {
26435
26465
  const container = await loadContainer(config.url);
26436
- if (!container || typeof container.init !== "function") {
26437
- throw new Error(`Container inv\xE1lido: ${config.scope}`);
26466
+ if (!container || typeof container.get !== "function") {
26467
+ throw new Error(`Container inv\xE1lido ou sem m\xE9todo get: ${config.scope}`);
26468
+ }
26469
+ if (typeof container.dynamicLoadingCss === "function") {
26470
+ try {
26471
+ await container.dynamicLoadingCss([]);
26472
+ } catch (err) {
26473
+ console.warn(`Aviso: Falha ao carregar CSS global do remote ${config.scope}`, err);
26474
+ }
26438
26475
  }
26439
- const shareScope = getSharedScope();
26440
- container.init(shareScope);
26441
26476
  const factory2 = await container.get(config.module);
26442
- const moduleExports = factory2();
26477
+ const moduleExports = await factory2();
26443
26478
  if (moduleExports && typeof moduleExports === "object" && "default" in moduleExports) {
26444
26479
  return moduleExports.default;
26445
26480
  }
@@ -26473,7 +26508,7 @@ var MetadataLoader = class {
26473
26508
  );
26474
26509
  }
26475
26510
  metadata.forEach((page, index3) => {
26476
- if (!page.id || !page.name || !page.path || !page.bundleUrl) {
26511
+ if (!page.id || !page.name || !page.path || !page.url) {
26477
26512
  throw new Error(
26478
26513
  `Invalid page metadata at index ${index3}: missing required fields`
26479
26514
  );
@@ -37661,9 +37696,9 @@ function buildSidebarItems(pages, modules) {
37661
37696
  isModule: false
37662
37697
  }));
37663
37698
  const fromModules = modules.map((m8) => ({
37664
- id: `mod:${m8.name}`,
37665
- label: m8.label,
37666
- to: `/page/${m8.name}`,
37699
+ id: `mod:${m8.id}`,
37700
+ label: m8.label ?? m8.name,
37701
+ to: `/page/${m8.id}`,
37667
37702
  group: m8.group || "Other",
37668
37703
  version: m8.module,
37669
37704
  iconName: m8.icon,
@@ -37699,13 +37734,29 @@ var Sidebar = ({ pages = [], modules = [], isOpen, setIsOpen }) => {
37699
37734
  };
37700
37735
  const isItemActive = (item) => location2.pathname === item.to;
37701
37736
  useEffect21(() => {
37702
- const all3 = {};
37703
- for (const groupName of Object.keys(itemGroups)) {
37704
- const hasActive = itemGroups[groupName].some((i14) => isItemActive(i14));
37705
- all3[groupName] = hasActive;
37706
- }
37707
- setExpandedGroups(all3);
37708
- }, [open, location2.pathname, allItems]);
37737
+ setExpandedGroups((prev) => {
37738
+ const next = { ...prev };
37739
+ let changed = false;
37740
+ for (const groupName of Object.keys(itemGroups)) {
37741
+ const hasActive = itemGroups[groupName].some((i14) => isItemActive(i14));
37742
+ if (prev[groupName] === void 0) {
37743
+ next[groupName] = hasActive;
37744
+ if (prev[groupName] !== next[groupName])
37745
+ changed = true;
37746
+ }
37747
+ }
37748
+ for (const groupName of Object.keys(itemGroups)) {
37749
+ const hasActive = itemGroups[groupName].some((i14) => isItemActive(i14));
37750
+ if (hasActive && !next[groupName]) {
37751
+ next[groupName] = true;
37752
+ changed = true;
37753
+ }
37754
+ }
37755
+ if (!changed)
37756
+ return prev;
37757
+ return next;
37758
+ });
37759
+ }, [location2.pathname, itemGroups]);
37709
37760
  const groupOrder = ["Encoder", "Decoder", "Network", "Playout", "Audio", "System", "Other"];
37710
37761
  const sortedGroupNames = Object.keys(itemGroups).sort((a23, b9) => {
37711
37762
  const ai = groupOrder.indexOf(a23);
@@ -37724,7 +37775,6 @@ var Sidebar = ({ pages = [], modules = [], isOpen, setIsOpen }) => {
37724
37775
  }
37725
37776
  return true;
37726
37777
  });
37727
- const totalModules = allItems.length;
37728
37778
  return /* @__PURE__ */ jsxs32(Fragment7, { children: [
37729
37779
  /* @__PURE__ */ jsx38(
37730
37780
  "button",
@@ -37735,7 +37785,7 @@ var Sidebar = ({ pages = [], modules = [], isOpen, setIsOpen }) => {
37735
37785
  children: open ? /* @__PURE__ */ jsx38(X, { className: "w-6 h-6" }) : /* @__PURE__ */ jsx38(Menu, { className: "w-6 h-6" })
37736
37786
  }
37737
37787
  ),
37738
- /* @__PURE__ */ jsxs32(
37788
+ /* @__PURE__ */ jsx38(
37739
37789
  "div",
37740
37790
  {
37741
37791
  className: [
@@ -37745,90 +37795,81 @@ var Sidebar = ({ pages = [], modules = [], isOpen, setIsOpen }) => {
37745
37795
  "transform transition-transform duration-300 ease-in-out",
37746
37796
  open ? "translate-x-0" : "-translate-x-full"
37747
37797
  ].join(" "),
37748
- children: [
37749
- /* @__PURE__ */ jsxs32("nav", { className: "flex-1 px-4 py-4 my-12 overflow-y-auto custom-scroll h-[calc(100%-90px)]", children: [
37750
- /* @__PURE__ */ jsxs32(
37751
- Link3,
37752
- {
37753
- to: "/",
37754
- className: `flex items-center px-3 py-2 mb-4 text-sm font-medium rounded-md transition-colors hover:bg-purple-700
37798
+ children: /* @__PURE__ */ jsxs32("nav", { className: "flex-1 px-4 py-4 my-12 overflow-y-auto custom-scroll h-[calc(100%-90px)]", children: [
37799
+ /* @__PURE__ */ jsxs32(
37800
+ Link3,
37801
+ {
37802
+ to: "/",
37803
+ className: `flex items-center px-3 py-2 mb-4 text-sm font-medium rounded-md transition-colors hover:bg-purple-700
37755
37804
  ${theme === "dark" || location2.pathname === "/" ? "text-neutral-50" : "text-primary hover:text-neutral-50"}
37756
37805
  ${location2.pathname === "/" ? "bg-purple-700" : ""}
37757
37806
  `,
37758
- onClick: () => setIsOpen?.(false),
37759
- children: [
37760
- /* @__PURE__ */ jsx38(House, { className: "w-5 h-5 mr-3" }),
37761
- "Home"
37762
- ]
37763
- }
37764
- ),
37765
- /* @__PURE__ */ jsx38("div", { className: "space-y-2", children: filteredGroupNames.map((groupName) => {
37766
- const items = itemGroups[groupName];
37767
- const isExpanded = expandedGroups[groupName];
37768
- return /* @__PURE__ */ jsxs32("div", { className: "space-y-1", children: [
37769
- /* @__PURE__ */ jsxs32(
37770
- "button",
37807
+ onClick: () => setIsOpen?.(false),
37808
+ children: [
37809
+ /* @__PURE__ */ jsx38(House, { className: "w-5 h-5 mr-3" }),
37810
+ "Home"
37811
+ ]
37812
+ }
37813
+ ),
37814
+ /* @__PURE__ */ jsx38("div", { className: "space-y-2", children: filteredGroupNames.map((groupName) => {
37815
+ const items = itemGroups[groupName];
37816
+ const isExpanded = expandedGroups[groupName];
37817
+ return /* @__PURE__ */ jsxs32("div", { className: "space-y-1", children: [
37818
+ /* @__PURE__ */ jsxs32(
37819
+ "button",
37820
+ {
37821
+ type: "button",
37822
+ onClick: () => toggleGroup(groupName),
37823
+ className: `flex items-center justify-between w-full px-3 py-2 text-sm font-medium rounded-md transition-colors ${theme === "dark" ? "text-neutral-300 hover:text-neutral-100 hover:bg-neutral-800" : "text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100"}`,
37824
+ "aria-expanded": isExpanded,
37825
+ "aria-controls": `group-${groupName}`,
37826
+ children: [
37827
+ /* @__PURE__ */ jsxs32("div", { className: "flex items-center", children: [
37828
+ /* @__PURE__ */ jsx38(GroupIcon, { groupName }),
37829
+ /* @__PURE__ */ jsx38("span", { className: "ml-2", children: groupName }),
37830
+ /* @__PURE__ */ jsx38("span", { className: `ml-2 px-2 py-0.5 text-xs rounded-full ${theme === "dark" ? "bg-neutral-800 text-neutral-400" : "bg-neutral-200 text-neutral-600"}`, children: items.length })
37831
+ ] }),
37832
+ /* @__PURE__ */ jsx38(
37833
+ "svg",
37834
+ {
37835
+ className: `w-4 h-4 transition-transform ${isExpanded ? "rotate-90" : ""}`,
37836
+ fill: "none",
37837
+ stroke: "currentColor",
37838
+ viewBox: "0 0 24 24",
37839
+ "aria-hidden": "true",
37840
+ children: /* @__PURE__ */ jsx38("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
37841
+ }
37842
+ )
37843
+ ]
37844
+ }
37845
+ ),
37846
+ isExpanded && /* @__PURE__ */ jsx38("div", { id: `group-${groupName}`, className: "ml-4 space-y-1", children: items.filter((item) => !(item.id === "authentication" && user?.role === "operator" /* Operator */)).filter((item) => !(item.id === "mod:authentication" && user?.role === "operator" /* Operator */)).map((item) => {
37847
+ const isActive = isItemActive(item);
37848
+ return /* @__PURE__ */ jsxs32(
37849
+ Link3,
37771
37850
  {
37772
- type: "button",
37773
- onClick: () => toggleGroup(groupName),
37774
- className: `flex items-center justify-between w-full px-3 py-2 text-sm font-medium rounded-md transition-colors ${theme === "dark" ? "text-neutral-300 hover:text-neutral-100 hover:bg-neutral-800" : "text-neutral-600 hover:text-neutral-800 hover:bg-neutral-100"}`,
37775
- "aria-expanded": isExpanded,
37776
- "aria-controls": `group-${groupName}`,
37851
+ to: item.to,
37852
+ onClick: () => setIsOpen?.(false),
37853
+ className: `flex items-center px-3 py-2 text-sm rounded-md transition-colors hover:text-purple-400 ${isActive ? "bg-purple-700 bg-opacity-20 text-purple-400 border-l-4 border-purple-900" : theme === "dark" ? "text-neutral-400 hover:bg-neutral-800" : "text-neutral-600 hover:bg-neutral-100"}`,
37854
+ title: item.description,
37777
37855
  children: [
37778
- /* @__PURE__ */ jsxs32("div", { className: "flex items-center", children: [
37779
- /* @__PURE__ */ jsx38(GroupIcon, { groupName }),
37780
- /* @__PURE__ */ jsx38("span", { className: "ml-2", children: groupName }),
37781
- /* @__PURE__ */ jsx38("span", { className: `ml-2 px-2 py-0.5 text-xs rounded-full ${theme === "dark" ? "bg-neutral-800 text-neutral-400" : "bg-neutral-200 text-neutral-600"}`, children: items.length })
37856
+ /* @__PURE__ */ jsx38(ItemIcon, { item }),
37857
+ /* @__PURE__ */ jsxs32("div", { className: "ml-2 flex-1", children: [
37858
+ /* @__PURE__ */ jsx38("div", { className: "font-medium", children: item.label }),
37859
+ item.description && /* @__PURE__ */ jsx38("div", { className: `text-xs truncate w-28 ${theme === "dark" ? "text-neutral-500" : "text-neutral-600"}`, children: item.description })
37782
37860
  ] }),
37783
- /* @__PURE__ */ jsx38(
37784
- "svg",
37785
- {
37786
- className: `w-4 h-4 transition-transform ${isExpanded ? "rotate-90" : ""}`,
37787
- fill: "none",
37788
- stroke: "currentColor",
37789
- viewBox: "0 0 24 24",
37790
- "aria-hidden": "true",
37791
- children: /* @__PURE__ */ jsx38("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5l7 7-7 7" })
37792
- }
37793
- )
37861
+ item.version && /* @__PURE__ */ jsxs32("span", { className: `text-xs px-1.5 py-0.5 rounded ${theme === "dark" ? "text-primary-purple bg-neutral-800" : "text-primary bg-neutral-100"}`, children: [
37862
+ "v",
37863
+ item.version
37864
+ ] })
37794
37865
  ]
37795
- }
37796
- ),
37797
- isExpanded && /* @__PURE__ */ jsx38("div", { id: `group-${groupName}`, className: "ml-4 space-y-1", children: items.filter((item) => !(item.id === "authentication" && user?.role === "operator" /* Operator */)).filter((item) => !(item.id === "mod:authentication" && user?.role === "operator" /* Operator */)).map((item) => {
37798
- const isActive = isItemActive(item);
37799
- return /* @__PURE__ */ jsxs32(
37800
- Link3,
37801
- {
37802
- to: item.to,
37803
- onClick: () => setIsOpen?.(false),
37804
- className: `flex items-center px-3 py-2 text-sm rounded-md transition-colors hover:text-purple-400 ${isActive ? "bg-purple-700 bg-opacity-20 text-purple-400 border-l-4 border-purple-900" : theme === "dark" ? "text-neutral-400 hover:bg-neutral-800" : "text-neutral-600 hover:bg-neutral-100"}`,
37805
- title: item.description,
37806
- children: [
37807
- /* @__PURE__ */ jsx38(ItemIcon, { item }),
37808
- /* @__PURE__ */ jsxs32("div", { className: "ml-2 flex-1", children: [
37809
- /* @__PURE__ */ jsx38("div", { className: "font-medium", children: item.label }),
37810
- item.description && /* @__PURE__ */ jsx38("div", { className: `text-xs truncate w-28 ${theme === "dark" ? "text-neutral-500" : "text-neutral-600"}`, children: item.description })
37811
- ] }),
37812
- item.version && /* @__PURE__ */ jsxs32("span", { className: `text-xs px-1.5 py-0.5 rounded ${theme === "dark" ? "text-primary-purple bg-neutral-800" : "text-primary bg-neutral-100"}`, children: [
37813
- "v",
37814
- item.version
37815
- ] })
37816
- ]
37817
- },
37818
- item.id
37819
- );
37820
- }) })
37821
- ] }, groupName);
37822
- }) })
37823
- ] }),
37824
- totalModules > 0 && /* @__PURE__ */ jsx38("div", { className: `absolute bottom-0 left-0 right-0 p-4 border-t ${theme === "dark" ? "border-neutral-800" : "border-neutral-200"}`, children: /* @__PURE__ */ jsxs32("p", { className: `text-xs text-center ${theme === "dark" ? "text-neutral-400" : "text-neutral-500"}`, children: [
37825
- totalModules,
37826
- " m\xF3dulo",
37827
- totalModules !== 1 ? "s" : "",
37828
- " carregado",
37829
- totalModules !== 1 ? "s" : ""
37830
- ] }) })
37831
- ]
37866
+ },
37867
+ item.id
37868
+ );
37869
+ }) })
37870
+ ] }, groupName);
37871
+ }) })
37872
+ ] })
37832
37873
  }
37833
37874
  )
37834
37875
  ] });
@@ -42571,9 +42612,33 @@ var VideoPlayer = ({
42571
42612
  }
42572
42613
  try {
42573
42614
  console.log("Initializing JSMpeg player url");
42574
- const apiBaseUrl = typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL ? import.meta.env.VITE_API_BASE_URL : "localhost:3000";
42615
+ const resolveWsOrigin = () => {
42616
+ try {
42617
+ if (typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL) {
42618
+ const raw = import.meta.env.VITE_API_BASE_URL;
42619
+ const pref = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
42620
+ const u16 = new URL(pref);
42621
+ return u16.protocol === "https:" ? `wss://${u16.host}` : `ws://${u16.host}`;
42622
+ }
42623
+ } catch (e10) {
42624
+ }
42625
+ if (typeof window !== "undefined") {
42626
+ const win = window;
42627
+ if (win.__VIASOFT_API_BASE_URL) {
42628
+ const raw = win.__VIASOFT_API_BASE_URL;
42629
+ const pref = /^https?:\/\//i.test(raw) ? raw : `http://${raw}`;
42630
+ const u16 = new URL(pref);
42631
+ return u16.protocol === "https:" ? `wss://${u16.host}` : `ws://${u16.host}`;
42632
+ }
42633
+ if (window.location && window.location.host) {
42634
+ return window.location.protocol === "https:" ? `wss://${window.location.host}` : `ws://${window.location.host}`;
42635
+ }
42636
+ }
42637
+ return `ws://localhost:3000`;
42638
+ };
42639
+ const wsOrigin = resolveWsOrigin();
42575
42640
  playerRef.current = new window.JSMpeg.Player(
42576
- `ws://${apiBaseUrl}/ws/preview-xcoder_${pgmIndex}`,
42641
+ `${wsOrigin}/ws/preview-xcoder_${pgmIndex}`,
42577
42642
  {
42578
42643
  canvas: videoRef.current,
42579
42644
  disableWebAssembly: false,
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { User, Role } from '../types';
3
+ interface AuthContextType {
4
+ user: User | null;
5
+ accessToken: string | null;
6
+ loading: boolean;
7
+ login: (username: string, password: string, options?: {
8
+ redirect?: boolean;
9
+ }) => Promise<void>;
10
+ logout: () => Promise<void>;
11
+ hasRole: (roles: Role | Role[]) => boolean;
12
+ }
13
+ export declare const AuthProvider: React.FC<{
14
+ children: React.ReactNode;
15
+ }>;
16
+ export declare function useAuth(): AuthContextType;
17
+ export {};
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ type Theme = 'light' | 'dark';
3
+ interface ThemeContextType {
4
+ theme: Theme;
5
+ toggleTheme: () => void;
6
+ }
7
+ export declare function ThemeProvider({ children }: {
8
+ children: React.ReactNode;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ export declare function useTheme(): ThemeContextType;
11
+ export {};
@@ -0,0 +1,3 @@
1
+ import { ThemeProvider } from './ThemeContext';
2
+ import { AuthProvider, useAuth } from './AuthContext';
3
+ export { ThemeProvider, AuthProvider, useAuth, };
package/dist/context.js CHANGED
@@ -3072,19 +3072,36 @@ var {
3072
3072
  } = axios_default;
3073
3073
 
3074
3074
  // src/services/api.ts
3075
- var getApiBaseUrl = () => {
3076
- if (typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL) {
3077
- return import.meta.env.VITE_API_BASE_URL;
3075
+ var normalizeOrigin = (raw) => {
3076
+ if (!raw)
3077
+ return "";
3078
+ if (/^https?:\/\//i.test(raw) || /^wss?:\/\//i.test(raw))
3079
+ return raw.replace(/\/$/, "");
3080
+ return `http://${raw.replace(/\/$/, "")}`;
3081
+ };
3082
+ var getApiOrigin = () => {
3083
+ try {
3084
+ if (typeof import.meta !== "undefined" && import.meta.env?.VITE_API_BASE_URL) {
3085
+ return normalizeOrigin(import.meta.env.VITE_API_BASE_URL);
3086
+ }
3087
+ } catch (e) {
3088
+ }
3089
+ if (typeof window !== "undefined") {
3090
+ const win = window;
3091
+ if (win.__VIASOFT_API_BASE_URL)
3092
+ return normalizeOrigin(win.__VIASOFT_API_BASE_URL);
3093
+ if (window.location && window.location.origin)
3094
+ return window.location.origin.replace(/\/$/, "");
3078
3095
  }
3079
- return "192.168.100.9:3000";
3096
+ return "http://localhost:3000";
3080
3097
  };
3081
- var serverUrl = getApiBaseUrl();
3098
+ var apiOrigin = getApiOrigin();
3082
3099
  var api = axios_default.create({
3083
- baseURL: `http://${serverUrl}`,
3100
+ baseURL: apiOrigin,
3084
3101
  timeout: 1e4
3085
3102
  });
3086
3103
  var authApi = axios_default.create({
3087
- baseURL: `http://${serverUrl}`,
3104
+ baseURL: apiOrigin,
3088
3105
  timeout: 1e4
3089
3106
  });
3090
3107
  function getAccessToken() {
@@ -3170,7 +3187,6 @@ authApi.interceptors.response.use(
3170
3187
  return Promise.reject(err);
3171
3188
  }
3172
3189
  );
3173
- var serverOrigin = `http://${serverUrl}`;
3174
3190
 
3175
3191
  // src/services/auth.ts
3176
3192
  var authService = {
@@ -3239,7 +3255,7 @@ var MetadataLoader = class {
3239
3255
  );
3240
3256
  }
3241
3257
  metadata.forEach((page, index) => {
3242
- if (!page.id || !page.name || !page.path || !page.bundleUrl) {
3258
+ if (!page.id || !page.name || !page.path || !page.url) {
3243
3259
  throw new Error(
3244
3260
  `Invalid page metadata at index ${index}: missing required fields`
3245
3261
  );
@@ -0,0 +1,3 @@
1
+ export { useSettings } from './useSettings';
2
+ export { useApi } from './useApi';
3
+ export { default as useAvailableSubservices } from './useAvailableSubservices';