Esben_Dalgaard的活动

回答

I'm pretty sure our backend is mostly slowed by the many repository calls, which is just something we'll have to effectivise, but I haven't had luck implementing the Permissions solution you have.

We're running 3.3.0 EFCore, mysql, and I see no such folder as you describe. When adding them myself, I get:

Saying that the PermissionsManagementModal is missing, and that the .web part of Volo.Abp.PermissionManagement.Web.Pages.AbpPermissionManagement also is missing.

回答

We added the abp redis package, and wrote this into our appsettings.json, and it has had no discernable effect on our backend.

Changed the log in the docs file to specifically that request

回答

Here's our backend log when one of our calls are made: https://docs.google.com/document/d/1-hbP01lTpqIP3YVbyqlS7-C88OLmIwdMMzKYyGj-CQU/edit?usp=sharing

It's a call that fetches organizationUnits, but filtered for what organizations you are part of and all sub-orgs.

We do not use redis. What is it, and how could we?

回答

We have tested it with both local frontend, backend and Db and deployed local, backend and Db, an a mixture of these. There is no seperate identity server, it all runs on two web services, and one azure MySql Db. The identity and tenant module is in the same Db as all of our entities.

We are 2 weeks from having to use this is a customer oriented version, so we would really appreciate any help.

Sorry for the late response, we are hard at work on a deadline.

It is because I want a dropdown that is sorted by organization (like the one on the organizations Page), so i run it through with a recursive method, which generates a orgList, with lists of objects inside them, for easily making a dropdown.

But here's the kicker: I suddenly realized that it works when I publish the API to Azure web app service and publish the frontend by gtihub to Azure web app service. So it may very well be a problem with some local packages or somesuch that I have, which the CI on github doesn't get.

Sooo... Closed? Sort of?

Sorry for the delayed response. The holidays and all.

Yes, here is the html:

In debug it shows the data as empty though, so I can't see how the html can impact it. Also the same html has worked with the endpoint that returns all organization units + children. Is it because I have placed the endpoint in another entity? - I don't see how it should affect it though + it still works on swagger. :/

Hah ha... Now don't laugh, but it was b/c i needed to import the module directly to app.module.ts, and restart the app, not just hot-reload :)

Hi armanozak, We're sort of deep into our development, so our angular directory alone is 700 mb, and we have several customizations on our program, such as, rabbitMq, microservices, custom identity entities and over 3-4 updates from 3.0.0 to 3.3.0, so honestly, it's a bit of a sizable jungle, and although I think the problem is in our frontend, but I agree not the component, it could also be from generating entities over several versions, where your Angular architecture changed considerably (which is my chief suspecion).

I'm not sure if I can share the project easily, but I've made a ticket out of it, if it helps.

Typescript:

import { TerminalMessageStatus } from '../../shared/enums/terminal-message-status';
import { ABP, ListService, PagedResultDto, TrackByService } from '@abp/ng.core';
import { Confirmation, ConfirmationService } from '@abp/ng.theme.shared';
import { DateAdapter } from '@abp/ng.theme.shared/extensions';
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NgbDateAdapter } from '@ng-bootstrap/ng-bootstrap';
import { filter, finalize, switchMap, tap } from 'rxjs/operators';
import { TerminalCommands } from '../../store/models';
import { TerminalCommandsService } from './terminalCommands.service';
import { Observable, timer, Subscription, interval } from 'rxjs';
import { Router } from '@angular/router';

@Component({
  selector: 'app-terminalCommands',
  templateUrl: './terminalCommands.component.html',
  styleUrls: ['./terminalCommands.component.scss'],
  providers: [ListService, { provide: NgbDateAdapter, useClass: DateAdapter }],
})
export class TerminalCommandsComponent implements OnInit {
  data: PagedResultDto<TerminalCommands.TerminalCommandWithNavigationProperties> = {
    items: [],
    totalCount: 0,
  };

  filters: Partial<TerminalCommands.TerminalCommandsQueryParams> = {};

  form: FormGroup;

  isFiltersHidden = true;

  isModalBusy = false;

  isModalOpen = false;

  selected: TerminalCommands.TerminalCommandWithNavigationProperties;

  terminalMessageTypeArr = Object.keys(TerminalMessageType).filter(value => isNaN(Number(value)) === false).map(key => ({ key: key, value: TerminalMessageType[key] }));
  terminalMessageStatusArr = Object.keys(TerminalMessageStatus).filter(value => isNaN(Number(value)) === false).map(key => ({ key: key, value: TerminalMessageStatus[key] }));
  

  constructor(
    public readonly list: ListService,
    public readonly track: TrackByService,
    public readonly terminalCommandsService: TerminalCommandsService,
    private confirmation: ConfirmationService,
    private fb: FormBuilder,
    private router: Router
  ) {}

  ngOnInit() {
    const getData = (query: ABP.PageQueryParams) =>
      this.terminalCommandsService.getListByInput({
        filterText: query.filter,
        ...query,
        ...this.filters,
      });

    const setData = (response: TerminalCommands.Response) => (this.data = response);

    this.list.hookToQuery(getData).subscribe(setData);
    this.start();
  }

  start(){
    if(this.router.url == "/terminalCommands")
    {
      setTimeout(this.ngOnInit.bind(this),2000);
    }
  }

  buildForm() {
    this.form = this.fb.group({
      productInstanceId: [(this.selected.productInstance || {}).id]
      
    });
  }

  hideForm() {
    this.isModalOpen = false;
    this.form.reset();
  }

  showForm() {
    /*
    if(this.filters.productInstanceId == null){
      return;
    }*/
    this.buildForm();
    this.isModalOpen = true;
  }

  submitForm() {
    if (this.form.invalid) return;
    

    const request = this.selected.terminalCommand.id
      ? this.terminalCommandsService.updateByIdAndInput(this.form.value, this.selected.terminalCommand.id)
      : this.terminalCommandsService.createByInput(this.form.value);

    this.isModalBusy = true;

    request
      .pipe(
        finalize(() => (this.isModalBusy = false)),
        tap(() => this.hideForm()),
      )
      .subscribe(this.list.get);
  }

  create() {
    this.selected = {
    terminalCommand: {},
      productInstance: {}
    } as TerminalCommands.TerminalCommandWithNavigationProperties;
    this.showForm();
  }

  update(record: TerminalCommands.TerminalCommandWithNavigationProperties) {
    this.terminalCommandsService
      .getByIdWithNavigationProperties(record.terminalCommand.id)
      .subscribe((response: TerminalCommands.TerminalCommandWithNavigationProperties) => {
        this.selected = response;
        this.showForm();
      });
  }

  delete(record: TerminalCommands.TerminalCommandWithNavigationProperties) {
    this.confirmation.warn(
      '::DeleteConfirmationMessage',
      '::AreYouSure',
      { messageLocalizationParams: [] }
    ).pipe(
      filter(status => status === Confirmation.Status.confirm),
      switchMap(() => this.terminalCommandsService.deleteById(record.terminalCommand.id)),
    ).subscribe(this.list.get);
  }
}

There's a method that keeps refreshing the data, and a lot of html removed, but other than that, it should be standard.

[1/4] Why do we have the module "@ng-bootstrap/ng-bootstrap"...? [2/4] Initialising dependency graph... warning @volo/abp.ng.identity > @abp/ng.components > ng-zorro-antd@9.3.0: please warning @angular-devkit/build-angular > webpack-dev-server > chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies. warning @angular-devkit/build-angular > webpack-dev-server > chokidar > fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. warning @angular-devkit/build-angular > webpack > watchpack > watchpack-chokidar2 > chokidar@2.1.8: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies. warning @angular-devkit/build-angular > resolve-url-loader > rework > css > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated warning @angular-devkit/build-angular > resolve-url-loader > rework > css > source-map-resolve > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated warning @angular-devkit/build-angular > resolve-url-loader > rework > css > source-map-resolve > resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated warning @angular/cli > universal-analytics > request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 warning @angular/cli > universal-analytics > request > har-validator@5.1.5: this library is no longer supported warning protractor > webdriver-manager > request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142 warning tslint@6.1.3: TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information. [3/4] Finding dependency... [4/4] Calculating file sizes... => Found "@ng-bootstrap/ng-bootstrap@7.0.0" info Reasons this module exists

  • "@volo#abp.ng.account#@abp#ng.theme.shared" depends on it
  • Hoisted from "@volo#abp.ng.account#@abp#ng.theme.shared#@ng-bootstrap#ng-bootstrap" info Disk size without dependencies: "6.93MB" info Disk size with unique dependencies: "7MB" info Disk size with transitive dependencies: "7MB" info Number of shared dependencies: 1 Done in 19.60s.

Html:

  <div class="col-auto">
    <h1 class="content-header-title">{{ '::TerminalCommands' | abpLocalization}}</h1>
  </div>
  <div class="col-lg-auto pl-lg-0">
    <abp-breadcrumb></abp-breadcrumb>
  </div>
  <div class="col">
    <div class="text-lg-right pt-2">
      <button
        *abpPermission="'Stella.TerminalCommands.Create'"
        class="btn btn-primary btn-sm"
        type="button"
        (click)="create()"
      >
        <i class="fa fa-plus mr-1"></i>
        {{ '::NewTerminalCommand' | abpLocalization }}
      </button>
    </div>
  </div>
</div>

<div class="card">
  <div class="card-body">
    <div class="col-12 col-sm-auto">
        <div class="form-group">
            <label>
              {{ '::ProductInstance' | abpLocalization }}
            </label>
            <abp-lookup-input
              [getFn]="terminalCommandsService.productInstanceLookup"
              [ngModelOptions]="{ standalone: true }" 
              displayNameProp="stellaId"
              lookupNameProp="displayName"
              [(ngModel)]="filters.productInstanceId"
            ></abp-lookup-input>
          </div>
    </div>

    <ngx-datatable [rows]="data.items" [count]="data.totalCount" [list]="list" default>

      <ngx-datatable-column name="{{ '::IsIncoming' | abpLocalization }}" prop="terminalCommand.isIncoming">
        <ng-template let-row="row" ngx-datatable-cell-template>
          <ng-template [ngIf]="row.terminalCommand?.isIncoming" [ngIfThen]="yes" [ngIfElse]="no"></ng-template>

          <ng-template #yes>
            <div class="text-center text-success">
              <i [title]="'AbpUi::Yes' | abpLocalization" class="fa fa-check"></i>
            </div>
          </ng-template>

          <ng-template #no>
            <div class="text-center text-danger">
              <i [title]="'AbpUi::No' | abpLocalization" class="fa fa-times"></i>
            </div>
          </ng-template>
        </ng-template>
      </ngx-datatable-column>
      <ngx-datatable-column name="{{ '::Source' | abpLocalization }}" prop="terminalCommand.source">
        <ng-template let-row="row" ngx-datatable-cell-template>
          {{ '::Enum:TerminalMessageType:' + row.terminalCommand?.source | abpLocalization }}
        </ng-template>
      </ngx-datatable-column>
      <ngx-datatable-column name="{{ '::Status' | abpLocalization }}" prop="terminalCommand.status">
        <ng-template let-row="row" ngx-datatable-cell-template>
          {{ '::Enum:TerminalMessageStatus:' + row.terminalCommand?.status | abpLocalization }}
        </ng-template>
      </ngx-datatable-column>
      <ngx-datatable-column name="{{ '::ErrorMessage' | abpLocalization }}" prop="terminalCommand.errorMessage">
        <ng-template let-row="row" ngx-datatable-cell-template>
          {{ row.terminalCommand?.errorMessage }}
        </ng-template>
      </ngx-datatable-column>
      <ngx-datatable-column name="{{ '::CommandText' | abpLocalization }}" prop="terminalCommand.commandText">
        <ng-template let-row="row" ngx-datatable-cell-template>
          {{ row.terminalCommand?.commandText }}
        </ng-template>
      </ngx-datatable-column>

      <ngx-datatable-column name="{{ '::ProductInstance' | abpLocalization }}" prop="productInstance.stellaId">
        <ng-template let-row="row" ngx-datatable-cell-template>
          {{ row.productInstance?.stellaId }}
        </ng-template>
      </ngx-datatable-column>

    </ngx-datatable>
  </div>
</div>

<abp-modal [busy]="isModalBusy" [(visible)]="isModalOpen">
  <ng-template #abpHeader>
    <h3>{{ (selected?.terminalCommand.id ? 'AbpUi::Edit' : '::NewTerminalCommand') | abpLocalization }}</h3>
  </ng-template>

  <ng-template #abpBody>
    <form [formGroup]="form" (ngSubmit)="submitForm()" validateOnSubmit>
      <div class="mt-2 fade-in-top">
	  
        <div class="form-group">
          <label for="terminalCommand-source">
            {{ '::Source' | abpLocalization }}
          </label>

          <select
            id="terminalCommand-source"
            formControlName="source"
            class="custom-select form-control"
          >
            
            <option *ngFor="let x of terminalMessageTypeArr; trackBy: track.by('key')" [ngValue]="x.key">
              {{ '::Enum:TerminalMessageType:' + x.key  | abpLocalization }}
            </option>
          </select>
        </div>

        <div class="form-group">
          <label for="terminalCommand-commandText">
            {{ '::CommandText' | abpLocalization }}
          </label>

          <input
            type="text" 
            id="terminalCommand-commandText" 
            formControlName="commandText"
            class="form-control"/>
        </div>
        <div class="form-group">
          <label for="ProductInstance-StellaId">
            {{ '::ProductInstance' | abpLocalization }}
          </label>

          <abp-lookup-input
            [getFn]="terminalCommandsService.productInstanceLookup"
            [editingData]="selected.productInstance"
            displayNameProp="stellaId"
            lookupNameProp="displayName"
            formControlName="productInstanceId">
           </abp-lookup-input>
        </div>
      </div>
    </form>
  </ng-template>

  <ng-template #abpFooter>
    <button type="button" class="btn btn-secondary" #abpClose>
      {{ 'AbpUi::Cancel' | abpLocalization }}
    </button>
    
    <abp-button
      iconClass="fa fa-check"
      (click)="submitForm()"
      [disabled]="form?.invalid"
    >
      {{ 'AbpUi::Save' | abpLocalization }}
    </abp-button>
  </ng-template>
</abp-modal>

显示 20 个条目中的 1 到 10 个.
Made with ❤️ on ABP v8.2.0-preview Updated on 三月 25, 2024, 15:11