-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* [SG-1950] -- MOHCD Calculator SG-1950 Added a new module for creating custom pages and widgets. First page/widget is MOHCD Calculator embed and its settings page. The setup will allow users to update content without having to update any config yml's, so users can update without having to update any code. Instruction: - Clear cache - Config import - Visit Calculator settings page in admin/config/system/sfgov-pages and go to the MOHCD calculator settings page. - Update all the settings and select the page to embed on. - Visit the test page via the link on the admin page or - Visit the embed page via the link on the admin page, after selecting a transaction node to embed on. * Javascript linting and cleanup * javascript linting and cleanup * Forgot the embed template and to enable the module * isset check to help remove some php warnings from the logs * [SG-1950] -- Theming of calculator. Changed custom javascript into a drupal ajax form setup. * Adjustment to mobile layout of calculator * Width adjustment of the calculator * Update to calculator setup and styling * Responsive styling * Set mohcd calculator permission to digital services. Also removed anonymous and authenticated permission to devel (anonymous permission for devel should definitely not be enabled) * [SG-1950] -- Clean up of code * Update to form to use numeric pad on mobile input * Cleanup of how the earliest and latest years are found. Better validation messaging. * Added ability to control the label and description of the calculator * [SG-1950] -- Better translation for calculator label and description
- Loading branch information
Showing
22 changed files
with
819 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
web/modules/custom/sfgov_amplitude/sfgov_amplitude.links.menu.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
sfgov_amplitude.admin: | ||
title: 'SF.Gov amplitude settings' | ||
title: 'SF.Gov Amplitude settings' | ||
description: 'Configure SF.Gov amplitude settings' | ||
parent: system.admin_config_development | ||
route_name: sfgov_amplitude.admin_settings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dist/ | ||
dist |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
module.exports = { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"scripts": { | ||
"build": "npm run build-css", | ||
"build-css": "postcss --verbose -d dist/css 'src/**/css/*.css'", | ||
"watch-css": "npm run build-css -- --watch", | ||
"watch": "npm run watch-css" | ||
}, | ||
"devDependencies": { | ||
"@csstools/postcss-sass": "^5.0.1", | ||
"npm-run-all": "^4.1.5", | ||
"postcss": "^8.4.18", | ||
"postcss-cli": "^10.0.0", | ||
"postcss-import": "^15.0.0", | ||
"postcss-scss": "^4.0.5", | ||
"prettier": "^2.5.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
name: 'SFGov Pages' | ||
type: module | ||
description: 'A module that contains source and configuration for custom built pages on sf.gov' | ||
core_version_requirement: ^8 || ^9 | ||
package: 'SF Gov' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mohcd_calculator: | ||
css: | ||
component: | ||
# src/mohcd/css/mohcd-calculator.css: { } | ||
dist/css/mohcd-calculator.css: { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
sfgov_pages.admin_config_sfgov_pages: | ||
route_name: sfgov_pages.admin_config_sfgov_pages | ||
parent: system.admin_config_development | ||
title: 'SF.Gov Pages' | ||
description: 'Configure custom SF.Gov pages and widgets, like the MOHCD calculator.' | ||
|
||
sfgov_pages.mohcd_bmr_valuation_calculator_settings_form: | ||
route_name: sfgov_pages.mohcd_bmr_valuation_calculator_settings_form | ||
parent: sfgov_pages.admin_config_sfgov_pages | ||
title: 'SF.Gov MOHCD BMR calculator' | ||
description: 'Configure settings and select the page to embed the MOHCD calculator.' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
/** | ||
* Implements hook_theme(). | ||
*/ | ||
function sfgov_pages_theme($existing, $type, $theme, $path) { | ||
return [ | ||
'input__textfield__mohcd_calculator_form__bmrcalculator_purchaseprice' => [ | ||
'base hook' => 'input', | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Implements hook_preprocess_node(). | ||
*/ | ||
function sfgov_pages_preprocess_node__transaction__full(&$variables) { | ||
$variables['#cache']['contexts'][] = 'url.query_args'; | ||
$node = $variables['node']; | ||
|
||
// Create the embed mchod calculator embed variable. | ||
$nid_to_embed_on = \Drupal::state()->get('sfgov_pages_mohcd_embed_page'); | ||
$variables['mohcd_embed'] = NULL; | ||
|
||
// If current transaction node matches the mohcd embed node... | ||
if ($node->id() == $nid_to_embed_on) { | ||
$variables['mohcd_embed'] = \Drupal::formBuilder()->getForm('\Drupal\sfgov_pages\mohcd\Form\CalculatorForm'); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
administer mohcd pages: | ||
title: 'Administer mohcd pages' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
sfgov_pages.admin_config_sfgov_pages: | ||
path: '/admin/config/system/sfgov-pages' | ||
defaults: | ||
_controller: '\Drupal\system\Controller\SystemController::systemAdminMenuBlockPage' | ||
_title: 'SF.Gov pages' | ||
requirements: | ||
_permission: 'access administration pages' | ||
|
||
sfgov_pages.mohcd_bmr_valuation_calculator_settings_form: | ||
path: '/admin/config/system/sfgov-pages/mohcd-bmr-valuation-calculator-settings' | ||
defaults: | ||
_form: '\Drupal\sfgov_pages\mohcd\Form\CalculatorSettingsForm' | ||
_title: 'SF.Gov MOHCD BMR valuation calculator settings' | ||
requirements: | ||
_permission: 'administer mohcd pages' | ||
|
||
sfgov_pages.mohcd_bmr_valuation_calculator: | ||
path: '/mohcd/calculator' | ||
defaults: | ||
_form: '\Drupal\sfgov_pages\mohcd\Form\CalculatorForm' | ||
_title: 'MOHCD Calculator' | ||
requirements: | ||
_permission: 'administer mohcd pages' |
238 changes: 238 additions & 0 deletions
238
web/modules/custom/sfgov_pages/src/mohcd/Form/CalculatorForm.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
<?php | ||
|
||
namespace Drupal\sfgov_pages\mohcd\Form; | ||
|
||
use Drupal\Core\Ajax\AjaxResponse; | ||
use Drupal\Core\Ajax\HtmlCommand; | ||
use Drupal\Core\Form\FormBase; | ||
use Drupal\Core\Form\FormStateInterface; | ||
use NumberFormatter; | ||
|
||
/** | ||
* MOHCD Calculator form. | ||
*/ | ||
class CalculatorForm extends FormBase { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getFormId() { | ||
return 'mohcd_calculator_form'; | ||
} | ||
|
||
/** | ||
* Return the calculator label | ||
*/ | ||
public function getLabel() { | ||
return \Drupal::state()->get('sfgov_pages_mohcd_label') ?? t('Calculate'); | ||
} | ||
|
||
/** | ||
* Return the calculator description/help text | ||
*/ | ||
public function getDescription() { | ||
return \Drupal::state()->get('sfgov_pages_mohcd_description') ?? t('Your purchase information can be found in the Promissory Note and closing documents.'); | ||
} | ||
|
||
/** | ||
* Return the current AMI | ||
*/ | ||
public function getCurrentYearAMI() { | ||
return \Drupal::state()->get('sfgov_pages_mohcd_currentYearAMI'); | ||
} | ||
|
||
/** | ||
* Get the complete year|AMI list | ||
*/ | ||
public function getYearAMIList(): array { | ||
$options = []; | ||
$yearAMI = \Drupal::state()->get('sfgov_pages_mohcd_yearAMI'); | ||
$yearAMIArray = preg_split('/\r\n|\r|\n/', $yearAMI); | ||
foreach($yearAMIArray as $yearAMI) { | ||
$value = explode("|", $yearAMI); | ||
$options[trim($value[0])] = trim($value[1]); | ||
} | ||
return $options; | ||
} | ||
|
||
/** | ||
* Get the least recent (earliest) year from the AMI list | ||
*/ | ||
public function getEarliestYear() { | ||
$options = $this->getYearAMIList(); | ||
$years = array_flip($options); | ||
return min($years); | ||
} | ||
|
||
/** | ||
* Get the most recent (latest) year from the AMI list | ||
*/ | ||
public function getLatestYear() { | ||
$options = $this->getYearAMIList(); | ||
$years = array_flip($options); | ||
return max($years); | ||
} | ||
|
||
/** | ||
* Return the AMI value for the given year. | ||
*/ | ||
public function getYearAMI($year) { | ||
$options = $this->getYearAMIList(); | ||
return $options[$year] ?? FALSE; | ||
} | ||
|
||
/** | ||
* Build the calculator. | ||
*/ | ||
public function buildForm(array $form, FormStateInterface $form_state) { | ||
$currentYearAMI = $this->getCurrentYearAMI(); | ||
|
||
$form['#tree'] = TRUE; | ||
|
||
$form['bmrCalculator'] = array( | ||
'#type' => 'fieldset', | ||
'#title' => t('@label', ['@label' => $this->getLabel()]), | ||
'#description' => t('@description', ['@description' => $this->getDescription()]), | ||
'#description_display' => 'before', | ||
); | ||
|
||
$form['bmrCalculator']['purchasePrice'] = [ | ||
'#id' => 'purchasePrice', | ||
'#type' => 'textfield', | ||
'#title' => t('Purchase price'), | ||
'#prefix' => '<div id="purchasePriceWrapper">', | ||
'#field_suffix' => '<div id="purchasePriceError"></div>', | ||
'#suffix' => '</div>', | ||
'#attributes' => [ | ||
'inputmode' => 'numeric', | ||
'pattern' => '[0-9]*', | ||
'minlength' => '4', | ||
'maxlength' => '12', | ||
], | ||
]; | ||
|
||
$form['bmrCalculator']['purchaseYear'] = [ | ||
'#id' => 'purchaseYear', | ||
'#type' => 'textfield', | ||
'#title' => t('Purchase year'), | ||
'#description' => t('Enter a year between @firstyear and @latestyear', [ | ||
'@firstyear' => $this->getEarliestYear(), | ||
'@latestyear' => $this->getLatestYear() | ||
]), | ||
'#prefix' => '<div id="purchaseYearWrapper">', | ||
'#field_suffix' => '<div id="purchaseYearError"></div>', | ||
'#suffix' => '</div>', | ||
'#attributes' => [ | ||
'inputmode' => 'numeric', | ||
'minlength' => '4', | ||
'maxlength' => '4', | ||
'pattern' => '[0-9]*', | ||
'min' => $this->getEarliestYear(), | ||
'max' => $this->getLatestYear(), | ||
], | ||
]; | ||
|
||
$form['bmrCalculator']['btnCalc'] = [ | ||
'#id' => 'btnCalc', | ||
'#type' => 'button', | ||
'#value' => t('Calculate'), | ||
'#attributes' => [ | ||
'class' => ['button button-primary'], | ||
], | ||
'#ajax' => [ | ||
'callback' => '::calculateBMRValuation', | ||
'effect' => 'fade', | ||
'progress' => array( | ||
'type' => 'none', | ||
'message' => t('Calculating...'), | ||
), | ||
], | ||
]; | ||
|
||
$form['bmrCalculator']['bmrValuation'] = [ | ||
'#type' => 'markup', | ||
'#markup'=> '<div id="bmrValuation"></div> ', | ||
]; | ||
|
||
$form['#attached']['library'][] = 'sfgov_pages/mohcd_calculator'; | ||
$form['#attached']['drupalSettings']['sfgov']['mohcd']['calculator']['currentYearAMI'] = $currentYearAMI; | ||
|
||
$form['#attributes']['class'][] = 'sfgov-section__content'; | ||
|
||
$form['#cache']['max-age'] = 0; | ||
|
||
return $form; | ||
} | ||
|
||
/** | ||
* Calculate the BMR Value and display on the form. | ||
*/ | ||
public function calculateBMRValuation(array $form, FormStateInterface $form_state): AjaxResponse { | ||
$ajax_response = new AjaxResponse(); | ||
|
||
$has_error = FALSE; | ||
$currentYearAMI = $this->getCurrentYearAMI(); | ||
$values = $form_state->getValues(); | ||
$purchasePrice = $values['bmrCalculator']['purchasePrice']; | ||
$purchaseYear = (int) $values['bmrCalculator']['purchaseYear']; | ||
$purchaseYearAMI = $this->getYearAMI($purchaseYear); | ||
|
||
// Assert the purchasePrice is valid | ||
$ajax_response->addCommand(new HtmlCommand('#purchasePriceError', '')); | ||
if (!$purchasePrice || !is_numeric($purchasePrice)) { | ||
$has_error = TRUE; | ||
$ajax_response->addCommand(new HtmlCommand('#purchasePriceError', t("Price must be in numbers only."))); | ||
} | ||
|
||
// Assert the purchaseYear is valid | ||
$ajax_response->addCommand(new HtmlCommand('#purchaseYearError', '')); | ||
if (!$purchaseYearAMI || !is_numeric($purchaseYearAMI)) { | ||
$has_error = TRUE; | ||
$ajax_response->addCommand(new HtmlCommand('#purchaseYearError ', t("Year must be 4 numbers."))); | ||
} | ||
|
||
// Assert the purchaseYear must be between the earliest and latest years. ##UNCOMMENT BELOW TO TRIGGER VALIDATION. | ||
// if ($purchaseYear && is_numeric($purchaseYear) && ($purchaseYear < $this->getEarliestYear() || $purchaseYear > $this->getLatestYear())) { | ||
// $has_error = TRUE; | ||
// $ajax_response->addCommand(new HtmlCommand('#purchaseYearError ', t('Year must be between @firstyear and @latestyear', [ | ||
// '@firstyear' => $this->getEarliestYear(), | ||
// '@latestyear' => $this->getLatestYear() | ||
// ]))); | ||
// } | ||
|
||
if (!$has_error) { | ||
$value = (int) round($purchasePrice + ($purchasePrice * (($currentYearAMI - $purchaseYearAMI) / $purchaseYearAMI))); | ||
|
||
$formatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY); | ||
$value = $formatter->formatCurrency($value, 'USD'); | ||
|
||
$text = []; | ||
|
||
$text['label'] = [ | ||
'#type' => 'markup', | ||
'#prefix' => '<div id="bmrValuationLabel">', | ||
'#markup' => t('Your current BMR valuation:'), | ||
'#suffix' => '</div>', | ||
]; | ||
|
||
$text['value'] = [ | ||
'#type' => 'markup', | ||
'#prefix' => '<div id="bmrValuationResults">', | ||
'#markup' => $value, | ||
'#suffix' => '</div>', | ||
]; | ||
|
||
$ajax_response->addCommand(new HtmlCommand('#bmrValuation', \Drupal::service('renderer')->render($text))); | ||
} else { | ||
$ajax_response->addCommand(new HtmlCommand('#bmrValuation', '')); | ||
} | ||
|
||
return $ajax_response; | ||
} | ||
|
||
// no validation handled in src/mohcd/js/mohcd-calculator.js | ||
public function validateForm(array &$form, FormStateInterface $form_state) {} | ||
|
||
// no submission, calculation handled in src/mohcd/js/mohcd-calculator.js | ||
public function submitForm(array &$form, FormStateInterface $form_state) {} | ||
} |
Oops, something went wrong.
cc1d0dc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Created multidev environment ci-18192 for sfgov.