Proper admin panel implementation in angular

Viewed 4271

I just finished the front-end part of an application I am creating using angular 4. I am now in the process of creating an admin panel that will have a separate login page and two or three components. At first I created a new module and used the router to create some "/admin" routes. The problem is that the app component has the header which I do not need. Using *ngIf to check the current URL seems too much ghetto way for that. Is it better to simple create a second angular application for the admin pages? What's the best approach?

2 Answers

The question is quite broad but I'll try to cover the case with multiple apps.

Advantages of having multiple apps:

  • the admin app is usually heavy and user's app is usually very optimised. So splitting the code into two apps is really helpful: the client is just not loading admin modules
  • you are able to run only admin or only client app - this is really saving time when the project gets heavy enough
  • the shared modules can get different global configurations because they are bootstrapped in different apps. So this is more flexible

Downsides:

  • the initial configuration step requires some knowledge and time investment

For angular-cli you can use the following approach. Create two applications in the .angular-cli.json (see the json schema). You should have something like

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "..."
  },
  "apps": [
    {
      "name": "default",
      "root": "src",
      "outDir": "ci/dist-default",
      "assets": [...],
      "index": "index.html",
      "main": "main-default.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [...],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    },
    {
      "name": "admin",
      "root": "src",
      "outDir": "ci/dist-admin",
      "assets": [...],
      "index": "index.html",
      "main": "main-admin.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [...],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  ...
}

Create your app-admin.module.ts and app-admin.component.ts for the admin panel which is mostly copy-pasting your original modules. Then you need to create another main-admin.ts file which will import the app-admin.module.ts.

Ideally would be good to have two separate folders for app1 and app2.

That's it! Now you have two applications that can use the same codebase within one project.

Then it's time to adapt your package.json scripts:

  "scripts": {
    "ng": "ng",
    "start-admin": "ng serve --proxy-config=proxy.conf.json --app=admin --base-href=/admin/ --port=4201",
    "start-default": "ng serve --proxy-config=proxy.conf.json --app=default",
    "start": "concurrently --kill-others 'npm run start-default' 'npm run start-admin'",
    "build-admin": "ng build --app=admin --base-href=/admin/",
    "build-default": "ng build --app=default",
    "build": "concurrently 'npm run build-default' 'npm run build-admin'",
    "build-prod": "concurrently 'npm run build-default -- -prod' 'npm run build-admin -- -prod'"
  },

Some explanation:

  • app parameter uses the app name to build
  • base-href is used to locate the admin project under /admin path, see base tag. This is required because after the build you will have two different apps and they cannot be both served by the same path
  • we have two ports: 4200 and 4201 to run the apps simultaneously and use a proxy to serve /admin/ part from 4200 if you run both apps together

See proxy.conf.json:

{
  "/admin": {
    "target": "http://localhost:4201",
    "secure": false,
    "changeOrigin": true,
    "pathRewrite": {
      "^/admin": ""
    }
  },
  "...": "..."
}

In the end you have something like this

.

This requires some tricks and understanding of proxies. Also you would need to configure your live server with the same proxy settings for /admin path. However it really worth it, I use it for quite some time and cannot call it a bad solution

Just move application-nav-header into separate component.

  • application.component.html

<alert-component></alert-component> <!-- Place there what is shared between `public` and `admin` --> <router-outlet></router-outlet>

  • public.component.html

<public-nav-header-component></public-nav-header-component> <!-- NavHeader that customers can see --> <router-outlet></router-outlet>

  • admin.component.html

<admin-nav-header-component></admin-nav-header-component> <!-- AdminNavHeader --> <router-outlet></router-outlet>

  • application.routes.ts

[ {path: "/", component: PublicComponent}, {path: "/admin", component: AdminComponent} ]

  • admin.routes.ts

[ {path: "/login", component: LoginComponent}, {path: "/user-listing", component: UserListingComponent} ]

  • public.routes.ts - move your current application.routes here
Related