Skip to content

Commit

Permalink
Merge pull request #630 from MauroDataMapper/feature/gh-580-bulkedit-…
Browse files Browse the repository at this point in the history
…path

Resizable path column in bulkeditor
  • Loading branch information
pjmonks authored Aug 1, 2022
2 parents 83a99f4 + e419a04 commit e2fd3e9
Show file tree
Hide file tree
Showing 14 changed files with 542 additions and 88 deletions.
32 changes: 27 additions & 5 deletions src/app/bulk-edit/bulk-edit-editor/bulk-edit-editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Profile, ProfileField } from '@maurodatamapper/mdm-resources';
import { ProfileField } from '@maurodatamapper/mdm-resources';
import { MessageHandlerService } from '@mdm/services';
import {
CellClassParams,
Expand All @@ -38,8 +38,10 @@ import { BulkEditProfileService } from '../bulk-edit-profile.service';
import {
MauroItem,
MauroProfileUpdatePayload,
MauroProfileValidationResult
MauroProfileValidationResult,
NavigatableProfile
} from '@mdm/mauro/mauro-item.types';
import { PathCellRendererComponent } from './cell-renderers/path-cell-renderer/path-cell-renderer.component';

@Component({
selector: 'mdm-bulk-edit-editor',
Expand All @@ -60,7 +62,8 @@ export class BulkEditEditorComponent implements OnInit {
*/
frameworkComponents = {
checkboxCellRenderer: CheckboxCellRendererComponent,
dateCellEditor: DateCellEditorComponent
dateCellEditor: DateCellEditorComponent,
pathCellRenderer: PathCellRendererComponent
};

validated: MauroProfileValidationResult[];
Expand Down Expand Up @@ -211,16 +214,35 @@ export class BulkEditEditorComponent implements OnInit {
const columnIds = this.gridColumnApi
.getAllColumns()
.map((col) => col.getColId());

this.excludeAutoResizeColumns(columnIds);
this.gridColumnApi.autoSizeColumns(columnIds);
}

private getColumnsForProfile(profile: Profile): ColGroupDef[] {
private excludeAutoResizeColumns(columnIds) {
const pathColKey = 'Path';
const pathId = this.gridColumnApi.getColumn(pathColKey).getColId();
const pathIndex = columnIds.indexOf(pathId);
if (pathIndex > -1) {
columnIds.splice(pathIndex, 1);
}
}

private getColumnsForProfile(profile: NavigatableProfile): ColGroupDef[] {
const elementGroup: ColGroupDef = {
children: [
{
headerName: 'Item',
field: 'label',
pinned: 'left'
},
{
headerName: 'Path',
field: 'path',
cellRenderer: 'pathCellRenderer',
cellRendererParams: { profile },
resizable: true,
pinned: 'left'
}
]
};
Expand Down Expand Up @@ -272,7 +294,7 @@ export class BulkEditEditorComponent implements OnInit {
return column;
}

private mapProfileToRow(profile: Profile): BulkEditDataRow {
private mapProfileToRow(profile: NavigatableProfile): BulkEditDataRow {
const data = {};
profile.sections.forEach((section) => {
section.fields.forEach((field) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!--
Copyright 2020-2022 University of Oxford
and Health and Social Care Information Centre, also known as NHS Digital
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
-->
<ng-container>
<ng-container class="path">
<span> {{ path ?? 'path not set' }} </span>
</ng-container>
</ng-container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
Copyright 2020-2022 University of Oxford
and Health and Social Care Information Centre, also known as NHS Digital
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2020-2022 University of Oxford
and Health and Social Care Information Centre, also known as NHS Digital
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
import { CatalogueItemDomainType } from '@maurodatamapper/mdm-resources';
import { NavigatableProfile } from '@mdm/mauro/mauro-item.types';
import {
ComponentHarness,
setupTestModuleForComponent
} from '@mdm/testing/testing.helpers';
import { PathCellRendererComponent } from './path-cell-renderer.component';

describe('PathCellRendererComponent', () => {
let harness: ComponentHarness<PathCellRendererComponent>;

beforeEach(async () => {
harness = await setupTestModuleForComponent(PathCellRendererComponent);
});

it('should create', () => {
expect(harness.isComponentCreated).toBeTruthy();
});

it('should process a list of breadcrumbs correctly into a string', () => {
const testProfile: NavigatableProfile = {
id: 'testUUID',
domainType: CatalogueItemDomainType.Folder,
label: 'testNavigatableProfile',
sections: [],
breadcrumbs: [
{
id: '200cfadf-8d3c-4423-acdb-77ce9b4ca7fb',
label: 'First',
domainType: CatalogueItemDomainType.DataModel,
finalised: false
},
{
id: '0b6a126d-c1dd-4e4a-bf5f-4c2d46c37df1',
label: 'Second',
domainType: CatalogueItemDomainType.DataClass
},
{
id: '13b5130e-7030-4560-b24b-38b9d4420989',
label: 'Third',
domainType: CatalogueItemDomainType.DataClass
}
]
};

harness.component.profile = testProfile;
expect(harness.component.getProfileBreadcrumbPath()).toEqual(
'First > Second > Third'
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright 2020-2022 University of Oxford
and Health and Social Care Information Centre, also known as NHS Digital
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
import { Component } from '@angular/core';
import { NavigatableProfile } from '@mdm/mauro/mauro-item.types';
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { ICellRendererParams } from 'ag-grid-community';

@Component({
selector: 'mdm-path-cell-renderer',
templateUrl: './path-cell-renderer.component.html',
styleUrls: ['./path-cell-renderer.component.scss']
})
export class PathCellRendererComponent implements ICellRendererAngularComp {
public profile: NavigatableProfile;
public path = '';

agInit(params: ICellRendererParams): void {
this.profile = this.getProfile(params);
this.path = this.getProfileBreadcrumbPath();
}

refresh(): boolean {
// Let agGrid handle refresh
return false;
}

getProfile(params: ICellRendererParams) {
return params.data.profile;
}

getProfileBreadcrumbPath() {
let builtPath = '';
const numberOfBreadcrumbs = this.profile.breadcrumbs.length;

this.profile.breadcrumbs.map((breadcrumb, i) => {
if (i < numberOfBreadcrumbs && i !== 0) {
builtPath = builtPath + ' > ';
}
builtPath = builtPath + breadcrumb.label;
});
return builtPath;
}
}
5 changes: 3 additions & 2 deletions src/app/bulk-edit/bulk-edit-profile.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import {
MauroIdentifier,
MauroItem,
MauroProfileUpdatePayload,
MauroProfileValidationResult
MauroProfileValidationResult,
NavigatableProfile
} from '@mdm/mauro/mauro-item.types';
import {
DefaultProfileProviderService,
Expand Down Expand Up @@ -77,7 +78,7 @@ export class BulkEditProfileService {
rootItem: MauroItem,
identifiers: MauroIdentifier[],
provider: ProfileProvider
): Observable<Profile[]> {
): Observable<NavigatableProfile[]> {
if (!this.isCorrectDomainType(rootItem.domainType)) {
return throwError(
new Error(`${rootItem.domainType} is not a model domain type`)
Expand Down
8 changes: 6 additions & 2 deletions src/app/bulk-edit/bulk-edit.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import {
ProfileProvider,
ProfileSummary
} from '@maurodatamapper/mdm-resources';
import { MauroIdentifier, MauroItem } from '@mdm/mauro/mauro-item.types';
import {
MauroIdentifier,
MauroItem,
NavigatableProfile
} from '@mdm/mauro/mauro-item.types';

export enum BulkEditStep {
Selection,
Expand All @@ -45,6 +49,6 @@ export interface BulkEditProfileContext {

export interface BulkEditDataRow {
label: string;
profile: Profile;
profile: NavigatableProfile;
[key: string]: any;
}
5 changes: 5 additions & 0 deletions src/app/mauro/mauro-item.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/
import {
Breadcrumb,
CatalogueItem,
MdmResponse,
Profile,
Expand Down Expand Up @@ -83,3 +84,7 @@ export interface MauroProfileValidationResult {
profile: Profile;
errors?: ProfileValidationError[];
}

export interface NavigatableProfile extends Profile {
breadcrumbs?: Breadcrumb[];
}
12 changes: 9 additions & 3 deletions src/app/mauro/profiles/default-profile-provider.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ import {
MauroItem,
MauroProfileUpdatePayload,
MauroProfileValidationResult,
MauroUpdatePayload
MauroUpdatePayload,
NavigatableProfile
} from '../mauro-item.types';
import { ProfileProviderService } from './profile-provider-service';

Expand Down Expand Up @@ -193,14 +194,19 @@ export class DefaultProfileProviderService implements ProfileProviderService {
rootItem: MauroItem,
identifiers: MauroIdentifier[],
provider: ProfileProvider
): Observable<Profile[]> {
): Observable<NavigatableProfile[]> {
if (!isDefaultProvider(provider)) {
return EMPTY;
}

return this.itemProvider
.getMany(identifiers)
.pipe(map((items) => items.map((item) => this.mapItemToProfile(item))));
.pipe(map((items) => items.map((item) => {
return {
...this.mapItemToProfile(item),
breadcrumbs: item.breadcrumbs
};
})));
}

/**
Expand Down
12 changes: 9 additions & 3 deletions src/app/mauro/profiles/mauro-profile-provider.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import {
MauroIdentifier,
MauroItem,
MauroProfileUpdatePayload,
MauroProfileValidationResult
MauroProfileValidationResult,
NavigatableProfile
} from '../mauro-item.types';
import { ProfileProviderService } from './profile-provider-service';

Expand Down Expand Up @@ -64,7 +65,7 @@ export class MauroProfileProviderService implements ProfileProviderService {
rootItem: MauroItem,
identifiers: MauroIdentifier[],
provider: ProfileProvider
): Observable<Profile[]> {
): Observable<NavigatableProfile[]> {
const payload: ProfileContextIndexPayload = {
multiFacetAwareItems: identifiers.map((identifier) => {
return {
Expand All @@ -81,7 +82,12 @@ export class MauroProfileProviderService implements ProfileProviderService {
.getMany(actualRootItem.domainType, actualRootItem.id, payload)
.pipe(
map((response: ProfileContextIndexResponse) =>
response.body.profilesProvided.map((provided) => provided.profile)
response.body.profilesProvided.map((provided) => {
return {
...provided.profile,
breadcrumbs: provided.multiFacetAwareItem?.breadcrumbs
};
})
)
);
}
Expand Down
7 changes: 4 additions & 3 deletions src/app/mauro/profiles/profile-provider-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ import {
MauroIdentifier,
MauroItem,
MauroProfileUpdatePayload,
MauroProfileValidationResult
MauroProfileValidationResult,
NavigatableProfile
} from '../mauro-item.types';

/**
Expand Down Expand Up @@ -56,14 +57,14 @@ export interface ProfileProviderService {
* @param identifiers An array of {@link MauroIdentifier} objects containing identification information.
* At least an ID and domain type is required, but some domain types based on hierarchy require further details.
* @param provider The namespace/name of the profile provider to use.
* @returns An array of {@link Profile} objects which are mapped to the requested catalogue items in an
* @returns An array of {@link NavigatableProfile} objects which are mapped to the requested catalogue items in an
* observable stream.
*/
getMany(
rootItem: MauroItem,
identifiers: MauroIdentifier[],
provider: ProfileProvider
): Observable<Profile[]>;
): Observable<NavigatableProfile[]>;

/**
* Validates multiple profiles based on the given profile provider.
Expand Down
Loading

0 comments on commit e2fd3e9

Please sign in to comment.