-
Notifications
You must be signed in to change notification settings - Fork 2.9k
NIFI-14319: Create initial project structure for new NiFi Registry UI #9855
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
base: main
Are you sure you want to change the base?
Conversation
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.
Thanks for this work on NiFi Registry @sardell!
The standard ci-workflow
builds are failing, does this build locally for you, or is this still a work in progress that should be marked as draft?
@exceptionfactory Thanks for raising the failing CI to my attention. It looks like the failure was due to the favicon missing from the old registry ui directory. I accidentally deleted it when copying over images to the new project. I noticed the missing file while working on this PR and added the file back, but it seems that file was accidentally added to the .gitignore (I think intention of that .gitignore line was to ignore the generated favicon, not all instances of that file). I believe this is why I could successfully build locally and also see the CI failures you pointed out. Fingers crossed the CI passes this time. I'll keep an eye on it. UPDATE: Looks like the CI build is now failing on a build step that runs fine locally. Will need to investigate a little further. |
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.
Thanks for the update @sardell, although the build completes on macOS, it is failing on Linux and Windows.
On Linux, there appears to be something platform-dependent:
[INFO] ::group::❌ > nx run shared:build:production
[INFO]
[INFO] Building Angular Package
[INFO]
[INFO] ------------------------------------------------------------------------------
[INFO] Building entry point '@nifi/shared'
[INFO] ------------------------------------------------------------------------------
[INFO] - Compiling with Angular sources in Ivy full compilation mode.
[INFO] ✖ Compiling with Angular sources in Ivy full compilation mode.
[INFO]
[INFO] NX The package "@esbuild/linux-x64" could not be found, and is needed by esbuild.
bd6fd83
to
74df539
Compare
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.
looks good for the 1st glance, I post my first comments, will continue the review soon
nifi-frontend/src/main/frontend/apps/nifi-registry/src/app/ui/header/header.component.ts
Outdated
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/src/app/state/droplets/droplets.effects.ts
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/src/app/state/droplets/droplets.effects.ts
Outdated
Show resolved
Hide resolved
...olorer/feature/ui/import-new-flow-version-dialog/import-new-flow-version-dialog.component.ts
Outdated
Show resolved
Hide resolved
...ry/src/app/pages/expolorer/feature/ui/droplet-table-filter/droplet-table-filter.component.ts
Outdated
Show resolved
Hide resolved
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.
@sardell thanks for the PR! I have left several comments on things that need to be addressed. Apologies that there are so many comments as I know this is a big undertaking and your effort here is appreciated. I am sure I will have more comments after you make the requested changes.
Also, I didn't have a great place to leave the following comments so placing them here:
Please run prettier and lint:fix. There are several strange formatting issues.
Please delete nifi-registry/public directory and the favicon.ico.
nifi-frontend/src/main/frontend/apps/nifi-registry/project.json
Outdated
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/project.json
Outdated
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/.eslintrc.json
Outdated
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/.eslintrc.json
Outdated
Show resolved
Hide resolved
nifi-frontend/src/main/frontend/apps/nifi-registry/.eslintrc.json
Outdated
Show resolved
Hide resolved
...rc/app/pages/expolorer/feature/ui/delete-droplet-dialog/delete-droplet-dialog.component.html
Outdated
Show resolved
Hide resolved
...rc/app/pages/expolorer/feature/ui/delete-droplet-dialog/delete-droplet-dialog.component.html
Outdated
Show resolved
Hide resolved
...rc/app/pages/expolorer/feature/ui/delete-droplet-dialog/delete-droplet-dialog.component.html
Outdated
Show resolved
Hide resolved
...rc/app/pages/expolorer/feature/ui/delete-droplet-dialog/delete-droplet-dialog.component.html
Outdated
Show resolved
Hide resolved
...rc/app/pages/expolorer/feature/ui/delete-droplet-dialog/delete-droplet-dialog.component.html
Outdated
Show resolved
Hide resolved
@scottyaslan @elcsiga Thank you both for taking the time to review this PR! I've addressed all your comments. When you have a chance, could you please take another look? @scottyaslan I've updated the Jira tickets for the Registry UI work to be tasks organized under an epic per your suggestion. I've also started breaking down the work into much smaller chunks (see the ticket for the buckets view and its subtasks for an example). I'll continue this work for the users and groups view. |
@scottyaslan @elcsiga Could you please re-review when you have time? |
Reviewing... |
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 @sardell! I have reviewed this PR and it is looking good. There are still several things to get dialed in but all in all this is headed in the right direction. Please let me know if you have any questions or comments or if you need any clarity on my latest set of comments.
nifi-frontend/src/main/frontend/apps/nifi-registry/src/app/ui/header/header.component.scss
Outdated
Show resolved
Hide resolved
...ifi-registry/src/app/ui/header/common/context-error-banner/context-error-banner.component.ts
Outdated
Show resolved
Hide resolved
...orer/feature/ui/import-new-flow-version-dialog/import-new-flow-version-dialog.component.html
Outdated
Show resolved
Hide resolved
}); | ||
} | ||
|
||
getDropletSnapshotMetadata(dropletUri: string): Observable<any> { |
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.
Can we do better than Observable<any>
here? It would be better if we had some types defined.
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 can manually type out all of these response interfaces in this PR, but we use Observable<any>
for most of the http response types in NiFi. I think if we want to have stronger typing for our API responses it would be much better to leverage a package that generates Typescript interfaces from backend schemas. Not only would it save us a ton of time doing manual work but we also get the big advantage of ensuring the contract between the frontend and the backend isn't broken at build time.
}); | ||
} | ||
|
||
exportDropletVersionedSnapshot(dropletUri: string, versionNumber: number): Observable<any> { |
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.
Can we do better than Observable<any>
here? It would be better if we had some types defined.
.../app/pages/expolorer/feature/ui/import-new-flow-dialog/import-new-flow-dialog.component.html
Outdated
Show resolved
Hide resolved
...src/main/frontend/apps/nifi-registry/src/app/pages/expolorer/feature/explorer.component.html
Outdated
Show resolved
Hide resolved
this.store | ||
.select(selectQueryParams) | ||
.pipe(takeUntilDestroyed()) | ||
.subscribe((queryParams) => { | ||
if (queryParams) { | ||
this.filterTerm = queryParams['filterTerm'] || ''; | ||
this.filterBucket = queryParams['filterBucket'] || 'All'; | ||
this.filterColumn = queryParams['filterColumn'] || ''; | ||
this.dataSource.filter = JSON.stringify(queryParams); | ||
} | ||
}); | ||
} |
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 have a few thoughts here:
First, no other listing in nifi preserves the filters, sortings, etc via query params. I see a few issues currently with having these query params with back/forward navigation and row selection while keeping the query params in sync. Also the handling of erroneous values for query params, handling erroneous query params, etc. seems to be missing.
Secondly, the routes in this new NiFi registry application explorer view do not behave the same way as the legacy UI and I think we need to honor the existing routes. Users from the existing NiFi Registry may have bookmarks etc and expect those to work and since NiFi Registry is part of the NiFi release I don't think we want to have breaking changes like this in a minor release. It is kind of like an api.
Both of these thoughts lead me to request that you remove the query params from the url for filtering, sorting, etc. Just let the user land at the explorer perspective and let them apply a filter, sort, etc. Instead we can use deep links like the legacy UI.
Now, if we look at the routes from legacy NiFi Registry legacy UI then /explorer/grid-list
takes the user to the listing of all resources. explorer/grid-list/buckets/<bucket-id>
takes the user to the listing of all resources in . And explorer/grid-list/buckets/<bucket-id>/flows/<resource-id>
takes the user to a single resource in the listing.
I think for this effort we can support the same routes and deep links. /explorer/grid-list
would route to the explorer.component and would take the user to the listing of all resources. explorer/grid-list/buckets/<bucket-id>
would also route to the explorer.component but would set the formcontrolname="filterBucket"
to the bucket-id which would then show only the resources in that bucket in the listing. Then for explorer/grid-list/buckets/<bucket-id>/flows/<resource-id>
it would also route to the explorer.component, set the formcontrolname="filterBucket"
to the bucket-id which would then show only the resources in that bucket in the listing, and would select the in the listing.
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.
Secondly, the routes in this new NiFi registry application explorer view do not behave the same way as the legacy UI and I think we need to honor the existing routes. Users from the existing NiFi Registry may have bookmarks etc and expect those to work and since NiFi Registry is part of the NiFi release I don't think we want to have breaking changes like this in a minor release. It is kind of like an api.
Couldn't we just add a redirect to handle legacy urls instead of locking into a convention that IMO is not very intuitive? Additionally, is the expectation really to have no breaking changes whatsoever when rewriting an entire UI? Why wouldn't we just follow semantic versioning if there are breaking changes?
I think most people would agree that nifi-registry/#/resources/<resource-id>
is much simpler and easier to understand than nifi-registry/resources/grid-list/buckets/<bucket-id>/flows/<resource-id>
. I think path parameters make sense when viewing a specific resource, but it's pretty common convention to use query parameters to handle the persistence of filter values selected on a page.
I'm fine not persisting filter values since we don't persist them in NiFi, but if we do want to support that in the url I don't think the deep linking you're proposing is the way we should it. Long urls like that make sense on the canvas, where it's a drill-down view of nested components without a filter, but we aren't doing that in list views. For example, when you look at the summary of a processor in NiFi, the url is nifi/#/summary/processors
and not nifi/#/summary/process-groups/<process-group-id>/processors
.
nifi-frontend/src/main/frontend/apps/nifi-registry/src/app/ui/header/header.component.ts
Outdated
Show resolved
Hide resolved
export const fullScreenError = createAction( | ||
'[Error] Full Screen Error', | ||
props<{ errorDetail: ErrorDetail; skipReplaceUrl?: boolean }>() | ||
); | ||
|
||
export const snackBarError = createAction('[Error] Snackbar Error', props<{ error: string }>()); | ||
|
||
export const addBannerError = createAction('[Error] Add Banner Error', props<{ errorContext: ErrorContext }>()); | ||
|
||
export const clearBannerErrors = createAction('[Error] Clear Banner Errors', props<{ context: ErrorContextKey }>()); | ||
|
||
export const resetErrorState = createAction('[Error] Reset Error State'); | ||
|
||
export const setRoutedToFullScreenError = createAction( | ||
'[Error] Set Routed To Full Screen Error', | ||
props<{ routedToFullScreenError: boolean }>() | ||
); |
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.
Are you really using all of these actions in this PR? If not, let's delete the ones we aren't using and we can bring them back when we need them for the next feature we work.
@sardell also please run |
<div class="pb-5 px-5 flex flex-col h-full"> | ||
<div class="h-full flex flex-col"> | ||
<h3 class="primary-color">Flows</h3> | ||
<div class="flex justify-between items-baseline"> |
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 likely also need a context banner above the table here. If the resources fail to load we need a place to inform the user. This should also have a unique context.
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 might be misunderstanding, but aren't context banners intended for dialogs? I currently show an error page if the main resources don't load.
</div> | ||
</div> | ||
@if (droplets$ | async; as droplets) { | ||
<droplet-table |
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.
How does the user know if the registry is empty versus a filter is applied and no resources are in the listing because they do not match the filter?
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 originally had a different message explaining the difference, but you didn't think it was needed because of the filtered count (which I still agree with).
* check if window.matchMedia has value before calling method * add empty states to explorer table * destroy direct store subscriptions * add filtered count to droplet table filter
* Linux solution: https://github.com/evanw/esbuild/issues/1819\#issuecomment-2426254293 * Windows solution: nrwl/nx#29551
* fix error service
* fix multiple namings * template cleanup * configuration changes to align better with NiFi * style fixes
* use px units instead of calc for logo container * use unique contexts for dialog errors * update explorer page title * margin and sizing class updates * run prettier to fix formatting issues
@sardell I hope to get back to reviewing this next week. Sorry for the delay! |
Summary
NIFI-14319
Description
This PR establishes the initial project setup for the new NiFi Registry UI and includes the new explorer view.
Testing
Build and start the old registry project with maven using the existing instructions. Next, run
npm ci
atnifi-frontend/src/main/frontend
and start the app by runningnpx nx run nifi-registry:serve
. Visithttp://localhost:4204/nifi-registry/
to see the new explorer page. Compare the old explorer view with the new one, ensuring feature parity between the two views. Run unit tests withnpx nx run nifi-registry:test
.NOTE: buckets cannot be created through the new UI yet, so in order to test the functionality of the new explorer view you must first create a bucket through the old UI.
Considerations
Styling - The old logo was created with a much darker background color in mind. It may be time for a refreshed logo, but for now I simply added the old one to the header along with a heading containing the application's name.
Tracking
Please complete the following tracking steps prior to pull request creation.
Issue Tracking
Pull Request Tracking
NIFI-00000
NIFI-00000
Pull Request Formatting
main
branchVerification
Please indicate the verification steps performed prior to pull request creation.
Build
mvn clean install -P contrib-check
Licensing
LICENSE
andNOTICE
filesDocumentation