[ 
https://issues.apache.org/jira/browse/AMBARI-26507?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

zrain updated AMBARI-26507:
---------------------------
    Attachment: image-2025-05-19-18-45-42-911.png

> MonoRepo design for reactJS admin and web
> -----------------------------------------
>
>                 Key: AMBARI-26507
>                 URL: https://issues.apache.org/jira/browse/AMBARI-26507
>             Project: Ambari
>          Issue Type: Story
>            Reporter: Nikita Pande
>            Priority: Major
>         Attachments: image-2025-05-19-18-41-01-314.png, 
> image-2025-05-19-18-45-42-911.png
>
>          Time Spent: 10m
>  Remaining Estimate: 0h
>
> With the efforts of Ambari community members and lots of contributors, Ambari 
> 3.0.0 [released|https://github.com/apache/ambari/releases/tag/release-3.0.0] 
> with a large number of new features and upgrades. In this release, there are 
> relatively few frontend updates for 
> [ambari-web|https://github.com/apache/ambari/tree/trunk/ambari-web] and 
> [admin-admin|https://github.com/apache/ambari/tree/trunk/ambari-admin/src/main/resources/ui/admin-web].
>  It is worth noting that the update of Jquery and Bootstrap in 
> [#3770|https://github.com/apache/ambari/pull/3770] brought many improvements, 
> including: cleaner and more modern syntax, and easier-to-use and more 
> controllable new components. However, it is undeniable that this update has 
> also exposed some issues:
>  # The underlying frontend framework ([emberjs|https://emberjs.com/] 
> {_}Version: v1.0.pre{_}) has not been updated, and its compatibility with the 
> new version of Jquery is poor, which can lead to unpredictable results 
> (AMBARI-26252, AMBARI-26193, AMBARI-26251). CVE vulnerabilities are also a 
> hidden danger.
>  # The Bootstrap upgrade has a significant impact on global styles, including 
> some breaking changes, and conflicts with the old [custom 
> styles|https://github.com/apache/ambari/tree/trunk/ambari-web/app/styles] 
> (AMBARI-26199, AMBARI-26250).
>  # The build tool ([brunch|https://brunch.io/] {_}Version: v1.7.20{_}) is too 
> old, and the latest version stopped maintenance in 2023. Brunch itself is not 
> suitable for large-scale web applications, lacks dependency analysis and tree 
> shaking, and its core packaging mechanism will result in very large bundle 
> files. This version also does not support proxies.
>  # There is a lack of code formatting standards. There are no prominent 
> formatting tools for [handlebars|https://handlebarsjs.com/] and there are [no 
> plans|https://github.com/prettier/prettier/issues/5340#issuecomment-641954294]
>  to support it.
>  # Frontend module building is coupled with Maven, which makes debugging 
> difficult for developers.
>  # Dependency management is missing. Multiple frontend modules are scattered 
> across modules, making it difficult to unify dependency versions and leading 
> to redundant test code.
> And so on...
> It is worth noting that this submission may be the opportunity to upgrade the 
> entire frontend technology stack. Considering the difficulty and benefits of 
> some upgrades, AMBARI-26060 and 
> [mailing|https://lists.apache.org/thread/rxfd35rnnd0sot0lc0tgftpsr7l5yq36] 
> chose to refactor the entire frontend application (including ambari-web and 
> ambari-admin) using React. As the saying goes, "A good beginning is half the 
> battle," here I provide a possible 
> [solution|https://github.com/apache/ambari/pull/3967#issuecomment-2788573351]:
> !image-2025-05-19-18-41-01-314.png!
> The frontend code for ambari-admin would move into 
> [ambari-web-next|https://www.google.com/url?sa=E&source=gmail&q=https://issues.apache.org/jira/browse/AMBARI-web-next]
>  as a package, and the React-refactored 
> [ambari-web|https://www.google.com/url?sa=E&source=gmail&q=https://issues.apache.org/jira/browse/AMBARI-web]
>  would also live there as its own package. Shared components (like buttons, 
> tables, etc.) would be handled by a ui-shared package. Meanwhile, the classic 
> [ambari-web|https://www.google.com/url?sa=E&source=gmail&q=https://issues.apache.org/jira/browse/AMBARI-web]
>  stays untouched.
> Here’s how it could look:
> {code:java}
> ...
> ├── ambari-views
> ├── ambari-web
> │   ├── api-docs
> │   ├── app
> │   └── ...
> ├── ambari-web-next
> │   ├── web
> │   ├── admin
> │   ├── ui-shared
> │   ├── utils-shared
> │   ├── package.json
> │   └── ...
> ├── ...
> └── version
> {code}
> Here’s what we’d get out of it:
>  # With pnpm workspace, we’re not just sharing components—we’d also share 
> dependencies and keep versions in sync. That’d speed up dev and builds(CI/CD) 
> time.
>  # Keeping the original ambari-web as-is means we don’t have to mess with 
> existing docs or guides (though admin might still need some tweaks). We can 
> focus on writing fresh docs for the refactored projects.
>  # Moving ambari-web would bundle in vanshuhassija’s change commits, which 
> might make tracking issues a bit trickier. This can be avoided.
> Regarding the technology stack, I offer my personal suggestions:
>  # Build tools: [vite|https://vitepress.dev/], 
> [plugin-legacy|https://www.npmjs.com/package/@vitejs/plugin-legacy]. 
> [CRA|https://www.google.com/search?q=https://create-react-app.dev/] is 
> gradually being 
> [deprecated|https://react.dev/blog/2025/02/14/sunsetting-create-react-app], 
> and vite has become a good choice for React applications, providing a modern 
> development process.
>  # Engineering tools: [prettier|https://prettier.io/], 
> [eslint|https://eslint.org/], [husky|https://typicode.github.io/husky/] 
> (force commit formatting), 
> [lint-staged|https://github.com/lint-staged/lint-staged].
>  # i18n: [i18next|https://www.i18next.com/], 
> [react-i18next|https://react.i18next.com/], 
> [i18next-browser-languagedetector|https://github.com/i18next/i18next-browser-languageDetector].
>  # Web requests: [axios|https://axios-http.com/].
>  # Utility functions: [es-toolkit|https://es-toolkit.slash.page/], 
> [react-hookz/web|https://github.com/react-hookz/web], 
> [clsx|https://github.com/lukeed/clsx].
>  # State management: [zustand|https://zustand-demo.pmnd.rs/], 
> [immer|https://immerjs.github.io/immer/].
>  # Component library: [shadcn|https://ui.shadcn.com/]
>  # Routing: [tanstack/react-router|https://github.com/tanstack/router]
>  # Testing: [vitest|https://vitest.dev/]
> Additional suggestion, regarding package.json script commands:
> {code:java}
> {
>   "scripts": {
>     "lint": "eslint --ext .ts,.tsx --ignore-path .gitignore .",
>     "fix": "eslint --fix --ext .ts,.tsx --ignore-path .gitignore .",
>     "format": "prettier --write ./**/*.{tsx,ts,scss,json,md}"
>   }
> }
> {code}
> With the cooperation of lint-staged, we can effectively control the code 
> format finally submitted to the repository:
> {code:java}
> {
>   "lint-staged": {
>     "src/**": "npm run format",
>     "src/**/*.{ts,tsx}": "npm run fix"
>   }
> }
> {code}
> In network communication with ambari-server, I noticed that request links are 
> often very long, similar to GraphQL in function, but the parameters are 
> placed in the link, which adds some difficulty to debugging. For example, the 
> following path is for querying Hosts information. I often need to concentrate 
> to know whether the query includes a certain field:
> {code:java}
> /api/v1/clusters/ckf_test/hosts?fields=Hosts/rack_info,Hosts/host_name,Hosts/maintenance_state,Hosts/public_host_name,Hosts/cpu_count,Hosts/ph_cpu_count,alerts_summary,Hosts/host_status,Hosts/host_state,Hosts/last_heartbeat_time,Hosts/ip,host_components/HostRoles/state,host_components/HostRoles/maintenance_state,host_components/HostRoles/stale_configs,host_components/HostRoles/service_name,host_components/HostRoles/display_name,host_components/HostRoles/desired_admin_state,host_components/metrics/dfs/namenode/ClusterId,host_components/metrics/dfs/FSNamesystem/HAState,Hosts/total_mem,stack_versions/HostStackVersions,stack_versions/repository_versions/RepositoryVersions/repository_version,stack_versions/repository_versions/RepositoryVersions/id,stack_versions/repository_versions/RepositoryVersions/display_name&minimal_response=true,host_components/logging&page_size=10&from=0&sortBy=Hosts/host_name.asc&_=1747645752540
> {code}
> The reason is that the query information contains fixed fields such as 
> Hosts/rack_info, Hosts/host_name, Hosts/maintenance_state. The word "Hosts" 
> is repeated here. Can we design a general structure and function to solve 
> this problem? For example:
> {code:java}
> interface FieldsObject {
>   [key: string]: Array<string | FieldsObject>
> }
> const HOST_FIELDS: Array<FieldsObject | string> = [
>   'alerts_summary',
>   {
>     Hosts: [
>       'rack_info',
>       'host_name',
>       'maintenance_state',
>       'public_host_name',
>       'cpu_count',
>       'ph_cpu_count',
>       'host_status',
>       'host_state',
>       'last_heartbeat_time',
>       'ip',
>       'total_mem',
>     ],
>     host_components: [
>       'logging',
>       {
>         HostRoles: [
>           'state',
>           'maintenance_state',
>           'stale_configs',
>           'service_name',
>           'display_name',
>           'desired_admin_state',
>         ],
>       },
>     ],
>     stack_versions: [
>       'HostStackVersions',
>       { repository_versions: [{ RepositoryVersions: ['repository_version', 
> 'id', 'display_name'] }] },
>     ],
>   },
> ]
> function flattenObjectPaths(arr: Array<string | FieldsObject> | string): 
> string {
>   if (isString(arr)) return arr
>   const pathSet: Set<string> = new Set()
>   function processItems(items: Array<string | FieldsObject>, prefix: string = 
> ''): void {
>     items.forEach((item) => {
>       if (isString(item)) {
>         const path = prefix ? `${prefix}/${item}` : item
>         pathSet.add(path)
>       } else if (isObject(item)) {
>         Object.entries(item).forEach(([key, value]) => {
>           const newPrefix = prefix ? `${prefix}/${key}` : key
>           processItems(value, newPrefix)
>         })
>       }
>     })
>   }
>   processItems(arr)
>   return Array.from(pathSet).join(',')
> }
> {code}
> I believe this would be much clearer. At the same time, we can also try to 
> encapsulate all network request logic into a new package: api-adapter:
> <img src="/Users/zrain/Downloads/api-adapter.png" style="zoom: 40%;" />
> Below is the directory structure:
> {code:java}
> ambari-web-next
> ├── web
> ├── admin
> ├── ui-shared
> ├── utils-shared
> ├── api-adapter   <=== Here
> ├── package.json
> └── ...
> {code}
> The benefit of doing this is that in web and admin, we no longer focus on the 
> specific logic of requests, but pay more attention to the business level. 
> Adjustments to ambari-server will only affect the api-adapter package. 
> Perhaps we can adapt to the golang/rust version of ambari-server in the 
> future?
> what are your thoughts or suggestions for improvement?



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@ambari.apache.org
For additional commands, e-mail: issues-h...@ambari.apache.org

Reply via email to