styling multi filters

This commit is contained in:
Tykayn 2025-09-15 16:09:20 +02:00 committed by tykayn
parent a359d0f9b1
commit 4ef8d42da2
23 changed files with 205 additions and 120 deletions

View file

@ -17,11 +17,6 @@ export class FeedbackButton {
submitSuccess: boolean = false; submitSuccess: boolean = false;
submitError: boolean = false; submitError: boolean = false;
// constructor(
// private store: Store<StateInterface>,
// private apiService: ApiService
// ) {
// }
toggleModal() { toggleModal() {
this.isModalOpen = !this.isModalOpen; this.isModalOpen = !this.isModalOpen;

View file

@ -1,17 +1,17 @@
<div [ngClass]="{highlighted}" class="filter-group"> <div [ngClass]="{highlighted, 'is-disabled': disabled}" class="filter-group">
<div class="selectors"> <div class="selectors">
<sae-multi-selector <sae-multi-selector
(availableChoicesChange)="onAvailableChoicesChange" (availableChoicesChange)="onAvailableChoicesChange"
(selectedChoicesChange)="onSelectedChoicesChange" (selectedChoicesChange)="onSelectedChoicesChange"
[actionTypes]="actionTypes" [actionTypes]="actionTypes"
[availableChoices]="appState.filters.engineType.availableChoices" [availableChoices]="appState.filters.engineType.availableChoices"
[disabled]="disabled"
[label]="'Engine type'" [label]="'Engine type'"
[selectedChoices]="appState.filters.engineType.selectedChoices" [selectedChoices]="appState.filters.engineType.selectedChoices"
[store]="store" [store]="store"
></sae-multi-selector> ></sae-multi-selector>
<sae-multi-selector <sae-multi-selector
[label]="'Findings'"
[disabled]="true" [label]="'Findings'"
[selectedChoices]="[]" [selectedChoices]="[]"
></sae-multi-selector> ></sae-multi-selector>
<sae-multi-selector [label]="'ATA'"></sae-multi-selector> <sae-multi-selector [label]="'ATA'"></sae-multi-selector>
@ -21,38 +21,30 @@
</div> </div>
<div (click)="highlighted = !highlighted" class="chips-listing"> <div (click)="highlighted = !highlighted" class="chips-listing">
<!-- liste de chips--> <!-- liste de chips-->
<pre>
filters:
{{ appState.filters }}
</pre>
<div class="chips-column"> <div class="chips-column">
<!-- @for( elem in appState.filters.engineType.selectedChoices; track elem.label ){-->
<!-- <button class="button chips is-rounded is-small">-->
<button class="button chips is-rounded is-small"> <!-- {{elem.label}}-->
<!-- <span class="post-button">-->
filtre c1 1 <!-- x-->
<span class="post-button"> <!-- </span>-->
x <!-- </button>-->
</span> <!-- }-->
</button>
<button class="button chips is-rounded is-small">
filtre c1 2
<span class="post-button">
x
</span>
</button>
<button class="button chips is-rounded is-small">
filtre c1 3
<span class="post-button">
x
</span>
</button>
</div> </div>
<div class="chips-column"> <!-- <div class="chips-column">-->
<button class="button chips is-rounded is-small"> <!-- <button class="button chips is-rounded is-small">-->
filtre col 2 <!-- filtre col 2-->
<span class="post-button"> <!-- <span class="post-button">-->
x <!-- x-->
</span> <!-- </span>-->
</button> <!-- </button>-->
</div> <!-- </div>-->
</div> </div>
</div> </div>

View file

@ -2,15 +2,15 @@
:host { :host {
.translate-texts {
width: 1312px;
}
.selectors { .selectors {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 10px; gap: 5px;
sae-multi-selector {
margin-left: 20px;
}
} }
.dropdown { .dropdown {
@ -20,7 +20,6 @@
right: 0; right: 0;
top: 0; top: 0;
cursor: pointer; cursor: pointer;
} }
&:hover { &:hover {
@ -46,8 +45,11 @@
.chips-listing { .chips-listing {
display: flex; display: flex;
border-radius: 8px; border-radius: 8px;
position: absolute;
top: 577px;
} }
.filter-group { .filter-group {
@ -65,9 +67,11 @@
margin-top: 16px; margin-top: 16px;
border-radius: 4px; border-radius: 4px;
background: variables.$csc-filters-box-color; background: variables.$csc-filters-box-color;
width: 100%;
height: 400px; width: 1332px;
height: 208px;
padding: 12px; padding: 12px;
overflow-y: auto;
.chips-column { .chips-column {
padding-right: 10px; padding-right: 10px;

View file

@ -17,7 +17,11 @@ export class FiltersGroup {
@Input() appState: any = {}; @Input() appState: any = {};
@Input() store: any; @Input() store: any;
@Input() actionTypes: any; @Input() actionTypes: any;
@Input() disabled!: boolean;
constructor() {
console.log('constructor filters group', this.appState, this.store, this.actionTypes);
}
onSelectedChoicesChange(e: any) { onSelectedChoicesChange(e: any) {
console.log('onSelectedChoicesChange', e); console.log('onSelectedChoicesChange', e);

View file

@ -12,14 +12,15 @@
{{ label }} {{ label }}
</span> </span>
</div> </div>
<!-- (blur)="displayDropdown = false"-->
<input <input
(blur)="displayDropdown = false" (click)="onClickInput()"
(click)="onClickInput()" (focus)="displayDropdown = true" (focus)="displayDropdown = true"
class="is-hidden" placeholder="{{label}}" class="is-hidden" placeholder="{{label}}"
type="text"> type="text">
<span [ngClass]="{ 'is-visible' : selectedChoices?.length}" <span [ngClass]="{ 'is-visible' : selectedChoices?.length}"
class="selected-items-counter"> class="selected-items-counter">
{{ selectedChoices?.length }} {{ selectedChoices?.length || 0 }}
</span> </span>
<div class="dropdown-button selector-button"> <div class="dropdown-button selector-button">
<!-- bouton--> <!-- bouton-->

View file

@ -3,7 +3,7 @@
:host { :host {
.input-box { .input-box {
margin-left: -1rem; width: 220px;
.d-none { .d-none {
display: none; display: none;
@ -36,11 +36,14 @@
} }
.selector-button { .selector-button {
top: -32px; top: -60px;
right: -183px; left: 188px;
width: 20px;
} }
.selected-items-counter { .selected-items-counter {
visibility: hidden;
background: variables.$csc-chips-bg-color; background: variables.$csc-chips-bg-color;
color: white; color: white;
border-radius: 200px; border-radius: 200px;
@ -48,9 +51,11 @@
display: inline-block; display: inline-block;
line-height: 10px; line-height: 10px;
position: relative; position: relative;
top: 2px; z-index: 11;
left: -53px; height: 30px;
visibility: hidden; top: -36px;
right: 65px;
&.is-visible { &.is-visible {
visibility: visible; visibility: visible;
@ -64,7 +69,6 @@
border: 1px solid #8D91A4; border: 1px solid #8D91A4;
background: var(--color-background-card-on-base, #FFF); background: var(--color-background-card-on-base, #FFF);
padding: 10px 40px; padding: 10px 40px;
width: 210px; width: 210px;
@ -90,8 +94,9 @@
z-index: 10; z-index: 10;
border-top-left-radius: 0; border-top-left-radius: 0;
border-top-right-radius: 0; border-top-right-radius: 0;
width: 210px;
top: -28px; top: -59px;
border-left: 1px solid #8D91A4; border-left: 1px solid #8D91A4;
border-bottom: 1px solid #8D91A4; border-bottom: 1px solid #8D91A4;
border-right: 1px solid #8D91A4; border-right: 1px solid #8D91A4;

View file

@ -11,7 +11,7 @@
}, },
"include": [ "include": [
"src/**/*.ts", "src/**/*.ts",
"inbox/translate-texts/**/*.ts" "../../../sae-csc/src/app/shared/translate-texts/**/*.ts"
], ],
"exclude": [ "exclude": [
"**/*.spec.ts" "**/*.spec.ts"

View file

@ -3,8 +3,12 @@
<title>CSC implémentation</title> <title>CSC implémentation</title>
</head> </head>
<body> <body>
@if (currentUrl !== '/login') { <!--<pre>-->
<app-top-navigation></app-top-navigation> <!-- currentUrl:-->
<!-- {{ currentUrl }}-->
<!--</pre>-->
@if (currentUrl !== '/login' && currentUrl !== '/') {
<app-top-navigation [user]="appState.user"></app-top-navigation>
<sae-feedback-button></sae-feedback-button> <sae-feedback-button></sae-feedback-button>
} }
<router-outlet/> <router-outlet/>

View file

@ -1,8 +1,10 @@
import {Component, inject, signal} from '@angular/core'; import {Component, inject, signal} from '@angular/core';
import {ActivatedRoute, Router, RouterOutlet, NavigationEnd} from '@angular/router'; import {NavigationEnd, Router, RouterOutlet} from '@angular/router';
import {TopNavigation} from './shared/navigation/top-navigation/top-navigation'; import {TopNavigation} from './shared/navigation/top-navigation/top-navigation';
import {FeedbackButton} from 'sae-lib/buttons/feedback-button/feedback-button'; import {FeedbackButton} from 'sae-lib/buttons/feedback-button/feedback-button';
import {filter} from 'rxjs/operators'; import {filter} from 'rxjs/operators';
import {Store} from '@ngrx/store';
import {StateInterface} from './redux/reducers';
// import {SaeLib} from '@sae-lib/src/public-api'; // import {SaeLib} from '@sae-lib/src/public-api';
@ -15,9 +17,14 @@ import {filter} from 'rxjs/operators';
export class App { export class App {
public router = inject(Router); public router = inject(Router);
currentUrl: string = ''; currentUrl: string = '';
public appState: any = {};
protected readonly title = signal('implem'); protected readonly title = signal('implem');
constructor() { constructor(private store: Store<StateInterface>) {
this.store.select(state => state.app).subscribe(appState => {
this.appState = appState;
});
this.router.events.pipe( this.router.events.pipe(
filter(event => event instanceof NavigationEnd) filter(event => event instanceof NavigationEnd)
).subscribe((event: any) => { ).subscribe((event: any) => {

View file

@ -24,14 +24,14 @@
</span> </span>
</div> </div>
<sae-translate-texts></sae-translate-texts> <sae-translate-texts [appState]="appState"></sae-translate-texts>
</div> </div>
<!-- analyse de question--> <!-- analyse de question-->
<div id="question_analysis"> <div id="question_analysis">
<h2 class="title"> <h2 class="title">
Question analysis Question analysis
</h2> </h2>
@if (appState.botMessage) { @if (appState?.botMessage) {
<sae-bot-talks <sae-bot-talks
[message]="appState.botMessage"></sae-bot-talks> [message]="appState.botMessage"></sae-bot-talks>
@ -39,7 +39,8 @@
<!--filters--> <!--filters-->
<!-- advanced filters--> <!-- advanced filters-->
<div class="filters-container"> <div class="filters-container">
<sae-filters-group (selectionchange)="onSelectedChoicesChange" [appState]="appState"></sae-filters-group> <sae-filters-group (selectionchange)="onSelectedChoicesChange" [appState]="appState"
[disabled]="!appState.fromText.length"></sae-filters-group>
</div> </div>
</div> </div>
</main> </main>

View file

@ -1,7 +1,9 @@
:host { :host {
width: 1312px; //width: 1312px;
display: block; //display: block;
margin: 0 auto;
#question_analysis { #question_analysis {
sae-bot-talks { sae-bot-talks {
@ -44,4 +46,8 @@
} }
} }
#main_page {
padding-bottom: 400px;
}
} }

View file

@ -1,5 +1,5 @@
import {Component} from '@angular/core'; import {Component} from '@angular/core';
import {TranslateTexts} from 'sae-lib/inbox/translate-texts/translate-texts'; import {TranslateTexts} from '../../shared/translate-texts/translate-texts';
import {FiltersGroup} from 'sae-lib/filters/filters-group/filters-group'; import {FiltersGroup} from 'sae-lib/filters/filters-group/filters-group';
import {BottomNavigation} from '../../shared/navigation/bottom-navigation/bottom-navigation'; import {BottomNavigation} from '../../shared/navigation/bottom-navigation/bottom-navigation';
import {FeedbackButton} from 'sae-lib/buttons/feedback-button/feedback-button'; import {FeedbackButton} from 'sae-lib/buttons/feedback-button/feedback-button';

View file

@ -1,9 +1,19 @@
export type CscCase = { export type CscCase = {};
export type TechManual = {};
}; export type filterListing = {};
export type TechManual = { export type filterGroupType = {
engineType: filterDoubleListType,
}; findings: filterDoubleListType,
export type filterListing = { ata: filterDoubleListType,
partNumber: filterDoubleListType,
}; technicalManual: filterDoubleListType,
onOffWing: filterDoubleListType,
}
export type filterDoubleListType = {
availableList: filterListType[],
selectedList: filterListType[],
}
export type filterListType = {
label: string,
value: string,
}

View file

@ -1,30 +1,17 @@
// Define initial state // Define initial state
import {StateInterface} from './reducers'; import {StateInterface} from './reducers';
export type filterGroupType = {
engineType: filterDoubleListType,
findings: filterDoubleListType,
ata: filterDoubleListType,
partNumber: filterDoubleListType,
technicalManual: filterDoubleListType,
onOffWing: filterDoubleListType,
}
export type filterDoubleListType = {
availableList: filterListType[],
selectedList: filterListType[],
}
export type filterListType = {
label: string,
value: string,
}
export const initialState: StateInterface = { export const initialState: StateInterface = {
app: { app: {
backendAPIRoot: "", backendAPIRoot: "",
demoMode: true, demoMode: true,
loading: false,
// fromText: "le texte",
fromText: "", fromText: "",
fromFile: "", fromFile: "",
toText: "", toText: "",
botMessage: "Generating a summary...analyzing clients question...", botMessage: "",
filters: { filters: {
engineType: { engineType: {
availableList: [{ availableList: [{
@ -37,30 +24,67 @@ export const initialState: StateInterface = {
}] }]
}, },
findings: { findings: {
availableList: {}, availableList: [],
selectedList: {} selectedList: []
}, },
ata: { ata: {
availableList: {}, availableList: [],
selectedList: {} selectedList: []
}, },
partNumber: { partNumber: {
availableList: {}, availableList: [],
selectedList: {} selectedList: []
}, },
technicalManual: { technicalManual: {
availableList: {}, availableList: [],
selectedList: {} selectedList: []
}, },
onOffWing: { onOffWing: {
availableList: {}, availableList: [],
selectedList: {} selectedList: []
} }
}, },
similarCases: [ similarCases: [
{ {
id: 1, id: 1,
} info: "Work stoppage case for CFM56-7B engine (ESN: 894773) at MTU Zhuhai. LPC Stage 3 blade platform dislocation detected during shop visit BSI. Maximum dislocation: 1.22mm axial, 0.63mm radial. Customer requests evaluation, acceptance criteria, or DICA for further action. No corresponding limits in AMM 72-00-00 BSI inspection chapter. ",
date: "2023-01-01",
chrono_id: "CSC/CFM/2023-10/00446-A",
responsable_team: "FO-CFM",
ge_instruction: "-",
original_question: "blah abl a a jjdbblja bajdblad blab ladlb kaabl",
answer_sent: "dfosdoo osg ogf ogf kgof gfkdmdm gfkdfmkl km opsg gfsok sfol lorem",
engine_part: "ABD cd CD DC DC ZFR ETT HETHG",
findings: "some findings were found here",
DICA: "one dica stuff",
DICA_file: "dica_file.pdf",
}, {
id: 1,
info: "Bhlah lahl hl lhalhadlh No corresponding limits in AMM 72-00-00 BSI inspection chapter. ",
date: "2024-07-08",
chrono_id: "CSC/CFM/1234-10/00446-A",
responsable_team: "FO-CFM",
ge_instruction: "-",
original_question: "blah abl a a jjdbblja bajdblad blab ladlb kaabl",
answer_sent: "dfosdoo osg ogf ogf kgof gfkdmdm gfkdfmkl km opsg gfsok sfol lorem",
engine_part: "ABD cd CD DC DC ZFR ETT HETHG",
findings: "some findings were found here",
DICA: "one dica stuff",
DICA_file: "dica_file_2.pdf",
}, {
id: 1,
info: "Work stoppage case for CFM56-7B engine (ESN: 894773) at MTU Zhuhai. LPC Stage 3 blade platform dislocation detected during shop visit BSI. Maximum dislocation: 1.22mm axial, 0.63mm radial. Customer requests evaluation, acceptance criteria, or DICA for further action. No corresponding limits in AMM 72-00-00 BSI inspection chapter. ",
date: "2023-01-01",
chrono_id: "CSC/CFM/2023-10/00446-A",
responsable_team: "FO-CFM",
ge_instruction: "-",
original_question: "blah abl a a jjdbblja bajdblad blab ladlb kaabl",
answer_sent: "dfosdoo osg ogf ogf kgof gfkdmdm gfkdfmkl km opsg gfsok sfol lorem",
engine_part: "ABD cd CD DC DC ZFR ETT HETHG",
findings: "some findings were found here",
DICA: "one dica stuff",
DICA_file: "dica_file.pdf",
},
], ],
searchInput: "", searchInput: "",
enableAiSuggestion: false, enableAiSuggestion: false,
@ -78,7 +102,9 @@ export const initialState: StateInterface = {
langsList: ["fr_FR", "en_US"], langsList: ["fr_FR", "en_US"],
themesList: ["light", "dark"], themesList: ["light", "dark"],
user: { user: {
isAuthenticated: false, isAuthenticated: true,
id: "", id: "123412345",
token: "abcd-123412345",
login: "Borhème",
}, },
}; };

View file

@ -95,9 +95,12 @@ export interface StateInterface {
user: { user: {
isAuthenticated: boolean; isAuthenticated: boolean;
id: string; id: string;
login: string;
token: string;
}; };
app: { app: {
demoMode: boolean; demoMode: boolean;
loading: boolean;
backendAPIRoot: string; backendAPIRoot: string;
fromFile: string, fromFile: string,
fromText: string, fromText: string,

View file

@ -38,11 +38,14 @@
<!-- exit--> <!-- exit-->
<i class="ri-door-line"></i> <i class="ri-door-line"></i>
</a> </a>
@if (appState.user) {
<a class="navbar-item user-account-item"> <a class="navbar-item user-account-item">
<!-- user --> <!-- user -->
<i class="ri-user-2-fill"></i> <i class="ri-user-2-fill"></i>
borhène {{ appState.user.login }}
</a> </a>
}
</div> </div>
</div> </div>

View file

@ -1,6 +1,5 @@
import {Component} from '@angular/core'; import {Component, Input} from '@angular/core';
import {RouterLink, RouterLinkActive} from '@angular/router'; import {RouterLink, RouterLinkActive} from '@angular/router';
// import {AlertBox} from '../../../../../../my-workspace/projects/sae-lib/alert-box/alert-box';
@Component({ @Component({
@ -15,4 +14,7 @@ import {RouterLink, RouterLinkActive} from '@angular/router';
}) })
export class TopNavigation { export class TopNavigation {
@Input() public user: any = {};
@Input() public appState: any = {};
} }

View file

@ -45,7 +45,8 @@
<textarea <textarea
(focus)="focusFromText()" (focus)="focusFromText()"
(keyup)="onFromTextChanged()" (keyup)="onFromTextChanged()"
[(ngModel)]="fromText" (ngModelChange)="onFromTextChanged()"
[ngModel]="appState.fromText"
cols="30" cols="30"
id="from_text" id="from_text"
name="from_text" name="from_text"

View file

@ -1,4 +1,4 @@
@use '../../src/styles/variables'; @use '../../../../../my-workspace/projects/sae-lib/src/styles/variables';
:host { :host {
@ -23,7 +23,7 @@
.delete-button { .delete-button {
border: 0; border: 0;
border-radius: 100%; border-radius: 100%;
background: #F2F2F2; background: #fff;
color: grey; color: grey;
cursor: pointer; cursor: pointer;
padding: 10px; padding: 10px;
@ -32,9 +32,10 @@
visibility: hidden; visibility: hidden;
z-index: 10; z-index: 10;
position: relative; position: relative;
right: -26px;
&:hover { &:hover {
background: #888; background: #F2F2F2;
color: #222; color: #222;
display: block; display: block;
} }
@ -86,7 +87,7 @@
border: 1px solid var(--color-text-title, variables.$csc-nav-color); border: 1px solid var(--color-text-title, variables.$csc-nav-color);
background: var(--color-background-card-on-base, #FFF); background: var(--color-background-card-on-base, #FFF);
left: 0; left: 0;
top: 100px; top: 68px;
position: relative; position: relative;
font-weight: 600; font-weight: 600;

View file

@ -1,10 +1,11 @@
import {Component, EventEmitter, Output} from '@angular/core'; import {Component, EventEmitter, Input, Output} from '@angular/core';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {NgClass} from '@angular/common'; import {NgClass} from '@angular/common';
import {Store} from '@ngrx/store';
import {StateInterface} from './../../redux/reducers';
@Component({ @Component({
selector: 'sae-translate-texts', selector: 'sae-translate-texts',
standalone: true,
imports: [FormsModule, NgClass], imports: [FormsModule, NgClass],
templateUrl: './translate-texts.html', templateUrl: './translate-texts.html',
styleUrl: './translate-texts.scss' styleUrl: './translate-texts.scss'
@ -20,6 +21,7 @@ export class TranslateTexts {
public fileIsUploaded: boolean = false; public fileIsUploaded: boolean = false;
public filePath: string = ''; public filePath: string = '';
public fileWeight: string = ''; public fileWeight: string = '';
// testing display of file selector // testing display of file selector
// public fileIsUploaded: boolean = true; // public fileIsUploaded: boolean = true;
// public filePath: string = 'abcd.csv'; // public filePath: string = 'abcd.csv';
@ -27,8 +29,19 @@ export class TranslateTexts {
public fromTimeout: any; public fromTimeout: any;
public debounceDuration: number = 1000; public debounceDuration: number = 1000;
@Input() appState: any = {};
@Output() updateFilters: EventEmitter<any> = new EventEmitter(); @Output() updateFilters: EventEmitter<any> = new EventEmitter();
constructor(private store: Store<StateInterface>) {
// Subscribe to the app state to get the loading state
this.store.select(state => state.app.loading).subscribe(loading => {
this.loadingResume = loading;
});
this.store.select(state => state.app).subscribe(appState => {
this.appState = appState;
});
}
onToTextChanged(e: any): void { onToTextChanged(e: any): void {
console.log('text changed toText', e) console.log('text changed toText', e)
@ -61,6 +74,8 @@ export class TranslateTexts {
onFromTextChanged(e?: any): void { onFromTextChanged(e?: any): void {
console.log('text changed fromText', e) console.log('text changed fromText', e)
// this.store.dispatch({})
// run research after a delay // run research after a delay
if (this.mode !== 'production') { if (this.mode !== 'production') {
this.loadingResume = true; this.loadingResume = true;

View file

@ -22,3 +22,7 @@ html, body {
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
sae-feedback-button .feedback-button {
top: 140px;
}

View file

@ -3,4 +3,5 @@
.all-pages { .all-pages {
padding: 70px 64px; padding: 70px 64px;
width: 100%;
} }