-
Notifications
You must be signed in to change notification settings - Fork 0
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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(); | ||
}) | ||
); | ||
} | ||
|
||
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'); | ||
}) | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'; | ||
|
@@ -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"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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> | ||
|
@@ -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> | ||
|
@@ -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> | ||
|
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'; | ||
|
@@ -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/ | ||
|
@@ -61,6 +95,8 @@ watch(visible, (newValue) => { | |
nextTick().then(() => { | ||
if (newValue && formRef.value) { | ||
formRef.value.setFieldValue('createdAt', new Date()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} | ||
}); | ||
}); | ||
|
@@ -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" | ||
|
There was a problem hiding this comment.
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