@silvestv/migration-planificator 3.0.0 → 4.1.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/LICENSE +201 -96
- package/NOTICE +105 -0
- package/README.fr.md +30 -24
- package/README.md +29 -25
- package/SECURITY.md +223 -187
- package/dist/client.bundle.js +51 -48
- package/dist/src/core/ast/matchers/html/html-pipe-variable-matcher.js +250 -0
- package/dist/src/core/ast/matchers/html/html-variable-resolver.js +105 -0
- package/dist/src/core/ast/matchers/index.js +7 -0
- package/dist/src/core/ast/matchers/ts/hierarchy-matcher.js +2 -1
- package/dist/src/core/ast/matchers/ts/rxjs-matcher.js +128 -0
- package/dist/src/core/workload/hierarchy-calculator.js +4 -4
- package/dist/src/core/workload/special-workload.js +2 -2
- package/dist/src/data/angular-migration-rules.json +2336 -2336
- package/dist/src/data/rules/rearchitecture/rearchitecture-rules.json +2 -2
- package/dist/src/data/rules/to18/rules-18-obligatoire.json +373 -373
- package/dist/src/data/rules/to18/rules-18-optionnelle.json +187 -187
- package/dist/src/data/rules/to18/rules-18-recommande.json +217 -217
- package/dist/src/data/rules/to19/rules-19-obligatoire.json +347 -347
- package/dist/src/data/rules/to19/rules-19-optionnelle.json +217 -222
- package/dist/src/data/rules/to19/rules-19-recommande.json +174 -199
- package/dist/src/data/rules/to20/rules-20-obligatoire.json +558 -555
- package/dist/src/data/rules/to20/rules-20-optionnelle.json +189 -189
- package/dist/src/data/rules/to20/rules-20-recommande.json +150 -150
- package/dist/src/models/interfaces/{ast-interfaces.js → angular-artifact-counts.interface.js} +0 -3
- package/dist/src/models/interfaces/base-target.interface.js +2 -0
- package/dist/src/models/interfaces/checklist-state.interface.js +2 -0
- package/dist/src/models/interfaces/dependency-counts.interface.js +2 -0
- package/dist/src/models/interfaces/migration-guide-data.interface.js +2 -0
- package/dist/src/models/interfaces/module-info.interface.js +2 -0
- package/dist/src/models/interfaces/parallelization.interface.js +2 -0
- package/dist/src/models/interfaces/refer-to-pattern.interface.js +2 -0
- package/dist/src/models/interfaces/summary-totals.interface.js +2 -0
- package/dist/src/models/interfaces/window-with-data.interface.js +2 -0
- package/dist/src/templates/workload/dashboard.template.js +7 -44
- package/dist/src/templates/workload/guide-rule-card.template.js +1 -1
- package/dist/src/templates/workload/rule-modal.template.js +6 -21
- package/dist/src/templates/workload/unified-settings-panel.template.js +149 -0
- package/dist/src/utils/core/args-parser.js +16 -1
- package/dist/styles.css +1 -1
- package/package.json +8 -7
- /package/dist/src/models/{chip-config.js → constants/chip-config.js} +0 -0
- /package/dist/src/models/interfaces/{client-interfaces.js → client-interfaces.interface.js} +0 -0
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
[
|
|
2
|
-
{
|
|
3
|
-
"key": "control_flow_deprecation",
|
|
4
|
-
"summary": "⚠️ DÉPRÉCIÉ: *ngIf/*ngFor/*ngSwitch (retrait v22)",
|
|
5
|
-
"description": "Les directives structurelles *ngIf, *ngFor et *ngSwitch sont officiellement dépréciées en Angular 20 et seront complètement retirées en v22. Migrer dès maintenant vers la syntaxe Control Flow (@if, @for, @switch) pour éviter les breaking changes futurs.",
|
|
6
|
-
"estimated_time_per_occurrence": 3,
|
|
7
|
-
"onFile": null,
|
|
8
|
-
"fileTypes": [
|
|
9
|
-
"*.html",
|
|
10
|
-
"*.ts"
|
|
11
|
-
],
|
|
12
|
-
"regex": "\\*ng(If|For|Switch)",
|
|
13
|
-
"category": "template",
|
|
14
|
-
"
|
|
15
|
-
"migration_command": "ng generate @angular/core:control-flow",
|
|
16
|
-
"risk_level": "high",
|
|
17
|
-
"code_description": "// ⚠️ DÉPRÉCIÉ - Retrait prévu en v22\n<div *ngIf=\"condition\">Content</div>\n<div *ngFor=\"let item of items\">{{ item }}</div>\n\n// Migrer vers Control Flow:\n@if (condition) {\n <div>Content</div>\n}\n@for (item of items; track item.id) {\n <div>{{ item }}</div>\n}",
|
|
18
|
-
"astPattern": {
|
|
19
|
-
"nodeType": "Attribute",
|
|
20
|
-
"name": [
|
|
21
|
-
"*ngIf",
|
|
22
|
-
"*ngFor",
|
|
23
|
-
"*ngSwitch",
|
|
24
|
-
"*ngSwitchCase",
|
|
25
|
-
"*ngSwitchDefault"
|
|
26
|
-
],
|
|
27
|
-
"excludeContext": [
|
|
28
|
-
"StringLiteral",
|
|
29
|
-
"Comment"
|
|
30
|
-
]
|
|
31
|
-
},
|
|
32
|
-
"doc_url": "https://angular.dev/reference/migrations"
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"key": "signals_stable",
|
|
36
|
-
"summary": "APIs Signals stabilisées (effect, linkedSignal, toSignal, computed)",
|
|
37
|
-
"description": "Toutes les APIs de signaux sortent de leur phase expérimentale et deviennent stables en Angular 20: effect, linkedSignal, toSignal, computed. Adopter ces APIs maintenant garantit une stabilité à long terme et des performances optimales.",
|
|
38
|
-
"estimated_time_per_occurrence": 5,
|
|
39
|
-
"onFile": null,
|
|
40
|
-
"fileTypes": [
|
|
41
|
-
"*.ts"
|
|
42
|
-
],
|
|
43
|
-
"regex": "\\b(effect|linkedSignal|toSignal|computed)\\s*\\(",
|
|
44
|
-
"category": "signals",
|
|
45
|
-
"
|
|
46
|
-
"migration_command": null,
|
|
47
|
-
"risk_level": "low",
|
|
48
|
-
"code_description": "// ✅ Maintenant stables (plus 'experimental')\n\neffect(() => {\n console.log('Value:', mySignal());\n});\n\nconst linked = linkedSignal({\n source: sourceSignal,\n computation: () => 'default'\n});\n\nconst fromObs = toSignal(observable$, {\n initialValue: 'default'\n});",
|
|
49
|
-
"astPattern": {
|
|
50
|
-
"nodeType": "CallExpression",
|
|
51
|
-
"functionName": [
|
|
52
|
-
"effect",
|
|
53
|
-
"linkedSignal",
|
|
54
|
-
"toSignal",
|
|
55
|
-
"computed"
|
|
56
|
-
],
|
|
57
|
-
"excludeContext": [
|
|
58
|
-
"StringLiteral",
|
|
59
|
-
"Comment"
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
"doc_url": "https://angular.dev/reference/migrations"
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"key": "incremental_hydration_stable",
|
|
66
|
-
"summary": "Hydratation incrémentale stable",
|
|
67
|
-
"description": "L'hydratation incrémentale passe de expérimental à stable, permettant d'hydrater progressivement les composants Angular côté client. Combiné avec @defer et les triggers d'hydratation, réduit drastiquement le TTI et le JavaScript initial sur mobile.",
|
|
68
|
-
"estimated_time_per_occurrence": 15,
|
|
69
|
-
"onFile": null,
|
|
70
|
-
"fileTypes": [
|
|
71
|
-
"*.ts",
|
|
72
|
-
"*.html"
|
|
73
|
-
],
|
|
74
|
-
"regex": "(?<![\"\\'])\\bprovideClientHydration\\s*\\(",
|
|
75
|
-
"category": "ssr",
|
|
76
|
-
"
|
|
77
|
-
"migration_command": null,
|
|
78
|
-
"risk_level": "medium",
|
|
79
|
-
"code_description": "// ✅ API stable en v20\n\nbootstrapApplication(App, {\n providers: [\n provideClientHydration(withIncrementalHydration())\n ]\n});\n\n// Template:\n@defer (hydrate on viewport) {\n <heavy-component />\n}",
|
|
80
|
-
"astPattern": {
|
|
81
|
-
"nodeType": "CallExpression",
|
|
82
|
-
"functionName": "provideClientHydration",
|
|
83
|
-
"arguments": {
|
|
84
|
-
"containsCall": {
|
|
85
|
-
"functionName": "withIncrementalHydration"
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
"excludeContext": [
|
|
89
|
-
"StringLiteral",
|
|
90
|
-
"Comment"
|
|
91
|
-
]
|
|
92
|
-
},
|
|
93
|
-
"doc_url": "https://angular.dev/reference/migrations"
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"key": "server_routes_stable",
|
|
97
|
-
"summary": "Configuration rendu par route stable",
|
|
98
|
-
"description": "L'API de configuration du rendu par route devient stable, permettant de définir précisément la stratégie (Prerender/Server/Client) pour chaque route. getPrerenderParams génère dynamiquement les paramètres pour le SSG, idéal pour les blogs et e-commerce.",
|
|
99
|
-
"estimated_time_per_occurrence": 20,
|
|
100
|
-
"onFile": null,
|
|
101
|
-
"fileTypes": [
|
|
102
|
-
"*.ts"
|
|
103
|
-
],
|
|
104
|
-
"regex": "export\\s+const\\s+serverRoutes",
|
|
105
|
-
"category": "ssr",
|
|
106
|
-
"
|
|
107
|
-
"migration_command": null,
|
|
108
|
-
"risk_level": "medium",
|
|
109
|
-
"code_description": "// app.routes.server.ts - ✅ API stable\n\nexport const serverRoutes: ServerRoute[] = [\n { path: '/', renderMode: RenderMode.Prerender },\n { path: '/api/**', renderMode: RenderMode.Server },\n { path: '/admin/**', renderMode: RenderMode.Client },\n {\n path: '/product/:id',\n renderMode: RenderMode.Prerender,\n async getPrerenderParams() {\n return ids.map(id => ({ id }));\n }\n }\n];",
|
|
110
|
-
"astPattern": {
|
|
111
|
-
"nodeType": "VariableDeclaration",
|
|
112
|
-
"name": "serverRoutes",
|
|
113
|
-
"type": "ServerRoute[]",
|
|
114
|
-
"exported": true,
|
|
115
|
-
"excludeContext": [
|
|
116
|
-
"StringLiteral",
|
|
117
|
-
"Comment"
|
|
118
|
-
]
|
|
119
|
-
},
|
|
120
|
-
"doc_url": "https://angular.dev/reference/migrations"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"key": "zoneless_preview",
|
|
124
|
-
"summary": "Zoneless en preview développeur avec error handling",
|
|
125
|
-
"description": "Le mode zoneless entre en preview développeur avec provideBrowserGlobalErrorListeners pour capturer les erreurs non gérées. Élimine Zone.js (~50KB), améliore les performances de 35% (cf YouTube), mais nécessite des tests approfondis avant production.",
|
|
126
|
-
"estimated_time_per_occurrence": 30,
|
|
127
|
-
"onFile": null,
|
|
128
|
-
"fileTypes": [
|
|
129
|
-
"*.ts",
|
|
130
|
-
"angular.json"
|
|
131
|
-
],
|
|
132
|
-
"regex": "\\bprovideZonelessChangeDetection\\b\\s*\\(",
|
|
133
|
-
"category": "architecture",
|
|
134
|
-
"
|
|
135
|
-
"migration_command": null,
|
|
136
|
-
"risk_level": "high",
|
|
137
|
-
"code_description": "// ✅ Preview développeur\n\nbootstrapApplication(App, {\n providers: [\n provideZonelessChangeDetection(),\n provideBrowserGlobalErrorListeners() // Nouveau\n ]\n});\n\n// angular.json: retirer \"zone.js\"",
|
|
138
|
-
"astPattern": {
|
|
139
|
-
"nodeType": "CallExpression",
|
|
140
|
-
"functionName": "provideZonelessChangeDetection",
|
|
141
|
-
"nextProvider": {
|
|
142
|
-
"missing": "provideBrowserGlobalErrorListeners"
|
|
143
|
-
},
|
|
144
|
-
"excludeContext": [
|
|
145
|
-
"StringLiteral",
|
|
146
|
-
"Comment"
|
|
147
|
-
]
|
|
148
|
-
},
|
|
149
|
-
"doc_url": "https://angular.dev/reference/migrations"
|
|
150
|
-
}
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"key": "control_flow_deprecation",
|
|
4
|
+
"summary": "⚠️ DÉPRÉCIÉ: *ngIf/*ngFor/*ngSwitch (retrait v22)",
|
|
5
|
+
"description": "Les directives structurelles *ngIf, *ngFor et *ngSwitch sont officiellement dépréciées en Angular 20 et seront complètement retirées en v22. Migrer dès maintenant vers la syntaxe Control Flow (@if, @for, @switch) pour éviter les breaking changes futurs.",
|
|
6
|
+
"estimated_time_per_occurrence": 3,
|
|
7
|
+
"onFile": null,
|
|
8
|
+
"fileTypes": [
|
|
9
|
+
"*.html",
|
|
10
|
+
"*.ts"
|
|
11
|
+
],
|
|
12
|
+
"regex": "\\*ng(If|For|Switch)",
|
|
13
|
+
"category": "template",
|
|
14
|
+
"isAutoFixable": false,
|
|
15
|
+
"migration_command": "ng generate @angular/core:control-flow",
|
|
16
|
+
"risk_level": "high",
|
|
17
|
+
"code_description": "// ⚠️ DÉPRÉCIÉ - Retrait prévu en v22\n<div *ngIf=\"condition\">Content</div>\n<div *ngFor=\"let item of items\">{{ item }}</div>\n\n// Migrer vers Control Flow:\n@if (condition) {\n <div>Content</div>\n}\n@for (item of items; track item.id) {\n <div>{{ item }}</div>\n}",
|
|
18
|
+
"astPattern": {
|
|
19
|
+
"nodeType": "Attribute",
|
|
20
|
+
"name": [
|
|
21
|
+
"*ngIf",
|
|
22
|
+
"*ngFor",
|
|
23
|
+
"*ngSwitch",
|
|
24
|
+
"*ngSwitchCase",
|
|
25
|
+
"*ngSwitchDefault"
|
|
26
|
+
],
|
|
27
|
+
"excludeContext": [
|
|
28
|
+
"StringLiteral",
|
|
29
|
+
"Comment"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"key": "signals_stable",
|
|
36
|
+
"summary": "APIs Signals stabilisées (effect, linkedSignal, toSignal, computed)",
|
|
37
|
+
"description": "Toutes les APIs de signaux sortent de leur phase expérimentale et deviennent stables en Angular 20: effect, linkedSignal, toSignal, computed. Adopter ces APIs maintenant garantit une stabilité à long terme et des performances optimales.",
|
|
38
|
+
"estimated_time_per_occurrence": 5,
|
|
39
|
+
"onFile": null,
|
|
40
|
+
"fileTypes": [
|
|
41
|
+
"*.ts"
|
|
42
|
+
],
|
|
43
|
+
"regex": "\\b(effect|linkedSignal|toSignal|computed)\\s*\\(",
|
|
44
|
+
"category": "signals",
|
|
45
|
+
"isAutoFixable": false,
|
|
46
|
+
"migration_command": null,
|
|
47
|
+
"risk_level": "low",
|
|
48
|
+
"code_description": "// ✅ Maintenant stables (plus 'experimental')\n\neffect(() => {\n console.log('Value:', mySignal());\n});\n\nconst linked = linkedSignal({\n source: sourceSignal,\n computation: () => 'default'\n});\n\nconst fromObs = toSignal(observable$, {\n initialValue: 'default'\n});",
|
|
49
|
+
"astPattern": {
|
|
50
|
+
"nodeType": "CallExpression",
|
|
51
|
+
"functionName": [
|
|
52
|
+
"effect",
|
|
53
|
+
"linkedSignal",
|
|
54
|
+
"toSignal",
|
|
55
|
+
"computed"
|
|
56
|
+
],
|
|
57
|
+
"excludeContext": [
|
|
58
|
+
"StringLiteral",
|
|
59
|
+
"Comment"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"key": "incremental_hydration_stable",
|
|
66
|
+
"summary": "Hydratation incrémentale stable",
|
|
67
|
+
"description": "L'hydratation incrémentale passe de expérimental à stable, permettant d'hydrater progressivement les composants Angular côté client. Combiné avec @defer et les triggers d'hydratation, réduit drastiquement le TTI et le JavaScript initial sur mobile.",
|
|
68
|
+
"estimated_time_per_occurrence": 15,
|
|
69
|
+
"onFile": null,
|
|
70
|
+
"fileTypes": [
|
|
71
|
+
"*.ts",
|
|
72
|
+
"*.html"
|
|
73
|
+
],
|
|
74
|
+
"regex": "(?<![\"\\'])\\bprovideClientHydration\\s*\\(",
|
|
75
|
+
"category": "ssr",
|
|
76
|
+
"isAutoFixable": false,
|
|
77
|
+
"migration_command": null,
|
|
78
|
+
"risk_level": "medium",
|
|
79
|
+
"code_description": "// ✅ API stable en v20\n\nbootstrapApplication(App, {\n providers: [\n provideClientHydration(withIncrementalHydration())\n ]\n});\n\n// Template:\n@defer (hydrate on viewport) {\n <heavy-component />\n}",
|
|
80
|
+
"astPattern": {
|
|
81
|
+
"nodeType": "CallExpression",
|
|
82
|
+
"functionName": "provideClientHydration",
|
|
83
|
+
"arguments": {
|
|
84
|
+
"containsCall": {
|
|
85
|
+
"functionName": "withIncrementalHydration"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
"excludeContext": [
|
|
89
|
+
"StringLiteral",
|
|
90
|
+
"Comment"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"key": "server_routes_stable",
|
|
97
|
+
"summary": "Configuration rendu par route stable",
|
|
98
|
+
"description": "L'API de configuration du rendu par route devient stable, permettant de définir précisément la stratégie (Prerender/Server/Client) pour chaque route. getPrerenderParams génère dynamiquement les paramètres pour le SSG, idéal pour les blogs et e-commerce.",
|
|
99
|
+
"estimated_time_per_occurrence": 20,
|
|
100
|
+
"onFile": null,
|
|
101
|
+
"fileTypes": [
|
|
102
|
+
"*.ts"
|
|
103
|
+
],
|
|
104
|
+
"regex": "export\\s+const\\s+serverRoutes",
|
|
105
|
+
"category": "ssr",
|
|
106
|
+
"isAutoFixable": false,
|
|
107
|
+
"migration_command": null,
|
|
108
|
+
"risk_level": "medium",
|
|
109
|
+
"code_description": "// app.routes.server.ts - ✅ API stable\n\nexport const serverRoutes: ServerRoute[] = [\n { path: '/', renderMode: RenderMode.Prerender },\n { path: '/api/**', renderMode: RenderMode.Server },\n { path: '/admin/**', renderMode: RenderMode.Client },\n {\n path: '/product/:id',\n renderMode: RenderMode.Prerender,\n async getPrerenderParams() {\n return ids.map(id => ({ id }));\n }\n }\n];",
|
|
110
|
+
"astPattern": {
|
|
111
|
+
"nodeType": "VariableDeclaration",
|
|
112
|
+
"name": "serverRoutes",
|
|
113
|
+
"type": "ServerRoute[]",
|
|
114
|
+
"exported": true,
|
|
115
|
+
"excludeContext": [
|
|
116
|
+
"StringLiteral",
|
|
117
|
+
"Comment"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"key": "zoneless_preview",
|
|
124
|
+
"summary": "Zoneless en preview développeur avec error handling",
|
|
125
|
+
"description": "Le mode zoneless entre en preview développeur avec provideBrowserGlobalErrorListeners pour capturer les erreurs non gérées. Élimine Zone.js (~50KB), améliore les performances de 35% (cf YouTube), mais nécessite des tests approfondis avant production.",
|
|
126
|
+
"estimated_time_per_occurrence": 30,
|
|
127
|
+
"onFile": null,
|
|
128
|
+
"fileTypes": [
|
|
129
|
+
"*.ts",
|
|
130
|
+
"angular.json"
|
|
131
|
+
],
|
|
132
|
+
"regex": "\\bprovideZonelessChangeDetection\\b\\s*\\(",
|
|
133
|
+
"category": "architecture",
|
|
134
|
+
"isAutoFixable": false,
|
|
135
|
+
"migration_command": null,
|
|
136
|
+
"risk_level": "high",
|
|
137
|
+
"code_description": "// ✅ Preview développeur\n\nbootstrapApplication(App, {\n providers: [\n provideZonelessChangeDetection(),\n provideBrowserGlobalErrorListeners() // Nouveau\n ]\n});\n\n// angular.json: retirer \"zone.js\"",
|
|
138
|
+
"astPattern": {
|
|
139
|
+
"nodeType": "CallExpression",
|
|
140
|
+
"functionName": "provideZonelessChangeDetection",
|
|
141
|
+
"nextProvider": {
|
|
142
|
+
"missing": "provideBrowserGlobalErrorListeners"
|
|
143
|
+
},
|
|
144
|
+
"excludeContext": [
|
|
145
|
+
"StringLiteral",
|
|
146
|
+
"Comment"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
150
|
+
}
|
|
151
151
|
]
|
|
@@ -5,59 +5,22 @@
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.renderDashboard = renderDashboard;
|
|
7
7
|
const core_1 = require("../../utils/core");
|
|
8
|
+
const unified_settings_panel_template_1 = require("./unified-settings-panel.template");
|
|
8
9
|
function renderDashboard(workload) {
|
|
9
10
|
const stats = workload.stats;
|
|
10
11
|
const time = workload.totalTime;
|
|
11
12
|
// Date de départ par défaut : aujourd'hui
|
|
12
13
|
const today = new Date().toISOString().split('T')[0]; // Format YYYY-MM-DD
|
|
13
14
|
return `
|
|
15
|
+
<!-- Unified Settings Panel (Migrations + Priorités) -->
|
|
16
|
+
${(0, unified_settings_panel_template_1.renderUnifiedSettingsPanel)()}
|
|
17
|
+
|
|
14
18
|
<div class="bg-white rounded-2xl shadow-xl p-8 mb-8">
|
|
15
|
-
<!-- Header avec titre
|
|
16
|
-
<div class="flex
|
|
17
|
-
<h2 class="text-3xl font-bold text-gray-800
|
|
19
|
+
<!-- Header avec titre -->
|
|
20
|
+
<div class="flex items-center mb-6">
|
|
21
|
+
<h2 class="text-3xl font-bold text-gray-800">
|
|
18
22
|
📊 Dashboard Global
|
|
19
|
-
<span data-migration-count class="ml-2 px-2 py-1 bg-green-100 text-green-700 text-xs font-semibold rounded-full">Toutes</span>
|
|
20
23
|
</h2>
|
|
21
|
-
|
|
22
|
-
<!-- Migration Selector -->
|
|
23
|
-
<div class="flex flex-col sm:flex-row gap-2 items-start sm:items-center">
|
|
24
|
-
<span class="text-sm font-medium text-gray-700">Migrations :</span>
|
|
25
|
-
<div class="flex gap-2 flex-wrap">
|
|
26
|
-
<label class="flex items-center gap-1 px-3 py-1.5 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors">
|
|
27
|
-
<input
|
|
28
|
-
type="checkbox"
|
|
29
|
-
data-migration-select="to18"
|
|
30
|
-
class="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
31
|
-
checked
|
|
32
|
-
/>
|
|
33
|
-
<span class="text-sm font-medium text-gray-700">To 18</span>
|
|
34
|
-
</label>
|
|
35
|
-
<label class="flex items-center gap-1 px-3 py-1.5 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors">
|
|
36
|
-
<input
|
|
37
|
-
type="checkbox"
|
|
38
|
-
data-migration-select="to19"
|
|
39
|
-
class="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
40
|
-
checked
|
|
41
|
-
/>
|
|
42
|
-
<span class="text-sm font-medium text-gray-700">To 19</span>
|
|
43
|
-
</label>
|
|
44
|
-
<label class="flex items-center gap-1 px-3 py-1.5 bg-gray-50 rounded-lg cursor-pointer hover:bg-gray-100 transition-colors">
|
|
45
|
-
<input
|
|
46
|
-
type="checkbox"
|
|
47
|
-
data-migration-select="to20"
|
|
48
|
-
class="w-4 h-4 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
49
|
-
checked
|
|
50
|
-
/>
|
|
51
|
-
<span class="text-sm font-medium text-gray-700">To 20</span>
|
|
52
|
-
</label>
|
|
53
|
-
<button
|
|
54
|
-
data-migration-select-all
|
|
55
|
-
class="px-3 py-1.5 bg-blue-100 text-blue-700 text-sm font-semibold rounded-lg hover:bg-blue-200 transition-colors"
|
|
56
|
-
>
|
|
57
|
-
Toutes
|
|
58
|
-
</button>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
24
|
</div>
|
|
62
25
|
|
|
63
26
|
<!-- KPIs -->
|
|
@@ -50,7 +50,7 @@ function renderGuideRuleCard(rule, matches) {
|
|
|
50
50
|
<div class="flex items-center flex-wrap gap-2">
|
|
51
51
|
${(0, shared_1.renderBadge)(rule.risk_level.toUpperCase(), riskColor)}
|
|
52
52
|
${(0, shared_1.renderBadge)(rule.category, 'blue')}
|
|
53
|
-
${rule.
|
|
53
|
+
${rule.isAutoFixable ? (0, shared_1.renderBadge)('Auto-fixable', 'green') : ''}
|
|
54
54
|
</div>
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
@@ -67,7 +67,7 @@ function renderModalHeader(rule, riskColor) {
|
|
|
67
67
|
<div class="flex items-center space-x-2">
|
|
68
68
|
${(0, shared_1.renderBadge)(rule.risk_level.toUpperCase(), riskColor)}
|
|
69
69
|
${(0, shared_1.renderBadge)(rule.category, 'blue')}
|
|
70
|
-
${rule.
|
|
70
|
+
${rule.isAutoFixable ? (0, shared_1.renderBadge)('Auto-fixable', 'green') : ''}
|
|
71
71
|
</div>
|
|
72
72
|
</div>
|
|
73
73
|
<button data-modal-close class="text-gray-400 hover:text-gray-600 text-3xl font-bold leading-none">
|
|
@@ -198,8 +198,6 @@ function renderAffectedFilesSection(matches) {
|
|
|
198
198
|
function renderMatchItem(match) {
|
|
199
199
|
const truncatedText = match.matchedText.substring(0, 100);
|
|
200
200
|
const displayText = match.matchedText.length > 100 ? `${truncatedText}...` : truncatedText;
|
|
201
|
-
// Formater le chemin pour VSCode (forward slashes, lowercase drive letter)
|
|
202
|
-
const vscodePath = formatVSCodePath(match.filePath);
|
|
203
201
|
return `
|
|
204
202
|
<li class="text-sm">
|
|
205
203
|
<div class="flex items-start justify-between">
|
|
@@ -208,7 +206,10 @@ function renderMatchItem(match) {
|
|
|
208
206
|
<p class="text-gray-600 mt-1 ml-4 text-xs font-mono bg-white p-2 rounded">${(0, shared_1.escapeHtml)(displayText)}</p>
|
|
209
207
|
</div>
|
|
210
208
|
<a
|
|
211
|
-
href="
|
|
209
|
+
href="#"
|
|
210
|
+
data-vscode-open
|
|
211
|
+
data-relative-path="${(0, shared_1.escapeHtml)(match.filePath)}"
|
|
212
|
+
data-line-number="${match.lineNumber}"
|
|
212
213
|
class="px-3 py-1.5 text-xs bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium shadow-sm"
|
|
213
214
|
title="Ouvrir dans VSCode à la ligne ${match.lineNumber}"
|
|
214
215
|
>
|
|
@@ -218,22 +219,6 @@ function renderMatchItem(match) {
|
|
|
218
219
|
</li>
|
|
219
220
|
`;
|
|
220
221
|
}
|
|
221
|
-
/**
|
|
222
|
-
* Formate un chemin Windows pour VSCode URI
|
|
223
|
-
* VSCode nécessite: forward slashes + lowercase drive letter
|
|
224
|
-
* Exemple: C:\Users\file.ts -> c:/Users/file.ts
|
|
225
|
-
*/
|
|
226
|
-
function formatVSCodePath(filePath) {
|
|
227
|
-
// Remplacer backslashes par forward slashes
|
|
228
|
-
let formatted = filePath.replace(/\\/g, '/');
|
|
229
|
-
// Convertir la lettre de lecteur en minuscule (C: -> c:)
|
|
230
|
-
// Format: "C:/path" ou "C:\path" -> "c:/path"
|
|
231
|
-
const driveLetterMatch = formatted.match(/^([A-Z]):/);
|
|
232
|
-
if (driveLetterMatch) {
|
|
233
|
-
formatted = driveLetterMatch[1].toLowerCase() + formatted.substring(1);
|
|
234
|
-
}
|
|
235
|
-
return formatted;
|
|
236
|
-
}
|
|
237
222
|
/**
|
|
238
223
|
* Section Métadonnées
|
|
239
224
|
* Exportée pour réutilisation dans guide-rule-card.template.ts
|
|
@@ -257,7 +242,7 @@ function renderMetadataSection(rule) {
|
|
|
257
242
|
</div>
|
|
258
243
|
<div>
|
|
259
244
|
<span class="font-semibold text-gray-700">Auto-fixable :</span>
|
|
260
|
-
<span class="ml-2 text-gray-600">${rule.
|
|
245
|
+
<span class="ml-2 text-gray-600">${rule.isAutoFixable ? '✅ Oui' : '❌ Non'}</span>
|
|
261
246
|
</div>
|
|
262
247
|
</div>
|
|
263
248
|
</section>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template Unified Settings Panel - Réglages migrations + priorités
|
|
4
|
+
* Regroupement des filtres de migrations et priorités dans un seul bloc
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.renderUnifiedSettingsPanel = renderUnifiedSettingsPanel;
|
|
8
|
+
/**
|
|
9
|
+
* Génère le panel de réglages unifié
|
|
10
|
+
*/
|
|
11
|
+
function renderUnifiedSettingsPanel() {
|
|
12
|
+
return `
|
|
13
|
+
<div class="bg-white rounded-2xl shadow-xl p-6 mb-8">
|
|
14
|
+
<!-- Header avec titre et badge global -->
|
|
15
|
+
<div class="flex items-center justify-between mb-6">
|
|
16
|
+
<h2 class="text-2xl font-bold text-gray-800 flex items-center">
|
|
17
|
+
⚙️ Réglages de Filtrage
|
|
18
|
+
<span data-total-filters-count class="ml-3 px-3 py-1.5 bg-green-100 text-green-700 text-sm font-semibold rounded-full">
|
|
19
|
+
6/6 actifs
|
|
20
|
+
</span>
|
|
21
|
+
</h2>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<!-- Grid 2 colonnes : Migrations | Priorités -->
|
|
25
|
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
|
26
|
+
<!-- Section Migrations -->
|
|
27
|
+
<div class="bg-gradient-to-br from-blue-50 to-blue-100 rounded-xl p-6">
|
|
28
|
+
<div class="flex items-center justify-between mb-4">
|
|
29
|
+
<h3 class="text-lg font-bold text-blue-900 flex items-center">
|
|
30
|
+
🔄 Migrations
|
|
31
|
+
<span data-migration-count class="ml-2 px-2 py-1 bg-green-100 text-green-700 text-xs font-semibold rounded-full">Toutes</span>
|
|
32
|
+
</h3>
|
|
33
|
+
<button
|
|
34
|
+
data-migration-select-all
|
|
35
|
+
class="px-3 py-1.5 bg-blue-100 text-blue-700 text-sm font-semibold rounded-lg hover:bg-blue-200 transition-colors focus:ring-2 focus:ring-blue-500"
|
|
36
|
+
aria-label="Sélectionner toutes les migrations"
|
|
37
|
+
>
|
|
38
|
+
Toutes
|
|
39
|
+
</button>
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
<div class="space-y-3">
|
|
43
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-blue-50 transition-colors border border-blue-200">
|
|
44
|
+
<input
|
|
45
|
+
type="checkbox"
|
|
46
|
+
data-migration-select="to18"
|
|
47
|
+
class="w-5 h-5 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
48
|
+
checked
|
|
49
|
+
aria-label="Migration vers Angular 18"
|
|
50
|
+
/>
|
|
51
|
+
<span class="text-base font-medium text-gray-800">Angular 17 → 18</span>
|
|
52
|
+
</label>
|
|
53
|
+
|
|
54
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-blue-50 transition-colors border border-blue-200">
|
|
55
|
+
<input
|
|
56
|
+
type="checkbox"
|
|
57
|
+
data-migration-select="to19"
|
|
58
|
+
class="w-5 h-5 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
59
|
+
checked
|
|
60
|
+
aria-label="Migration vers Angular 19"
|
|
61
|
+
/>
|
|
62
|
+
<span class="text-base font-medium text-gray-800">Angular 18 → 19</span>
|
|
63
|
+
</label>
|
|
64
|
+
|
|
65
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-blue-50 transition-colors border border-blue-200">
|
|
66
|
+
<input
|
|
67
|
+
type="checkbox"
|
|
68
|
+
data-migration-select="to20"
|
|
69
|
+
class="w-5 h-5 text-blue-600 rounded focus:ring-2 focus:ring-blue-500"
|
|
70
|
+
checked
|
|
71
|
+
aria-label="Migration vers Angular 20"
|
|
72
|
+
/>
|
|
73
|
+
<span class="text-base font-medium text-gray-800">Angular 19 → 20</span>
|
|
74
|
+
</label>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
<!-- Section Priorités -->
|
|
79
|
+
<div class="bg-gradient-to-br from-purple-50 to-purple-100 rounded-xl p-6">
|
|
80
|
+
<div class="flex items-center justify-between mb-4">
|
|
81
|
+
<h3 class="text-lg font-bold text-purple-900 flex items-center">
|
|
82
|
+
🎯 Priorités
|
|
83
|
+
<span data-priority-count class="ml-2 px-2 py-1 bg-green-100 text-green-700 text-xs font-semibold rounded-full">Toutes</span>
|
|
84
|
+
</h3>
|
|
85
|
+
<button
|
|
86
|
+
data-priority-select-all
|
|
87
|
+
class="px-3 py-1.5 bg-purple-100 text-purple-700 text-sm font-semibold rounded-lg hover:bg-purple-200 transition-colors focus:ring-2 focus:ring-purple-500"
|
|
88
|
+
aria-label="Sélectionner toutes les priorités"
|
|
89
|
+
>
|
|
90
|
+
Toutes
|
|
91
|
+
</button>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="space-y-3">
|
|
95
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-purple-50 transition-colors border border-purple-200">
|
|
96
|
+
<input
|
|
97
|
+
type="checkbox"
|
|
98
|
+
data-priority-select="obligatoire"
|
|
99
|
+
class="w-5 h-5 text-purple-600 rounded focus:ring-2 focus:ring-purple-500"
|
|
100
|
+
checked
|
|
101
|
+
aria-label="Règles obligatoires"
|
|
102
|
+
/>
|
|
103
|
+
<div class="flex items-center gap-2">
|
|
104
|
+
<span class="text-2xl">🔴</span>
|
|
105
|
+
<span class="text-base font-medium text-gray-800">Obligatoire</span>
|
|
106
|
+
</div>
|
|
107
|
+
</label>
|
|
108
|
+
|
|
109
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-purple-50 transition-colors border border-purple-200">
|
|
110
|
+
<input
|
|
111
|
+
type="checkbox"
|
|
112
|
+
data-priority-select="recommande"
|
|
113
|
+
class="w-5 h-5 text-purple-600 rounded focus:ring-2 focus:ring-purple-500"
|
|
114
|
+
checked
|
|
115
|
+
aria-label="Règles recommandées"
|
|
116
|
+
/>
|
|
117
|
+
<div class="flex items-center gap-2">
|
|
118
|
+
<span class="text-2xl">🟡</span>
|
|
119
|
+
<span class="text-base font-medium text-gray-800">Recommandé</span>
|
|
120
|
+
</div>
|
|
121
|
+
</label>
|
|
122
|
+
|
|
123
|
+
<label class="flex items-center gap-3 px-4 py-3 bg-white rounded-lg cursor-pointer hover:bg-purple-50 transition-colors border border-purple-200">
|
|
124
|
+
<input
|
|
125
|
+
type="checkbox"
|
|
126
|
+
data-priority-select="optionnelle"
|
|
127
|
+
class="w-5 h-5 text-purple-600 rounded focus:ring-2 focus:ring-purple-500"
|
|
128
|
+
checked
|
|
129
|
+
aria-label="Règles optionnelles"
|
|
130
|
+
/>
|
|
131
|
+
<div class="flex items-center gap-2">
|
|
132
|
+
<span class="text-2xl">🟢</span>
|
|
133
|
+
<span class="text-base font-medium text-gray-800">Optionnel</span>
|
|
134
|
+
</div>
|
|
135
|
+
</label>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- Info Box -->
|
|
141
|
+
<div class="mt-6 p-4 bg-gray-50 rounded-lg border border-gray-200">
|
|
142
|
+
<p class="text-sm text-gray-700">
|
|
143
|
+
<strong>ℹ️ Info :</strong> Les filtres s'appliquent à l'ensemble du rapport (timelines, gantt, diagrammes et totaux).
|
|
144
|
+
Au moins 1 migration et 1 priorité doivent rester sélectionnées.
|
|
145
|
+
</p>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
`;
|
|
149
|
+
}
|