Skip to content

Commit

Permalink
fix(ui): fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Nov 4, 2024
2 parents fc324a4 + 02f06a1 commit 39294bd
Show file tree
Hide file tree
Showing 50 changed files with 1,343 additions and 492 deletions.
5 changes: 5 additions & 0 deletions .changeset/nine-seals-drop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudoperators/juno-ui-components": patch
---

Migrate Select component to typescript
5 changes: 5 additions & 0 deletions .changeset/shiny-rivers-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudoperators/juno-ui-components": minor
---

Migrate the InputGroup component to TypeScript
6 changes: 6 additions & 0 deletions .changeset/sweet-items-rescue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@cloudoperators/juno-app-heureka": patch
"@cloudoperators/juno-app-greenhouse": patch
---

harmonizes filter names across different views
5 changes: 5 additions & 0 deletions .changeset/tiny-cooks-try.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudoperators/juno-ui-components": patch
---

adds very high z-index (9999) to portal root container
5 changes: 5 additions & 0 deletions .changeset/twelve-phones-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@cloudoperators/juno-ui-components": patch
---

Update packages to the latest patch versions.
9 changes: 4 additions & 5 deletions apps/heureka/src/components/filters/FilterSelect.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import React, { useState } from "react"
import { Button, InputGroup, SelectOption, Select, Stack, SearchInput } from "@cloudoperators/juno-ui-components"
import { useFilterActions } from "../StoreProvider"
import { humanizeString } from "../../lib/utils"

const FilterSelect = ({
entityName,
Expand Down Expand Up @@ -48,19 +47,19 @@ const FilterSelect = ({
name="filter"
className="filter-label-select w-64 mb-0"
label="Filter"
value={humanizeString(filterLabel)}
value={filterLabel}
onChange={handleFilterLabelChange}
disabled={isLoading}
>
{filterLabels?.map((filter) => (
<SelectOption value={filter} label={humanizeString(filter)} key={filter} />
{filterLabels?.map(({ displayName, filterName }) => (
<SelectOption value={filterName} label={displayName} key={filterName} />
))}
</Select>
<Select
name="filterValue"
value={filterValue}
onChange={handleFilterValueChange}
disabled={!filterLabelValues[filterLabel]?.length}
disabled={!filterLabelValues?.[filterLabel]?.length}
className="filter-value-select w-96 bg-theme-background-lvl-0"
>
{filterOptions?.map((value) => (
Expand Down
12 changes: 6 additions & 6 deletions apps/heureka/src/components/filters/Filters.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,26 @@ const Filters = ({
})

const filters = useMemo(() => {
//Since there is a custom query to fetch filter labels and values for each entity in API
//Since there is a custom query to fetch filter labels, names and values for each entity in API
//We need to map the data to the format that the FilterSelect component expects
//You can check the response structure of custom query e.g in /lib/queries/serviceFilterValues.js
if (!data || !data[queryKey]) return []

return Object.keys(data[queryKey]).map((key) => {
const field = data[queryKey][key]
return {
label: field.filterName, // Collecting filterName as filterLabel
values: field.values, // Collecting values as filterValues
displayName: field.displayName, // Display name of the filter
filterName: field.filterName, // Name of the filter to build the query
values: field.values,
}
})
}, [data, queryKey])

useEffect(() => {
// Set filter labels and values in the store
// Set filter labels, names and values in the store
// It is done in this control as the fetch filter label and values is done above here
if (filters.length > 0) {
const filterLabels = filters.map((filter) => filter.label)
setLabels(entityName, filterLabels)
setLabels(entityName, filters)
setFilterLabelValues(entityName, filters)
}
}, [filters, setLabels, setFilterLabelValues, entityName])
Expand Down
46 changes: 25 additions & 21 deletions apps/heureka/src/lib/slices/createFiltersSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ const COMPONENTS = "Components"

// Function to generate the initial filter state
const createFilterState = () => ({
labels: [], // Labels for each entity: ["label1", "label2", ...]
activeFilters: {}, // Active filters { label1: [value1], label2: [value2_1, value2_2], ... }
filterLabelValues: {}, // Filter label values { label1: ["val1", "val2", ...], label2: [...] }
predefinedFilters: [], // Predefined filters [ {name: "filter1", matchers: {"label1": "regex1", ...}}]
labels: [], // Array of objects: { displayName, filterName } for each filter entity. Filter names are used for request-building
activeFilters: {}, // Active filters { filterName1: [value1], filterName2: [value2_1, value2_2], ... }
filterLabelValues: {}, // Filter name values { filterName1: ["val1", "val2", ...], filterName2: [...] }
predefinedFilters: [], // Predefined filters [ {name: "filter1", matchers: {"filterName1": "regex1", ...}}]
activePredefinedFilter: null, // Active predefined filter
search: "", // Search term used for full-text filtering
})
Expand All @@ -32,10 +32,14 @@ const createFiltersSlice = (set, get) => ({
filters: {
...initialFiltersState,
actions: {
setLabels: (entity, labels) =>
setLabels: (entity, labelPairs) =>
set(
produce((state) => {
state.filters[entity].labels = labels
state.filters[entity].labels = labelPairs.map(({ displayName, filterName }) => ({
displayName,
filterName,
}))
state.filters[entity].filterNames = labelPairs.map(({ filterName }) => filterName) // update filterNames accordingly
}),
false,
`filters.setLabels.${entity}`
Expand All @@ -45,7 +49,7 @@ const createFiltersSlice = (set, get) => ({
set(
produce((state) => {
state.filters[entity].filterLabelValues = filters.reduce((acc, filter) => {
acc[filter.label] = filter.values
acc[filter.filterName] = filter.values
return acc
}, {})
}),
Expand Down Expand Up @@ -73,51 +77,51 @@ const createFiltersSlice = (set, get) => ({
)
},

addActiveFilter: (entity, filterLabel, filterValue) => {
addActiveFilter: (entity, filterName, filterValue) => {
set(
produce((state) => {
if (!state.filters[entity].activeFilters[filterLabel]) {
state.filters[entity].activeFilters[filterLabel] = []
if (!state.filters[entity].activeFilters[filterName]) {
state.filters[entity].activeFilters[filterName] = []
}

// Add the filter value if it doesn't already exist
state.filters[entity].activeFilters[filterLabel] = [
...new Set([...state.filters[entity].activeFilters[filterLabel], filterValue]),
state.filters[entity].activeFilters[filterName] = [
...new Set([...state.filters[entity].activeFilters[filterName], filterValue]),
]
}),
false,
`filters.addActiveFilter.${entity}`
)
},

addActiveFilters: (entity, filterLabel, filterValues) => {
addActiveFilters: (entity, filterName, filterValues) => {
set(
produce((state) => {
if (!state.filters[entity].activeFilters[filterLabel]) {
state.filters[entity].activeFilters[filterLabel] = []
if (!state.filters[entity].activeFilters[filterName]) {
state.filters[entity].activeFilters[filterName] = []
}

// Add the filter values and ensure uniqueness
state.filters[entity].activeFilters[filterLabel] = [
...new Set([...state.filters[entity].activeFilters[filterLabel], ...filterValues]),
state.filters[entity].activeFilters[filterName] = [
...new Set([...state.filters[entity].activeFilters[filterName], ...filterValues]),
]
}),
false,
`filters.addActiveFilters.${entity}`
)
},

removeActiveFilter: (entity, filterLabel, filterValue) => {
removeActiveFilter: (entity, filterName, filterValue) => {
set(
produce((state) => {
const updatedFilters = state.filters[entity].activeFilters[filterLabel].filter(
const updatedFilters = state.filters[entity].activeFilters[filterName].filter(
(value) => value !== filterValue
)

if (updatedFilters.length === 0) {
delete state.filters[entity].activeFilters[filterLabel]
delete state.filters[entity].activeFilters[filterName]
} else {
state.filters[entity].activeFilters[filterLabel] = updatedFilters
state.filters[entity].activeFilters[filterName] = updatedFilters
}
}),
false,
Expand Down
74 changes: 68 additions & 6 deletions apps/heureka/src/lib/slices/createFiltersSlice.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { createStore } from "zustand"
import createFiltersSlice from "./createFiltersSlice"
import constants from "../../components/shared/constants" // Import constants for use in tests

// Constants for entities
const ISSUEMATCHES = "IssueMatches"
Expand All @@ -13,8 +14,8 @@ describe("createFiltersSlice", () => {
let store

beforeEach(() => {
store = createStore((set) => ({
...createFiltersSlice(set),
store = createStore((set, get) => ({
...createFiltersSlice(set, get),
}))
})

Expand All @@ -28,17 +29,22 @@ describe("createFiltersSlice", () => {

it("should set labels correctly for an entity", () => {
const { setLabels } = store.getState().filters.actions
setLabels(ISSUEMATCHES, ["label1", "label2"])
const labelPairs = [
{ displayName: "Label 1", filterName: "filter1" },
{ displayName: "Label 2", filterName: "filter2" },
]
setLabels(ISSUEMATCHES, labelPairs)

const state = store.getState()
expect(state.filters[ISSUEMATCHES].labels).toEqual(["label1", "label2"])
expect(state.filters[ISSUEMATCHES].labels).toEqual(labelPairs)
expect(state.filters[ISSUEMATCHES].filterNames).toEqual(["filter1", "filter2"])
})

it("should set filter label values correctly for an entity", () => {
const { setFilterLabelValues } = store.getState().filters.actions
const filters = [
{ label: "filter1", values: ["value1", "value2"] },
{ label: "filter2", values: ["value3", "value4"] },
{ filterName: "filter1", values: ["value1", "value2"] },
{ filterName: "filter2", values: ["value3", "value4"] },
]
setFilterLabelValues(ISSUEMATCHES, filters)

Expand Down Expand Up @@ -83,6 +89,18 @@ describe("createFiltersSlice", () => {
})
})

it("should not duplicate values when adding a single active filter", () => {
const { addActiveFilter } = store.getState().filters.actions

addActiveFilter(COMPONENTS, "filter1", "value1")
addActiveFilter(COMPONENTS, "filter1", "value1") // Adding the same value again

const state = store.getState()
expect(state.filters[COMPONENTS].activeFilters).toEqual({
filter1: ["value1"],
})
})

it("should add multiple active filters correctly for an entity", () => {
const { addActiveFilters } = store.getState().filters.actions

Expand Down Expand Up @@ -140,4 +158,48 @@ describe("createFiltersSlice", () => {
const state = store.getState()
expect(state.filters[SERVICES].search).toBe("searchText")
})

it("should set filters from URL correctly", () => {
const { setFiltersFromURL } = store.getState().filters.actions
const activeFilters = {
[ISSUEMATCHES]: { filter1: ["value1"] },
[SERVICES]: { filter2: ["value2"] },
[COMPONENTS]: { filter3: ["value3"] },
}
const searchTerm = {
[ISSUEMATCHES]: "search1",
[SERVICES]: "search2",
[COMPONENTS]: "search3",
}

setFiltersFromURL(activeFilters, searchTerm)

const state = store.getState()
expect(state.filters[ISSUEMATCHES].activeFilters).toEqual(activeFilters[ISSUEMATCHES])
expect(state.filters[SERVICES].activeFilters).toEqual(activeFilters[SERVICES])
expect(state.filters[COMPONENTS].activeFilters).toEqual(activeFilters[COMPONENTS])
expect(state.filters[ISSUEMATCHES].search).toBe("search1")
expect(state.filters[SERVICES].search).toBe("search2")
expect(state.filters[COMPONENTS].search).toBe("search3")
})

it("should synchronize filters with URL correctly", () => {
const { syncFiltersWithURL } = store.getState().filters.actions

// Set up initial filters and search terms
store.getState().filters.actions.setActiveFilters(ISSUEMATCHES, { filter1: ["value1"] })
store.getState().filters.actions.setActiveFilters(SERVICES, { filter2: ["value2"] })
store.getState().filters.actions.setActiveFilters(COMPONENTS, { filter3: ["value3"] })

const result = syncFiltersWithURL()

expect(result).toEqual({
[constants.ACTIVE_FILTERS]: {
[ISSUEMATCHES]: { filter1: ["value1"] },
[SERVICES]: { filter2: ["value2"] },
[COMPONENTS]: { filter3: ["value3"] },
},
[constants.SEARCH_TERM]: expect.any(String), // Use expect.any() for encoded search term verification
})
})
})
Loading

0 comments on commit 39294bd

Please sign in to comment.