Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement initial bring forward features #49

Merged
merged 3 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions app/src/db/migrations/20240327000000_001-bring-forward.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { Knex } from 'knex';

export async function up(knex: Knex): Promise<void> {
return Promise.resolve()
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.dropColumn('bring_forward_date');
})
)
.then(() =>
knex.schema.alterTable('note', function (table) {
table.timestamp('bring_forward_date', { useTz: true });
table.text('bring_forward_state').nullable();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi. you don't need to add nullable(). fields are nullable by default on column creation

})
);
}

export async function down(knex: Knex): Promise<void> {
return Promise.resolve()
.then(() =>
knex.schema.alterTable('submission', function (table) {
table.timestamp('bring_forward_date', { useTz: true });
})
)
.then(() =>
knex.schema.alterTable('note', function (table) {
table.dropColumn('bring_forward_date');
table.dropColumn('bring_forward_state');
})
);
}
4 changes: 4 additions & 0 deletions app/src/db/models/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export default {
return {
note_id: input.noteId,
activity_id: input.activityId,
bring_forward_date: input.bringForwardDate ? new Date(input.bringForwardDate) : null,
bring_forward_state: input.bringForwardState,
note: input.note,
note_type: input.noteType,
title: input.title,
Expand All @@ -30,6 +32,8 @@ export default {
return {
noteId: input.note_id,
activityId: input.activity_id,
bringForwardDate: input.bring_forward_date?.toISOString() ?? null,
bringForwardState: input.bring_forward_state ?? null,
note: input.note || '',
noteType: input.note_type || '',
title: input.title || '',
Expand Down
2 changes: 0 additions & 2 deletions app/src/db/models/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export default {
financially_supported_housing_coop: input.financiallySupportedHousingCoop,
aai_updated: input.aaiUpdated,
waiting_on: input.waitingOn,
bring_forward_date: input.bringForwardDate ? new Date(input.bringForwardDate) : null,
intake_status: input.intakeStatus,
application_status: input.applicationStatus,
guidance: input.guidance,
Expand Down Expand Up @@ -94,7 +93,6 @@ export default {
financiallySupportedHousingCoop: input.financially_supported_housing_coop,
aaiUpdated: input.aai_updated,
waitingOn: input.waiting_on,
bringForwardDate: input.bring_forward_date?.toISOString() ?? null,
intakeStatus: input.intake_status,
applicationStatus: input.application_status,
guidance: input.guidance,
Expand Down
23 changes: 12 additions & 11 deletions app/src/db/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,18 @@ model initiative {
}

model note {
note_id String @id @db.Uuid
activity_id String
note String @default("")
note_type String @default("")
title String @default("")
created_by String? @default("00000000-0000-0000-0000-000000000000")
created_at DateTime? @default(now()) @db.Timestamptz(6)
updated_by String?
updated_at DateTime? @db.Timestamptz(6)
activity activity @relation(fields: [activity_id], references: [activity_id], onDelete: Cascade, map: "note_activity_id_foreign")
note_id String @id @db.Uuid
activity_id String
note String @default("")
note_type String @default("")
title String @default("")
created_by String? @default("00000000-0000-0000-0000-000000000000")
created_at DateTime? @default(now()) @db.Timestamptz(6)
updated_by String?
updated_at DateTime? @db.Timestamptz(6)
bring_forward_date DateTime? @db.Timestamptz(6)
bring_forward_state String?
activity activity @relation(fields: [activity_id], references: [activity_id], onDelete: Cascade, map: "note_activity_id_foreign")
}

model permit {
Expand Down Expand Up @@ -156,7 +158,6 @@ model submission {
financially_supported_housing_coop Boolean @default(false)
aai_updated Boolean @default(false)
waiting_on String?
bring_forward_date DateTime? @db.Timestamptz(6)
intake_status String?
application_status String?
guidance Boolean @default(false)
Expand Down
2 changes: 2 additions & 0 deletions app/src/types/Note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { IStamps } from '../interfaces/IStamps';
export type Note = {
noteId: string; // Primary Key
activityId: string;
bringForwardDate: string | null;
bringForwardState: string | null;
note: string;
noteType: string;
title: string;
Expand Down
1 change: 0 additions & 1 deletion app/src/types/Submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export type Submission = {
financiallySupportedHousingCoop: boolean;
aaiUpdated: boolean;
waitingOn: string | null;
bringForwardDate: string | null;
intakeStatus: string | null;
applicationStatus: string | null;
guidance: boolean;
Expand Down
2 changes: 2 additions & 0 deletions app/src/validators/note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const schema = {
body: Joi.object({
createdAt: Joi.date().required(),
activityId: activityId,
bringForwardDate: Joi.date().iso().allow(null),
bringForwardState: Joi.string().min(1).allow(null),
note: Joi.string(),
noteType: Joi.string().max(255).required(),
title: Joi.string().max(255)
Expand Down
8 changes: 8 additions & 0 deletions app/tests/unit/controllers/note.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ describe('createNote', () => {
body: {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Some not text',
noteType: 'GENERAL',
title: 'Note title'
Expand All @@ -52,6 +54,8 @@ describe('createNote', () => {
const created = {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Some not text',
noteType: 'GENERAL',
title: 'Note title'
Expand Down Expand Up @@ -79,6 +83,8 @@ describe('createNote', () => {
body: {
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Some not text',
noteType: 'GENERAL',
title: 'Note title'
Expand Down Expand Up @@ -120,6 +126,8 @@ describe('listNotes', () => {
{
noteId: '123-123',
activityId: '123',
bringForwardDate: null,
bringForwardState: null,
note: 'Some not text',
noteType: 'GENERAL',
title: 'Note title'
Expand Down
29 changes: 24 additions & 5 deletions frontend/src/components/note/NoteCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { onMounted, ref } from 'vue';

import { Card, Divider } from '@/lib/primevue';
import { userService } from '@/services';
import { formatDateShort } from '@/utils/formatters';
import { formatDate, formatDateShort } from '@/utils/formatters';

import type { Ref } from 'vue';
import type { Note } from '@/types';
Expand All @@ -30,13 +30,21 @@ onMounted(() => {
<template>
<Card>
<template #title>
<h3 class="mt-1 mb-1">{{ props.note.title }}</h3>
<h3 class="mt-1 mb-1">
{{ props.note.title }}
<span
v-if="props.note.bringForwardState"
data-test="bf-title"
>
{{ `(${props.note.bringForwardState})` }}
</span>
</h3>
<Divider type="solid" />
</template>
<template #content>
<div class="grid nested-grid">
<!-- Left column -->
<div class="col-12 md:col-6 lg:col-4">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these columns are too wide on big screens. lg:col-2 is probably enough

<div class="col-12 md:col-6 lg:col-3">
<div class="grid">
<p class="col-12">
<span class="key font-bold">Date:</span>
Expand All @@ -45,7 +53,7 @@ onMounted(() => {
</div>
</div>
<!-- Middle column -->
<div class="col-12 md:col-6 lg:col-4">
<div class="col-12 md:col-6 lg:col-3">
<div class="grid">
<p class="col-12">
<span class="key font-bold">Author:</span>
Expand All @@ -54,14 +62,25 @@ onMounted(() => {
</div>
</div>
<!-- Right column -->
<div class="col-12 md:col-6 lg:col-4">
<div class="col-12 md:col-6 lg:col-3">
<div class="grid">
<p class="col-12">
<span class="key font-bold">Note type:</span>
{{ props.note.noteType }}
</p>
</div>
</div>
<div
v-if="props.note.bringForwardDate"
class="col-12 md:col-6 lg:col-3"
>
<div class="grid">
<p class="col-12">
<span class="key font-bold">Bring forward date:</span>
{{ props.note.bringForwardDate ? formatDate(props.note.bringForwardDate) : '' }}
</p>
</div>
</div>
<p class="col-12 mt-0 mb-0 note-content">{{ props.note.note }}</p>
</div>
</template>
Expand Down
66 changes: 61 additions & 5 deletions frontend/src/components/note/NoteModal.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { Form } from 'vee-validate';
import { object, string } from 'yup';
import { mixed, object, string } from 'yup';

import { Calendar, Dropdown, InputText, TextArea } from '@/components/form';
import { Button, Dialog } from '@/lib/primevue';
import { NoteTypes } from '@/utils/constants';
import { NOTE_TYPES } from '@/utils/enums';
import { BringForwardTypes, NoteTypes } from '@/utils/constants';
import { BRING_FORWARD_TYPES, NOTE_TYPES } from '@/utils/enums';

import type { Note } from '@/types';
import { nextTick, ref, watch } from 'vue';
Expand All @@ -26,21 +26,55 @@ const emit = defineEmits(['note:submit']);
// State
const visible = defineModel<boolean>('visible');
const formRef: Ref<InstanceType<typeof Form> | null> = ref(null);
const showBringForward: Ref<boolean> = ref(false);

// Default form values
let initialFormValues: any = {
createdAt: new Date(),
bringForwardDate: null,
bringForwardState: null,
note: props.note?.note,
noteType: NOTE_TYPES.GENERAL
};

// Form validation schema
const formSchema = object({
bringForwardDate: mixed()
.nullable()
.when('noteType', {
is: (noteType: string) => noteType === NOTE_TYPES.BRING_FORWARD,
then: (schema) =>
schema.test(
'bring forward required',
'Bring forward date is a required field',
(value) => value instanceof Date
),
otherwise: (schema) => schema.nullable()
})
.label('Bring forward date'),
bringForwardState: mixed()
.when('noteType', {
is: (noteType: string) => noteType === NOTE_TYPES.BRING_FORWARD,
then: () => string().oneOf(BringForwardTypes),
otherwise: () => mixed().nullable()
})
.label('Bring forward state'),
note: string().required().label('Note'),
noteType: string().oneOf(NoteTypes).label('Note type'),
title: string().required().max(255, 'Title too long').label('Title')
});

const handleBringForward = (e: { OriginalEvent: Event; value: string }) => {
if (e.value === NOTE_TYPES.BRING_FORWARD) {
formRef.value?.setFieldValue('bringForwardState', BRING_FORWARD_TYPES.UNRESOLVED);
showBringForward.value = true;
} else {
showBringForward.value = false;
formRef.value?.setFieldValue('bringForwardDate', null);
formRef.value?.setFieldValue('bringForwardState', null);
}
};

// Actions
// @ts-expect-error TS7031
// resetForm is an automatic binding https://vee-validate.logaretm.com/v4/guide/components/handling-forms/
Expand All @@ -61,6 +95,8 @@ watch(visible, (newValue) => {
nextTick().then(() => {
if (newValue && formRef.value) {
formRef.value.setFieldValue('createdAt', new Date());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the 'Date' field is read-only, and we always want it to be the current date/time i question whether it needs to be on the form at all. something i could ask Tyler about i guess

} else {
showBringForward.value = false;
}
});
});
Expand Down Expand Up @@ -104,14 +140,34 @@ watch(visible, (newValue) => {
name="noteType"
label="Note type"
:options="NoteTypes"
@on-change="(e) => handleBringForward(e)"
/>
<Calendar
v-if="showBringForward"
class="col-6"
name="bringForwardDate"
label="Bring forward date"
/>
<div
v-else
class="col-6"
/>
<div class="col-6" />
<InputText
class="col-6"
name="title"
label="Title"
/>
<div class="col-6" />
<Dropdown
v-if="showBringForward"
class="col-6"
name="bringForwardState"
label="Bring forward state"
:options="BringForwardTypes"
/>
<div
v-else
class="col-6"
/>
<TextArea
class="col-12"
name="note"
Expand Down
7 changes: 0 additions & 7 deletions frontend/src/components/submission/SubmissionForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ onBeforeMount(async () => {
initialFormValues.value = {
...props.submission,
applicationStatus: props.submission.applicationStatus,
bringForwardDate: props.submission.bringForwardDate ? new Date(props.submission.bringForwardDate) : undefined,
submittedAt: new Date(props.submission.submittedAt),
submittedBy: formatJwtUsername(props.submission.submittedBy),
submissionTypes: {
Expand Down Expand Up @@ -408,12 +407,6 @@ onBeforeMount(async () => {
label="Waiting on"
:disabled="!props.editable"
/>
<Calendar
class="col-6"
name="bringForwardDate"
label="Bring forward date"
:disabled="!props.editable"
/>
<EditableDropdown
class="col-4"
name="user"
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/types/Note.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { IStamps } from '@/interfaces';
export type Note = {
noteId: string; // Primary Key
activityId: string;
bringForwardDate?: string;
bringForwardState?: string;
note: string;
noteType: string;
title: string;
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NIL } from 'uuid';
import {
ACCESS_ROLES,
APPLICATION_STATUS_LIST,
BRING_FORWARD_TYPES,
INTAKE_STATUS_LIST,
NOTE_TYPES,
PERMIT_STATUS,
Expand Down Expand Up @@ -86,6 +87,8 @@ export const IntakeStatusList = [
*/
export const NoteTypes = [NOTE_TYPES.GENERAL, NOTE_TYPES.BRING_FORWARD];

export const BringForwardTypes = [BRING_FORWARD_TYPES.UNRESOLVED, BRING_FORWARD_TYPES.RESOLVED];

export const QueuePriority = [0, 1, 2, 3, 4, 5];

/**
Expand Down
Loading
Loading