Skip to content
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

UserBox Layout Customization #57

Open
fabioformosa opened this issue Mar 17, 2018 · 6 comments
Open

UserBox Layout Customization #57

fabioformosa opened this issue Mar 17, 2018 · 6 comments

Comments

@fabioformosa
Copy link

It needs to allow the customization of userBox.

Before to work to this issue, has someone done something about?
Here @catull spoke about a hack...

@catull
Copy link
Contributor

catull commented Mar 17, 2018

Here's the hack.

I only want the UserBox' HTML template to be

<div class='user-body'>
  {{ currentUser.email }}
</div>

To achieve this, I had to go really deep into Angular internals.

First, you have to add a very invasive piece of code to main.ts.
You have to override the so called DirectResolver class used in Angular.

Second, you have to provide a customised DirectiveResolver, which when loading all components, modifies the HTML template of the component, whose selector is.userBox.
This is all done in custom-directive.resolver.ts, see below.

main.ts now becomes like this:

import { enableProdMode } from '@angular/core';
import { DirectiveResolver, CompileReflector } from '@angular/compiler';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { CustomDirectiveResolver } from './custom-directive.resolver';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(
  AppModule, {
    providers: [
      {
        provide: DirectiveResolver,
        useClass: CustomDirectiveResolver,
        deps: [
          CompileReflector
        ]
      },
    ]
  })
  .then(ref => {
    // Ensure Angular destroys itself on hot reloads.
    if (window['ngRef']) {
      window['ngRef'].destroy();
    }

    window['ngRef'] = ref;

    // Otherise, log the boot error
  })
  .catch(err => console.error(err));

Finally custom-directive.resolver.ts, only replaces HTML code; it could also modify CSS configuration.
Luckily, by this point, each component's template attribute contains the content of the file pointed to by templateUrl.

This is its content for my purposes:

import { Directive, Type, Component } from '@angular/core';
import { DirectiveResolver } from '@angular/compiler';

// import { environment } from '../environments/environment';

export class CustomDirectiveResolver extends DirectiveResolver {

  resolve (type: Type<any>, throwIfNotFound?: boolean): Directive {
    const view: Component = super.resolve(type, throwIfNotFound);

    if (!view) {
      return view;
    }

    // use this to inspect all components, it is quite interesting
    // console.log(JSON.stringify(view));

    if (view.selector === '.userBox') {
      view.template = `
        <div class='user-body'>
          {{ currentUser.email }}
        </div>
        `;
      view.templateUrl = null;
    }

    return view;
  }
}

I wish there was a much simpler way.

@fabioformosa
Copy link
Author

fabioformosa commented Mar 17, 2018

A very clever solution, thank you to have shared.
You achieved your goal without to touch the library, but I think:

  • if, in the next versions, the selector of userBox changes this hack fails
  • ngx-admin-lte can't have in the userBox the hard-coded string 'web developer', the registration date in timestamp or a series of button (follower, etc) unhandled and not customizable.

@TwanoO67 it's better a structural change to ngx-admin-lte, isn't?
What about a new attribute in app-header to pass the userBox template?

@catull
Copy link
Contributor

catull commented Mar 18, 2018

This would be the proper way.

  1. All components have a simple, standard Angular selector, not CSS style selector.
  2. The components HTML template is simply containing this
<ng-content></ng-content>
  1. You can now have your own HTML content. No more fix content you cannot change.

The fundamental problem with ngx-admin-lte is that it mixes many things into one.

A. It wants to be an Angular Library for AminLTE, offering natural Angular Components, Services, Pipes etc.
This is what I call "core library".

B. It also wants to showcase AdminLTE, so as the beginner developer gets something up quickly.
This is what I call "Demo" use case.

C. It does want to keep compatibility to very old APIs, such as before Angular 4.
It also includes keeping the TypeScript language level way too low.
This is what I call legacy.

It is high time the list gets reconsidered.

My plan is to concentrate on A and defining a lower boundary for Angular, addressing C.
My preference is Angular 4+.

B is best addressed in a separate project, say ngx-admin-lte-demo or ngx-admin-lte-showcase or Bootstrapping Ngx-Admin-Lte.

@TwanoO67
Copy link
Owner

TwanoO67 commented Mar 19, 2018

ngx-admin-lte can't have in the userBox the hard-coded string 'web developer', the registration date in timestamp or a series of button (follower, etc) unhandled and not customizable.
@TwanoO67 it's better a structural change to ngx-admin-lte, isn't?

I totally agree! Hard coded string shouldn't be in here (or at least in the translation files), and all parts of the app should be customisable.

What about a new attribute in app-header to pass the userBox template?

I would rather set a service for that, in the same way that menu, or control-sidebar works

I also agree with @catull, ngx-admin-lte have to stick to purpose A.
Purpose B is adressed by https://github.com/TwanoO67/bootstraping-ngx-admin-lte, so we could move part of the project to that one.

I also agree with stopping backward compatibility to Angular4 level for this package version >2

@catull
Copy link
Contributor

catull commented Mar 19, 2018

@TwanoO67 Then please, in the README.md state that this project is for "Angular 4+", drop "2".

@MihaiHoriaPopescu
Copy link
Contributor

@TwanoO67 Is the UserBox Layout Customization change in plan? Or for now is better to use the hack @catull shared?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants