@hai3/studio 0.3.0-alpha.1 → 0.4.0-alpha.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/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import React3, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
2
- import { I18nRegistry, Language, i18nRegistry, ScreensetCategory, eventBus, useTranslation, useNavigation, screensetRegistry, useAppSelector, useTheme, getLanguageMetadata, LanguageDisplayMode, SUPPORTED_LANGUAGES, TextDirection, toggleMockMode } from '@hai3/react';
3
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
- import { Card, Button, ButtonSize, ButtonVariant, DropdownMenu, DropdownMenuTrigger, DropdownButton, DropdownMenuContent, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent, DropdownMenuItem, Switch } from '@hai3/uikit';
1
+ import React2, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';
2
+ import { I18nRegistry, Language, i18nRegistry, eventBus, useHAI3, useTranslation, HAI3_SCREEN_DOMAIN, HAI3_ACTION_MOUNT_EXT, useRegisteredPackages, useActivePackage, useAppSelector, useTheme, getLanguageMetadata, LanguageDisplayMode, SUPPORTED_LANGUAGES, TextDirection, toggleMockMode } from '@hai3/react';
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+ import { Card, Button, ButtonSize, ButtonVariant, DropdownMenu, DropdownMenuTrigger, DropdownButton, DropdownMenuContent, DropdownMenuItem, Switch } from '@hai3/uikit';
5
5
  import { clamp, upperFirst } from 'lodash';
6
6
 
7
7
  var __create = Object.create;
@@ -45,7 +45,8 @@ var require_en = __commonJS({
45
45
  screenset: "Screenset:",
46
46
  theme: "Theme:",
47
47
  language: "Language:",
48
- mockApi: "Mock API"
48
+ mockApi: "Mock API",
49
+ gts_package: "GTS Package"
49
50
  }
50
51
  };
51
52
  }
@@ -66,7 +67,8 @@ var require_ar = __commonJS({
66
67
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u0634\u0627\u0634\u0627\u062A:",
67
68
  theme: "\u0627\u0644\u0633\u0645\u0629:",
68
69
  language: "\u0627\u0644\u0644\u063A\u0629:",
69
- mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629"
70
+ mockApi: "\u0648\u0627\u062C\u0647\u0629 \u0628\u0631\u0645\u062C\u064A\u0629 \u0648\u0647\u0645\u064A\u0629",
71
+ gts_package: "GTS Package"
70
72
  }
71
73
  };
72
74
  }
@@ -87,7 +89,8 @@ var require_bn = __commonJS({
87
89
  screenset: "\u09B8\u09CD\u0995\u09CD\u09B0\u09BF\u09A8\u09B8\u09C7\u099F:",
88
90
  theme: "\u09A5\u09BF\u09AE:",
89
91
  language: "\u09AD\u09BE\u09B7\u09BE:",
90
- mockApi: "\u09AE\u0995 API"
92
+ mockApi: "\u09AE\u0995 API",
93
+ gts_package: "GTS Package"
91
94
  }
92
95
  };
93
96
  }
@@ -108,7 +111,8 @@ var require_cs = __commonJS({
108
111
  screenset: "Sada obrazovek:",
109
112
  theme: "Motiv:",
110
113
  language: "Jazyk:",
111
- mockApi: "Simulovan\xE9 API"
114
+ mockApi: "Simulovan\xE9 API",
115
+ gts_package: "GTS Package"
112
116
  }
113
117
  };
114
118
  }
@@ -129,7 +133,8 @@ var require_da = __commonJS({
129
133
  screenset: "Sk\xE6rms\xE6t:",
130
134
  theme: "Tema:",
131
135
  language: "Sprog:",
132
- mockApi: "Mock-API"
136
+ mockApi: "Mock-API",
137
+ gts_package: "GTS Package"
133
138
  }
134
139
  };
135
140
  }
@@ -150,7 +155,8 @@ var require_de = __commonJS({
150
155
  screenset: "Bildschirmset:",
151
156
  theme: "Design:",
152
157
  language: "Sprache:",
153
- mockApi: "Mock-API"
158
+ mockApi: "Mock-API",
159
+ gts_package: "GTS Package"
154
160
  }
155
161
  };
156
162
  }
@@ -171,7 +177,8 @@ var require_el = __commonJS({
171
177
  screenset: "\u03A3\u03CD\u03BD\u03BF\u03BB\u03BF \u039F\u03B8\u03BF\u03BD\u03CE\u03BD:",
172
178
  theme: "\u0398\u03AD\u03BC\u03B1:",
173
179
  language: "\u0393\u03BB\u03CE\u03C3\u03C3\u03B1:",
174
- mockApi: "Mock API"
180
+ mockApi: "Mock API",
181
+ gts_package: "GTS Package"
175
182
  }
176
183
  };
177
184
  }
@@ -192,7 +199,8 @@ var require_es = __commonJS({
192
199
  screenset: "Conjunto de Pantallas:",
193
200
  theme: "Tema:",
194
201
  language: "Idioma:",
195
- mockApi: "API Simulada"
202
+ mockApi: "API Simulada",
203
+ gts_package: "GTS Package"
196
204
  }
197
205
  };
198
206
  }
@@ -213,7 +221,8 @@ var require_fa = __commonJS({
213
221
  screenset: "\u0645\u062C\u0645\u0648\u0639\u0647 \u0635\u0641\u062D\u0647\u200C\u0646\u0645\u0627\u06CC\u0634:",
214
222
  theme: "\u067E\u0648\u0633\u062A\u0647:",
215
223
  language: "\u0632\u0628\u0627\u0646:",
216
- mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC"
224
+ mockApi: "API \u0633\u0627\u062E\u062A\u06AF\u06CC",
225
+ gts_package: "GTS Package"
217
226
  }
218
227
  };
219
228
  }
@@ -234,7 +243,8 @@ var require_fi = __commonJS({
234
243
  screenset: "N\xE4ytt\xF6sarja:",
235
244
  theme: "Teema:",
236
245
  language: "Kieli:",
237
- mockApi: "Mock-API"
246
+ mockApi: "Mock-API",
247
+ gts_package: "GTS Package"
238
248
  }
239
249
  };
240
250
  }
@@ -255,7 +265,8 @@ var require_fr = __commonJS({
255
265
  screenset: "Ensemble d'\xC9crans:",
256
266
  theme: "Th\xE8me:",
257
267
  language: "Langue:",
258
- mockApi: "API Simul\xE9e"
268
+ mockApi: "API Simul\xE9e",
269
+ gts_package: "GTS Package"
259
270
  }
260
271
  };
261
272
  }
@@ -276,7 +287,8 @@ var require_he = __commonJS({
276
287
  screenset: "\u05E2\u05E8\u05DB\u05EA \u05DE\u05E1\u05DB\u05D9\u05DD:",
277
288
  theme: "\u05E2\u05E8\u05DB\u05EA \u05E0\u05D5\u05E9\u05D0:",
278
289
  language: "\u05E9\u05E4\u05D4:",
279
- mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4"
290
+ mockApi: "API \u05DE\u05D3\u05D5\u05DE\u05D4",
291
+ gts_package: "GTS Package"
280
292
  }
281
293
  };
282
294
  }
@@ -297,7 +309,8 @@ var require_hi = __commonJS({
297
309
  screenset: "\u0938\u094D\u0915\u094D\u0930\u0940\u0928\u0938\u0947\u091F:",
298
310
  theme: "\u0925\u0940\u092E:",
299
311
  language: "\u092D\u093E\u0937\u093E:",
300
- mockApi: "\u092E\u0949\u0915 API"
312
+ mockApi: "\u092E\u0949\u0915 API",
313
+ gts_package: "GTS Package"
301
314
  }
302
315
  };
303
316
  }
@@ -318,7 +331,8 @@ var require_hu = __commonJS({
318
331
  screenset: "K\xE9perny\u0151k\xE9szlet:",
319
332
  theme: "T\xE9ma:",
320
333
  language: "Nyelv:",
321
- mockApi: "Mock API"
334
+ mockApi: "Mock API",
335
+ gts_package: "GTS Package"
322
336
  }
323
337
  };
324
338
  }
@@ -339,7 +353,8 @@ var require_id = __commonJS({
339
353
  screenset: "Set Layar:",
340
354
  theme: "Tema:",
341
355
  language: "Bahasa:",
342
- mockApi: "API Tiruan"
356
+ mockApi: "API Tiruan",
357
+ gts_package: "GTS Package"
343
358
  }
344
359
  };
345
360
  }
@@ -360,7 +375,8 @@ var require_it = __commonJS({
360
375
  screenset: "Set di Schermate:",
361
376
  theme: "Tema:",
362
377
  language: "Lingua:",
363
- mockApi: "API Simulata"
378
+ mockApi: "API Simulata",
379
+ gts_package: "GTS Package"
364
380
  }
365
381
  };
366
382
  }
@@ -381,7 +397,8 @@ var require_ja = __commonJS({
381
397
  screenset: "\u30B9\u30AF\u30EA\u30FC\u30F3\u30BB\u30C3\u30C8:",
382
398
  theme: "\u30C6\u30FC\u30DE:",
383
399
  language: "\u8A00\u8A9E:",
384
- mockApi: "\u30E2\u30C3\u30AF API"
400
+ mockApi: "\u30E2\u30C3\u30AF API",
401
+ gts_package: "GTS Package"
385
402
  }
386
403
  };
387
404
  }
@@ -402,7 +419,8 @@ var require_ko = __commonJS({
402
419
  screenset: "\uD654\uBA74 \uC138\uD2B8:",
403
420
  theme: "\uD14C\uB9C8:",
404
421
  language: "\uC5B8\uC5B4:",
405
- mockApi: "\uBAA8\uC758 API"
422
+ mockApi: "\uBAA8\uC758 API",
423
+ gts_package: "GTS Package"
406
424
  }
407
425
  };
408
426
  }
@@ -423,7 +441,8 @@ var require_ms = __commonJS({
423
441
  screenset: "Set Skrin:",
424
442
  theme: "Tema:",
425
443
  language: "Bahasa:",
426
- mockApi: "API Palsu"
444
+ mockApi: "API Palsu",
445
+ gts_package: "GTS Package"
427
446
  }
428
447
  };
429
448
  }
@@ -444,7 +463,8 @@ var require_nl = __commonJS({
444
463
  screenset: "Schermset:",
445
464
  theme: "Thema:",
446
465
  language: "Taal:",
447
- mockApi: "Nep-API"
466
+ mockApi: "Nep-API",
467
+ gts_package: "GTS Package"
448
468
  }
449
469
  };
450
470
  }
@@ -465,7 +485,8 @@ var require_no = __commonJS({
465
485
  screenset: "Skjermsett:",
466
486
  theme: "Tema:",
467
487
  language: "Spr\xE5k:",
468
- mockApi: "Mock-API"
488
+ mockApi: "Mock-API",
489
+ gts_package: "GTS Package"
469
490
  }
470
491
  };
471
492
  }
@@ -486,7 +507,8 @@ var require_pl = __commonJS({
486
507
  screenset: "Zestaw ekran\xF3w:",
487
508
  theme: "Motyw:",
488
509
  language: "J\u0119zyk:",
489
- mockApi: "Fikcyjne API"
510
+ mockApi: "Fikcyjne API",
511
+ gts_package: "GTS Package"
490
512
  }
491
513
  };
492
514
  }
@@ -507,7 +529,8 @@ var require_pt = __commonJS({
507
529
  screenset: "Conjunto de Telas:",
508
530
  theme: "Tema:",
509
531
  language: "Idioma:",
510
- mockApi: "API Simulada"
532
+ mockApi: "API Simulada",
533
+ gts_package: "GTS Package"
511
534
  }
512
535
  };
513
536
  }
@@ -528,7 +551,8 @@ var require_ro = __commonJS({
528
551
  screenset: "Set de Ecrane:",
529
552
  theme: "Tem\u0103:",
530
553
  language: "Limb\u0103:",
531
- mockApi: "API Simulat"
554
+ mockApi: "API Simulat",
555
+ gts_package: "GTS Package"
532
556
  }
533
557
  };
534
558
  }
@@ -549,7 +573,8 @@ var require_ru = __commonJS({
549
573
  screenset: "\u041D\u0430\u0431\u043E\u0440 \u044D\u043A\u0440\u0430\u043D\u043E\u0432:",
550
574
  theme: "\u0422\u0435\u043C\u0430:",
551
575
  language: "\u042F\u0437\u044B\u043A:",
552
- mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API"
576
+ mockApi: "\u0424\u0438\u043A\u0442\u0438\u0432\u043D\u044B\u0439 API",
577
+ gts_package: "GTS Package"
553
578
  }
554
579
  };
555
580
  }
@@ -570,7 +595,8 @@ var require_sv = __commonJS({
570
595
  screenset: "Sk\xE4rmupps\xE4ttning:",
571
596
  theme: "Tema:",
572
597
  language: "Spr\xE5k:",
573
- mockApi: "Mock-API"
598
+ mockApi: "Mock-API",
599
+ gts_package: "GTS Package"
574
600
  }
575
601
  };
576
602
  }
@@ -591,7 +617,8 @@ var require_sw = __commonJS({
591
617
  screenset: "Seti ya Skrini:",
592
618
  theme: "Mandhari:",
593
619
  language: "Lugha:",
594
- mockApi: "API ya Majaribio"
620
+ mockApi: "API ya Majaribio",
621
+ gts_package: "GTS Package"
595
622
  }
596
623
  };
597
624
  }
@@ -612,7 +639,8 @@ var require_ta = __commonJS({
612
639
  screenset: "\u0BA4\u0BBF\u0BB0\u0BC8\u0BA4\u0BCD \u0BA4\u0BCA\u0B95\u0BC1\u0BAA\u0BCD\u0BAA\u0BC1:",
613
640
  theme: "\u0BA4\u0BC0\u0BAE\u0BCD:",
614
641
  language: "\u0BAE\u0BCA\u0BB4\u0BBF:",
615
- mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API"
642
+ mockApi: "\u0BAA\u0BCB\u0BB2\u0BBF API",
643
+ gts_package: "GTS Package"
616
644
  }
617
645
  };
618
646
  }
@@ -633,7 +661,8 @@ var require_th = __commonJS({
633
661
  screenset: "\u0E0A\u0E38\u0E14\u0E2B\u0E19\u0E49\u0E32\u0E08\u0E2D:",
634
662
  theme: "\u0E18\u0E35\u0E21:",
635
663
  language: "\u0E20\u0E32\u0E29\u0E32:",
636
- mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07"
664
+ mockApi: "API \u0E08\u0E33\u0E25\u0E2D\u0E07",
665
+ gts_package: "GTS Package"
637
666
  }
638
667
  };
639
668
  }
@@ -654,7 +683,8 @@ var require_tl = __commonJS({
654
683
  screenset: "Hanay ng Screen:",
655
684
  theme: "Tema:",
656
685
  language: "Wika:",
657
- mockApi: "Mock API"
686
+ mockApi: "Mock API",
687
+ gts_package: "GTS Package"
658
688
  }
659
689
  };
660
690
  }
@@ -675,7 +705,8 @@ var require_tr = __commonJS({
675
705
  screenset: "Ekran Seti:",
676
706
  theme: "Tema:",
677
707
  language: "Dil:",
678
- mockApi: "Sahte API"
708
+ mockApi: "Sahte API",
709
+ gts_package: "GTS Package"
679
710
  }
680
711
  };
681
712
  }
@@ -696,7 +727,8 @@ var require_uk = __commonJS({
696
727
  screenset: "\u041D\u0430\u0431\u0456\u0440 \u0435\u043A\u0440\u0430\u043D\u0456\u0432:",
697
728
  theme: "\u0422\u0435\u043C\u0430:",
698
729
  language: "\u041C\u043E\u0432\u0430:",
699
- mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API"
730
+ mockApi: "\u0424\u0456\u043A\u0442\u0438\u0432\u043D\u0438\u0439 API",
731
+ gts_package: "GTS Package"
700
732
  }
701
733
  };
702
734
  }
@@ -717,7 +749,8 @@ var require_ur = __commonJS({
717
749
  screenset: "\u0627\u0633\u06A9\u0631\u06CC\u0646 \u0633\u06CC\u0679:",
718
750
  theme: "\u062A\u06BE\u06CC\u0645:",
719
751
  language: "\u0632\u0628\u0627\u0646:",
720
- mockApi: "\u0641\u0631\u0636\u06CC API"
752
+ mockApi: "\u0641\u0631\u0636\u06CC API",
753
+ gts_package: "GTS Package"
721
754
  }
722
755
  };
723
756
  }
@@ -738,7 +771,8 @@ var require_vi = __commonJS({
738
771
  screenset: "B\u1ED9 M\xE0n h\xECnh:",
739
772
  theme: "Ch\u1EE7 \u0111\u1EC1:",
740
773
  language: "Ng\xF4n ng\u1EEF:",
741
- mockApi: "API Gi\u1EA3 l\u1EADp"
774
+ mockApi: "API Gi\u1EA3 l\u1EADp",
775
+ gts_package: "GTS Package"
742
776
  }
743
777
  };
744
778
  }
@@ -759,7 +793,8 @@ var require_zh_TW = __commonJS({
759
793
  screenset: "\u87A2\u5E55\u96C6:",
760
794
  theme: "\u4E3B\u984C:",
761
795
  language: "\u8A9E\u8A00:",
762
- mockApi: "\u6A21\u64EC API"
796
+ mockApi: "\u6A21\u64EC API",
797
+ gts_package: "GTS Package"
763
798
  }
764
799
  };
765
800
  }
@@ -780,7 +815,8 @@ var require_zh = __commonJS({
780
815
  screenset: "\u5C4F\u5E55\u96C6:",
781
816
  theme: "\u4E3B\u9898:",
782
817
  language: "\u8BED\u8A00:",
783
- mockApi: "\u6A21\u62DF API"
818
+ mockApi: "\u6A21\u62DF API",
819
+ gts_package: "GTS Package"
784
820
  }
785
821
  };
786
822
  }
@@ -822,14 +858,19 @@ var STORAGE_KEYS = {
822
858
  POSITION: `${STORAGE_PREFIX}position`,
823
859
  SIZE: `${STORAGE_PREFIX}size`,
824
860
  COLLAPSED: `${STORAGE_PREFIX}collapsed`,
825
- BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`
861
+ BUTTON_POSITION: `${STORAGE_PREFIX}buttonPosition`,
862
+ THEME: `${STORAGE_PREFIX}theme`,
863
+ LANGUAGE: `${STORAGE_PREFIX}language`,
864
+ MOCK_ENABLED: `${STORAGE_PREFIX}mockEnabled`,
865
+ ACTIVE_PACKAGE_ID: `${STORAGE_PREFIX}activePackageId`
826
866
  };
827
867
 
828
868
  // src/events/studioEvents.ts
829
869
  var StudioEvents = {
830
870
  PositionChanged: "studio/positionChanged",
831
871
  SizeChanged: "studio/sizeChanged",
832
- ButtonPositionChanged: "studio/buttonPositionChanged"
872
+ ButtonPositionChanged: "studio/buttonPositionChanged",
873
+ ActivePackageChanged: "studio/activePackageChanged"
833
874
  };
834
875
 
835
876
  // src/effects/persistenceEffects.ts
@@ -852,12 +893,82 @@ var initPersistenceEffects = () => {
852
893
  saveStudioState(STORAGE_KEYS.BUTTON_POSITION, position);
853
894
  }
854
895
  );
896
+ const themeSubscription = eventBus.on("theme/changed", (payload) => {
897
+ saveStudioState(STORAGE_KEYS.THEME, payload.themeId);
898
+ });
899
+ const languageSubscription = eventBus.on("i18n/language/changed", (payload) => {
900
+ saveStudioState(STORAGE_KEYS.LANGUAGE, payload.language);
901
+ });
902
+ const mockSubscription = eventBus.on("mock/toggle", (payload) => {
903
+ saveStudioState(STORAGE_KEYS.MOCK_ENABLED, payload.enabled);
904
+ });
905
+ const activePackageSubscription = eventBus.on(
906
+ StudioEvents.ActivePackageChanged,
907
+ ({ activePackageId }) => {
908
+ saveStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, activePackageId);
909
+ }
910
+ );
855
911
  return () => {
856
912
  positionSubscription.unsubscribe();
857
913
  sizeSubscription.unsubscribe();
858
914
  buttonPositionSubscription.unsubscribe();
915
+ themeSubscription.unsubscribe();
916
+ languageSubscription.unsubscribe();
917
+ mockSubscription.unsubscribe();
918
+ activePackageSubscription.unsubscribe();
859
919
  };
860
920
  };
921
+ function isScreenExtension(ext) {
922
+ return "presentation" in ext && typeof ext.presentation === "object";
923
+ }
924
+ var useRestoreStudioSettings = () => {
925
+ const restoredRef = useRef(false);
926
+ useEffect(() => {
927
+ if (restoredRef.current) return;
928
+ restoredRef.current = true;
929
+ const themeId = loadStudioState(STORAGE_KEYS.THEME, null);
930
+ if (themeId != null && typeof themeId === "string" && themeId.length > 0) {
931
+ eventBus.emit("theme/changed", { themeId });
932
+ }
933
+ const language = loadStudioState(STORAGE_KEYS.LANGUAGE, null);
934
+ if (language != null && typeof language === "string" && language.length > 0) {
935
+ eventBus.emit("i18n/language/changed", { language });
936
+ }
937
+ const mockEnabled = loadStudioState(STORAGE_KEYS.MOCK_ENABLED, null);
938
+ if (typeof mockEnabled === "boolean") {
939
+ eventBus.emit("mock/toggle", { enabled: mockEnabled });
940
+ }
941
+ }, []);
942
+ };
943
+ var useRestoreGtsPackage = (registry) => {
944
+ const restoredRef = useRef(false);
945
+ useEffect(() => {
946
+ if (restoredRef.current || !registry) return;
947
+ const activePackageId = loadStudioState(STORAGE_KEYS.ACTIVE_PACKAGE_ID, null);
948
+ if (!activePackageId || typeof activePackageId !== "string") return;
949
+ restoredRef.current = true;
950
+ const restore = async () => {
951
+ try {
952
+ const extensions = registry.getExtensionsForPackage(activePackageId);
953
+ const screenExtensions = extensions.filter(
954
+ (ext) => ext.domain === HAI3_SCREEN_DOMAIN && isScreenExtension(ext)
955
+ );
956
+ if (screenExtensions.length === 0) return;
957
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
958
+ const firstExtension = screenExtensions[0];
959
+ await registry.executeActionsChain({
960
+ action: {
961
+ type: HAI3_ACTION_MOUNT_EXT,
962
+ target: HAI3_SCREEN_DOMAIN,
963
+ payload: { extensionId: firstExtension.id }
964
+ }
965
+ });
966
+ } catch {
967
+ }
968
+ };
969
+ void restore();
970
+ }, [registry]);
971
+ };
861
972
  var studioTranslations = I18nRegistry.createLoader({
862
973
  [Language.English]: () => Promise.resolve().then(() => __toESM(require_en())),
863
974
  [Language.Arabic]: () => Promise.resolve().then(() => __toESM(require_ar())),
@@ -898,6 +1009,11 @@ var studioTranslations = I18nRegistry.createLoader({
898
1009
  });
899
1010
  i18nRegistry.registerLoader("studio", studioTranslations);
900
1011
  var StudioContext = createContext(void 0);
1012
+ var RestoreGtsPackageOnMount = () => {
1013
+ const app = useHAI3();
1014
+ useRestoreGtsPackage(app.screensetsRegistry);
1015
+ return null;
1016
+ };
901
1017
  var useStudioContext = () => {
902
1018
  const context = useContext(StudioContext);
903
1019
  if (!context) {
@@ -914,6 +1030,7 @@ var StudioProvider = ({ children }) => {
914
1030
  const cleanup = initPersistenceEffects();
915
1031
  return cleanup;
916
1032
  }, []);
1033
+ useRestoreStudioSettings();
917
1034
  const toggleCollapsed = useCallback(() => {
918
1035
  setCollapsed((prev) => {
919
1036
  const newValue = !prev;
@@ -921,7 +1038,7 @@ var StudioProvider = ({ children }) => {
921
1038
  return newValue;
922
1039
  });
923
1040
  }, []);
924
- return /* @__PURE__ */ jsx(
1041
+ return /* @__PURE__ */ jsxs(
925
1042
  StudioContext.Provider,
926
1043
  {
927
1044
  value: {
@@ -930,18 +1047,30 @@ var StudioProvider = ({ children }) => {
930
1047
  portalContainer,
931
1048
  setPortalContainer
932
1049
  },
933
- children
1050
+ children: [
1051
+ /* @__PURE__ */ jsx(RestoreGtsPackageOnMount, {}),
1052
+ children
1053
+ ]
934
1054
  }
935
1055
  );
936
1056
  };
937
1057
  StudioProvider.displayName = "StudioProvider";
1058
+ var VIEWPORT_MARGIN = 20;
1059
+ function clampToViewport(pos, size) {
1060
+ const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - size.width - VIEWPORT_MARGIN);
1061
+ const maxY = Math.max(VIEWPORT_MARGIN, window.innerHeight - size.height - VIEWPORT_MARGIN);
1062
+ return {
1063
+ x: clamp(pos.x, VIEWPORT_MARGIN, maxX),
1064
+ y: clamp(pos.y, VIEWPORT_MARGIN, maxY)
1065
+ };
1066
+ }
938
1067
  var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
939
1068
  const getDefaultPosition = () => ({
940
- x: window.innerWidth - panelSize.width - 20,
941
- y: window.innerHeight - panelSize.height - 20
1069
+ x: window.innerWidth - panelSize.width - VIEWPORT_MARGIN,
1070
+ y: window.innerHeight - panelSize.height - VIEWPORT_MARGIN
942
1071
  });
943
1072
  const [position, setPosition] = useState(
944
- () => loadStudioState(storageKey, getDefaultPosition())
1073
+ () => clampToViewport(loadStudioState(storageKey, getDefaultPosition()), panelSize)
945
1074
  );
946
1075
  const [isDragging, setIsDragging] = useState(false);
947
1076
  const dragStartPos = useRef({ x: 0, y: 0 });
@@ -955,16 +1084,10 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
955
1084
  useEffect(() => {
956
1085
  if (!isDragging) return;
957
1086
  const handleMouseMove = (e) => {
958
- const newX = clamp(
959
- e.clientX - dragStartPos.current.x,
960
- 0,
961
- window.innerWidth - panelSize.width
962
- );
963
- const newY = clamp(
964
- e.clientY - dragStartPos.current.y,
965
- 0,
966
- window.innerHeight - panelSize.height
967
- );
1087
+ const maxX = Math.max(VIEWPORT_MARGIN, window.innerWidth - panelSize.width - VIEWPORT_MARGIN);
1088
+ const maxY = Math.max(VIEWPORT_MARGIN, window.innerHeight - panelSize.height - VIEWPORT_MARGIN);
1089
+ const newX = clamp(e.clientX - dragStartPos.current.x, VIEWPORT_MARGIN, maxX);
1090
+ const newY = clamp(e.clientY - dragStartPos.current.y, VIEWPORT_MARGIN, maxY);
968
1091
  const newPosition = { x: newX, y: newY };
969
1092
  setPosition(newPosition);
970
1093
  const eventName = storageKey === STORAGE_KEYS.BUTTON_POSITION ? StudioEvents.ButtonPositionChanged : StudioEvents.PositionChanged;
@@ -980,6 +1103,19 @@ var useDraggable = ({ panelSize, storageKey = STORAGE_KEYS.POSITION }) => {
980
1103
  window.removeEventListener("mouseup", handleMouseUp);
981
1104
  };
982
1105
  }, [isDragging, panelSize.width, panelSize.height, storageKey]);
1106
+ useEffect(() => {
1107
+ const handleResize = () => {
1108
+ setPosition((prev) => {
1109
+ const clamped = clampToViewport(prev, panelSize);
1110
+ if (clamped.x === prev.x && clamped.y === prev.y) return prev;
1111
+ const eventName = storageKey === STORAGE_KEYS.BUTTON_POSITION ? StudioEvents.ButtonPositionChanged : StudioEvents.PositionChanged;
1112
+ eventBus.emit(eventName, { position: clamped });
1113
+ return clamped;
1114
+ });
1115
+ };
1116
+ window.addEventListener("resize", handleResize);
1117
+ return () => window.removeEventListener("resize", handleResize);
1118
+ }, [panelSize.width, panelSize.height, panelSize, storageKey]);
983
1119
  return {
984
1120
  position,
985
1121
  isDragging,
@@ -1048,6 +1184,64 @@ var useResizable = () => {
1048
1184
  handleMouseDown
1049
1185
  };
1050
1186
  };
1187
+ function isScreenExtension2(ext) {
1188
+ return "presentation" in ext && typeof ext.presentation === "object";
1189
+ }
1190
+ var MfePackageSelector = ({
1191
+ className = ""
1192
+ }) => {
1193
+ const app = useHAI3();
1194
+ const registry = app.screensetsRegistry;
1195
+ const { portalContainer } = useStudioContext();
1196
+ const { t } = useTranslation();
1197
+ const packages = useRegisteredPackages();
1198
+ const activePackage = useActivePackage();
1199
+ if (!registry) {
1200
+ return null;
1201
+ }
1202
+ const handlePackageChange = async (selectedPackageId) => {
1203
+ const extensions = registry.getExtensionsForPackage(selectedPackageId);
1204
+ const screenExtensions = extensions.filter(
1205
+ (ext) => ext.domain === HAI3_SCREEN_DOMAIN && isScreenExtension2(ext)
1206
+ );
1207
+ if (screenExtensions.length === 0) {
1208
+ console.warn(`No screen extensions found for package: ${selectedPackageId}`);
1209
+ return;
1210
+ }
1211
+ screenExtensions.sort((a, b) => (a.presentation.order ?? 0) - (b.presentation.order ?? 0));
1212
+ const firstExtension = screenExtensions[0];
1213
+ await registry.executeActionsChain({
1214
+ action: {
1215
+ type: HAI3_ACTION_MOUNT_EXT,
1216
+ target: HAI3_SCREEN_DOMAIN,
1217
+ payload: { extensionId: firstExtension.id }
1218
+ }
1219
+ });
1220
+ eventBus.emit(StudioEvents.ActivePackageChanged, { activePackageId: selectedPackageId });
1221
+ };
1222
+ return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1223
+ /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.gts_package") }),
1224
+ /* @__PURE__ */ jsxs(DropdownMenu, { children: [
1225
+ /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1226
+ DropdownButton,
1227
+ {
1228
+ variant: ButtonVariant.Outline,
1229
+ disabled: packages.length <= 1,
1230
+ children: activePackage || "No package"
1231
+ }
1232
+ ) }),
1233
+ /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: packages.map((pkg) => /* @__PURE__ */ jsx(
1234
+ DropdownMenuItem,
1235
+ {
1236
+ onClick: () => handlePackageChange(pkg),
1237
+ children: pkg
1238
+ },
1239
+ pkg
1240
+ )) })
1241
+ ] })
1242
+ ] });
1243
+ };
1244
+ MfePackageSelector.displayName = "MfePackageSelector";
1051
1245
  var ThemeSelector = ({
1052
1246
  className = ""
1053
1247
  }) => {
@@ -1073,46 +1267,6 @@ var ThemeSelector = ({
1073
1267
  ] });
1074
1268
  };
1075
1269
  ThemeSelector.displayName = "ThemeSelector";
1076
- var ScreensetSelector = ({
1077
- options,
1078
- currentValue,
1079
- onChange,
1080
- className = ""
1081
- }) => {
1082
- const { portalContainer } = useStudioContext();
1083
- const { t, isRTL } = useTranslation();
1084
- const formatName = (name) => {
1085
- return name.split(/[-_]/).map((word) => upperFirst(word)).join(" ");
1086
- };
1087
- const getCurrentDisplay = () => {
1088
- const [category, itemId] = currentValue.split(":");
1089
- if (!category || !itemId) return "Select";
1090
- const categoryGroup = options.find((opt) => opt.category === category);
1091
- const item = categoryGroup?.screensets.find((i) => i.id === itemId);
1092
- return item ? item.name : "Select";
1093
- };
1094
- const handleItemClick = (category, itemId) => {
1095
- onChange(`${category}:${itemId}`);
1096
- };
1097
- return /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${className}`, children: [
1098
- /* @__PURE__ */ jsx("label", { className: "text-sm text-muted-foreground whitespace-nowrap", children: t("studio:controls.screenset") }),
1099
- /* @__PURE__ */ jsxs(DropdownMenu, { dir: isRTL ? "rtl" : "ltr", children: [
1100
- /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(DropdownButton, { variant: ButtonVariant.Outline, children: formatName(getCurrentDisplay()) }) }),
1101
- /* @__PURE__ */ jsx(DropdownMenuContent, { align: "end", container: portalContainer, className: "z-[99999] pointer-events-auto", children: options.map((categoryGroup) => /* @__PURE__ */ jsxs(DropdownMenuSub, { children: [
1102
- /* @__PURE__ */ jsx(DropdownMenuSubTrigger, { disabled: categoryGroup.screensets.length === 0, children: formatName(categoryGroup.category) }),
1103
- /* @__PURE__ */ jsx(DropdownMenuSubContent, { container: portalContainer, className: "z-[99999] pointer-events-auto", children: categoryGroup.screensets.map((item) => /* @__PURE__ */ jsx(
1104
- DropdownMenuItem,
1105
- {
1106
- onClick: () => handleItemClick(categoryGroup.category, item.id),
1107
- children: formatName(item.name)
1108
- },
1109
- item.id
1110
- )) })
1111
- ] }, categoryGroup.category)) })
1112
- ] })
1113
- ] });
1114
- };
1115
- ScreensetSelector.displayName = "ScreensetSelector";
1116
1270
  var FALLBACK_SELECT_LANGUAGE_TEXT = "Select language";
1117
1271
  var RTL_INDICATOR_SUFFIX = " (RTL)";
1118
1272
  function LanguageSelector({
@@ -1170,48 +1324,12 @@ var ApiModeToggle = ({
1170
1324
  ] });
1171
1325
  };
1172
1326
  ApiModeToggle.displayName = "ApiModeToggle";
1173
- var ALL_CATEGORIES = [ScreensetCategory.Drafts, ScreensetCategory.Mockups, ScreensetCategory.Production];
1174
- var buildScreensetOptions = () => {
1175
- const allScreensets = screensetRegistry.getAll();
1176
- return ALL_CATEGORIES.map((category) => ({
1177
- category,
1178
- screensets: allScreensets.filter((s) => s.category === category).map((s) => ({
1179
- id: s.id,
1180
- name: s.name
1181
- }))
1182
- }));
1183
- };
1184
1327
  var ControlPanel = () => {
1185
- const { currentScreenset, navigateToScreenset } = useNavigation();
1186
- const [screensetOptions, setScreensetOptions] = useState([]);
1187
1328
  const { t } = useTranslation();
1188
- useEffect(() => {
1189
- const options = buildScreensetOptions();
1190
- setScreensetOptions(options);
1191
- }, []);
1192
- const getCurrentValue = () => {
1193
- if (!currentScreenset) return "";
1194
- const screenset = screensetRegistry.get(currentScreenset);
1195
- if (!screenset) return "";
1196
- return `${screenset.category}:${screenset.id}`;
1197
- };
1198
- const handleScreensetChange = (value) => {
1199
- const [, screensetId] = value.split(":");
1200
- if (screensetId) {
1201
- navigateToScreenset(screensetId);
1202
- }
1203
- };
1204
1329
  return /* @__PURE__ */ jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1205
1330
  /* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: t("studio:controls.heading") }),
1206
1331
  /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
1207
- screensetOptions.length > 0 && /* @__PURE__ */ jsx(
1208
- ScreensetSelector,
1209
- {
1210
- options: screensetOptions,
1211
- currentValue: getCurrentValue(),
1212
- onChange: handleScreensetChange
1213
- }
1214
- ),
1332
+ /* @__PURE__ */ jsx(MfePackageSelector, {}),
1215
1333
  /* @__PURE__ */ jsx(ApiModeToggle, {}),
1216
1334
  /* @__PURE__ */ jsx(ThemeSelector, {}),
1217
1335
  /* @__PURE__ */ jsx(LanguageSelector, {})
@@ -1222,13 +1340,13 @@ ControlPanel.displayName = "ControlPanel";
1222
1340
  var StudioPanel = () => {
1223
1341
  const { toggleCollapsed, setPortalContainer } = useStudioContext();
1224
1342
  const { t } = useTranslation();
1225
- const portalRef = React3.useRef(null);
1343
+ const portalRef = React2.useRef(null);
1226
1344
  const { size, handleMouseDown: handleResizeMouseDown } = useResizable();
1227
1345
  const { position, isDragging, handleMouseDown: handleDragMouseDown } = useDraggable({
1228
1346
  panelSize: size,
1229
1347
  storageKey: STORAGE_KEYS.POSITION
1230
1348
  });
1231
- React3.useEffect(() => {
1349
+ React2.useEffect(() => {
1232
1350
  setPortalContainer(portalRef.current);
1233
1351
  return () => setPortalContainer(null);
1234
1352
  }, [setPortalContainer]);