diff --git a/Makefile b/Makefile index b47e39d78cc..f2c86cbc1e8 100644 --- a/Makefile +++ b/Makefile @@ -113,9 +113,15 @@ lint_yarn_lock: package.json yarn.lock lint_lockfiles: lint_gemfile_lock lint_yarn_lock ## Lints to ensure lockfiles are in sync -lintfix: ## Runs rubocop fix +lintfix: ## Try to automatically fix any ruby, ERB, javascript, or CSS lint errors @echo "--- rubocop fix ---" bundle exec rubocop -a + @echo "--- erblint fix ---" + bundle exec erblint app/views app/components -a + @echo "--- eslint fix ---" + yarn lint --fix + @echo "--- stylelint fix ---" + yarn lint:css --fix brakeman: ## Runs brakeman bundle exec brakeman @@ -159,8 +165,8 @@ run-https: tmp/$(HOST)-$(PORT).key tmp/$(HOST)-$(PORT).crt ## Runs the developme normalize_yaml: ## Normalizes YAML files (alphabetizes keys, fixes line length, smart quotes) yarn normalize-yaml .rubocop.yml --disable-sort-keys --disable-smart-punctuation - find ./config/locales/telephony -type f | xargs yarn normalize-yaml --disable-smart-punctuation - find ./config/locales -not -path "./config/locales/telephony*" -type f | xargs yarn normalize-yaml \ + find ./config/locales/telephony -type f -name '*.yml' | xargs yarn normalize-yaml --disable-smart-punctuation + find ./config/locales -not -path "./config/locales/telephony*" -type f -name '*.yml' | xargs yarn normalize-yaml \ config/pinpoint_supported_countries.yml \ config/pinpoint_overrides.yml \ config/country_dialing_codes.yml diff --git a/app/controllers/api/irs_attempts_api_controller.rb b/app/controllers/api/irs_attempts_api_controller.rb index 138d7768efc..e6719e600bf 100644 --- a/app/controllers/api/irs_attempts_api_controller.rb +++ b/app/controllers/api/irs_attempts_api_controller.rb @@ -20,7 +20,7 @@ class IrsAttemptsApiController < ApplicationController def create start_time = Time.zone.now.to_f if timestamp - if IdentityConfig.store.irs_attempt_api_aws_s3_enabled + if s3_helper.attempts_serve_events_from_s3 if IrsAttemptApiLogFile.find_by(requested_time: timestamp_key(key: timestamp)) log_file_record = IrsAttemptApiLogFile.find_by( requested_time: timestamp_key(key: timestamp), @@ -29,10 +29,8 @@ def create headers['X-Payload-Key'] = log_file_record.encrypted_key headers['X-Payload-IV'] = log_file_record.iv - bucket_name = IdentityConfig.store.irs_attempt_api_bucket_name - - requested_data = s3_client.get_object( - bucket: bucket_name, + requested_data = s3_helper.s3_client.get_object( + bucket: s3_helper.attempts_bucket_name, key: log_file_record.filename, ) @@ -102,8 +100,8 @@ def redis_client @redis_client ||= IrsAttemptsApi::RedisClient.new end - def s3_client - @s3_client ||= JobHelpers::S3Helper.new.s3_client + def s3_helper + @s3_helper ||= JobHelpers::S3Helper.new end def valid_auth_tokens diff --git a/app/javascript/packages/build-sass/CHANGELOG.md b/app/javascript/packages/build-sass/CHANGELOG.md index 3633966fa5e..86b50fbdca5 100644 --- a/app/javascript/packages/build-sass/CHANGELOG.md +++ b/app/javascript/packages/build-sass/CHANGELOG.md @@ -3,6 +3,7 @@ ### Improvements - Improves watch mode error recovery to monitor changes to all files in the stack trace of the error. +- Adds support for `--load-path=` flag to include additional default paths in Sass path resolution. ## 1.0.0 (2022-11-21) diff --git a/app/javascript/packages/build-sass/README.md b/app/javascript/packages/build-sass/README.md index 53b6bf3ccf3..5a3a7923731 100644 --- a/app/javascript/packages/build-sass/README.md +++ b/app/javascript/packages/build-sass/README.md @@ -22,13 +22,14 @@ Default behavior includes: Invoke the included `build-sass` executable with the source files and any relevant command flags. ``` -npx build-sass path/to/sass/*.css.scss --out-dir=build +npx build-sass path/to/sass/*.css.scss --out-dir=build --load-path=node_modules/@uswds/uswds/packages ``` Flags: - `--out-dir`: The output directory - `--watch`: Run in watch mode, recompiling files on change +- `--load-path`: Include additional path in Sass path resolution ### API diff --git a/app/javascript/packages/build-sass/cli.js b/app/javascript/packages/build-sass/cli.js index 1e514b0c139..a77f6c7d67e 100755 --- a/app/javascript/packages/build-sass/cli.js +++ b/app/javascript/packages/build-sass/cli.js @@ -20,9 +20,12 @@ const flags = args.filter((arg) => arg.startsWith('-')); const isWatching = flags.includes('--watch'); const outDir = flags.find((flag) => flag.startsWith('--out-dir='))?.slice(10); +const loadPaths = flags + .filter((flag) => flag.startsWith('--load-path=')) + .map((flag) => flag.slice(12)); /** @type {BuildOptions & SyncSassOptions} */ -const options = { outDir, optimize: isProduction }; +const options = { outDir, loadPaths, optimize: isProduction }; /** * Watches given file path(s), triggering the callback on the first change. diff --git a/app/javascript/packages/build-sass/index.js b/app/javascript/packages/build-sass/index.js index df99996fc53..cad1aae6e76 100644 --- a/app/javascript/packages/build-sass/index.js +++ b/app/javascript/packages/build-sass/index.js @@ -27,11 +27,11 @@ const TARGETS = browserslistToTargets( * @return {Promise} */ export async function buildFile(file, options) { - const { outDir, optimize, ...sassOptions } = options; + const { outDir, optimize, loadPaths = [], ...sassOptions } = options; const sassResult = sass.compile(file, { style: optimize ? 'compressed' : 'expanded', ...sassOptions, - loadPaths: ['node_modules'], + loadPaths: ['node_modules', ...loadPaths], quietDeps: true, }); diff --git a/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx b/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx index 8350cef79e2..bddb9cc5626 100644 --- a/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx +++ b/app/javascript/packages/document-capture/components/in-person-location-post-office-search-step.tsx @@ -11,11 +11,13 @@ import InPersonLocations, { FormattedLocation } from './in-person-locations'; interface PostOffice { address: string; city: string; + distance: string; name: string; phone: string; saturday_hours: string; state: string; sunday_hours: string; + tty: string; weekday_hours: string; zip_code_4: string; zip_code_5: string; @@ -37,11 +39,13 @@ const formatLocation = (postOffices: PostOffice[]) => { const location = { formattedCityStateZip: `${po.city}, ${po.state}, ${po.zip_code_5}-${po.zip_code_4}`, id: index, + distance: po.distance, name: po.name, phone: po.phone, saturdayHours: po.saturday_hours, streetAddress: po.address, sundayHours: po.sunday_hours, + tty: po.tty, weekdayHours: po.weekday_hours, } as FormattedLocation; formattedLocations.push(location); diff --git a/app/javascript/packages/document-capture/components/in-person-locations.tsx b/app/javascript/packages/document-capture/components/in-person-locations.tsx index 0c689105fb7..e0e98af4a8e 100644 --- a/app/javascript/packages/document-capture/components/in-person-locations.tsx +++ b/app/javascript/packages/document-capture/components/in-person-locations.tsx @@ -4,9 +4,11 @@ import LocationCollectionItem from './location-collection-item'; export interface FormattedLocation { formattedCityStateZip: string; + distance: string; id: number; name: string; phone: string; + tty: string; saturdayHours: string; streetAddress: string; sundayHours: string; @@ -47,10 +49,12 @@ function InPersonLocations({ locations, onSelect, address }: InPersonLocationsPr { .parentElement!; expect(sunHours.textContent).to.contain('Closed'); }); + + it('renders the component that includes contact information with expected data', () => { + const onClick = sinon.stub(); + const { getByText } = render( + , + ); + + const addressParent = getByText('123 Test Address').parentElement!; + expect(addressParent.textContent).to.contain('in_person_proofing.body.location.distance'); + expect(addressParent.textContent).to.contain('555-123-4567'); + expect(addressParent.textContent).to.contain('222-222-2222'); + }); }); diff --git a/app/javascript/packages/document-capture/components/location-collection-item.tsx b/app/javascript/packages/document-capture/components/location-collection-item.tsx index dbc67e46a30..6ce95be84ca 100644 --- a/app/javascript/packages/document-capture/components/location-collection-item.tsx +++ b/app/javascript/packages/document-capture/components/location-collection-item.tsx @@ -2,33 +2,47 @@ import { Button } from '@18f/identity-components'; import { useI18n } from '@18f/identity-react-i18n'; interface LocationCollectionItemProps { + distance?: string; formattedCityStateZip: string; handleSelect: (event: React.FormEvent, selection: number) => void; - name: string; + name?: string; + phone?: string; saturdayHours: string; selectId: number; streetAddress: string; sundayHours: string; + tty?: string; weekdayHours: string; } function LocationCollectionItem({ + distance, formattedCityStateZip, handleSelect, name, + phone, saturdayHours, selectId, streetAddress, sundayHours, + tty, weekdayHours, }: LocationCollectionItemProps) { const { t } = useI18n(); + const numericDistance = distance?.split(' ')[0]; return (
  • -

    {name}

    + {numericDistance && ( +

    + {t('in_person_proofing.body.location.distance', { + count: parseFloat(numericDistance), + })} +

    + )} + {!distance &&

    {name}

    }
    {`${t('in_person_proofing.body.location.retail_hours_sat')} ${saturdayHours}`}
    {`${t('in_person_proofing.body.location.retail_hours_sun')} ${sundayHours}`}
    + {(phone || tty) && ( +
    +

    {t('in_person_proofing.body.location.contact_info_heading')}

    +
    {`${t('in_person_proofing.body.location.phone')} ${phone}`}
    +
    {`${t('in_person_proofing.body.location.tty')} ${tty}`}
    +
    + )}