Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@ import { PoPopupAction } from '../po-popup/po-popup-action.interface';
*
* @usedBy PoDropdownComponent
*/
export interface PoDropdownAction extends PoPopupAction {}
export interface PoDropdownAction extends PoPopupAction {
/**
* Array de ações (`PoDropdownAction`) usado para criar agrupadores de subitens.
*
* - Permite a criação de menus aninhados (submenus).
*
* > Boas práticas de desenvolvimento:
* Recomenda-se limitar a navegação a, no máximo, três níveis hierárquicos.
* Isso evita sobrecarga cognitiva, facilita a memorização da estrutura e garante uma melhor experiência de uso.
*/
subItems?: Array<PoDropdownAction>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
[p-custom-positions]="['bottom-left', 'top-left']"
[p-size]="size"
[p-target]="dropdownRef"
[p-listbox-subitems]="true"
>
</po-popup>
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import { PoDropdownBaseComponent } from './po-dropdown-base.component';
* <file name="sample-po-dropdown-basic/sample-po-dropdown-basic.component.ts"> </file>
* </example>
*
* <example name="po-dropdown-subitems" title="PO Dropdown Subitems" >
* <file name="sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.html"> </file>
* <file name="sample-po-dropdown-subitems/sample-po-dropdown-subitems.component.ts"> </file>
* </example>
*
* <example name="po-dropdown-labs" title="PO Dropdown Labs" >
* <file name="sample-po-dropdown-labs/sample-po-dropdown-labs.component.html"> </file>
* <file name="sample-po-dropdown-labs/sample-po-dropdown-labs.component.ts"> </file>
Expand Down Expand Up @@ -59,7 +64,7 @@ export class PoDropdownComponent extends PoDropdownBaseComponent {
}

private checkClickArea(event: MouseEvent) {
return this.dropdownRef && this.dropdownRef.nativeElement.contains(event.target);
return this.dropdownRef?.nativeElement.contains(event.target);
}

private hideDropdown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,28 @@
<po-divider />

<form #formAction="ngForm">
<po-input class="po-md-6 po-lg-4" name="actionAction" [(ngModel)]="action.action" p-clean p-label="Action">
<po-input class="po-md-6 po-lg-4" name="actionLabel" [(ngModel)]="action.label" p-label="Label" p-required>
</po-input>

<po-input class="po-md-6 po-lg-4" name="actionLabel" [(ngModel)]="action.label" p-label="Label" p-required>
<po-input class="po-md-6 po-lg-4" name="actionAction" [(ngModel)]="action.action" p-clean p-label="Action">
</po-input>

<po-input class="po-md-6 po-lg-4" name="actionURL" [(ngModel)]="action.url" p-label="URL"> </po-input>

<po-select class="po-md-6 po-lg-3" name="type" [(ngModel)]="action.type" p-label="Type" [p-options]="typeOptions">
<po-select class="po-md-6 po-lg-4" name="type" [(ngModel)]="action.type" p-label="Type" [p-options]="typeOptions">
</po-select>

<po-select class="po-md-6 po-lg-3" name="icon" [(ngModel)]="action.icon" p-label="Icon" [p-options]="iconOptions">
<po-select class="po-md-6 po-lg-4" name="icon" [(ngModel)]="action.icon" p-label="Icon" [p-options]="iconOptions">
</po-select>

<po-select
class="po-md-6 po-lg-4"
name="parent"
[(ngModel)]="action.parent"
p-label="Subitems"
p-placeholder="Add subitems"
[p-options]="parentList"
>
</po-select>

<po-checkbox-group
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import {
export class SamplePoDropdownLabsComponent implements OnInit {
private poNotification = inject(PoNotificationService);

action: PoDropdownAction;
action: PoDropdownAction & { parent?: string };
actions: Array<PoDropdownAction>;
parentList: Array<PoSelectOption>;
label: string;
properties: Array<string>;
size: string;
Expand Down Expand Up @@ -52,16 +53,72 @@ export class SamplePoDropdownLabsComponent implements OnInit {
this.restore();
}

addAction(action: PoDropdownAction) {
const newAction = Object.assign({}, action);
addAction(action: PoDropdownAction & { parent?: string }) {
const newAction: PoDropdownAction = { ...action };
newAction.action = newAction.action ? this.showAction.bind(this, newAction.action) : undefined;
this.actions.push(newAction);

if (!action.parent) {
this.actions = [...this.actions, newAction];
} else {
const parentNode = this.getActionNode(this.actions, action.parent);
if (parentNode) {
parentNode.subItems = [...(parentNode.subItems || []), newAction];
} else {
this.actions = [...this.actions, newAction];
}
}

this.actions = [].concat(this.actions);
this.parentList = this.updateParentList(this.actions);

this.restoreActionForm();
}

private getActionNode(items: Array<PoDropdownAction>, value: string): PoDropdownAction | undefined {
if (!items || !Array.isArray(items) || !value) {
return undefined;
}

for (const item of items) {
if (item.label === value || (item as any).value === value) {
return item;
}

if (item.subItems && Array.isArray(item.subItems)) {
const found = this.getActionNode(item.subItems, value);
if (found) {
return found;
}
}
}

return undefined;
}

private updateParentList(
items: Array<PoDropdownAction>,
level = 0,
parentList: Array<PoSelectOption> = []
): Array<PoSelectOption> {
if (!items || !Array.isArray(items)) {
return parentList;
}

items.forEach(item => {
const { label } = item;
parentList.push({ label: `${'-'.repeat(level)} ${label}`, value: label });

if (item.subItems && Array.isArray(item.subItems)) {
this.updateParentList(item.subItems, level + 1, parentList);
}
});

return parentList;
}

restore() {
this.actions = [];
this.parentList = [];
this.label = 'PO Dropdown';
this.size = 'medium';
this.properties = [];
Expand All @@ -71,8 +128,9 @@ export class SamplePoDropdownLabsComponent implements OnInit {
restoreActionForm() {
this.action = {
label: undefined,
visible: null
};
visible: null,
parent: undefined
} as any;
}

showAction(label: string): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<po-dropdown p-label="PO Dropdown" [p-actions]="actions"> </po-dropdown>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Component } from '@angular/core';
import { PoDropdownAction } from '@po-ui/ng-components';

@Component({
selector: 'sample-po-dropdown-subitems',
templateUrl: './sample-po-dropdown-subitems.component.html',
standalone: false
})
export class SamplePoDropdownSubitemsComponent {
actions: Array<PoDropdownAction> = [
{ label: 'New Sale', action: () => console.log('New Sale') },
{ label: 'New Cancellation', action: () => console.log('New Cancellation'), type: 'danger' },
{
label: 'Reports',
subItems: [
{ label: 'Monthly Sales', action: () => console.log('Monthly Sales'), icon: 'an an-chart-line-up' },
{ label: 'Annual Sales', action: () => console.log('Annual Sales'), icon: 'an an-chart-line-up' }
]
},
{
label: 'Settings',
subItems: [
{ label: 'Users', action: () => console.log('Users') },
{
label: 'System',
subItems: [
{ label: 'Backup', action: () => console.log('Backup') },
{ label: 'Logs', action: () => console.log('Logs') }
]
}
]
}
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Interface para definição de literais utilizadas no `po-listbox`
*/
export interface PoListBoxLiterals {
/** Texto do botão para voltar ao agrupador anterior. */
backToPreviousGroup?: string;

/** Texto exibido quando não houver itens na lista */
noItems?: string;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ export class PoItemListBaseComponent {
@Input('p-label') label: string;

/** Tamanho do texto exibido. */
@Input('p-size') size: string;
@HostBinding('attr.p-size')
@Input('p-size')
size: string;

/** Valor do item. */
@Input('p-value') value: string;
Expand Down Expand Up @@ -118,6 +120,9 @@ export class PoItemListBaseComponent {
*/
@Input('p-icon') icon: string | TemplateRef<void>;

// Define a posição do ícone: 'left' (padrão) ou 'right'.
@Input('p-icon-position') iconPosition: 'left' | 'right' = 'left';

/**
* @optional
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@
[class.po-item-list__danger]="danger"
class="po-item-list po-item-list__action"
>
@if (icon) {
<po-icon class="po-popup-icon-item" [p-icon]="icon"></po-icon>
@if (icon && iconPosition === 'left') {
<po-icon
class="po-popup-icon-item po-field-icon"
[class.po-field-icon-aa]="size === 'small'"
[p-icon]="icon"
></po-icon>
}
<span class="po-item-list-label">{{ label }}</span>

@if (icon && iconPosition === 'right') {
<po-icon class="po-popup-icon-item-right po-field-icon" [p-icon]="icon"></po-icon>
}
</div>
}
@case ('option') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Directive, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
import { Directive, EventEmitter, HostBinding, Input, Output, TemplateRef } from '@angular/core';

import { poLocaleDefault } from '../../services/po-language/po-language.constant';
import { PoLanguageService } from '../../services/po-language/po-language.service';
Expand All @@ -14,15 +14,19 @@ import { PoItemListOption } from './po-item-list/interfaces/po-item-list-option.

export const poListBoxLiteralsDefault = {
en: <PoListBoxLiterals>{
backToPreviousGroup: 'Go back to the previous list',
noItems: 'No items found'
},
es: <PoListBoxLiterals>{
backToPreviousGroup: 'Volver a la lista anterior',
noItems: 'No se encontraron artículos'
},
pt: <PoListBoxLiterals>{
backToPreviousGroup: 'Voltar para a lista anterior',
noItems: 'Nenhum item encontrado'
},
ru: <PoListBoxLiterals>{
backToPreviousGroup: 'Вернуться к предыдущему списку',
noItems: 'ничего не найдено'
}
};
Expand All @@ -39,6 +43,8 @@ export class PoListBoxBaseComponent {
private language: string = poLocaleDefault;
private _size?: string = undefined;

@Input('p-listbox-subitems') listboxSubitems = false;

@Input({ alias: 'p-visible', transform: convertToBoolean }) visible: boolean = false;

@Input('p-type') set type(value: string) {
Expand Down Expand Up @@ -82,22 +88,6 @@ export class PoListBoxBaseComponent {
// parâmetro que pode ser passado para o popup ao clicar em um item
@Input('p-param') param?;

@Output('p-select-item') selectItem = new EventEmitter<PoItemListOption | PoItemListOptionGroup | any>();

@Output('p-close') closeEvent = new EventEmitter<any>();
// MULTISELECT PROPERTIES

//output para evento do checkbox
@Output('p-change') change = new EventEmitter();

//output para evento do checkbox
@Output('p-selectcombo-item') selectCombo = new EventEmitter();

//output para evento do checkbox de selecionar todos
@Output('p-change-all') changeAll = new EventEmitter();

@Output('p-update-infinite-scroll') UpdateInfiniteScroll = new EventEmitter();

//valor do checkbox de selecionar todos
@Input('p-checkboxAllValue') checkboxAllValue: any;

Expand All @@ -111,9 +101,6 @@ export class PoListBoxBaseComponent {

@Input('p-field-label') fieldLabel: string = 'label';

// Evento disparado a cada tecla digitada na pesquisa.
@Output('p-change-search') changeSearch = new EventEmitter();

// Propriedade que recebe as literais definidas no componente `po-multiselect`.
@Input('p-literal-search') literalSearch?: any;

Expand Down Expand Up @@ -151,7 +138,9 @@ export class PoListBoxBaseComponent {

@Input('p-should-mark-letter') shouldMarkLetters: boolean = true;

@Input('p-size') set size(value: string) {
@HostBinding('attr.p-size')
@Input('p-size')
set size(value: string) {
this._size = validateSizeFn(value, PoFieldSize);
}

Expand All @@ -177,6 +166,25 @@ export class PoListBoxBaseComponent {
// Define se haverá ou não um separador entre todos os itens do listbox
@Input('p-separator') separator: boolean = false;

// Evento disparado a cada tecla digitada na pesquisa.
@Output('p-change-search') changeSearch = new EventEmitter();

@Output('p-select-item') selectItem = new EventEmitter<PoItemListOption | PoItemListOptionGroup | any>();

@Output('p-close') closeEvent = new EventEmitter<any>();
// MULTISELECT PROPERTIES

//output para evento do checkbox
@Output('p-change') change = new EventEmitter();

//output para evento do checkbox
@Output('p-selectcombo-item') selectCombo = new EventEmitter();

//output para evento do checkbox de selecionar todos
@Output('p-change-all') changeAll = new EventEmitter();

@Output('p-update-infinite-scroll') UpdateInfiniteScroll = new EventEmitter();

// Evento disparado quando uma tab é ativada
@Output('p-activated-tabs') activatedTab = new EventEmitter();

Expand Down
Loading