Create internal links when editing long text more easily with a shortcut
Closed this issue · 8 comments
A bit like in an IDE where you can press e.g. Ctrl+Space, and start typing, and it will give you suggestions for appropriate content. It would be very handy to be able to do this here, using a Lucene prefix search (a suitable endpoint may need to be created if one doesn't already exist).
See also #417
Related
@jamesrwelch @olliefreeman Is there an endpoint that exists which can act as a quick search for this autocomplete feature?
this is dependent on work on the API branch feature/addtl-search-endpoints
I believe the endpoints required for this are now merged in mdm-core
. It feels like to have an autocomplete style search, the following endpoint should be used:
POST /api/catalogueItems/search
{
"searchTerm": <autocomplete input>,
"labelOnly" : true,
"max": 20, // Or some suitable number
"offset: 0,
"sort": "label",
"order": "asc"
}
@olliefreeman - can you confirm if this is correct?
See https://metadatacatalogue.myjetbrains.com/youtrack/issue/MC-9843 for further details on front/back end features.
I've been experimenting with the UI concepts of this "autocomplete" component with Jodit and the markdown editor. My initial thoughts were that this was going to look like an inline, popup-based component that appears as (and where) you type, like this:
In fact, Jodit has a plugin just for this: https://xdsoft.net/jodit/pro/docs/plugin/autocomplete. But I'm coming up against a number of issues.
Jodit Pro
The Jodit Autocomplete plugin is for the Pro version of the Jodit editor only. Given the price and restrictions, it is not feasible to use this. Plus, this only affects the Jodit HTML editor, an equivalent would have to be found for the Markdown editor.
Custom Jodit plugin
The next alternative is to write out own version of an autocomplete plugin. There I was faced with new issues:
- The type definitions exported by the
jodit
library end up producing compiler errors, I'm not sure why - I can't seem to access the global
Jodit
JavaScript object from an Angular component, this is required to add to the plugins list viaJodit.plugins.add()
. - Again, this would only work with the Jodit HTML editor, not our Markdown editor.
Custom JavaScript UI
The next alternative I thought of was to manually handle input triggers to both the Jodit and Markdown editors, then figure out how to display our own <div>
inline popup with a list of eventual search results. This involves:
- Identifying the
keydown
event where the Ctrl+Space key is pressed together - Locating the caret position/co-ordinates of the currently focused input field
- Use the co-ordinates to manually set the
display
of some<div>
that was previously hidden, setting thetop
andleft
of the div as well for absolute positioning. - Respond to further events to handle re-positioning, hiding the autocomplete, key inputs to send further search requests etc
This is actually incredibly complex (probably why 3rd party controls exist for this kind of thing). In my experiments I could sometimes get the caret position, but sometimes not depending on whitespace. Then handling further interactions would make this a lot of code to maintain.
Simplification
Complex JavaScript and DOM manipulation is a bit outside of my skillset. However, to get something like this working for both the Markdown and HTML editors, the best solution I can think of for now is to follow the existing pattern used by generating links:
In the above screenshot, a custom editor toolbar button is used to trigger own own MatDialog
containing a small wizard for selecting a model directly from a tree search.
My simplified proposal would be:
- Still respond to keyboard events to capture the Ctrl+Space shortcut (or trigger via a custom toolbar button too)
- Display a new
MatDialog
containing the autocomplete search - The dialog would contain a search field. Once enough characters have been entered, a prefix label search will be triggered to show a small number of results (e.g. 10)
- Typing in the search field would automatically adjust the search results - no manual button clicks required
- Once a result was selected, the details are sent back to the editor to construct a suitable link (HTML or Markdown style) to that item. The editors already do something similar.
Forcing a MatDialog
to contain the "autocomplete" would simplify this feature and get something available out sooner. In the future, someone else could then look into updating to be more inline if possible.
@pjmonks Yep, I agree, let's not worry about it appearing at the caret position. If we can ensure it disappears / cancels with an 'esc' key press (I think this is the default behaviour), then that would be lovely.
Endpoints
Reading https://metadatacatalogue.myjetbrains.com/youtrack/issue/MC-9843 and looking at the source code for mdm-core
, it seems like this is the endpoint we need for autocomplete search:
Request
POST api/{catalogueItemdomainType}/{cataloguetItemid}/search
{
"searchTerm": "text",
"max": 10,
"offset": 0,
"sort": null // or label?
"order": null // or "asc"?
}
Response
{
"count": 10,
"items": [
{
"id": "1234-5678",
"label": "item",
"domainType": "DataModel",
"breadcrumbs": [...]
}
]
}
Questions
For @jamesrwelch:
This endpoint assumes we know a catalogue item acting as a parent/root for the search, but the content editors could be used in various places where you might not know a suitable parent. Is the intention for this autocomplete to be for descriptions of models? If so, it feels like the autocomplete feature will only work in the scenario of editing a model, so would be an editing feature enabled when a parentModel
is passed through an @Input
.
@pjmonks I think we'd want it whenever we're editing any model item / catalogue item (Data Element, Data Class, Term, etc). In those cases we'd know the Catalogue Item domain / id, because that would be the thing we'd pass the submission to?
In other cases (API Properties, etc) we could make this functionality unavailable?