diff --git a/front/current/assets/styles/components/_global.scss b/front/current/assets/styles/components/_global.scss index 2a470360a5c36ce8ded8a7f40eddc64086c76383..3b56ff9d2553b2aeb6c7308fc818f99cc555c61f 100644 --- a/front/current/assets/styles/components/_global.scss +++ b/front/current/assets/styles/components/_global.scss @@ -110,7 +110,6 @@ address { font-style: normal; } input[type=file].hidden { width: 0.1px; height: 0.1px; - position: absolute; opacity: 0; overflow: hidden; z-index: -1; diff --git a/front/current/assets/styles/components/_project-list.scss b/front/current/assets/styles/components/_project-list.scss index 397f130156856d81b3944c325cbfac36437c7ac3..ce855ed2c9b1035abb605d3a4527840cfd345e49 100644 --- a/front/current/assets/styles/components/_project-list.scss +++ b/front/current/assets/styles/components/_project-list.scss @@ -23,7 +23,7 @@ project-list { } th { text-transform: uppercase; - font-weight: normal; + font-weight: bold; text-align: left; color: $gray-02; } diff --git a/front/current/assets/styles/components/_project.scss b/front/current/assets/styles/components/_project.scss index dedb30de6fa87cf7c39f5cc56787da948cb8925a..7863b3ba51450ae1632b0d365e703a81a02377e5 100644 --- a/front/current/assets/styles/components/_project.scss +++ b/front/current/assets/styles/components/_project.scss @@ -9,6 +9,9 @@ project { display: flex; flex-direction: column; flex-grow: 1; + width:0px;//Setting the width anything less than expanding width of flexgrow + // causes the with of all child elements to be relative to this + // element's width. So we use 0 as a placeholder. header { display: flex; @@ -59,10 +62,62 @@ project { } document-slots { - display: block; - flex-grow: 1; - overflow: auto; - padding: 10px; + overflow-x: auto; + overflow-y: auto; + white-space: nowrap; + + .timeline-track { + width: 100%; + height: 10px; + background: $light-gray; + position: relative; + top: 45px; + } + + state { + display: inline-block; + vertical-align: top; + width: 600px; + + .content_padding { + padding-left : 10px; + padding-right: 10px; + padding-bottom: 10px; + } + + h3 { + color: gray; + padding-bottom:10px; + margin-top: 15px; + } + + p { + color: #838383; + white-space: normal; + } + + .oval{ + position: relative; + width: auto; + display: table; + height: 80px; + background: $light-gray; + border-radius: 40px; + + padding: 20px; + + margin-left: 20px; + margin-right: 40px; + + h3 { + display: table-cell; + padding: 0; + text-align: center; + vertical-align: middle; + color: $white; + } + } + } document-slot { display: block; diff --git a/front/current/components/project/detail.component.ts b/front/current/components/project/detail.component.ts index 63500c4490910fe7385b6818f9e0cb1f68323d2c..14adba223ca639984a06807893dec439a65437d8 100644 --- a/front/current/components/project/detail.component.ts +++ b/front/current/components/project/detail.component.ts @@ -16,7 +16,6 @@ import { AddressComponent } from './address.component'; import { ContactsComponent } from './contacts.component'; import { SlotsComponent } from './slots.component'; - @Component({ selector: 'project', templateUrl: config.static_url + '/components/project/detail.component.html', diff --git a/front/current/components/project/slot.component.html b/front/current/components/project/slot.component.html index 4bd89997b8842d2eb7d1328054e2befb7a26ab24..583df8d9d51180b02cd8d7927919a33e3b75a6dc 100644 --- a/front/current/components/project/slot.component.html +++ b/front/current/components/project/slot.component.html @@ -1,6 +1,14 @@
{{ slot.title }}
diff --git a/front/current/components/project/slot.component.ts b/front/current/components/project/slot.component.ts index 13c8c32ca335d27de3f14eb54c611b10d917ff15..fb5e270cdda5243fb91e45703c3a8b1f9fdf709a 100644 --- a/front/current/components/project/slot.component.ts +++ b/front/current/components/project/slot.component.ts @@ -11,7 +11,7 @@ declare var moment:any; selector: 'document-slot', templateUrl: config.static_url + '/components/project/slot.component.html', inputs: [ - 'project', 'slot', 'document_slots', 'documents', 'parent_documents', + 'project', 'slot', 'documents', 'parent_documents', 'parent_document_slots'], directives: [NewDocumentSlotComponent] }) @@ -22,6 +22,7 @@ export class SlotComponent { documents:Collection; parent_documents:Collection; parent_document_slots:Collection; + /*state:any*/ /* state will be a complete state model*/ moment = moment; diff --git a/front/current/components/project/slots.component.html b/front/current/components/project/slots.component.html index e851a9b0dcbd0921cbb62fbb411be2d9afedb6ea..28149d2fd4f597fddb459d7495d1adf6b0e6d79e 100644 --- a/front/current/components/project/slots.component.html +++ b/front/current/components/project/slots.component.html @@ -1,16 +1,13 @@ -

Documents

-

- +
diff --git a/front/current/components/project/slots.component.ts b/front/current/components/project/slots.component.ts index 566a592380a70edb6125340194afe3aa4a1ba4c8..83c227864e215f86d00c40d28a146672f8424aba 100644 --- a/front/current/components/project/slots.component.ts +++ b/front/current/components/project/slots.component.ts @@ -1,91 +1,59 @@ import { Component } from 'angular2/core'; - import { config } from '../../config'; - -import { RestService, Model, Collection } from '../../services/rest.service'; -import { DocumentSlotService } from '../../services/project/document-slot.service'; -import { DocumentService } from '../../services/document/document.service'; - -import { SlotComponent } from './slot.component'; +import { Model, Collection } from '../../services/rest.service'; +import { ProjectService } from '../../services/project/project.service'; +import { StateComponent } from './state.component'; @Component({ selector: 'document-slots', templateUrl: config.static_url + '/components/project/slots.component.html', inputs: ['project', 'document_slots', 'documents'], - directives: [SlotComponent] + directives: [StateComponent] }) export class SlotsComponent { constructor( - private _restService:RestService, - public documentSlotService:DocumentSlotService, - public documentService:DocumentService + public projectService:ProjectService ) {}; slots:any[] = [ - {name: 'utility-bills', title: 'Utility Bills'}, - {name: 'breakdown-of-bills', title: 'Breakdown of Bills'}, - {name: 'canvas', title: 'Canvas'}, - {name: 'pns', title: 'PNS Form'}, - {name: 'pictures', title: 'Pictures'}, - {name: 'sketches', title: 'Sketches'}, - {name: 'heat-load', title: 'Heat Load'}, - {name: 'cooling-load', title: 'Cooling Load'}, - {name: 'diagnostic-report', title: 'Diagnostic Report'}, - {name: 'sceep-forms', title: 'SCEEP Forms'}, - {name: 'pea-reports', title: 'PEA Reports'}, - {name: 'balance-sheets', title: 'Balance Sheets'}, - {name: 'income-statements', title: 'Income Statements'}, - {name: 'financial-reports', title: 'Financial Reports'}, - {name: 'taxes', title: 'Taxes'}, - {name: 'credit-reports', title: 'Credit Reports'}, - {name: 'certificate-of-incorporation', title: 'Certificate of Incorporation'}, - {name: 'bank-statements', title: 'Bank Statements'}, - {name: '501(c)3-confirmation', title: '501(c)3 Confirmation'}, - {name: 'proof-of-insurance', title: 'Proof of Property and Liability Insurance'}, - {name: 'property-appraisal', title: 'Property Appraisal'}, - {name: 'title-of-location', title: 'Title of Location'}, - {name: 'nyserda', title: 'NYSERDA Request for Financing Form'}, - {name: 'loan-application', title: 'Loan Application'}, - {name: 'contractor-quotes', title: 'Contractor Quotes'}, - {name: 'misc', title: 'Miscellaneous'} - ] - project:Model + {name: 'utility-bills', title: 'Utility Bills', state_id: 3}, + {name: 'breakdown-of-bills', title: 'Breakdown of Bills', state_id: 8}, + {name: 'canvas', title: 'Canvas', state_id: 9}, + {name: 'pns', title: 'PNS Form', state_id: 4}, /*Contains multiple PNS Forms for each department, 10, 11*/ + {name: 'pictures', title: 'Pictures', state_id: 9}, + {name: 'sketches', title: 'Sketches', state_id: 9}, + {name: 'heat-load', title: 'Heat Load', state_id: 8}, /* Also in state 12*/ + {name: 'cooling-load', title: 'Cooling Load', state_id: 12}, + {name: 'diagnostic-report', title: 'Diagnostic Report', state_id: 13}, + {name: 'sceep-forms', title: 'SCEEP Forms', state_id: 3}, + {name: 'pea-reports', title: 'PEA Reports', state_id: 3}, + {name: 'balance-sheets', title: 'Balance Sheets', state_id: 6}, + {name: 'income-statements', title: 'Income Statements', state_id: 3}, + {name: 'financial-reports', title: 'Financial Reports', state_id: 6}, /*Is it 4 or 6*/ + {name: 'taxes', title: 'Taxes', state_id: 3}, + {name: 'credit-reports', title: 'Credit Reports', state_id: 3}, + {name: 'certificate-of-incorporation', title: 'Certificate of Incorporation', state_id: 3}, + {name: 'bank-statements', title: 'Bank Statements', state_id: 3}, + {name: '501(c)3-confirmation', title: '501(c)3 Confirmation', state_id: 3}, + {name: 'proof-of-insurance', title: 'Proof of Property and Liability Insurance', state_id: 3}, + {name: 'property-appraisal', title: 'Property Appraisal', state_id: 3}, + {name: 'title-of-location', title: 'Title of Location', state_id: 3}, + {name: 'nyserda', title: 'NYSERDA Request for Financing Form', state_id: 40}, + {name: 'loan-application', title: 'Loan Application', state_id: 40}, + {name: 'contractor-quotes', title: 'Contractor Quotes', state_id: 30}, + {name: 'misc', title: 'Miscellaneous', state_id: 3} + ]; + project:Model; document_slots:Collection; documents:Collection; - public getDocumentSlots(slot:any) { - // Gets a subset of document slots for the given slot description. - let documentSlots = []; - let collection = this._restService.Collection(this.documentSlotService, []); - - for (let documentSlot of this.document_slots.models) { - if (documentSlot.data['role'] == slot.name) - documentSlots.push(documentSlot); + public getDocumentSlotsForState(state_id: number) { + let state_slots = []; + for (let slot of this.slots) { + if(slot.state_id == state_id) + state_slots.push(slot); } - - collection.models = documentSlots; - return collection; + return state_slots; }; - - public getDocuments(slot:any) { - // Gets a subset of documents for the given slot description. - let documents = []; - let collection = this._restService.Collection(this.documentService, []); - let document_slots = this.getDocumentSlots(slot); - let keys = []; - - for (let document_slot of document_slots.models) { - let key = document_slot.data['document_key']; - keys.push(key); - } - - for (let document_ of this.documents.models) { - if (keys.indexOf(document_.data['key']) > -1) - documents.push(document_); - } - - collection.models = documents; - return collection; - } }; diff --git a/front/current/components/project/state.component.html b/front/current/components/project/state.component.html new file mode 100644 index 0000000000000000000000000000000000000000..08181ebd942eaee75103d427232a5970a582338f --- /dev/null +++ b/front/current/components/project/state.component.html @@ -0,0 +1,18 @@ +
+
+

{{state.name}}

+
+
+

{{state.description}}

+ +

Documents:

+ +
+
diff --git a/front/current/components/project/state.component.ts b/front/current/components/project/state.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..14b86f12929f61aef9fb4f37c506e39d4d4a932a --- /dev/null +++ b/front/current/components/project/state.component.ts @@ -0,0 +1,64 @@ +import { Component } from 'angular2/core'; +import { config } from '../../config'; +import { SlotComponent } from './slot.component'; +import { Collection, Model, RestService } from '../../services/rest.service'; +import { DocumentSlotService } from '../../services/project/document-slot.service'; +import { DocumentService } from '../../services/document/document.service'; + + +@Component({ + selector: 'state', + templateUrl: config.static_url + '/components/project/state.component.html', + inputs: ['state', 'state_slots','project','document_slots','documents'], + directives: [SlotComponent] +}) + +export class StateComponent{ + public state: any; + public state_slots: any[]; + public project:Model; + public document_slots:Collection; + public documents:Collection; + + constructor( + private _restService:RestService, + public documentSlotService:DocumentSlotService, + public documentService:DocumentService + ){ + } + + public getDocumentSlots(slot:any) { + // Gets a subset of document slots for the given slot description. + let documentSlots = []; + let collection = this._restService.Collection(this.documentSlotService, []); + + for (let documentSlot of this.document_slots.models) { + if (documentSlot.data['role'] == slot.name) + documentSlots.push(documentSlot); + } + + collection.models = documentSlots; + return collection; + }; + + public getDocuments(slot:any) { + // Gets a subset of documents for the given slot description. + let documents = []; + let collection = this._restService.Collection(this.documentService, []); + let document_slots = this.getDocumentSlots(slot); + let keys = []; + + for (let document_slot of document_slots.models) { + let key = document_slot.data['document_key']; + keys.push(key); + } + + for (let document_ of this.documents.models) { + if (keys.indexOf(document_.data['key']) > -1) + documents.push(document_); + } + + collection.models = documents; + return collection; + } +}; diff --git a/front/current/components/projects/list.component.html b/front/current/components/projects/list.component.html index 299f2b4059b9f149900d2dabf4da97598763a7cc..670a45718267b3abf812d397ca49bae978ebeaea 100644 --- a/front/current/components/projects/list.component.html +++ b/front/current/components/projects/list.component.html @@ -1,7 +1,7 @@
- +
diff --git a/front/current/services/project/project.service.ts b/front/current/services/project/project.service.ts index 0db2072e1fc636440d174d9a7f6484071eeb2cd2..3ade946b3b47d6be0b99c21ea2732e3004253a9d 100644 --- a/front/current/services/project/project.service.ts +++ b/front/current/services/project/project.service.ts @@ -7,7 +7,214 @@ export class ProjectService { public service_name:string = 'project'; public config:any = config.SERVICES.project; public url:string = '/project/'; - + public states: any[] = + [ + { + name: 'Collect Forms', + id: 3, + description: 'Collect 12 Months of Utility Bills and 3 years of Income. Fill out business section of PNS form.', + }, + { + name: 'Create Opportunity', + id: 4, + description: 'Create object on project dashboard with pending state. Create opportunity on salesforce.', + }, + { + name: 'Confirm Bill Validity', + id: 5, + description: 'Quality Assurance checks bills on dashboard are correct.', + }, + { + name: 'Confirm Validity of 3 Years of Income Statements ', + id: 6, + description: 'Finance does quality check on 3 Years of Income Statements on dashboard.', + }, + { + name: 'Schedule Site Visit', + id: 7, + description: 'Schedule site visit with client and project engineer.', + }, + { + name: 'Perform Remote Assessment', + id: 8, + description: 'Project Engineers perform remote assessment (Energy Watch, Code Violations, Google Earth, Heat Load Calculations).', + }, + { + name: 'Conduct Site Visit', + id: 9, + description: 'Project Engineer conducts site visit audit. All data entry is complete. Sensors are installed.', + }, + { + name: 'Complete Finance PNS', + id: 10, + description: 'Complete Finance section of the PNS Form. This step does not have any dependencies. Must only be complete one month post site visit.', + }, + { + name: 'Send PNS Form', + id: 11, + description: 'Project Engineer sends client PNS Form.', + }, + { + name: 'Perform Initial Engineering Analysis', + id: 12, + description: 'Project Engineer performs energy efficiency calculations for annual savings.', + }, + { + name: 'Send Diagnostic Report', + id: 13, + description: 'Project Engineer creates diagnostic report.', + }, + { + name: 'Follow Up Post Project Update', + id: 14, + description: 'Project Engineer contacts client to discover if client is interested in moving forward.', + }, + { + name: 'Outsource Retrofit', + id: 15, + description: 'Project Manager assesses potential outsourced retrofits (e.g. lighting and windows).' + }, + { + name: 'HPD Finance', + id: 16, + description: 'Finance discovers if HPD will finance the project.', + }, + { + name: 'Confirm Client wants HPD', + id: 17, + description: 'Finance confirms client wants to proceed with HPD program.' + }, + { + name: 'Preliminary Financial Analysis', + id: 18, + description: 'Run preliminary finance model and suggest budget range for Project Engineer.', + }, + { + name: 'Confirm Project Financing', + id: 19, + description: 'Finance decides if project is feasible.', + }, + { + name: 'Perform Detailed Calculations and Analysis', + id: 20, + description: 'Project Engineer runs models (hydronic, steam, cooling, heating, controls).', + }, + { + name: 'Write Scope of Work Report', + id: 21, + description: 'Project Engineer selects desired equipment for retrofits.', + }, + { + name: 'Obtain Quotes', + id: 22, + description: 'Project Manager bundles nearby projects together and sends equipment lists to contractor to collect quotes and look for violations.', + }, + { + name: 'Create Engineering Energy Output Model', + id: 23, + description: 'Project Engineer generates Engineering Output Model for suggested scenario.', + }, + { + name: 'Create Finance Model', + id: 24, + description: 'Finance uses quotes and Engineering Output Model to run Finance model for suggested scenario.', + }, + { + name: 'Create Client Presentation', + id: 25, + description: 'Project Engineer creates final presentation for various retrofit scenarios with upfront cost estimates and annual savings.', + }, + { + name: 'Schedule Client Presentation', + id: 26, + description: 'Project Manager coordinates with client, engineer, and finance/business to set up presentation date.', + }, + { + name: 'Present to Client', + id: 27, + description: 'Project Engineer presents retrofit scenarios and financing options to client.', + }, + { + name: 'Client Chooses Retrofits', + id: 28, + description: 'Project Engineer contacts Client to determine actionable retrofits. ', + }, + { + name: 'Redesign Scope of Work', + id: 29, + description: 'Project Engineer redesigns and finalizes scope of work.', + }, + { + name: 'Finalize Quotes', + id: 30, + description: 'Project Engineer sends contractor Final Scope of Work and finalizes quotes. Contractor signs contract.', + }, + { + name: 'Final Finance Model' , + id: 31, + description: 'Finance runs the finance model to obtain actual costs inclduing payback years.', + }, + { + name: 'Update Client with Project Financing' , + id: 32 , + description: 'Finance contacts client to discuss financing options such as loans and marketplace.', + }, + { + name: 'Client Decides on Marketplace' , + id: 33 , + description: 'Client decides if they want to use Marketplace.', + }, + { + name: 'Marketplace Content' , + id: 34, + description: 'The Project content gets collected to prepare it for a Marketplace Launch.', + }, + { + name: 'Marketplace' , + id: 35, + description: 'The Project is launched on the Marketplace and is being funded.', + }, + { + name: 'Contractor Downpayment' , + id: 39, + description: 'A downpayment is payed to contractor.', + }, + { + name: 'Apply for Loan' , + id: 40, + description: 'Finance appplies for loan.', + }, + { + name: 'Approval of Underwriter' , + id: 41, + description: 'Finance is notified that the loan was approved by the Underwriter (banks).', + }, + { + name: 'Confirm Funding' , + id: 42, + description: 'Finance confirms project is funded.', + }, + { + name: 'Commence Construction' , + id: 43, + description: 'Construction Manager coordinates with client contractor, and engineers to schedule retrofit construction.', + }, + { + name: 'Measurement and Verification' , + id: 44, + description: 'Project Engineer collects sensor data during site visit, recalibrates sensors, and reinstalls sensors for "post retrofit" measurement and verification.', + }, + { + name: 'Loan Payback' , + id: 45, + description: 'Loan is in the process of being paid back.', + }, + { + name: 'Completed', + id: 46, + description: 'Project is complete!' + } + ] getSalesForceUrl(model:Model) { return '//na34.salesforce.com/' + model.data['sales_force_id'].substr(0, 15); };