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

[Tagging] Assign taxonomy to organizations #117

Closed
bradenmacdonald opened this issue Sep 21, 2023 · 10 comments
Closed

[Tagging] Assign taxonomy to organizations #117

bradenmacdonald opened this issue Sep 21, 2023 · 10 comments

Comments

@bradenmacdonald
Copy link
Contributor

bradenmacdonald commented Sep 21, 2023

"As a global staff member, I can assign taxonomies to organizations."

"As a global staff member, I can assign a taxonomy to all organizations."

"As a global staff member, I can assign a taxonomy to no particular organization."

Relates to #108 , #116 , and #109

Acceptance Criteria

  1. On the Taxonomy List Page, Indicate when a taxonomy is used by multiple organizations, as shown below.
  2. For global staff users (and no other users), the "Manage organizations" menu will be added to the Taxonomies List Page and the Taxonomy Detail Page:
    Screenshot 2023-10-11 at 2 46 08 PM
    Screenshot 2023-10-11 at 2 46 48 PM
  3. This does not apply to system taxonomies.
  4. Upon selecting that menu, this dialog will pop up, allowing the user to edit the assigned orgs:
    Screenshot 2023-10-11 at 2 50 07 PM
    Screenshot 2023-10-11 at 2 50 22 PM
  5. If no orgs are selected, display this warning:
    Screenshot 2023-10-11 at 2 51 19 PM
  6. Upon saving changes, a toast appears in the bottom left:
    Screenshot 2023-09-20 at 5 40 37 PM

Developer Notes

@bradenmacdonald
Copy link
Contributor Author

@ali-hugo I don't think we'll have time/budget here to implement your exact design, especially since Paragon doesn't yet have a working multiselect component.

What do you think about using a simpler design where we show the list of currently assigned orgs usings chips (like in your design now, but not inside of a multiselect, just above on the page), and then using a Form.autosuggest component to allow adding additional orgs one at a time? I think you actually had a design like that previously...

something like this:


Assign to Organizations

Currently assigned: [ Org 1 Chip x ] [ Org 2 Chip x ]

Add another organization: [ Form.Autoselect ⌄ ]

[ ] Assign to all orgs


Also, can you confirm if checking "assign to all orgs" should disable the controls above?

@rpenido
Copy link

rpenido commented Dec 12, 2023

Hi @bradenmacdonald! CC @ali-hugo
Do you think this is enough for the Autosuggest? I will fix the CSS to give more room for the dropdown.

manage_orgs

It is not possible to clear the input the right way because the Autosuggest component does not forward the ref of the input (as other components usually do).

@bradenmacdonald
Copy link
Contributor Author

bradenmacdonald commented Dec 12, 2023

@rpenido That seems like a bug in paragon. The Form.Autosuggest should have higher priority than the modal it's in. Can you just keep the modal the same size but add a CSS rule so that the dropdown has a higher z-index? I have asked about this on #wg-frontend in case we're missing something.

It is not possible to clear the input the right way because the Autosuggest component does not forward the ref of the input (as other components usually do).

What do you mean? You shouldn't need a ref to the input element to reset it. You just need to change the value prop of the <Form.Autosuggest to be an empty string. Wouldn't that clear it?

@rpenido
Copy link

rpenido commented Dec 12, 2023

It uses the value only in the first render to set the displayValue internal state (ref).

const [state, setState] = useState({
    displayValue: value || '',
    errorMessage: '',
    dropDownItems: [],
  });

This displayValue is the state that define the value of the input:

 <FormControl
          ...
          value={state.displayValue}
          ...
/>

After the first render, the displayValue is updated in the onChange (when we type something) or when we select an option.

    setState(prevState => ({
      ...prevState,
      dropDownItems: [],
      displayValue: clickedValue,
    }));

It could not always render the value props because the user input data is handled (and rendered) internally in the component.

I tried to clean the input value using document.querySelector('...').value = '', but it was overrided as soon as I interacted with the component.

I'm not seeing an easy solution to improve it here.

@brian-smith-tcril
Copy link

brian-smith-tcril commented Dec 13, 2023

It uses the value only in the first render to set the displayValue internal state (ref).

I have a PR out to rework the Autosuggest component a bit (with breaking changes) here: openedx/paragon#2899

Is there any chance you could try out that version of the component? I'd be more than happy to update that PR to include solutions for any issues it doesn't solve!

The Form.Autosuggest should have higher priority than the modal it's in. Can you just keep the modal the same size but add a CSS rule so that the dropdown has a higher z-index? I have asked about this on #wg-frontend in case we're missing something.

I brought this up in the Paragon working group meeting today and I will be looking into possible short term (read: small code change) fixes today. Once a short term fix is in place, the plan is to look into how to best integrate z-index hooks into Paragon.

edit: After some quick testing on https://deploy-preview-2899--paragon-openedx.netlify.app/components/form/form-autosuggest/ I found that the display value in the text box is still not being updated when the value is updated from outside of the component. I used this in the jsx live box to test:

() => {
    const [value, setValue] = useState({});
    const [valueRequired, setValueRequired] = useState(false);
    const [selectionRequired, setSelectionRequired] = useState(false);
    const [customValidation, setCustomValidation] = useState(false);

    const customError = () => customValidation ? value.selectionId !== "c-option-id" : false;

    return (
        <>
        <button onClick={() => setValue({})}>Clear Value</button>
        <Form.Group>
            <Form.Label>
                <h4>Programming language</h4>
            </Form.Label>
            <Form.Autosuggest
                aria-label="form autosuggest"
                helpMessage="Select language"
                value={value}
                onChange={(v) => setValue(v)}
                valueRequired={valueRequired}
                valueRequiredErrorMessageText="Error: value required"
                selectionRequired={selectionRequired}
                selectionRequiredErrorMessageText="Error: selection required"
                customError={customError()}
                customErrorMessageText="Error: selected language less than 50 years old"
            >
                <Form.AutosuggestOption id="javascript-option-id">JavaScript</Form.AutosuggestOption>
                <Form.AutosuggestOption id="python-option-id">Python</Form.AutosuggestOption>
                <Form.AutosuggestOption id="ruby-option-id">Ruby</Form.AutosuggestOption>
                <Form.AutosuggestOption id="c-option-id">C</Form.AutosuggestOption>
            </Form.Autosuggest>
        </Form.Group>
        <Form.Group>
          <Form.CheckboxSet isInline>
            <Form.Checkbox checked={valueRequired} onChange={e => setValueRequired(e.target.checked)}>Value Required</Form.Checkbox>
            <Form.Checkbox checked={selectionRequired} onChange={e => setSelectionRequired(e.target.checked)}>Selection Required</Form.Checkbox>
            <Form.Checkbox checked={customValidation} onChange={e => setCustomValidation(e.target.checked)}>Custom Validation</Form.Checkbox>
          </Form.CheckboxSet>
        </Form.Group>
        <Collapsible styling="basic" title="Value details">
            <Row>
                <Col xs={3}><pre>userProvidedText:</pre></Col>
                <Col><pre>{value.userProvidedText}</pre></Col>
            </Row>
            <Row>
                <Col xs={3}><pre>selectionValue:</pre></Col>
                <Col><pre>{value.selectionValue}</pre></Col>
            </Row>
            <Row>
                <Col xs={3}><pre>selectionId:</pre></Col>
                <Col><pre>{value.selectionId}</pre></Col>
            </Row>
        </Collapsible>
        </>
    );
}

Before clicking "Clear Value" we see
image
and after clicking "Clear Value" we get
image

I will work to update the PR to address this.

@bradenmacdonald
Copy link
Contributor Author

Thanks @brian-smith-tcril !

@rpenido
Copy link

rpenido commented Dec 13, 2023

Thank you @brian-smith-tcril! I think this will cover our use case.

I will work to update the PR to address this.

I took a fast look at the code and didn't find any immediate problem. 😞

From my side, I managed to clear the component using:

      const inputRef = document.querySelector('.pgn__form-group input');
      inputRef.value = null;
      const event = new Event('change', { bubbles: true });
      inputRef.dispatchEvent(event);

@brian-smith-tcril
Copy link

I have a PR out for the overflow issue here openedx/paragon#2939

I've made some progress on setting/clearing the value on my other branch, I'll take another pass at it today and share once I get it to a point I'm happy with.

@brian-smith-tcril
Copy link

I'm happy with the value clearing implementation I have in this PR now (preview here). If you pull in the updated example code from #117 (comment) (I switched value={value.userProvidedValue} to value={value}) it should be working as expected now.

@ali-hugo
Copy link

ali-hugo commented Jan 3, 2024

@bradenmacdonald Sorry for the delayed response; today is my first day back from leave.

What do you think about using a simpler design [...] I think you actually had a design like that previously...

I'm happy with that approach :)

Also, can you confirm if checking "assign to all orgs" should disable the controls above?

Yes, if the user selects “assign to all organizations”, the dropdown for assigning individual orgs disappears (sorry, I see I forgot to update this in the design - I have done so now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Development

No branches or pull requests

4 participants