add redux in csc
This commit is contained in:
parent
a89007a81b
commit
3534919502
14 changed files with 277 additions and 12 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -0,0 +1 @@
|
||||||
|
ng-demo
|
15
my-workspace/projects/sae-lib/alert-box/alert-box.html
Normal file
15
my-workspace/projects/sae-lib/alert-box/alert-box.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="alert is-{{alertKind}}">
|
||||||
|
@if (alertKind == "warning"){
|
||||||
|
<i class="ri-triangle-line"></i>
|
||||||
|
}
|
||||||
|
@if (alertKind == "danger"){
|
||||||
|
<i class="ri-triangle-line"></i>
|
||||||
|
}
|
||||||
|
@if (alertKind == "error"){
|
||||||
|
<i class="ri-triangle-line"></i>
|
||||||
|
}
|
||||||
|
<slot name="main">
|
||||||
|
{{message}}
|
||||||
|
</slot>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
0
my-workspace/projects/sae-lib/alert-box/alert-box.scss
Normal file
0
my-workspace/projects/sae-lib/alert-box/alert-box.scss
Normal file
23
my-workspace/projects/sae-lib/alert-box/alert-box.spec.ts
Normal file
23
my-workspace/projects/sae-lib/alert-box/alert-box.spec.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AlertBox } from './alert-box';
|
||||||
|
|
||||||
|
describe('AlertBox', () => {
|
||||||
|
let component: AlertBox;
|
||||||
|
let fixture: ComponentFixture<AlertBox>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [AlertBox]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AlertBox);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
22
my-workspace/projects/sae-lib/alert-box/alert-box.ts
Normal file
22
my-workspace/projects/sae-lib/alert-box/alert-box.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import {Component, Input} from '@angular/core';
|
||||||
|
import {NgClass} from '@angular/common';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-alert-box',
|
||||||
|
imports: [
|
||||||
|
],
|
||||||
|
templateUrl: './alert-box.html',
|
||||||
|
styleUrl: './alert-box.scss'
|
||||||
|
})
|
||||||
|
export class AlertBox {
|
||||||
|
get alertKind(): string {
|
||||||
|
return this._alertKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
set alertKind(value: string) {
|
||||||
|
this._alertKind = value;
|
||||||
|
}
|
||||||
|
@Input() public _alertKind: string = "warning";
|
||||||
|
@Input() public message: string = "";
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,10 @@
|
||||||
"@angular/forms": "^20.1.0",
|
"@angular/forms": "^20.1.0",
|
||||||
"bulma": "^1.0.4",
|
"bulma": "^1.0.4",
|
||||||
"remixicon": "^4.6.0",
|
"remixicon": "^4.6.0",
|
||||||
"shepherd.js": "^14.5.1"
|
"shepherd.js": "^14.5.1",
|
||||||
|
|
||||||
|
"@ngrx/store": "^20.0.0",
|
||||||
|
"@ngrx/store-devtools": "^20.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
|
|
|
@ -27,3 +27,4 @@
|
||||||
@use '_layout_demo.scss';
|
@use '_layout_demo.scss';
|
||||||
@use '_main_button.scss';
|
@use '_main_button.scss';
|
||||||
|
|
||||||
|
|
||||||
|
|
14
sae-csc/package-lock.json
generated
14
sae-csc/package-lock.json
generated
|
@ -14,6 +14,7 @@
|
||||||
"@angular/forms": "^20.1.0",
|
"@angular/forms": "^20.1.0",
|
||||||
"@angular/platform-browser": "^20.1.0",
|
"@angular/platform-browser": "^20.1.0",
|
||||||
"@angular/router": "^20.1.0",
|
"@angular/router": "^20.1.0",
|
||||||
|
"@ngrx/store": "^20.0.0",
|
||||||
"remixicon": "^4.6.0",
|
"remixicon": "^4.6.0",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
|
@ -4930,6 +4931,19 @@
|
||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@ngrx/store": {
|
||||||
|
"version": "20.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@ngrx/store/-/store-20.0.0.tgz",
|
||||||
|
"integrity": "sha512-UVj6UVayXknq1V/OXSGAVG+CdSXYg+oFM6T4aplcP2fuq/4oHtnVi93hkIYa9OU+rhAuHvfRsOsGsTtxlpj52w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@angular/core": "^20.0.0",
|
||||||
|
"rxjs": "^6.5.3 || ^7.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ngtools/webpack": {
|
"node_modules/@ngtools/webpack": {
|
||||||
"version": "20.1.4",
|
"version": "20.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.1.4.tgz",
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
"@angular/forms": "^20.1.0",
|
"@angular/forms": "^20.1.0",
|
||||||
"@angular/platform-browser": "^20.1.0",
|
"@angular/platform-browser": "^20.1.0",
|
||||||
"@angular/router": "^20.1.0",
|
"@angular/router": "^20.1.0",
|
||||||
|
"@ngrx/store": "^20.0.0",
|
||||||
"remixicon": "^4.6.0",
|
"remixicon": "^4.6.0",
|
||||||
"rxjs": "~7.8.0",
|
"rxjs": "~7.8.0",
|
||||||
"tslib": "^2.3.0",
|
"tslib": "^2.3.0",
|
||||||
|
@ -42,6 +43,7 @@
|
||||||
"@storybook/addon-docs": "^9.1.1",
|
"@storybook/addon-docs": "^9.1.1",
|
||||||
"@storybook/angular": "^9.1.1",
|
"@storybook/angular": "^9.1.1",
|
||||||
"@types/jasmine": "~5.1.0",
|
"@types/jasmine": "~5.1.0",
|
||||||
|
"bulma": "^1.0.4 ",
|
||||||
"jasmine-core": "~5.8.0",
|
"jasmine-core": "~5.8.0",
|
||||||
"karma": "~6.4.0",
|
"karma": "~6.4.0",
|
||||||
"karma-chrome-launcher": "~3.2.0",
|
"karma-chrome-launcher": "~3.2.0",
|
||||||
|
@ -49,7 +51,6 @@
|
||||||
"karma-jasmine": "~5.1.0",
|
"karma-jasmine": "~5.1.0",
|
||||||
"karma-jasmine-html-reporter": "~2.1.0",
|
"karma-jasmine-html-reporter": "~2.1.0",
|
||||||
"storybook": "^9.1.1",
|
"storybook": "^9.1.1",
|
||||||
"bulma": "^1.0.4 ",
|
|
||||||
"typescript": "~5.8.2"
|
"typescript": "~5.8.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Component, signal } from '@angular/core';
|
import { Component, signal } from '@angular/core';
|
||||||
import { RouterOutlet } from '@angular/router';
|
import { RouterOutlet } from '@angular/router';
|
||||||
|
import {SaeLib} from '../../../my-workspace/projects/sae-lib/src/public-api';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [RouterOutlet],
|
imports: [RouterOutlet, SaeLib],
|
||||||
templateUrl: './app.html',
|
templateUrl: './app.html',
|
||||||
styleUrl: './app.scss'
|
styleUrl: './app.scss'
|
||||||
})
|
})
|
||||||
|
|
18
sae-csc/src/app/redux/initialState.ts
Normal file
18
sae-csc/src/app/redux/initialState.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Define initial state
|
||||||
|
import {StateInterface} from './reducers';
|
||||||
|
|
||||||
|
|
||||||
|
export const initialState: StateInterface = {
|
||||||
|
app: {
|
||||||
|
backendAPIRoot: "",
|
||||||
|
demoMode: true, // selon l'environnement
|
||||||
|
},
|
||||||
|
currentLang: "fr_FR",
|
||||||
|
currentTheme: "light",
|
||||||
|
langsList: ["fr_FR", "en_US"],
|
||||||
|
themesList: ["light", "dark"],
|
||||||
|
user: {
|
||||||
|
isAuthenticated: false,
|
||||||
|
id: "",
|
||||||
|
},
|
||||||
|
};
|
172
sae-csc/src/app/redux/reducers/index.ts
Normal file
172
sae-csc/src/app/redux/reducers/index.ts
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
import {isDevMode} from '@angular/core';
|
||||||
|
import {ActionReducerMap, MetaReducer} from '@ngrx/store';
|
||||||
|
import {initialState} from '../initialState';
|
||||||
|
|
||||||
|
// Define action types
|
||||||
|
export enum ActionTypes {
|
||||||
|
UPDATE_USER = '[User] Update User',
|
||||||
|
UPDATE_APP = '[App] Update App',
|
||||||
|
UPDATE_CONVERSATIONS_LIST = '[Conversations] Update Conversations List',
|
||||||
|
UPDATE_ACTIVE_CONVERSATION = '[Conversations] Update Active Conversation',
|
||||||
|
POST_MESSAGE_TO_ACTIVE_CONVERSATION = '[Conversations] Post message to Active Conversation',
|
||||||
|
UPDATE_LAST_SEEN_MESSAGE = '[Conversations] Update Last Seen Message',
|
||||||
|
TOGGLE_CONVERSATIONS_LIST_PANEL = '[App] displayConversationListPanelLarge',
|
||||||
|
UPDATE_SINGLE_CONVERSATION = '[Conversations] Update Single Conversation',
|
||||||
|
SEND_USER_FEEDBACK = '[App] Send User Feedback',
|
||||||
|
SWITCH_TO_NEXT_THEME = '[App] Switch To Next Theme',
|
||||||
|
SWITCH_TO_NEXT_LANGUAGE = '[App] Switch To Next Language'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Define action interfaces
|
||||||
|
export interface UpdateUserAction {
|
||||||
|
type: ActionTypes.UPDATE_USER;
|
||||||
|
payload: {
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateAppAction {
|
||||||
|
type: ActionTypes.UPDATE_APP;
|
||||||
|
payload: {
|
||||||
|
backendAPIRoot?: string;
|
||||||
|
displayConversationListPanelLarge?: boolean;
|
||||||
|
displayFeedBackPanel?: boolean;
|
||||||
|
displayErrorResponse?: boolean;
|
||||||
|
displaySourcesPanelLarge?: boolean;
|
||||||
|
displayTour?: boolean;
|
||||||
|
displayWarningAIMaturing?: boolean;
|
||||||
|
feedBackInput?: string;
|
||||||
|
input?: string;
|
||||||
|
lang?: string;
|
||||||
|
notifications?: any[];
|
||||||
|
ollamaAvailable?: boolean;
|
||||||
|
searchInput?: string;
|
||||||
|
version?: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SendUserFeedbackAction {
|
||||||
|
type: ActionTypes.SEND_USER_FEEDBACK;
|
||||||
|
payload: {
|
||||||
|
feedback: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SwitchToNextThemeAction {
|
||||||
|
type: ActionTypes.SWITCH_TO_NEXT_THEME;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SwitchToNextLanguageAction {
|
||||||
|
type: ActionTypes.SWITCH_TO_NEXT_LANGUAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Theme = 'light' | 'dark';
|
||||||
|
type Lang = 'fr_FR' | 'en_US';
|
||||||
|
|
||||||
|
export type AppActions =
|
||||||
|
| UpdateUserAction
|
||||||
|
| UpdateAppAction
|
||||||
|
| SendUserFeedbackAction
|
||||||
|
| SwitchToNextThemeAction
|
||||||
|
| SwitchToNextLanguageAction;
|
||||||
|
|
||||||
|
// Define the State interface
|
||||||
|
export interface StateInterface {
|
||||||
|
user: {
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
app: {
|
||||||
|
demoMode:boolean;
|
||||||
|
backendAPIRoot: string;
|
||||||
|
};
|
||||||
|
themesList: Array<Theme>;
|
||||||
|
currentTheme: Theme;
|
||||||
|
langsList: Array<Lang>;
|
||||||
|
currentLang: Lang;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define reducers
|
||||||
|
function userReducer(state = initialState.user, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
case ActionTypes.UPDATE_USER:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.payload
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appReducer(state = initialState.app, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
case ActionTypes.UPDATE_APP:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.payload
|
||||||
|
};
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function themesListReducer(state = initialState.themesList, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function currentThemeReducer(state = initialState.currentTheme, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
case ActionTypes.SWITCH_TO_NEXT_THEME:
|
||||||
|
// Get the themesList from the store
|
||||||
|
const themesList = initialState.themesList;
|
||||||
|
// Find the index of the current theme
|
||||||
|
const currentThemeIndex = themesList.indexOf(state);
|
||||||
|
// Calculate the index of the next theme (or go back to the first theme if at the end)
|
||||||
|
const nextThemeIndex = (currentThemeIndex + 1) % themesList.length;
|
||||||
|
// Get the next theme
|
||||||
|
return themesList[nextThemeIndex];
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function langsListReducer(state = initialState.langsList, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function currentLangReducer(state = initialState.currentLang, action: AppActions) {
|
||||||
|
switch (action.type) {
|
||||||
|
case ActionTypes.SWITCH_TO_NEXT_LANGUAGE:
|
||||||
|
// Get the langsList from the store
|
||||||
|
const langsList = initialState.langsList;
|
||||||
|
// Find the index of the current language
|
||||||
|
const currentLangIndex = langsList.indexOf(state);
|
||||||
|
// Calculate the index of the next language (or go back to the first language if at the end)
|
||||||
|
const nextLangIndex = (currentLangIndex + 1) % langsList.length;
|
||||||
|
// Get the next language
|
||||||
|
return langsList[nextLangIndex];
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add reducers to ActionReducerMap
|
||||||
|
export const reducers: ActionReducerMap<StateInterface, AppActions> = {
|
||||||
|
user: userReducer,
|
||||||
|
app: appReducer,
|
||||||
|
themesList: themesListReducer,
|
||||||
|
currentTheme: currentThemeReducer,
|
||||||
|
langsList: langsListReducer,
|
||||||
|
currentLang: currentLangReducer
|
||||||
|
};
|
||||||
|
|
||||||
|
export const metaReducers: MetaReducer<StateInterface, AppActions>[] = isDevMode() ? [] : [];
|
|
@ -1,13 +1,5 @@
|
||||||
|
|
||||||
// libs
|
|
||||||
@use 'remixicon/fonts/remixicon.scss';
|
|
||||||
|
|
||||||
@use 'bulma/sass/base/minireset.scss';
|
|
||||||
@use 'bulma/sass/grid/_index.scss';
|
|
||||||
@use 'bulma/sass/components/navbar.scss';
|
|
||||||
|
|
||||||
// dev tools
|
// dev tools
|
||||||
//@use '_app.scss';
|
|
||||||
@use '_global.scss';
|
@use '_global.scss';
|
||||||
@use '_debug.scss';
|
@use '_debug.scss';
|
||||||
@use '_variables.scss';
|
@use '_variables.scss';
|
||||||
|
|
|
@ -2,4 +2,6 @@
|
||||||
// sass lang utils
|
// sass lang utils
|
||||||
@use "sass:color";
|
@use "sass:color";
|
||||||
@use "app/styles/app.scss";
|
@use "app/styles/app.scss";
|
||||||
//@use "../../my-workspace/projects/sae-lib/app/styles/app.scss";
|
// lib SAE Aero styles
|
||||||
|
//@use 'sae-lib/src/styles/index.scss';
|
||||||
|
@use '../../my-workspace/projects/sae-lib/src/styles/index.scss';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue