Skip to content

RcFilterPanel Component #14406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 71 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
eb1e730
app card component
Apr 28, 2025
6246cc4
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
Apr 28, 2025
1ca5301
cover upgradable and installed statuses
Apr 28, 2025
5d0cb11
support tags
Apr 28, 2025
c2a25b8
comment out handle clicks
Apr 29, 2025
ffe5c98
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
Apr 29, 2025
95363c7
add matching chart logic
Apr 30, 2025
cf6597c
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
Apr 30, 2025
497cb0f
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
Apr 30, 2025
790d6f7
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
May 1, 2025
0805c2f
add unit tests
May 1, 2025
4180302
add unit tests for chart model
May 1, 2025
321fe3a
fix e2e tests
May 1, 2025
6a694b4
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
May 1, 2025
3737050
fix e2e test
May 1, 2025
d5fa36d
add secondary text link in css
May 2, 2025
ae5868b
Merge branch 'master' of github.com:rancher/dashboard into 14198-app-…
May 4, 2025
1084fa9
Merge branch 'master' of github.com:rancher/dashboard into 14244-app-…
May 6, 2025
920a77c
Merge branch 'master' of github.com:rancher/dashboard into 14244-app-…
May 8, 2025
44b8721
Merge branch 'master' of github.com:rancher/dashboard into 14244-app-…
May 9, 2025
cadcc6a
change AppCard to a generic ItemCard
May 9, 2025
4594a94
continue making itemcard more generic
May 13, 2025
c1a82fc
fix reference issue
May 13, 2025
fba0a71
title slot + variant styling
May 13, 2025
6d632de
code cleanup + minor refactor
May 13, 2025
baa13ca
new icons
May 13, 2025
e747ae5
update icon lib + minor refactor and styling
May 14, 2025
9809c98
unit tests
May 15, 2025
07b17e7
more unit tests for chart model
May 15, 2025
8c6dc9b
refactor some slots + finishing touches
May 15, 2025
ac70cde
some accessibility updates
May 15, 2025
7acaa2c
Merge branch 'master' of github.com:rancher/dashboard into 14244-item…
May 15, 2025
67eed80
minor styling
May 15, 2025
b433e30
move image div inside slot
May 15, 2025
6294c95
uncomment e2e tests
May 15, 2025
7145f20
fix charts selector
May 16, 2025
657a7bf
fix test
May 16, 2025
e95bf1a
fix statuses alignment
May 16, 2025
874f6fc
more robust header styling
May 16, 2025
82ff141
remove PropType
May 16, 2025
3e73f24
updated translation key
May 16, 2025
ed66ac1
update key
May 16, 2025
c4ea3a2
rename
May 16, 2025
3aa0bb1
improve aria labels + minor cleanup
May 16, 2025
edb89bf
fix import
May 16, 2025
b2d417e
replace deep targetting lazyimage css with style attr
May 20, 2025
1ea0ddd
remove deep for actions + fix small header alignment
May 20, 2025
c841cee
rename component
May 20, 2025
4029fa5
remove extra check
May 21, 2025
4897e54
add comments
May 21, 2025
14b5fe7
add comments to model
May 21, 2025
5091bd6
Merge branch 'master' of github.com:rancher/dashboard into 14244-item…
May 21, 2025
9972b6b
use id instead of chartName
May 23, 2025
5908ca4
Merge branch 'master' of github.com:rancher/dashboard into 14244-item…
May 23, 2025
ef8a36d
remove todos
May 25, 2025
0bbdd08
fix matching app logic not including the latest version
May 27, 2025
22d2694
create RcFilterPanel component and use it in charts page
May 28, 2025
2c3a3d7
Merge branch 'master' of github.com:rancher/dashboard into 14244-item…
May 28, 2025
9d44466
Merge branch '14244-item-card' of github.com:momesgin/dashboard into …
May 28, 2025
92b6486
fix repo click + minor styling
May 29, 2025
d6e9ce7
update checkbox styling + fix unnecessary render for extra slot
May 29, 2025
6f62b15
revert checkbox styling changes
May 29, 2025
5c92287
Merge branch 'master' of github.com:rancher/dashboard into 14244-item…
May 30, 2025
677debd
wrapper styling
May 30, 2025
033377c
imporve performance
May 31, 2025
64dbab4
debounce search query
May 31, 2025
3d0ebe2
update e2e tests
Jun 2, 2025
9f71ac9
support actions as prop
Jun 2, 2025
9e01391
Merge branch '14244-item-card' of github.com:momesgin/dashboard into …
Jun 2, 2025
2023613
resolve conflicts
Jun 2, 2025
3b22af7
update filter component + add statuses filter
Jun 2, 2025
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
23 changes: 23 additions & 0 deletions cypress/e2e/po/components/rc-item-card.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';

export default class RcItemCardPo extends ComponentPo {
constructor(selector = '.dashboard-root') {
super(selector);
}

getCardById(id: string) {
return this.self().get(`[data-testid="item-card-${ id }"]`);
}

getCardByTitle(title: string) {
return this.self().find('[data-testid="item-card-header-title"]').contains(title);
}

getImageByTitle(title: string) {
return this.getCardByTitle(title).get('[data-testid="item-card-image"] img');
}

clickByTitle(name: string) {
return this.getCardByTitle(name).click();
}
}
2 changes: 1 addition & 1 deletion cypress/e2e/po/pages/explorer/charts/chart.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class ChartPage extends PagePo {
const chartsPage = new ChartsPage(clusterId);

ChartsPage.navTo();
chartsPage.charts().select(chartName);
chartsPage.clickChart(chartName);
}

chartHeader(options?: any) {
Expand Down
14 changes: 6 additions & 8 deletions cypress/e2e/po/pages/explorer/charts/charts.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import SelectPo from '@/cypress/e2e/po/components/select.po';
import BurgerMenuPo from '@/cypress/e2e/po/side-bars/burger-side-menu.po';
import ProductNavPo from '@/cypress/e2e/po/side-bars/product-side-nav.po';
import BannersPo from '@/cypress/e2e/po/components/banners.po';
import SelectIconGridPo from '@/cypress/e2e/po/components/select-icon-grid.po';
import RcItemCardPo from '@/cypress/e2e/po/components/rc-item-card.po';
import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po';

export class ChartsPage extends PagePo {
Expand Down Expand Up @@ -51,18 +51,16 @@ export class ChartsPage extends PagePo {
return new CheckboxInputPo(this.self().find('[data-testid="charts-show-deprecated-filter"]'));
}

charts() {
return new SelectIconGridPo('[data-testid="chart-selection-grid"]', 'chart-selection');
getAppByName(name: string) {
return new RcItemCardPo().getCardByTitle(name);
}

getChartByName(name: string) {
return this.charts().self().find(`[data-testid="select-icon-grid-${ name }"]`);
clickChart(name: string) {
return new RcItemCardPo().clickByTitle(name);
}

checkChartGenericIcon(name: string, isGeneric = true) {
const src = this.charts().self().contains(name).parent()
.find('.logo img')
.invoke('attr', 'src');
const src = new RcItemCardPo().getImageByTitle(name).invoke('attr', 'src');

if (isGeneric) {
return src.should('contain', 'generic-catalog');
Expand Down
22 changes: 13 additions & 9 deletions cypress/e2e/tests/pages/explorer/apps/charts.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,21 +72,25 @@ describe('Apps/Charts', { tags: ['@explorer', '@adminUser'] }, () => {
// by default "Show deprecated apps" filter is not enabled (except if "deprecated" query param exists in the url)
chartsPage.chartsShowDeprecatedFilterCheckbox().isUnchecked();
// a deprecated chart should not be listed before enabling the checkbox
chartsPage.getChartByName('deprecatedChart').should('not.exist');
chartsPage.getAppByName('deprecatedChart').should('not.exist');
// an experimental chart should still be visible
chartsPage.getChartByName('experimentalChart').should('exist').scrollIntoView().and('be.visible');
chartsPage.getAppByName('experimentalChart').should('exist').scrollIntoView()
.and('be.visible');
// a chart that's deprecated & experimental should not be listed before enabling the checkbox
chartsPage.getChartByName('deprecatedAndExperimentalChart').should('not.exist');
chartsPage.getAppByName('deprecatedAndExperimentalChart').should('not.exist');
// enabling the checkbox
chartsPage.chartsShowDeprecatedFilterCheckbox().set();
chartsPage.getChartByName('deprecatedChart').should('exist').scrollIntoView().and('be.visible');
chartsPage.getChartByName('experimentalChart').should('exist').scrollIntoView().and('be.visible');
chartsPage.getChartByName('deprecatedAndExperimentalChart').should('exist').scrollIntoView().and('be.visible');
chartsPage.getAppByName('deprecatedChart').should('exist').scrollIntoView()
.and('be.visible');
chartsPage.getAppByName('experimentalChart').should('exist').scrollIntoView()
.and('be.visible');
chartsPage.getAppByName('deprecatedAndExperimentalChart').should('exist').scrollIntoView()
.and('be.visible');
// going to chart's page
const chartPage = new ChartPage();

generateDeprecatedAndExperimentalChart();
chartsPage.getChartByName('deprecatedAndExperimentalChart').click();
chartsPage.getAppByName('deprecatedAndExperimentalChart').click();
cy.wait('@generateDeprecatedAndExperimentalChart');
// checking the "deprecated" query to be included in the url
cy.location('search').should('include', 'deprecated=true');
Expand All @@ -100,7 +104,7 @@ describe('Apps/Charts', { tags: ['@explorer', '@adminUser'] }, () => {
cy.wait('@fetchChartData');
cy.get('@fetchChartData.all').should('have.length.at.least', 3);

chartsPage.getChartByName(chartName)
chartsPage.getAppByName(chartName)
.should('exist')
.scrollIntoView()
.should('be.visible')
Expand All @@ -124,7 +128,7 @@ describe('Apps/Charts', { tags: ['@explorer', '@adminUser'] }, () => {
cy.wait('@fetchChartData');
cy.get('@fetchChartData.all').should('have.length.at.least', 3);

chartsPage.getChartByName(chartName)
chartsPage.getAppByName(chartName)
.should('exist')
.scrollIntoView()
.should('be.visible')
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/tests/pages/explorer/apps/repositories.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe('Apps', () => {
chartsPage.chartsFilterReposSelect().checkOptionSelected('All');
chartsPage.chartsFilterInput().clear();

chartsPage.charts().select('Rancher Backups');
chartsPage.clickChart('Rancher Backups');
chartPage.waitForPage();

// The repo charts should have been fetched
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"@aws-sdk/client-kms": "3.8.1",
"@novnc/novnc": "1.2.0",
"@popperjs/core": "2.11.8",
"@rancher/icons": "2.0.32",
"@rancher/icons": "2.0.36",
"@vee-validate/zod": "4.15.0",
"ansi_up": "5.0.0",
"axios": "1.8.3",
Expand Down
6 changes: 6 additions & 0 deletions shell/assets/styles/themes/_dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -229,4 +229,10 @@
$slate: #4B4F6B;

--slate: #{$slate};

--link-text-secondary: #{$secondary};

.secondary-text-link {
color: var(--link-text-secondary);
}
}
15 changes: 15 additions & 0 deletions shell/assets/styles/themes/_light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ BODY, .theme-light {

--link : #{$link};
--link-text : #{contrast-color($link)};
--link-text-secondary : #{$darker};
--link-hover-bg : #{darken($link, 10%)};
--link-hover-text : #{saturate($lightest, 20%)};
--link-active-bg : #{darken($link, 25%)};
Expand All @@ -96,6 +97,15 @@ BODY, .theme-light {
}
}

.secondary-text-link {
color: var(--link-text-secondary);
text-decoration: underline;

&:hover {
text-decoration: none;
}
}

.bg-link {
background-color: var(--link);
color: var(--link-text);
Expand Down Expand Up @@ -350,6 +360,7 @@ BODY, .theme-light {
--border : #{$medium};
--border-width : 1px;
--border-radius : 4px;
--border-radius-md : 6px;
--border-radius-lg : 8px;
--outline : var(--primary);
--outline-width : 1px;
Expand Down Expand Up @@ -552,4 +563,8 @@ BODY, .theme-light {
--badge-state-disabled-text : #{$darker};
--badge-state-disabled-bg : #{$lighter};
--badge-state-disabled-border: #{$medium};

--gap : 8px;
--gap-md : 16px;
--gap-lg : 24px;
}
13 changes: 13 additions & 0 deletions shell/assets/translations/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,12 @@ generic:
experimental: Experimental

deprecated: Deprecated
upgradeable: Upgradeable
installed: Installed
featured: Featured
shortFeatured: Feat
category: Category
tags: Tags
placeholder: "e.g. {text}"
moreInfo: More Info
selectors:
Expand Down Expand Up @@ -1028,6 +1034,7 @@ catalog:
search: Filter charts results
deprecatedChartsFilter:
label: Show deprecated apps
addNew: Add new
install:
action:
goToUpgrade: Edit/Upgrade
Expand Down Expand Up @@ -3136,6 +3143,12 @@ istio:
tracing: Enable Jaeger Tracing (limited)
v1Warning: Please uninstall the current Istio version in the <code>istio-system</code> namespace before attempting to install this version.

itemCard:
ariaLabel:
clickable: Click on Card
card: Item Card
status: Status
content: Card Content
jwt:
title: JWT Authentication
actions:
Expand Down
118 changes: 118 additions & 0 deletions shell/components/RcFilterPanel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<script setup lang="ts">
import Checkbox from '@components/Form/Checkbox/Checkbox.vue';

type FilterOption = {
value?: string;
component?: any;
componentProps?: Record<string, any>;
label?: string | { component: any; componentProps: Record<string, any>; };
};

type FilterGroup = {
key: string;
title: string;
options: FilterOption[];
};

const props = defineProps<{
modelValue: Record<string, string[]>;
filters: FilterGroup[];
}>();

const emit = defineEmits<{(e: 'update:modelValue', val: Record<string, string[]>): void;}>();

const updateFilter = (key: string, value: string[]) => {
const newValue = { ...props.modelValue, [key]: value };

emit('update:modelValue', newValue);
};

</script>

<template>
<div class="filter-panel">
<div
v-for="filter in filters"
:key="filter.key"
class="filter-panel-filter-group"
>
<h4 class="filter-panel-filter-group-title">
{{ filter.title }}
</h4>
<div
v-for="(option, i) in filter.options"
:key="`${filter.key}-${i}`"
class="filter-panel-filter-option"
>
<template v-if="option.component">
<component
:is="option.component"
v-bind="option.componentProps"
/>
</template>
<template v-else>
<Checkbox
:key="i"
class="filter-panel-filter-checkbox"
:label="typeof option.label === 'string' ? option.label : undefined"
:value="modelValue[filter.key]"
:value-when-true="option.value"
@update:value="updateFilter(filter.key, $event)"
>
<template #label>
<span v-if="typeof option.label === 'string'">{{ option.label }}</span>
<component
:is="option.label.component"
v-else
v-bind="option.label.componentProps"
/>
</template>
</Checkbox>
</template>
</div>
</div>
</div>
</template>

<style lang='scss' scoped>
.filter-panel {
display: flex;
min-width: 250px;
height: max-content;
padding: 16px;
flex-direction: column;
align-items: flex-start;
gap: 24px;
border-radius: 6px;
background: var(--sortable-table-header-bg);

&-filter-group {
display: flex;
flex-direction: column;
gap: 8px;
width: 100%;

&-title {
margin-bottom: 6px;
font-size: 16px;
font-weight: 600;
line-height: 23px;
}
}

&-filter-option {
width: 100%;

.filter-panel-filter-checkbox {

.checkbox-label span {
max-width: 240px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
color: var(--link-text-secondary);
}
}
}
}
</style>
27 changes: 0 additions & 27 deletions shell/components/__tests__/ApplicationCard.test.ts

This file was deleted.

Loading
Loading