Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into jmo-vue-recommended-a…
Browse files Browse the repository at this point in the history
…pp-files
  • Loading branch information
jeffsmohan committed Mar 22, 2024
2 parents 8d6219e + bc1b74b commit 5744cfb
Show file tree
Hide file tree
Showing 17 changed files with 569 additions and 445 deletions.
10 changes: 0 additions & 10 deletions packages/client/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,6 @@ module.exports = {
// ARPA Reporter: annual performance reporter
'./src/views/ArpaAnnualPerformanceReporter.vue',

// Grant Finder: core views
'./src/views/Home.vue',
'./src/views/Login.vue',
'./src/views/NotFound.vue',

// Grant Finder: grants tables
'./src/views/Grants.vue',
'./src/views/MyGrants.vue',
'./src/components/GrantsTable.vue',

// Grant Finder: search modals
'./src/components/Modals/AddKeyword.vue',
'./src/components/Modals/SavedSearchPanel.vue',
Expand Down
214 changes: 132 additions & 82 deletions packages/client/src/components/GrantsTable.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
<template>
<section class="container-fluid grants-table-container">
<b-row class="my-3" v-if="showSearchControls">
<b-row
v-if="showSearchControls"
class="my-3"
>
<div class="ml-3">
<SavedSearchPanel :isDisabled="loading" />
<SavedSearchPanel :is-disabled="loading" />
</div>
<div class="ml-1">
<SearchPanel :isDisabled="loading" ref="searchPanel" :search-id="Number(editingSearchId)" @filters-applied="retrieveFilteredGrants" />
<SearchPanel
ref="searchPanel"
:is-disabled="loading"
:search-id="Number(editingSearchId)"
@filters-applied="retrieveFilteredGrants"
/>
</div>
</b-row>
<b-row class="grants-table-title-control">
<b-col v-if="showSearchControls" >
<SearchFilter :isDisabled="loading" :filterKeys="searchFilters" @filter-removed="onFilterRemoved" />
<b-row class="grants-table-title-control">
<b-col v-if="showSearchControls">
<SearchFilter
:is-disabled="loading"
:filter-keys="searchFilters"
@filter-removed="onFilterRemoved"
/>
</b-col>
<b-col align-self="end" v-if="!showSearchControls">
<h2 class="mb-0">{{ searchTitle }}</h2>
<b-col
v-if="!showSearchControls"
align-self="end"
>
<h2 class="mb-0">
{{ searchTitle }}
</h2>
</b-col>
<b-col class="d-flex justify-content-end">
<b-button @click="exportCSV" :disabled="loading" variant="outline-primary" size="sm">
<b-icon icon="download" class="mr-2" aria-hidden="true" />Export to CSV</b-button>
<b-button
:disabled="loading"
variant="outline-primary"
size="sm"
@click="exportCSV"
>
<b-icon
icon="download"
class="mr-2"
aria-hidden="true"
/>Export to CSV
</b-button>
</b-col>
</b-row>
<b-row align-v="center">
Expand All @@ -33,7 +60,7 @@
:items="formattedGrants"
:fields="fields.filter(field => !field.hideGrantItem)"
show-empty
emptyText="No matches found"
empty-text="No matches found"
no-local-sorting
:sort-by.sync="orderBy"
:sort-desc.sync="orderDesc"
Expand All @@ -48,39 +75,54 @@
<p> {{ formatCurrency(row.item.award_ceiling) }}</p>
</template>
<template #table-busy>
<div class="text-center text-info my-2" style="height: 1200px;">
<b-spinner class="align-middle"></b-spinner>
<div
class="text-center text-info my-2"
style="height: 1200px;"
>
<b-spinner class="align-middle" />
<strong> Loading...</strong>
</div>
</template>
<template #empty="scope">
&emsp;
&emsp;
<div class="text-center">
<p class="empty-text"><strong>{{ scope.emptyText }}</strong></p>
<p class="empty-text">
<strong>{{ scope.emptyText }}</strong>
</p>
<div v-if="showSearchControls">
<p class="empty-text">Tip: Broaden your search or adjust your keywords for more results</p>
<p class="empty-text">
Tip: Broaden your search or adjust your keywords for more results
</p>
&nbsp;
<p><a @click="initEditSearch(searchId);" class="link">
Edit Search Criteria
</a></p>
<p>
<a
class="link"
@click="initEditSearch(searchId);"
>
Edit Search Criteria
</a>
</p>
</div>
</div>
</template>
</b-table>
</b-col>
</b-row>
<b-row class="grants-table-pagination">
<b-col cols="11" class="grants-table-pagination-component">
<b-col
cols="11"
class="grants-table-pagination-component"
>
<!--
Pagination component resets currentPage to 1 if totalRows is too low.
When loading the page with e.g. `?page=4`, this would reset the currentPage to 1
instead of 4. So we delay rendering of the pagination until grants are loaded.
-->
<template v-if="totalRows > 0">
<b-pagination
class="m-0"
v-model="currentPage"
class="m-0"
:total-rows="totalRows"
:per-page="perPage"
first-text="First"
Expand All @@ -90,10 +132,15 @@
aria-controls="grants-table"
/>
</template>
<div class="my-1 rounded py-1 px-2 page-item">{{ totalRows }} total grant{{ totalRows == 1 ? '' : 's' }}</div>
<div class="my-1 rounded py-1 px-2 page-item">
{{ totalRows }} total grant{{ totalRows == 1 ? '' : 's' }}
</div>
</b-col>
</b-row>
<GrantDetailsLegacy v-if="!newGrantsDetailPageEnabled" :selected-grant.sync="selectedGrant" />
<GrantDetailsLegacy
v-if="!newGrantsDetailPageEnabled"
:selected-grant.sync="selectedGrant"
/>
</section>
</template>

Expand Down Expand Up @@ -123,7 +170,10 @@ export default {
showInterested: Boolean,
showRejected: Boolean,
showResult: Boolean,
showAssignedToAgency: String,
showAssignedToAgency: {
type: String,
default: undefined,
},
showSearchControls: {
type: Boolean,
default: true,
Expand Down Expand Up @@ -180,65 +230,6 @@ export default {
orderDesc: DEFAULT_ORDER_DESC,
};
},
async mounted() {
document.addEventListener('keyup', this.changeSelectedGrantIndex);
this.clearSelectedSearch();
// Watch route query updates and reflect them in the component
// (This happens with browser back/forward through history)
this.$watch(
() => this.$route.query,
this.extractStateFromRoute,
{ deep: true },
);
// Retrieve the initial grants list for the table
if (this.$route.query.search) {
// We need to load saved searches before extracting initial state from route
this.loading = true;
await this.fetchSavedSearches({
perPage: 100, // TODO: make this robust to users with more saved searches
currentPage: 1,
});
this.extractStateFromRoute();
this.retrieveFilteredGrants();
this.loading = false;
} else {
this.extractStateFromRoute();
this.retrieveFilteredGrants();
}
// Watch route query and push a route update when it changes.
// This needs to be set up after the initial setting of related
// data (currentPage, order, etc.) so it won't trigger initially.
this.$watch(
() => this.routeQuery,
(routeQuery) => {
this.pushRouteUpdate(routeQuery);
this.retrieveFilteredGrants();
},
{ deep: true, immediate: false },
);
// Watch selected search and reset orderBy and orderDesc
// (This must be done after these values are set on initial page load
// to prevent them being overwritten)
this.$watch(
'selectedSearchId',
() => {
this.currentPage = 1;
const filterKeys = this.activeFilters.map((f) => f.key);
if (this.searchId !== null && (filterKeys.includes('includeKeywords') || filterKeys.includes('excludeKeywords'))) {
// only if include/exclude keywords are selected
this.orderBy = 'rank';
this.orderDesc = false;
} else {
this.orderBy = 'open_date';
this.orderDesc = true;
}
},
);
},
computed: {
...mapGetters({
grants: 'grants/grants',
Expand Down Expand Up @@ -333,6 +324,65 @@ export default {
this.changeSelectedGrant();
},
},
async mounted() {
document.addEventListener('keyup', this.changeSelectedGrantIndex);
this.clearSelectedSearch();
// Watch route query updates and reflect them in the component
// (This happens with browser back/forward through history)
this.$watch(
() => this.$route.query,
this.extractStateFromRoute,
{ deep: true },
);
// Retrieve the initial grants list for the table
if (this.$route.query.search) {
// We need to load saved searches before extracting initial state from route
this.loading = true;
await this.fetchSavedSearches({
perPage: 100, // TODO: make this robust to users with more saved searches
currentPage: 1,
});
this.extractStateFromRoute();
this.retrieveFilteredGrants();
this.loading = false;
} else {
this.extractStateFromRoute();
this.retrieveFilteredGrants();
}
// Watch route query and push a route update when it changes.
// This needs to be set up after the initial setting of related
// data (currentPage, order, etc.) so it won't trigger initially.
this.$watch(
() => this.routeQuery,
(routeQuery) => {
this.pushRouteUpdate(routeQuery);
this.retrieveFilteredGrants();
},
{ deep: true, immediate: false },
);
// Watch selected search and reset orderBy and orderDesc
// (This must be done after these values are set on initial page load
// to prevent them being overwritten)
this.$watch(
'selectedSearchId',
() => {
this.currentPage = 1;
const filterKeys = this.activeFilters.map((f) => f.key);
if (this.searchId !== null && (filterKeys.includes('includeKeywords') || filterKeys.includes('excludeKeywords'))) {
// only if include/exclude keywords are selected
this.orderBy = 'rank';
this.orderDesc = false;
} else {
this.orderBy = 'open_date';
this.orderDesc = true;
}
},
);
},
methods: {
...mapActions({
fetchGrants: 'grants/fetchGrantsNext',
Expand Down
12 changes: 6 additions & 6 deletions packages/client/src/router/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import VueRouter from 'vue-router';

import { myProfileEnabled, newTerminologyEnabled, newGrantsDetailPageEnabled } from '@/helpers/featureFlags';
import Login from '../views/Login.vue';
import BaseLayout from '../components/BaseLayout.vue';
import LoginView from '@/views/LoginView.vue';
import BaseLayout from '@/components/BaseLayout.vue';
import ArpaAnnualPerformanceReporter from '../views/ArpaAnnualPerformanceReporter.vue';

import store from '../store';
Expand All @@ -11,7 +11,7 @@ export const routes = [
{
path: '/login',
name: 'login',
component: Login,
component: LoginView,
},
{
path: '/arpa-annual-performance-reporter',
Expand Down Expand Up @@ -63,7 +63,7 @@ export const routes = [
{
path: '/grants',
name: 'grants',
component: () => import('../views/Grants.vue'),
component: () => import('../views/GrantsView.vue'),
meta: {
requiresAuth: true,
},
Expand All @@ -85,7 +85,7 @@ export const routes = [
{
path: '/my-grants/:tab',
name: 'myGrants',
component: () => import('../views/MyGrants.vue'),
component: () => import('../views/MyGrantsView.vue'),
meta: {
tabNames: ['interested', 'assigned', 'not-applying', 'applied'],
requiresAuth: true,
Expand Down Expand Up @@ -156,7 +156,7 @@ export const routes = [
},
{
path: '*',
component: () => import('../views/NotFound.vue'),
component: () => import('../views/NotFoundView.vue'),
name: 'notFound',
meta: {
requiresAuth: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<GrantsTable hideGrantItems />
<GrantsTable hide-grant-items />
</template>

<script>
Expand Down
24 changes: 0 additions & 24 deletions packages/client/src/views/Home.vue

This file was deleted.

Loading

0 comments on commit 5744cfb

Please sign in to comment.