diff --git a/solution/ui/e2e/cypress/e2e/search.spec.cy.js b/solution/ui/e2e/cypress/e2e/search.spec.cy.js
index d9d8c8f81e..2fc842744b 100644
--- a/solution/ui/e2e/cypress/e2e/search.spec.cy.js
+++ b/solution/ui/e2e/cypress/e2e/search.spec.cy.js
@@ -41,6 +41,10 @@ describe("Search flow", () => {
cy.intercept("**/v3/resources/public/categories**", {
fixture: "categories.json",
}).as("categories");
+
+ cy.intercept(`**/v3/content-search/counts**`, {
+ fixture: "counts.json",
+ }).as("counts");
});
it("has a working search box on the homepage on desktop", () => {
@@ -161,10 +165,6 @@ describe("Search flow", () => {
});
it("should not show internal checkbox when not logged in", () => {
- cy.intercept(`**/v3/content-search/counts**`, {
- fixture: "counts.json",
- }).as("counts");
-
cy.viewport("macbook-15");
cy.visit(`/search/?q=${SEARCH_TERM}`, { timeout: 60000 });
cy.get(".doc-type__toggle fieldset > div")
@@ -196,7 +196,7 @@ describe("Search flow", () => {
.should("have.text", "Internal Resources(1)");
});
- it("should not show the categories dropdown when only regulations are selected", () => {
+ it("should not show the categories or subjects dropdowns when only regulations are selected", () => {
cy.viewport("macbook-15");
cy.eregsLogin({
@@ -207,16 +207,22 @@ describe("Search flow", () => {
cy.visit(`/search/?q=${SEARCH_TERM}`, { timeout: 60000 });
cy.get("div[data-testid='category-select']").should("be.visible");
+ cy.get("button[data-testid='subjects-activator']").should("be.visible");
cy.get(".doc-type__toggle fieldset > div")
.eq(0)
.find("input")
.check({ force: true });
cy.get("div[data-testid='category-select']").should("not.be.visible");
+ cy.get("button[data-testid='subjects-activator']").should(
+ "not.be.visible",
+ );
+ cy.get(".doc-type__toggle fieldset > div");
cy.get(".doc-type__toggle fieldset > div")
.eq(1)
.find("input")
.check({ force: true });
cy.get("div[data-testid='category-select']").should("be.visible");
+ cy.get("button[data-testid='subjects-activator']").should("be.visible");
});
it("has the correct type params in URL for each doc type combination", () => {
@@ -263,13 +269,124 @@ describe("Search flow", () => {
it("category should be selected on load if included in URL", () => {
cy.viewport("macbook-15");
- cy.visit("/subjects/?categories=3");
+ cy.visit(`/search?q={SEARCH_TERM}&categories=3`);
cy.get("div[data-testid='category-select']")
.should("exist")
.find(".v-select__selection")
.should("have.text", "Related Regulations Fixture Item");
});
+ it("subject should be selected on load if included in the URL", () => {
+ cy.viewport("macbook-15");
+ cy.visit(`/search?q={SEARCH_TERM}&subjects=2`);
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "ABP")
+ .click({ force: true });
+
+ cy.get("button[data-testid=add-subject-2]").should(
+ "have.class",
+ "subjects-li__button--selected",
+ );
+ });
+
+ it("subject should change in URL if new subject is selected from the Subjects dropdown", () => {
+ cy.viewport("macbook-15");
+ cy.visit(`/search?q=${SEARCH_TERM}&subjects=2`);
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "ABP")
+ .click({ force: true });
+
+ cy.get("button[data-testid=add-subject-3]")
+ .should("not.have.class", "subjects-li__button--selected")
+ .find(".count")
+ .should("have.text", "(15)");
+
+ cy.get("button[data-testid=add-subject-3]").click({ force: true });
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "Access to Services")
+ .click({ force: true });
+
+ cy.get("button[data-testid=add-subject-2]").should(
+ "not.have.class",
+ "subjects-li__button--selected",
+ );
+
+ cy.get("button[data-testid=add-subject-3]").should(
+ "have.class",
+ "subjects-li__button--selected",
+ );
+
+ cy.url().should("include", "subjects=3");
+ });
+
+ it("subjects and categories can be selected simultaneously", () => {
+ cy.viewport("macbook-15");
+ cy.visit(`/search?q=${SEARCH_TERM}`);
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .click();
+
+ cy.get("button[data-testid=add-subject-3]").click({ force: true });
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "Access to Services")
+ .click({ force: true });
+
+ cy.get("div[data-testid='category-select']").click();
+ cy.get("div[data-testid='external-0']").click({ force: true });
+
+ cy.get("div[data-testid='category-select']")
+ .find(".v-select__selection")
+ .should("have.text", "Related Statutes in Fixture");
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "Access to Services");
+
+ cy.url().should("include", "subjects=3").and("include", "categories=1");
+ });
+
+ it("subjects can be cleared by clicking the clear button", () => {
+ cy.viewport("macbook-15");
+ cy.visit(`/search?q=${SEARCH_TERM}`);
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .click();
+
+ cy.get("button[data-testid=add-subject-3]").click({ force: true });
+
+ cy.url().should("include", "subjects=3");
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "Access to Services")
+ .click({ force: true });
+
+ cy.get("i[data-testid='subjects-select-clear']").click({ force: true });
+
+ cy.get("button[data-testid='subjects-activator']")
+ .should("exist")
+ .find(".subjects-select__label")
+ .should("have.text", "Choose Subject");
+
+ cy.url().should("not.include", "subjects=3");
+
+ });
+
it("displays results of the search and highlights search term in regulation text", () => {
cy.viewport("macbook-15");
cy.visit(`/search/?q=${SEARCH_TERM}`, { timeout: 60000 });
diff --git a/solution/ui/e2e/cypress/e2e/subjects.spec.cy.js b/solution/ui/e2e/cypress/e2e/subjects.spec.cy.js
index ea3bf6b0d0..61736fa0b2 100644
--- a/solution/ui/e2e/cypress/e2e/subjects.spec.cy.js
+++ b/solution/ui/e2e/cypress/e2e/subjects.spec.cy.js
@@ -427,14 +427,14 @@ describe("Find by Subjects", () => {
cy.get(`button[data-testid=remove-subject-77]`).should("exist");
cy.get("button[data-testid=add-subject-63]").should(
"not.have.class",
- "sidebar-li__button--selected"
+ "subjects-li__button--selected"
);
cy.get("button[data-testid=add-subject-63]").click({
force: true,
});
cy.get("button[data-testid=add-subject-63]").should(
"have.class",
- "sidebar-li__button--selected"
+ "subjects-li__button--selected"
);
cy.get(`button[data-testid=remove-subject-63]`).should("exist");
cy.get(`button[data-testid=remove-subject-77]`).should("not.exist");
@@ -541,11 +541,11 @@ describe("Find by Subjects", () => {
cy.get(".doc-type__toggle fieldset > div")
.eq(0)
.find("label")
- .should("have.text", "Public Resources");
+ .should("include.text", "Public Resources");
cy.get(".doc-type__toggle fieldset > div")
.eq(1)
.find("label")
- .should("have.text", "Internal Resources");
+ .should("include.text", "Internal Resources");
// Remove subject
cy.get("button[data-testid=remove-subject-63]").click({ force: true });
@@ -566,11 +566,11 @@ describe("Find by Subjects", () => {
cy.get(".doc-type__toggle fieldset > div")
.eq(0)
.find("label")
- .should("have.text", "Public Resources");
+ .should("include.text", "Public Resources");
cy.get(".doc-type__toggle fieldset > div")
.eq(1)
.find("label")
- .should("have.text", "Internal Resources");
+ .should("include.text", "Internal Resources");
// Clear search
cy.get("form.search-form .v-field__clearable i").click({
diff --git a/solution/ui/e2e/cypress/fixtures/counts.json b/solution/ui/e2e/cypress/fixtures/counts.json
index a1a6e5371f..4d57b0e2fd 100644
--- a/solution/ui/e2e/cypress/fixtures/counts.json
+++ b/solution/ui/e2e/cypress/fixtures/counts.json
@@ -1,5 +1,36 @@
{
"internal_resource_count": 1,
"public_resource_count": 2,
- "regulation_text_count": 3
+ "regulation_text_count": 3,
+ "subjects": [
+ {
+ "subject": 2,
+ "count": 41
+ },
+ {
+ "subject": 3,
+ "count": 15
+ },
+ {
+ "subject": 4,
+ "count": 6
+ }
+ ],
+ "categories": [
+ {
+ "category": 2,
+ "parent": null,
+ "count": 100
+ },
+ {
+ "category": 4,
+ "parent": 3,
+ "count": 20
+ },
+ {
+ "category": 5,
+ "parent": 3,
+ "count": 13
+ }
+ ]
}
diff --git a/solution/ui/regulations/alias.js b/solution/ui/regulations/alias.js
index 2db6c58d8d..cf178e04f5 100644
--- a/solution/ui/regulations/alias.js
+++ b/solution/ui/regulations/alias.js
@@ -4,6 +4,7 @@ const r = (p) => resolve(__dirname, p);
export default {
"@": r("src"),
+ composables: r("./composables"),
cypress: r("../e2e/cypress"),
eregsComponentLib: r("../regulations/eregs-component-lib"),
legacy: r("../../regulations"),
diff --git a/solution/ui/regulations/css/scss/partials/_search.scss b/solution/ui/regulations/css/scss/partials/_search.scss
index 8ddfd56c3a..8e63859b04 100644
--- a/solution/ui/regulations/css/scss/partials/_search.scss
+++ b/solution/ui/regulations/css/scss/partials/_search.scss
@@ -14,7 +14,6 @@
&--menu {
background-color: white;
max-height: 300px;
- overflow-y: scroll;
.subjects__list-container {
form {
diff --git a/solution/ui/regulations/css/scss/partials/_subjects_selector.scss b/solution/ui/regulations/css/scss/partials/_subjects_selector.scss
index 1d1037e2a9..7124ebfb5f 100644
--- a/solution/ui/regulations/css/scss/partials/_subjects_selector.scss
+++ b/solution/ui/regulations/css/scss/partials/_subjects_selector.scss
@@ -76,7 +76,7 @@
ul.subjects__list {
height: 300px;
- overflow: scroll;
+ overflow-y: auto;
padding: 0;
margin: 0;
@@ -87,19 +87,11 @@
margin-bottom: 0;
}
- .sidebar-li__button {
+ .subjects-li__button {
text-align: left;
color: #000;
width: 100%;
- .match__container {
- @include font-bold-keep-width;
-
- .match {
- @include font-bold-keep-width-reset;
- }
- }
-
&--selected {
@include font-bold-keep-width;
@@ -113,6 +105,18 @@
cursor: pointer;
}
+
+ .match__container {
+ @include font-bold-keep-width;
+
+ .match {
+ @include font-bold-keep-width-reset;
+ }
+ }
+
+ .count {
+ margin-left: var(--spacer-1);
+ }
}
}
}
@@ -160,6 +164,12 @@
font-size: $font_size_sm;
line-height: 22px;
margin-bottom: var(--spacer-2);
+
+ .subjects-li__button {
+ display: flex;
+ justify-content: space-between;
+ line-height: 22px;
+ }
}
}
}
diff --git a/solution/ui/regulations/eregs-vite/src/components/SearchContinueResearch.test.js b/solution/ui/regulations/eregs-vite/src/components/SearchContinueResearch.test.js
index 847c0bf525..25cbb9e588 100644
--- a/solution/ui/regulations/eregs-vite/src/components/SearchContinueResearch.test.js
+++ b/solution/ui/regulations/eregs-vite/src/components/SearchContinueResearch.test.js
@@ -5,9 +5,7 @@ import SearchContinueResearch from "./SearchContinueResearch.vue";
describe("Search Continue Research", () => {
it("correctly determines if a query string has spaces", () => {
expect(SearchContinueResearch.hasSpaces("test")).toBe(false);
- expect(SearchContinueResearch.hasSpaces("test query")).toBe(
- true
- );
+ expect(SearchContinueResearch.hasSpaces("test query")).toBe(true);
});
it("correctly determines if a query has quotes", () => {
diff --git a/solution/ui/regulations/eregs-vite/src/components/dropdowns/Categories.vue b/solution/ui/regulations/eregs-vite/src/components/dropdowns/Categories.vue
index 731eab2e36..4a687c5a60 100644
--- a/solution/ui/regulations/eregs-vite/src/components/dropdowns/Categories.vue
+++ b/solution/ui/regulations/eregs-vite/src/components/dropdowns/Categories.vue
@@ -187,7 +187,6 @@ const onMenuUpdate = () => {
data-testid="category-select"
item-type="CategoriesItem"
label="Choose Category"
- :loading="loading"
:disabled="loading"
:items="list"
:item-props="itemProps"
diff --git a/solution/ui/regulations/eregs-vite/src/components/dropdowns/FetchItemsContainer.vue b/solution/ui/regulations/eregs-vite/src/components/dropdowns/FetchItemsContainer.vue
new file mode 100644
index 0000000000..d796263cf0
--- /dev/null
+++ b/solution/ui/regulations/eregs-vite/src/components/dropdowns/FetchItemsContainer.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
diff --git a/solution/ui/regulations/eregs-vite/src/components/dropdowns/Subjects.vue b/solution/ui/regulations/eregs-vite/src/components/dropdowns/Subjects.vue
index 8cedfb1649..f7d2a36fa4 100644
--- a/solution/ui/regulations/eregs-vite/src/components/dropdowns/Subjects.vue
+++ b/solution/ui/regulations/eregs-vite/src/components/dropdowns/Subjects.vue
@@ -16,6 +16,10 @@ const props = defineProps({
type: Object,
required: true,
},
+ counts: {
+ type: Array,
+ default: () => [],
+ },
loading: {
type: Boolean,
default: true,
@@ -44,7 +48,8 @@ const labelClasses = computed(() => ({
const menuItemClick = (event) => {
const menuItemClicked =
- event.target.className.includes("sidebar-li__button") || event.target.className.includes("match__container");
+ event.target.className.includes("subjects-li__button") ||
+ event.target.className.includes("match__container");
if (event.target.dataset.name) {
buttonTitle.value = event.target.dataset.name;
@@ -57,7 +62,7 @@ const menuItemClick = (event) => {
const clearClick = (event) => {
// don't let click fall through to menu activator
- event.stopPropagation();
+ if (event) event.stopPropagation();
// if menu is open, close it
if (menuToggleModel.value === true) menuToggleModel.value = false;
@@ -79,18 +84,38 @@ const clearClick = (event) => {
});
};
+const transformedList = ref({});
+
watchEffect(() => {
+ if (props.loading === false) {
+ const clonedCounts = [...props.counts];
+
+ const sortedCountList = clonedCounts.map((item) => {
+ const subject = props.list.find(
+ (subject) => subject.id == item.subject
+ );
+
+ return {
+ ...subject,
+ count: item.count,
+ };
+ });
+
+ transformedList.value = {
+ results: sortedCountList,
+ loading: props.loading,
+ };
+ }
+
if ($route.query?.subjects === undefined) {
buttonTitle.value = undefined;
return;
}
- if (props.list.loading === false && $route.query.subjects) {
+ if (props.loading === false && $route.query.subjects) {
const subjectId = $route.query.subjects;
- const subject = props.list.results.find(
- (subject) => subject.id == subjectId
- );
+ const subject = props.list.find((subject) => subject.id == subjectId);
buttonTitle.value = getSubjectName(subject);
}
@@ -100,6 +125,7 @@ watchEffect(() => {
{
@@ -135,7 +163,7 @@ watchEffect(() => {
@keydown.enter="menuItemClick"
>