-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
[Ingest Pipelines] Add url generator for ingest pipelines app #77872
Conversation
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
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.
Great work, Yulia! I took a quick look and had some questions/suggestions, mostly regarding the interface.
@@ -50,11 +50,11 @@ export const PipelinesCreate: React.FunctionComponent<RouteComponentProps & Prop | |||
return; | |||
} | |||
|
|||
history.push(BASE_PATH + `?pipeline=${encodeURIComponent(pipeline.name)}`); | |||
history.push(URL_GENERATOR[INGEST_PIPELINES_PAGES.LIST](pipeline.name)); |
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.
This seems like a bit of an awkward interface because I have to import two things, combine them in the right way, and then infer that they map to a function which I then call. It seems like a more intuitive interface would be to import a function and then call that.
import { getListPath } from '../../services/navigation';
/* ... */
history.push(getListPath(pipeline.name));
WDYT?
EDIT: I just got to the end of the PR and saw the URL generator, which implements an interface similar to what I'm suggesting. Is it possible to use the generator internally?
import { urlGenerator } from '../../services/navigation';
/* ... */
history.push(getListPath(pipeline.name));
history.push(urlGenerator.createUrl({
page: urlGenerator.LIST,
pipelineId: pipeline.name,
}));
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.
I agree, the import is too complicated, I changed it to a function export for internal use. I'm not sure UrlGenerator
should be used internally, since we don't need an absolute path and createUrl
is async.
return `${BASE_PATH}${CREATE_PATH}`; | ||
}; | ||
|
||
const getClonePath = (name: string, encode = true): string => { |
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.
I think we can improve the readability of the code by using config parameters for these path factories. Consider the difference:
// current
getListPath(updatedPipeline.name);
getClonePath(':sourceName', false);
// my suggestion
getListPath({ inspectedPipeline: updatedPipeline.name });
getClonePath({ clonedPipeline: ':sourceName', skipEncode: true });
I think it generally makes sense to avoid config parameters when you're only passing in one or two arguments, but I think in this situation it's very helpful for communicating the intention of the code.
const urlGenerator = new IngestPipelinesUrlGenerator(getAppBasePath); | ||
|
||
describe('Pipelines List', () => { | ||
it('should generate correct relative url for list without pipelineId', async () => { |
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.
This is just a pet peeve of mine so feel free to disregard it. 😄 I noticed that every description contains the phrase should generate correct <result>
and I think the words "should" and "correct' become a bit redundant for test descriptions. If you wanted to make them terser I think you could rephrase them as generates <result>
.
|
||
public readonly createUrl = async (state: IngestPipelinesUrlGeneratorState): Promise<string> => { | ||
return `${await this.getAppBasePath(!!state.absolute)}${URL_GENERATOR[state.page]( | ||
state.pipelineId! |
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.
We're referring to this as pipelineId
here but in navigation.ts
the term name
is used instead. Can we consistently use one or the other to make the connection clearer?
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.
Hey @cjcenizal , I'm glad you noticed that! After a discussion with @darnautov and reading the docs, I figured out that the "official" term is pipeline_id
. In Ingest Pipelines plugin code we refer to this property as pipelineName
, so I decided to use name
in internal functions and id
for external use.
|
||
it('should generate correct absolute url for pipeline clone', async () => { | ||
const url = await urlGenerator.createUrl({ | ||
page: INGEST_PIPELINES_PAGES.CREATE, |
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.
Do consumers of the generator have access to INGEST_PIPELINES_PAGES
? Is it defined on the public interface somewhere? I wonder why it's not exposed as part of the URL generator's interface, like this:
urlGenerator.createUrl({
page: urlGenerator.CREATE,
pipelineId: 'pipeline_name',
});
I guess I'm just confused about how consumers in another plugin will know which strings to pass in for the page
property.
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.
We've faced the same issue, it's not possible ATM to extend urlGenerator
class, check
getPublicContract(): UrlGeneratorContract<Id> { |
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.
I am currently exporting generator id, generator class, generator state and pages enum for external use in public.ts
export {
INGEST_PIPELINES_APP_ULR_GENERATOR,
IngestPipelinesUrlGenerator,
IngestPipelinesUrlGeneratorState,
INGEST_PIPELINES_PAGES,
} from './url_generator';
I think, it should be enough for ML plugin to use this url generator, WDYT @darnautov ?
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.
I don't think we need any of these TBH, because you register the URL generator during your Inget Pipeline plugin setup and we simply get it using the share
. Typescript will validate the provided state as well.
@elasticmachine merge upstream |
Hi @cjcenizal, |
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.
Code LGTM! Nice work! I had a couple of suggestions but they're not blockers.
@@ -9,9 +9,9 @@ const basicLicense: LicenseType = 'basic'; | |||
|
|||
export const PLUGIN_ID = 'ingest_pipelines'; | |||
|
|||
export const PLUGIN_MIN_LICENSE_TYPE = basicLicense; | |||
export const MANAGEMENT_APP_ID = 'management'; |
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.
This seems like something the management
plugin should define inside a common/constants.ts
file and export in https://github.com/elastic/kibana/blob/master/src/plugins/management/public/index.ts. Since the management
plugin is already a dependency of this plugin, it seems like it would be straightforward to make that change and consume the constant wherever we need it like this:
import { MANAGEMENT_APP_ID } from 'src/plugins/management/public';
The only slightly invasive change would be you'd have to update the management
plugin to consume this constant on this line: https://github.com/elastic/kibana/blob/master/src/plugins/management/public/plugin.ts#L75
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.
Yeah, I was looking at the management app for an exported constant but couldn't find any. So I added an export, do you know maybe who would be a code owner for this plugin? @cjcenizal
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.
That would be the Kibana App Arch team.
return `${BASE_PATH}${name ? `?pipeline=${encodeURIComponent(name)}` : ''}`; | ||
}; | ||
|
||
export const ROUTES_CONFIG = { |
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.
Nit: I'm not sure the CONFIG
suffix adds more information, since personally I'd infer ROUTES
to be a constant, and from the name it would contain the various routes of the app.
clone: _getClonePath(':sourceName', false), | ||
}; | ||
|
||
export const getListPath = ({ |
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.
Nit: what do we gain by exporting adapter functions instead of the original functions? For example:
// Setting a default for `encode` supports the simpler consumption pattern of not
// having to specify it, and I don't think we lose anything by allowing the consumer
// to specify `false`.
export const getEditPath = ({ pipelineName, encode = true }: { pipelineName: string, encode?: boolean }): string => {
return `${BASE_PATH}${EDIT_PATH}/${encode ? encodeURIComponent(name) : name}`;
};
/* snip */
export const ROUTES_CONFIG = {
edit: getEditPath({ pipelineName: ':name', encode: false }),
/* snip */
};
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.
I think that encoding the parameter is an implementation detail and should not be needed for clients using the navigation service, hence a separate ROUTES
constant.
💚 Build SucceededBuild metrics@kbn/optimizer bundle module count
async chunks size
page load bundle size
distributable file count
History
To update your PR or re-run it, just comment with: |
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.
app arch owned changes LGTM
…c#77872) * [Ingest Pipelines] Add url generator for ingest pipelines app * [Ingest Pipelines] Fix type check error * [Ingest Pipelines] Fix import errors * [Ingest Pipelines] Fix type check errors * [Ingest Pipelines] Fix type check errors * [ILM] Update UrlGenerator interface, clean up internal navigation service * [ILM] Fix function export * [ILM] Update functions signatures * [ILM] Fix errors * [ILM] Fix errors * [ILM] Rename ROUTES_CONFIG and export MANAGEMENT_APP_ID Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
* master: (31 commits) skip tests for old pacakge (elastic#78194) [Ingest Pipelines] Add url generator for ingest pipelines app (elastic#77872) [Lens] Rename "telemetry" to "stats" (elastic#78125) [CSM] Url search (elastic#77516) [Drilldowns] Config to disable URL Drilldown (elastic#77887) [Lens] Combined histogram/range aggregation for numbers (elastic#76121) Remove legacy plugins support (elastic#77599) 'Auto' interval must be correctly calculated for natural numbers (elastic#77995) [CSM] fix ingest data retry order messed up (elastic#78163) Add response status helpers (elastic#78006) Bump react-beautiful-dnd (elastic#78028) [Security Solution][Detection Engine] Bubbles up more error messages from ES queries to the UI (elastic#78004) Index pattern - refactor constructor (elastic#77791) Add `xpack.security.sameSiteCookies` to docker allow list (elastic#78192) Remove [key: string]: any; from IIndexPattern (elastic#77968) Remove requirement for manage_index_templates privilege for Index Management (elastic#77377) [Ingest Manager] Agent bulk actions UI (elastic#77690) [Metrics UI] Add inventory view timeline (elastic#77804) Reporting/Docs: Updates for setting to enable CSV Download (elastic#78101) Update to latest rum-react (elastic#78193) ...
#78278) * [Ingest Pipelines] Add url generator for ingest pipelines app * [Ingest Pipelines] Fix type check error * [Ingest Pipelines] Fix import errors * [Ingest Pipelines] Fix type check errors * [Ingest Pipelines] Fix type check errors * [ILM] Update UrlGenerator interface, clean up internal navigation service * [ILM] Fix function export * [ILM] Update functions signatures * [ILM] Fix errors * [ILM] Fix errors * [ILM] Rename ROUTES_CONFIG and export MANAGEMENT_APP_ID Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Summary
Fixes #75558.
This PR adds a url generator for Ingest Pipelines UI plugin that is registered in
SharePlugin
and can be used by other apps to deep-link to pages in Ingest Pipelines. For more information see README.md.Checklist
Delete any items that are not applicable to this PR.