diff --git a/app/components/ui-grid-table-column.hbs b/app/components/ui-grid-table-column.hbs index 97b23804a..219b6826c 100644 --- a/app/components/ui-grid-table-column.hbs +++ b/app/components/ui-grid-table-column.hbs @@ -1,3 +1,3 @@ -
+
{{yield}}
\ No newline at end of file diff --git a/app/components/vc/application-details.hbs b/app/components/vc/application-details.hbs index c65684a75..45816b6a2 100644 --- a/app/components/vc/application-details.hbs +++ b/app/components/vc/application-details.hbs @@ -18,66 +18,69 @@ Unreviewed paragraph {{/if}} -
-
- Experience
- {{@application.experienceLabel}} - {{#if @application.isBRCExperienceOkay}} -
BRC exp. appears to be okay
- {{#if @application.isBRC1R1}} - Regional exp. may need verification. - {{/if}} - {{/if}} - {{#if @application.experienceIssue}} -
{{@application.experienceIssue}}
- {{/if}} -
-
- BRC Events
+ + + BRC Events + + {{#if @application.eventsList}} - {{pluralize @application.eventsList.length - (if @application.hasPandemicEvents "total event" "event")}} - [{{year-range @application.eventsList}}] + {{#if @application.isBRCExperienceOkay}} + {{fa-icon "check" right=1}} Experience is okay + {{else}} + {{fa-icon "hand" right=1}} Experience issue + {{/if}} +
+ {{pluralize @application.eventsList.length + (if @application.hasPandemicEvents "total event" "event")}} + [{{year-range @application.eventsList}}] +
{{#if @application.hasPandemicEvents}}
- Pandemic year(s) present.
+ {{fa-icon "hand" right=1}} Pandemic year(s) selected.
{{/if}} {{else}} - No events listed. + {{fa-icon "hand" right=1}} No events selected {{/if}} -
-
- Is 18 Or Older?
+ + Age + {{#if @application.is_over_18}} - {{fa-icon "check" right=1}} Yes + {{fa-icon "check" right=1}} Is 18 or older {{else}} - {{fa-icon "times" right=1}} NO - Individual is under 18. + {{fa-icon "times" right=1}} Under 18 {{/if}} -
-
-
-
- Known Rangers
+ + + + Known Rangers + + -
-
- Known Applicants
+ + + Known Applicants + + -
-
- -
-
+ + Why Ranger? -
-
+ + {{#if (eq @application.why_volunteer_review 'okay')}} - {{fa-icon "check" right=1}} Paragraph is okay + + {{fa-icon "check" right=1}} paragraph okay + + {{else if (eq @application.why_volunteer_review 'problem')}} - {{fa-icon "ban" right=1}} Problem paragraph + + {{fa-icon "ban" right=1}} problem paragraph + {{else}} - {{fa-icon "question" right=1}} Unreviewed paragraph + + {{fa-icon "question" right=1}} unreviewed paragraph + {{/if}} {{#if @application.reviewed_at}} @@ -102,33 +105,38 @@ Mark As Problem {{/if}} -
-
Regional Experience
-
+ + Regional Experience + {{#if @application.regional_experience}} {{nl2br @application.regional_experience}} {{else}} none stated {{/if}} -
-
Comments
-
+ + Comments + -
+ -
Unified Flagging Notes
-
+ Unified Flagging Notes + -
-
Actions
-
+ + Actions + + + Approve for Callsign Processing + Lacking Event Experience + {{!-- Failed Regional Verification + --}} Too Young (< 18 years old) @@ -142,20 +150,19 @@ Returning Ranger + {{!-- Request RRN Check + --}} Why Ranger Answer Issue - Ask for Qualification Confirmation + Ask for Experience Confirmation - - Approve for Callsign Processing - -
-
+ + <:edit as |f|> diff --git a/app/components/vc/application-handles.hbs b/app/components/vc/application-handles.hbs index f15b234dd..32fb07231 100644 --- a/app/components/vc/application-handles.hbs +++ b/app/components/vc/application-handles.hbs @@ -1,4 +1,4 @@ - + <:title> Handle Information @@ -19,7 +19,7 @@ Callsign approved - awaiting account creation. - {{else if @application.isStatusApprovedPiiIssue}} + {{else if @application.hasPersonalInfoIssue}} Handle has been approved, however, the Personal Info has issues. Application is on hold until the applicant responds. @@ -38,12 +38,15 @@ none assigned yet {{/if}}
- - Edit & Approve Callsign - - - Edit Callsign - + {{#if @application.approved_handle}} + + Edit Callsign + + {{else}} + + Assign Callsign + + {{/if}}
@@ -68,48 +71,66 @@ {{handle.handle}} - - - assign callsign - - - - - check handle - - - - {{#if handle.existing_person}} - Conflict with existing account: - -
- {{/if}} - {{#if handle.reserved_handles}} - Conflict with reserved: - - {{#each handle.reserved_handles as |reserved idx|}} - {{if idx ", "}} - {{reserved.handle}} - - {{/each}} - {{/if}} - + {{#if (or handle.reserved_handles handle.existing_person)}} + + {{#if handle.existing_person}} + {{#if handle.is_applicant1}} + + already assigned to this applicant + + {{else}} + + taken by existing account + + {{/if}} + + {{else if handle.reserved_handles}} + Conflicts with reserved handles / terms: + {{#each handle.reserved_handles as |reserved idx|}} + {{if idx ", "}} + {{reserved.handle}} + + {{/each}} + {{/if}} + + {{else}} + + + assign callsign + + + + + check handle + + + {{/if}} {{/each}} {{else}} - {{fa-icon "alert"}} none submitted + {{fa-icon "alert" right=1}} none submitted {{/if}}
- - Reject Handle Submissions - - - Edit Handles - + + + Reject Handle Submissions + + + Edit Handles List + + {{#if @application.handles}} + + Extract Handles + + {{/if}} +
Rejected Handles @@ -283,3 +304,49 @@ {{/if}} +{{#if this.extractedHandlesForm}} + + + Edit Handles List + + {{#if @application.isStatusCreated}} + + {{fa-icon "hand-point-right" right=1}} Account has been created. No more handles should be recorded. + + {{/if}} +
+ +
+ {{fa-icon "arrow-left" size="2x"}} +
+
+ Original Handles: +
+ {{nl2br @application.handles}} +
+
+
+
+ + + + +
+
+{{/if}} + +{{#if this.isSubmitting}} + + Submitting the request + +{{/if}} + diff --git a/app/components/vc/application-handles.js b/app/components/vc/application-handles.js index 0be7dcfaf..3d25d444f 100644 --- a/app/components/vc/application-handles.js +++ b/app/components/vc/application-handles.js @@ -5,7 +5,7 @@ import {service} from '@ember/service'; import {validatePresence} from 'ember-changeset-validations/validators'; import { STATUS_APPROVED, - STATUS_APPROVED_PII_ISSUE, + STATUS_PII_ISSUE, STATUS_MORE_HANDLES } from "clubhouse/models/prospective-application"; import {ReservationTypeLabels} from "clubhouse/models/handle-reservation"; @@ -34,6 +34,8 @@ export default class VcApplicationHandlesComponent extends Component { @tracked showEditAndApproveCallsign; + @tracked extractedHandlesForm = null; + moreHandlesValidation = { message: [validatePresence({presence: true, message: 'Please supply a reason / message.'})] }; @@ -177,7 +179,7 @@ export default class VcApplicationHandlesComponent extends Component { this.isSubmitting = true; await this.ajax.post(`prospective-application/${application.id}/status`, { data: { - status: application.hasPersonalInfoIssues ? STATUS_APPROVED_PII_ISSUE : STATUS_APPROVED, + status: application.hasPersonalInfoIssues ? STATUS_PII_ISSUE : STATUS_APPROVED, approved_handle: model.approved_handle, } }); @@ -210,4 +212,37 @@ export default class VcApplicationHandlesComponent extends Component { return ReservationTypeLabels[type] ?? `Bug: ${type}`; } + @action + async extractHandles() { + try { + this.isSubmitting = true; + const { handles } = await this.ajax.request(`prospective-application/handles-extract`, { data: { text: this.args.application.handles}}); + this.extractedHandlesForm = EmberObject.create({ handles: handles.join("\n") }); + } catch(response) { + this.house.handleErrorResponse(response); + } finally { + this.isSubmitting = false; + } + } + + @action + cancelExtractedHandles() { + this.extractedHandlesForm = null; + } + + @action + async saveExtractedHandles(model) { + try { + this.isSubmitting = true; + const { application } = this.args; + application.handles = model.handles; + await application.save(); + this.toast.success('The handles has been saved successfully.'); + this.extractedHandlesForm = null; + } catch (response) { + this.house.handleErrorResponse(response); + } finally { + this.isSubmitting = false; + } + } } diff --git a/app/components/vc/application-personal-info.hbs b/app/components/vc/application-personal-info.hbs index eb06f0ebd..256bc9b3d 100644 --- a/app/components/vc/application-personal-info.hbs +++ b/app/components/vc/application-personal-info.hbs @@ -13,7 +13,7 @@ One or more fields is blank. All fields, except the Emergency Contact info, are required before a Clubhouse account can be created. - {{else if @application.isStatusApprovedPiiIssue}} + {{else if @application.hasPersonalInfoIssue}} {{fa-icon "hand-point-right" right=1}} Callsign has been approved, and the Personal Info issues appear to be resolved. Approve the application if everything looks good. diff --git a/app/controllers/vc/applications/index.js b/app/controllers/vc/applications/index.js index 08b15f0eb..15f7f9f40 100644 --- a/app/controllers/vc/applications/index.js +++ b/app/controllers/vc/applications/index.js @@ -1,8 +1,10 @@ import ClubhouseController from "clubhouse/controllers/clubhouse-controller"; import { + STATUS_APPROVED, STATUS_CREATED, STATUS_PENDING, - STATUS_APPROVED, WHY_VOLUNTEER_REVIEW_PROBLEM, STATUS_APPROVED_PII_ISSUE, + STATUS_PII_ISSUE, + WHY_VOLUNTEER_REVIEW_PROBLEM, } from "clubhouse/models/prospective-application"; import {cached, tracked} from '@glimmer/tracking'; import {action} from '@ember/object'; @@ -12,7 +14,7 @@ const statusFilterDescription = { pending: 'awaiting V.C. review', handles: 'in callsign processing', held: 'on hold, awaiting applicant response, RRN reply, or further investigation needed', - 'approved-pii-issues': 'approved, however, Personal Info issues must be resolved first before an account is created.', + 'pii-issues': 'Personal Info issues must be resolved first before an account is created.', approved: 'approved, callsign assigned, awaiting account creation', created: 'application approved, Clubhouse account(s) created', rejected: 'rejected due to lack of experience, age, pre-bonk, uber-bonk, is returning Ranger, or is duplicate submission.', @@ -38,7 +40,7 @@ export default class VcApplicationsIndexController extends ClubhouseController { ['Pending', 'pending'], ['Handle Processing', 'handles'], ['On Hold', 'held'], - ['Approved w/PII Issues', 'approved-pii-issues'], + ['Personal Info Issues', 'pii-issues'], ['Approved', 'approved'], ['Created Accounts', 'created'], ['Rejected', 'rejected'], @@ -116,8 +118,8 @@ export default class VcApplicationsIndexController extends ClubhouseController { case 'held': apps = this.applications.filter((a) => a.hasHeldStatus); break; - case 'approved-pii-issues': - apps = this.applications.filter((a) => a.status === STATUS_APPROVED_PII_ISSUE); + case 'pii-issues': + apps = this.applications.filter((a) => a.status === STATUS_PII_ISSUE); break; case 'approved': apps = this.applications.filter((a) => a.status === STATUS_APPROVED); diff --git a/app/models/prospective-application.js b/app/models/prospective-application.js index ac2d2f5fe..90d7d01f1 100644 --- a/app/models/prospective-application.js +++ b/app/models/prospective-application.js @@ -26,7 +26,7 @@ export const ExperienceLabels = optionsToLabels(ExperienceOptions); export const STATUS_PENDING = 'pending'; export const STATUS_APPROVED = 'approved'; -export const STATUS_APPROVED_PII_ISSUE = 'approved-pii-issue'; +export const STATUS_PII_ISSUE = 'pii-issue'; export const STATUS_CREATED = 'created'; export const STATUS_REASON_ISSUE = 'reason-issue'; @@ -53,7 +53,7 @@ export const WHY_VOLUNTEER_REVIEW_UNREVIEWED = 'unreviewed'; export const StatusOptions = [ ['Approved - Awaiting Account Creation', STATUS_APPROVED], - ['Approved - Personal Info Issue', STATUS_APPROVED_PII_ISSUE], + ['Personal Info Issue', STATUS_PII_ISSUE], ['Duplicate Application', STATUS_DUPLICATE], ['In Callsign Processing', STATUS_HANDLE_CHECK], ['Account Created', STATUS_CREATED], @@ -74,7 +74,7 @@ export const StatusLabels = optionsToLabels(StatusOptions); export const StatusColors = { [STATUS_APPROVED]: 'text-bg-success', - [STATUS_APPROVED_PII_ISSUE]: 'text-bg-warning', + [STATUS_PII_ISSUE]: 'text-bg-warning', [STATUS_DUPLICATE]: 'text-bg-danger', [STATUS_HANDLE_CHECK]: 'text-bg-gray', [STATUS_CREATED]: 'text-bg-success', @@ -99,14 +99,14 @@ export const WhyVolunteerReviewLabels = { export const StatusesThatSendEmail = [ STATUS_APPROVED, - STATUS_APPROVED_PII_ISSUE, + STATUS_HOLD_QUALIFICATION_ISSUE, + STATUS_HOLD_RRN_CHECK, STATUS_MORE_HANDLES, + STATUS_PII_ISSUE, STATUS_REJECT_REGIONAL, + STATUS_REJECT_RETURNING_RANGER, STATUS_REJECT_TOO_YOUNG, STATUS_REJECT_UNQUALIFIED, - STATUS_HOLD_RRN_CHECK, - STATUS_HOLD_QUALIFICATION_ISSUE, - STATUS_REJECT_RETURNING_RANGER, ]; @@ -149,7 +149,7 @@ export const ColumnLabels = { export const BadHandleRegexps = [ [/^\d\s*[.)-]?\s*\b/, 'Priority indicators detected (e.g., 1., 2), 3 -, etc) - remove the indicators.'], [/\branger\b/i, 'The word "Ranger" detected - remove the word.'], - [/[,."'!&-]/, 'Punctuation (commas, periods, quotes, ampersands, exclamations) detected - remove all punctuations. Dashes are okay IF its part of the actual handle'], + [/[,."'!()]/, 'Punctuation (commas, periods, quotes, exclamations, parentheses) detected - remove all punctuations. Dashes are okay IF its part of the actual handle'], ]; export default class ProspectiveApplicationModel extends Model { @attr('string', {defaultVault: STATUS_PENDING}) status; @@ -279,8 +279,8 @@ export default class ProspectiveApplicationModel extends Model { return this.status === STATUS_PENDING; } - get isStatusApprovedPiiIssue() { - return this.status === STATUS_APPROVED_PII_ISSUE + get hasPersonalInfoIssue() { + return this.status === STATUS_PII_ISSUE } get isBonked() { @@ -292,32 +292,41 @@ export default class ProspectiveApplicationModel extends Model { } get experienceIssue() { - switch (this.experience) { - case EXPERIENCE_NONE: - return 'NO BRC OR REGIONAL EXPERIENCE'; + if (!this.qualifiedEvents.length) { + return 'NO QUALIFIED EVENT YEARS LISTED'; + } else if (!this.hasEventYearWithinRange) { + return 'NO EVENT YEAR WITHIN THE LAST 10'; + } - case EXPERIENCE_BRC2: - if (this.qualifiedEvents.length < 2) { - return 'LESS THAN TWO BRC QUALIFIED EVENTS'; - } else if (!this.hasEventYearWithinRange) { - return 'NO EVENT YEAR WITHIN THE LAST 10'; - } else { - return null; - } - case EXPERIENCE_BRC1R1: - if (!this.qualifiedEvents.length) { - return 'NO BRC EVENTS'; - } else if (!this.hasEventYearWithinRange) { - return 'NO EVENT YEAR WITHIN THE LAST 10'; - } else if (isEmpty(this.regional_experience)) { - return 'NO REGIONAL EXP. LISTED'; + return null; + /* + switch (this.experience) { + case EXPERIENCE_NONE: + return 'NO BRC OR REGIONAL EXPERIENCE'; + + case EXPERIENCE_BRC2: + if (this.qualifiedEvents.length < 2) { + return 'LESS THAN TWO BRC QUALIFIED EVENTS'; + } else if (!this.hasEventYearWithinRange) { + return 'NO EVENT YEAR WITHIN THE LAST 10'; + } else { + return null; + } + case EXPERIENCE_BRC1R1: + if (!this.qualifiedEvents.length) { + return 'NO BRC EVENTS'; + } else if (!this.hasEventYearWithinRange) { + return 'NO EVENT YEAR WITHIN THE LAST 10'; + } else if (isEmpty(this.regional_experience)) { + return 'NO REGIONAL EXP. LISTED'; + } + + return null; + + default: + return null; } - - return null; - - default: - return null; - } + */ } get isBRCExperienceOkay() { diff --git a/app/routes/vc/applications/record.js b/app/routes/vc/applications/record.js index 0b49d13f9..071f1f4ce 100644 --- a/app/routes/vc/applications/record.js +++ b/app/routes/vc/applications/record.js @@ -1,6 +1,7 @@ import ClubhouseRoute from "clubhouse/routes/clubhouse-route"; import {VOLUNTEER_COORDINATOR} from "clubhouse/constants/positions"; -import { NotFoundError } from '@ember-data/adapter/error'; +import {NotFoundError} from '@ember-data/adapter/error'; +import {schedule, later} from '@ember/runloop'; export default class VcApplicationsRecordRoute extends ClubhouseRoute { async model({application_id}) { @@ -26,12 +27,29 @@ export default class VcApplicationsRecordRoute extends ClubhouseRoute { controller.relatedApplications = related; controller.VCs = VCs; + /* if (application.isProcessingCallsign) { controller.initialTabId = 'handles'; - } else if ((application.isStatusApproved && application.hasPersonalInfoIssues) || application.isStatusApprovedPiiIssue) { + } else if ((application.isStatusApproved && application.hasPersonalInfoIssues) || application.hasPersonalInfoIssue) { controller.initialTabId = 'personal-info'; } else { controller.initialTabId = 'details'; } + + */ + let id; + if (application.isProcessingCallsign) { + id = 'handles'; + } else if ((application.isStatusApproved && application.hasPersonalInfoIssues) || application.hasPersonalInfoIssue) { + id = 'personal-info'; + } else { + id = 'details'; + } + + if (id) { + later(() => schedule('afterRender', () => { + this.house.scrollToElement(`#${id}`) + }), 100); + } } } diff --git a/app/templates/vc/applications/record.hbs b/app/templates/vc/applications/record.hbs index c31ee802b..caf4243ee 100644 --- a/app/templates/vc/applications/record.hbs +++ b/app/templates/vc/applications/record.hbs @@ -8,7 +8,7 @@ {{#if this.application.isBonked}} {{fa-icon "ban" right=1}} Application has been bonked. Take no further action. Do not contact the individual unless - instructed to do so by the V.C. Cadre. + instructed to do so by the V.C. Cadre or the Personnel Managers. {{/if}} @@ -23,45 +23,42 @@ {{/if}} +{{#if this.application.existingAccount}} + {{#if this.application.isStatusCreated}} + + Application was approved, and an account created. + + + {{else if this.application.isReturningApplicant}} + + Application belongs to a returning Past Prospective. + + + {{else if this.application.wasUberbonkedPreviously}} + + Applicant was Uberbonked in a prior year. Double-check the application, and Clubhouse + account. + + + {{else if this.application.isReturningRanger}} + + Application may to belong to a returning Ranger. Verify this is not a mistake. + + + {{else}} + + Application may be associated with an existing Clubhouse account. + + + {{/if}} +{{/if}} -
+
{{#if this.notCurrentYear}}
{{fa-icon "exclamation" right=1}} You are viewing an application from a prior year.
{{/if}} - {{#if this.application.existingAccount}} - {{#if this.application.isStatusCreated}} -
- {{fa-icon "check" right=1}} Application was approved. The Clubhouse account is - -
- {{else if this.application.isReturningApplicant}} -
- {{fa-icon "hand-point-right" right=1}} Application belongs to a returning Past Prospective. - -
- {{else if this.application.wasUberbonkedPreviously}} -
- {{fa-icon "ban" right=1}} Applicant may have been Uberbonked. Double-check the application, and Clubhouse - account. - -
- {{else if this.application.isReturningRanger}} -
- {{fa-icon "hand-point-right" right=1}} Application may to belong to a returning Ranger. - Verify this is not a mistake. - -
- {{else}} -
- {{fa-icon "hand-point-right" right=1}} Application may be associated with an existing Clubhouse account. - However, the status is unknown. Double-check the application and account to verify this is not a - returning Ranger, nor a problematic individual. - -
- {{/if}} - {{/if}}
A-{{this.application.id}} Year {{this.application.year}} @@ -72,140 +69,86 @@
- - Adjust Status - - - Delete Application - - + Send Email
-
- {{#if this.isAssignedToMe}} - {{fa-icon "thumbs-up" right=1}} You are assigned to this application. - {{else if this.assignedToOther}} - - {{fa-icon "hand" right=1}} - Assigned to {{this.application.assigned_person.callsign}}. - - {{else if (not this.application.assigned_person_id)}} - Application is unassigned - {{/if}} - {{#unless this.isAssignedToMe}} - Assign To Self - {{/unless}} - Assign To VC - {{#if this.application.assigned_person_id}} - Clear Assignment - {{/if}} -
-
- -
-
- {{#if this.application.updated_by_person}} - Last updated at {{shift-format this.application.updated_by_person_at}} - by {{this.application.updated_by_person.callsign}} - {{else}} - Application has not been updated yet. - {{/if}} -
-
- Salesforce record - - {{this.application.salesforce_name}} - +
+
+ {{#if this.isAssignedToMe}} + {{fa-icon "thumbs-up" right=1}} You are assigned to this application. + {{else if this.assignedToOther}} + + {{fa-icon "hand" right=1}} + Assigned to {{this.application.assigned_person.callsign}}. + + {{else if (not this.application.assigned_person_id)}} + Application is unassigned + {{/if}} + {{#unless this.isAssignedToMe}} + Assign To Self + {{/unless}} + Assign To VC + {{#if this.application.assigned_person_id}} + Clear Assignment + {{/if}} +
+
+ {{#if this.application.updated_by_person}} + Last updated at {{shift-format this.application.updated_by_person_at}} + by {{this.application.updated_by_person.callsign}} + {{else}} + Application has not been updated yet. + {{/if}} +
+
+ Salesforce ID + + {{this.application.salesforce_name}} + +
- - - -
- Details -
-
- -
- Handles -
-
- -
- Personal Info -
-
- -
- Related Applications {{if this.relatedApplications (concat " (" this.relatedApplications.length ")")}} -
-
- -
- Mail Log ({{this.application.mail_logs.length}}) -
-
- -
- Audit Log ({{this.application.audit_logs.length}}) -
-
- -
- Misc -
-
-
- -
- - - - - - - - + + - - - - - - - <:title>Mail Log - <:body> - - - - - - - - - - <:title>Misc. - <:body> - - BPGUID - {{this.application.bpguid}} - SFUID - {{this.application.sfuid}} - - - - -
-
+/> + + + <:title>Mail Log + <:body> + + + + + + <:title>Misc. + <:body> + + BPGUID + {{this.application.bpguid}} + SFUID + {{this.application.sfuid}} + Actions + + + Adjust Status + + + Delete Application + + + + +
Back to {{this.application.year}} Prospective Applications Listing @@ -275,6 +218,13 @@ Adjust Application Status + + This is considered an emergency fix feature. Please note: +
    +
  • No emails wil be sent when updating the status through this dialog.
  • +
  • Confirm with your fellow V.C.s that this action is appropriate.
  • +
+

No emails will be sent when updating the status through this dialog.