From 278836c17f0ec5b361fa4e490ed5ab916bcded5f Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 06:21:54 -0500 Subject: [PATCH 01/10] chore(deps): bump design-system -> 2.5.0 --- client/package-lock.json | 8 ++++---- client/package.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 714153a9..28ceba6c 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -23,7 +23,7 @@ "eslint-plugin-vue": "^9.20.1", "happy-dom": "^13.1.4", "jest-serializer-vue-tjw": "^3.20.0", - "pdap-design-system": "^2.3.0", + "pdap-design-system": "^2.5.0", "postcss": "^8.4.32", "tailwindcss": "^3.3.6", "vite": "^4.5.1", @@ -3950,9 +3950,9 @@ } }, "node_modules/pdap-design-system": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pdap-design-system/-/pdap-design-system-2.3.0.tgz", - "integrity": "sha512-wTYw/kSrQ39f8u5Z66C37kMmlKZDSm1jtY4LswIGWpWx40xh6rt2MRj5d4A0PxCIm9ftRzLqmxQ4ykfh0Th49A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pdap-design-system/-/pdap-design-system-2.5.0.tgz", + "integrity": "sha512-5a9oWn6V/G51YfIVsepV1HN4OFSVWiALC1EWcmB6K4FyMdt6yhu/jM+jV9SFj4q0KQNbfUCzDVLD1ltGaDODKw==", "dev": true, "dependencies": { "@vuelidate/core": "^2.0.3", diff --git a/client/package.json b/client/package.json index a2504e2f..597846eb 100644 --- a/client/package.json +++ b/client/package.json @@ -29,7 +29,7 @@ "eslint-plugin-vue": "^9.20.1", "happy-dom": "^13.1.4", "jest-serializer-vue-tjw": "^3.20.0", - "pdap-design-system": "^2.3.0", + "pdap-design-system": "^2.5.0", "postcss": "^8.4.32", "tailwindcss": "^3.3.6", "vite": "^4.5.1", @@ -42,4 +42,4 @@ "not dead", "not ie 11" ] -} +} \ No newline at end of file From 896fa53b866fd84f889aed045394cc04f12ca370 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 06:22:06 -0500 Subject: [PATCH 02/10] chore(config): dev server port --- client/vite.config.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/client/vite.config.js b/client/vite.config.js index 55ca83a7..d5972fed 100644 --- a/client/vite.config.js +++ b/client/vite.config.js @@ -1,25 +1,28 @@ -import { defineConfig } from "vite"; -import vue from "@vitejs/plugin-vue"; -import svgLoader from "vite-svg-loader"; +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import svgLoader from 'vite-svg-loader'; export default defineConfig({ - plugins: [vue(), svgLoader({ defaultImport: "url" })], + plugins: [vue(), svgLoader({ defaultImport: 'url' })], resolve: { paths: { - "@/*": ["src/*"], + '@/*': ['src/*'], }, }, + server: { + port: 8888, + }, test: { coverage: { all: true, - include: ["src/**/*.vue", "src/util/**/*.js"], - provider: "v8", - reportsDirectory: "./coverage", + include: ['src/**/*.vue', 'src/util/**/*.js'], + provider: 'v8', + reportsDirectory: './coverage', }, - environment: "happy-dom", - exclude: ["node_modules"], + environment: 'happy-dom', + exclude: ['node_modules'], globals: true, - include: ["src/**/{__tests__,__spec__}/*.test.js"], - setupFiles: ["tools/testing/setup.js"], + include: ['src/**/{__tests__,__spec__}/*.test.js'], + setupFiles: ['tools/testing/setup.js'], }, }); From d1867b5fd230d9c88179269f42d93b9a09816bd1 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 06:24:23 -0500 Subject: [PATCH 03/10] refactor(util): move page data and add search shape --- client/src/pages/DataSourceStaticView.vue | 3 +- .../src/{pages/util.js => util/pageData.js} | 78 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) rename client/src/{pages/util.js => util/pageData.js} (63%) diff --git a/client/src/pages/DataSourceStaticView.vue b/client/src/pages/DataSourceStaticView.vue index a38118bf..cfa94b5f 100644 --- a/client/src/pages/DataSourceStaticView.vue +++ b/client/src/pages/DataSourceStaticView.vue @@ -130,7 +130,7 @@ import axios from 'axios'; import { Button } from 'pdap-design-system'; import formatDateForSearchResults from '../util/formatDate'; -import { STATIC_VIEW_UI_SHAPE } from './util'; +import { STATIC_VIEW_UI_SHAPE } from '../util/pageData.js'; export default { name: 'DataSourceStaticView', @@ -198,3 +198,4 @@ export default { @apply my-2; } +./pageData diff --git a/client/src/pages/util.js b/client/src/util/pageData.js similarity index 63% rename from client/src/pages/util.js rename to client/src/util/pageData.js index 983632c7..0f9f12ea 100644 --- a/client/src/pages/util.js +++ b/client/src/util/pageData.js @@ -122,3 +122,81 @@ export const STATIC_VIEW_UI_SHAPE = [ ], }, ]; + +export const SEARCH_RESULTS_UI_SHAPE = [ + { + header: 'Police & public interactions', + records: [ + { type: 'Accident Reports' }, + { type: 'Arrest Records' }, + { type: 'Calls for Service' }, + { type: 'Car GPS' }, + { type: 'Citations' }, + { type: 'Dispatch Logs' }, + { type: 'Dispatch Recordings' }, + { type: 'Field Contacts' }, + { type: 'Incident Reports' }, + { type: 'Misc Police Activity' }, + { type: 'Officer Involved Shootings' }, + { type: 'Stops' }, + { type: 'Surveys' }, + { type: 'Use of Force Reports' }, + { type: 'Vehicle Pursuits' }, + ], + }, + { + header: 'Info about officers', + records: [ + { type: 'Complaints & Misconduct' }, + { type: 'Daily Activity Logs' }, + { type: 'Training & Hiring Info' }, + { type: 'Personnel Records' }, + ], + }, + { + header: 'Info about agencies', + records: [ + { type: 'Annual & Monthly Reports' }, + { type: 'Budgets & Finances' }, + { type: 'Contact Info & Agency Meta' }, + { type: 'Geographic' }, + { type: 'List of Data Sources' }, + { type: 'Policies & Contracts' }, + ], + }, + { + header: 'Agency-published resources', + records: [ + { type: 'Crime Maps & Reports' }, + { type: 'Crime Statistics' }, + { type: 'Records Request Info' }, + { type: 'Resources' }, + { type: 'Sex Offender Registry' }, + { type: 'Wanted Persons' }, + ], + }, + { + header: 'Jails & Courts specific', + records: [ + { type: 'Booking Reports' }, + { type: 'Court Cases' }, + { type: 'Incarceration Records' }, + ], + }, +]; + +// example obj: +// { +// "airtable_uid": "rec00T2YLS2jU7Tbn", +// "data_source_name": "Calls for Service for Chicago Police Department - IL", +// "description": null, +// "record_type": "Calls for Service", +// "source_url": "https://informationportal.igchicago.org/911-calls-for-cpd-service/", +// "record_format": null, +// "coverage_start": "2019-01-01", +// "coverage_end": null, +// "agency_supplied": true, +// "agency_name": "Chicago Police Department - IL", +// "municipality": "Chicago", +// "state_iso": "IL" +// } From 801f90ad67d96dd14af9da30e7ebf61fcdf8538f Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 06:25:29 -0500 Subject: [PATCH 04/10] refactor(components): miscellaneous updates to search results card --- client/src/components/SearchResultCard.vue | 99 ++++++++++++---------- 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/client/src/components/SearchResultCard.vue b/client/src/components/SearchResultCard.vue index 6e2e245a..d662c30e 100644 --- a/client/src/components/SearchResultCard.vue +++ b/client/src/components/SearchResultCard.vue @@ -3,9 +3,32 @@ class="flex flex-col border border-neutral-400 p-3 text-lg leading-snug" data-test="search-result-card" > -

+

{{ dataSource.data_source_name }} -

+ + + +

{{ dataSource.record_type }}
-

- Unknown -

+

Unknown

- Agency -

+ Agency +

{{ dataSource.agency_name }}

Unknown

-

Time range

2016–2017

-

Formats available

+

Formats available

  • [
  • '
  • @@ -46,19 +48,17 @@ exports[`SearchResultCard with all data > search result card exists with full da
  • '
  • ]
-
- - -
+ `; exports[`SearchResultCard with coverage end but not start > search result card exists with coverage end but not start 1`] = `
-

+

+

Record type

-

Unknown

+

Unknown

Agency

Unknown

@@ -82,21 +82,19 @@ exports[`SearchResultCard with coverage end but not start > search result card e -->

Time range

Unknown start–2016

-

Formats available

-

Unknown

-
- - -
+

Formats available

+

Unknown

+
`; exports[`SearchResultCard with coverage start but not end > search result card exists with coverage start but not end 1`] = `
-

+

+

Record type

-

Unknown

+

Unknown

Agency

Unknown

@@ -120,21 +118,19 @@ exports[`SearchResultCard with coverage start but not end > search result card e -->

Time range

2016–Unknown end

-

Formats available

-

Unknown

-
- - -
+

Formats available

+

Unknown

+
`; exports[`SearchResultCard with missing data > search result card exists with missing data 1`] = `
-

Calls for Service for Cicero Police Department - IN

+

Calls for Service for Cicero Police Department - IN

+

Record type

-

Unknown

+

Unknown

Agency

Unknown

@@ -157,13 +153,9 @@ exports[`SearchResultCard with missing data > search result card exists with mis
-->

Time range

-

Unknown

-

Formats available

-

Unknown

-
- - -
+

Unknown

+

Formats available

+

Unknown

+
`; From b62304b8ebc99d82b3ab07d76b26060ecb2a18a6 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 06:26:28 -0500 Subject: [PATCH 06/10] refactor(pages): miscellaneous updates to search results page --- client/src/pages/SearchResultPage.vue | 125 ++++++++++++++++---------- 1 file changed, 76 insertions(+), 49 deletions(-) diff --git a/client/src/pages/SearchResultPage.vue b/client/src/pages/SearchResultPage.vue index a13a7976..e7107c80 100644 --- a/client/src/pages/SearchResultPage.vue +++ b/client/src/pages/SearchResultPage.vue @@ -16,56 +16,58 @@ New search
- + Loading results... +

+ +
+

+ If you don't see what you need, + + make a request  + +

+

+ To see these results in a table, + + view the full database  + +

+
+ +

- - Loading results... - - -

- If you don't see what you need, - - make a request  - -

-

- To see these results in a table, - - view the full database  - -

- - + +
+ - No results found. - - - + + {{ section.header }} + + + + +
@@ -74,6 +76,7 @@ import { Button, GridContainer, GridItem } from 'pdap-design-system'; import SearchResultCard from '../components/SearchResultCard.vue'; import axios from 'axios'; import pluralize from '../util/pluralize'; +import { SEARCH_RESULTS_UI_SHAPE } from '../util/pageData'; export default { name: 'SearchResultPage', @@ -89,6 +92,7 @@ export default { searchResult: {}, searchTerm: '', location: '', + uiShape: {}, }), mounted: function () { this.searchTerm = this.$route.params.searchTerm; @@ -109,8 +113,25 @@ export default { try { const res = await axios.get(url); + + // Format results into object keyed by record_type + const resultFormatted = res.data.data.reduce((acc, cur) => { + return { ...acc, [cur.record_type]: cur }; + }, {}); + + // Modify ui shape object to exclude any sections / data sources that do not have records returned by API + this.uiShape = SEARCH_RESULTS_UI_SHAPE.reduce((acc, cur) => { + const recordsFiltered = cur.records.filter( + (record) => resultFormatted[record.type], + ); + return recordsFiltered.length > 0 + ? [...acc, { header: cur.header, records: recordsFiltered }] + : acc; + }, []); + + // Set data and away we go this.searchStatusCode = res.status; - this.searchResult = res.data; + this.searchResult = resultFormatted; } catch (error) { this.searchStatusCode = error?.response?.status ?? 400; this.searchResult = error?.response?.data ?? {}; @@ -122,3 +143,9 @@ export default { }, }; + + From 540783a29e8af977e25a46bf8ce236de20f5ccd2 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 07:12:49 -0500 Subject: [PATCH 07/10] test(pages): update search results page test --- client/src/pages/SearchResultPage.vue | 22 +- .../searchResultPage.test.js.snap | 189 ++++++------------ .../pages/__tests__/searchResultPage.test.js | 7 +- 3 files changed, 68 insertions(+), 150 deletions(-) diff --git a/client/src/pages/SearchResultPage.vue b/client/src/pages/SearchResultPage.vue index e7107c80..ee413b08 100644 --- a/client/src/pages/SearchResultPage.vue +++ b/client/src/pages/SearchResultPage.vue @@ -5,9 +5,7 @@

Searching for "{{ searchTerm }}" in "{{ location }}". - Found {{ getResultsCopy() }}.

@@ -21,7 +19,11 @@ Loading results...

-
+

+ No results found. +

+ +

If you don't see what you need,

-

- No results found. -

-
({ + count: 0, searched: false, searchStatusCode: 200, searchResult: {}, @@ -101,8 +97,7 @@ export default { }, methods: { getResultsCopy() { - const count = this.searchResult?.data?.length; - return `${count} ${pluralize('result', count)}`; + return `${this.count} ${pluralize('result', this.count)}`; }, async search() { const url = `${ @@ -132,6 +127,7 @@ export default { // Set data and away we go this.searchStatusCode = res.status; this.searchResult = resultFormatted; + this.count = Object.entries(this.searchResult).length; } catch (error) { this.searchStatusCode = error?.response?.status ?? 400; this.searchResult = error?.response?.data ?? {}; diff --git a/client/src/pages/__tests__/__snapshots__/searchResultPage.test.js.snap b/client/src/pages/__tests__/__snapshots__/searchResultPage.test.js.snap index e6cf0c9c..b0190c24 100644 --- a/client/src/pages/__tests__/__snapshots__/searchResultPage.test.js.snap +++ b/client/src/pages/__tests__/__snapshots__/searchResultPage.test.js.snap @@ -4,106 +4,34 @@ exports[`SearchResultPage renders with data > Calls API and renders search resul

Data Sources Search results

-

Searching for "calls" in "Cook". Found 3 results. +

Searching for "calls" in "Cook". Found 1 result.

-
- -
-

Calls for Service for Cicero Police Department - IN

-

Record type

-
Calls for Service
-
-

Agency

-

Cicero Police Department - IN

-
- -

Time range

-

2016–Unknown end

-

Formats available

-
    -
  • [
  • -
  • ]
  • -
-
- - -
-
-
-

Calls for Service for Chicago Police Department - IL

-

Record type

-
Calls for Service
-
-

Agency

-

Chicago Police Department - IL

-
- -

Time range

-

2018–Unknown end

-

Formats available

-
    -
  • [
  • -
  • ]
  • -
-
+
+

If you don't see what you need, make a request  + +

+

To see these results in a table, view the full database  + +

+
+
+
+

Police & public interactions

+
+

311 Calls for City of Chicago

- -
-
-
-

311 Calls for City of Chicago

-

Record type

-
Calls for Service
-
-

Agency

-

Chicago Police Department - IL

-
- -

Time range

-

12/17/2018–Unknown end

-

Formats available

-
    -
  • [
  • -
  • '
  • -
  • C
  • -
  • S
  • -
  • V
  • -
  • '
  • -
  • ,
  • -
  • -
  • '
  • -
  • X
  • -
  • M
  • -
  • L
  • -
  • '
  • -
  • ,
  • -
  • -
  • '
  • -
  • R
  • -
  • D
  • -
  • F
  • -
  • '
  • -
  • ,
  • -
  • -
  • '
  • -
  • R
  • -
  • S
  • -
  • S
  • -
  • '
  • -
  • ]
  • -
-
- - +

Time range

+

12/17/2018–Unknown end

+

Formats available

+
    +
  • [
  • +
  • '
  • +
  • C
  • +
  • S
  • +
  • V
  • +
  • '
  • +
  • ,
  • +
  • +
  • '
  • +
  • X
  • +
  • M
  • +
  • L
  • +
  • '
  • +
  • ,
  • +
  • +
  • '
  • +
  • R
  • +
  • D
  • +
  • F
  • +
  • '
  • +
  • ,
  • +
  • +
  • '
  • +
  • R
  • +
  • S
  • +
  • S
  • +
  • '
  • +
  • ]
  • +
+
-
-
+ +
`; diff --git a/client/src/pages/__tests__/searchResultPage.test.js b/client/src/pages/__tests__/searchResultPage.test.js index 38a9653f..c24ac9e6 100644 --- a/client/src/pages/__tests__/searchResultPage.test.js +++ b/client/src/pages/__tests__/searchResultPage.test.js @@ -69,18 +69,15 @@ describe('SearchResultPage renders with data', () => { const searchTerm = wrapper.vm.searchTerm; const location = wrapper.vm.location; - const count = wrapper.vm.searchResult.count; expect( wrapper.get('[data-test="search-results-section-header-p"]').text(), ).toBe( - `Searching for "${searchTerm}" in "${location}". Found ${count} results.`, + `Searching for "${searchTerm}" in "${location}". Found ${wrapper.vm.getResultsCopy()}.`, ); }); test('renders search result count properly', () => { - // const count = wrapper.vm.searchResult.count; - expect(wrapper.get('[data-test="search-results-count"]').text()).toBe( `Found ${wrapper.vm.getResultsCopy()}.`, ); @@ -95,7 +92,7 @@ describe('SearchResultPage renders with data', () => { test('search results card count matches search results returned in data', () => { expect(wrapper.findAll('[data-test="search-results-cards"]').length).toBe( - wrapper.vm.searchResult.count, + wrapper.vm.count, ); }); }); From 9782adcf922487e2dede23871119e45ba2e00202 Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 07:13:04 -0500 Subject: [PATCH 08/10] test(pages): update quick search page test --- .../quickSearchPage.test.js.snap | 22 +------------------ .../pages/__tests__/quickSearchPage.test.js | 7 ++++-- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/client/src/pages/__tests__/__snapshots__/quickSearchPage.test.js.snap b/client/src/pages/__tests__/__snapshots__/quickSearchPage.test.js.snap index 91dd5e6c..124597ed 100644 --- a/client/src/pages/__tests__/__snapshots__/quickSearchPage.test.js.snap +++ b/client/src/pages/__tests__/__snapshots__/quickSearchPage.test.js.snap @@ -2,26 +2,6 @@ exports[`QuickSearchPage > is a Vue instance 1`] = `
-
-

Search our database

-

If you have a question to answer, we may already know about helpful data in your area. Learn more about the data here. -

-
-
-
- -
- - - -
-
- - - -
- -
-
+
`; diff --git a/client/src/pages/__tests__/quickSearchPage.test.js b/client/src/pages/__tests__/quickSearchPage.test.js index e447c0bb..bf2c2c5b 100644 --- a/client/src/pages/__tests__/quickSearchPage.test.js +++ b/client/src/pages/__tests__/quickSearchPage.test.js @@ -1,11 +1,14 @@ -import { mount } from '@vue/test-utils'; +import { shallowMount } from '@vue/test-utils'; import QuickSearchPage from '../QuickSearchPage.vue'; import { describe, expect, test } from 'vitest'; describe('QuickSearchPage', () => { test('is a Vue instance', () => { - const wrapper = mount(QuickSearchPage); + const wrapper = shallowMount(QuickSearchPage); expect(wrapper.vm).toBeTruthy(); expect(wrapper.html()).toMatchSnapshot(); }); }); + +// Shallow mounting this test for now. It's 1. not really testing much, and 2. erroring on `getRoutes` +// TODO: write an actual test for this. From d39d1fc9640c62c1233a0845e17432fc4331ddbf Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Thu, 29 Feb 2024 07:32:00 -0500 Subject: [PATCH 09/10] chore(cleanup): remove stray comment --- client/src/util/pageData.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/client/src/util/pageData.js b/client/src/util/pageData.js index 0f9f12ea..01bb8946 100644 --- a/client/src/util/pageData.js +++ b/client/src/util/pageData.js @@ -184,19 +184,3 @@ export const SEARCH_RESULTS_UI_SHAPE = [ ], }, ]; - -// example obj: -// { -// "airtable_uid": "rec00T2YLS2jU7Tbn", -// "data_source_name": "Calls for Service for Chicago Police Department - IL", -// "description": null, -// "record_type": "Calls for Service", -// "source_url": "https://informationportal.igchicago.org/911-calls-for-cpd-service/", -// "record_format": null, -// "coverage_start": "2019-01-01", -// "coverage_end": null, -// "agency_supplied": true, -// "agency_name": "Chicago Police Department - IL", -// "municipality": "Chicago", -// "state_iso": "IL" -// } From b1deeca112ccce84170813a9660a20f5e3b52fae Mon Sep 17 00:00:00 2001 From: Joshua Graber Date: Mon, 4 Mar 2024 16:37:56 -0500 Subject: [PATCH 10/10] test(pages): update search results --- client/src/pages/SearchResultPage.vue | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/src/pages/SearchResultPage.vue b/client/src/pages/SearchResultPage.vue index ee413b08..33c6ed2d 100644 --- a/client/src/pages/SearchResultPage.vue +++ b/client/src/pages/SearchResultPage.vue @@ -84,7 +84,6 @@ export default { data: () => ({ count: 0, searched: false, - searchStatusCode: 200, searchResult: {}, searchTerm: '', location: '', @@ -125,12 +124,9 @@ export default { }, []); // Set data and away we go - this.searchStatusCode = res.status; this.searchResult = resultFormatted; this.count = Object.entries(this.searchResult).length; } catch (error) { - this.searchStatusCode = error?.response?.status ?? 400; - this.searchResult = error?.response?.data ?? {}; console.error(error); } finally { this.searched = true;