Activities of "sumeyye.kurtulus"

Hello, the current setup, the user View Details modal isn't directly customizable. However, you can extend the functionality by using Entity Action Extensions to add a custom tab or action that opens a separate component with the additional details you want to display.

Here's how you can approach it:

  1. Create a new Angular component that will serve as your custom tab or detail view.
  2. Use the Entity Action Extension API to register a new action (e.g., “View More Details”) for the User entity.
  3. In the action handler, open your custom component either in a modal or a separate route, depending on your UI preference.

You can refer to the official documentation for step-by-step guidance:

👉 Entity Action Extensions – Angular UI | ABP Docs

Let me know if you need further assistance.

Hello, In the Angular frontend generated by ABP Studio for a microservice-based architecture, each subproject typically corresponds to an Angular library.

These frontend "subsystems" are not standalone Angular applications by default — they are structured as libraries, meaning they are meant to be consumed by a root Angular application (the host app). This structure promotes code sharing and encapsulation across microservices.

However, it is technically possible to host each subsystem as an independent Angular application, but this requires:

  1. Creating a new Angular application shell for each library.
  2. Wiring up routing, environment configs, and bootstrapping logic manually.
  3. Ensuring each new app has access to shared services (e.g., authentication, theming, localization) if needed — which might involve refactoring common modules into shared libraries.

So, while they're not tightly coupled to the main app and can be decoupled, they’re not standalone out-of-the-box. Making them standalone would involve restructuring and setting up new applications that consume these libraries independently.

Yes, there is a temporary workaround for that. I can suggest you to override the routes component as follows until we publish the fix:

//new-routes.component.ts
import { RoutesComponent } from '@volo/abp.ng.theme.lepton';
@Component({
  selector: 'app-new-routes',
  imports: [SharedModule],
  templateUrl: './new-routes.component.html',
})
export class NewRoutesComponent extends RoutesComponent implements OnInit {
  readonly environmentService = inject(EnvironmentService);
  readonly cdRef = inject(ChangeDetectorRef);
  public _router = inject(Router);

  override ngOnInit(): void {
    const { oAuthConfig } = this.environmentService.getEnvironment() || {};
    const waitForNavigation = oAuthConfig.responseType === 'code';

    const routerEvents$ = waitForNavigation
      ? this._router.events.pipe(
          filter(event => event instanceof NavigationEnd),
          take(1)
        )
      : of(null);

    routerEvents$.subscribe(() => {
      let node = {
        parent: findRoute(this.routes, getRoutePath(this._router)),
      } as TreeNode<ABP.Route>;

      const nodes: string[] = [];
      while (node.parent) {
        node = node.parent;
        nodes.push(node.name);
      }

      let max = nodes.length + this.initialLevel;

      nodes.forEach(name => {
        this.expandedRoutes.add(name + --max);
      });

      this.cdRef.detectChanges();
    });
  }
}
//new-routes.component.html
<div class="lp-sidebar-wrapper mx-2">
  <nav role="navigation" class="lp-sidebar-navi">
    <ul>
      @for (component of contentBefore; track $index) {
      <li class="position-relative">
        <ng-container *ngComponentOutlet="component; injector: injector" />
      </li>
      } @for (route of routes$ | async; track $index) {
      <ng-container
        [ngTemplateOutlet]="isDropdown(route) ? dropdownLink : defaultLink"
        [ngTemplateOutletContext]="{ $implicit: route, level: initialLevel }"
      />
      } @for (component of contentAfter; track $index) {
      <li class="position-relative">
        <ng-container *ngComponentOutlet="component; injector: injector" />
      </li>
      }

      <ng-template #defaultLink let-route let-level="level">
        <li
          routerLinkActive="active-page current"
          [routerLinkActiveOptions]="{ exact: route.path === '/' }"
          *abpPermission="route.requiredPolicy"
          (click)="$event.stopPropagation(); onNavigate(route, level)"
        >
          <a [routerLink]="[route.path]" (click)="clickedToLink.emit()">
            <ng-container *ngTemplateOutlet="linkContent; context: { $implicit: route }" />
          </a>
        </li>
      </ng-template>

      <ng-template #linkContent let-route>
        @if (route.iconClass) {
        <span class="lp-icon">
          <i [ngClass]="route.iconClass"></i>
        </span>
        }
        <span class="lp-text">
          {{ route.name | abpLocalization }}
        </span>
      </ng-template>

      <ng-template #dropdownLink let-route let-level="level">
        @if (route.children?.length) {
        <li
          *abpPermission="route.requiredPolicy"
          class="has-drop"
          [class.current]="expandedRoutes.has(route.name + level)"
        >
          <a
            attr.data-level="{{ level }}"
            href="javascript:void(0)"
            (click)="
              $event.stopPropagation();
              isMenuPlacementTop && !smallScreen ? null : toggleExpand(route, level)
            "
          >
            <ng-container *ngTemplateOutlet="linkContent; context: { $implicit: route }" />

            <span class="lp-arrow-icon" [attr.for]="route.name">
              <i class="fa fa-chevron-down" aria-hidden="true"></i>
            </span>
          </a>
          <ul
            class="dropdown-ul"
            [ngClass]="{
                'd-block overflow-hidden': isMenuPlacementTop && !smallScreen ? false : true,
              }"
            [id]="route.name"
          >
            <div
              #routeContainer
              [@collapse]="
                !isMenuPlacementTop
                  ? expandedRoutes.has(route.name + level)
                    ? 'expanded'
                    : 'collapsed'
                  : ''
              "
            >
              @for (child of route.children; track $index) {
              <ng-container
                [ngTemplateOutlet]="dropdownMenu"
                [ngTemplateOutletContext]="{ $implicit: child, level: level + 1 }"
              />
              }
            </div>
          </ul>
        </li>
        }
      </ng-template>

      <ng-template #dropdownMenu let-route let-level="level">
        <ng-container
          *ngTemplateOutlet="
            isDropdown(route) ? dropdownLink : defaultLink;
            context: { $implicit: route, level: level }
          "
        />
      </ng-template>
    </ul>
  </nav>
</div>
//app.component.ts
import { ReplaceableComponentsService } from '@abp/ng.core';
import { eThemeLeptonComponents } from '@volo/abp.ng.theme.lepton';
@Component({
  standalone: false,
  selector: 'app-root',
  template: `
    ...
  `,
})
export class AppComponent {
  protected replaceComponent = inject(ReplaceableComponentsService);
  constructor() {
    this.replaceComponent.add({
      component: NewRoutesComponent,
      key: eThemeLeptonComponents.Routes,
    });
  }
}

Yes, you can update the frontend version to 9.1.

Please also make sure to update your Angular version to 19 by following the migration guide: https://abp.io/docs/latest/release-info/migration-guides/abp-9-1

Note that Angular now uses standalone: true by default, so you may need to explicitly set standalone: false for any components, directives, or pipes that are not standalone.

Let us know if you need any further assistance.

Hello, thank you for sharing the version details, and apologies for the delayed response.

After reviewing your setup, it looks like the issue is caused by an incorrect version of the @volosoft/abp.ng.theme.lepton-x package. Updating it to ~4.0.0 should resolve the problem.

Please give that a try and let us know if it works for you. We really appreciate your patience and cooperation—thanks again!

Thanks for providing the details. This will also be investigated and fixed in the next release.

Thank you for sharing the details. We’ve successfully reproduced the same issue on our side and confirmed that it stems from an inconsistency in the code generation process when using ABP Suite alongside proxy generation.

We’re currently working on a fix, which will be included in the upcoming release. In the meantime, I can share the updated file that resolves the issue directly with you via drive. https://drive.google.com/drive/folders/1MHQSeIa6rOw4rAcXAnq11U2XLfFYjTc5?usp=drive_link. If you replace the .suite folder under your angular app directory, you will be able to work around the issue.

We appreciate your patience and cooperation as we work to improve the experience. Let us know if you have any further questions!

Hello, this problem will be solved within the next release as we have mentioned in this answer: https://abp.io/qa/questions/9043/3a18ea20-92a2-5df8-caf1-981e1f1c0fb1

Thank you for your cooperation.

This problem occurs where this permission guard is used. That is why, some routes are affected while others are not.

Does the module need to refer to permission.guard.ts separately in the next version?

The solution I offered is a temporary one, so you will not need it once it is fixed on our side. Also, I cannot produce the sidebar problem on my end. Can you confirm that this happens after adding the new guard?

Hello, thank you for your patience, and we sincerely apologize for the delayed response. We appreciate you reporting this issue. The problem will be addressed in our upcoming release. In the meantime, you can work around it by overriding the related guard as follows:

// new-permission.guard.ts
import {
  RoutesService,
  AuthService,
  PermissionService,
  HttpErrorReporterService,
  findRoute,
  getRoutePath,
  ConfigStateService,
} from '@abp/ng.core';
import { HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import {
  CanActivateFn,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  Router,
} from '@angular/router';
import { of, switchMap, take, tap, distinctUntilChanged, filter, map } from 'rxjs';

export const newPermissionGuard: CanActivateFn = (
  route: ActivatedRouteSnapshot,
  state: RouterStateSnapshot
) => {
  const router = inject(Router);
  const routesService = inject(RoutesService);
  const authService = inject(AuthService);
  const permissionService = inject(PermissionService);
  const configState = inject(ConfigStateService);
  const httpErrorReporter = inject(HttpErrorReporterService);

  let { requiredPolicy } = route.data || {};

  if (!requiredPolicy) {
    const routeFound = findRoute(routesService, getRoutePath(router, state.url));
    requiredPolicy = routeFound?.requiredPolicy;
  }

  if (!requiredPolicy) {
    return of(true);
  }

  return configState.getAll$().pipe(
    map(config => config.auth?.grantedPolicies),
    distinctUntilChanged(),
    filter(Boolean),
    take(1),
    switchMap(() => permissionService.getGrantedPolicy$(requiredPolicy)),
    tap(access => {
      if (!access && authService.isAuthenticated) {
        httpErrorReporter.reportError({ status: 403 } as HttpErrorResponse);
      }
    })
  );
};

Inside the app-routing.module

const routes: Routes = [
...
  {
    path: 'openiddict',
    loadChildren: () =>
      import('@volo/abp.ng.openiddictpro').then(m => m.OpeniddictproModule.forLazy()),
    canActivate: [newPermissionGuard],
  },
...
];

Additionally, we will be processing a refund for your ticket. Please don't hesitate to reach out if you need any further assistance.

Showing 1 to 10 of 254 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 10, 2025, 12:38