From fd2e4909f6563e493048bbad9eb00ccd0cc70ab2 Mon Sep 17 00:00:00 2001
From: Katrina Wheelan <katrina.wheelan@detroitmi.gov>
Date: Thu, 18 Jul 2024 16:44:50 -0400
Subject: [PATCH 1/4] #22 added place to save edit status of funds

---
 src/index.html                                   | 2 +-
 src/js/components/table/subcomponents/data.js    | 2 +-
 src/js/utils/data_utils/budget_data_handlers.js  | 8 +++++---
 src/js/views/02_baseline_landing_page/helpers.js | 4 ++--
 src/js/views/08_summary/helpers.js               | 3 ++-
 5 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/index.html b/src/index.html
index 4eb97e9..e85b8dc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -94,7 +94,7 @@ <h3 id="supp-title" class="accordion-title">
             <div class="accordion summary-accordion"></div>
         </div>
         <div class="add-init-btn-div">
-            <button class="btn btn-add-init">Add another initiative</button>
+            <button class="btn btn-add-init">Add new initiative</button>
         </div>        
     </div>
 
diff --git a/src/js/components/table/subcomponents/data.js b/src/js/components/table/subcomponents/data.js
index 9342721..7f28afb 100644
--- a/src/js/components/table/subcomponents/data.js
+++ b/src/js/components/table/subcomponents/data.js
@@ -62,7 +62,7 @@ function loadFunds(){
     for (const key in fundDict) {
         if (fundDict.hasOwnProperty(key)) {
             resultArray.push({
-                Fund: fundDict[key]     // Use the value directly
+                Fund: fundDict[key]['name']     // Use the value directly
             });
         }
     }
diff --git a/src/js/utils/data_utils/budget_data_handlers.js b/src/js/utils/data_utils/budget_data_handlers.js
index 598af9e..01e7426 100644
--- a/src/js/utils/data_utils/budget_data_handlers.js
+++ b/src/js/utils/data_utils/budget_data_handlers.js
@@ -8,13 +8,14 @@ export const FundLookupTable = {
     update : function(fundData){
         const table = this.retrieve();
         for (let fund of Object.keys(fundData)){
-            // fund = toString(fund);
             // add to lookup table if not in there already
             if (!table[fund]){
                 // get fund name
                 const fundName = fundData[fund][0]['Fund Name'];
                 // add fund to dictionary
-                table[fund] = fundName;
+                table[fund] = {};
+                table[fund]['name'] = fundName;
+                table[fund]['viewed'] = false;
             }
         }
         // save any updates
@@ -24,7 +25,8 @@ export const FundLookupTable = {
         this.save({});
     },
     getName : function(number){
-        return this.retrieve()[number];
+        if(number == '') { return '' };
+        return this.retrieve()[number]['name'];
     },
     listFunds : function(){
         return Object.keys(this.retrieve());
diff --git a/src/js/views/02_baseline_landing_page/helpers.js b/src/js/views/02_baseline_landing_page/helpers.js
index 6963fcd..a1d60e4 100644
--- a/src/js/views/02_baseline_landing_page/helpers.js
+++ b/src/js/views/02_baseline_landing_page/helpers.js
@@ -41,8 +41,8 @@ function allowRowSelection(){
     });
 }
 
-export async function initializeFundTable(){
-    await Table.Data.loadFunds();
+export function initializeFundTable(){
+    Table.Data.loadFunds();
     Table.adjustWidth('30%');
     Table.show();
     Table.Columns.assignClasses(fundCols);
diff --git a/src/js/views/08_summary/helpers.js b/src/js/views/08_summary/helpers.js
index 933e034..0315209 100644
--- a/src/js/views/08_summary/helpers.js
+++ b/src/js/views/08_summary/helpers.js
@@ -16,7 +16,7 @@ export function summaryView(){
 
     // prompt buttons
     Prompt.Buttons.Right.updateText('Download Excel');
-    Prompt.Buttons.Left.updateText('Go back to home');
+    Prompt.Buttons.Left.updateText('Start over');
     // add button links
     Prompt.Buttons.Left.addAction(returnToWelcome);
     Prompt.Buttons.Right.addAction(downloadXLSX);
@@ -47,4 +47,5 @@ const returnToWelcome = () => {visitPage('welcome')}
 export function disablePromptButtons(){
     Prompt.Buttons.Left.removeAction(returnToWelcome);
     Prompt.Buttons.Right.removeAction(downloadXLSX);
+    Prompt.Buttons.Right.enable();
 }
\ No newline at end of file

From 02a4939b19cc16ff2712b9c5edb0c58d732d309a Mon Sep 17 00:00:00 2001
From: Katrina Wheelan <katrina.wheelan@detroitmi.gov>
Date: Fri, 19 Jul 2024 12:20:15 -0400
Subject: [PATCH 2/4] #22 FundLookUp table records viewed funds; updated logic
 to cycle through funds

---
 src/js/components/accordion/accordion.css     |  4 +--
 src/js/components/nav_buttons/nav_buttons.js  |  8 +++++-
 src/js/components/table/subcomponents/data.js | 18 +++++++------
 src/js/utils/common_utils.js                  |  8 ------
 .../utils/data_utils/budget_data_handlers.js  | 23 +++++++++++++++++
 src/js/views/03_revenue/helpers.js            |  6 ++---
 src/js/views/06_nonpersonnel/helpers.js       |  5 ++--
 src/js/views/07_new_initiatives/helpers.js    |  6 ++---
 src/js/views/view_logic.js                    | 25 +++++++++++--------
 9 files changed, 64 insertions(+), 39 deletions(-)

diff --git a/src/js/components/accordion/accordion.css b/src/js/components/accordion/accordion.css
index 45257e7..998772e 100644
--- a/src/js/components/accordion/accordion.css
+++ b/src/js/components/accordion/accordion.css
@@ -18,7 +18,7 @@
 
 .accordion-table { 
     width: 100%;
-    font-size: 1.25em;
+    font-size: 1.2em;
     /* border-collapse: separate; This is required for rounded corners */
 }
 
@@ -49,7 +49,7 @@ span.amount {
 }
 
 .accordion-header button {
-    font-size: 0.8em;
+    font-size: 0.6em;
 }
 
 .btn-add-init {
diff --git a/src/js/components/nav_buttons/nav_buttons.js b/src/js/components/nav_buttons/nav_buttons.js
index e3c6e16..4d9d362 100644
--- a/src/js/components/nav_buttons/nav_buttons.js
+++ b/src/js/components/nav_buttons/nav_buttons.js
@@ -31,7 +31,13 @@ function enable(button_id) {
 
 const Next = {
     disable : function() { disable('btn-next') },
-    enable : function() { enable('btn-next') }
+    enable : function() { enable('btn-next') },
+    addAction : function(fn) {
+        document.querySelector(`#btn-next`).addEventListener('click', fn);
+    },
+    removeAction : function(fn) {
+        document.querySelector(`#btn-next`).removeEventListener('click', fn);
+    },
 }
 
 const Last = {
diff --git a/src/js/components/table/subcomponents/data.js b/src/js/components/table/subcomponents/data.js
index 7f28afb..a12a68d 100644
--- a/src/js/components/table/subcomponents/data.js
+++ b/src/js/components/table/subcomponents/data.js
@@ -58,15 +58,17 @@ function loadFunds(){
     // get list of funds from storage
     const fundDict = FundLookupTable.retrieve();
     // build out data in correct format
-    const resultArray = [];
-    for (const key in fundDict) {
-        if (fundDict.hasOwnProperty(key)) {
-            resultArray.push({
-                Fund: fundDict[key]['name']     // Use the value directly
-            });
+    const ret = [];
+    Object.keys(fundDict).forEach(key => {
+        // determine if the fund has already been edited
+        if (fundDict[key]['viewed']){
+            // todo: add a checkmark here
+            ret.push({'Fund' : fundDict[key]['name'] + ' (Edited)'});
+        } else {
+            ret.push({'Fund' : fundDict[key]['name']});   
         }
-    }
-    fillTable(resultArray);
+    });
+    fillTable(ret);
 }
 
 
diff --git a/src/js/utils/common_utils.js b/src/js/utils/common_utils.js
index 17e13a4..3e92ad2 100644
--- a/src/js/utils/common_utils.js
+++ b/src/js/utils/common_utils.js
@@ -32,14 +32,6 @@ export function displayWithCommas(value) {
     return formatCurrency(value).replace('$', '');
 }
 
-function delay(ms) {
-    return new Promise(resolve => setTimeout(resolve, ms));
-}
-
-export async function pauseExecution(seconds) {
-    await delay(seconds * 1000); // convert to milliseconds
-}
-
 export function cleanString(str){
     return str.toLowerCase().replaceAll(' ', '-');
 }
diff --git a/src/js/utils/data_utils/budget_data_handlers.js b/src/js/utils/data_utils/budget_data_handlers.js
index 01e7426..0a80041 100644
--- a/src/js/utils/data_utils/budget_data_handlers.js
+++ b/src/js/utils/data_utils/budget_data_handlers.js
@@ -30,6 +30,29 @@ export const FundLookupTable = {
     },
     listFunds : function(){
         return Object.keys(this.retrieve());
+    },
+    editFund : function(fund){
+        const table = this.retrieve();
+        if (table[fund]){
+            table[fund]['viewed'] = true;
+            this.save(table);
+        } else {
+            console.error('No fund selected.');
+        }
+        
+    },
+    listUneditedFunds : function(){
+        const table = this.retrieve();
+        const ret = [];
+        this.listFunds().forEach(key => {
+            if (!table[key]['viewed']){
+                ret.push(key);
+            }
+        });
+        return ret;
+    },
+    fundsLeft : function(){
+        return (this.listUneditedFunds().length > 0);
     }
 }
 
diff --git a/src/js/views/03_revenue/helpers.js b/src/js/views/03_revenue/helpers.js
index 47d8d2e..06709c5 100644
--- a/src/js/views/03_revenue/helpers.js
+++ b/src/js/views/03_revenue/helpers.js
@@ -3,7 +3,7 @@ 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 { pauseAndContinue } from '../view_logic.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'
@@ -23,7 +23,7 @@ export function preparePageView(){
 
 export function setUpNavButtons(){
     // clicking 'confirm' will also take us to the next page
-    Prompt.Buttons.Left.addAction(pauseAndContinue);
+    Prompt.Buttons.Left.addAction(nextPage);
     // TODO: allow user to edit revenue here
     Modal.Link.add('option2');
     handleErrorComment();
@@ -31,7 +31,7 @@ export function setUpNavButtons(){
 
 export function removeButtonEvents(){
     // remove event listeners on prompt buttons
-    Prompt.Buttons.Left.removeAction(pauseAndContinue);
+    Prompt.Buttons.Left.removeAction(nextPage);
     Modal.Link.remove('option2');
 }
 
diff --git a/src/js/views/06_nonpersonnel/helpers.js b/src/js/views/06_nonpersonnel/helpers.js
index c31d998..a24a960 100644
--- a/src/js/views/06_nonpersonnel/helpers.js
+++ b/src/js/views/06_nonpersonnel/helpers.js
@@ -4,6 +4,8 @@ import Table from "../../components/table/table.js";
 import Body from "../../components/body/body.js";
 import NavButtons from "../../components/nav_buttons/nav_buttons.js";
 import Subtitle from "../../components/header/header.js";
+import { FundLookupTable } from "../../utils/data_utils/budget_data_handlers.js";
+import { CurrentFund } from "../../utils/data_utils/local_storage_handlers.js";
 
 const nonPersonnelColumns = [
     { title: 'FY26 Request', className: 'request', isCost: true },
@@ -26,9 +28,6 @@ export function preparePageView(){
     // update page text
     Subtitle.update('Non-Personnel');
     Prompt.Text.update('Select an action item for each non-personnel line item from last year.');
-
-    // just enable next for now
-    // TODO: only enable when all info is entered
     NavButtons.Next.enable();
 }
 
diff --git a/src/js/views/07_new_initiatives/helpers.js b/src/js/views/07_new_initiatives/helpers.js
index 7e65a27..62ee00e 100644
--- a/src/js/views/07_new_initiatives/helpers.js
+++ b/src/js/views/07_new_initiatives/helpers.js
@@ -5,7 +5,7 @@ import Form from '../../components/form/form.js'
 import Table from '../../components/table/table.js'
 import Body from '../../components/body/body.js'
 import NavButtons from '../../components/nav_buttons/nav_buttons.js'
-import { pauseAndContinue } from '../view_logic.js'
+import { nextPage } from '../view_logic.js'
 import Subtitle from '../../components/header/header.js'
 import Sidebar from '../../components/sidebar/sidebar.js'
 
@@ -28,7 +28,7 @@ export function initializePageView() {
     Prompt.Buttons.Left.updateText('Yes');
     Prompt.Buttons.Right.updateText('No');
     // clicking 'no new initialitives' will also take us to the next page
-    Prompt.Buttons.Right.addAction(pauseAndContinue);
+    Prompt.Buttons.Right.addAction(nextPage);
     Prompt.Buttons.Left.addAction(NavButtons.Next.enable);
 }
 
@@ -114,7 +114,7 @@ export function removeModalLinks(){
 }
 
 export function removePromptButtonListeners(){
-    Prompt.Buttons.Right.removeAction(pauseAndContinue);
+    Prompt.Buttons.Right.removeAction(nextPage);
     Prompt.Buttons.Left.removeAction(NavButtons.Next.enable);
     Modal.clear();
 }
\ No newline at end of file
diff --git a/src/js/views/view_logic.js b/src/js/views/view_logic.js
index f4a9448..581483c 100644
--- a/src/js/views/view_logic.js
+++ b/src/js/views/view_logic.js
@@ -7,9 +7,8 @@ import { loadNonpersonnelPage } from './06_nonpersonnel/main.js';
 import { loadBaselineLandingPage } from './02_baseline_landing_page/main.js';
 import { cleanUpSummaryPage, loadSummaryPage } from './08_summary/main.js';
 import { loadUploadPage } from './01_upload/main.js';
-import { pauseExecution } from '../utils/common_utils.js';
-
-import { CurrentPage } from '../utils/data_utils/local_storage_handlers.js';
+import { CurrentPage, CurrentFund } from '../utils/data_utils/local_storage_handlers.js';
+import { FundLookupTable } from '../utils/data_utils/budget_data_handlers.js';
 
 export let PAGES = {
     'welcome' : initializeWelcomePage,
@@ -50,10 +49,19 @@ export function nextPage(){
 
     // clean up current page
     if (CLEANUP[page_state]) { CLEANUP[page_state]() };
-    
-    // Check if there is a next key
+
+    // if on non-personnel, circle back to fund selection unless all funds are edited
+    if (CurrentPage.load() == 'nonpersonnel'){
+        // mark fund as viewed/edited
+        FundLookupTable.editFund(CurrentFund.number());
+        // if any funds left to edit, go back to that page
+        if ( FundLookupTable.fundsLeft() ){
+            visitPage('baseline-landing');
+            return;
+        }
+    }
     if (currentIndex >= 0 && currentIndex < keys.length - 1) {
-        // Get the next key
+        // Check if there is a next key, and get it
         const nextKey = keys[currentIndex + 1];
         // go to that page
         visitPage(nextKey);
@@ -78,9 +86,4 @@ export function lastPage(){
         // go to that page
         visitPage(lastKey);
     } 
-}
-
-export async function pauseAndContinue(){
-    await pauseExecution(0.1);
-    nextPage();
 }
\ No newline at end of file

From 162495cf61f853bf64b350bf34524569e56b212e Mon Sep 17 00:00:00 2001
From: Katrina Wheelan <katrina.wheelan@detroitmi.gov>
Date: Fri, 19 Jul 2024 15:37:59 -0400
Subject: [PATCH 3/4] #22 use fontawesome to add a checkmark next to edited
 funds

---
 src/css/common.css                            | 12 ++++++++++--
 src/index.html                                |  2 ++
 src/js/components/table/subcomponents/data.js | 11 ++++++++---
 src/js/components/table/table.css             |  7 ++++++-
 4 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/src/css/common.css b/src/css/common.css
index b6e336a..26127be 100644
--- a/src/css/common.css
+++ b/src/css/common.css
@@ -53,6 +53,14 @@ body, button, input, textarea, select, .sidebar, table {
     margin: 0;
 }
 
-div.row {
+/* Font awesome */
+
+i.fas.fa-check { 
+    font-size: 1.5em;
+    color: var(--spiritgreen);
+    margin-right: 10px;
+}
+
+/* div.row {
     margin: 0px;
-}
\ No newline at end of file
+} */
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index e85b8dc..8e1d261 100644
--- a/src/index.html
+++ b/src/index.html
@@ -9,6 +9,8 @@
 <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
 <!-- Google fonts -->
 <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;700&display=swap" rel="stylesheet">
+<!-- Font Awesome CSS -->
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
 <!-- Bootstrap JS and its dependencies (jQuery & Popper.js) -->
 <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" crossorigin="anonymous"></script>
 <script src="https://cdn.jsdelivr.net/npm/popper.js@1.9.4/dist/umd/popper.min.js" crossorigin="anonymous"></script>
diff --git a/src/js/components/table/subcomponents/data.js b/src/js/components/table/subcomponents/data.js
index a12a68d..809ac0c 100644
--- a/src/js/components/table/subcomponents/data.js
+++ b/src/js/components/table/subcomponents/data.js
@@ -25,7 +25,7 @@ function fillTable(data) {
             const row = document.createElement('tr');
             Object.values(item).forEach(val => {
             const cell = document.createElement('td');
-            cell.textContent = val;
+            cell.innerHTML = val;
             row.appendChild(cell);
             });
             tbody.appendChild(row);
@@ -63,9 +63,14 @@ function loadFunds(){
         // determine if the fund has already been edited
         if (fundDict[key]['viewed']){
             // todo: add a checkmark here
-            ret.push({'Fund' : fundDict[key]['name'] + ' (Edited)'});
+            ret.push({'Fund' :  `<span class = 'viewed-fund'> 
+                                    <i class="fas fa-check"></i>
+                                    ${fundDict[key]['name']}
+                                </span>`});
         } else {
-            ret.push({'Fund' : fundDict[key]['name']});   
+            ret.push({'Fund' : `<span class = 'unviewed-fund'> 
+                                    ${fundDict[key]['name']}
+                                </span>`});   
         }
     });
     fillTable(ret);
diff --git a/src/js/components/table/table.css b/src/js/components/table/table.css
index a8c20ad..5f2f784 100644
--- a/src/js/components/table/table.css
+++ b/src/js/components/table/table.css
@@ -96,4 +96,9 @@ div.table-container {
 .hover-effect:hover {
     cursor: pointer;
     background-color: var(--verypalegreen); 
-}
\ No newline at end of file
+}
+
+/* Fund table */
+.fund-name > .viewed-fund {
+    color: gray;
+}

From 4765d5ab2ef7870f9e6f953fc2b169ff68f7154d Mon Sep 17 00:00:00 2001
From: Katrina Wheelan <katrina.wheelan@detroitmi.gov>
Date: Fri, 19 Jul 2024 15:59:53 -0400
Subject: [PATCH 4/4] #22 redirect to summary page after edit from summary page

---
 src/js/views/08_summary/helpers.js | 7 ++++++-
 src/js/views/view_logic.js         | 8 ++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/js/views/08_summary/helpers.js b/src/js/views/08_summary/helpers.js
index 0315209..21dd1ea 100644
--- a/src/js/views/08_summary/helpers.js
+++ b/src/js/views/08_summary/helpers.js
@@ -5,15 +5,20 @@ import Subtitle from "../../components/header/header.js";
 import { visitPage } from "../view_logic.js";
 import { Accordion } from "../../components/accordion/accordion.js";
 import { downloadXLSX } from "../../utils/data_utils/XLSX_handlers.js";
-import { Baseline } from '../../utils/data_utils/local_storage_handlers.js';
+import { Baseline, CurrentFund } from '../../utils/data_utils/local_storage_handlers.js';
 import { TARGET } from '../../init.js';
 import { formatCurrency } from '../../utils/common_utils.js';
 
 export function summaryView(){
+
+    // show/hide elements
     Body.reset();
     Accordion.build();
     Accordion.show();
 
+    // set fund to none
+    CurrentFund.reset();
+
     // prompt buttons
     Prompt.Buttons.Right.updateText('Download Excel');
     Prompt.Buttons.Left.updateText('Start over');
diff --git a/src/js/views/view_logic.js b/src/js/views/view_logic.js
index 581483c..b32751d 100644
--- a/src/js/views/view_logic.js
+++ b/src/js/views/view_logic.js
@@ -60,6 +60,14 @@ export function nextPage(){
             return;
         }
     }
+
+    // unless on personnel (which will go to overtime), return to summary if all funds are viewed
+    const returnPages = ['revenue', 'nonpersonnel', 'new-inits', 'overtime'];
+    if (!FundLookupTable.fundsLeft() && returnPages.includes(CurrentPage.load())) {
+        visitPage('summary');
+        return;
+    }
+
     if (currentIndex >= 0 && currentIndex < keys.length - 1) {
         // Check if there is a next key, and get it
         const nextKey = keys[currentIndex + 1];