Skip to content
Draft
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
8 changes: 8 additions & 0 deletions showcase/app/components/mock/app/index.gts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import MockAppSidebarOldSideNav from './sidebar/side-nav';
import MockAppMainPageHeader from './main/page-header';
import MockAppMainGenericTextContent from './main/generic-text-content';
import MockAppMainGenericAdvancedTable from './main/generic-advanced-table';
import MockAppMainGenericDropdownFilter from './main/generic-filter/generic-dropdown-filter';
import MockAppMainGenericSuperSelectFilter from './main/generic-filter/generic-super-select-filter';
import MockAppFooterAppFooter from './footer/app-footer';

// HDS components
Expand All @@ -25,6 +27,8 @@ import type { MockAppSidebarOldSideNavSignature } from './sidebar/side-nav';
import type { MockAppMainPageHeaderSignature } from './main/page-header';
import type { MockAppMainGenericTextContentSignature } from './main/generic-text-content';
import type { MockAppMainGenericAdvancedTableSignature } from './main/generic-advanced-table';
import type { MockAppMainGenericDropdownFilterSignature } from './main/generic-filter/generic-dropdown-filter';
import type { MockAppMainGenericSuperSelectFilterSignature } from './main/generic-super-select-filter';
import type { MockAppFooterAppFooterSignature } from './footer/app-footer';

export interface MockAppSignature {
Expand Down Expand Up @@ -52,6 +56,8 @@ export interface MockAppSignature {
PageHeader?: ComponentLike<MockAppMainPageHeaderSignature>;
GenericTextContent?: ComponentLike<MockAppMainGenericTextContentSignature>;
GenericAdvancedTable?: ComponentLike<MockAppMainGenericAdvancedTableSignature>;
GenericDropdownFilter?: ComponentLike<MockAppMainGenericDropdownFilterSignature>;
GenericSuperSelectFilter?: ComponentLike<MockAppMainGenericSuperSelectFilterSignature>;
},
];
footer?: [
Expand Down Expand Up @@ -98,6 +104,8 @@ export default class MockApp extends Component<MockAppSignature> {
PageHeader=MockAppMainPageHeader
GenericTextContent=MockAppMainGenericTextContent
GenericAdvancedTable=MockAppMainGenericAdvancedTable
GenericDropdownFilter=MockAppMainGenericDropdownFilter
GenericSuperSelectFilter=MockAppMainGenericSuperSelectFilter
)
to="main"
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { on } from '@ember/modifier';
import type { WithBoundArgs } from '@glint/template';

import type { Filter } from './index';

// HDS components
import { HdsDropdownListItemCheckbox } from '@hashicorp/design-system-components/components';

import type { HdsDropdownSignature } from '@hashicorp/design-system-components/components/hds/dropdown/index';

export interface MockAppMainGenericFilterBarCheckboxSignature {
Args: HdsDropdownSignature['Args'] & {
checkbox?: WithBoundArgs<typeof HdsDropdownListItemCheckbox, never>;
value?: string;
keyFilter: Filter[] | Filter | undefined;
onChange?: (event: Event) => void;
};
Blocks: {
default: [];
};
Element: HTMLDivElement;
}

export default class MockAppMainGenericFilterBarCheckbox extends Component<MockAppMainGenericFilterBarCheckboxSignature> {
@action
onChange(event: Event): void {
const { onChange } = this.args;
if (onChange && typeof onChange === 'function') {
onChange(event);
}
}

get isChecked(): boolean {
const { keyFilter, value } = this.args;
if (Array.isArray(keyFilter)) {
return keyFilter.some((filter) => filter.value === value);
} else if (keyFilter && value) {
return keyFilter.value === value;
}
return false;
}

<template>
{{#let @checkbox as |Checkbox|}}
<Checkbox
checked={{this.isChecked}}
@value={{@value}}
{{on "change" this.onChange}}
>
{{yield}}
</Checkbox>
{{/let}}
</template>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import Component from '@glimmer/component';
import { action } from '@ember/object';
import { hash } from '@ember/helper';
import { tracked } from '@glimmer/tracking';
import { on } from '@ember/modifier';
import { modifier } from 'ember-modifier';
import type { WithBoundArgs } from '@glint/template';

import MockAppMainGenericFilterBarCheckbox from './checkbox';
import MockAppMainGenericFilterBarRadio from './radio';

// HDS components
import {
HdsButton,
HdsButtonSet,
HdsDropdown,
HdsDropdownToggleButton,
} from '@hashicorp/design-system-components/components';

import type { Filters, Filter } from './index';
import type { HdsDropdownSignature } from '@hashicorp/design-system-components/components/hds/dropdown/index';

export interface MockAppMainGenericFilterBarDropdownSignature {
Args: HdsDropdownSignature['Args'] & {
dropdown?: WithBoundArgs<typeof HdsDropdown, never>;
key: string;
filters: Filters;
isMultiSelect?: boolean;
isLiveFilter?: boolean;
onChange: (key: string, keyFilter?: Filter[]) => void;
};
Blocks: {
default: [
{
ToggleButton?: WithBoundArgs<
typeof HdsDropdownToggleButton,
'color' | 'text'
>;
Checkbox?: WithBoundArgs<
typeof MockAppMainGenericFilterBarCheckbox,
'checkbox' | 'keyFilter' | 'onChange'
>;
Radio?: WithBoundArgs<
typeof MockAppMainGenericFilterBarRadio,
'radio' | 'keyFilter' | 'onChange'
>;
},
];
};
Element: HTMLDivElement;
}

export default class MockAppMainGenericFilterBarDropdown extends Component<
HdsDropdownSignature & MockAppMainGenericFilterBarDropdownSignature
> {
@tracked internalFilters: Filter[] | Filter | undefined = [];

private _updateInternalFilters = modifier(() => {
this.internalFilters = this.keyFilter;
});

get keyFilter(): Filter[] | Filter | undefined {
const { filters, key } = this.args;

if (!filters) {
return undefined;
}
return filters[key];
}

@action
onChange(event: Event): void {
const addFilter = (value: unknown): Filter[] => {
const newFilter = {
text: value as string,
value: value,
};
if (
Array.isArray(this.internalFilters) &&
input.classList.contains('hds-form-checkbox')
) {
this.internalFilters.push(newFilter);
return this.internalFilters;
} else {
return [newFilter];
}
};

const removeFilter = (value: string): Filter[] => {
const newFilter = [] as Filter[];
if (Array.isArray(this.internalFilters)) {
this.internalFilters.forEach((filter) => {
if (filter.value != value) {
newFilter.push(filter);
}
});
}
return newFilter;
};

const input = event.target as HTMLInputElement;

let newFilter = [] as Filter[];

if (input.checked) {
newFilter = addFilter(input.value);
} else {
newFilter = removeFilter(input.value);
}

this.internalFilters = newFilter;

if (this.args.isLiveFilter) {
const { onChange } = this.args;
if (onChange && typeof onChange === 'function') {
if (newFilter.length === 0) {
onChange(this.args.key, undefined);
} else {
onChange(this.args.key, newFilter);
}
}
}
}

@action
onApply(): void {
const { onChange } = this.args;
if (onChange && typeof onChange === 'function') {
onChange(this.args.key, this.internalFilters);
}
}

@action
onClear(): void {
this.internalFilters = [];

const { onChange } = this.args;
if (onChange && typeof onChange === 'function') {
onChange(this.args.key, this.internalFilters);
}
}

<template>
{{! @glint-nocheck }}
<HdsDropdown
@listPosition="bottom-left"
@height="200px"
{{this._updateInternalFilters}}
as |D|
>
{{yield
(hash
ToggleButton=(component D.ToggleButton text=@text color="secondary")
Checkbox=(component
MockAppMainGenericFilterBarCheckbox
checkbox=D.Checkbox
keyFilter=this.internalFilters
onChange=this.onChange
)
Radio=(component
MockAppMainGenericFilterBarRadio
radio=D.Radio
keyFilter=this.internalFilters
onChange=this.onChange
)
)
}}
{{#unless @isLiveFilter}}
<D.Footer @hasDivider={{true}}>
<HdsButtonSet>
<HdsButton
@text="Apply filters"
@isFullWidth={{true}}
@size="small"
{{on "click" this.onApply}}
/>
<HdsButton
@text="Clear"
@color="secondary"
@size="small"
{{on "click" this.onClear}}
/>
</HdsButtonSet>
</D.Footer>
{{/unless}}
</HdsDropdown>
</template>
}
Loading
Loading