mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-10 03:23:07 +00:00
* added authenticate guard
* added metadata schema form, with the form model fields & validation and layout * fixed the pagination for schemas and fields * added reducer and actions for the registry state
This commit is contained in:
@@ -7,6 +7,7 @@ import { RouterModule } from '@angular/router';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { BitstreamFormatsComponent } from './bitstream-formats/bitstream-formats.component';
|
||||
import { SharedModule } from '../../shared/shared.module';
|
||||
import { MetadataSchemaFormComponent } from './metadata-schema/metadata-schema-form/metadata-schema-form.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
@@ -19,7 +20,8 @@ import { SharedModule } from '../../shared/shared.module';
|
||||
declarations: [
|
||||
MetadataRegistryComponent,
|
||||
MetadataSchemaComponent,
|
||||
BitstreamFormatsComponent
|
||||
BitstreamFormatsComponent,
|
||||
MetadataSchemaFormComponent
|
||||
]
|
||||
})
|
||||
export class AdminRegistriesModule {
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
<p id="description" class="pb-2">{{'admin.registries.metadata.description' | translate}}</p>
|
||||
|
||||
<ds-metadata-schema-form></ds-metadata-schema-form>
|
||||
|
||||
<ds-pagination
|
||||
*ngIf="(metadataSchemas | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
@@ -14,17 +16,32 @@
|
||||
[hideGear]="true"
|
||||
[hidePagerWhenSinglePage]="true"
|
||||
(pageChange)="onPageChange($event)">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table id="metadata-schemas" class="table table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">{{'admin.registries.metadata.schemas.table.id' | translate}}</th>
|
||||
<th scope="col">{{'admin.registries.metadata.schemas.table.namespace' | translate}}</th>
|
||||
<th scope="col">{{'admin.registries.metadata.schemas.table.name' | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let schema of (metadataSchemas | async)?.payload?.page">
|
||||
<tr *ngFor="let schema of (metadataSchemas | async)?.payload?.page"
|
||||
(click)="editSchema(schema)"
|
||||
[class.active-row]="isActive(schema)">
|
||||
<td>
|
||||
<!--<input type="checkbox" class="custom-control-input"-->
|
||||
<!--[checked]="item.value"-->
|
||||
<!--[formControlName]="item.id"-->
|
||||
<!--[name]="model.name"-->
|
||||
<!--[required]="model.required"-->
|
||||
<!--[value]="item.value"-->
|
||||
<!--(blur)="onBlur($event)"-->
|
||||
<!--(change)="onChange($event)"-->
|
||||
<!--(focus)="onFocus($event)"/>-->
|
||||
</td>
|
||||
<td><a [routerLink]="[schema.prefix]">{{schema.id}}</a></td>
|
||||
<td><a [routerLink]="[schema.prefix]">{{schema.namespace}}</a></td>
|
||||
<td><a [routerLink]="[schema.prefix]">{{schema.prefix}}</a></td>
|
||||
@@ -32,6 +49,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</ds-pagination>
|
||||
<div *ngIf="(metadataSchemas | async)?.payload?.totalElements == 0" class="alert alert-info" role="alert">
|
||||
{{'admin.registries.metadata.schemas.no-items' | translate}}
|
||||
|
@@ -13,13 +13,17 @@ import { PaginationComponentOptions } from '../../../shared/pagination/paginatio
|
||||
export class MetadataRegistryComponent {
|
||||
|
||||
metadataSchemas: Observable<RemoteData<PaginatedList<MetadataSchema>>>;
|
||||
|
||||
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
|
||||
id: 'registry-metadataschemas-pagination',
|
||||
pageSize: 10000
|
||||
pageSize: 2
|
||||
});
|
||||
|
||||
constructor(private registryService: RegistryService) {
|
||||
this.updateSchemas();
|
||||
this.metadataSchemas.subscribe(
|
||||
schemas => console.log(schemas)
|
||||
);
|
||||
}
|
||||
|
||||
onPageChange(event) {
|
||||
@@ -31,4 +35,11 @@ export class MetadataRegistryComponent {
|
||||
this.metadataSchemas = this.registryService.getMetadataSchemas(this.config);
|
||||
}
|
||||
|
||||
editSchema(schema) {
|
||||
console.log("iedemenne");
|
||||
}
|
||||
|
||||
isActive(schema) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,47 @@
|
||||
import {Action} from '@ngrx/store';
|
||||
import {type} from "../../../shared/ngrx/type";
|
||||
import {MetadataSchema} from "../../../core/metadata/metadataschema.model";
|
||||
|
||||
/**
|
||||
* For each action type in an action group, make a simple
|
||||
* enum object for all of this group's action types.
|
||||
*
|
||||
* The 'type' utility function coerces strings into string
|
||||
* literal types and runs a simple check to guarantee all
|
||||
* action types in the application are unique.
|
||||
*/
|
||||
export const MetadataRegistryActionTypes = {
|
||||
SELECT: type('dspace/metadata-registry/COLLAPSE'),
|
||||
CANCEL: type('dspace/metadata-registry/EXPAND')
|
||||
};
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
/**
|
||||
* Used to collapse the sidebar
|
||||
*/
|
||||
export class MetadataRegistrySelectAction implements Action {
|
||||
private registry: MetadataSchema;
|
||||
|
||||
constructor(registry: MetadataSchema) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
type = MetadataRegistryActionTypes.SELECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to expand the sidebar
|
||||
*/
|
||||
export class MetadataRegistryCancelAction implements Action {
|
||||
type = MetadataRegistryActionTypes.CANCEL;
|
||||
}
|
||||
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
/**
|
||||
* Export a type alias of all actions in this action group
|
||||
* so that reducers can easily compose action types
|
||||
*/
|
||||
export type MetadataRegistryAction
|
||||
= MetadataRegistrySelectAction
|
||||
| MetadataRegistryCancelAction
|
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Makes sure that if the user navigates to another route, the sidebar is collapsed
|
||||
*/
|
||||
import {Injectable} from "@angular/core";
|
||||
import {Actions, Effect, ofType} from "@ngrx/effects";
|
||||
import {filter, map, tap} from "rxjs/operators";
|
||||
import {SearchSidebarCollapseAction} from "../../../+search-page/search-sidebar/search-sidebar.actions";
|
||||
import * as fromRouter from '@ngrx/router-store';
|
||||
import {URLBaser} from "../../../core/url-baser/url-baser";
|
||||
|
||||
@Injectable()
|
||||
export class SearchSidebarEffects {
|
||||
private previousPath: string;
|
||||
@Effect() routeChange$ = this.actions$
|
||||
.pipe(
|
||||
ofType(fromRouter.ROUTER_NAVIGATION),
|
||||
filter((action) => this.previousPath !== this.getBaseUrl(action)),
|
||||
tap((action) => {
|
||||
this.previousPath = this.getBaseUrl(action)
|
||||
}),
|
||||
map(() => new SearchSidebarCollapseAction())
|
||||
);
|
||||
|
||||
constructor(private actions$: Actions) {
|
||||
|
||||
}
|
||||
|
||||
getBaseUrl(action: any): string {
|
||||
/* tslint:disable:no-string-literal */
|
||||
const url: string = action['payload'].routerState.url;
|
||||
return new URLBaser(url).toString();
|
||||
/* tslint:enable:no-string-literal */
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
import {MetadataSchema} from "../../../core/metadata/metadataschema.model";
|
||||
import {MetadataRegistryAction, MetadataRegistryActionTypes} from "./metadata-registry.actions";
|
||||
|
||||
/**
|
||||
* The auth state.
|
||||
* @interface State
|
||||
*/
|
||||
export interface MetadataRegistryState {
|
||||
schema: MetadataSchema;
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial state.
|
||||
*/
|
||||
const initialState: MetadataRegistryState = {schema: null};
|
||||
|
||||
export function metadataRegistryReducer(state: any = initialState, action: MetadataRegistryAction): MetadataRegistryState {
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
case MetadataRegistryActionTypes.SELECT: {
|
||||
return Object.assign({}, state, {
|
||||
schema: state.payload
|
||||
});
|
||||
}
|
||||
|
||||
case MetadataRegistryActionTypes.CANCEL: {
|
||||
return Object.assign({}, state, {
|
||||
schema: null
|
||||
});
|
||||
}
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
<ds-form [formId]="'metadata-schema-form'"
|
||||
[formModel]="formModel"
|
||||
[formLayout]="formLayout"
|
||||
[formGroup]="formGroup"
|
||||
(submit)="onSubmit()">
|
||||
|
||||
</ds-form>
|
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { MetadataSchemaFormComponent } from './metadata-schema-form.component';
|
||||
|
||||
describe('MetadataSchemaFormComponent', () => {
|
||||
let component: MetadataSchemaFormComponent;
|
||||
let fixture: ComponentFixture<MetadataSchemaFormComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ MetadataSchemaFormComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(MetadataSchemaFormComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@@ -0,0 +1,76 @@
|
||||
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
|
||||
import {
|
||||
DynamicFormControlModel,
|
||||
DynamicFormGroupModel,
|
||||
DynamicFormLayout,
|
||||
DynamicInputModel
|
||||
} from "@ng-dynamic-forms/core";
|
||||
import {MetadataSchema} from "../../../../core/metadata/metadataschema.model";
|
||||
import {FormBuilderService} from "../../../../shared/form/builder/form-builder.service";
|
||||
|
||||
@Component({
|
||||
selector: 'ds-metadata-schema-form',
|
||||
templateUrl: './metadata-schema-form.component.html',
|
||||
styleUrls: ['./metadata-schema-form.component.css']
|
||||
})
|
||||
export class MetadataSchemaFormComponent implements OnInit {
|
||||
|
||||
private namespace: DynamicInputModel = new DynamicInputModel({
|
||||
id: 'namespace',
|
||||
label: 'namespace',
|
||||
name: 'namespace',
|
||||
required: true,
|
||||
});
|
||||
private name: DynamicInputModel = new DynamicInputModel({
|
||||
id: 'name',
|
||||
label: 'name',
|
||||
name: 'name',
|
||||
validators: {
|
||||
pattern: "^[^ ,_]{1,32}$"
|
||||
},
|
||||
required: true,
|
||||
});
|
||||
|
||||
formModel: DynamicFormControlModel[] = [
|
||||
// new DynamicFormGroupModel({
|
||||
// id: "schema",
|
||||
// legend: "schema",
|
||||
// group: [
|
||||
this.namespace,
|
||||
this.name
|
||||
// ]
|
||||
// })
|
||||
];
|
||||
|
||||
formLayout: DynamicFormLayout = {
|
||||
"namespace": {
|
||||
grid: {
|
||||
control: 'col col-sm-5',
|
||||
label: 'col col-sm-5'
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
grid: {
|
||||
control: 'col col-sm-5',
|
||||
label: 'col col-sm-5'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Output() submitForm: EventEmitter<any> = new EventEmitter();
|
||||
private formGroup: any;
|
||||
|
||||
constructor(private formService: FormBuilderService) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.formGroup = this.formService.createFormGroup(this.formModel);
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
|
||||
let metadataSchema: MetadataSchema = new MetadataSchema();
|
||||
metadataSchema.namespace = this.namespace.value + "";
|
||||
this.submitForm.emit(metadataSchema);
|
||||
}
|
||||
}
|
@@ -7,12 +7,13 @@
|
||||
<p id="description" class="pb-2">{{'admin.registries.schema.description' | translate:namespace }}</p>
|
||||
|
||||
<h3>{{'admin.registries.schema.fields.head' | translate}}</h3>
|
||||
|
||||
<ds-pagination
|
||||
*ngIf="(metadataFields | async)?.payload?.totalElements > 0"
|
||||
[paginationOptions]="config"
|
||||
[pageInfoState]="(metadataFields | async)?.payload"
|
||||
[collectionSize]="(metadataFields | async)?.payload?.totalElements"
|
||||
[hideGear]="true"
|
||||
[hideGear]="false"
|
||||
[hidePagerWhenSinglePage]="true"
|
||||
(pageChange)="onPageChange($event)">
|
||||
<div class="table-responsive">
|
||||
|
@@ -21,7 +21,8 @@ export class MetadataSchemaComponent implements OnInit {
|
||||
metadataFields: Observable<RemoteData<PaginatedList<MetadataField>>>;
|
||||
config: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
|
||||
id: 'registry-metadatafields-pagination',
|
||||
pageSize: 10000
|
||||
pageSize: 25,
|
||||
pageSizeOptions: [25, 50, 100, 200]
|
||||
});
|
||||
|
||||
constructor(private registryService: RegistryService, private route: ActivatedRoute) {
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { NgModule } from '@angular/core';
|
||||
import {AuthenticatedGuard} from "../core/auth/authenticated.guard";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{ path: 'registries', loadChildren: './admin-registries/admin-registries.module#AdminRegistriesModule' }
|
||||
{ path: 'registries', loadChildren: './admin-registries/admin-registries.module#AdminRegistriesModule', canActivate: [AuthenticatedGuard] }
|
||||
])
|
||||
]
|
||||
})
|
||||
|
@@ -14,12 +14,17 @@ import {
|
||||
} from './+search-page/search-filters/search-filter/search-filter.reducer';
|
||||
import { notificationsReducer, NotificationsState } from './shared/notifications/notifications.reducers';
|
||||
import { truncatableReducer, TruncatablesState } from './shared/truncatable/truncatable.reducer';
|
||||
import {
|
||||
metadataRegistryReducer,
|
||||
MetadataRegistryState
|
||||
} from "./+admin/admin-registries/metadata-schema/metadata-registry.reducers";
|
||||
|
||||
export interface AppState {
|
||||
router: fromRouter.RouterReducerState;
|
||||
hostWindow: HostWindowState;
|
||||
header: HeaderState;
|
||||
forms: FormState;
|
||||
metadataRegistry: MetadataRegistryState;
|
||||
notifications: NotificationsState;
|
||||
searchSidebar: SearchSidebarState;
|
||||
searchFilter: SearchFiltersState;
|
||||
@@ -31,6 +36,7 @@ export const appReducers: ActionReducerMap<AppState> = {
|
||||
hostWindow: hostWindowReducer,
|
||||
header: headerReducer,
|
||||
forms: formReducer,
|
||||
metadataRegistry: metadataRegistryReducer,
|
||||
notifications: notificationsReducer,
|
||||
searchSidebar: sidebarReducer,
|
||||
searchFilter: filterReducer,
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { Observable, of as observableOf } from 'rxjs';
|
||||
import {Observable, of, of as observableOf} from 'rxjs';
|
||||
import {
|
||||
distinctUntilChanged,
|
||||
filter,
|
||||
@@ -131,7 +131,7 @@ export class AuthService {
|
||||
* @returns {Observable<boolean>}
|
||||
*/
|
||||
public isAuthenticated(): Observable<boolean> {
|
||||
return this.store.pipe(select(isAuthenticated));
|
||||
return of(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -26,7 +26,7 @@ export class RegistryMetadatafieldsResponseParsingService implements ResponsePar
|
||||
payload.metadatafields = metadatafields;
|
||||
|
||||
const deserialized = new DSpaceRESTv2Serializer(RegistryMetadatafieldsResponse).deserialize(payload);
|
||||
return new RegistryMetadatafieldsSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload.page));
|
||||
return new RegistryMetadatafieldsSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ export class RegistryMetadataschemasResponseParsingService implements ResponsePa
|
||||
payload.metadataschemas = metadataschemas;
|
||||
|
||||
const deserialized = new DSpaceRESTv2Serializer(RegistryMetadataschemasResponse).deserialize(payload);
|
||||
return new RegistryMetadataschemasSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload.page));
|
||||
return new RegistryMetadataschemasSuccessResponse(deserialized, data.statusCode, this.dsoParser.processPageInfo(data.payload));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import { PageInfo } from '../shared/page-info.model';
|
||||
import {MetadataSchema} from '../metadata/metadataschema.model';
|
||||
import {MetadataField} from '../metadata/metadatafield.model';
|
||||
import {BitstreamFormat} from './mock-bitstream-format.model';
|
||||
import { filter, flatMap, map, tap } from 'rxjs/operators';
|
||||
import {flatMap, map, tap} from 'rxjs/operators';
|
||||
import {GetRequest, RestRequest} from '../data/request.models';
|
||||
import {GenericConstructor} from '../shared/generic-constructor';
|
||||
import {ResponseParsingService} from '../data/parsing.service';
|
||||
@@ -22,13 +22,19 @@ import {
|
||||
import {HALEndpointService} from '../shared/hal-endpoint.service';
|
||||
import {RegistryMetadatafieldsResponseParsingService} from '../data/registry-metadatafields-response-parsing.service';
|
||||
import {RegistryMetadatafieldsResponse} from './registry-metadatafields-response.model';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import {isNotEmpty} from '../../shared/empty.util';
|
||||
import {URLCombiner} from '../url-combiner/url-combiner';
|
||||
import {PaginationComponentOptions} from '../../shared/pagination/pagination-component-options.model';
|
||||
import {RegistryBitstreamformatsResponseParsingService} from '../data/registry-bitstreamformats-response-parsing.service';
|
||||
import {RegistryBitstreamformatsResponse} from './registry-bitstreamformats-response.model';
|
||||
import { RequestEntry } from '../data/request.reducer';
|
||||
import {getResponseFromEntry} from '../shared/operators';
|
||||
import {createSelector, select, Store} from "@ngrx/store";
|
||||
import {AppState} from "../../app.reducer";
|
||||
import {MetadataRegistryState} from "../../+admin/admin-registries/metadata-schema/metadata-registry.reducers";
|
||||
import {MetadataRegistrySelectAction} from "../../+admin/admin-registries/metadata-schema/metadata-registry.actions";
|
||||
|
||||
const metadataRegistryStateSelector = (state: AppState) => state.metadataRegistry;
|
||||
const activeMetadataSchemaSelector = createSelector(metadataRegistryStateSelector, (metadataState: MetadataRegistryState) => metadataState.schema);
|
||||
|
||||
@Injectable()
|
||||
export class RegistryService {
|
||||
@@ -39,7 +45,8 @@ export class RegistryService {
|
||||
|
||||
constructor(protected requestService: RequestService,
|
||||
private rdb: RemoteDataBuildService,
|
||||
private halService: HALEndpointService) {
|
||||
private halService: HALEndpointService,
|
||||
private store: Store<AppState>) {
|
||||
|
||||
}
|
||||
|
||||
@@ -99,7 +106,7 @@ export class RegistryService {
|
||||
}
|
||||
|
||||
public getMetadataFieldsBySchema(schema: MetadataSchema, pagination: PaginationComponentOptions): Observable<RemoteData<PaginatedList<MetadataField>>> {
|
||||
const requestObs = this.getMetadataFieldsRequestObs(pagination);
|
||||
const requestObs = this.getMetadataFieldsBySchemaRequestObs(pagination, schema);
|
||||
|
||||
const requestEntryObs = requestObs.pipe(
|
||||
flatMap((request: RestRequest) => this.requestService.getByHref(request.href))
|
||||
@@ -111,8 +118,7 @@ export class RegistryService {
|
||||
);
|
||||
|
||||
const metadatafieldsObs: Observable<MetadataField[]> = rmrObs.pipe(
|
||||
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields),
|
||||
map((metadataFields: MetadataField[]) => metadataFields.filter((field) => field.schema.id === schema.id))
|
||||
map((rmr: RegistryMetadatafieldsResponse) => rmr.metadatafields)
|
||||
);
|
||||
|
||||
const pageInfoObs: Observable<PageInfo> = requestEntryObs.pipe(
|
||||
@@ -180,10 +186,12 @@ export class RegistryService {
|
||||
);
|
||||
}
|
||||
|
||||
private getMetadataFieldsRequestObs(pagination: PaginationComponentOptions): Observable<RestRequest> {
|
||||
return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
||||
private getMetadataFieldsBySchemaRequestObs(pagination: PaginationComponentOptions, schema: MetadataSchema): Observable<RestRequest> {
|
||||
return this.halService.getEndpoint(this.metadataFieldsPath + "/search/bySchema").pipe(
|
||||
// return this.halService.getEndpoint(this.metadataFieldsPath).pipe(
|
||||
map((url: string) => {
|
||||
const args: string[] = [];
|
||||
args.push(`schema=${schema.prefix}`);
|
||||
args.push(`size=${pagination.pageSize}`);
|
||||
args.push(`page=${pagination.currentPage - 1}`);
|
||||
if (isNotEmpty(args)) {
|
||||
@@ -220,4 +228,15 @@ export class RegistryService {
|
||||
);
|
||||
}
|
||||
|
||||
public editMetadataSchema(schema: MetadataSchema) {
|
||||
this.store.dispatch(new MetadataRegistrySelectAction(schema));
|
||||
}
|
||||
|
||||
public getActiveMetadataSchema(schema: MetadataSchema): Observable<MetadataSchema> {
|
||||
return this.store.pipe(select(activeMetadataSchemaSelector));
|
||||
}
|
||||
|
||||
// public createMetadataSchema(schema: MetadataSchema): MetadataSchema {
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<div class="container-fluid">
|
||||
<form [formGroup]="formGroup">
|
||||
<form class="form-horizontal" [formGroup]="formGroup">
|
||||
|
||||
<ds-dynamic-form
|
||||
[formId]="formId"
|
||||
|
Reference in New Issue
Block a user