Skip to content

Commit

Permalink
Merge pull request #48 from kwheelan/4-revenue-table
Browse files Browse the repository at this point in the history
4 revenue table
  • Loading branch information
kwheelan authored Jul 24, 2024
2 parents 3cd6f10 + 94f75bc commit cf9d147
Show file tree
Hide file tree
Showing 14 changed files with 186 additions and 125 deletions.
Binary file modified sample_data/sample_detail_sheet.xlsx
Binary file not shown.
10 changes: 10 additions & 0 deletions src/js/components/form/form.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,14 @@ textarea, input {
width: 60%;
margin-left: 20%;
background-color: var(--spiritgreen);
}

#new-form label {
display: block; /* Ensure label is on its own line */
margin-bottom: 0.5em;
}

#new-form select {
margin: auto;
width: 300px;
}
18 changes: 9 additions & 9 deletions src/js/components/form/subcomponents/dropdown.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
async function createDropdownFromJSON(json_path) {
// Fetch JSON data from a file asynchronously
const response = await fetch(json_path);
const dataArray = await response.json();
// create and return element
return createDropdown(dataArray);
}
// async function createDropdownFromJSON(json_path) {
// // Fetch JSON data from a file asynchronously
// const response = await fetch(json_path);
// const dataArray = await response.json();
// // create and return element
// return createDropdown(dataArray);
// }

function createDropdown(dataArray) {

Expand All @@ -25,8 +25,8 @@ function createDropdown(dataArray) {


export const Dropdown = {
createFromJSON : function(json_path){ return createDropdownFromJSON(json_path) },
create : function(dataArray) { return createDropdown(dataArray) }
// createFromJSON : function(json_path){ return createDropdownFromJSON(json_path) },
create : function(dataArray) { return createDropdown(dataArray) },
}

export default Dropdown;
42 changes: 21 additions & 21 deletions src/js/components/form/subcomponents/fields.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
// function to add questions to forms
// type is 'input' or 'textarea'

import Dropdown from "./dropdown";

// inputType is for validation ('number' or 'text', etc)
function appendFormElement(type, label, inputId, required, inputType, form_id = 'new-form', cost = false) {
function appendFormElement(label, inputEl, inputId, required) {

// change if we want forms elsewhere
const form = document.getElementById(form_id);
const form = document.getElementById('new-form');

// create outer wrapper for element
const wrapper = document.createElement('div');

// label question
const labelEl = document.createElement('label');
labelEl.textContent = label;

// set type (input or textarea)
let inputEl;
if (type === 'input') {
inputEl = document.createElement('input');
inputEl.type = inputType;
} else if (type === 'textarea') {
inputEl = document.createElement('textarea');
} else {
throw new Error('Unsupported element type');
}


// mark as required if applicable
inputEl.required = required;

Expand All @@ -39,14 +30,23 @@ function appendFormElement(type, label, inputId, required, inputType, form_id =
}

export const NewField = {
shortText : function(label, inputId, required = false, form_id = 'new-form', cost = false) {
appendFormElement('input', label, inputId, required, 'text', form_id);
shortText : function(label, inputId, required = false) {
const inputEl = document.createElement('input');
inputEl.type = 'text';
appendFormElement(label, inputEl, inputId,required);
},
longText : function(label, inputId, required = false) {
const inputEl = document.createElement('textarea');
appendFormElement(label, inputEl, inputId, required);
},
longText : function(label, inputId, required = false, form_id = 'new-form', cost = false) {
appendFormElement('textarea', label, inputId, required, form_id);
numericInput : function(label, inputId, required = false) {
const inputEl = document.createElement('input');
inputEl.type = 'number';
appendFormElement(label, inputEl, inputId,required);
},
numericInput: function(label, inputId, required = false, form_id = 'new-form', cost = true) {
appendFormElement('input', label, inputId, required, 'number', form_id);
dropdown : function(label, inputId, optionArray, required = false){
var inputEl = Dropdown.create(optionArray);
appendFormElement(label, inputEl, inputId, required);
}
}

Expand Down
16 changes: 8 additions & 8 deletions src/js/components/table/subcomponents/cells.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,24 @@ function createEditableCell(cellClass, isCost){
textbox.type = 'text';
if (isCost){
var value = cell.getAttribute('value');
textbox.value = displayWithCommas(value);
} else {
var value = cell.textContent;
textbox.value = cell.textContent;
}
textbox.value = displayWithCommas(value);
// Clear the current content and append the textbox to the cell
cell.innerHTML = '';
cell.appendChild(textbox);
}

function createServiceDropdown(){
function createDropdown(cellClass, optionArray){
// get cell
var cellClass = 'service';
const cell = document.querySelector(`.active-editing td.${cellClass}`);
// add service dropdown
const serviceDropdown = Dropdown.create(Services.list());
serviceDropdown.value = cell.textContent;
const dropdown = Dropdown.create(optionArray);
dropdown.value = cell.textContent;
// Clear the current content and append the textbox to the cell
cell.innerHTML = '';
cell.appendChild(serviceDropdown);
cell.appendChild(dropdown);
}

const Cell = {
Expand All @@ -68,7 +67,8 @@ const Cell = {
createTextbox : function(className, isCost) {
createEditableCell(className, isCost)
},
createServiceDropdown : createServiceDropdown
createServiceDropdown : () => { createDropdown('service', Services.list()) },
createDropdown : createDropdown
};

export default Cell;
4 changes: 4 additions & 0 deletions src/js/components/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ export const Tooltip = {
linkAllNP : function() {
this.linkAccountStringCol();
this.linkCPACol();
},

linkAllRevenue : function() {
this.linkAccountStringCol();
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/js/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { CurrentPage } from './utils/data_utils/local_storage_handlers.js';

// temporary hard-coding
export let REVENUE = 0;
export let TARGET = 14000000;
export let TARGET = 10000000;
// Set to equal current fiscal year
export var FISCAL_YEAR = '26';

Expand Down
22 changes: 18 additions & 4 deletions src/js/utils/data_utils/local_storage_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class StoredTable {
case 'nonpersonnel':
return `FY${FISCAL_YEAR} Request`;
case 'revenue':
break;
return `Departmental Request Total`;
default:
break;
}
Expand All @@ -106,7 +106,9 @@ function colSum(table, colName) {
if (headers.includes(colName)) {
let sum = 0;
for (let i = 0; i < table.length; i++){
sum += Math.round(parseFloat(table[i][colName]));
var value = Math.round(parseFloat(table[i][colName]));
// treat NaN (non-numerics) as zeroes
if (value) { sum += value; }
}
return sum;
} else {
Expand Down Expand Up @@ -188,9 +190,21 @@ export class Initiative {
this.name = row['Initiative Name'];
}

expenses() { return this.data['Ballpark Total Expenses']}
expenses() {
if (this.data['Ballpark Total Expenses']) {
return this.data['Ballpark Total Expenses'];
} else {
return 0;
}
}

revenue() { return this.data['Revenue'] }
revenue() {
if (this.data['Revenue']) {
return this.data['Revenue'];
} else {
return 0;
}
}

net() { return this.expenses() - this.revenue() }

Expand Down
89 changes: 47 additions & 42 deletions src/js/views/03_revenue/helpers.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,65 @@
import Prompt from '../../components/prompt/prompt.js'
import { formatCurrency } from '../../utils/common_utils.js'
import { REVENUE } from '../../init.js'
import Body from '../../components/body/body.js'
import NavButtons from '../../components/nav_buttons/nav_buttons.js'
import { nextPage } from '../view_logic.js'
import Subtitle from '../../components/header/header.js'
import Modal from '../../components/modal/modal.js'
import Form from '../../components/form/form.js'
import Sidebar from '../../components/sidebar/sidebar.js'
import Table from '../../components/table/table.js'
import Tooltip from '../../components/tooltip/tooltip.js'

const revenueColumns = [
{ title: 'Edit', className : 'edit' },
{ title : 'Account String', className : 'account-string'},
{ title: 'Recurring or One-Time', className: 'recurring'},
{ title: 'Object Category', className: 'object-category'},
{ title: 'Departmental Request Total', className: 'request', isCost: true},
{ title: 'Departmental Request Notes', className: 'notes'},

// hidden columns used for calcs and info boxes
{ title: 'Appropriation Name', className: 'approp-name', hide: true },
{ title: 'Cost Center Name', className: 'cc-name', hide: true },
{ title: 'Object Name', className: 'object-name', hide: true}
];

export function preparePageView(){
// prepare page view
Body.reset();
NavButtons.show();
Sidebar.show();
Table.adjustWidth('100%');

// update page text
Subtitle.update('Revenue Projections');
// TODO: update to make dynamic
Prompt.Text.update(`Your revenue projection for FY26 is ${formatCurrency(REVENUE, true)}`);
Prompt.Buttons.Left.updateText('Confirm');
Prompt.Buttons.Right.updateText("This doesn't look right");
}
Subtitle.update('Revenues');

export function setUpNavButtons(){
// clicking 'confirm' will also take us to the next page
Prompt.Buttons.Left.addAction(nextPage);
// TODO: allow user to edit revenue here
Modal.Link.add('option2');
handleErrorComment();
}
// set up table
initializeRevTable()

export function removeButtonEvents(){
// remove event listeners on prompt buttons
Prompt.Buttons.Left.removeAction(nextPage);
Modal.Link.remove('option2');
}
// enable continue button
NavButtons.Next.enable();

Prompt.Text.update('Review and edit revenue line items.');

function handleErrorComment(){
var fund = localStorage.getItem("fund");
Modal.clear();
Modal.Title.update(`Comment on ${fund} Revenue`);
Form.new('modal-body');
Form.NewField.longText('Explain your concerns here. Someone from the revenue team will follow up with you.',
'revenue-comment', true);
Form.SubmitButton.add();
// save comment on submission
Modal.Submit.init(handleRevenueCommentSubmission);
}

function handleRevenueCommentSubmission(event){
// get data from form in modal
const responses = Form.fetchAllResponses(event);
// TODO: save comment here
export async function initializeRevTable(){
// load table data from storage
if(await Table.Data.load()) {
//after table is loaded, fill it
Table.show();
Table.Columns.addAtEnd(Table.Buttons.edit_confirm_btns, "Edit");
// assign cost classes
Table.Columns.assignClasses(revenueColumns);
// enable editing
Table.Buttons.Edit.init(revRowOnEdit, Table.save);
// show info boxes on click
Tooltip.linkAllRevenue();
} else {
Prompt.Text.update('No revenues for this fund.')
}
}

// hide modal, update page, and enable continue
Modal.hide();
Prompt.Buttons.hide();
Prompt.Text.update('Your comment has been received.');
NavButtons.Next.enable();
function revRowOnEdit(){
// make it editable
Table.Cell.createTextbox('request', true);
Table.Cell.createTextbox('notes');
Table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);
}
6 changes: 1 addition & 5 deletions src/js/views/03_revenue/main.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { CurrentPage } from '../../utils/data_utils/local_storage_handlers.js'
import { preparePageView, removeButtonEvents, setUpNavButtons } from './helpers.js'
import { preparePageView } from './helpers.js'

export function loadRevenuePage() {

//update page state
CurrentPage.update('revenue');
preparePageView();
setUpNavButtons();
}

export function cleanupRevenuePage() {
removeButtonEvents();
};
1 change: 1 addition & 0 deletions src/js/views/05_overtime/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function OTRowOnEdit(){
Table.Cell.createTextbox('OT-wages', true);
Table.Cell.createTextbox('OT-salary', true);
Table.Cell.createServiceDropdown(Services.list());
Table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);
}

export async function initializeOTTable(){
Expand Down
3 changes: 2 additions & 1 deletion src/js/views/06_nonpersonnel/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function preparePageView(){
Table.adjustWidth('100%');
// update page text
Subtitle.update('Non-Personnel');
Prompt.Text.update('Select an action item for each non-personnel line item from last year.');
Prompt.Text.update('Review and edit non-personnel line items.');
NavButtons.Next.enable();
}

Expand All @@ -59,5 +59,6 @@ function nonPersonnelRowOnEdit(){
// make it editable
Table.Cell.createTextbox('request', true);
Table.Cell.createServiceDropdown();
Table.Cell.createDropdown('recurring', ['One-Time', 'Recurring']);
}

Loading

0 comments on commit cf9d147

Please sign in to comment.