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

PSP-8316 | Lease consultation updates #4281

Merged
merged 9 commits into from
Aug 27, 2024

Conversation

FuriousLlama
Copy link
Collaborator

@FuriousLlama FuriousLlama commented Aug 24, 2024

Added view and containers on the front end for consultations. Updated backend for new specifications

image

@FuriousLlama FuriousLlama added the enhancement New feature or request label Aug 24, 2024
@FuriousLlama FuriousLlama self-assigned this Aug 24, 2024
Copy link
Contributor

✅ No secrets were detected in the code.

1 similar comment
Copy link
Contributor

✅ No secrets were detected in the code.

Copy link
Contributor

✅ No secrets were detected in the code.

@eddherrera eddherrera self-requested a review August 26, 2024 15:40
@devinleighsmith
Copy link
Collaborator

The story, mockup, and confluence seem to have "There are no approvals or consultations." not "There are no consultations."

@devinleighsmith
Copy link
Collaborator

According to the mockup/confluence the heading should be Approvals/Consultation (although I wonder if it should be Approvals/Consultations)

@devinleighsmith
Copy link
Collaborator

Oh, and the button should be Add Approval/Consultation apparently.

I'm getting the feeling that maybe the mockups/confluence changed during development?

.max(2000, 'Other Description must be at most ${max} characters'),
otherwise: Yup.string().nullable(),
}),
comment: Yup.string().max(500, 'Other name must be at most ${max} characters'),
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this text is probably not correct for this field.

otherDescription: Yup.string().when('consultationTypeCode', {
is: (consultationTypeCode: string) => consultationTypeCode && consultationTypeCode === 'OTHER',
then: Yup.string()
.required('Other Description required')
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps: Other description?

@devinleighsmith
Copy link
Collaborator

Oddly, I don't see any documentation stating that Response received on is conditionally rendered, but that is the current logic. Is there a requirement I'm not seeing.

One issue with the current implementation is that if I set Response received Yes, and set a date, and then set response received No, the date is still set, and is displayed on the view only version of the screen, even when set to No.

@devinleighsmith
Copy link
Collaborator

@FuriousLlama what is the plan for the DB issue related to this story? Does Doug have a defect logged? my concern is that the next sprint is a release sprint, and I'm not sure Doug has made any corrections for this issue in 88.

@devinleighsmith
Copy link
Collaborator

Consultation type on the add/edit/view form should be Consultation/Approval type: or Approval/Consultation type depending on confluence or the mockup

@devinleighsmith
Copy link
Collaborator

There are a number of tooltips that were requested on the create/edit screen that appear to be missing (mentioned on the mockup and confluence).

@devinleighsmith
Copy link
Collaborator

Hmm, the confluence page specifies that the only allowed values for the Response received or Yes/No but the implementation has Unknown as well.

@devinleighsmith
Copy link
Collaborator

The text on the modal is Approval/Consultation as well.

@devinleighsmith
Copy link
Collaborator

Hmm, also I think the Consultation top-level header is being styled the same as the other headers. In the mockup I think it is using different styling (Hopefully consistent with existing PSP headers).

/// </summary>
/// <returns>The consultation items.</returns>
[HttpPost("{id:long}/consultations")]
[HasPermission(Permissions.LeaseView)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

LeaseEdit?

User.GetUsername(),
DateTime.Now);

var result = _leaseService.DeleteConsultation(consultationId);
Copy link
Collaborator

Choose a reason for hiding this comment

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

not sure if it matters, but:

  1. the lease id is unused.
  2. the other endpoints validate that the lease id passed is valid for the given consultationId.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point, I have added validation to all the routes

return _consultationRepository.GetConsultationById(consultationId);
}

public PimsLeaseConsultation AddConsultation(long leaseId, PimsLeaseConsultation consultation)
Copy link
Collaborator

Choose a reason for hiding this comment

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

unused param.

.Map(dest => dest.OtherDescription, src => src.OtherDescription)
.Map(dest => dest.RequestedOn, src => src.RequestedOn.ToNullableDateTime())
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this a DateOnly or a DateTime?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Its a datetime, however we only need dates, that's wh y the model changes it


return Context.PimsLeaseConsultations
.Where(lc => lc.LeaseId == leaseId)
.Include(lc => lc.ConsultationTypeCodeNavigation)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need the ConsultationStatusTypeCodeNavigation as well? or neither?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Consultation status is no longer used.

@@ -30,7 +30,7 @@ export const Section: React.FC<
className,
...rest
}) => {
const [isCollapsed, setIsCollapsed] = useState<boolean>(!initiallyExpanded && true);
Copy link
Collaborator

Choose a reason for hiding this comment

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

this was a strange one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yeah, changed it after some tests to make sure it does what we want

@@ -66,7 +66,6 @@ const StyledButton = styled(BootstrapButton)`
align-items: center;
justify-content: center;
padding: 0.4rem 1.2rem;
min-height: 3rem;
Copy link
Collaborator

Choose a reason for hiding this comment

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

ooph, this seems scary, are you sure that this doesn't have any unintended consequences?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Pretty confident, was causing misalignment on a lot of pages

Copy link
Collaborator

Choose a reason for hiding this comment

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

Its subtle, but this has definitely re-introduced the issue where the save and cancel buttons aren't the same size:

image

Could you either revert this, or find a way of sizing the cancel button (with its additional border) the same as the save button?

@@ -76,7 +75,6 @@ const StyledButton = styled(BootstrapButton)`
font-weight: 700;
letter-spacing: 0.1rem;
cursor: pointer;
height: 3.8rem;
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same as above

onDelete,
}) => {
const keycloak = useKeycloakWrapper();
const history = useHistory();
Copy link
Collaborator

Choose a reason for hiding this comment

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

See github actions warnings about unused variables.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think you have seen an old commit?

}, [consultationTypeCodes, consultations]);

if (loading) {
return <LoadingBackdrop show={loading} parentScreen={true} />;
Copy link
Collaborator

Choose a reason for hiding this comment

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

You probably couldn't see this, because load times are so fast on our locals, but this is what the loading screen looks like:

image

My preference for these is to render an empty version of the screen with the loading backdrop overtop, but some kind of correction required here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think there is some room for improvement here. Will chat win ana to check what her thoughts are on loading.

<Row>
<Col>
{group.consultationTypeCode === 'OTHER'
? `${consultation.otherDescription} Consultation`
Copy link
Collaborator

Choose a reason for hiding this comment

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

is null/undefined checking required here? aka ?? ''

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not needed, the view model uses empty strings if the value coming from the wire is empty

Copy link
Collaborator

Choose a reason for hiding this comment

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

This is what I'm seeing locally:

image

) => {
try {
const consultationSaved = await addConsultation(leaseId, values.toApi());
if (consultationSaved) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm, the only issue I see is that if somehow this is false, no error is presented but also the onSuccess and navigation isn't fired.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That is true, however, that's our current pattern in other screens.

const consultationSaved = await addConsultation(leaseId, values.toApi());
if (consultationSaved) {
onSuccess();
history.push(backUrl);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this component be handling navigation or should it just be firing callbacks?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Navigation at the container makes sense to me.

return (
initialValues && (
<StyledFormWrapper>
<Formik<ConsultationFormModel>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think these forms could use the component as well.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what you mean here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh, one of my comments must not have been saved, referring to the ConfirmNavigation component.

const ConsultationUpdateContainer: React.FunctionComponent<
React.PropsWithChildren<IConsultationUpdateContainerProps>
> = ({ leaseId, consultationId, onSuccess, View }) => {
const [leaseConsultations, setLeaseConsultations] = useState<ApiGen_Concepts_ConsultationLease[]>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

some more unused variables detected by GH.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this is an earlier commit

person = await getPerson(consultation.personId);
}
if (isValidId(consultation.organizationId)) {
person = await getOrganization(consultation.organizationId);
Copy link
Collaborator

Choose a reason for hiding this comment

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

typo, should be organization not person.

) => {
try {
const consultationSaved = await updateConultation(leaseId, values.id, values.toApi());
if (consultationSaved) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

same comment here, what should happen if the object is falsey?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Same as above

? fromApiOrganization(organization)
: undefined;

consultation.primaryContactId = apiModel.primaryContactId;
Copy link
Collaborator

Choose a reason for hiding this comment

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

hmm, I think this is ok - just want to make sure we shouldn't be conditionally setting this based on whether the id is an org?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

AFAIK only persons can be primary contacts

() => ({
getLeaseConsultationsApi: (leaseFileId: number) =>
api.get<ApiGen_Concepts_ConsultationLease[]>(`/leases/${leaseFileId}/consultations`),
getLeaseConsultationByIdApi: (leaseFileId: number, agreementId: number) =>
Copy link
Collaborator

Choose a reason for hiding this comment

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

is agreementId correct?

onError: useAxiosErrorHandler('Failed to create Lease File Consultation'),
});

const updateLeaseConsultation = useApiRequestWrapper<
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, I think you have try/catches down the line from these calls, but I think the default behaviour is to catch errors from these and use the onError provided below. If you want to throw an exception I think you need throwError: true.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

thats right. I've updated it now

@@ -54,6 +54,12 @@ export function isPersonResult(
return contactResult.id.startsWith('P') && contactResult.personId !== undefined;
}

export function isOrganizationResult(
Copy link
Collaborator

Choose a reason for hiding this comment

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

thanks for this.

Copy link
Collaborator

@devinleighsmith devinleighsmith left a comment

Choose a reason for hiding this comment

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

Only blocking this because I'm concerned about the changes to the base button styling. If you are confident that isn't an issue, let me know.

@FuriousLlama
Copy link
Collaborator Author

Only blocking this because I'm concerned about the changes to the base button styling. If you are confident that isn't an issue, let me know.

Pretty confident is not an issue. That extra padding was causing alignment issues all over the app. Checked when it was added and its very early on so I don't think it was part of any button styling enhancement.

@asanchezr asanchezr added the 5.5 label Aug 27, 2024
Copy link
Contributor

✅ No secrets were detected in the code.

@FuriousLlama
Copy link
Collaborator Author

Oddly, I don't see any documentation stating that Response received on is conditionally rendered, but that is the current logic. Is there a requirement I'm not seeing.

One issue with the current implementation is that if I set Response received Yes, and set a date, and then set response received No, the date is still set, and is displayed on the view only version of the screen, even when set to No.

Yes, I infered that. I will check with dev once this hits DEV and adjust it as necessary

Copy link
Contributor

✅ No secrets were detected in the code.

@devinleighsmith
Copy link
Collaborator

I had a look at the button styling, and this did introduce an issue, but its minor enough that I'll lift the change request. Would still prefer a solution before this is merged.

Copy link
Collaborator

@devinleighsmith devinleighsmith left a comment

Choose a reason for hiding this comment

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

Approved, but would like some more changes before merge. Also assuming test coverage is coming in future?

Copy link
Contributor

✅ No secrets were detected in the code.

@FuriousLlama FuriousLlama merged commit 52137cd into bcgov:dev Aug 27, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5.5 enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants