Skip to content
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

Use .iati-card for filters on report page #835

Merged
merged 4 commits into from
Jan 7, 2025
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
53 changes: 26 additions & 27 deletions cypress/integration/validationReport.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe("The Validation Report page", () => {
cy.visit("/report/ares-activities");
cy.wait("@validation");
cy.contains("Error");
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(0).click({ force: true });
cy.get("[data-cy='feedback-group']").eq(0).find("button").click({ force: true });
cy.contains("An empty space was added to the attribute");
});

Expand All @@ -20,8 +20,8 @@ describe("The Validation Report page", () => {
cy.wait("@validation");
cy.contains("Error");
cy.get("#search").should("have.value", "BE-BCE_KBO-0546740696-PG2017-2021_CD");
cy.get(".iati-accordion").eq(2).children("div").find("button").should("have.length", 1);
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(0).click({ force: true });
cy.get("[data-cy='feedback-group']").should("have.length", 1);
cy.get("[data-cy='feedback-group']").find("button").click({ force: true });
cy.contains("An empty space was added to the attribute");
});

Expand All @@ -32,10 +32,11 @@ describe("The Validation Report page", () => {
}).as("validation");
cy.visit("/report/ares-activities");
cy.wait("@validation");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 10);
cy.get(".iati-accordion").eq(2).find("span").eq(-1).should("contain", "Page 1 of");
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(-1).click({ force: true });
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 3);
cy.get("[data-cy='feedback-group']").should("have.length", 10);
cy.contains("Page 1 of 2");
cy.get("[data-cy='next-page'").click({ force: true });
cy.contains("Page 2 of 2");
cy.get("[data-cy='feedback-group']").should("have.length", 3);
});

it("filters results when passed an IATI Identifier on query string and paging is in operation", () => {
Expand All @@ -47,10 +48,10 @@ describe("The Validation Report page", () => {
cy.wait("@validation");
cy.contains("Error");
cy.get("#search").should("have.value", "XM-TEST-VALIDATION-01-A-PROJECT-01626");
cy.get(".iati-accordion").eq(2).children("div").find("button").should("have.length", 1);
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(0).click({ force: true });
cy.contains("The organisation role is invalid");
cy.contains("Budget Period must not be longer than one year");
cy.get("[data-cy='feedback-group']").should("have.length", 1);
cy.get("[data-cy='feedback-group']").find("button").click({ force: true });
cy.get("[data-cy='feedback-group']").contains("The organisation role is invalid");
cy.get("[data-cy='feedback-group']").contains("Budget Period must not be longer than one year");
});

it("filters results and still uses paging when search for IATI Identifier on query string gives more than 10 results", () => {
Expand All @@ -62,10 +63,10 @@ describe("The Validation Report page", () => {
cy.wait("@validation");
cy.contains("Error");
cy.get("#search").should("have.value", "XM-TEST-VALIDATION-01-A");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 10);
cy.get(".iati-accordion").eq(2).find("span").eq(-1).should("contain", "Page 1 of");
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(-1).click({ force: true });
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 1);
cy.get("[data-cy='feedback-group']").should("have.length", 10);
cy.contains("Page 1 of 2");
cy.get("[data-cy='next-page'").click({ force: true });
cy.get("[data-cy='feedback-group']").should("have.length", 1);
});

it("updates the displayed results after user does new search when on first page of search results", () => {
Expand All @@ -77,11 +78,11 @@ describe("The Validation Report page", () => {
cy.wait("@validation");
cy.contains("Error");
cy.get("#search").should("have.value", "XM-TEST-VALIDATION-01-A");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 10);
cy.get(".iati-accordion").eq(2).find("span").eq(-1).should("contain", "Page 1 of");
cy.get("[data-cy='feedback-group']").should("have.length", 10);
cy.contains("Page 1 of 2");
cy.get("#search").clear();
cy.get("#search").type("XM-TEST-VALIDATION-01-B-PROJECT-01926");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 1);
cy.get("[data-cy='feedback-group']").should("have.length", 1);
});

it("updates the displayed results after user does new search when not on first page of search results", () => {
Expand All @@ -93,14 +94,14 @@ describe("The Validation Report page", () => {
cy.wait("@validation");
cy.contains("Error");
cy.get("#search").should("have.value", "XM-TEST-VALIDATION-01-A");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 10);
cy.get(".iati-accordion").eq(2).find("span").eq(-1).should("contain", "Page 1 of");
cy.get(".iati-accordion").eq(2).children("div").find("button").eq(-1).click({ force: true });
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 1);
cy.get("[data-cy='feedback-group']").should("have.length", 10);
cy.contains("Page 1 of 2");
cy.get("[data-cy='next-page'").click({ force: true });
cy.get("[data-cy='feedback-group']").should("have.length", 1);

cy.get("#search").clear();
cy.get("#search").type("XM-TEST-VALIDATION-01-B-PROJECT-01926");
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 1);
cy.get("[data-cy='feedback-group']").should("have.length", 1);
});

it("updates the query string after user loads page then does new search", () => {
Expand All @@ -115,9 +116,8 @@ describe("The Validation Report page", () => {
cy.get("#search").clear();
cy.get("#search").type("XM-TEST-VALIDATION-01-B-PROJECT-01926");
cy.get("#search").blur();
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 1);
cy.get("[data-cy='feedback-group']").should("have.length", 1);
cy.location().should((loc) => {
console.log(loc);
expect(loc.search).to.eq("?id=XM-TEST-VALIDATION-01-B-PROJECT-01926");
});
});
Expand All @@ -134,9 +134,8 @@ describe("The Validation Report page", () => {
cy.get("#search").clear();
cy.get("#search").type("XM-TEST-VALIDATION-01-B");
cy.get("#search").blur();
cy.get(".iati-accordion").eq(2).find("div.mb-4").should("have.length", 2);
cy.get("[data-cy='feedback-group']").should("have.length", 2);
cy.location().should((loc) => {
console.log(loc);
expect(loc.search).to.eq("?id=XM-TEST-VALIDATION-01-B");
});
});
Expand Down
10 changes: 7 additions & 3 deletions src/components/AppAccordion.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<script setup>
import { ref } from "vue";

const props = defineProps({ open: { type: Boolean, default: false } });
const props = defineProps({
open: { type: Boolean, default: false },
headerClasses: { type: String, default: "" },
});

const isOpen = ref(props.open);

Expand All @@ -13,14 +16,15 @@
<template>
<div v-auto-animate class="w-full">
<button
class="relative flex w-full items-center space-x-3 p-0 border-none"
:class="props.headerClasses"
class="flex w-full items-center border-none"
:aria-expanded="isOpen"
@click="toggleAccordion()"
>
<slot name="title" />

<svg
class="absolute right-4 w-3 transform transition-all duration-200"
class="w-3 h-3 transform transition-all duration-200 float-right"
:class="{
'rotate-180': isOpen,
'rotate-0': !isOpen,
Expand Down
7 changes: 6 additions & 1 deletion src/components/AppPagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
<IconChevron />
</button>
<slot />
<button class="ml-1 rounded-md border border-slate-200 p-4" aria-label="Next" @click="emits('next')">
<button
class="ml-1 rounded-md border border-slate-200 p-4"
aria-label="Next"
data-cy="next-page"
@click="emits('next')"
>
<IconChevron direction="right" />
</button>
</div>
Expand Down
7 changes: 3 additions & 4 deletions src/components/CheckBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@
position: relative;
vertical-align: top;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}

Expand Down Expand Up @@ -156,12 +155,12 @@

.icheck-green > input:first-child:not(:checked):not(:disabled):hover + label::before,
.icheck-green > input:first-child:not(:checked):not(:disabled):hover + input[type="hidden"] + label::before {
border-color: #155336;
border-color: #155366;
}

.icheck-green > input:first-child:checked + label::before,
.icheck-green > input:first-child:checked + input[type="hidden"] + label::before {
background-color: #155336;
border-color: #155336;
background-color: #155366;
border-color: #155366;
}
</style>
7 changes: 4 additions & 3 deletions src/components/SearchFilter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,24 @@
</script>

<template>
<div class="flex w-full flex-row flex-wrap justify-around sm:w-[500px]">
<div class="iati-search-bar">
<input
id="search"
v-model="search"
class="m-0 w-full border px-4 py-3 text-lg focus-visible:outline-none sm:w-[350px]"
:class="props.inputClasses"
class="flex-1 p-4 border border-solid border-slate-200"
:placeholder="props.placeholder"
autofocus
@blur="onLoseFocus"
/>
<!-- TODO: Button -->
<button
v-if="props.showButton"
class="relative mt-4 inline w-full border-0 bg-iati-blue p-3 text-base uppercase sm:mt-0 sm:w-[150px]"
@click="onSearch"
>
{{ props.buttonCaption }}
</button>
<label id="search" for="search" class="invisible">Search</label>
<label id="search" for="search" class="hidden">Search</label>
</div>
</template>
11 changes: 8 additions & 3 deletions src/components/report/ActivityErrors.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,20 @@
</script>

<template>
<AppAccordion :open="true" class="iati-accordion">
<AppAccordion :open="true" :header-classes="'text-white bg-iati-green px-4 py-2'">
<template #title>
<div class="w-full bg-iati-green px-4 py-2 text-left text-white">
<div class="w-full text-left">
{{ props.title }}
</div>
</template>
<template #content>
<div class="border border-solid border-gray-200 p-4">
<FeedbackGroup v-for="activity in pageData" :key="activity.identifier" :activity="activity" />
<FeedbackGroup
v-for="activity in pageData"
:key="activity.identifier"
:activity="activity"
data-cy="feedback-group"
/>
<AppPagination v-if="filteredData.length > 10" @next="onNext" @previous="onPrevious">
<span class="text-sm">Page {{ page }} of {{ Math.ceil(filteredData.length / PAGE_LIMIT) }}</span>
</AppPagination>
Expand Down
72 changes: 27 additions & 45 deletions src/components/report/DocumentReport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -155,45 +155,33 @@
</script>

<template>
<div class="flex flex-wrap">
<div v-if="hasMessages" class="relative flex shrink grow flex-col sm:w-full md:basis-1/3">
<div class="sticky top-0 m-2.5">
<h3>Search and filter</h3>
<div class="bg-slate-300">
<div class="px-4 py-2">
<SearchFilter
placeholder="Search activity title and identifier..."
:search-text="searchText"
class="mb-4 mt-2 !w-full"
input-classes="!py-2 border-iati-blue text-base w-full"
:show-button="false"
@on-search="onFilter"
@on-lose-focus="onSearchLoseFocus"
/>
<h4>View by message type</h4>
<div class="text-sm text-slate-700">Click to show or hide individual message types</div>
</div>
<SeverityItem
v-for="severity in severities"
:key="severity.id"
:severity="severity"
@select="onFilterBySeverity"
/>
<div class="px-4 pt-2">
<h4>View by category</h4>
</div>
<div class="px-4 py-2">
<CategoryItem
v-for="category in categories"
:key="category.id"
:category="category"
@select="onFilterByCategory"
/>
</div>
<div v-if="hasActiveFilter()" class="px-4 pt-2 pb-4">
<button class="iati-button w-full" @click="onClearFilters">Clear Filters</button>
</div>
</div>
<div class="flex gap-x-4 flex-col md:flex-row">
<div v-if="hasMessages" class="iati-card md:self-start md:sticky md:top-6 md:w-[400px]">
<p class="iati-card__title">Search</p>
<SearchFilter
placeholder="Search activity title and identifier..."
:search-text="searchText"
:show-button="false"
@on-search="onFilter"
@on-lose-focus="onSearchLoseFocus"
/>
<p class="iati-card__title pt-2">Filter</p>
<p class="iati-card__subtitle">Filter by message type</p>
<SeverityItem
v-for="severity in severities"
:key="severity.id"
:severity="severity"
@select="onFilterBySeverity"
/>
<p class="iati-card__subtitle pt-2">Filter by category</p>
<CategoryItem
v-for="category in categories"
:key="category.id"
:category="category"
@select="onFilterByCategory"
/>
<div v-if="hasActiveFilter()" class="mt-4">
<button class="iati-button w-full" @click="onClearFilters">Clear Filters</button>
</div>
</div>
<div class="flex shrink grow flex-col" :class="hasMessages ? 'sm:w-full md:basis-2/3' : 'w-full'">
Expand All @@ -215,9 +203,3 @@
</div>
</div>
</template>

<style>
.iati-accordion > button > svg {
color: #ffffff;
}
</style>
6 changes: 3 additions & 3 deletions src/components/report/FeedbackGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@
};
</script>
<template>
<AppAccordion :open="false" class="mb-4">
<AppAccordion :open="false" class="mb-4" :header-classes="'bg-slate-100 px-4 py-2'">
<template #title>
<div class="w-full bg-slate-100 px-4 py-2 text-left">
<div class="w-full text-left">
<div class="font-medium">
{{ props.activity.title || "Untitled Activity" }}
<span v-if="show" class="text-[12px]">Link copied</span>
Expand All @@ -80,7 +80,7 @@
</div>
</template>
<template #content>
<div class="border border-gray-100 px-4 py-2">
<div class="border border-solid border-gray-100 px-4 py-2">
<FeedbackList v-for="(message, index) in messages" :key="index" :message="message" class="pb-2" />
<span v-if="!messages.length">There is no feedback to display</span>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/components/report/FileErrors.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
v-if="(report && report.summary.critical === 0) || messages.length"
:open="true"
class="iati-accordion mb-4"
:header-classes="'text-white bg-iati-green px-4 py-2'"
>
<template #title>
<div class="flex w-full items-center bg-iati-green px-4 py-2 text-left text-white">
<div class="flex w-full items-center text-left">
<span class="mr-2">{{ props.title }}</span>
<AppBadge v-for="messageType in messageTypes" :key="messageType.type" :variant="messageType.type">
{{ messageType.count }}
Expand Down
2 changes: 1 addition & 1 deletion src/components/report/ReportDocumentStatus.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<template>
<div
v-if="props.document"
class="flex flex-col gap-0 border border-solid border-gray-300 odd:bg-white even:bg-slate-100 sm:grid sm:grid-cols-5 sm:border-0"
class="flex flex-col gap-0 odd:bg-white even:bg-slate-100 sm:grid sm:grid-cols-5 sm:border-0"
>
<div class="py-2 pb-2 first:pl-3.5" :class="textClasses">
<div class="text-base font-bold sm:hidden">File Name</div>
Expand Down
Loading
Loading