up storybook main button

This commit is contained in:
Tykayn 2025-09-17 15:41:04 +02:00 committed by tykayn
parent 4af14e6e34
commit d5610f38be
15 changed files with 339 additions and 547 deletions

View file

@ -0,0 +1,7 @@
import { Meta } from '@storybook/addon-docs/blocks';
{/* 👇 Documentation-only page */}
<Meta title="Documentation" />
hey yo
{/* 👇 Component documentation page */}

View file

@ -0,0 +1,20 @@
<button
[ngClass]="{
'is-disabled': disabled
}"
class="sae-main-button is-{{kind}} is-size-{{size}}"
>
@if (icon && inconPosition !== "right") {
<i class="ri ri-{{icon}}"></i>
}
<span class="label">
{{ label }}
</span>
@if (divider) {
<span class="pipe">|</span>
}
@if (icon && inconPosition == "right") {
<i class="ri ri-{{icon}}"></i>
}
</button>

View file

@ -1,14 +1,16 @@
@use "sae-lib/src/styles/shadows.scss"; @use "sae-lib/src/styles/shadows.scss";
@use "sae-lib/src/styles/states.scss"; @use "sae-lib/src/styles/states.scss";
@use "sae-lib/src/styles/variables.scss"; @use "sae-lib/src/styles/variables.scss" as variables;
@use "sass:color"; @use "sass:color";
:host { :host {
display: inline-block; display: inline-block;
font-family: Barlow;
button { button {
background: shadows.$primary-color; //background: shadows.$primary-color;
color: shadows.$neutral-white; color: shadows.$neutral-white;
border-radius: shadows.$radius-main; border-radius: shadows.$radius-main;
padding: 1rem 2rem; padding: 1rem 2rem;
@ -23,47 +25,108 @@
} }
&:hover, &:active, &:focus { &:hover, &:active, &:focus {
background: shadows.$main-bg-color-active;
color: shadows.$main-color-active;
transition: all 0.25s ease; transition: all 0.25s ease;
} }
&:hover {
background: var(--Gradient, linear-gradient(77deg, #073A7C -4.23%, #1767AD 51.8%, #255B8E 87.72%));
}
&.is-size {
&-large {
padding: 17px 24px;
font-size: 18px;
font-weight: 600;
line-height: 26px;
}
&-medium {
padding: 14px 18px;
border-radius: var(--radius-2, 8px);
font-size: 16px;
font-weight: 600;
line-height: 20px;
}
&-small {
padding: 14px 10px;
border-radius: var(--radius-2, 8px);
font-size: 14px;
font-weight: 600;
line-height: 20px;
}
&-extrasm {
padding: 10px 10px;
border-radius: var(--radius-2, 4px);
color: var(--Colors-Blanc, #FFF);
font-size: 12px;
font-weight: 600;
line-height: 18px;
}
}
// state colors
&.is-primary { &.is-primary {
background-color: variables.$primary-color; background: var(--Gradient, linear-gradient(77deg, #073A7C -4.23%, #1767AD 51.8%, #255B8E 87.72%));
color: variables.$neutral-white; color: variables.$neutral-white;
border-color: color.adjust(variables.$primary-color, $lightness: - 10%); border-color: color.adjust(variables.$primary-color, $lightness: - 10%);
&:hover {
background: var(--Hover, linear-gradient(70deg, #073A7C 43.99%, #1767AD 94.38%, #255B8E 126.68%));
}
&.is-disabled {
background-color: #BED7EE;
color: white;
}
} }
&.is-secondary { &.is-secondary {
background-color: variables.$secondary-color; background-color: variables.$neutral-white;
color: variables.$neutral-white; color: variables.$neutral-white;
&.is-disabled {
background-color: #BED7EE;
color: white;
}
} }
&.is-warning { &.is-ghost {
background: variables.$neutral-white; background: variables.$neutral-white;
color: variables.$warning-color-text; color: #255B8E;
border: 0; border: 0;
&:focus {
background: variables.$neutral-white;
}
&.is-disabled {
background-color: #BED7EE;
color: #BED7EE;
}
} }
&.is-info { &.is-link {
background: variables.$info-color; background: variables.$neutral-white;
color: variables.$neutral-white; color: #255B8E;
border-color: color.adjust(variables.$info-color, $lightness: -50%);
}
&.is-success {
background: variables.$success-color;
color: variables.$neutral-white;
border-color: color.adjust(variables.$success-color, $lightness: -50%);
}
&.is-error {
background: rgba(variables.$danger-color, 10%);
color: variables.$danger-color;
border: 0; border: 0;
.label {
text-decoration: underline;
text-decoration-color: variables.$primary-color;
}
&.is-disabled {
background-color: #BED7EE;
color: #BED7EE;
}
} }
} }

View file

@ -1,27 +1,19 @@
import type {Meta, StoryObj} from '@storybook/angular'; import type {Meta, StoryObj} from '@storybook/angular';
import {MainButton} from './main-button'; import {MainButton} from './main-button';
import {moduleMetadata} from '@storybook/angular';
import {CommonModule} from '@angular/common';
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction // More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
const meta: Meta<MainButton> = { const meta: Meta<MainButton> = {
title: 'composants/boutons/MainButton', title: 'composants/boutons/MainButton',
component: MainButton, component: MainButton,
tags: ['autodocs'], tags: ['autodocs'],
decorators: [
moduleMetadata({
imports: [CommonModule],
providers: []
})
],
argTypes: { argTypes: {
disabled: {control: 'boolean'},
divider: {control: 'boolean'},
label: {control: 'text'}, label: {control: 'text'},
icon: {control: 'text'}, icon: {control: 'text'},
kind: { inconPosition: {control: 'select', options: ['left', 'right']},
control: 'select', size: {control: 'select', options: ['', 'large', 'medium', 'small', 'extrasm']},
options: ['', 'primary', 'secondary', 'info', 'success', 'warning', 'danger'], kind: {control: 'select', options: ['', 'primary', 'secondary', 'ghost', 'link']},
description: 'Style du bouton'
},
}, },
}; };
@ -29,66 +21,146 @@ export default meta;
type Story = StoryObj<MainButton>; type Story = StoryObj<MainButton>;
// More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args // More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args
export const Default: Story = {
args: {
label: 'Call to action',
kind: 'primary',
size: 'large',
disabled: false,
divider: true,
icon: 'arrow-right-line',
inconPosition: 'right',
},
};
export const Primary: Story = { export const Primary: Story = {
args: { args: {
label: 'Button', label: 'Primary Button',
icon: 'home-line-2', kind: 'primary',
kind: 'primary' size: 'medium',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
}, },
}; };
export const Secondary: Story = { export const Secondary: Story = {
args: { args: {
label: 'Secondary Button', label: 'Secondary Button',
icon: 'settings-line', kind: 'secondary',
kind: 'secondary' size: 'medium',
}, disabled: false,
}; divider: false,
export const Info: Story = {
args: {
label: 'Info Button',
icon: 'information-line',
kind: 'info'
},
};
export const Success: Story = {
args: {
label: 'Success Button',
icon: 'check-line',
kind: 'success'
},
};
export const Warning: Story = {
args: {
label: 'Warning Button',
icon: 'alert-line',
kind: 'warning'
},
};
export const Danger: Story = {
args: {
label: 'Danger Button',
icon: 'close-circle-line',
kind: 'danger'
},
};
export const WithoutIcon: Story = {
args: {
label: 'Button without icon',
icon: '', icon: '',
kind: 'primary' inconPosition: 'left',
},
};
export const Ghost: Story = {
args: {
label: 'Ghost Button',
kind: 'ghost',
size: 'medium',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
},
};
export const Link: Story = {
args: {
label: 'Link Button',
kind: 'link',
size: 'medium',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
}, },
}; };
export const WithIcon: Story = { export const WithIcon: Story = {
args: { args: {
label: 'Button with icon', label: 'Button with Icon',
icon: 'user-line', kind: 'primary',
kind: '' size: 'medium',
disabled: false,
divider: false,
icon: 'arrow-right-line',
inconPosition: 'left',
},
};
export const WithIconRight: Story = {
args: {
label: 'Button with Icon Right',
kind: 'primary',
size: 'medium',
disabled: false,
divider: false,
icon: 'arrow-right-line',
inconPosition: 'right',
},
};
export const WithDivider: Story = {
args: {
label: 'Button with Divider',
kind: 'primary',
size: 'medium',
disabled: false,
divider: true,
icon: 'arrow-right-line',
inconPosition: 'right',
},
};
export const Disabled: Story = {
args: {
label: 'Disabled Button',
kind: 'primary',
size: 'medium',
disabled: true,
divider: false,
icon: '',
inconPosition: 'left',
},
};
export const Large: Story = {
args: {
label: 'Large Button',
kind: 'primary',
size: 'large',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
},
};
export const Small: Story = {
args: {
label: 'Small Button',
kind: 'primary',
size: 'small',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
},
};
export const ExtraSmall: Story = {
args: {
label: 'Extra Small Button',
kind: 'primary',
size: 'extrasm',
disabled: false,
divider: false,
icon: '',
inconPosition: 'left',
}, },
}; };

View file

@ -1,28 +1,22 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {ButtonKindType, ButtonSizeType, inconPositionKindType} from 'sae-lib/buttons/main-button/main-button';
export type ButtonKind = '' | 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger'; export type ButtonKind = '' | 'primary' | 'secondary' | 'info' | 'success' | 'warning' | 'danger';
@Component({ @Component({
selector: 'app-main-button', selector: 'app-main-button',
standalone: true,
imports: [CommonModule], imports: [CommonModule],
template: ` templateUrl: './main-button.html',
<button class="is-{{kind}}">
@if (icon) {
<i class="ri ri-{{icon}}"></i>
}
<span class="label">
{{ label }}
</span>
</button>
`,
styleUrl: './main-button.scss' styleUrl: './main-button.scss'
}) })
export class MainButton { export class MainButton {
@Input() disabled: boolean = false;
@Input() divider: boolean = false;
@Input() label: string = ''; @Input() label: string = '';
@Input() icon: string = ''; @Input() icon: string = '';
@Input() kind: ButtonKind = ''; @Input() inconPosition: inconPositionKindType = 'left';
@Input() size: ButtonSizeType = '';
@Input() kind: ButtonKindType = '';
} }

View file

@ -1,75 +0,0 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { ConversationItem } from './conversation-item';
import { moduleMetadata } from '@storybook/angular';
import { NgClass, NgIf, DatePipe } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ChatbotConversation } from '../../services/conversations.service';
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
const meta: Meta<ConversationItem> = {
title: 'composants/conversation/ConversationItem',
component: ConversationItem,
tags: ['autodocs'],
decorators: [
moduleMetadata({
imports: [NgClass, NgIf, DatePipe, FormsModule],
providers: []
})
],
argTypes: {
isActive: { control: 'boolean' },
onSelect: { action: 'selected' },
onShare: { action: 'shared' },
onRename: { action: 'renamed' },
onPin: { action: 'pinned' },
onDelete: { action: 'deleted' }
},
};
export default meta;
type Story = StoryObj<ConversationItem>;
// Create a mock conversation
const createMockConversation = (name: string, description: string, pinned: boolean = false): ChatbotConversation => {
const conversation = new ChatbotConversation();
conversation.name = name;
conversation.description = description;
conversation.pinned = pinned;
conversation.lastMessageDate = new Date();
return conversation;
};
// Default story
export const Default: Story = {
args: {
conversation: createMockConversation('Project Discussion', 'Latest updates on the project timeline'),
isActive: false
},
};
// Active conversation
export const Active: Story = {
args: {
conversation: createMockConversation('Project Discussion', 'Latest updates on the project timeline'),
isActive: true
},
};
// Pinned conversation
export const Pinned: Story = {
args: {
conversation: createMockConversation('Important Meeting', 'CEO quarterly update', true),
isActive: false
},
};
// Long name and description
export const LongContent: Story = {
args: {
conversation: createMockConversation(
'Very Long Conversation Name That Should Truncate',
'This is a very long description that should demonstrate how the component handles overflow text in the description area of the conversation item component',
),
isActive: false
},
};

View file

@ -1,186 +0,0 @@
import type { Meta, StoryObj } from '@storybook/angular';
import { moduleMetadata } from '@storybook/angular';
import { CommonModule } from '@angular/common';
import { MainButton } from '../../../../my-workspace/projects/sae-lib/buttons/main-button/main-button';
// More on how to set up stories at: https://storybook.js.org/docs/angular/writing-stories/introduction
const meta: Meta<MainButton> = {
title: 'composants/boutons/SaeMainButton',
component: MainButton,
tags: ['autodocs'],
decorators: [
moduleMetadata({
imports: [CommonModule],
providers: []
})
],
argTypes: {
label: { control: 'text' },
icon: { control: 'text' },
kind: {
control: 'select',
options: ['', 'primary', 'secondary', 'ghost', 'link'],
description: 'Style du bouton'
},
size: {
control: 'select',
options: ['', 'large', 'medium', 'small', 'extrasm'],
description: 'Taille du bouton'
},
inconPosition: {
control: 'select',
options: ['left', 'right'],
description: 'Position de l\'icône'
},
disabled: { control: 'boolean' },
divider: { control: 'boolean' }
},
};
export default meta;
type Story = StoryObj<MainButton>;
// More on writing stories with args: https://storybook.js.org/docs/angular/writing-stories/args
export const Primary: Story = {
args: {
label: 'Button',
icon: 'home-line',
kind: 'primary',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Secondary: Story = {
args: {
label: 'Secondary Button',
icon: 'settings-line',
kind: 'secondary',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Ghost: Story = {
args: {
label: 'Ghost Button',
icon: 'ghost-line',
kind: 'ghost',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Link: Story = {
args: {
label: 'Link Button',
icon: 'link',
kind: 'link',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Large: Story = {
args: {
label: 'Large Button',
icon: 'arrow-up-line',
kind: 'primary',
size: 'large',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Small: Story = {
args: {
label: 'Small Button',
icon: 'arrow-down-line',
kind: 'primary',
size: 'small',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const ExtraSmall: Story = {
args: {
label: 'Extra Small Button',
icon: 'arrow-left-line',
kind: 'primary',
size: 'extrasm',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const RightIcon: Story = {
args: {
label: 'Button with Right Icon',
icon: 'arrow-right-line',
kind: 'primary',
size: 'medium',
inconPosition: 'right',
disabled: false,
divider: false
},
};
export const WithoutIcon: Story = {
args: {
label: 'Button without icon',
icon: '',
kind: 'primary',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: false
},
};
export const Disabled: Story = {
args: {
label: 'Disabled Button',
icon: 'close-line',
kind: 'primary',
size: 'medium',
inconPosition: 'left',
disabled: true,
divider: false
},
};
export const WithDivider: Story = {
args: {
label: 'Button with Divider',
icon: 'menu-line',
kind: 'primary',
size: 'medium',
inconPosition: 'left',
disabled: false,
divider: true
},
};
export const GhostDisabled: Story = {
args: {
label: 'Disabled Ghost Button',
icon: 'ghost-line',
kind: 'ghost',
size: 'medium',
inconPosition: 'left',
disabled: true,
divider: false
},
};

View file

@ -25,31 +25,19 @@ We'll use a three-level hierarchy to organize our stories:
## Naming Convention ## Naming Convention
Story titles should follow this pattern: Story titles should follow this pattern:
``` ```
{Top-level}/{Sub-category}/{ComponentName} {Top-level}/{Sub-category}/{ComponentName}
``` ```
For example: For example:
- `UI/Buttons/MainButton` - `UI/Buttons/MainButton`
- `UI/Feedback/AlertBox` - `UI/Feedback/AlertBox`
- `Chatbot/Conversation/ConversationItem` - `Chatbot/Conversation/ConversationItem`
- `Chatbot/Messages/MessageBox` - `Chatbot/Messages/MessageBox`
- `Design/Colors/ColorDisplay` - `Design/Colors/ColorDisplay`
## Examples of New Category Structure
| Current Title | New Title |
|---------------|-----------|
| UI/Buttons/MainButton | composants/boutons/MainButton |
| UI/Buttons/ToggleButton | composants/boutons/ToggleButton |
| UI/Inputs/PromptInput | composants/inputs/PromptInput |
| UI/Feedback/AlertBox | composants/feedback/AlertBox |
| Design/Colors/ColorDisplay | fondations/couleurs/ColorDisplay |
| UI/Navigation/Navbar | patterns/breadcrumbs/Navbar |
| Chatbot/Conversation/ConversationItem | composants/conversation/ConversationItem |
| Chatbot/Actions/ExportChatButton | composants/boutons/ExportChatButton |
| Chatbot/Messages/MessageBox | composants/conversation/MessageBox |
## Implementation ## Implementation
To change a component's category, update the `title` property in its story file: To change a component's category, update the `title` property in its story file:
@ -63,6 +51,7 @@ const meta: Meta<MyComponent> = {
``` ```
This new structure will make it easier to: This new structure will make it easier to:
1. Find related components 1. Find related components
2. Understand the purpose and context of each component 2. Understand the purpose and context of each component
3. Maintain a consistent organization as the component library grows 3. Maintain a consistent organization as the component library grows

View file

@ -1,153 +0,0 @@
/**
* Script to update Storybook story categories according to the new hierarchical structure
*
* Usage:
* 1. Run with Node.js: node update-story-categories.js
* 2. The script will scan all .stories.ts files and suggest category updates
* 3. You can review and apply the changes
*/
const fs = require('fs');
const path = require('path');
const {execSync} = require('child_process');
// Define the mapping from old categories to new categories
const categoryMapping = {
// UI Components to composants/boutons
'UI/Buttons/ExportChatButton': 'composants/boutons/ExportChatButton',
'UI/Buttons/MainButton': 'composants/boutons/MainButton',
'UI/Buttons/ToggleButton': 'composants/boutons/ToggleButton',
'Chatbot/Actions/ExportChatButton': 'composants/boutons/ExportChatButton',
'Components/Buttons/ExportChatButton': 'composants/boutons/ExportChatButton',
'Components/MainButton': 'composants/boutons/MainButton',
'Components/ToggleButton': 'composants/boutons/ToggleButton',
'Components/FeedbackButton': 'composants/boutons/FeedbackButton',
// UI Feedback to composants/feedback
'UI/Feedback/AlertBox': 'composants/feedback/AlertBox',
'UI/Feedback/FeedbackButton': 'composants/boutons/FeedbackButton',
'Components/AlertBox': 'composants/feedback/AlertBox',
// Design to fondations
'Design/Colors/ColorDisplay': 'fondations/couleurs/ColorDisplay',
'Design/Brand/Logo': 'fondations/brand/Logo',
'Components/Logo': 'fondations/brand/Logo',
'Components/ColorDisplay': 'fondations/couleurs/ColorDisplay',
// UI Navigation to patterns/breadcrumbs
'UI/Navigation/Navbar': 'patterns/breadcrumbs/Navbar',
'Navigation/DsNavbar': 'patterns/breadcrumbs/Navbar',
// Chatbot Components to composants
'Chatbot/Conversation/ConversationItem': 'composants/conversation/ConversationItem',
'Chatbot/Feedback/WarningBugs': 'composants/feedback/WarningBugs',
'Chatbot/Messages/MessageBox': 'composants/conversation/MessageBox',
'Chatbot/Input/PromptInput': 'composants/inputs/PromptInput',
'Chatbot/Input/NewInput': 'composants/inputs/NewInput',
'Chatbot/Sources/SourceBlock': 'composants/conversation/SourceBlock',
'Chatbot/ConversationItem': 'composants/conversation/ConversationItem',
'Chatbot/WarningBugs': 'composants/feedback/WarningBugs',
'Components/MessageBox': 'composants/conversation/MessageBox',
'Components/PromptInput': 'composants/inputs/PromptInput',
'Components/NewInput': 'composants/inputs/NewInput',
'Components/SourceBlock': 'composants/conversation/SourceBlock',
// App
'App/Features/Chatbot': 'composants/conversation/Chatbot',
'App/Chatbot': 'composants/conversation/Chatbot',
};
// Find all story files
const findStoryFiles = () => {
try {
const result = execSync(
'find /home/poule/encrypted/stockage-syncable/www/development/html/ng-implementation/airwatch/src -name "*.stories.ts"'
).toString();
return result.split('\n').filter(Boolean);
} catch (error) {
console.error('Error finding story files:', error);
return [];
}
};
// Extract current category from a story file
const extractCurrentCategory = (filePath) => {
try {
const content = fs.readFileSync(filePath, 'utf8');
const match = content.match(/title:\s*['"]([^'"]+)['"]/);
return match ? match[1] : null;
} catch (error) {
console.error(`Error reading file ${filePath}:`, error);
return null;
}
};
// Update category in a story file
const updateCategory = (filePath, oldCategory, newCategory) => {
try {
let content = fs.readFileSync(filePath, 'utf8');
content = content.replace(
`title: '${oldCategory}'`,
`title: '${newCategory}'`
);
fs.writeFileSync(filePath, content, 'utf8');
console.log(`✅ Updated ${filePath}: ${oldCategory} -> ${newCategory}`);
return true;
} catch (error) {
console.error(`Error updating file ${filePath}:`, error);
return false;
}
};
// Main function
const main = () => {
console.log('🔍 Finding story files...');
const storyFiles = findStoryFiles();
console.log(`Found ${storyFiles.length} story files.`);
let updated = 0;
let skipped = 0;
let notMapped = 0;
storyFiles.forEach(filePath => {
const currentCategory = extractCurrentCategory(filePath);
if (!currentCategory) {
console.log(`⚠️ Could not extract category from ${filePath}`);
skipped++;
return;
}
const newCategory = categoryMapping[currentCategory];
if (!newCategory) {
console.log(` No mapping defined for category: ${currentCategory} in ${filePath}`);
notMapped++;
return;
}
if (currentCategory === newCategory) {
console.log(` Category already up to date: ${currentCategory} in ${filePath}`);
skipped++;
return;
}
const success = updateCategory(filePath, currentCategory, newCategory);
if (success) {
updated++;
} else {
skipped++;
}
});
console.log('\n📊 Summary:');
console.log(`Total files: ${storyFiles.length}`);
console.log(`Updated: ${updated}`);
console.log(`Skipped: ${skipped}`);
console.log(`Not mapped: ${notMapped}`);
if (notMapped > 0) {
console.log('\n⚠ Some categories were not mapped. Please update the categoryMapping object in the script.');
}
};
// Run the script
main();

View file

@ -10,7 +10,8 @@
button { button {
background: shadows.$primary-color;
background: transparent;
color: shadows.$neutral-white; color: shadows.$neutral-white;
border-radius: shadows.$radius-main; border-radius: shadows.$radius-main;
padding: 1rem 2rem; padding: 1rem 2rem;
@ -81,6 +82,11 @@
background: var(--Hover, linear-gradient(70deg, #073A7C 43.99%, #1767AD 94.38%, #255B8E 126.68%)); background: var(--Hover, linear-gradient(70deg, #073A7C 43.99%, #1767AD 94.38%, #255B8E 126.68%));
} }
&:focus {
border: 3px solid var(--Colors-Principal-100, #96BEE4);
background: var(--Gradient, linear-gradient(77deg, #073A7C -4.23%, #1767AD 51.8%, #255B8E 87.72%));
}
&.is-disabled { &.is-disabled {
background-color: #BED7EE; background-color: #BED7EE;
color: white; color: white;

View file

@ -1,23 +1,60 @@
<div [ngClass]="{highlighted, 'is-disabled': disabled}" 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($event, 'engineType')"
(selectedChoicesChange)="onSelectedChoicesChange" (selectedChoicesChange)="onSelectedChoicesChange($event, 'engineType')"
[actionTypes]="actionTypes" [actionTypes]="actionTypes"
[availableChoices]="appState.filters.engineType.availableChoices" [availableChoices]="appState.filters?.engineType?.availableChoices || []"
[disabled]="disabled" [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
(availableChoicesChange)="onAvailableChoicesChange($event, 'findings')"
(selectedChoicesChange)="onSelectedChoicesChange($event, 'findings')"
[actionTypes]="actionTypes"
[label]="'Findings'" [label]="'Findings'"
[selectedChoices]="[]" [selectedChoices]="appState.filters?.findings?.selectedChoices || []"
[availableChoices]="appState.filters?.findings?.availableChoices || []"
[store]="store"
></sae-multi-selector>
<sae-multi-selector
(availableChoicesChange)="onAvailableChoicesChange($event, 'ata')"
(selectedChoicesChange)="onSelectedChoicesChange($event, 'ata')"
[actionTypes]="actionTypes"
[label]="'ATA'"
[selectedChoices]="appState.filters?.ata?.selectedChoices || []"
[availableChoices]="appState.filters?.ata?.availableChoices || []"
[store]="store"
></sae-multi-selector>
<sae-multi-selector
(availableChoicesChange)="onAvailableChoicesChange($event, 'partNumber')"
(selectedChoicesChange)="onSelectedChoicesChange($event, 'partNumber')"
[actionTypes]="actionTypes"
[label]="'Part number'"
[selectedChoices]="appState.filters?.partNumber?.selectedChoices || []"
[availableChoices]="appState.filters?.partNumber?.availableChoices || []"
[store]="store"
></sae-multi-selector>
<sae-multi-selector
(availableChoicesChange)="onAvailableChoicesChange($event, 'technicalManual')"
(selectedChoicesChange)="onSelectedChoicesChange($event, 'technicalManual')"
[actionTypes]="actionTypes"
[label]="'Technical Manual'"
[selectedChoices]="appState.filters?.technicalManual?.selectedChoices || []"
[availableChoices]="appState.filters?.technicalManual?.availableChoices || []"
[store]="store"
></sae-multi-selector>
<sae-multi-selector
(availableChoicesChange)="onAvailableChoicesChange($event, 'wingStatus')"
(selectedChoicesChange)="onSelectedChoicesChange($event, 'wingStatus')"
[actionTypes]="actionTypes"
[label]="'On-wing/off-wing'"
[selectedChoices]="appState.filters?.wingStatus?.selectedChoices || []"
[availableChoices]="appState.filters?.wingStatus?.availableChoices || []"
[store]="store"
></sae-multi-selector> ></sae-multi-selector>
<sae-multi-selector [label]="'ATA'"></sae-multi-selector>
<sae-multi-selector [label]="'Part number'"></sae-multi-selector>
<sae-multi-selector [label]="'Technical Manual'"></sae-multi-selector>
<sae-multi-selector [label]="'On-wing/off-wing'"></sae-multi-selector>
</div> </div>
<div (click)="highlighted = !highlighted" class="chips-listing"> <div (click)="highlighted = !highlighted" class="chips-listing">
<!-- liste de chips--> <!-- liste de chips-->

View file

@ -24,11 +24,29 @@ export class FiltersGroup {
console.log('constructor filters group', this.appState, this.store, this.actionTypes); console.log('constructor filters group', this.appState, this.store, this.actionTypes);
} }
onSelectedChoicesChange(e: any) { onSelectedChoicesChange(choice: any, filterType: string) {
console.log('onSelectedChoicesChange', e); console.log('onSelectedChoicesChange', choice, 'for filter', filterType);
if (this.store && this.actionTypes) {
this.store.dispatch({
type: this.actionTypes.UPDATE_FILTER,
payload: {
filter: filterType,
selectedChoice: choice
}
});
}
} }
onAvailableChoicesChange(e: any) { onAvailableChoicesChange(choice: any, filterType: string) {
console.log('onSelectedChoicesChange', e); console.log('onAvailableChoicesChange', choice, 'for filter', filterType);
if (this.store && this.actionTypes) {
this.store.dispatch({
type: this.actionTypes.UPDATE_FILTER,
payload: {
filter: filterType,
availableChoice: choice
}
});
}
} }
} }

View file

@ -16,7 +16,7 @@ export class MultiSelector {
// @Input() ActionTypes: any; // @Input() ActionTypes: any;
@Input() availableChoices: any = ['choix 1', 'choix 2', 'choix 3']; @Input() availableChoices: any = ['choix 1', 'choix 2', 'choix 3'];
@Input() selectedChoices: any = ['choix 4', 'choix 5']; @Input() selectedChoices: any = ['choix 4', 'choix 5'];
@Input() displayDropdown: boolean = false; @Input() displayDropdown: boolean = true;
@Input() store: any; @Input() store: any;
@Input() actionTypes: any; @Input() actionTypes: any;

View file

@ -1 +1 @@
prefix=/home/tykayn/.npm-global #prefix=/home/tykayn/.npm-global

View file

@ -22,12 +22,12 @@ export const initialState: StateInterface = {
engineType: { engineType: {
availableList: [{ availableList: [{
label: 'choix 1', label: 'ABC',
value: 'choix 1', value: 'ABC',
}], }],
selectedList: [{ selectedList: [{
label: 'choix 2', label: 'DEF',
value: 'choix 2', value: 'DEF',
}] }]
}, },
findings: { findings: {