qdadm 0.54.0 → 0.55.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.
Files changed (29) hide show
  1. package/package.json +2 -2
  2. package/src/kernel/Kernel.js +18 -2
  3. package/src/kernel/Module.js +32 -0
  4. package/src/kernel/ModuleLoader.js +5 -1
  5. package/src/{debug → modules/debug}/DebugModule.js +7 -1
  6. package/src/{debug → modules/debug}/RouterCollector.js +1 -1
  7. package/src/{debug → modules/debug}/components/DebugBar.vue +0 -528
  8. package/src/{debug → modules/debug}/components/ObjectTree.vue +0 -80
  9. package/src/{debug → modules/debug}/components/panels/AuthPanel.vue +0 -100
  10. package/src/{debug → modules/debug}/components/panels/EntitiesPanel.vue +0 -524
  11. package/src/{debug → modules/debug}/components/panels/EntriesPanel.vue +0 -117
  12. package/src/{debug → modules/debug}/components/panels/RouterPanel.vue +0 -691
  13. package/src/{debug → modules/debug}/components/panels/SignalsPanel.vue +0 -164
  14. package/src/modules/debug/components/panels/ToastsPanel.vue +34 -0
  15. package/src/{debug → modules/debug}/components/panels/ZonesPanel.vue +0 -131
  16. package/src/modules/debug/styles.scss +2469 -0
  17. package/src/debug/components/panels/ToastsPanel.vue +0 -112
  18. /package/src/{debug → modules/debug}/AuthCollector.js +0 -0
  19. /package/src/{debug → modules/debug}/Collector.js +0 -0
  20. /package/src/{debug → modules/debug}/DebugBridge.js +0 -0
  21. /package/src/{debug → modules/debug}/EntitiesCollector.js +0 -0
  22. /package/src/{debug → modules/debug}/ErrorCollector.js +0 -0
  23. /package/src/{debug → modules/debug}/LocalStorageAdapter.js +0 -0
  24. /package/src/{debug → modules/debug}/SignalCollector.js +0 -0
  25. /package/src/{debug → modules/debug}/ToastCollector.js +0 -0
  26. /package/src/{debug → modules/debug}/ZonesCollector.js +0 -0
  27. /package/src/{debug → modules/debug}/components/index.js +0 -0
  28. /package/src/{debug → modules/debug}/components/panels/index.js +0 -0
  29. /package/src/{debug → modules/debug}/index.js +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qdadm",
3
- "version": "0.54.0",
3
+ "version": "0.55.0",
4
4
  "description": "Vue 3 framework for admin dashboards with PrimeVue",
5
5
  "author": "quazardous",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "./editors": "./src/editors/index.js",
28
28
  "./module": "./src/module/index.js",
29
29
  "./utils": "./src/utils/index.js",
30
- "./debug": "./src/debug/index.js",
30
+ "./modules/debug": "./src/modules/debug/index.js",
31
31
  "./styles": "./src/styles/index.scss",
32
32
  "./styles/breakpoints": "./src/styles/_breakpoints.scss",
33
33
  "./gen": "./src/gen/index.js",
@@ -466,6 +466,17 @@ export class Kernel {
466
466
  continue
467
467
  }
468
468
 
469
+ // Load module styles if defined (must happen before connect)
470
+ if (typeof module.loadStyles === 'function') {
471
+ const styleResult = module.loadStyles()
472
+ // Fire-and-forget for async style loading in sync context
473
+ if (styleResult instanceof Promise) {
474
+ styleResult.catch(err => {
475
+ console.warn(`[Kernel] Module '${name}' styles failed:`, err)
476
+ })
477
+ }
478
+ }
479
+
469
480
  // Connect module (sync - async modules will be fire-and-forget)
470
481
  const result = module.connect(ctx)
471
482
 
@@ -514,6 +525,11 @@ export class Kernel {
514
525
  continue
515
526
  }
516
527
 
528
+ // Load module styles if defined (must happen before connect)
529
+ if (typeof module.loadStyles === 'function') {
530
+ await module.loadStyles()
531
+ }
532
+
517
533
  // Connect module (await async)
518
534
  await module.connect(ctx)
519
535
 
@@ -1336,7 +1352,7 @@ export class Kernel {
1336
1352
 
1337
1353
  /**
1338
1354
  * Get the DebugModule instance if loaded
1339
- * @returns {import('../debug/DebugModule.js').DebugModule|null}
1355
+ * @returns {import('../modules/debug/DebugModule.js').DebugModule|null}
1340
1356
  */
1341
1357
  getDebugModule() {
1342
1358
  return this.moduleLoader?._loaded?.get('debug') ?? null
@@ -1345,7 +1361,7 @@ export class Kernel {
1345
1361
  /**
1346
1362
  * Shorthand accessor for debug bridge
1347
1363
  * Allows `kernel.debugBar.toggle()` syntax
1348
- * @returns {import('../debug/DebugBridge.js').DebugBridge|null}
1364
+ * @returns {import('../modules/debug/DebugBridge.js').DebugBridge|null}
1349
1365
  */
1350
1366
  get debugBar() {
1351
1367
  const debugModule = this.getDebugModule()
@@ -48,6 +48,20 @@ export class Module {
48
48
  */
49
49
  static priority = 0
50
50
 
51
+ /**
52
+ * Path to module styles (relative import or absolute)
53
+ * Set in subclass to auto-load CSS/SCSS when module connects.
54
+ * Styles are loaded once and cached.
55
+ *
56
+ * @example
57
+ * class DebugModule extends Module {
58
+ * static styles = () => import('./styles.scss')
59
+ * }
60
+ *
61
+ * @type {(() => Promise<any>)|null}
62
+ */
63
+ static styles = null
64
+
51
65
  /**
52
66
  * @param {Object} options - Module configuration options
53
67
  */
@@ -55,6 +69,7 @@ export class Module {
55
69
  this.options = options
56
70
  this.ctx = null
57
71
  this._signalCleanups = []
72
+ this._stylesLoaded = false
58
73
  }
59
74
 
60
75
  /**
@@ -75,6 +90,23 @@ export class Module {
75
90
  return true
76
91
  }
77
92
 
93
+ /**
94
+ * Load module styles if defined
95
+ * Called automatically by ModuleLoader before connect()
96
+ * @returns {Promise<void>}
97
+ */
98
+ async loadStyles() {
99
+ const stylesLoader = this.constructor.styles
100
+ if (this._stylesLoaded || !stylesLoader) return
101
+
102
+ try {
103
+ await stylesLoader()
104
+ this._stylesLoaded = true
105
+ } catch (e) {
106
+ console.warn(`[${this.constructor.name}] Failed to load styles:`, e)
107
+ }
108
+ }
109
+
78
110
  /**
79
111
  * Connect module to kernel - main registration point
80
112
  * Override in subclass to register entities, routes, etc.
@@ -294,8 +294,12 @@ export class ModuleLoader {
294
294
  continue
295
295
  }
296
296
 
297
- // Connect module
297
+ // Load styles and connect module
298
298
  try {
299
+ // Load module styles if defined (Module subclasses only)
300
+ if (typeof module.loadStyles === 'function') {
301
+ await module.loadStyles()
302
+ }
299
303
  await module.connect(ctx)
300
304
  this._loaded.set(name, module)
301
305
  this._loadOrder.push(name)
@@ -19,7 +19,7 @@
19
19
  */
20
20
 
21
21
  import { h, inject, defineComponent } from 'vue'
22
- import { Module } from '../kernel/Module.js'
22
+ import { Module } from '../../kernel/Module.js'
23
23
  import { createDebugBridge } from './DebugBridge.js'
24
24
  import { ErrorCollector } from './ErrorCollector.js'
25
25
  import { SignalCollector } from './SignalCollector.js'
@@ -81,6 +81,12 @@ export class DebugModule extends Module {
81
81
  */
82
82
  static priority = 1000
83
83
 
84
+ /**
85
+ * Module styles - loaded automatically before connect()
86
+ * @type {() => Promise<any>}
87
+ */
88
+ static styles = () => import('./styles.scss')
89
+
84
90
  /**
85
91
  * Create a new DebugModule
86
92
  *
@@ -12,7 +12,7 @@
12
12
  */
13
13
 
14
14
  import { Collector } from './Collector.js'
15
- import { computeSemanticBreadcrumb } from '../composables/useSemanticBreadcrumb.js'
15
+ import { computeSemanticBreadcrumb } from '../../composables/useSemanticBreadcrumb.js'
16
16
 
17
17
  /**
18
18
  * Collector for Vue Router state visualization
@@ -722,531 +722,3 @@ function getCollectorColor(name) {
722
722
  </Teleport>
723
723
  </template>
724
724
 
725
- <style scoped>
726
- /* Minimized button */
727
- .debug-minimized {
728
- position: fixed;
729
- bottom: 1rem;
730
- right: 1rem;
731
- width: 44px;
732
- height: 44px;
733
- border-radius: 8px;
734
- background: #18181b;
735
- border: 1px solid #3f3f46;
736
- box-shadow: 0 4px 12px rgba(0,0,0,0.4);
737
- display: flex;
738
- align-items: center;
739
- justify-content: center;
740
- cursor: pointer;
741
- transition: transform 0.15s;
742
- }
743
- .debug-minimized:hover {
744
- transform: scale(1.08);
745
- border-color: #60a5fa;
746
- }
747
-
748
- /* Separate badges */
749
- .debug-badge {
750
- position: absolute;
751
- min-width: 16px;
752
- height: 16px;
753
- padding: 0 4px;
754
- border-radius: 8px;
755
- font-size: 10px;
756
- font-weight: 600;
757
- display: flex;
758
- align-items: center;
759
- justify-content: center;
760
- gap: 2px;
761
- }
762
- .debug-badge .pi {
763
- font-size: 8px;
764
- }
765
-
766
- /* Header inline badges */
767
- .debug-header-badge {
768
- display: inline-flex;
769
- align-items: center;
770
- gap: 3px;
771
- padding: 2px 6px;
772
- border-radius: 10px;
773
- font-size: 11px;
774
- font-weight: 600;
775
- }
776
- .debug-header-badge .pi {
777
- font-size: 10px;
778
- }
779
- .debug-header-badge-error {
780
- background: #ef4444;
781
- color: white;
782
- }
783
- .debug-header-badge-signal {
784
- background: #8b5cf6;
785
- color: white;
786
- }
787
- .debug-badge-error {
788
- top: -4px;
789
- right: -4px;
790
- background: #ef4444;
791
- color: white;
792
- }
793
- .debug-badge-signal {
794
- bottom: -4px;
795
- right: -4px;
796
- background: #8b5cf6;
797
- color: white;
798
- }
799
-
800
- /* Panel base */
801
- .debug-panel {
802
- position: fixed;
803
- background: #18181b;
804
- border: 1px solid #3f3f46;
805
- font-family: system-ui, sans-serif;
806
- font-size: 13px;
807
- color: #f4f4f5;
808
- display: flex;
809
- flex-direction: column;
810
- }
811
-
812
- /* Bottom mode */
813
- .debug-bottom {
814
- bottom: 0; left: 0; right: 0;
815
- border-top: 1px solid #3f3f46;
816
- border-left: none; border-right: none; border-bottom: none;
817
- }
818
- .debug-bottom.debug-expanded {
819
- min-height: 100px;
820
- max-height: 600px;
821
- }
822
-
823
- /* Right mode - vertical header on left, horizontal slide */
824
- .debug-right {
825
- top: 0; right: 0; bottom: 0;
826
- flex-direction: row;
827
- border-left: 1px solid #3f3f46;
828
- border-top: none; border-right: none; border-bottom: none;
829
- transition: transform 0.2s ease-out;
830
- }
831
- .debug-right:not(.debug-expanded) {
832
- transform: translateX(calc(100% - 44px));
833
- }
834
- .debug-right.debug-expanded {
835
- min-width: 200px;
836
- max-width: 800px;
837
- transform: translateX(0);
838
- }
839
-
840
- /* Window mode - floating draggable/resizable */
841
- .debug-window {
842
- /* Window appearance */
843
- position: fixed;
844
- border-radius: 8px;
845
- box-shadow: 0 8px 32px rgba(0,0,0,0.5);
846
- border: 1px solid #3f3f46;
847
- min-width: 280px;
848
- min-height: 200px;
849
- }
850
- .debug-window .debug-header {
851
- cursor: move;
852
- user-select: none;
853
- flex-wrap: nowrap;
854
- }
855
- .debug-window .debug-tabs {
856
- flex: 1;
857
- min-width: 0;
858
- overflow: hidden;
859
- }
860
- .debug-window .debug-actions {
861
- flex-shrink: 0;
862
- }
863
- .debug-window .debug-content {
864
- flex: 1;
865
- min-height: 0;
866
- overflow: auto;
867
- }
868
- .debug-resize-handle {
869
- position: absolute;
870
- bottom: 0;
871
- right: 0;
872
- width: 16px;
873
- height: 16px;
874
- cursor: nwse-resize;
875
- background: linear-gradient(135deg, transparent 50%, #3f3f46 50%);
876
- border-bottom-right-radius: 8px;
877
- z-index: 10;
878
- }
879
- .debug-resize-handle:hover {
880
- background: linear-gradient(135deg, transparent 50%, #60a5fa 50%);
881
- }
882
-
883
- /* Panel resize handles for docked modes */
884
- .debug-panel-resize {
885
- position: absolute;
886
- z-index: 10;
887
- background: transparent;
888
- }
889
- .debug-panel-resize-top {
890
- top: 0;
891
- left: 0;
892
- right: 0;
893
- height: 4px;
894
- cursor: ns-resize;
895
- }
896
- .debug-panel-resize-top:hover {
897
- background: linear-gradient(180deg, #60a5fa 0%, transparent 100%);
898
- }
899
- .debug-panel-resize-left {
900
- top: 0;
901
- left: 0;
902
- bottom: 0;
903
- width: 4px;
904
- cursor: ew-resize;
905
- }
906
- .debug-panel-resize-left:hover {
907
- background: linear-gradient(90deg, #60a5fa 0%, transparent 100%);
908
- }
909
-
910
- .debug-right .debug-header {
911
- flex-direction: column;
912
- width: 44px;
913
- padding: 8px 6px;
914
- border-bottom: none;
915
- border-right: 1px solid #3f3f46;
916
- align-items: center;
917
- gap: 4px;
918
- }
919
- .debug-right .debug-title {
920
- flex-direction: column;
921
- gap: 4px;
922
- }
923
- .debug-right .debug-title span:not(.debug-header-badge) {
924
- display: none;
925
- }
926
- .debug-right .debug-tabs {
927
- flex-direction: column;
928
- margin-left: 0;
929
- margin-top: 8px;
930
- gap: 2px;
931
- }
932
- .debug-right .debug-tab {
933
- width: 32px;
934
- height: 32px;
935
- padding: 0;
936
- justify-content: center;
937
- position: relative;
938
- }
939
- .debug-right .debug-tab-label {
940
- display: none;
941
- }
942
- .debug-right .debug-tab .p-badge {
943
- position: absolute;
944
- top: -2px;
945
- right: -2px;
946
- min-width: 14px;
947
- height: 14px;
948
- font-size: 9px;
949
- padding: 0 3px;
950
- }
951
- /* Content header for right mode */
952
- .debug-content-header {
953
- display: flex;
954
- align-items: center;
955
- justify-content: space-between;
956
- padding: 6px 12px;
957
- background: #27272a;
958
- border-bottom: 1px solid #3f3f46;
959
- flex-shrink: 0;
960
- }
961
- .debug-content-title {
962
- font-weight: 600;
963
- font-size: 12px;
964
- color: #a1a1aa;
965
- }
966
- .debug-content-controls {
967
- display: flex;
968
- gap: 4px;
969
- }
970
- .debug-content-controls .debug-tab-toggle,
971
- .debug-content-controls .debug-tab-clear {
972
- margin-left: 0;
973
- width: 22px;
974
- height: 22px;
975
- }
976
- .debug-right .debug-actions {
977
- flex-direction: column;
978
- margin-left: 0;
979
- margin-top: auto;
980
- gap: 2px;
981
- }
982
- .debug-right .debug-actions .p-button {
983
- width: 28px;
984
- height: 28px;
985
- }
986
- .debug-right .debug-content {
987
- flex: 1;
988
- min-width: 0;
989
- }
990
-
991
- /* Fullscreen - standalone mode like window but full viewport */
992
- .debug-fullscreen {
993
- position: fixed;
994
- top: 0;
995
- left: 0;
996
- right: 0;
997
- bottom: 0;
998
- width: auto;
999
- height: auto;
1000
- border: none;
1001
- border-radius: 0;
1002
- flex-direction: column;
1003
- }
1004
- .debug-fullscreen .debug-header {
1005
- flex-direction: row;
1006
- width: auto;
1007
- height: auto;
1008
- padding: 8px 16px;
1009
- border-bottom: 1px solid #3f3f46;
1010
- border-right: none;
1011
- }
1012
- .debug-fullscreen .debug-title {
1013
- flex-direction: row;
1014
- }
1015
- .debug-fullscreen .debug-title span:not(.debug-header-badge) {
1016
- display: inline;
1017
- }
1018
- .debug-fullscreen .debug-tabs {
1019
- flex-direction: row;
1020
- margin-left: 12px;
1021
- margin-top: 0;
1022
- }
1023
- .debug-fullscreen .debug-tab {
1024
- width: auto;
1025
- height: auto;
1026
- padding: 4px 10px;
1027
- }
1028
- .debug-fullscreen .debug-tab-label {
1029
- display: inline;
1030
- }
1031
- .debug-fullscreen .debug-tab .p-badge {
1032
- position: static;
1033
- }
1034
- .debug-fullscreen .debug-actions {
1035
- flex-direction: row;
1036
- margin-left: auto;
1037
- margin-top: 0;
1038
- }
1039
- .debug-fullscreen .debug-actions .p-button {
1040
- width: auto;
1041
- height: auto;
1042
- }
1043
- .debug-fullscreen .debug-content {
1044
- flex: 1;
1045
- min-height: 0;
1046
- overflow: auto;
1047
- }
1048
-
1049
- /* Header */
1050
- .debug-header {
1051
- display: flex;
1052
- align-items: center;
1053
- gap: 8px;
1054
- padding: 6px 12px;
1055
- background: #27272a;
1056
- border-bottom: 1px solid #3f3f46;
1057
- flex-shrink: 0;
1058
- }
1059
- .debug-title {
1060
- display: flex;
1061
- align-items: center;
1062
- gap: 6px;
1063
- font-weight: 600;
1064
- }
1065
- .debug-title-draggable {
1066
- cursor: grab;
1067
- }
1068
- .debug-title-draggable:active {
1069
- cursor: grabbing;
1070
- }
1071
- .debug-tabs {
1072
- display: flex;
1073
- gap: 2px;
1074
- margin-left: 12px;
1075
- }
1076
- .debug-tabs-compact {
1077
- gap: 1px;
1078
- }
1079
- .debug-tabs-compact .debug-tab {
1080
- padding: 4px 6px;
1081
- }
1082
- .debug-tab {
1083
- display: flex;
1084
- align-items: center;
1085
- gap: 4px;
1086
- padding: 4px 10px;
1087
- background: transparent;
1088
- border: none;
1089
- border-radius: 4px;
1090
- color: #a1a1aa;
1091
- cursor: pointer;
1092
- font-size: 12px;
1093
- }
1094
- .debug-tab:hover {
1095
- background: #3f3f46;
1096
- color: #f4f4f5;
1097
- }
1098
- .debug-tab-active {
1099
- background: #3f3f46;
1100
- color: #a78bfa;
1101
- }
1102
-
1103
- /* Tabs dropdown mode */
1104
- .debug-tabs-dropdown {
1105
- position: relative;
1106
- margin-left: 12px;
1107
- overflow: visible;
1108
- }
1109
- .debug-dropdown-trigger {
1110
- display: flex;
1111
- align-items: center;
1112
- gap: 6px;
1113
- padding: 4px 10px;
1114
- background: #3f3f46;
1115
- border: none;
1116
- border-radius: 4px;
1117
- color: #f4f4f5;
1118
- cursor: pointer;
1119
- font-size: 12px;
1120
- }
1121
- .debug-dropdown-trigger:hover {
1122
- background: #52525b;
1123
- }
1124
- .debug-dropdown-trigger .pi-chevron-down {
1125
- font-size: 10px;
1126
- color: #71717a;
1127
- margin-left: 4px;
1128
- }
1129
- .debug-dropdown-menu {
1130
- position: absolute;
1131
- top: 100%;
1132
- left: 0;
1133
- margin-top: 4px;
1134
- background: #27272a;
1135
- border: 1px solid #3f3f46;
1136
- border-radius: 6px;
1137
- box-shadow: 0 4px 12px rgba(0,0,0,0.4);
1138
- min-width: 160px;
1139
- z-index: 10001;
1140
- padding: 4px;
1141
- }
1142
- .debug-dropdown-item {
1143
- display: flex;
1144
- align-items: center;
1145
- gap: 8px;
1146
- width: 100%;
1147
- padding: 6px 10px;
1148
- background: transparent;
1149
- border: none;
1150
- border-radius: 4px;
1151
- color: #a1a1aa;
1152
- cursor: pointer;
1153
- font-size: 12px;
1154
- text-align: left;
1155
- }
1156
- .debug-dropdown-item:hover {
1157
- background: #3f3f46;
1158
- color: #f4f4f5;
1159
- }
1160
- .debug-dropdown-item-active {
1161
- background: #3f3f46;
1162
- color: #a78bfa;
1163
- }
1164
- .debug-actions {
1165
- display: flex;
1166
- gap: 2px;
1167
- margin-left: auto;
1168
- }
1169
-
1170
- /* Content */
1171
- .debug-content {
1172
- flex: 1;
1173
- overflow: auto;
1174
- background: #18181b;
1175
- }
1176
- .debug-empty {
1177
- display: flex;
1178
- flex-direction: column;
1179
- align-items: center;
1180
- justify-content: center;
1181
- height: 100%;
1182
- color: #71717a;
1183
- gap: 8px;
1184
- }
1185
-
1186
- /* Per-collector toggle button */
1187
- .debug-tab-toggle {
1188
- display: flex;
1189
- align-items: center;
1190
- justify-content: center;
1191
- width: 18px;
1192
- height: 18px;
1193
- margin-left: 4px;
1194
- padding: 0;
1195
- background: transparent;
1196
- border: none;
1197
- border-radius: 3px;
1198
- color: #71717a;
1199
- cursor: pointer;
1200
- font-size: 9px;
1201
- }
1202
- .debug-tab-toggle:hover {
1203
- background: #52525b;
1204
- color: #f4f4f5;
1205
- }
1206
- .debug-tab-toggle-paused {
1207
- color: #f59e0b;
1208
- }
1209
- .debug-tab-clear {
1210
- display: flex;
1211
- align-items: center;
1212
- justify-content: center;
1213
- width: 18px;
1214
- height: 18px;
1215
- margin-left: 2px;
1216
- padding: 0;
1217
- background: transparent;
1218
- border: none;
1219
- border-radius: 3px;
1220
- color: #71717a;
1221
- cursor: pointer;
1222
- font-size: 9px;
1223
- }
1224
- .debug-tab-clear:hover {
1225
- background: #ef4444;
1226
- color: white;
1227
- }
1228
-
1229
- /* Custom mode toggle button */
1230
- .debug-mode-btn {
1231
- display: flex;
1232
- align-items: center;
1233
- justify-content: center;
1234
- width: 2rem;
1235
- height: 2rem;
1236
- padding: 0;
1237
- background: transparent;
1238
- border: none;
1239
- border-radius: 50%;
1240
- color: #a1a1aa;
1241
- cursor: pointer;
1242
- font-size: 18px;
1243
- font-weight: bold;
1244
- font-family: monospace;
1245
- line-height: 1;
1246
- transition: background-color 0.15s, color 0.15s;
1247
- }
1248
- .debug-mode-btn:hover {
1249
- background: rgba(255, 255, 255, 0.1);
1250
- color: #f4f4f5;
1251
- }
1252
- </style>