Skip to content

Commit 591653b

Browse files
authored
Implement Row Action Resolvers concept (#116)
1 parent ca11b21 commit 591653b

File tree

3 files changed

+67
-20
lines changed

3 files changed

+67
-20
lines changed

src/ng-generate/components/shared/generators/language/index.ts

+21-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,25 @@ function getBlockTransCustomColumns(): string {
103103
}
104104

105105
function getBlockTransRowActions(): string {
106-
const customRowActions = sharedOptions.customRowActions
106+
if (!sharedOptions.customRowActions || sharedOptions.customRowActions.length === 0) {
107+
return '';
108+
}
109+
110+
const actions: string[] = sharedOptions.customRowActions
111+
.map((action: string) => action.replace(/\.[^/.]+$/, '').replace(/\s+/g, '-').toLowerCase());
112+
113+
const actionTitles = actions.map(action => `"${action}.customRowAction": "${action}"`).join(', ');
114+
const actionNotAvailableTitles = actions.map(action => `"${action}.notAvailable": ""`).join(', ');
115+
116+
return `
117+
${actionTitles},
118+
"customRowAction": {
119+
${actionNotAvailableTitles}
120+
},
121+
`;
122+
123+
124+
/*const customRowActions = sharedOptions.customRowActions
107125
?.map((cr: string, i: number, arr: string[]) => {
108126
const crReplaced = cr
109127
.replace(/\.[^/.]+$/, '')
@@ -113,7 +131,7 @@ function getBlockTransRowActions(): string {
113131
})
114132
.join(', ');
115133
116-
return customRowActions?.length > 0 ? `${customRowActions},` : '';
134+
return customRowActions?.length > 0 ? `${customRowActions},` : '';*/
117135
}
118136

119137
function getBlockCustomCommandBarActions(): string {
@@ -126,7 +144,7 @@ function getBlockCustomCommandBarActions(): string {
126144

127145
const actions = sharedOptions.customCommandBarActions.map(transformActionName);
128146

129-
const actionStrings = actions.map((action: string, index: number) => `"${action}.customCommandBarAction": "${action}"`);
147+
const actionStrings = actions.map((action: string) => `"${action}.customCommandBarAction": "${action}"`);
130148

131149
return actionStrings.length > 0 ? `${actionStrings},` : '';
132150
}

src/ng-generate/components/shared/utils.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -195,21 +195,24 @@ export function getCustomRowActions(options: any): string {
195195
const formattedAction = action.replace(/\.[^/.]+$/, '');
196196
const formattedActionKebab = formattedAction.replace(/\s+/g, '-').toLowerCase();
197197
const classifiedAction = classify(formattedActionKebab);
198-
const commonParts = `style="cursor: pointer;" matTooltip="{{ '${options.templateHelper.getVersionedAccessPrefix(
199-
options,
200-
)}${formattedActionKebab}.customRowAction' | transloco }}" aria-hidden="false" attr.aria-label="{{ '${options.templateHelper.getVersionedAccessPrefix(
201-
options,
202-
)}${formattedActionKebab}.customRowAction' | transloco }}"`;
198+
const versionPrefix = options.templateHelper.getVersionedAccessPrefix(options);
199+
const rowActionTextKey = `${versionPrefix}${formattedActionKebab}.customRowAction`;
200+
const commonParts = `style="cursor: pointer;" matTooltip="{{ '${rowActionTextKey}' | transloco }}" aria-hidden="false" attr.aria-label="{{ '${rowActionTextKey}' | transloco }}"`;
203201
const iconTemplate =
204202
action.lastIndexOf('.') === -1
205203
? `<mat-icon data-test="custom-action-icon" ${commonParts} class="material-icons">${formattedAction}</mat-icon>`
206204
: `<mat-icon data-test="custom-action-icon" svgIcon="${formattedAction}" ${commonParts}></mat-icon>`;
207205
return `
208-
<button mat-menu-item *ngIf="is${classifiedAction}Visible" data-test="custom-action-button" (click)="executeCustomAction($event, '${formattedActionKebab}', row)">
206+
<button
207+
*ngIf="is${classifiedAction}Visible"
208+
[disabled]="!isAvailableRowAction('${formattedActionKebab}', row)"
209+
[matTooltipDisabled]="isAvailableRowAction('${formattedActionKebab}', row)"
210+
[matTooltip]="'${versionPrefix}customRowAction.${formattedActionKebab}.notAvailable' | transloco"
211+
(click)="executeCustomAction($event, '${formattedActionKebab}', row)"
212+
mat-menu-item
213+
data-test="custom-action-button">
209214
${iconTemplate}
210-
<span data-test="custom-action-text" style="vertical-align: middle">{{ '${options.templateHelper.getVersionedAccessPrefix(
211-
options,
212-
)}${formattedActionKebab}.customRowAction' | transloco}}</span>
215+
<span data-test="custom-action-text" style="vertical-align: middle">{{ '${rowActionTextKey}' | transloco}}</span>
213216
</button>
214217
`;
215218
})

src/ng-generate/components/table/generators/components/table/files/__name@dasherize__.component.ts.template

+34-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<%
33
var tableColumnsEnumName = classify(name) + 'Column';
44
var cmpFileName = dasherize(name);
5+
var hasCustomRowActions = options.customRowActions.length > 0;
6+
var customRowActionNames = options.customRowActions.map(action => `'${action.replace(/\.[^/.]+$/, '')}'`);
57
%>
68
import {
79
AfterViewInit,
@@ -96,17 +98,23 @@ export enum <%= tableColumnsEnumName %> {
9698
<% if (options.addRowCheckboxes) { %>CHECKBOX = 'checkboxes',<% } %>
9799
<%= enumPropertyDefinitions %>
98100
<%= enumCustomColumns %>
99-
<% if (options.customRowActions.length > 0) { %>CUSTOM_ROW_ACTIONS = 'customRowActions',<% } %>
101+
<% if (hasCustomRowActions) { %>CUSTOM_ROW_ACTIONS = 'customRowActions',<% } %>
100102
COLUMNS_MENU = 'columnsMenu'
101103
}
102104

103105
export const NON_DATA_COLUMNS: <%= tableColumnsEnumName %>[] = [
104-
<% if (options.customRowActions.length > 0) { %>
106+
<% if (hasCustomRowActions) { %>
105107
<%= tableColumnsEnumName %>.CUSTOM_ROW_ACTIONS,
106108
<% } %>
107109
<%= tableColumnsEnumName %>.COLUMNS_MENU
108110
];
109111

112+
<% if (hasCustomRowActions) { %>
113+
type RowAction = <%= customRowActionNames.join(' | ') %>;
114+
export type <%= options.aspectModelTypeName %>ActionsResolvers = Partial<Record<RowAction, (rowData: <%= options.aspectModelTypeName %>) => boolean>> | undefined;
115+
<% } %>
116+
117+
110118

111119
@Component({
112120
selector: '<%= options.selector %>',
@@ -160,6 +168,10 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
160168
@Input() maxExportRows: number = 0;
161169
<% } %>
162170

171+
<% if (hasCustomRowActions) { %>
172+
@Input() actionResolvers: <%= options.aspectModelTypeName %>ActionsResolvers = {};
173+
<% } %>
174+
163175
@Output() rowClickEvent = new EventEmitter<any>();
164176
@Output() rowDblClickEvent = new EventEmitter<any>();
165177
@Output() rowRightClickEvent = new EventEmitter<any>();
@@ -169,7 +181,7 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
169181
@Output() downloadEvent = new EventEmitter<{error: boolean, success: boolean, inProgress: boolean}>();
170182
@Output() rowSelectionEvent = new EventEmitter<any>();
171183

172-
<% if (options.customRowActions.length > 0) { %>
184+
<% if (hasCustomRowActions) { %>
173185
@Output() customActionEvent = new EventEmitter<any>();
174186
<% } %>
175187
<% if (options.customCommandBarActions.length > 0) { %>
@@ -383,9 +395,15 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
383395
this.rowRightClickEvent.emit({ data: row, mousePosition: mousePositionOnClick });
384396
}
385397

386-
if ($event.type === 'click') {
387-
this.rowClickEvent.emit({ data: row })
388-
}
398+
<% if (hasCustomRowActions) { %>
399+
if ($event.type === 'click' && this.isAvailableRowAction('forward-right', row)) {
400+
this.rowClickEvent.emit({ data: row })
401+
}
402+
<% } else {%>
403+
if ($event.type === 'click') {
404+
this.rowClickEvent.emit({ data: row })
405+
}
406+
<% }%>
389407

390408
return false;
391409
}
@@ -438,7 +456,7 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
438456
<% } %>
439457
<% } %>
440458

441-
<% if (options.customRowActions.length > 0) { %>
459+
<% if (hasCustomRowActions) { %>
442460
executeCustomAction($event: MouseEvent, action: string, row:any): void{
443461
if(this.customRowActionsLength <= this.visibleRowActionsIcons) {
444462
$event.stopPropagation();
@@ -635,7 +653,7 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
635653

636654
displayedColumnsTmp.push(...columns);
637655

638-
<% if (options.customRowActions.length > 0) { %>
656+
<% if (hasCustomRowActions) { %>
639657
displayedColumnsTmp.push({name: <%= tableColumnsEnumName %>['CUSTOM_ROW_ACTIONS'], selected: true});
640658
<% } %>
641659

@@ -657,6 +675,14 @@ export class <%= classify(name) %>Component implements OnInit, AfterViewInit, Af
657675
}
658676
<% } %>
659677

678+
protected isAvailableRowAction(action: RowAction, rowData: <%= options.aspectModelTypeName %>): boolean {
679+
if (!this.actionResolvers || !this.actionResolvers[action]) {
680+
return true;
681+
}
682+
683+
return this.actionResolvers[action](rowData) ?? true;
684+
}
685+
660686
<% if (options.hasSearchBar) { %>
661687
private initializeHighlightConfig(): void {
662688
const configStorage = this.storageService.getItem(this.<%= options.localStorageKeyConfig %>);

0 commit comments

Comments
 (0)