up airwatch imports
This commit is contained in:
parent
e815c56815
commit
4e57a2368a
17 changed files with 169 additions and 79 deletions
81
airwatch/SOLUTION.md
Normal file
81
airwatch/SOLUTION.md
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
# Solution for Angular NgClass Import Error
|
||||||
|
|
||||||
|
## Issue Description
|
||||||
|
|
||||||
|
When running `npm start` in the airwatch directory, the following error occurred:
|
||||||
|
|
||||||
|
```
|
||||||
|
✘ [ERROR] NG3004: Unable to import symbol NgClass.
|
||||||
|
The symbol is not exported from /home/poule/encrypted/stockage-syncable/www/development/html/ng-implementation/airwatch/node_modules/@angular/common/index.d.ts (module '@angular/common'). [plugin angular-compiler]
|
||||||
|
|
||||||
|
../my-workspace/projects/sae-lib/buttons/main-button/main-button.ngtypecheck.ts:0:0:
|
||||||
|
0 │
|
||||||
|
╵ ^
|
||||||
|
|
||||||
|
The symbol is declared here.
|
||||||
|
|
||||||
|
../my-workspace/projects/sae-lib/node_modules/@angular/common/common_module.d.d.ts:351:0:
|
||||||
|
351 │ declare class NgClass implements DoCheck {
|
||||||
|
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
```
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
|
||||||
|
The error occurred because:
|
||||||
|
|
||||||
|
1. The `main-button` component in the `sae-lib` project was importing `NgClass` directly from `@angular/common`.
|
||||||
|
2. In Angular 20+ (the project is using Angular 20.1.0), `NgClass` is no longer exported directly from `@angular/common` but is available from `@angular/common/directives`.
|
||||||
|
3. Additionally, the `link-sae-lib.sh` script was incorrectly linking `sae-lib` to `old-sae-airwatch` instead of the `airwatch` project.
|
||||||
|
|
||||||
|
## Changes Made
|
||||||
|
|
||||||
|
1. Updated the import statement in `/my-workspace/projects/sae-lib/buttons/main-button/main-button.ts`:
|
||||||
|
```typescript
|
||||||
|
// Changed from:
|
||||||
|
import {NgClass} from '@angular/common';
|
||||||
|
|
||||||
|
// To:
|
||||||
|
import {NgClass} from '@angular/common/directives';
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Fixed the `link-sae-lib.sh` script to link `sae-lib` to the `airwatch` project instead of `old-sae-airwatch`:
|
||||||
|
```bash
|
||||||
|
# Changed from:
|
||||||
|
cd ../../../old-sae-airwatch
|
||||||
|
echo "Utilisation du lien dans l'application old-sae-airwatch..."
|
||||||
|
|
||||||
|
# To:
|
||||||
|
cd ../../../airwatch
|
||||||
|
echo "Utilisation du lien dans l'application airwatch..."
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Requirements
|
||||||
|
|
||||||
|
When attempting to verify the fix, a Node.js version compatibility issue was discovered:
|
||||||
|
|
||||||
|
```
|
||||||
|
Node.js version v20.18.1 detected.
|
||||||
|
The Angular CLI requires a minimum Node.js version of v20.19 or v22.12.
|
||||||
|
```
|
||||||
|
|
||||||
|
To fully run the application, you'll need to update Node.js to version v20.19+ or v22.12+.
|
||||||
|
|
||||||
|
## How to Update Node.js
|
||||||
|
|
||||||
|
You can update Node.js using one of the following methods:
|
||||||
|
|
||||||
|
### Using NVM (Node Version Manager)
|
||||||
|
```bash
|
||||||
|
# Install NVM if not already installed
|
||||||
|
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
|
||||||
|
|
||||||
|
# Install and use the required Node.js version
|
||||||
|
nvm install 20.19
|
||||||
|
nvm use 20.19
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using the Official Node.js Installer
|
||||||
|
1. Visit https://nodejs.org/
|
||||||
|
2. Download and install version 20.19 or higher
|
||||||
|
|
||||||
|
After updating Node.js, run `npm start` in the airwatch directory to verify that both the NgClass import issue and the Node.js version issue are resolved.
|
|
@ -28,10 +28,10 @@ fi
|
||||||
echo "Création d'un lien npm pour sae-lib..."
|
echo "Création d'un lien npm pour sae-lib..."
|
||||||
npm link
|
npm link
|
||||||
|
|
||||||
cd ../../../old-sae-airwatch
|
cd ../../../airwatch
|
||||||
|
|
||||||
# Utiliser le lien dans l'application
|
# Utiliser le lien dans l'application
|
||||||
echo "Utilisation du lien dans l'application old-sae-airwatch..."
|
echo "Utilisation du lien dans l'application airwatch..."
|
||||||
npm link sae-lib
|
npm link sae-lib
|
||||||
|
|
||||||
echo "Lien créé avec succès. sae-lib est maintenant disponible comme un module npm."
|
echo "Lien créé avec succès. sae-lib est maintenant disponible comme un module npm."
|
||||||
|
|
|
@ -4,7 +4,6 @@ import {DomSanitizer, SafeHtml} from '@angular/platform-browser';
|
||||||
import {Copy} from 'sae-lib/buttons/copy/copy';
|
import {Copy} from 'sae-lib/buttons/copy/copy';
|
||||||
import {FeedbackButton} from '../feedback-button/feedback-button';
|
import {FeedbackButton} from '../feedback-button/feedback-button';
|
||||||
import {ChatbotMessage} from '../../services/chatbot.message.type';
|
import {ChatbotMessage} from '../../services/chatbot.message.type';
|
||||||
import {NgClass} from '@angular/common';
|
|
||||||
import {Store} from '@ngrx/store';
|
import {Store} from '@ngrx/store';
|
||||||
import {ActionTypes, StateInterface} from '../../reducers';
|
import {ActionTypes, StateInterface} from '../../reducers';
|
||||||
|
|
||||||
|
@ -16,7 +15,6 @@ type MessageKind = "user" | "llm";
|
||||||
imports: [
|
imports: [
|
||||||
Copy,
|
Copy,
|
||||||
FeedbackButton,
|
FeedbackButton,
|
||||||
NgClass
|
|
||||||
],
|
],
|
||||||
templateUrl: './message-box.html',
|
templateUrl: './message-box.html',
|
||||||
styleUrl: './message-box.scss'
|
styleUrl: './message-box.scss'
|
||||||
|
|
|
@ -1,14 +1,23 @@
|
||||||
.options-dropdown {
|
.options-dropdown {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0.15em;
|
display: inline-block;
|
||||||
right: 0;
|
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: -6em;
|
margin-right: -6em;
|
||||||
|
|
||||||
|
|
||||||
.dropwdown {
|
.dropwdown {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
right: 0;
|
||||||
|
min-width: 160px;
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
z-index: 1000;
|
||||||
|
transition: opacity 0.2s ease, visibility 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -18,6 +27,7 @@
|
||||||
|
|
||||||
.dropwdown {
|
.dropwdown {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,18 +36,28 @@
|
||||||
width: 2em;
|
width: 2em;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.dropdown-item {
|
.dropdown-item {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding-left: 12px;
|
padding-left: 12px;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-left-radius: 6px;
|
||||||
|
border-top-right-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom-left-radius: 6px;
|
||||||
|
border-bottom-right-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
color: cornflowerblue;
|
color: cornflowerblue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -48,16 +68,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-mode-structured,
|
.is-mode-structured,
|
||||||
.is-mode-other,
|
.is-mode-specific {
|
||||||
{
|
|
||||||
.indicator {
|
.indicator {
|
||||||
|
|
||||||
background: red;
|
background: red;
|
||||||
border-radius: 100px;
|
border-radius: 100px;
|
||||||
width: 3px;
|
width: 3px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
position: relative;
|
position: absolute;
|
||||||
left: 30px;
|
right: 2px;
|
||||||
top: -20px;
|
top: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {NgClass} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
|
|
||||||
|
|
||||||
export type optionsDropdownOptions = 'auto' | 'structured' | 'specific';
|
export type optionsDropdownOptions = 'auto' | 'structured' | 'specific';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-options-dropdown',
|
selector: 'app-options-dropdown',
|
||||||
|
standalone: true,
|
||||||
templateUrl: './options-dropdown.html',
|
templateUrl: './options-dropdown.html',
|
||||||
imports: [
|
imports: [
|
||||||
NgClass
|
CommonModule
|
||||||
],
|
],
|
||||||
styleUrl: './options-dropdown.scss'
|
styleUrl: './options-dropdown.scss'
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {NgClass} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
|
|
||||||
type ToggleButtonKind = "local" | "outside";
|
type ToggleButtonKind = "local" | "outside";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-toggle-button',
|
selector: 'app-toggle-button',
|
||||||
imports: [
|
imports: [
|
||||||
NgClass
|
CommonModule
|
||||||
],
|
],
|
||||||
templateUrl: './toggle-button.html',
|
templateUrl: './toggle-button.html',
|
||||||
styleUrl: './toggle-button.scss'
|
styleUrl: './toggle-button.scss'
|
||||||
|
@ -16,7 +16,7 @@ export class ToggleButton {
|
||||||
@Input() kind: ToggleButtonKind = "local";
|
@Input() kind: ToggleButtonKind = "local";
|
||||||
@Input() active: boolean = false;
|
@Input() active: boolean = false;
|
||||||
@Input() icon: string = "";
|
@Input() icon: string = "";
|
||||||
@Input() tooltip: string = "";
|
@Input() tooltip: string | null | undefined = "";
|
||||||
@Output() stateChanged = new EventEmitter<boolean>();
|
@Output() stateChanged = new EventEmitter<boolean>();
|
||||||
|
|
||||||
toggleState() {
|
toggleState() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@if (displayError) {
|
@if (displayError) {
|
||||||
<sae-alert-box _alertKind="error"
|
<sae-alert-box alertKind="error"
|
||||||
message="System error - I couldn't process your request. Please try again in few moments"></sae-alert-box>
|
message="System error - I couldn't process your request. Please try again in few moments"></sae-alert-box>
|
||||||
} @else {
|
} @else {
|
||||||
<sae-alert-box _alertKind="warning"
|
<sae-alert-box alertKind="warning"
|
||||||
message="<strong>AI can make mistakes</strong> - consider verifying important information."></sae-alert-box>
|
message="<strong>AI can make mistakes</strong> - consider verifying important information."></sae-alert-box>
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
:host {
|
||||||
|
|
||||||
|
position: relative;
|
||||||
|
bottom: 0;
|
||||||
|
left: -242px;
|
||||||
|
top: 150px;
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
<div class="button-displayer">
|
<div class="button-displayer">
|
||||||
<!-- <sae-main-button label="bouton large"></sae-main-button>-->
|
coucou
|
||||||
<!-- <sae-main-button></sae-main-button>-->
|
|
||||||
<!-- <sae-main-button></sae-main-button>-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
import {Component} from '@angular/core';
|
import {Component} from '@angular/core';
|
||||||
import {Index} from 'sae-lib/tabs/index';
|
|
||||||
import {MainButton} from 'sae-lib/buttons/main-button/main-button';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-button-displayer',
|
selector: 'app-button-displayer',
|
||||||
imports: [
|
imports: [],
|
||||||
Index,
|
|
||||||
MainButton
|
|
||||||
],
|
|
||||||
templateUrl: './button-displayer.html',
|
templateUrl: './button-displayer.html',
|
||||||
styleUrl: './button-displayer.scss'
|
styleUrl: './button-displayer.scss'
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,22 +1,9 @@
|
||||||
@use '../src/styles/variables.scss';
|
:host {
|
||||||
@use '../src/styles/shadows.scss';
|
|
||||||
|
|
||||||
.alert {
|
|
||||||
padding: 1rem 2rem;
|
|
||||||
border-radius: shadows.$spacing-1;
|
|
||||||
margin-top: shadows.$spacing-1;
|
|
||||||
margin-bottom: shadows.$spacing-1;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
i {
|
i {
|
||||||
margin-right: 10px;
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
float: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sae-alert-box {
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 18px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,29 +1,19 @@
|
||||||
import {Component, ElementRef, Input} from '@angular/core';
|
import {Component, ElementRef, Input} from '@angular/core';
|
||||||
import {CommonModule} from '@angular/common';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'sae-alert-box',
|
selector: 'sae-alert-box',
|
||||||
standalone: true,
|
// standalone: true,
|
||||||
imports: [CommonModule],
|
imports: [],
|
||||||
templateUrl: './alert-box.html',
|
templateUrl: './alert-box.html',
|
||||||
styleUrl: './alert-box.scss'
|
styleUrl: './alert-box.scss'
|
||||||
})
|
})
|
||||||
export class AlertBox {
|
export class AlertBox {
|
||||||
@Input() public message = "";
|
@Input() public message = "";
|
||||||
|
@Input() public alertKind = "warning";
|
||||||
|
|
||||||
constructor(private host: ElementRef<HTMLElement>) {
|
constructor(private host: ElementRef<HTMLElement>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Input() public _alertKind = "warning";
|
|
||||||
|
|
||||||
get alertKind(): string {
|
|
||||||
return this._alertKind;
|
|
||||||
}
|
|
||||||
|
|
||||||
set alertKind(value: string) {
|
|
||||||
this._alertKind = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// whatEver function name you want to give
|
// whatEver function name you want to give
|
||||||
onCloseClicked() {
|
onCloseClicked() {
|
||||||
this.host.nativeElement.remove();
|
this.host.nativeElement.remove();
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
<button
|
<button
|
||||||
[ngClass]="{
|
|
||||||
'is-disabled': disabled
|
|
||||||
}"
|
|
||||||
class="sae-main-button is-{{kind}} is-size-{{size}}"
|
class="sae-main-button is-{{kind}} is-size-{{size}}"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -18,3 +15,4 @@
|
||||||
<i class="ri ri-{{icon}}"></i>
|
<i class="ri ri-{{icon}}"></i>
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {NgClass} from '@angular/common';
|
// import {NgClass} from '@angular/common/directives';
|
||||||
|
|
||||||
export type ButtonKindType = '' | 'primary' | 'secondary' | 'ghost' | 'link';
|
export type ButtonKindType = '' | 'primary' | 'secondary' | 'ghost' | 'link';
|
||||||
export type ButtonSizeType = '' | 'large' | 'medium' | 'small' | 'extrasm';
|
export type ButtonSizeType = '' | 'large' | 'medium' | 'small' | 'extrasm';
|
||||||
|
@ -9,7 +9,7 @@ export type inconPositionKindType = '' | 'left' | 'right';
|
||||||
selector: 'sae-m-button',
|
selector: 'sae-m-button',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
imports: [
|
imports: [
|
||||||
NgClass,
|
// NgClass,
|
||||||
],
|
],
|
||||||
templateUrl: './main-button.html',
|
templateUrl: './main-button.html',
|
||||||
styleUrl: './main-button.scss'
|
styleUrl: './main-button.scss'
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {MultiSelector} from '../../inputs/multi-selector/multi-selector';
|
import {MultiSelector} from '../../inputs/multi-selector/multi-selector';
|
||||||
import {NgClass} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'sae-filters-group',
|
selector: 'sae-filters-group',
|
||||||
imports: [
|
imports: [
|
||||||
MultiSelector,
|
MultiSelector,
|
||||||
NgClass
|
CommonModule,
|
||||||
],
|
],
|
||||||
templateUrl: './filters-group.html',
|
templateUrl: './filters-group.html',
|
||||||
styleUrl: './filters-group.scss'
|
styleUrl: './filters-group.scss'
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
import {Component, EventEmitter, Input, Output} from '@angular/core';
|
||||||
import {NgClass} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'sae-multi-selector',
|
selector: 'sae-multi-selector',
|
||||||
imports: [
|
imports: [
|
||||||
NgClass
|
CommonModule
|
||||||
],
|
],
|
||||||
templateUrl: './multi-selector.html',
|
templateUrl: './multi-selector.html',
|
||||||
styleUrl: './multi-selector.scss'
|
styleUrl: './multi-selector.scss'
|
||||||
|
|
|
@ -24,14 +24,31 @@ export const initialState: StateInterface = {
|
||||||
label: 'ABC',
|
label: 'ABC',
|
||||||
value: 'ABC',
|
value: 'ABC',
|
||||||
}],
|
}],
|
||||||
selectedList: [{
|
selectedList: [
|
||||||
label: 'DEF',
|
{
|
||||||
value: 'DEF',
|
label: 'DEF',
|
||||||
}]
|
value: 'DEF',
|
||||||
|
}, {
|
||||||
|
label: 'GER',
|
||||||
|
value: 'GER',
|
||||||
|
}, {
|
||||||
|
label: '134D',
|
||||||
|
value: '134D',
|
||||||
|
},
|
||||||
|
]
|
||||||
},
|
},
|
||||||
findings: {
|
findings: {
|
||||||
availableList: [],
|
availableList: [{
|
||||||
selectedList: []
|
label: 'DEF',
|
||||||
|
value: 'DEF',
|
||||||
|
}],
|
||||||
|
selectedList: [{
|
||||||
|
label: 'GER',
|
||||||
|
value: 'GER',
|
||||||
|
}, {
|
||||||
|
label: '134D',
|
||||||
|
value: '134D',
|
||||||
|
},]
|
||||||
},
|
},
|
||||||
ata: {
|
ata: {
|
||||||
availableList: [],
|
availableList: [],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue