Skip to content

Commit

Permalink
1254 Create Artifact Record as part of Project Creation
Browse files Browse the repository at this point in the history
 - Added artifact creation endpoint and returning artifact id from server to client
 - Create a form through which users may submit and attach documents (client)

Co-authored-by: horatio <[email protected]>
Co-authored-by: tangoyankee <[email protected]>

lala
  • Loading branch information
TangoYankee authored and horatiorosa committed Nov 26, 2024
1 parent e0965b5 commit 2af2f4b
Show file tree
Hide file tree
Showing 36 changed files with 1,150 additions and 291 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
deploy-server:
name: 🚀 Deploy server
needs: test-client
environment:
environment:
name: production
url: https://applicants-api.nycplanningdigital.com
runs-on: ubuntu-latest
Expand All @@ -46,6 +46,7 @@ jobs:
appdir: server
env:
HD_FEATURE_FLAG_SELF_SERVICE: ${{ vars.FEATURE_FLAG_SELF_SERVICE }}
HD_LETTER_FILETYPE_UUID: ${{ vars.LETTER_FILETYPE_UUID }}
HD_ADO_PRINCIPAL: ${{ secrets.ADO_PRINCIPAL }}
HD_AUTHORITY_HOST_URL: ${{ secrets.AUTHORITY_HOST_URL }}
HD_CITYPAY_AGENCYID: ${{ secrets.CITYPAY_AGENCYID }}
Expand Down Expand Up @@ -107,7 +108,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 12.x
- name: Install application dependencies
- name: Install application dependencies
working-directory: client
run: yarn install --immutable --immutable-cache --check-cache
- name: Build client
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/qa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
appdir: server
env:
HD_FEATURE_FLAG_SELF_SERVICE: ${{ vars.FEATURE_FLAG_SELF_SERVICE }}
HD_LETTER_FILETYPE_UUID: ${{ vars.LETTER_FILETYPE_UUID }}
HD_ADO_PRINCIPAL: ${{ secrets.ADO_PRINCIPAL }}
HD_AUTHORITY_HOST_URL: ${{ secrets.AUTHORITY_HOST_URL }}
HD_CITYPAY_AGENCYID: ${{ secrets.CITYPAY_AGENCYID }}
Expand Down Expand Up @@ -102,7 +103,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 12.x
- name: Install application dependencies
- name: Install application dependencies
working-directory: client
run: yarn install --immutable --immutable-cache --check-cache
- name: Build client
Expand All @@ -119,4 +120,3 @@ jobs:
--site ${{secrets.NETLIFY_SITE_ID}} \
--auth ${{secrets.NETLIFY_AUTH_TOKEN}} \
--message "${{ github.event.head_commit.message }}"
3 changes: 2 additions & 1 deletion .github/workflows/staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
appdir: server
env:
HD_FEATURE_FLAG_SELF_SERVICE: ${{ vars.FEATURE_FLAG_SELF_SERVICE }}
HD_LETTER_FILETYPE_UUID: ${{ vars.LETTER_FILETYPE_UUID }}
HD_ADO_PRINCIPAL: ${{ secrets.ADO_PRINCIPAL }}
HD_AUTHORITY_HOST_URL: ${{ secrets.AUTHORITY_HOST_URL }}
HD_CLIENT_ID: ${{ secrets.CLIENT_ID }}
Expand Down Expand Up @@ -94,7 +95,7 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: 12.x
- name: Install application dependencies
- name: Install application dependencies
working-directory: client
run: yarn install
- name: Build client
Expand Down
4 changes: 2 additions & 2 deletions client/.gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist/
**/dist
/tmp/

# dependencies
/bower_components/
/node_modules/
**/node_modules

# misc
/.env*
Expand Down
64 changes: 0 additions & 64 deletions client/app/components/packages/projects/new.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,44 @@
Planning will contact you with the next steps.
</p>
</section>
<Packages::Projects::ProjectsNewInformation @form={{saveableProjectsNewForm}} />
<Projects::ProjectsNewInformation
@project={{saveableProjectsNewForm.data}}
@form={{saveableProjectsNewForm}}
@boroughOptions={{this.boroughOptions}}
@onBoroughChange={{this.handleBoroughChange}}
@selectedBorough={{this.selectedBorough}}
@onApplicantTypeSelection={{this.handleApplicantTypeChange}}
@selectedApplicantType={{this.selectedApplicantType}}
@applicantOptions={{this.applicantOptions}}
/>

<Projects::ProjectsNewAddContacts
@form={{saveableProjectsNewForm}} />

<Projects::ProjectsNewProjectDescription
@form={{saveableProjectsNewForm}} />

<Projects::ProjectsNewAttachedDocuments
@artifact={{saveableProjectsNewForm.data}}
@form={{saveableProjectsNewForm}}
@model={{@package}} />
</div>

<div class="cell large-4 sticky-sidebar">
<saveableProjectsNewForm.PageNav>
<saveableProjectsNewForm.SubmitButton @isEnabled={{saveableProjectsNewForm.isSubmittable}} data-test-save-button />
</saveableProjectsNewForm.PageNav>
<Messages::Assistance class="large-margin-top" />

<saveableProjectsNewForm.ConfirmationModal @action={{component saveableProjectsNewForm.SubmitButton
isEnabled=saveableProjectsNewForm.isSubmittable onClick=this.submitPackage class="no-margin" }}
isEnabled=saveableProjectsNewForm.isSubmittable onClick=this.submitProject class="no-margin" }}
@continueButtonTitle="Continue Editing" data-test-confirm-submit-button={{true}}>
<h6>Confirm New Project Submission</h6>
<p class="header-large medium-margin-top small-margin-bottom">
Are you sure?
</p>
<p>
Before submitting, ensure that your answers are accurate and complete, and that necessary attachments (including
the
signature form) have been uploaded.
Before submitting, ensure that your answers are accurate and complete, and that necessary attachments have been uploaded. If NYC Planning does not receive enough accurate information to provide guidance, the Lead Planner will notify you and request that this form be resubmitted with necessary materials, corrections, or
clarifications.
</p>
</saveableProjectsNewForm.ConfirmationModal>
</div>
Expand Down
115 changes: 115 additions & 0 deletions client/app/components/projects/new.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import SubmittableProjectsNewForm from '../../validations/submittable-projects-new-form';
import { optionset } from '../../helpers/optionset';
import config from '../../config/environment';

export default class ProjectsNewFormComponent extends Component {
validations = {
SubmittableProjectsNewForm,
};

@service
router;

@service
store;

get boroughOptions() {
return optionset(['project', 'boroughs', 'list']);
}

get applicantOptions() {
return optionset(['applicant', 'dcpApplicantType', 'list']);
}

@action
async submitProject() {
const primaryContactInput = {
first: this.args.package.primaryContactFirstName,
last: this.args.package.primaryContactLastName,
email: this.args.package.primaryContactEmail,
phone: this.args.package.primaryContactPhone,
};

const applicantInput = {
first: this.args.package.applicantFirstName,
last: this.args.package.applicantLastName,
email: this.args.package.applicantEmail,
phone: this.args.package.applicantPhone,
};

const contactInputs = [primaryContactInput, applicantInput];

try {
const contactPromises = contactInputs.map((contact) => this.store.queryRecord('contact', {
email: contact.email,
includeAllStatusCodes: true,
}));

const contacts = await Promise.all(contactPromises);

const verifiedContactPromises = contacts.map((contact, index) => {
if (contact.id === '-1') {
const contactInput = contactInputs[index];
const contactModel = this.store.createRecord('contact', {
firstname: contactInput.first,
lastname: contactInput.last,
emailaddress1: contactInput.email,
telephone1: contactInput.phone,
});
return contactModel.save();
}
return contact;
});

const [verifiedPrimaryContact, verifiedApplicant] = await Promise.all(
verifiedContactPromises,
);

const authSessionRaw = localStorage.getItem('ember_simple_auth-session');

if (authSessionRaw === null) {
throw new Error('unauthorized');
}
const authSession = JSON.parse(authSessionRaw);
const {
authenticated: { access_token: accessToken },
} = authSession;
if (accessToken === undefined) {
throw new Error('unauthorized');
}

const response = await fetch(`${config.host}/projects`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
data: {
attributes: {
dcpProjectname: this.args.package.projectName,
dcpBorough: this.args.package.borough.code,
dcpApplicanttype: this.args.package.applicantType.code,
dcpProjectbrief: this.args.package.projectBrief,
_dcpApplicantadministratorCustomerValue:
verifiedPrimaryContact.id,
_dcpApplicantCustomerValue: verifiedApplicant.id,
},
},
}),
});
const { data: project } = await response.json();

this.args.package.saveAttachedFiles(project.attributes['dcp-artifactsid']);

this.router.transitionTo('project', project.id);
} catch {
/* eslint-disable-next-line no-console */
console.error('Error while creating project');
}
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,4 @@
{{#let @form as |form|}}
<form.Section @title="Project Information">
<Ui::Question @required={{true}} as |Q|>
<Q.Label>
Project Name
</Q.Label>

<form.Field
@attribute="projectName"
@type="text-input"
id={{Q.questionId}}
@showCounter={{true}}
@maxlength="50"
/>
</Ui::Question>
</form.Section>
<form.Section @title="Contact Information">
<h3>Primary Contact</h3>
<p>This contact is the person who will respond to public inquiries regarding the application.</p>
Expand Down Expand Up @@ -70,13 +55,15 @@
id={{Q.questionId}}
@showCounter={{true}}
@maxlength="10"
placeholder='2125551212'
/>
</Ui::Question>

<h3>Applicant</h3>
<p>The owner, entity, or representative of the project described in this application.</p>
<p class="q-help">
If using a company or organization, please split the name in the "First Name" and "Last Name" fields. For example, "NYC
If using a company or organization, please split the name in the "First Name" and "Last Name" fields. For example,
"NYC
Planning" would be: <b>First Name:</b> NYC, <b>Last Name:</b> Planning
</p>
<Ui::Question @required={{true}} as |Q|>
Expand Down Expand Up @@ -132,7 +119,8 @@
id={{Q.questionId}}
@showCounter={{true}}
@maxlength="10"
placeholder='2125551212'
/>
</Ui::Question>
</form.Section>
{{/let}}
{{/let}}
22 changes: 22 additions & 0 deletions client/app/components/projects/projects-new-attached-documents.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{{#let @form as |form|}}
<@form.Section @title='Attached Documents'>
<p>
Please attach the required items list on the
<Ui::ExternalLink @href="https://www.nyc.gov/assets/planning/download/pdf/applicants/applicant-portal/interest_checklist.pdf">
Informational Interest Meeting checklist
</Ui::ExternalLink> &nbsp;in one PDF document. The maximum
size for a document is 50MB.
</p>

<SaveableForm::FieldValidationMessage
@attribute='documents'
@validation={{@form.errors.documents.validation}} />

<Projects::ProjectsNewAttachments
@package={{@form.data}}
@artifact={{@artifact}}
@fileManager={{@model.fileManager}}
data-test-section='attachments' />
</@form.Section>

{{/let}}
Loading

0 comments on commit 2af2f4b

Please sign in to comment.