@sava-info-systems/api-maker-with-extensions 2.2.1 → 3.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.
Files changed (244) hide show
  1. package/.dockerignore +5 -1
  2. package/Dockerfile +1 -35
  3. package/Dockerfile.base +22 -0
  4. package/Dockerfile.extended-base +44 -0
  5. package/dist/1025.5c34b11ab88519fd.js +1 -0
  6. package/dist/1097.3c5b2b4587cefa6e.js +1 -0
  7. package/dist/115.8d10b2b963e7d632.js +1 -0
  8. package/dist/148.f8f560a5f818328e.js +1 -0
  9. package/dist/1558.576af7585833e289.js +1 -0
  10. package/dist/1678.14f917ee37080d63.js +1 -0
  11. package/dist/1754.fc6d6e9f6c1e96d5.js +1 -0
  12. package/dist/1928.9c9375dd036b025a.js +1 -0
  13. package/dist/1957.b718aa368330b524.js +1 -0
  14. package/dist/2140.bb097d69bcb6a1e5.js +1 -0
  15. package/dist/2295.aa3514c8d1238cb2.js +1 -0
  16. package/dist/238.553f30dbe5124419.js +1 -0
  17. package/dist/2473.260a6b26a70eaa8d.js +1 -0
  18. package/dist/2579.b02fe6a8ba3a2e71.js +1 -0
  19. package/dist/2714.b41d14f7378785df.js +1 -0
  20. package/dist/2735.4046cae4c68ac75f.js +1 -0
  21. package/dist/292.bb85e0ea91dcc118.js +1 -0
  22. package/dist/3139.5dd9289cc24b4100.js +1 -0
  23. package/dist/3450.588aafa515b19133.js +1 -0
  24. package/dist/3664.ed1232e3c70195fc.js +1 -0
  25. package/dist/3752.d4e0a280a37c1426.js +1 -0
  26. package/dist/3rdpartylicenses.txt +1 -1
  27. package/dist/4110.b9ebfd9a7382c450.js +1 -0
  28. package/dist/4186.2fd0537d5bc6d882.js +1 -0
  29. package/dist/4211.b6b9f495b100e985.js +1 -0
  30. package/dist/4575.1fee055d10b57afc.js +1 -0
  31. package/dist/4842.ccf765ed3e9753a7.js +1 -0
  32. package/dist/485.7870367c9475fed8.js +1 -0
  33. package/dist/{4895.a54759704d1994b1.js → 4895.fa7b24d66157c531.js} +1 -1
  34. package/dist/5334.e0a2450fc295f659.js +1 -0
  35. package/dist/5421.2c2c0fbf926792db.js +1 -0
  36. package/dist/5434.0997994b319a866a.js +1 -0
  37. package/dist/5679.e362a3e10cb1b953.js +1 -0
  38. package/dist/5761.6c20b09245ac31ef.js +1 -0
  39. package/dist/5765.8d761aef1708e8a1.js +1 -0
  40. package/dist/6236.969b45cad747277c.js +1 -0
  41. package/dist/6393.1b7b097f17d75290.js +1 -0
  42. package/dist/6401.f18e3c98d6deaa22.js +1 -0
  43. package/dist/6650.05ea40acd68697c3.js +1 -0
  44. package/dist/7368.85d940d08fdca6e2.js +1 -0
  45. package/dist/7436.4a62f7ef13cffb21.js +1 -0
  46. package/dist/7470.d24359dc7a3ef75a.js +1 -0
  47. package/dist/7649.8e5ff8a951b474e0.js +1 -0
  48. package/dist/7975.d3d7064d527ac017.js +1 -0
  49. package/dist/7977.85b17bdb465e9a90.js +1 -0
  50. package/dist/7987.c1637bec96a9cc03.js +1 -0
  51. package/dist/8125.8390bc1b477ec6b9.js +1 -0
  52. package/dist/8266.0bf85311cf40ddff.js +1 -0
  53. package/dist/8296.fe54c3787977fad3.js +1 -0
  54. package/dist/885.7e1ec0f82adbdd6f.js +1 -0
  55. package/dist/891.fee03277c7f1c29d.js +1 -0
  56. package/dist/{913.4580b4ce4307a40f.js → 913.e49eb351997bc25c.js} +1 -1
  57. package/dist/9243.eaa2c312b42fc4b3.js +1 -0
  58. package/dist/9575.8404e98d640fd9f9.js +1 -0
  59. package/dist/9939.537c5e355804804b.js +1 -0
  60. package/dist/assets/images/icons/api-group-light.svg +11 -0
  61. package/dist/assets/images/icons/api-group.svg +5 -5
  62. package/dist/assets/images/icons/api-maker-deployment-light.svg +5 -0
  63. package/dist/assets/images/icons/api-maker-deployment.svg +3 -3
  64. package/dist/assets/images/icons/api-user-light.svg +12 -0
  65. package/dist/assets/images/icons/api-user.svg +2 -2
  66. package/dist/assets/images/icons/comparator-light.svg +61 -0
  67. package/dist/assets/images/icons/comparator.svg +2 -2
  68. package/dist/assets/images/icons/custom-light.svg +6 -0
  69. package/dist/assets/images/icons/custom.svg +5 -5
  70. package/dist/assets/images/icons/database-light.svg +29 -0
  71. package/dist/assets/images/icons/database.svg +6 -6
  72. package/dist/assets/images/icons/db-m-light.svg +10 -0
  73. package/dist/assets/images/icons/db-m.svg +4 -4
  74. package/dist/assets/images/icons/db-token-generator-light.svg +4 -0
  75. package/dist/assets/images/icons/db-token-generator.svg +4 -0
  76. package/dist/assets/images/icons/dev-light.svg +13 -0
  77. package/dist/assets/images/icons/dev.svg +4 -4
  78. package/dist/assets/images/icons/diagram-light.svg +28 -0
  79. package/dist/assets/images/icons/diagram.svg +9 -9
  80. package/dist/assets/images/icons/event-light.svg +16 -0
  81. package/dist/assets/images/icons/event.svg +4 -4
  82. package/dist/assets/images/icons/film-movies-icon.svg +3 -3
  83. package/dist/assets/images/icons/finder-light.svg +14 -0
  84. package/dist/assets/images/icons/finder.svg +3 -3
  85. package/dist/assets/images/icons/i18n-light.svg +11 -0
  86. package/dist/assets/images/icons/i18n.svg +6 -6
  87. package/dist/assets/images/icons/increment-light.svg +5 -0
  88. package/dist/assets/images/icons/increment.svg +2 -2
  89. package/dist/assets/images/icons/license-light.svg +6 -0
  90. package/dist/assets/images/icons/license.svg +4 -4
  91. package/dist/assets/images/icons/log-light.svg +17 -0
  92. package/dist/assets/images/icons/log-profile-light.svg +23 -0
  93. package/dist/assets/images/icons/log-profile.svg +7 -7
  94. package/dist/assets/images/icons/log.svg +6 -6
  95. package/dist/assets/images/icons/masters.svg +3 -3
  96. package/dist/assets/images/icons/native-process-logs-light.svg +13 -0
  97. package/dist/assets/images/icons/native-process-logs.svg +6 -6
  98. package/dist/assets/images/icons/nodes-light.svg +5 -0
  99. package/dist/assets/images/icons/nodes.svg +2 -2
  100. package/dist/assets/images/icons/notes-light.svg +16 -0
  101. package/dist/assets/images/icons/notes.svg +2 -2
  102. package/dist/assets/images/icons/process_initializers-light.svg +20 -0
  103. package/dist/assets/images/icons/process_initializers.svg +7 -7
  104. package/dist/assets/images/icons/rsa_encryption-light.svg +6 -0
  105. package/dist/assets/images/icons/rsa_encryption.svg +2 -2
  106. package/dist/assets/images/icons/sandbox-light.svg +11 -0
  107. package/dist/assets/images/icons/sandbox.svg +2 -2
  108. package/dist/assets/images/icons/scanning-period-light.svg +13 -0
  109. package/dist/assets/images/icons/scanning-period.svg +4 -4
  110. package/dist/assets/images/icons/schedulers-light.svg +8 -0
  111. package/dist/assets/images/icons/schedulers.svg +5 -5
  112. package/dist/assets/images/icons/secret-light.svg +15 -0
  113. package/dist/assets/images/icons/secret.svg +2 -2
  114. package/dist/assets/images/icons/swagger-logo-light.svg +9 -0
  115. package/dist/assets/images/icons/swagger-logo.svg +2 -2
  116. package/dist/assets/images/icons/systems-light.svg +8 -0
  117. package/dist/assets/images/icons/systems.svg +3 -3
  118. package/dist/assets/images/icons/testing-light.svg +12 -0
  119. package/dist/assets/images/icons/testing.svg +6 -6
  120. package/dist/assets/images/icons/third-party-light.svg +19 -0
  121. package/dist/assets/images/icons/third-party.svg +4 -4
  122. package/dist/assets/images/icons/typescript-light.svg +12 -0
  123. package/dist/assets/images/icons/typescript.svg +2 -2
  124. package/dist/assets/images/icons/ui-maker-light.svg +23 -0
  125. package/dist/assets/images/icons/ui-maker.svg +10 -10
  126. package/dist/assets/images/icons/utility-light.svg +19 -0
  127. package/dist/assets/images/icons/utility.svg +2 -2
  128. package/dist/assets/images/icons/vulnerability-light.svg +20 -0
  129. package/dist/assets/images/icons/vulnerability.svg +5 -5
  130. package/dist/assets/images/icons/web-light.svg +16 -0
  131. package/dist/assets/images/icons/web.svg +3 -3
  132. package/dist/assets/images/logo/api_maker_logo_dark.svg +29 -0
  133. package/dist/assets/images/logo/api_maker_logo_full_white.svg +29 -0
  134. package/dist/assets/images/logo/api_maker_logo_light.svg +22 -0
  135. package/dist/assets/images/logo/apple-touch-icon.png +0 -0
  136. package/dist/assets/images/logo/favicon-192x192.png +0 -0
  137. package/dist/assets/images/logo/favicon-32x32.png +0 -0
  138. package/dist/assets/images/logo/favicon-512x512.png +0 -0
  139. package/dist/assets/images/logo/logo_docs-light.svg +15 -0
  140. package/dist/assets/images/logo/logo_docs.svg +3 -3
  141. package/dist/assets/images/logo/logo_store-light.svg +17 -0
  142. package/dist/assets/images/logo/logo_store.svg +3 -3
  143. package/dist/assets/images/logo/store_logo-dark.svg +11 -0
  144. package/dist/assets/images/logo/store_logo-light.svg +11 -0
  145. package/dist/assets/images/logo/store_logo.svg +2 -2
  146. package/dist/assets/primeng-theme/primeng-theme-overrides.scss +1426 -31
  147. package/dist/assets/public/diagram-viewer/data.json +1886 -0
  148. package/dist/assets/public/diagram-viewer/index.html +1228 -0
  149. package/dist/assets/public/diagram-viewer/index.js +1 -0
  150. package/dist/assets/public/monaco-editor/index.html +105 -9
  151. package/dist/assets/public/monaco-editor/index.js +1 -1
  152. package/dist/assets/public/table-viewer/index.html +738 -0
  153. package/dist/assets/public/table-viewer/index.js +1 -0
  154. package/dist/assets/schema-types/InterfaceProps.ts +71 -13
  155. package/dist/assets/schema-types/store-types.ts +2 -0
  156. package/dist/assets/schema-types/types.ts +65 -17
  157. package/dist/assets/styles/bootstrap-overrides.scss +170 -7
  158. package/dist/assets/styles/colors-dark.scss +320 -33
  159. package/dist/assets/styles/colors-light.scss +453 -9
  160. package/dist/assets/styles/out/styles.css.map +1 -1
  161. package/dist/assets/styles/styles.scss +286 -15
  162. package/dist/assets/styles/variables.scss +2 -2
  163. package/dist/bootstrap-overrides.css +1 -0
  164. package/dist/colors-dark.css +1 -0
  165. package/dist/colors-light.css +1 -0
  166. package/dist/{common.912ad7a22e5de63a.js → common.86c514055f788290.js} +1 -1
  167. package/dist/index.html +111 -27
  168. package/dist/main.0ac98a72f1b9c1dd.js +1 -0
  169. package/dist/runtime.0e9fc303007ced09.js +1 -0
  170. package/dist/styles-global.css +1 -0
  171. package/dist/{styles.242217e145c3f7ab.css → styles.c1032bc4f4d7829b.css} +1 -1
  172. package/main.js +1 -1
  173. package/package-sandbox.json +1 -1
  174. package/package.json +9 -9
  175. package/pnpm-workspace.yaml +15 -0
  176. package/sandbox.js +1 -1
  177. package/src/assets/schema-types/store-types.ts +2 -0
  178. package/src/assets/schema-types/types.ts +65 -17
  179. package/src/schema-types/store-types.js +2 -0
  180. package/src/schema-types/types.js +1 -0
  181. package/src/tools/.github/copilot-instructions.md +17 -9
  182. package/src/tools/local-client.js +1 -1
  183. package/dist/1025.a0db9347453600d0.js +0 -1
  184. package/dist/1097.d0d6fd13031aa1f0.js +0 -1
  185. package/dist/148.1dc7d9e0cfe45510.js +0 -1
  186. package/dist/1558.0aae3e5c538d3815.js +0 -1
  187. package/dist/1678.ed1e4a269e0f42bc.js +0 -1
  188. package/dist/1754.691f142aa1eabe28.js +0 -1
  189. package/dist/1928.2b376f7cf66ed038.js +0 -1
  190. package/dist/1957.ab7fda21d9978597.js +0 -1
  191. package/dist/2140.1ce150285aebe3cc.js +0 -1
  192. package/dist/2295.4fa1d4b5ff482f3a.js +0 -1
  193. package/dist/238.891233aa670bdd2b.js +0 -1
  194. package/dist/2473.4b2bb1ad5b1cc99d.js +0 -1
  195. package/dist/2579.6558b67b2d98f116.js +0 -1
  196. package/dist/2714.0d6939336a02dd0a.js +0 -1
  197. package/dist/2735.86437a8639a0c1bb.js +0 -1
  198. package/dist/292.c7c794ff29abbe37.js +0 -1
  199. package/dist/3139.0921102d181c220d.js +0 -1
  200. package/dist/3450.9b5cfc83039b02b5.js +0 -1
  201. package/dist/3664.4a1dd7f16f8b57fb.js +0 -1
  202. package/dist/4110.d108e786ecbdfd1b.js +0 -1
  203. package/dist/4186.ac3e8af0efeeac14.js +0 -1
  204. package/dist/4211.1bfe72ce0b7b2f76.js +0 -1
  205. package/dist/443.7e3946651373e09a.js +0 -1
  206. package/dist/4575.6ad36e53bd72fb6f.js +0 -1
  207. package/dist/4842.e7649d81606ad80d.js +0 -1
  208. package/dist/485.b546656b466cb8a4.js +0 -1
  209. package/dist/5334.72c1c6d89fdf136e.js +0 -1
  210. package/dist/5421.2067001c10533303.js +0 -1
  211. package/dist/5679.4e22239895c7f520.js +0 -1
  212. package/dist/5761.331ca41ab64cca92.js +0 -1
  213. package/dist/5765.2b640be5d177d794.js +0 -1
  214. package/dist/6236.6c0fc469f0c96549.js +0 -1
  215. package/dist/6393.173ecdfc3b022973.js +0 -1
  216. package/dist/6401.374823002788afe7.js +0 -1
  217. package/dist/6650.1d18ee25901d68be.js +0 -1
  218. package/dist/7368.9ebf62d518f8ad7a.js +0 -1
  219. package/dist/7436.640bf5fe48814cbe.js +0 -1
  220. package/dist/7470.b1ce7eedb9cedb2d.js +0 -1
  221. package/dist/7649.ab4744cfe713eec0.js +0 -1
  222. package/dist/7975.578a00ebd1160a1e.js +0 -1
  223. package/dist/7977.afeded970bac8b66.js +0 -1
  224. package/dist/7987.5958ad5b81873058.js +0 -1
  225. package/dist/8125.b2f908096882ed45.js +0 -1
  226. package/dist/8266.aca59a0a04590ab1.js +0 -1
  227. package/dist/8296.a387c28f5702c5e8.js +0 -1
  228. package/dist/885.be44d92efca1aaf6.js +0 -1
  229. package/dist/891.5e08c81e5200413e.js +0 -1
  230. package/dist/9243.08630ad94e1fddba.js +0 -1
  231. package/dist/9575.30ac91b65602c0ca.js +0 -1
  232. package/dist/9939.4b0d758462bcc042.js +0 -1
  233. package/dist/assets/images/logo/API Maker Logo 2021 black.svg +0 -47
  234. package/dist/assets/images/logo/API Maker Logo 2021.svg +0 -49
  235. package/dist/assets/images/logo/logo.svg +0 -41
  236. package/dist/assets/styles/out/bootstrap-overrides.css +0 -2
  237. package/dist/assets/styles/out/colors-dark.css +0 -2
  238. package/dist/assets/styles/out/colors-light.css +0 -2
  239. package/dist/assets/styles/out/monaco-editor-overrides.css +0 -2
  240. package/dist/assets/styles/out/styles.css +0 -2
  241. package/dist/assets/styles/out/variables.css +0 -2
  242. package/dist/favicon.ico +0 -0
  243. package/dist/main.d3c81428418939dc.js +0 -1
  244. package/dist/runtime.2f0f434d4763c970.js +0 -1
@@ -0,0 +1,738 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Table Viewer</title>
7
+ <script>
8
+ // Apply the app theme (shared localStorage, same origin) before render to avoid a flash.
9
+ (function () {
10
+ function applyTheme(t) {
11
+ var light = t === 'LIGHT';
12
+ document.documentElement.classList.toggle('light', light);
13
+ // swap AG Grid theme class on any existing grid container
14
+ document.querySelectorAll('.ag-theme-alpine-dark, .ag-theme-alpine').forEach(function (el) {
15
+ el.classList.toggle('ag-theme-alpine', light);
16
+ el.classList.toggle('ag-theme-alpine-dark', !light);
17
+ });
18
+ }
19
+ try { applyTheme(localStorage.getItem('THEME')); } catch (e) {}
20
+ window.addEventListener('message', function (ev) {
21
+ var m = ev.data;
22
+ if (m && m.type === 'SET_THEME') applyTheme(m.payload && m.payload.theme);
23
+ });
24
+ // expose for the grid-creation code to read
25
+ window.__amIsLight = function () { try { return localStorage.getItem('THEME') === 'LIGHT'; } catch (e) { return false; } };
26
+ }());
27
+ </script>
28
+
29
+ <!-- AG Grid Community -->
30
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-grid.css">
31
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-theme-alpine-dark.css">
32
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/styles/ag-theme-alpine.css">
33
+ <script src="https://cdn.jsdelivr.net/npm/ag-grid-community@31.3.4/dist/ag-grid-community.min.js"></script>
34
+
35
+ <!-- SheetJS for Excel export -->
36
+ <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
37
+
38
+ <!-- jsPDF + autotable for PDF export -->
39
+ <script src="https://cdn.jsdelivr.net/npm/jspdf@2.5.1/dist/jspdf.umd.min.js"></script>
40
+ <script src="https://cdn.jsdelivr.net/npm/jspdf-autotable@3.8.2/dist/jspdf.plugin.autotable.min.js"></script>
41
+
42
+ <style>
43
+ *, *::before, *::after {
44
+ box-sizing: border-box;
45
+ margin: 0;
46
+ padding: 0;
47
+ }
48
+
49
+ :root {
50
+ --bg-primary: #141c29;
51
+ --bg-secondary: #1b2636;
52
+ --bg-tertiary: #22324a;
53
+ --hairline: rgba(97, 175, 239, 0.14);
54
+ --hairline-strong: rgba(97, 175, 239, 0.28);
55
+ --text-primary: #e6ebf2;
56
+ --text-secondary: #9aa6b5;
57
+ --text-muted: #6f7c8c;
58
+ --brand: #61AFEF;
59
+ --blue: #0C53A4;
60
+ --success: #00893F;
61
+ --warning: #E5C07B;
62
+ --danger: #E06C75;
63
+ --editor-bg: #10161f;
64
+ }
65
+
66
+ /* LIGHT theme — applied when <html> has class "light" (set from app's THEME) */
67
+ html.light {
68
+ --bg-primary: #ffffff;
69
+ --bg-secondary: #eef3fa;
70
+ --bg-tertiary: #e3eaf3;
71
+ --hairline: rgba(12, 83, 164, 0.14);
72
+ --hairline-strong: rgba(12, 83, 164, 0.28);
73
+ --text-primary: #1b2330;
74
+ --text-secondary: #4a5563;
75
+ --text-muted: #7a8694;
76
+ --brand: #0C53A4;
77
+ --blue: #0C53A4;
78
+ --success: #00893F;
79
+ --warning: #d99a07;
80
+ --danger: #DC2626;
81
+ --editor-bg: #f6f8fb;
82
+ }
83
+
84
+ html, body {
85
+ height: 100%;
86
+ overflow: hidden;
87
+ background: var(--editor-bg);
88
+ color: var(--text-primary);
89
+ font-family: 'JetBrains Mono', 'Menlo', 'Monaco', 'Consolas', monospace;
90
+ font-size: 12px;
91
+ }
92
+
93
+ #app {
94
+ display: flex;
95
+ flex-direction: column;
96
+ height: 100vh;
97
+ position: relative;
98
+ }
99
+
100
+ /* ── Toolbar ─────────────────────────────────────────────────────────────── */
101
+ .toolbar {
102
+ display: flex;
103
+ align-items: center;
104
+ gap: 4px;
105
+ padding: 4px 36px 4px 8px;
106
+ background: var(--bg-secondary);
107
+ border-bottom: 1px solid var(--hairline);
108
+ flex-shrink: 0;
109
+ flex-wrap: nowrap;
110
+ min-height: 30px;
111
+ }
112
+
113
+ .btn {
114
+ background: var(--bg-tertiary);
115
+ border: 1px solid var(--hairline-strong);
116
+ color: var(--text-primary);
117
+ padding: 2px 7px;
118
+ border-radius: 3px;
119
+ cursor: pointer;
120
+ font-size: 11px;
121
+ font-family: inherit;
122
+ display: inline-flex;
123
+ align-items: center;
124
+ gap: 3px;
125
+ white-space: nowrap;
126
+ transition: background 0.12s, border-color 0.12s;
127
+ line-height: 18px;
128
+ height: 22px;
129
+ }
130
+
131
+ .btn:hover {
132
+ /* Brand-blue tint + hairline (matches the app's button hover),
133
+ instead of a flat grey that clashed with the brand surfaces. */
134
+ background: rgba(12, 83, 164, 0.18);
135
+ border-color: var(--hairline-strong);
136
+ color: var(--text-primary);
137
+ }
138
+
139
+ .btn:active {
140
+ background: rgba(12, 83, 164, 0.28);
141
+ }
142
+
143
+ .btn-success {
144
+ color: var(--success);
145
+ border-color: rgba(38, 180, 127, 0.4);
146
+ }
147
+
148
+ .btn-success:hover {
149
+ background: rgba(38, 180, 127, 0.12);
150
+ }
151
+
152
+ .btn-danger {
153
+ color: var(--danger);
154
+ border-color: rgba(237, 75, 72, 0.4);
155
+ }
156
+
157
+ .btn-danger:hover {
158
+ background: rgba(237, 75, 72, 0.12);
159
+ }
160
+
161
+ .btn-warning {
162
+ color: var(--warning);
163
+ border-color: rgba(255, 180, 0, 0.4);
164
+ }
165
+
166
+ /* Export = primary action: solid brand blue, consistent with the
167
+ other toolbar buttons' shape but clearly the primary control. */
168
+ .btn-blue {
169
+ background: var(--blue);
170
+ color: #ffffff;
171
+ border-color: var(--blue);
172
+ }
173
+
174
+ .btn-blue:hover {
175
+ background: #0a4685;
176
+ border-color: #0a4685;
177
+ color: #ffffff;
178
+ }
179
+
180
+ .btn-blue:active {
181
+ background: #083a6f;
182
+ border-color: #083a6f;
183
+ }
184
+
185
+ .toolbar-sep {
186
+ width: 1px;
187
+ height: 16px;
188
+ background: var(--hairline-strong);
189
+ flex-shrink: 0;
190
+ }
191
+
192
+ .toolbar-spacer {
193
+ flex: 1;
194
+ }
195
+
196
+ .filter-input {
197
+ background: var(--bg-tertiary);
198
+ border: 1px solid var(--hairline-strong);
199
+ color: var(--text-primary);
200
+ padding: 2px 7px;
201
+ border-radius: 3px;
202
+ font-size: 11px;
203
+ font-family: inherit;
204
+ width: 160px;
205
+ outline: none;
206
+ height: 22px;
207
+ transition: border-color 0.12s;
208
+ }
209
+
210
+ .filter-input:focus {
211
+ border-color: var(--blue);
212
+ }
213
+
214
+ .filter-input::placeholder {
215
+ color: var(--text-muted);
216
+ }
217
+
218
+ /* ── Grid container ──────────────────────────────────────────────────────── */
219
+ .grid-wrap {
220
+ flex: 1;
221
+ position: relative;
222
+ overflow: hidden;
223
+ min-height: 0;
224
+ }
225
+
226
+ #myGrid {
227
+ width: 100%;
228
+ height: 100%;
229
+ }
230
+
231
+ /* ── AG Grid overrides (dark theme) ──────────────────────────────────────── */
232
+ .ag-theme-alpine-dark {
233
+ /* Brand navy grid surfaces (match the app dark theme: navy base
234
+ #0e1726, card surface #141c29, brand-blue hairlines). */
235
+ --ag-background-color: #0e1726;
236
+ --ag-foreground-color: #e6ebf2;
237
+ --ag-border-color: rgba(97, 175, 239, 0.14);
238
+ --ag-secondary-border-color: rgba(97, 175, 239, 0.14);
239
+ --ag-header-background-color: #141c29;
240
+ --ag-header-foreground-color: #9aa6b5;
241
+ --ag-odd-row-background-color: #121b2a;
242
+ --ag-even-row-background-color: #0e1726;
243
+ --ag-row-hover-color: rgba(12, 83, 164, 0.18);
244
+ --ag-selected-row-background-color: rgba(12, 83, 164, 0.22);
245
+ --ag-range-selection-background-color: rgba(12, 83, 164, 0.14);
246
+ --ag-range-selection-border-color: #0C53A4;
247
+ --ag-header-cell-hover-background-color: #1b2636;
248
+ --ag-cell-horizontal-padding: 5px;
249
+ --ag-font-size: 12px;
250
+ --ag-font-family: 'JetBrains Mono', 'Menlo', 'Monaco', monospace;
251
+ --ag-row-height: 26px;
252
+ --ag-header-height: 28px;
253
+ --ag-filter-tool-panel-header-height: 26px;
254
+ --ag-input-focus-border-color: #0C53A4;
255
+ --ag-checkbox-checked-color: #0C53A4;
256
+ --ag-checkbox-unchecked-color: #686868;
257
+ --ag-active-color: #0C53A4;
258
+ --ag-balham-active-color: #0C53A4;
259
+ }
260
+
261
+ /* ── AG Grid overrides (LIGHT theme) ─────────────────────────────────────── */
262
+ html.light .ag-theme-alpine,
263
+ html.light .ag-theme-alpine-dark {
264
+ --ag-background-color: #ffffff;
265
+ --ag-foreground-color: #1b2330;
266
+ --ag-border-color: rgba(12, 83, 164, 0.14);
267
+ --ag-secondary-border-color: rgba(12, 83, 164, 0.14);
268
+ --ag-header-background-color: #eef3fa;
269
+ --ag-header-foreground-color: #4a5563;
270
+ --ag-odd-row-background-color: #f3f7fc;
271
+ --ag-even-row-background-color: #ffffff;
272
+ --ag-row-hover-color: #eaf1fb;
273
+ --ag-selected-row-background-color: rgba(12, 83, 164, 0.14);
274
+ --ag-range-selection-background-color: rgba(12, 83, 164, 0.10);
275
+ --ag-range-selection-border-color: #0C53A4;
276
+ --ag-header-cell-hover-background-color: #e3eaf3;
277
+ --ag-input-focus-border-color: #0C53A4;
278
+ --ag-checkbox-checked-color: #0C53A4;
279
+ --ag-active-color: #0C53A4;
280
+ --ag-balham-active-color: #0C53A4;
281
+ /* keep the SAME compact density as dark mode (alpine-light defaults are taller) */
282
+ --ag-grid-size: 3px;
283
+ --ag-cell-horizontal-padding: 5px;
284
+ --ag-row-height: 26px;
285
+ --ag-header-height: 28px;
286
+ --ag-list-item-height: 24px;
287
+ --ag-font-size: 12px;
288
+ --ag-font-family: 'JetBrains Mono', 'Menlo', 'Monaco', monospace;
289
+ }
290
+
291
+ /* Tighter header padding */
292
+ .ag-theme-alpine-dark .ag-header-cell {
293
+ padding-left: 5px;
294
+ padding-right: 5px;
295
+ font-size: 11px;
296
+ color: #b0b0b0;
297
+ font-weight: 600;
298
+ letter-spacing: 0.02em;
299
+ }
300
+
301
+ .ag-theme-alpine-dark .ag-cell {
302
+ line-height: 26px;
303
+ padding-left: 5px;
304
+ padding-right: 5px;
305
+ }
306
+
307
+ /* Modified cell highlight */
308
+ .ag-theme-alpine-dark .cell-modified {
309
+ background-color: rgba(255, 180, 0, 0.08) !important;
310
+ border-left: 2px solid var(--warning) !important;
311
+ }
312
+
313
+ /* Server-side field error highlight */
314
+ .ag-theme-alpine-dark .cell-error {
315
+ background-color: rgba(237, 75, 72, 0.1) !important;
316
+ border-left: 2px solid var(--danger) !important;
317
+ }
318
+
319
+ /* Cell editing */
320
+ .ag-theme-alpine-dark .ag-cell.ag-cell-inline-editing {
321
+ background-color: #1a3555 !important;
322
+ border: 1px solid var(--blue) !important;
323
+ box-shadow: 0 0 0 1px rgba(9, 123, 237, 0.3);
324
+ }
325
+
326
+ /* Sortable header arrows */
327
+ .ag-theme-alpine-dark .ag-sort-indicator-icon {
328
+ color: var(--blue);
329
+ }
330
+
331
+ /* Filter active indicator */
332
+ .ag-theme-alpine-dark .ag-header-icon.ag-filter-icon {
333
+ color: var(--warning);
334
+ }
335
+
336
+ /* Scrollbars */
337
+ .ag-theme-alpine-dark ::-webkit-scrollbar {
338
+ width: 6px;
339
+ height: 6px;
340
+ }
341
+
342
+ .ag-theme-alpine-dark ::-webkit-scrollbar-track {
343
+ background: #1a1a1a;
344
+ }
345
+
346
+ .ag-theme-alpine-dark ::-webkit-scrollbar-thumb {
347
+ background: #444;
348
+ border-radius: 3px;
349
+ }
350
+
351
+ .ag-theme-alpine-dark ::-webkit-scrollbar-thumb:hover {
352
+ background: #666;
353
+ }
354
+
355
+ /* ── Status bar ──────────────────────────────────────────────────────────── */
356
+ .status-bar {
357
+ padding: 2px 8px;
358
+ background: var(--bg-secondary);
359
+ border-top: 1px solid var(--hairline);
360
+ font-size: 10px;
361
+ color: var(--text-secondary);
362
+ flex-shrink: 0;
363
+ display: flex;
364
+ align-items: center;
365
+ gap: 10px;
366
+ min-height: 20px;
367
+ }
368
+
369
+ .status-dot {
370
+ width: 6px;
371
+ height: 6px;
372
+ border-radius: 50%;
373
+ background: var(--text-muted);
374
+ flex-shrink: 0;
375
+ transition: background 0.2s;
376
+ }
377
+
378
+ .status-dot.loading {
379
+ background: var(--warning);
380
+ animation: blink 0.9s ease-in-out infinite;
381
+ }
382
+
383
+ .status-dot.success {
384
+ background: var(--success);
385
+ }
386
+
387
+ .status-dot.error {
388
+ background: var(--danger);
389
+ }
390
+
391
+ @keyframes blink {
392
+ 0%, 100% {
393
+ opacity: 1;
394
+ }
395
+ 50% {
396
+ opacity: 0.3;
397
+ }
398
+ }
399
+
400
+ .status-sep {
401
+ color: var(--text-muted);
402
+ }
403
+
404
+ /* ── Overlays ─────────────────────────────────────────────────────────────── */
405
+ .loading-overlay {
406
+ position: absolute;
407
+ inset: 0;
408
+ background: rgba(30, 30, 30, 0.8);
409
+ display: flex;
410
+ align-items: center;
411
+ justify-content: center;
412
+ z-index: 100;
413
+ }
414
+
415
+ .spinner {
416
+ width: 26px;
417
+ height: 26px;
418
+ border: 2.5px solid rgba(255, 255, 255, 0.1);
419
+ border-top-color: var(--blue);
420
+ border-radius: 50%;
421
+ animation: spin 0.65s linear infinite;
422
+ }
423
+
424
+ .confirm-overlay {
425
+ position: fixed;
426
+ inset: 0;
427
+ background: rgba(0, 0, 0, 0.55);
428
+ display: none;
429
+ align-items: center;
430
+ justify-content: center;
431
+ z-index: 200;
432
+ padding: 16px;
433
+ }
434
+
435
+ .confirm-dialog {
436
+ width: min(440px, 100%);
437
+ background: var(--bg-secondary);
438
+ border: 1px solid var(--hairline-strong);
439
+ box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
440
+ border-radius: 12px;
441
+ padding: 18px;
442
+ color: var(--text-primary);
443
+ }
444
+
445
+ .confirm-dialog h3 {
446
+ margin-bottom: 10px;
447
+ font-size: 14px;
448
+ color: var(--text-primary);
449
+ }
450
+
451
+ .confirm-dialog p {
452
+ margin-bottom: 20px;
453
+ font-size: 12px;
454
+ color: var(--text-muted);
455
+ line-height: 1.5;
456
+ white-space: pre-wrap;
457
+ }
458
+
459
+ .confirm-actions {
460
+ display: flex;
461
+ justify-content: flex-end;
462
+ gap: 8px;
463
+ flex-wrap: wrap;
464
+ }
465
+
466
+ .confirm-actions .btn {
467
+ min-width: 88px;
468
+ justify-content: center;
469
+ }
470
+
471
+ @keyframes spin {
472
+ to {
473
+ transform: rotate(360deg);
474
+ }
475
+ }
476
+
477
+ .empty-state {
478
+ position: absolute;
479
+ inset: 0;
480
+ display: flex;
481
+ flex-direction: column;
482
+ align-items: center;
483
+ justify-content: center;
484
+ gap: 6px;
485
+ color: var(--text-muted);
486
+ font-size: 12px;
487
+ pointer-events: none;
488
+ }
489
+
490
+ .empty-state svg {
491
+ opacity: 0.3;
492
+ margin-bottom: 4px;
493
+ }
494
+
495
+ /* ── Pending badge ────────────────────────────────────────────────────────── */
496
+ .pending-pill {
497
+ display: inline-flex;
498
+ align-items: center;
499
+ justify-content: center;
500
+ background: var(--warning);
501
+ color: #111;
502
+ border-radius: 9px;
503
+ font-size: 10px;
504
+ font-weight: 700;
505
+ padding: 0 5px;
506
+ min-width: 16px;
507
+ height: 16px;
508
+ line-height: 1;
509
+ }
510
+
511
+ /* ── Export dropdown ─────────────────────────────────────────────────────── */
512
+ .export-wrap {
513
+ position: relative;
514
+ display: inline-flex;
515
+ }
516
+
517
+ .export-menu {
518
+ display: none;
519
+ flex-direction: column;
520
+ position: absolute;
521
+ top: calc(100% + 4px);
522
+ right: 0;
523
+ background: var(--bg-secondary);
524
+ border: 1px solid var(--hairline-strong);
525
+ border-radius: 4px;
526
+ box-shadow: 0 6px 18px rgba(0,0,0,0.35);
527
+ z-index: 500;
528
+ min-width: 110px;
529
+ overflow: hidden;
530
+ }
531
+
532
+ .export-menu.open {
533
+ display: flex;
534
+ }
535
+
536
+ .export-menu-item {
537
+ display: flex;
538
+ align-items: center;
539
+ gap: 6px;
540
+ padding: 5px 10px;
541
+ font-size: 11px;
542
+ font-family: inherit;
543
+ color: var(--text-primary);
544
+ background: none;
545
+ border: none;
546
+ cursor: pointer;
547
+ text-align: left;
548
+ white-space: nowrap;
549
+ transition: background 0.1s;
550
+ }
551
+
552
+ .export-menu-item:hover {
553
+ background: var(--bg-tertiary);
554
+ }
555
+
556
+ .export-menu-item.item-csv { color: var(--text-primary); }
557
+ .export-menu-item.item-xlsx { color: var(--success); }
558
+ .export-menu-item.item-pdf { color: var(--danger); }
559
+
560
+ /* ── Tooltip for long text ───────────────────────────────────────────────── */
561
+ .ag-tooltip {
562
+ /* Brand surface (navy in dark, light card in light) via theme var. */
563
+ background: var(--bg-secondary) !important;
564
+ border: 1px solid var(--hairline-strong) !important;
565
+ color: var(--text-primary) !important;
566
+ font-size: 11px !important;
567
+ border-radius: 3px !important;
568
+ padding: 4px 7px !important;
569
+ max-width: 480px !important;
570
+ word-break: break-all !important;
571
+ }
572
+ </style>
573
+ </head>
574
+ <body>
575
+ <div id="app">
576
+
577
+ <!-- Toolbar -->
578
+ <div class="toolbar" id="toolbar">
579
+ <div class="toolbar-sep" id="editSep" style="display:none"></div>
580
+
581
+ <button class="btn btn-success" id="btnSaveEdits" style="display:none" title="Save pending edits via API">
582
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
583
+ <polyline points="20 6 9 17 4 12"/>
584
+ </svg>
585
+ Save
586
+ <span class="pending-pill" id="pendingPill">0</span>
587
+ </button>
588
+
589
+ <button class="btn btn-danger" id="btnDiscardEdits" style="display:none" title="Discard all pending edits">
590
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
591
+ <line x1="18" y1="6" x2="6" y2="18"/>
592
+ <line x1="6" y1="6" x2="18" y2="18"/>
593
+ </svg>
594
+ Discard
595
+ </button>
596
+
597
+ <button class="btn btn-danger" id="btnDeleteRows" style="display:none; margin-left:4px" title="Delete selected rows via API">
598
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
599
+ <path d="M6 7h12" />
600
+ <path d="M9 7V5h6v2" />
601
+ <path d="M10 10v8" />
602
+ <path d="M14 10v8" />
603
+ <rect x="5" y="7" width="14" height="12" rx="2" />
604
+ </svg>
605
+ </button>
606
+
607
+ <button class="btn" id="btnAddColumn" style="display:none; margin-left:4px" title="Add a new column">
608
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
609
+ <line x1="12" y1="5" x2="12" y2="19"/>
610
+ <line x1="5" y1="12" x2="19" y2="12"/>
611
+ </svg>
612
+ Col
613
+ </button>
614
+
615
+ <div class="toolbar-sep"></div>
616
+
617
+ <input class="filter-input" id="quickFilter" placeholder="Quick filter rows…" type="text" spellcheck="false">
618
+
619
+ <div class="toolbar-spacer"></div>
620
+
621
+ <div class="toolbar-sep"></div>
622
+
623
+ <button class="btn" id="btnAutoSize" title="Auto-size all columns to fit content">
624
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
625
+ <line x1="5" y1="12" x2="19" y2="12"/>
626
+ <polyline points="12 5 19 12 12 19"/>
627
+ </svg>
628
+ Fit Cols
629
+ </button>
630
+
631
+ <button class="btn" id="btnFitGrid" title="Size columns to fit grid width">
632
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
633
+ <line x1="8" y1="3" x2="8" y2="21"/>
634
+ <line x1="16" y1="3" x2="16" y2="21"/>
635
+ <line x1="3" y1="8" x2="21" y2="8"/>
636
+ <line x1="3" y1="16" x2="21" y2="16"/>
637
+ </svg>
638
+ Fit Grid
639
+ </button>
640
+
641
+ <div class="export-wrap" id="exportWrap">
642
+ <button class="btn btn-blue" id="btnExport" title="Export data">
643
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
644
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
645
+ <polyline points="14 2 14 8 20 8"/>
646
+ <line x1="12" y1="12" x2="12" y2="18"/>
647
+ <polyline points="9 15 12 18 15 15"/>
648
+ </svg>
649
+ Export
650
+ <svg width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
651
+ <polyline points="6 9 12 15 18 9"/>
652
+ </svg>
653
+ </button>
654
+ <div class="export-menu" id="exportMenu">
655
+ <button class="export-menu-item item-csv" id="btnExportCsv">
656
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
657
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
658
+ <polyline points="14 2 14 8 20 8"/>
659
+ </svg>
660
+ CSV
661
+ </button>
662
+ <button class="export-menu-item item-xlsx" id="btnExportExcel">
663
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
664
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
665
+ <polyline points="14 2 14 8 20 8"/>
666
+ </svg>
667
+ Excel (.xlsx)
668
+ </button>
669
+ <button class="export-menu-item item-pdf" id="btnExportPdf">
670
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
671
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
672
+ <polyline points="14 2 14 8 20 8"/>
673
+ </svg>
674
+ PDF
675
+ </button>
676
+ </div>
677
+ </div>
678
+ </div>
679
+
680
+ <!-- Grid -->
681
+ <div class="grid-wrap">
682
+ <div id="myGrid" class="ag-theme-alpine-dark"></div>
683
+
684
+ <div class="empty-state" id="emptyState">
685
+ <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2">
686
+ <rect x="3" y="3" width="18" height="18" rx="2"/>
687
+ <line x1="3" y1="9" x2="21" y2="9"/>
688
+ <line x1="3" y1="15" x2="21" y2="15"/>
689
+ <line x1="9" y1="3" x2="9" y2="21"/>
690
+ <line x1="15" y1="3" x2="15" y2="21"/>
691
+ </svg>
692
+ <span>Waiting for data…</span>
693
+ <small>Trigger an API call or click Refresh</small>
694
+ </div>
695
+
696
+ <div class="loading-overlay" id="loadingOverlay" style="display:none">
697
+ <div class="spinner"></div>
698
+ </div>
699
+
700
+ <div class="confirm-overlay" id="confirmOverlay" role="dialog" aria-modal="true" aria-labelledby="confirmTitle" aria-describedby="confirmMessage">
701
+ <div class="confirm-dialog">
702
+ <h3 id="confirmTitle">Delete selected rows?</h3>
703
+ <p id="confirmMessage">This action cannot be undone.</p>
704
+ <div class="confirm-actions">
705
+ <button class="btn" id="confirmCancelBtn" type="button">Cancel</button>
706
+ <button class="btn btn-danger" id="confirmOkBtn" type="button">Delete</button>
707
+ </div>
708
+ </div>
709
+ </div>
710
+
711
+ <div class="confirm-overlay" id="addColOverlay" role="dialog" aria-modal="true">
712
+ <div class="confirm-dialog">
713
+ <h3>Add Column</h3>
714
+ <p style="margin-bottom:10px">Enter a name for the new column:</p>
715
+ <input type="text" id="addColInput" class="filter-input" style="width:100%;margin-bottom:16px" placeholder="column_name" spellcheck="false">
716
+ <div class="confirm-actions">
717
+ <button class="btn" id="addColCancelBtn" type="button">Cancel</button>
718
+ <button class="btn btn-success" id="addColOkBtn" type="button">Add</button>
719
+ </div>
720
+ </div>
721
+ </div>
722
+ </div>
723
+
724
+ <!-- Status bar -->
725
+ <div class="status-bar">
726
+ <span class="status-dot" id="statusDot"></span>
727
+ <span id="statusText">Ready</span>
728
+ <span class="status-sep" id="statusSep" style="display:none">·</span>
729
+ <span id="rowCount" style="display:none"></span>
730
+ <span class="status-sep" id="statusSep2" style="display:none">·</span>
731
+ <span id="selCount" style="display:none"></span>
732
+ </div>
733
+
734
+ </div>
735
+
736
+ <script src="index.js"></script>
737
+ </body>
738
+ </html>