ngx-dev-toolbar 1.0.2 → 1.0.4

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 (130) hide show
  1. package/components/button/button.component.d.ts +12 -0
  2. package/components/card/card.component.d.ts +8 -0
  3. package/components/clickable-card/clickable-card.component.d.ts +11 -0
  4. package/components/icons/angular-icon.component.d.ts +5 -0
  5. package/components/icons/bug-icon.component.d.ts +6 -0
  6. package/components/icons/code-icon.component.d.ts +6 -0
  7. package/components/icons/database-icon.component.d.ts +6 -0
  8. package/components/icons/discord-icon.component.d.ts +6 -0
  9. package/components/icons/docs-icon.component.d.ts +6 -0
  10. package/components/icons/export-icon.component.d.ts +6 -0
  11. package/components/icons/gauge-icon.component.d.ts +6 -0
  12. package/components/icons/gear-icon.component.d.ts +6 -0
  13. package/components/icons/git-branch-icon.component.d.ts +6 -0
  14. package/components/icons/icon.component.d.ts +9 -0
  15. package/components/icons/icon.models.d.ts +1 -0
  16. package/components/icons/import-icon.component.d.ts +6 -0
  17. package/components/icons/layout-icon.component.d.ts +6 -0
  18. package/components/icons/lightbulb-icon.component.d.ts +6 -0
  19. package/components/icons/lighting-icon.component.d.ts +6 -0
  20. package/components/icons/moon-icon.component.d.ts +6 -0
  21. package/components/icons/network-icon.component.d.ts +6 -0
  22. package/components/icons/puzzle-icon.component.d.ts +6 -0
  23. package/components/icons/refresh-icon.component.d.ts +6 -0
  24. package/components/icons/star-icon.component.d.ts +6 -0
  25. package/components/icons/sun-icon.component.d.ts +6 -0
  26. package/components/icons/terminal-icon.component.d.ts +6 -0
  27. package/components/icons/toggle-left-icon.component.d.ts +6 -0
  28. package/components/icons/translate-icon.component.d.ts +6 -0
  29. package/components/icons/trash-icon.component.d.ts +6 -0
  30. package/components/icons/users-icon.component.d.ts +6 -0
  31. package/components/input/input.component.d.ts +10 -0
  32. package/components/link-button/link-button.component.d.ts +8 -0
  33. package/components/select/select.component.d.ts +25 -0
  34. package/components/tool-button/tool-button.component.d.ts +23 -0
  35. package/components/toolbar-tool/toolbar-tool.component.d.ts +30 -0
  36. package/components/toolbar-tool/toolbar-tool.models.d.ts +25 -0
  37. package/components/window/window.component.d.ts +16 -0
  38. package/dev-toolbar-state.service.d.ts +21 -0
  39. package/dev-toolbar.component.d.ts +18 -0
  40. package/fesm2022/ngx-dev-toolbar.mjs +3039 -0
  41. package/fesm2022/ngx-dev-toolbar.mjs.map +1 -0
  42. package/models/dev-tools.interface.d.ts +17 -0
  43. package/package.json +32 -9
  44. package/tools/feature-flags-tool/feature-flags-internal.service.d.ts +21 -0
  45. package/tools/feature-flags-tool/feature-flags-tool.component.d.ts +27 -0
  46. package/tools/feature-flags-tool/feature-flags.models.d.ts +9 -0
  47. package/tools/feature-flags-tool/feature-flags.service.d.ts +19 -0
  48. package/tools/home-tool/home-tool.component.d.ts +38 -0
  49. package/{src/tools/home-tool/settings.models.ts → tools/home-tool/settings.models.d.ts} +1 -1
  50. package/tools/home-tool/settings.service.d.ts +10 -0
  51. package/tools/language-tool/language-internal.service.d.ts +19 -0
  52. package/tools/language-tool/language-tool.component.d.ts +14 -0
  53. package/tools/language-tool/language.models.d.ts +4 -0
  54. package/tools/language-tool/language.service.d.ts +19 -0
  55. package/utils/storage.service.d.ts +18 -0
  56. package/eslint.config.cjs +0 -47
  57. package/ng-package.json +0 -7
  58. package/project.json +0 -37
  59. package/src/components/button/button.component.scss +0 -49
  60. package/src/components/button/button.component.ts +0 -36
  61. package/src/components/card/card.component.scss +0 -18
  62. package/src/components/card/card.component.ts +0 -30
  63. package/src/components/clickable-card/clickable-card.component.scss +0 -39
  64. package/src/components/clickable-card/clickable-card.component.ts +0 -34
  65. package/src/components/icons/angular-icon.component.ts +0 -35
  66. package/src/components/icons/bug-icon.component.ts +0 -23
  67. package/src/components/icons/code-icon.component.ts +0 -24
  68. package/src/components/icons/database-icon.component.ts +0 -27
  69. package/src/components/icons/discord-icon.component.ts +0 -23
  70. package/src/components/icons/docs-icon.component.ts +0 -23
  71. package/src/components/icons/export-icon.component.ts +0 -23
  72. package/src/components/icons/gauge-icon.component.ts +0 -27
  73. package/src/components/icons/gear-icon.component.ts +0 -27
  74. package/src/components/icons/git-branch-icon.component.ts +0 -27
  75. package/src/components/icons/icon.component.ts +0 -129
  76. package/src/components/icons/icon.models.ts +0 -27
  77. package/src/components/icons/import-icon.component.ts +0 -23
  78. package/src/components/icons/layout-icon.component.ts +0 -24
  79. package/src/components/icons/lightbulb-icon.component.ts +0 -23
  80. package/src/components/icons/lighting-icon.component.ts +0 -24
  81. package/src/components/icons/moon-icon.component.ts +0 -27
  82. package/src/components/icons/network-icon.component.ts +0 -27
  83. package/src/components/icons/puzzle-icon.component.ts +0 -27
  84. package/src/components/icons/refresh-icon.component.ts +0 -27
  85. package/src/components/icons/star-icon.component.ts +0 -27
  86. package/src/components/icons/sun-icon.component.ts +0 -27
  87. package/src/components/icons/terminal-icon.component.ts +0 -27
  88. package/src/components/icons/toggle-left-icon.component.ts +0 -27
  89. package/src/components/icons/translate-icon.component.ts +0 -23
  90. package/src/components/icons/trash-icon.component.ts +0 -23
  91. package/src/components/icons/users-icon.component.ts +0 -27
  92. package/src/components/input/input.component.ts +0 -67
  93. package/src/components/link-button/link-button.component.scss +0 -36
  94. package/src/components/link-button/link-button.component.ts +0 -29
  95. package/src/components/select/select.component.scss +0 -162
  96. package/src/components/select/select.component.ts +0 -127
  97. package/src/components/tool-button/tool-button.component.scss +0 -67
  98. package/src/components/tool-button/tool-button.component.ts +0 -126
  99. package/src/components/toolbar-tool/toolbar-tool.component.scss +0 -9
  100. package/src/components/toolbar-tool/toolbar-tool.component.ts +0 -169
  101. package/src/components/toolbar-tool/toolbar-tool.models.ts +0 -33
  102. package/src/components/window/window.component.scss +0 -95
  103. package/src/components/window/window.component.ts +0 -69
  104. package/src/dev-toolbar-state.service.ts +0 -89
  105. package/src/dev-toolbar.component.scss +0 -22
  106. package/src/dev-toolbar.component.ts +0 -105
  107. package/src/models/dev-tools.interface.ts +0 -19
  108. package/src/styles.scss +0 -342
  109. package/src/test-setup.ts +0 -12
  110. package/src/tools/feature-flags-tool/feature-flags-internal.service.ts +0 -96
  111. package/src/tools/feature-flags-tool/feature-flags-tool.component.ts +0 -261
  112. package/src/tools/feature-flags-tool/feature-flags.models.ts +0 -10
  113. package/src/tools/feature-flags-tool/feature-flags.service.ts +0 -28
  114. package/src/tools/home-tool/home-tool.component.scss +0 -67
  115. package/src/tools/home-tool/home-tool.component.ts +0 -197
  116. package/src/tools/home-tool/settings.service.spec.ts +0 -59
  117. package/src/tools/home-tool/settings.service.ts +0 -21
  118. package/src/tools/language-tool/language-internal.service.ts +0 -51
  119. package/src/tools/language-tool/language-tool.component.scss +0 -7
  120. package/src/tools/language-tool/language-tool.component.ts +0 -71
  121. package/src/tools/language-tool/language.models.ts +0 -4
  122. package/src/tools/language-tool/language.service.ts +0 -26
  123. package/src/utils/storage.service.spec.ts +0 -179
  124. package/src/utils/storage.service.ts +0 -80
  125. package/tsconfig.json +0 -28
  126. package/tsconfig.lib.json +0 -28
  127. package/tsconfig.lib.prod.json +0 -9
  128. package/tsconfig.spec.json +0 -29
  129. package/vite.config.mts +0 -27
  130. /package/{src/index.ts → index.d.ts} +0 -0
package/src/styles.scss DELETED
@@ -1,342 +0,0 @@
1
- @use 'sass:map';
2
- // Color primitives
3
- $color-black-900: rgb(17, 24, 39); // darkest
4
- $color-black-800: rgb(19, 21, 26);
5
- $color-gray-700: rgb(55, 65, 81);
6
- $color-gray-600: rgb(107, 114, 128);
7
- $color-gray-500: rgb(156, 163, 175);
8
- $color-gray-300: rgb(229, 231, 235);
9
- $color-gray-200: rgb(243, 244, 246);
10
- $color-white: rgb(255, 255, 255);
11
- $color-red-600: rgb(220, 38, 38); // dark red
12
- $color-red-500: rgb(239, 68, 68); // light red
13
- $color-blue-100: rgb(219, 234, 254);
14
- $color-blue-600: rgb(37, 99, 235);
15
- $color-yellow-100: rgb(254, 249, 195);
16
- $color-yellow-600: rgb(202, 138, 4);
17
- $color-red-100: rgb(254, 226, 226);
18
- // Colors and Themes
19
- $colors: (
20
- dark: (
21
- background: (
22
- primary: $color-black-900,
23
- gradient:
24
- linear-gradient(
25
- 180deg,
26
- $color-black-800 0%,
27
- rgba($color-black-800, 0.88) 100%
28
- ),
29
- ),
30
- text: (
31
- primary: $color-white,
32
- secondary: $color-gray-300,
33
- muted: $color-gray-500,
34
- ),
35
- border: (
36
- primary: #343841,
37
- subtle: rgba($color-white, 0.1),
38
- ),
39
- hover: (
40
- background: rgba($color-white, 0.12),
41
- danger: $color-red-600,
42
- ),
43
- annotation: (
44
- note: (
45
- background: rgba($color-blue-600, 0.15),
46
- border: rgba($color-blue-600, 0.3),
47
- ),
48
- warning: (
49
- background: rgba($color-yellow-600, 0.15),
50
- border: rgba($color-yellow-600, 0.3),
51
- ),
52
- error: (
53
- background: rgba($color-red-600, 0.15),
54
- border: rgba($color-red-600, 0.3),
55
- ),
56
- ),
57
- ),
58
- light: (
59
- background: (
60
- primary: $color-white,
61
- gradient:
62
- linear-gradient(
63
- 180deg,
64
- $color-gray-200 0%,
65
- rgba($color-gray-200, 0.88) 100%
66
- ),
67
- ),
68
- text: (
69
- primary: $color-black-900,
70
- secondary: $color-gray-700,
71
- muted: $color-gray-600,
72
- ),
73
- border: (
74
- primary: #e5e7eb,
75
- subtle: rgba($color-black-900, 0.1),
76
- ),
77
- hover: (
78
- background: rgba($color-black-900, 0.05),
79
- danger: $color-red-500,
80
- ),
81
- annotation: (
82
- note: (
83
- background: $color-blue-100,
84
- border: rgba($color-blue-600, 0.2),
85
- ),
86
- warning: (
87
- background: $color-yellow-100,
88
- border: rgba($color-yellow-600, 0.2),
89
- ),
90
- error: (
91
- background: $color-red-100,
92
- border: rgba($color-red-600, 0.2),
93
- ),
94
- ),
95
- ),
96
- );
97
-
98
- // Shadows
99
- $shadow-themes: (
100
- dark: (
101
- toolbar: 0 2px 8px rgba(19, 21, 26, 0.3),
102
- tooltip: (
103
- 0 0 0 1px rgba(255, 255, 255, 0.1),
104
- 0 4px 8px rgba(0, 0, 0, 0.4),
105
- 0 2px 4px rgba(0, 0, 0, 0.3),
106
- ),
107
- window: (
108
- 0px 0px 0px 0px rgba(19, 21, 26, 0.3),
109
- 0px 1px 2px 0px rgba(19, 21, 26, 0.29),
110
- 0px 4px 4px 0px rgba(19, 21, 26, 0.26),
111
- 0px 10px 6px 0px rgba(19, 21, 26, 0.15),
112
- 0px 17px 7px 0px rgba(19, 21, 26, 0.04),
113
- 0px 26px 7px 0px rgba(19, 21, 26, 0.01),
114
- ),
115
- ),
116
- light: (
117
- toolbar: 0 2px 8px rgba(156, 163, 175, 0.2),
118
- tooltip: (
119
- 0 0 0 1px rgba(17, 24, 39, 0.05),
120
- 0 4px 8px rgba(107, 114, 128, 0.15),
121
- 0 2px 4px rgba(107, 114, 128, 0.1),
122
- ),
123
- window: (
124
- 0px 0px 0px 0px rgba(156, 163, 175, 0.1),
125
- 0px 1px 2px 0px rgba(156, 163, 175, 0.12),
126
- 0px 4px 4px 0px rgba(156, 163, 175, 0.1),
127
- 0px 10px 6px 0px rgba(156, 163, 175, 0.08),
128
- 0px 17px 7px 0px rgba(156, 163, 175, 0.05),
129
- 0px 26px 7px 0px rgba(156, 163, 175, 0.02),
130
- ),
131
- ),
132
- );
133
-
134
- // Typography
135
- $font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
136
- 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif,
137
- 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
138
-
139
- // Add font size variables
140
- $font-sizes: (
141
- xs: 0.75rem,
142
- sm: 0.875rem,
143
- md: 1rem,
144
- lg: 1.25rem,
145
- xl: 2rem,
146
- );
147
-
148
- // Dimensions
149
- $dimensions: (
150
- toolbar-height: 40px,
151
- toolbar-button-width: 44px,
152
- window-max-width: 640px,
153
- window-max-height: 480px,
154
- border-radius: (
155
- small: 4px,
156
- medium: 8px,
157
- large: 12px,
158
- full: 9999px,
159
- ),
160
- );
161
-
162
- // Transitions
163
- $transitions: (
164
- default: all 0.2s ease-out,
165
- smooth: all 0.2s ease-in-out,
166
- );
167
-
168
- // Z-indices
169
- $z-indices: (
170
- toolbar: 999999,
171
- window: 999999999,
172
- );
173
-
174
- // Create a mixin for the CSS variables that can be used by components
175
- @mixin devtools-theme {
176
- --ndt-border-radius-small: #{map.get(
177
- map.get($dimensions, border-radius),
178
- small
179
- )};
180
- --ndt-border-radius-medium: #{map.get(
181
- map.get($dimensions, border-radius),
182
- medium
183
- )};
184
- --ndt-border-radius-large: #{map.get(
185
- map.get($dimensions, border-radius),
186
- large
187
- )};
188
-
189
- --ndt-transition-default: #{map.get($transitions, default)};
190
- --ndt-transition-smooth: #{map.get($transitions, smooth)};
191
-
192
- --ndt-bg-primary: #{map.get(map.get($colors, light), background, primary)};
193
- --ndt-bg-gradient: #{map.get(map.get($colors, light), background, gradient)};
194
- --ndt-text-primary: #{map.get(map.get($colors, light), text, primary)};
195
- --ndt-text-secondary: #{map.get(map.get($colors, light), text, secondary)};
196
- --ndt-text-muted: #{map.get(map.get($colors, light), text, muted)};
197
- --ndt-border-primary: #{map.get(map.get($colors, light), border, primary)};
198
- --ndt-border-subtle: #{map.get(map.get($colors, light), border, subtle)};
199
- --ndt-hover-bg: #{map.get(map.get($colors, light), hover, background)};
200
- --ndt-hover-danger: #{map.get(map.get($colors, light), hover, danger)};
201
- --ndt-shadow-toolbar: #{map.get(map.get($shadow-themes, light), toolbar)};
202
- --ndt-shadow-tooltip: #{map.get(map.get($shadow-themes, light), tooltip)};
203
- --ndt-shadow-window: #{map.get(map.get($shadow-themes, light), window)};
204
-
205
- --ndt-spacing-xs: 4px;
206
- --ndt-spacing-sm: 8px;
207
- --ndt-spacing-md: 16px;
208
- --ndt-window-padding: 24px;
209
-
210
- --ndt-font-size-xs: #{map.get($font-sizes, xs)};
211
- --ndt-font-size-sm: #{map.get($font-sizes, sm)};
212
- --ndt-font-size-md: #{map.get($font-sizes, md)};
213
- --ndt-font-size-lg: #{map.get($font-sizes, lg)};
214
- --ndt-font-size-xl: #{map.get($font-sizes, xl)};
215
-
216
- --ndt-background-secondary: var(--ndt-bg-primary);
217
- --ndt-background-hover: var(--ndt-hover-bg);
218
-
219
- --ndt-primary: #df30d4;
220
- --ndt-primary-rgb: 223, 48, 212;
221
- --ndt-text-on-primary: #{$color-white};
222
-
223
- --ndt-border-color: var(--ndt-border-primary);
224
-
225
- --ndt-note-background: #{map.get(
226
- map.get(map.get($colors, light), annotation),
227
- note,
228
- background
229
- )};
230
- --ndt-note-border: #{map.get(
231
- map.get(map.get($colors, light), annotation),
232
- note,
233
- border
234
- )};
235
- --ndt-warning-background: #{map.get(
236
- map.get(map.get($colors, light), annotation),
237
- warning,
238
- background
239
- )};
240
- --ndt-warning-border: #{map.get(
241
- map.get(map.get($colors, light), annotation),
242
- warning,
243
- border
244
- )};
245
- --ndt-error-background: #{map.get(
246
- map.get(map.get($colors, light), annotation),
247
- error,
248
- background
249
- )};
250
- --ndt-error-border: #{map.get(
251
- map.get(map.get($colors, light), annotation),
252
- error,
253
- border
254
- )};
255
-
256
- &[data-theme='dark'] {
257
- --ndt-bg-primary: #{map.get(map.get($colors, dark), background, primary)};
258
- --ndt-bg-gradient: #{map.get(map.get($colors, dark), background, gradient)};
259
- --ndt-text-primary: #{map.get(map.get($colors, dark), text, primary)};
260
- --ndt-text-secondary: #{map.get(map.get($colors, dark), text, secondary)};
261
- --ndt-text-muted: #{map.get(map.get($colors, dark), text, muted)};
262
- --ndt-border-primary: #{map.get(map.get($colors, dark), border, primary)};
263
- --ndt-border-subtle: #{map.get(map.get($colors, dark), border, subtle)};
264
- --ndt-hover-bg: #{map.get(map.get($colors, dark), hover, background)};
265
- --ndt-hover-danger: #{map.get(map.get($colors, dark), hover, danger)};
266
- --ndt-shadow-toolbar: #{map.get(map.get($shadow-themes, dark), toolbar)};
267
- --ndt-shadow-tooltip: #{map.get(map.get($shadow-themes, dark), tooltip)};
268
- --ndt-shadow-window: #{map.get(map.get($shadow-themes, dark), window)};
269
-
270
- --ndt-note-background: #{map.get(
271
- map.get(map.get($colors, dark), annotation),
272
- note,
273
- background
274
- )};
275
- --ndt-note-border: #{map.get(
276
- map.get(map.get($colors, dark), annotation),
277
- note,
278
- border
279
- )};
280
- --ndt-warning-background: #{map.get(
281
- map.get(map.get($colors, dark), annotation),
282
- warning,
283
- background
284
- )};
285
- --ndt-warning-border: #{map.get(
286
- map.get(map.get($colors, dark), annotation),
287
- warning,
288
- border
289
- )};
290
- --ndt-error-background: #{map.get(
291
- map.get(map.get($colors, dark), annotation),
292
- error,
293
- background
294
- )};
295
- --ndt-error-border: #{map.get(
296
- map.get(map.get($colors, dark), annotation),
297
- error,
298
- border
299
- )};
300
- }
301
- }
302
-
303
- .dev-toolbar {
304
- @include devtools-theme;
305
-
306
- // Typography styles
307
- h1,
308
- h2,
309
- h3,
310
- h4,
311
- h5 {
312
- font-weight: 600;
313
- color: var(--ndt-text-primary);
314
- margin: 0;
315
- }
316
-
317
- h1 {
318
- font-size: var(--ndt-font-size-xl);
319
- }
320
- h2 {
321
- font-size: var(--ndt-font-size-lg);
322
- }
323
- h3 {
324
- font-size: var(--ndt-font-size-md);
325
- }
326
- h4 {
327
- font-size: var(--ndt-font-size-sm);
328
- }
329
- h5 {
330
- font-size: var(--ndt-font-size-xs);
331
- }
332
-
333
- hr {
334
- border: 1px solid var(--ndt-border-subtle);
335
- margin: 1em 0;
336
- }
337
-
338
- p {
339
- line-height: 1.5em;
340
- margin: 0;
341
- }
342
- }
package/src/test-setup.ts DELETED
@@ -1,12 +0,0 @@
1
- import '@analogjs/vitest-angular/setup-zone';
2
-
3
- import {
4
- BrowserDynamicTestingModule,
5
- platformBrowserDynamicTesting,
6
- } from '@angular/platform-browser-dynamic/testing';
7
- import { getTestBed } from '@angular/core/testing';
8
-
9
- getTestBed().initTestEnvironment(
10
- BrowserDynamicTestingModule,
11
- platformBrowserDynamicTesting()
12
- );
@@ -1,96 +0,0 @@
1
- import { Injectable, inject } from '@angular/core';
2
- import { toSignal } from '@angular/core/rxjs-interop';
3
- import { BehaviorSubject, Observable, combineLatest, map } from 'rxjs';
4
- import { DevToolsStorageService } from '../../utils/storage.service';
5
- import { DevToolbarFlag } from './feature-flags.models';
6
-
7
- interface ForcedFlagsState {
8
- enabled: string[];
9
- disabled: string[];
10
- }
11
-
12
- @Injectable({ providedIn: 'root' })
13
- export class DevToolbarInternalFeatureFlagService {
14
- private readonly STORAGE_KEY = 'feature-flags';
15
- private storageService = inject(DevToolsStorageService);
16
-
17
- private appFlags$ = new BehaviorSubject<DevToolbarFlag[]>([]);
18
- private forcedFlagsSubject = new BehaviorSubject<ForcedFlagsState>({
19
- enabled: [],
20
- disabled: [],
21
- });
22
-
23
- private readonly forcedFlags$ = this.forcedFlagsSubject.asObservable();
24
-
25
- public flags$: Observable<DevToolbarFlag[]> = combineLatest([
26
- this.appFlags$,
27
- this.forcedFlags$,
28
- ]).pipe(
29
- map(([appFlags, { enabled, disabled }]) => {
30
- return appFlags.map((flag) => ({
31
- ...flag,
32
- isForced: enabled.includes(flag.id) || disabled.includes(flag.id),
33
- isEnabled: enabled.includes(flag.id),
34
- }));
35
- })
36
- );
37
-
38
- public flags = toSignal(this.flags$, { initialValue: [] });
39
-
40
- constructor() {
41
- this.loadForcedFlags();
42
- }
43
-
44
- setAppFlags(flags: DevToolbarFlag[]): void {
45
- this.appFlags$.next(flags);
46
- }
47
-
48
- getAppFlags(): Observable<DevToolbarFlag[]> {
49
- return this.appFlags$.asObservable();
50
- }
51
-
52
- getForcedFlags(): Observable<DevToolbarFlag[]> {
53
- return this.flags$.pipe(
54
- map((flags) => flags.filter((flag) => flag.isForced))
55
- );
56
- }
57
-
58
- setFlag(flagId: string, isEnabled: boolean): void {
59
- const { enabled, disabled } = this.forcedFlagsSubject.value;
60
-
61
- const newEnabled = enabled.filter((id) => id !== flagId);
62
- const newDisabled = disabled.filter((id) => id !== flagId);
63
-
64
- if (isEnabled) {
65
- newEnabled.push(flagId);
66
- } else {
67
- newDisabled.push(flagId);
68
- }
69
-
70
- const newState = { enabled: newEnabled, disabled: newDisabled };
71
- this.forcedFlagsSubject.next(newState);
72
- this.storageService.set(this.STORAGE_KEY, newState);
73
- }
74
-
75
- removeFlagOverride(flagId: string): void {
76
- const { enabled, disabled } = this.forcedFlagsSubject.value;
77
-
78
- const newState = {
79
- enabled: enabled.filter((id) => id !== flagId),
80
- disabled: disabled.filter((id) => id !== flagId),
81
- };
82
-
83
- this.forcedFlagsSubject.next(newState);
84
- this.storageService.set(this.STORAGE_KEY, newState);
85
- }
86
-
87
- private loadForcedFlags(): void {
88
- const savedFlags = this.storageService.get<ForcedFlagsState>(
89
- this.STORAGE_KEY
90
- );
91
-
92
- if (savedFlags) {
93
- this.forcedFlagsSubject.next(savedFlags);
94
- }
95
- }
96
- }
@@ -1,261 +0,0 @@
1
- import {
2
- ChangeDetectionStrategy,
3
- Component,
4
- computed,
5
- inject,
6
- signal,
7
- } from '@angular/core';
8
- import { FormsModule } from '@angular/forms';
9
- import { DevToolbarInputComponent } from '../../components/input/input.component';
10
- import { DevToolbarSelectComponent } from '../../components/select/select.component';
11
- import { DevToolbarToolComponent } from '../../components/toolbar-tool/toolbar-tool.component';
12
- import { DevToolbarWindowOptions } from '../../components/toolbar-tool/toolbar-tool.models';
13
- import { DevToolbarInternalFeatureFlagService } from './feature-flags-internal.service';
14
- import { DevToolbarFlag, FeatureFlagFilter } from './feature-flags.models';
15
- @Component({
16
- selector: 'ndt-feature-flags-tool',
17
- standalone: true,
18
- imports: [
19
- FormsModule,
20
- DevToolbarToolComponent,
21
- DevToolbarInputComponent,
22
- DevToolbarSelectComponent,
23
- ],
24
- template: `
25
- <ndt-toolbar-tool
26
- [options]="options"
27
- title="Feature Flags"
28
- icon="toggle-left"
29
- >
30
- <div class="container">
31
- <div class="header">
32
- <ndt-input
33
- [value]="searchQuery()"
34
- (valueChange)="onSearchChange($event)"
35
- placeholder="Search..."
36
- />
37
- <ndt-select
38
- [value]="activeFilter()"
39
- [options]="filterOptions"
40
- [size]="'medium'"
41
- (valueChange)="onFilterChange($event)"
42
- />
43
- </div>
44
-
45
- @if (hasNoFlags()) {
46
- <div class="empty">
47
- <p>No flags found</p>
48
- </div>
49
- } @else if (hasNoFilteredFlags()) {
50
- <div class="empty">
51
- <p>No flags found matching your filter</p>
52
- </div>
53
- } @else {
54
- <div class="flag-list">
55
- @for (flag of filteredFlags(); track flag.id) {
56
- <div class="flag">
57
- <div class="info">
58
- <h3>{{ flag.name }}</h3>
59
- <p>{{ flag?.description }}</p>
60
- </div>
61
-
62
- <ndt-select
63
- [value]="getFlagValue(flag)"
64
- [options]="flagValueOptions"
65
- [ariaLabel]="'Set value for ' + flag.name"
66
- (valueChange)="onFlagChange(flag.id, $event ?? '')"
67
- size="small"
68
- />
69
- </div>
70
- }
71
- </div>
72
- }
73
- </div>
74
- </ndt-toolbar-tool>
75
- `,
76
- styles: [
77
- `
78
- .container {
79
- display: flex;
80
- flex-direction: column;
81
- height: 100%;
82
- }
83
-
84
- .header {
85
- flex-shrink: 0;
86
- display: flex;
87
- gap: var(--ndt-spacing-sm);
88
- margin-bottom: var(--ndt-spacing-md);
89
-
90
- ndt-input {
91
- flex: 0.65;
92
- }
93
-
94
- ndt-select {
95
- flex: 0.35;
96
- }
97
- }
98
-
99
- .empty {
100
- display: flex;
101
- flex-direction: column;
102
- gap: var(--ndt-spacing-md);
103
- flex: 1;
104
- min-height: 0;
105
- justify-content: center;
106
- align-items: center;
107
- border: 1px solid var(--ndt-warning-border);
108
- border-radius: var(--ndt-border-radius-medium);
109
- padding: var(--ndt-spacing-md);
110
- background: var(--ndt-warning-background);
111
- color: var(--ndt-text-muted);
112
- }
113
-
114
- .flag-list {
115
- display: flex;
116
- flex-direction: column;
117
- gap: var(--ndt-spacing-md);
118
- flex: 1;
119
- min-height: 0;
120
- overflow-y: auto;
121
- padding-right: var(--ndt-spacing-sm);
122
-
123
- &::-webkit-scrollbar {
124
- width: 8px;
125
- }
126
-
127
- &::-webkit-scrollbar-track {
128
- background: var(--ndt-background-secondary);
129
- border-radius: 4px;
130
- }
131
-
132
- &::-webkit-scrollbar-thumb {
133
- background: var(--ndt-border-primary);
134
- border-radius: 4px;
135
-
136
- &:hover {
137
- background: var(--ndt-hover-bg);
138
- }
139
- }
140
-
141
- scrollbar-width: thin;
142
- scrollbar-color: var(--ndt-border-primary)
143
- var(--ndt-background-secondary);
144
- }
145
-
146
- .flag {
147
- display: flex;
148
- flex-direction: row;
149
- gap: var(--ndt-spacing-sm);
150
- background: var(--ndt-background-secondary);
151
- .info {
152
- flex: 0 0 65%;
153
- h3 {
154
- margin: 0;
155
- font-size: var(--ndt-font-size-md);
156
- color: var(--ndt-text-primary);
157
- }
158
-
159
- p {
160
- font-size: var(--ndt-font-size-xs);
161
- color: var(--ndt-text-muted);
162
- }
163
- }
164
-
165
- ndt-select {
166
- flex: 0 0 35%;
167
- }
168
- }
169
- `,
170
- ],
171
- changeDetection: ChangeDetectionStrategy.OnPush,
172
- })
173
- export class DevToolbarFeatureFlagsToolComponent {
174
- // Injects
175
- private readonly featureFlags = inject(DevToolbarInternalFeatureFlagService);
176
-
177
- // Signals
178
- protected readonly activeFilter = signal<FeatureFlagFilter>('all');
179
- protected readonly searchQuery = signal<string>('');
180
-
181
- protected readonly flags = this.featureFlags.flags;
182
- protected readonly hasNoFlags = computed(() => this.flags().length === 0);
183
- protected readonly filteredFlags = computed(() => {
184
- return this.flags().filter((flag) => {
185
- const searchTerm = this.searchQuery().toLowerCase();
186
- const flagName = flag.name.toLowerCase();
187
- const flagDescription = flag.description?.toLowerCase() ?? '';
188
-
189
- const matchesSearch =
190
- !this.searchQuery() ||
191
- flagName.toLowerCase().includes(searchTerm.toLowerCase()) ||
192
- flagDescription.toLowerCase().includes(searchTerm.toLowerCase());
193
-
194
- const matchesFilter =
195
- this.activeFilter() === 'all' ||
196
- (this.activeFilter() === 'forced' && flag.isForced) ||
197
- (this.activeFilter() === 'enabled' && flag.isEnabled) ||
198
- (this.activeFilter() === 'disabled' && !flag.isEnabled);
199
-
200
- return matchesSearch && matchesFilter;
201
- });
202
- });
203
- protected readonly hasNoFilteredFlags = computed(
204
- () => this.filteredFlags().length === 0
205
- );
206
-
207
- // Other properties
208
- protected readonly options = {
209
- title: 'Feature Flags',
210
- description: 'Manage the feature flags for your current session',
211
- isClosable: true,
212
- size: 'tall',
213
- id: 'ndt-feature-flags',
214
- isBeta: true,
215
- } as DevToolbarWindowOptions;
216
-
217
- protected readonly filterOptions = [
218
- { value: 'all', label: 'All Flags' },
219
- { value: 'forced', label: 'Forced' },
220
- { value: 'enabled', label: 'Enabled' },
221
- { value: 'disabled', label: 'Disabled' },
222
- ];
223
-
224
- protected readonly flagValueOptions = [
225
- { value: 'not-forced', label: 'Not Forced' },
226
- { value: 'off', label: 'Forced Off' },
227
- { value: 'on', label: 'Forced On' },
228
- ];
229
-
230
- // Public methods
231
- onFilterChange(value: string | undefined): void {
232
- const filter = this.filterOptions.find((f) => f.value === value);
233
- if (filter) {
234
- this.activeFilter.set(filter.value as FeatureFlagFilter);
235
- }
236
- }
237
-
238
- onFlagChange(flagId: string, value: string): void {
239
- switch (value) {
240
- case 'not-forced':
241
- this.featureFlags.removeFlagOverride(flagId);
242
- break;
243
- case 'on':
244
- this.featureFlags.setFlag(flagId, true);
245
- break;
246
- case 'off':
247
- this.featureFlags.setFlag(flagId, false);
248
- break;
249
- }
250
- }
251
-
252
- onSearchChange(query: string): void {
253
- this.searchQuery.set(query);
254
- }
255
-
256
- // Protected methods
257
- protected getFlagValue(flag: DevToolbarFlag): string {
258
- if (!flag.isForced) return '';
259
- return flag.isEnabled ? 'on' : 'off';
260
- }
261
- }