Overview
The VenziaDatalinkSearchDialogService is an Angular service that manages datalink dialogs and performs operations on Alfresco nodes. It handles adding datalinks to nodes, deleting datalink rows, and updating node properties with datalink data.
Import
import { VenziaDatalinkSearchDialogService } from 'venzia-datalink';
Injectable
@Injectable({
providedIn: 'root'
})
Constructor
constructor(
private dialog: MatDialog,
private nodesApiService: NodesApiService,
private contentApi: ContentApiService
)
Angular Material dialog service
Alfresco nodes API service
Alfresco Content API service
Public Methods
openAddDatalinkDialog
Opens a dialog to add datalink entries to a node.
openAddDatalinkDialog(
node: Node,
dataLink: any,
title?: string
): Observable<NodeEntry[]>
The Alfresco node to add datalinks to
Datalink configuration object
Observable that emits selected node entries when user confirms
Example
import { Component } from '@angular/core';
import { VenziaDatalinkSearchDialogService } from 'venzia-datalink';
import { Node } from '@alfresco/js-api';
@Component({
selector: 'app-add-datalink',
template: `
<button (click)="openDialog()">Add Datalink</button>
`
})
export class AddDatalinkComponent {
node: Node;
dataLink: any;
constructor(
private datalinkDialogService: VenziaDatalinkSearchDialogService
) {}
openDialog() {
this.datalinkDialogService
.openAddDatalinkDialog(this.node, this.dataLink, 'Add Customer Data')
.subscribe(
(selections) => {
console.log('User selected:', selections);
},
(error) => {
console.error('Dialog error:', error);
}
);
}
}
updateNodeDatalinkByDialog
Opens a dialog to update datalink data for a node, then saves the selections to the node.
updateNodeDatalinkByDialog(
nodeId: string,
dataLink: any,
title?: string
): Observable<Node>
Datalink configuration object
Observable that emits the updated node
Example
import { Component, Input } from '@angular/core';
import { VenziaDatalinkSearchDialogService } from 'venzia-datalink';
@Component({
selector: 'app-manage-datalink',
template: `
<button (click)="updateDatalink()">Manage Datalinks</button>
<div *ngIf="updating">Updating...</div>
`
})
export class ManageDatalinkComponent {
@Input() nodeId: string;
@Input() dataLink: any;
updating = false;
constructor(
private datalinkDialogService: VenziaDatalinkSearchDialogService
) {}
updateDatalink() {
this.updating = true;
this.datalinkDialogService
.updateNodeDatalinkByDialog(this.nodeId, this.dataLink, 'Manage Customer Data')
.subscribe(
(updatedNode) => {
console.log('Node updated:', updatedNode);
this.updating = false;
},
(error) => {
console.error('Update failed:', error);
this.updating = false;
}
);
}
}
deleteSelectRows
Deletes selected rows from a node’s datalink data.
deleteSelectRows(
nodeId: string,
deleteRows: Array<any>,
dataLink: any
): Observable<Node>
Array of row objects to delete
Datalink configuration object
Observable that emits the updated node
Example
import { Component, Input } from '@angular/core';
import { VenziaDatalinkSearchDialogService } from 'venzia-datalink';
@Component({
selector: 'app-delete-rows',
template: `
<button
[disabled]="selectedRows.length === 0"
(click)="deleteRows()">
Delete Selected ({{ selectedRows.length }})
</button>
`
})
export class DeleteRowsComponent {
@Input() nodeId: string;
@Input() dataLink: any;
@Input() selectedRows: any[] = [];
constructor(
private datalinkDialogService: VenziaDatalinkSearchDialogService
) {}
deleteRows() {
if (this.selectedRows.length === 0) return;
this.datalinkDialogService
.deleteSelectRows(this.nodeId, this.selectedRows, this.dataLink)
.subscribe(
(updatedNode) => {
console.log('Rows deleted, node updated:', updatedNode);
this.selectedRows = [];
},
(error) => {
console.error('Delete failed:', error);
}
);
}
}
close
Closes all open dialogs.
Example
import { Component } from '@angular/core';
import { VenziaDatalinkSearchDialogService } from 'venzia-datalink';
@Component({
selector: 'app-dialog-manager',
template: `<button (click)="closeDialogs()">Close All Dialogs</button>`
})
export class DialogManagerComponent {
constructor(
private datalinkDialogService: VenziaDatalinkSearchDialogService
) {}
closeDialogs() {
this.datalinkDialogService.close();
}
}
Private Methods
getColumnPrimaryKey
Finds and returns the primary key column name from a datalink configuration.
private getColumnPrimaryKey(dataLink: any): string
parseSelectionsRows
Parses and merges selected rows with existing node datalink data.
private parseSelectionsRows(
displayNode: Node,
selectedRows: Array<any>,
dataLink: any
): Array<any>
parseRemoveRows
Parses and removes selected rows from node datalink data.
private parseRemoveRows(
displayNode: Node,
selectedRows: Array<any>,
dataLink: any
): Array<any>
openDialog
Opens a Material dialog with specified configuration.
private openDialog(
data: any,
currentPanelClass: string,
chosenWidth: string
): void
Implementation Details
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import { switchMap } from 'rxjs/operators';
import { Node, NodeEntry } from '@alfresco/js-api';
import { MatDialog } from '@angular/material/dialog';
import { NodesApiService } from '@alfresco/adf-content-services';
import { ContentApiService } from '@alfresco/aca-shared';
import { AddDatalinkDialogComponent } from '../dialogs/datalink-add-dialog/datalink-add-dialog.component';
import { AddDatalinkDialogData } from '../dialogs/datalink-add-dialog/datalink-add-data.interface';
@Injectable({
providedIn: 'root'
})
export class VenziaDatalinkSearchDialogService {
constructor(
private dialog: MatDialog,
private nodesApiService: NodesApiService,
private contentApi: ContentApiService
) {}
openAddDatalinkDialog(
node: Node,
dataLink: any,
title?: string
): Observable<NodeEntry[]> {
const confirm = new Subject<NodeEntry[]>();
confirm.subscribe({
complete: this.close.bind(this)
});
const data: AddDatalinkDialogData = {
nodeId: node.id,
dataLink: dataLink,
title: title,
confirm: confirm
};
this.openDialog(data, 'adf-add-permission-dialog', '630px');
return confirm;
}
updateNodeDatalinkByDialog(
nodeId: string,
dataLink: any,
title?: string
): Observable<Node> {
return this.contentApi.getNode(nodeId).pipe(
switchMap((node) => {
return this.openAddDatalinkDialog(node.entry, dataLink, title).pipe(
switchMap((selection) => {
const data = { properties: {} };
data.properties[dataLink.aspectPropertyName] = JSON.stringify(
this.parseSelectionsRows(node.entry, selection, dataLink)
);
return this.nodesApiService.updateNode(nodeId, data);
})
);
})
);
}
deleteSelectRows(
nodeId: string,
deleteRows: Array<any>,
dataLink: any
): Observable<Node> {
return this.contentApi.getNode(nodeId).pipe(
switchMap((node) => {
const data = { properties: {} };
data.properties[dataLink.aspectPropertyName] = JSON.stringify(
this.parseRemoveRows(node.entry, deleteRows, dataLink)
);
return this.nodesApiService.updateNode(nodeId, data);
})
);
}
close() {
this.dialog.closeAll();
}
}
Data Flow
- Add Datalinks: Opens dialog → User selects items → Merges with existing data → Updates node properties
- Delete Rows: Filters out selected rows → Updates node properties
- Primary Key Matching: Uses primary key column to prevent duplicates when adding data
Node Property Storage
Datalink data is stored in Alfresco node properties as JSON strings:
- Property name is defined in
dataLink.aspectPropertyName
- Data is stored as a JSON array of objects
- Each object represents one row with column names as keys
Dependencies
@angular/core: Angular framework
@angular/material/dialog: Material dialogs
@alfresco/js-api: Alfresco JavaScript API
@alfresco/adf-content-services: ADF content services
@alfresco/aca-shared: Alfresco Content App shared library
rxjs: Reactive programming support
See Also