codeforpdx / PASS

PASS project - with HMIS module integration
MIT License
26 stars 25 forks source link

Enhancement: Convert the "To" field in New Message Modal to select contacts #413

Closed timbot1789 closed 7 months ago

timbot1789 commented 10 months ago

Currently, if you want to send a message, you need to fill the "To" field with the whole web ID of whoever you want to message. This is a multipart URL (like https://timstanden.solidcommunity.net). It needs to be typed exactly, and is very difficult for users to remember.

image

Instead, we could make the "To" field select from the user's contacts list. If a person is in your contacts list, you simply type in their name, and we autopopulate the field with the proper URL, like gmail does with a person's name and email: image

Implementing this will make it significantly easier to send messages in PASS

timbot1789 commented 10 months ago

The technique of matching on an odd part of a string is usually called "fuzzy search." We'll probably want to use a fuzzy search library to implement this feature: https://www.geeksforgeeks.org/fuzzy-search-in-javascript/#

We can do a fuzzy search match on either the person's name, or their webId

cnease10 commented 9 months ago

Based on what is in the comments of this issue, I'm going to implement the https://mui.com/material-ui/react-autocomplete/ instead of the Select due to user needing to type.

That sounds good to me!

cnease10 commented 9 months ago

Question: Can users send messages to more than one recipient at a time?

cnease10 commented 9 months ago
Screen Shot 2023-10-09 at 9 08 33 PM
cnease10 commented 9 months ago
Screen Shot 2023-10-09 at 9 08 58 PM
cnease10 commented 9 months ago

Testing Issues/Questions

timbot1789 commented 9 months ago

Question: Can users send messages to more than one recipient at a time?

We don't have this feature yet

timbot1789 commented 9 months ago

Testing Issues/Questions

  • There's no unit tests for this file
  • I created a couple of contacts to use with the dropdown but I get a 401 when trying to send the message, not sure if I need a real webId for the contact to be able to send the message
  1. Older code that was implemented before we added unit testing may not have unit test coverage. We expect all new code to have full coverage
  2. Does the account/webId actually exist? Adding someone to your contacts list doesnt create them. Just like adding a friend's phone number in your phone doesn't create a phone number. If the webid doesnt actually exist, 401 is expected behavior.
cnease10 commented 9 months ago
  1. Older code that was implemented before we added unit testing may not have unit test coverage. We expect all new code to have full coverage
  2. Does the account/webId actually exist? Adding someone to your contacts list doesnt create them. Just like adding a friend's phone number in your phone doesn't create a phone number. If the webid doesnt actually exist, 401 is expected behavior.
  1. Okay cool, I see a section in the wiki that I can review.
  2. Yeah it doesn't exist, I figured that was it. Good to know, thank you!
cnease10 commented 9 months ago

^^ draft CR to figure out the CR process implementation code is here https://github.com/codeforpdx/PASS/compare/Development...messageSelectContact

Before posting finished CR, will add tests and create another webId to to manually test with

timbot1789 commented 7 months ago

@cnease10 Are you still interested in working on this issue? If not, we'll reassign it.

DionSat commented 7 months ago

Hello, cnease10 are you still working on this issue. If you want I can pick up this issue.

cnease10 commented 7 months ago

Hi @timbot1789 @DionSat apologies for the delay - I've been out of work/off computer screens since 10/26 from a car crash. I had started working on the tests for this, let me check where this is at.

cnease10 commented 7 months ago

@timbot1789 @DionSat I have the code for this here https://github.com/codeforpdx/PASS/tree/messageSelectContact and if someone wants to pull it down and add tests it will be finished.

starter code for the test

import React from 'react';
import { render } from '@testing-library/react';
import { expect, it, describe, vi } from 'vitest';
import { BrowserRouter } from 'react-router-dom';
import { NewMessageModal } from '@components/Modals';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const setShowModal = vi.fn()
const queryClient = new QueryClient();

/* eslint-disable react/jsx-no-constructed-context-values */
const MockModalComponent = () => (
  <BrowserRouter>
    <QueryClientProvider client={queryClient}>
        <NewMessageModal showModal={true} setShowModal={setShowModal} oldMessage={''} />
    </QueryClientProvider>
  </BrowserRouter>
);
/* eslint-enable react/jsx-no-constructed-context-values */

describe('NewMessageModal tests', () => {
    it('renders the autosuggest to field', () => {
        const contacts = [
          { familyName: 'Abby', person: 'Aaron Abby', podUrl: 'https://example.com/Abby' },
          { familyName: 'Builder', person: 'Bob Builder', podUrl: 'https://example.com/Builder' }
        ];

        const { getByTestId} = render(<MockModalComponent showModal={true} setShowModal={setShowModal} oldMessage={''} />);
        const toField = getByTestId('newMessageTo')

        // expect the autosuggest to field to be in the document
        expect(toField).toBe(true);

      });

})
DionSat commented 7 months ago

@cnease10 Looks like you already got most of it done, I was just curious to see if I could pick this up or I can finish the tests. I hope your doing alright after the accident.

cnease10 commented 7 months ago

@DionSat Thank you, it's slow progress, but I'm happy for the progress. It'd be awesome if you could finish the tests so it can be merged into the development branch :) Happy holidays!

DionSat commented 7 months ago

@cnease10 I'm going to go ahead and update your branch as well because its behind the development branch. Happy Holidays to you too.

DionSat commented 7 months ago

Okay I was able to make a test to select a contact from the dropdown menu on autocomplete and check if input field updated with the value.

it('selecting contact from autocomplete', async () => {
  vi.mock('@hooks/useContactsList', async (importOriginal) => {
    const mod = await importOriginal();
    return {
      ...mod,
      default: vi.fn(() => ({
        data: [
          {
            familyName: 'test',
            givenName: 'mock',
            person: 'mock test',
            podUrl: 'http://example/mocktest',
            thingId: 'http://example/mocktest/profile/card#me',
            webId: 'http://example/mocktest/profile/card#me'
          }
        ]
      }))
    };
  });

  render(<MockNewMessageModal />);
  // Get the input field of autocomplete
  const toInput = screen.getByRole('combobox');

  // Change the value of input
  await userEvent.type(toInput, 'test');
  // Keydown to highlight autocomplete dropdown option
  await userEvent.keyboard('[ArrowDown]');
  // Enter to select dropdown option
  await userEvent.keyboard('[Enter]');
  // verify value of input field
  expect(toInput.value).toBe('mock test');
});

Just want to know if this is enough for tests for now or if you want me to come up a few more. I'll reopen the PR for now.