[ACS-7429] cleanup APS1 task-list before refactorings (#9650)

This commit is contained in:
Denys Vuika 2024-05-07 14:51:56 -04:00 committed by GitHub
parent e749473a32
commit 20ee286902
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 266 additions and 992 deletions

View File

@ -45,14 +45,11 @@ Note: If you need more information about how to sync your fork, see [this page](
## Code style
The code style for ADF follows the [Angular style guide](https://angular.io/guide/styleguide) plus some internal rules.
You dont have to worry too much about those rules because they are automatically checked by tslint/codelyzer/adf-rules.
If your code is not compliant with one of these rules you will see an error when you build the project along with some help on how to fix it.
The ADF-Rules are as follows:
The codebase is also checked with:
* File name component/directive cannot start with Alfresco/Activiti/adf - this rule is to help developers find files easily
* Class names cannot start with Alfresco/Activiti/adf for the same reason as above
* scss is mandatory. All the classes need to have the `adf-` prefix
- ESLint tool
- Stylelint tool
## Test guide

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -55,7 +55,6 @@ import { CloudViewerComponent } from './components/cloud/cloud-viewer.component'
import { ProcessDetailsCloudDemoComponent } from './components/cloud/process-details-cloud-demo.component';
import { StartTaskCloudDemoComponent } from './components/cloud/start-task-cloud-demo.component';
import { StartProcessCloudDemoComponent } from './components/cloud/start-process-cloud-demo.component';
import { CloudBreadcrumbsComponent } from './components/cloud/cloud-breadcrumb-component';
import { CloudFiltersDemoComponent } from './components/cloud/cloud-filters-demo.component';
import { FormCloudDemoComponent } from './components/app-layout/cloud/form-demo/cloud-form-demo.component';
import { environment } from '../environments/environment';
@ -119,7 +118,6 @@ import { FolderDirectiveModule } from './folder-directive';
ProcessDetailsCloudDemoComponent,
StartTaskCloudDemoComponent,
StartProcessCloudDemoComponent,
CloudBreadcrumbsComponent,
CloudFiltersDemoComponent,
FormCloudDemoComponent,
CustomEditorComponent,

View File

@ -1,4 +0,0 @@
<adf-toolbar>
<div class="app-crumb">{{appName + ' >'}} </div>
<div class="app-filter-crumb"> {{filterName | translate}}</div>
</adf-toolbar>

View File

@ -1,14 +0,0 @@
app-cloud-breadcrumbs {
.app-app-crumb {
opacity: 0.5;
}
.app-filter-crumb {
opacity: 0.8;
margin-left: 5px;
}
adf-toolbar {
display: flex;
}
}

View File

@ -1,43 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-cloud-breadcrumbs',
templateUrl: './cloud-breadcrumb-component.html',
styleUrls: ['./cloud-breadcrumb-component.scss'],
encapsulation: ViewEncapsulation.None
})
export class CloudBreadcrumbsComponent implements OnInit {
appName: string;
filterName: string;
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.parent.params.subscribe(params => {
this.appName = params.appName;
});
this.route.queryParams.subscribe(params => {
if (params.filterName) {
this.filterName = params.filterName;
}
});
}
}

View File

@ -3,7 +3,10 @@
<adf-sidenav-layout [sidenavMin]="70" [sidenavMax]="270" [stepOver]="780">
<adf-sidenav-layout-header>
<ng-template>
<app-cloud-breadcrumbs></app-cloud-breadcrumbs>
<div class="app-cloud-layout-toolbar">
<span>{{appName}}</span>
<span *ngIf="filterName">{{ ' > ' + (filterName | translate)}}</span>
</div>
</ng-template>
</adf-sidenav-layout-header>
<adf-sidenav-layout-navigation>

View File

@ -2,10 +2,6 @@
overflow: auto;
}
.app-cloud-layout-tab-body .mat-tab-body-wrapper {
height: 100%;
}
app-cloud-layout {
.app-cloud-layout-tab-body {
height: 100%;
@ -18,5 +14,13 @@ app-cloud-layout {
box-sizing: border-box;
display: flex;
}
& > div {
height: 100%;
}
}
.app-cloud-layout-toolbar {
display: flex;
}
}

View File

@ -26,14 +26,10 @@ import { CloudLayoutService } from './services/cloud-layout.service';
encapsulation: ViewEncapsulation.None
})
export class CloudLayoutComponent implements OnInit {
displayMenu = true;
appName: string;
filterName: string;
constructor(
private router: Router,
private route: ActivatedRoute,
private cloudLayoutService: CloudLayoutService
) { }
constructor(private router: Router, private route: ActivatedRoute, private cloudLayoutService: CloudLayoutService) {}
ngOnInit() {
let root: string = '';
@ -53,6 +49,10 @@ export class CloudLayoutComponent implements OnInit {
if (root === 'processes' && params.id) {
this.cloudLayoutService.setCurrentProcessFilterParam({ id: params.id });
}
if (params.filterName) {
this.filterName = params.filterName;
}
});
}

View File

@ -347,7 +347,6 @@
</section>
<div *ngIf="!acceptedFilesTypeShow">
<adf-upload-button
#uploadButton
[disabled]="!enableUpload"
[rootFolderId]="documentList.currentFolderId"
[multipleFiles]="multipleFileUpload"
@ -362,7 +361,6 @@
</div>
<div *ngIf="acceptedFilesTypeShow">
<adf-upload-button
#uploadButton
[disabled]="!enableUpload"
[rootFolderId]="documentList.currentFolderId"
[acceptedFilesType]="acceptedFilesType"

View File

@ -10,7 +10,7 @@
</adf-form>
</div>
<div class="app-console" #console>
<div class="app-console">
<h3>Error log:</h3>
<p *ngFor="let error of errorFields">Error {{ error.name }} {{error.validationSummary.message | translate}}</p>
</div>

View File

@ -15,8 +15,16 @@
* limitations under the License.
*/
import { Component, Inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { FormModel, FormFieldModel, FormService, FormOutcomeEvent, NotificationService, CoreAutomationService, FormRenderingService } from '@alfresco/adf-core';
import { Component, inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import {
FormModel,
FormFieldModel,
FormService,
FormOutcomeEvent,
NotificationService,
CoreAutomationService,
FormRenderingService
} from '@alfresco/adf-core';
import { ProcessFormRenderingService } from '@alfresco/adf-process-services';
import { InMemoryFormService } from '../../services/in-memory-form.service';
import { Subject } from 'rxjs';
@ -33,6 +41,10 @@ import { takeUntil } from 'rxjs/operators';
encapsulation: ViewEncapsulation.None
})
export class FormComponent implements OnInit, OnDestroy {
private formService = inject(FormService);
private notificationService = inject(NotificationService);
private automationService = inject(CoreAutomationService);
form: FormModel;
errorFields: FormFieldModel[] = [];
formConfig: string;
@ -49,25 +61,16 @@ export class FormComponent implements OnInit, OnDestroy {
private onDestroy$ = new Subject<boolean>();
constructor(@Inject(FormService) private formService: InMemoryFormService,
private notificationService: NotificationService,
private automationService: CoreAutomationService) {
}
logErrors(errorFields: FormFieldModel[]) {
this.errorFields = errorFields;
}
ngOnInit() {
this.formService.executeOutcome
.pipe(takeUntil(this.onDestroy$))
.subscribe((formOutcomeEvent: FormOutcomeEvent) => {
this.formService.executeOutcome.pipe(takeUntil(this.onDestroy$)).subscribe((formOutcomeEvent: FormOutcomeEvent) => {
formOutcomeEvent.preventDefault();
});
this.formConfig = JSON.stringify(
this.automationService.forms.getFormDefinition()
);
this.formConfig = JSON.stringify(this.automationService.forms.getFormDefinition());
this.parseForm();
}

View File

@ -1,53 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
/* eslint-disable */
import { Component, NgModule } from '@angular/core';
import { WidgetComponent } from '@alfresco/adf-core';
@Component({
selector: 'custom-editor',
template: `
<div style="color: red">Look, I'm a custom editor!</div>
`
})
export class CustomEditorComponent extends WidgetComponent {
constructor() {
super();
}
}
@Component({
selector: 'custom-stencil-01',
template: `<div style="color: green">ADF version of custom ProcessService stencil</div>`
})
export class CustomStencil01 extends WidgetComponent {
constructor() {
super();
}
}
@NgModule({
declarations: [ CustomEditorComponent, CustomStencil01 ],
exports: [ CustomEditorComponent, CustomStencil01 ]
})
export class CustomEditorsModule {
}

View File

@ -50,8 +50,7 @@
class="app-grid-item app-tasks-details"
*ngIf="!isStartTaskMode()"
data-automation-id="app-tasks-details">
<adf-task-details #activitiDetails
[debugMode]="true"
<adf-task-details
[taskId]="currentTaskId"
[showFormTitle]="true"
[fieldValidators]="fieldValidators"
@ -129,14 +128,12 @@
<adf-pagination
*ngIf="processList"
[target]="processList"
(changePageSize)="onChangePageSize($event)"
#processListPagination>
(changePageSize)="onChangePageSize($event)">
</adf-pagination>
</div>
<div class="app-grid-item app-processes-details" *ngIf="!isStartProcessMode()">
<adf-process-instance-details
#activitiProcessDetails
[processInstanceId]="currentProcessInstanceId"
(processCancelled)="processCancelled()"
(showProcessDiagram)="onShowProcessDiagram($event)"

View File

@ -16,32 +16,26 @@
*/
// eslint-disable-next-line
import {
AfterViewInit,
Component,
ElementRef,
Input,
OnDestroy,
OnInit,
ViewChild,
ViewEncapsulation,
EventEmitter,
Output
} from '@angular/core';
import { AfterViewInit, Component, ElementRef, Input, OnDestroy, OnInit, ViewChild, ViewEncapsulation, EventEmitter, Output } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Pagination, UserProcessInstanceFilterRepresentation, ScriptFilesApi } from '@alfresco/js-api';
import {
FORM_FIELD_VALIDATORS, FormRenderingService, FormService, AppConfigService, PaginationComponent, UserPreferenceValues,
AlfrescoApiService, UserPreferencesService, NotificationService
FORM_FIELD_VALIDATORS,
FormRenderingService,
FormService,
AppConfigService,
PaginationComponent,
UserPreferenceValues,
AlfrescoApiService,
UserPreferencesService,
NotificationService
} from '@alfresco/adf-core';
import {
ProcessFiltersComponent,
ProcessInstance,
ProcessInstanceDetailsComponent,
ProcessInstanceListComponent,
StartProcessInstanceComponent,
FilterRepresentationModel,
TaskDetailsComponent,
TaskDetailsEvent,
TaskFiltersComponent,
TaskListComponent,
@ -51,7 +45,6 @@ import {
DynamicTableRow
} from '@alfresco/adf-process-services';
import { Subject } from 'rxjs';
import { CustomStencil01 } from './custom-editor/custom-editor.component';
import { DemoFieldValidator } from './demo-field-validator';
import { PreviewService } from '../../services/preview.service';
import { Location } from '@angular/common';
@ -69,18 +62,12 @@ const REPORT_ROUTE = 2;
templateUrl: './process-service.component.html',
styleUrls: ['./process-service.component.scss'],
encapsulation: ViewEncapsulation.None,
providers: [
{ provide: FormRenderingService, useClass: ProcessFormRenderingService }
]
providers: [{ provide: FormRenderingService, useClass: ProcessFormRenderingService }]
})
export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit {
@ViewChild('activitiFilter')
activitiFilter: TaskFiltersComponent;
@ViewChild('processListPagination')
processListPagination: PaginationComponent;
@ViewChild('taskListPagination')
taskListPagination: PaginationComponent;
@ -93,12 +80,6 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
@ViewChild('processList')
processList: ProcessInstanceListComponent;
@ViewChild('activitiProcessDetails')
activitiProcessDetails: ProcessInstanceDetailsComponent;
@ViewChild('activitiDetails')
activitiDetails: TaskDetailsComponent;
@ViewChild('activitiStartProcess')
activitiStartProcess: StartProcessInstanceComponent;
@ -133,40 +114,31 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
presetColumn = 'default';
showApplications: boolean;
applicationId: number;
processDefinitionName: string;
fieldValidators = [
...FORM_FIELD_VALIDATORS,
new DemoFieldValidator()
];
fieldValidators = [...FORM_FIELD_VALIDATORS, new DemoFieldValidator()];
private onDestroy$ = new Subject<boolean>();
private scriptFileApi: ScriptFilesApi;
constructor(private elementRef: ElementRef,
constructor(
private elementRef: ElementRef,
private route: ActivatedRoute,
private router: Router,
private apiService: AlfrescoApiService,
private appConfig: AppConfigService,
private preview: PreviewService,
formRenderingService: FormRenderingService,
formService: FormService,
private location: Location,
private notificationService: NotificationService,
private preferenceService: UserPreferencesService) {
private preferenceService: UserPreferencesService
) {
this.scriptFileApi = new ScriptFilesApi(this.apiService.getInstance());
this.defaultProcessName = this.appConfig.get<string>('adf-start-process.name');
this.defaultProcessDefinitionName = this.appConfig.get<string>('adf-start-process.processDefinitionName');
this.defaultTaskName = this.appConfig.get<string>('adf-start-task.name');
this.processDefinitionName = this.defaultProcessDefinitionName;
// Uncomment this line to replace all 'text' field editors with custom component
// formRenderingService.setComponentTypeResolver('text', () => CustomEditorComponent, true);
// Uncomment this line to map 'custom_stencil_01' to local editor component
formRenderingService.setComponentTypeResolver('custom_stencil_01', () => CustomStencil01, true);
this.preferenceService
.select(UserPreferenceValues.PaginationSize)
@ -177,20 +149,16 @@ export class ProcessServiceComponent implements AfterViewInit, OnDestroy, OnInit
formService.validateDynamicTableRow
.pipe(takeUntil(this.onDestroy$))
.subscribe(
(validateDynamicTableRowEvent: ValidateDynamicTableRowEvent) => {
.subscribe((validateDynamicTableRowEvent: ValidateDynamicTableRowEvent) => {
const row: DynamicTableRow = validateDynamicTableRowEvent.row;
if (row?.value && row.value.name === 'admin') {
validateDynamicTableRowEvent.summary.isValid = false;
validateDynamicTableRowEvent.summary.message = 'Sorry, wrong value. You cannot use "admin".';
validateDynamicTableRowEvent.preventDefault();
}
}
);
});
formService.formContentClicked
.pipe(takeUntil(this.onDestroy$))
.subscribe((content) => {
formService.formContentClicked.pipe(takeUntil(this.onDestroy$)).subscribe((content) => {
this.showContentPreview(content);
});
}

View File

@ -18,7 +18,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Params, Router } from '@angular/router';
import { Pagination, ResultSetPaging } from '@alfresco/js-api';
import { SearchConfiguration, SearchForm, SearchQueryBuilderService, SearchService } from '@alfresco/adf-content-services';
import { SearchConfiguration, SearchQueryBuilderService, SearchService } from '@alfresco/adf-content-services';
import { ShowHeaderMode, UserPreferencesService } from '@alfresco/adf-core';
import { combineLatest, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@ -30,7 +30,6 @@ import { takeUntil } from 'rxjs/operators';
providers: [SearchService]
})
export class SearchFilterChipsComponent implements OnInit, OnDestroy {
queryParamName = 'q';
searchedWord = '';
data: ResultSetPaging;
@ -38,15 +37,16 @@ export class SearchFilterChipsComponent implements OnInit, OnDestroy {
isLoading = true;
sorting = ['name', 'asc'];
searchForms: SearchForm[];
showHeader = ShowHeaderMode.Always;
private onDestroy$ = new Subject<boolean>();
constructor(public router: Router,
constructor(
public router: Router,
private preferences: UserPreferencesService,
private queryBuilder: SearchQueryBuilderService,
private route: ActivatedRoute) {
private route: ActivatedRoute
) {
combineLatest([this.route.params, this.queryBuilder.configUpdated])
.pipe(takeUntil(this.onDestroy$))
.subscribe(([params, searchConfig]) => {
@ -69,16 +69,12 @@ export class SearchFilterChipsComponent implements OnInit, OnDestroy {
this.sorting = this.getSorting();
this.queryBuilder.updated
.pipe(takeUntil(this.onDestroy$))
.subscribe(() => {
this.queryBuilder.updated.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
this.sorting = this.getSorting();
this.isLoading = true;
});
this.queryBuilder.executed
.pipe(takeUntil(this.onDestroy$))
.subscribe((resultSetPaging: ResultSetPaging) => {
this.queryBuilder.executed.pipe(takeUntil(this.onDestroy$)).subscribe((resultSetPaging: ResultSetPaging) => {
this.queryBuilder.paging.skipCount = 0;
this.onSearchResultLoaded(resultSetPaging);
@ -92,12 +88,14 @@ export class SearchFilterChipsComponent implements OnInit, OnDestroy {
this.queryBuilder.update();
} else {
this.queryBuilder.userQuery = null;
this.queryBuilder.executed.next(new ResultSetPaging({
this.queryBuilder.executed.next(
new ResultSetPaging({
list: {
pagination: { totalItems: 0 },
entries: []
}
}));
})
);
}
});
}

View File

@ -2,10 +2,12 @@
Title: Add Permission Dialog Component
Added: v2.4.0
Status: Active
Last reviewed: 2018-11-13
Last reviewed: 2024-05-07
---
# [Add Permission Dialog Component](../../../lib/content-services/src/lib/permission-manager/components/add-permission/add-permission-dialog.component.ts "Defined in add-permission-dialog.component.ts")
# Add Permission Dialog Component
`import { NodePermissionDialogService } from '@alfresco/adf-content-services';`
Displays a dialog to search for people or groups to add to the current node permissions.
@ -15,41 +17,53 @@ Displays a dialog to search for people or groups to add to the current node perm
```ts
import { NodePermissionDialogService } from '@alfresco/adf-content-services';
import { inject } from '@angular/core';
constructor(private nodePermissionDialogService: nodePermissionDialogService) {
}
export class MyComponent {
private nodePermissionDialogService = inject(NodePermissionDialogService);
this.nodePermissionDialogService.openAddPermissionDialog(this.nodeId).subscribe((selectedNodes) => {
showDialog() {
this.nodePermissionDialogService
.openAddPermissionDialog(this.nodeId)
.subscribe((selectedNodes) => {
//action for selected nodes
},
(error) => {
this.showErrorMessage(error);
});
}
}
```
## Details
This component extends the [Add permission panel component](add-permission-panel.component.md)
to apply the chosen selection of permissions when they are accepted.
You can open the dialog with the `openAddPermissionDialog` method from the
[Node Permission Dialog Service](../services/node-permission-dialog.service.md).
This returns an [`Observable`](http://reactivex.io/documentation/observable.html)
that you can subscribe to so you can get the details of the node after the update.
Use the `updateNodePermissionByDialog` nethod from the service to update node permissions, as shown in
that you can subscribe to, so you can get the details of the node after the update.
Use the `updateNodePermissionByDialog` method from the service to update node permissions, as shown in
the following example:
```ts
import { NodePermissionDialogService } from '@alfresco/adf-content-services';
import { inject } from '@angular/core';
constructor(private nodePermissionDialogService: nodePermissionDialogService) {
}
export class MyComponent {
private nodePermissionDialogService = inject(NodePermissionDialogService);
updateNodePermissions() {
this.nodePermissionDialogService.updateNodePermissionByDialog(this.nodeId).subscribe((node) => {
//updated node
},
(error) => {
this.showErrorMessage(error);
});
}
}
```
## See also

View File

@ -2,24 +2,34 @@
Title: Aspect List component
Added: v2.0.0
Status: Active
Last reviewed: 2021-01-20
Last reviewed: 2024-05-07
---
# [Aspect List component](../../../lib/content-services/src/lib/aspect-list/aspect-list.component.ts "Defined in aspect-list.component.ts")
# Aspect List Component
`import { AspectListComponent } from '@alfresco/adf-content-services';`
This component will show in an expandable row list with checkboxes all the aspect of a node, if a node id is given, or otherwise a complete list.
The aspect are filtered via the app.config.json in this way :
The aspects are filtered via the `app.config.json` in the following way :
```json
{
"aspect-visible": {
"default" : ["as:aspectThatWillBeShowedIfPresent"]
"default": [
"as:aspectThatWillBeShowedIfPresent"
]
}
}
```
## Basic Usage
```html
<adf-aspect-list (valueChanged)="onValueChanged($event)" (updateCounter)="onUpdateCounter($event)" [nodeId]="nodeId">
<adf-aspect-list
[nodeId]="nodeId"
(valueChanged)="onValueChanged($event)"
(updateCounter)="onUpdateCounter($event)">
</adf-aspect-list>
```
@ -28,14 +38,14 @@ The aspect are filtered via the app.config.json in this way :
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
|-----------------|------------|---------------|-----------------------------------------------------|
| nodeId | `string` | "" | Node Id of the node that we want to update |
| excludedAspects | `string[]` | undefined | List of aspects' ids which should not be displayed. |
### Events
| Name | Type | Description |
| ---- | ---- | ----------- |
|---------------|------------------------------------------------------------------------|-----------------------------------------------------------|
| valueChanged | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<string[]>` | Emitted every time the user select a new aspect |
| updateCounter | [`EventEmitter`](https://angular.io/api/core/EventEmitter)`<number>` | Emitted every time the number of selected aspects changes |

View File

@ -50,8 +50,6 @@ const missingRepositories = {
'@webassemblyjs/helper-fsm': 'https://github.com/xtuc/webassemblyjs',
'@webassemblyjs/ieee754': 'https://github.com/xtuc/webassemblyjs',
'@webassemblyjs/leb128': 'https://github.com/xtuc/webassemblyjs',
'adf-tslint-rules': 'https://github.com/Alfresco/alfresco-ng2-components',
'adf-monaco-extension': 'https://github.com/eromano/aca-monaco-extension',
indexof: 'https://github.com/component/indexof',
'rxjs-compat': 'https://github.com/ReactiveX/rxjs/tree/master/compat'
};

View File

@ -62,7 +62,7 @@ export class ChecklistComponent implements OnChanges {
checklist: TaskDetailsModel[] = [];
constructor(private activitiTaskList: TaskListService, private dialog: MatDialog) {}
constructor(private taskListService: TaskListService, private dialog: MatDialog) {}
ngOnChanges(changes: SimpleChanges) {
const taskId = changes['taskId'];
@ -75,7 +75,7 @@ export class ChecklistComponent implements OnChanges {
getTaskChecklist() {
this.checklist = [];
if (this.taskId) {
this.activitiTaskList.getTaskChecklist(this.taskId).subscribe(
this.taskListService.getTaskChecklist(this.taskId).subscribe(
(taskDetailsModel) => {
taskDetailsModel.forEach((task) => {
this.checklist.push(task);
@ -100,7 +100,7 @@ export class ChecklistComponent implements OnChanges {
parentTaskId: this.taskId,
assignee: { id: this.assignee }
});
this.activitiTaskList.addTask(newTask).subscribe(
this.taskListService.addTask(newTask).subscribe(
(taskDetailsModel) => {
this.checklist.push(taskDetailsModel);
this.checklistTaskCreated.emit(taskDetailsModel);
@ -114,7 +114,7 @@ export class ChecklistComponent implements OnChanges {
}
public delete(taskId: string) {
this.activitiTaskList.deleteTask(taskId).subscribe(
this.taskListService.deleteTask(taskId).subscribe(
() => {
this.checklist = this.checklist.filter((check) => check.id !== taskId);
this.checklistTaskDeleted.emit(taskId);

View File

@ -18,7 +18,7 @@
<div class="adf-task-details-core">
<div class="adf-task-details-core-form">
<div *ngIf="isAssigned()">
<adf-task-form
<adf-task-form #taskForm
[taskId]="taskDetails.id"
[showFormTitle]="showFormTitle"
[showFormRefreshButton]="showFormRefreshButton"
@ -33,9 +33,9 @@
(executeOutcome)='onFormExecuteOutcome($event)'
(taskClaimed)="onClaimAction($event)"
(taskUnclaimed)="onUnclaimAction($event)"
(error)="onFormError($event)" #activitiTaskForm>
(error)="onFormError($event)">
</adf-task-form>
<adf-attach-form *ngIf="isShowAttachForm()"
<adf-attach-form *ngIf="showAttachForm"
[taskId]="taskDetails.id"
[formKey]="taskDetails.formKey"
(cancelAttachForm)="onCancelAttachForm()"
@ -68,7 +68,7 @@
(claim)="onClaimAction($event)"
(unclaim)="onUnclaimAction($event)">
</adf-task-header>
<adf-people *ngIf="showInvolvePeople" #people
<adf-people *ngIf="showInvolvePeople"
[people]="taskPeople"
[readOnly]="internalReadOnlyForm"
[taskId]="taskDetails.id">
@ -79,7 +79,6 @@
<mat-card *ngIf="showComments">
<mat-card-content>
<adf-task-comments
#activitiComments
[readOnly]="isReadOnlyComment()"
[taskId]="taskDetails.id"
>
@ -92,7 +91,7 @@
<div *ngIf="showHeaderContent" class="adf-task-details-core-sidebar-checklist">
<div *ngIf="showChecklist">
<adf-checklist #activitiChecklist
<adf-checklist
[readOnly]="internalReadOnlyForm"
[taskId]="taskDetails.id"
[assignee]="$any(taskDetails)?.assignee?.id"

View File

@ -311,7 +311,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails.endDate = new Date('2017-10-03T17:03:57.311+0000');
fixture.detectChanges();
expect((component.activitiComments as any).readOnly).toBe(true);
expect(component.isReadOnlyComment()).toBe(true);
});
it('should comments be readonly if the task is complete and user are NOT involved', () => {
@ -323,7 +323,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails.endDate = new Date('2017-10-03T17:03:57.311+0000');
fixture.detectChanges();
expect((component.activitiComments as any).readOnly).toBe(true);
expect(component.isReadOnlyComment()).toBe(true);
});
it('should comments NOT be readonly if the task is NOT complete and user are NOT involved', () => {
@ -335,7 +335,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails.endDate = null;
fixture.detectChanges();
expect((component.activitiComments as any).readOnly).toBe(false);
expect(component.isReadOnlyComment()).toBe(false);
});
it('should comments NOT be readonly if the task is complete and user are involved', () => {
@ -347,7 +347,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails.endDate = new Date('2017-10-03T17:03:57.311+0000');
fixture.detectChanges();
expect((component.activitiComments as any).readOnly).toBe(false);
expect(component.isReadOnlyComment()).toBe(false);
});
it('should comments be present if showComments is true', () => {
@ -358,7 +358,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails = new TaskDetailsModel(taskDetailsMock);
fixture.detectChanges();
expect(component.activitiComments).toBeDefined();
expect(component.showComments).toBe(true);
});
it('should comments NOT be present if showComments is false', () => {
@ -368,7 +368,7 @@ describe('TaskDetailsComponent', () => {
component.taskDetails = new TaskDetailsModel(taskDetailsMock);
fixture.detectChanges();
expect(component.activitiComments).not.toBeDefined();
expect(component.showComments).toBeFalse();
});
});

View File

@ -18,7 +18,6 @@
import {
CardViewUpdateService,
ClickNotification,
CommentsComponent,
ContentLinkModel,
FormFieldValidator,
FormModel,
@ -55,22 +54,12 @@ import { PeopleProcessService } from '../../common/services/people-process.servi
encapsulation: ViewEncapsulation.None
})
export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
@ViewChild('activitiComments')
activitiComments: CommentsComponent;
@ViewChild('activitiChecklist')
activitiChecklist: any;
@ViewChild('errorDialog')
errorDialog: TemplateRef<any>;
@ViewChild('activitiTaskForm')
@ViewChild('taskForm')
taskFormComponent: TaskFormComponent;
/** Toggles debug mode. */
@Input()
debugMode: boolean = false;
/** (**required**) The id of the task whose details we are asking for. */
@Input()
taskId: string;
@ -177,9 +166,9 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
taskFormName: string = null;
taskPeople: UserProcessModel[] = [];
noTaskDetailsTemplateComponent: TemplateRef<any>;
showAssignee: boolean = false;
showAttachForm: boolean = false;
internalReadOnlyForm: boolean = false;
showAssignee = false;
showAttachForm = false;
internalReadOnlyForm = false;
errorDialogRef: MatDialogRef<TemplateRef<any>>;
peopleSearch: Observable<UserProcessModel[]>;
data: any;
@ -222,14 +211,6 @@ export class TaskDetailsComponent implements OnInit, OnChanges, OnDestroy {
}
}
isShowAttachForm(): boolean {
return this.showAttachForm;
}
isTaskActive() {
return this.taskDetails && this.taskDetails.duration === null;
}
isAssigned(): boolean {
return !!this.taskDetails.assignee;
}

View File

@ -58,7 +58,6 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
unclaim: EventEmitter<any> = new EventEmitter<any>();
properties: any[] = [];
inEdit: boolean = false;
displayDateClearAction = false;
dateFormat: string;
dateLocale: string;
@ -196,10 +195,20 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
return this.taskDetails?.isCompleted() ? 'Completed' : 'Running';
}
/**
* Emit the claim event
*
* @param taskId the id of the task to claim
*/
onClaimTask(taskId: string) {
this.claim.emit(taskId);
}
/**
* Emit the unclaim event
*
* @param taskId the id of the task to unclaim
*/
onUnclaimTask(taskId: string) {
this.unclaim.emit(taskId);
}
@ -213,15 +222,25 @@ export class TaskHeaderComponent implements OnChanges, OnInit {
return !!this.taskDetails?.endDate;
}
/**
* Check if the form is clickable
*
* @returns `true` if the form is clickable, otherwise `false`
*/
isFormClickable(): boolean {
return !!this.formName && !this.isCompleted();
}
/**
* Get the task duration
*
* @returns the task duration in milliseconds
*/
getTaskDuration(): string {
return this.taskDetails.duration ? `${this.taskDetails.duration} ms` : '';
}
private initDefaultProperties(parentInfoMap): any[] {
private initDefaultProperties(parentInfoMap: Map<string, string>): any[] {
return [
new CardViewTextItemModel({
label: 'ADF_TASK_LIST.PROPERTIES.ASSIGNEE',

View File

@ -1,6 +1,5 @@
<div *ngIf="!requestNode">{{ 'ADF_TASK_LIST.FILTERS.MESSAGES.NONE' | translate }}</div>
<ng-container *ngIf="requestNode">
<adf-datatable
*ngIf="requestNode; else noMessagesTemplate"
[data]="data"
[rows]="rows"
[columns]="columns"
@ -16,28 +15,30 @@
(row-select)="onRowSelect($any($event))"
(row-unselect)="onRowUnselect($any($event))"
(rowClick)="onRowClick($any($event))"
(row-keyup)="onRowKeyUp($any($event))">
(row-keyup)="onRowKeyUp($any($event))"
>
<adf-loading-content-template>
<ng-template>
<!--Add your custom loading template here-->
<mat-progress-spinner
*ngIf="!customLoadingContent"
class="adf-task-list-loading-margin"
color="primary"
mode="indeterminate">
<mat-progress-spinner *ngIf="!customLoadingContent" class="adf-task-list-loading-margin" color="primary" mode="indeterminate">
</mat-progress-spinner>
<ng-content select="adf-custom-loading-content-template"></ng-content>
</ng-template>
</adf-loading-content-template>
<adf-no-content-template>
<ng-template>
<adf-empty-content *ngIf="!customEmptyContent"
<adf-empty-content
*ngIf="!customEmptyContent"
icon="assignment"
[title]="'ADF_TASK_LIST.LIST.MESSAGES.TITLE' | translate"
[subtitle]="'ADF_TASK_LIST.LIST.MESSAGES.SUBTITLE' | translate">
[subtitle]="'ADF_TASK_LIST.LIST.MESSAGES.SUBTITLE' | translate"
>
</adf-empty-content>
<ng-content select="adf-custom-empty-content-template"></ng-content>
</ng-template>
</adf-no-content-template>
</adf-datatable>
</ng-container>
<ng-template #noMessagesTemplate>
<div>{{ 'ADF_TASK_LIST.FILTERS.MESSAGES.NONE' | translate }}</div>
</ng-template>

View File

@ -23,29 +23,26 @@ import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angu
styleUrls: ['./task-standalone.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class TaskStandaloneComponent {
/** Name of the task. */
@Input()
taskName;
taskName: string;
/** Id of the task. */
@Input()
taskId;
taskId: string;
/** If true then Task completed message is shown and `Complete` and `Cancel` buttons are hidden. */
@Input()
isCompleted: boolean = false;
isCompleted = false;
/** Toggles rendering of the `Complete` button. */
@Input()
hasCompletePermission: boolean = true;
hasCompletePermission = true;
// TODO: rename all with show prefix
/** Toggles rendering of the `Cancel` button. */
@Input()
hideCancelButton: boolean = true;
hideCancelButton = true;
/** Emitted when the "Cancel" button is clicked. */
@Output()
@ -59,8 +56,6 @@ export class TaskStandaloneComponent {
@Output()
showAttachForm = new EventEmitter<void>();
constructor() { }
onCancelButtonClick(): void {
this.cancel.emit();
}

View File

@ -1,7 +0,0 @@
/npm-debug.log
/.idea
node_modules
coverage
/temp/
local.log
/rules/*.js

View File

@ -1,15 +0,0 @@
.idea
coverage/
node_modules
temp/
test/
/.editorconfig
/gulpfile.js
/.npmignore
*.tgz
/assets/
local.log

View File

@ -1,36 +0,0 @@
# adf-tslint-rules
A set of [TSLint](https://github.com/palantir/tslint) rules used on [ADF](https://github.com/Alfresco/alfresco-ng2-components) project.
## Installation
```sh
npm install adf-tslint-rules
```
## Configuration
```javascript
{
"rulesDirectory": [
"node_modules/codelyzer",
"node_modules/adf-tslint-rules"
],
"rules": {
"adf-file-name": true,
"adf-class-name": true,
"adf-no-on-prefix-output-name": true
}
}
```
Supported Rules
-----
Rule Name | Description |
---------- | ------------ |
`adf-file-name` | The name of the File should not start with ADF Alfresco or Activiti prefix |
`adf-class-name` | The name of the class should not start with ADF Alfresco or Activiti prefix |
`adf-no-on-prefix-output-name` | Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression |
|

View File

@ -1,44 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
const sprintf_js_1 = require("sprintf-js");
const walkerFactory_1 = require("codelyzer/walkerFactory/walkerFactory");
const walkerFn_1 = require("codelyzer/walkerFactory/walkerFn");
const function_1 = require("codelyzer/util/function");
class Rule extends Lint.Rules.AbstractRule {
static invalidName(className) {
var whiteList = ['ActivitiContentComponent', 'ActivitiForm'];
var classNameReg = /^(alfresco|activiti|adf|activity)/ig;
var classNameMatch = classNameReg.exec(className);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === className;
});
if (classNameMatch && !isWhiteListName) {
return true;
}
return false;
}
apply(sourceFile) {
return this.applyWithWalker(Rule.walkerBuilder(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-class-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify class when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'The name of the class should not start with ADF Alfresco or Activiti prefix ';
Rule.walkerBuilder = walkerFn_1.all(walkerFn_1.validateComponent((meta, suffixList) => function_1.Maybe.lift(meta.controller)
.fmap(controller => controller.name)
.fmap(name => {
const className = name.text;
if (Rule.invalidName(className)) {
return [new walkerFactory_1.Failure(name, sprintf_js_1.sprintf(Rule.FAILURE_STRING + className, className, suffixList))];
}
})));
exports.Rule = Rule;

View File

@ -1,78 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { sprintf } from 'sprintf-js';
import { ComponentMetadata } from 'codelyzer/angular/metadata';
import { Failure } from 'codelyzer/walkerFactory/walkerFactory';
import { all, validateComponent } from 'codelyzer/walkerFactory/walkerFn';
import { Maybe, F2 } from 'codelyzer/util/function';
import { IOptions } from 'tslint';
import { NgWalker } from 'codelyzer/angular/ngWalker';
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-class-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify class when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
public static FAILURE_STRING = 'The name of the class should not start with ADF Alfresco or Activiti prefix ';
static walkerBuilder: F2<ts.SourceFile, IOptions, NgWalker> =
all(
validateComponent((meta: ComponentMetadata, suffixList?: string[]) =>
Maybe.lift(meta.controller)
.fmap(controller => controller.name)
.fmap(name => {
const className = name.text;
if (Rule.invalidName(className)) {
return [new Failure(name, sprintf(Rule.FAILURE_STRING + className, className, suffixList))];
}
})
));
static invalidName(className: string): boolean {
var whiteList = ['ActivitiContentComponent', 'ActivitiForm'];
var classNameReg = /^(alfresco|activiti|adf|activity)/ig;
var classNameMatch = classNameReg.exec(className);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === className;
});
if (classNameMatch && !isWhiteListName) {
return true;
}
return false;
}
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
Rule.walkerBuilder(sourceFile, this.getOptions())
);
}
}

View File

@ -1,55 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new AdfFileName(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-file-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify files when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'The name of the File should not start with ADF Alfresco or Activiti prefix ';
Rule.FAILURE_STRING_UNDERSCORE = 'The name of the File should not have _ in the name but you can use - prefer the kebab case';
Rule.FAILURE_STRING_UPPERCASE = 'The name of the File should not start with uppercase';
exports.Rule = Rule;
class AdfFileName extends Lint.RuleWalker {
visitSourceFile(node) {
var whiteList = ['activiti-alfresco.service.ts', 'activiti-alfresco.service.spec.ts',
'alfresco-api.service.ts', 'alfresco-api.service.spects'];
var fileName = this.getFilename();
var fileNameReg = /^(alfresco|activiti|adf|activity)/ig;
var filenameMatch = fileNameReg.exec(fileName);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === fileName;
});
if (filenameMatch && !isWhiteListName) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + fileName));
super.visitSourceFile(node);
}
if (fileName.indexOf('_') >= 0) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING_UNDERSCORE + fileName));
super.visitSourceFile(node);
}
if (fileName[0] == fileName[0].toUpperCase()) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING_UPPERCASE + fileName));
super.visitSourceFile(node);
}
}
getFilename() {
const filename = this.getSourceFile().fileName;
const lastSlash = filename.lastIndexOf('/');
if (lastSlash > -1) {
return filename.substring(lastSlash + 1);
}
return filename;
}
}

View File

@ -1,66 +0,0 @@
import * as ts from "typescript";
import * as Lint from "tslint";
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-file-name',
type: 'maintainability',
description: `Enforce consistent name avoid prefix`,
descriptionDetails: `See more at https://angular.io/styleguide#style-05-13.`,
rationale: `Consistent conventions make it easy to quickly identify files when you search with autocomplete.`,
options: null,
optionsDescription: "Not configurable.",
typescriptOnly: true,
};
public static FAILURE_STRING = 'The name of the File should not start with ADF Alfresco or Activiti prefix ';
public static FAILURE_STRING_UNDERSCORE = 'The name of the File should not have _ in the name but you can use - ';
public static FAILURE_STRING_UPPERCASE = 'The name of the File should not start with uppercase';
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new AdfFileName(sourceFile, this.getOptions()));
}
}
// The walker takes care of all the work.
class AdfFileName extends Lint.RuleWalker {
public visitSourceFile(node: ts.SourceFile) {
var whiteList = ['activiti-alfresco.service.ts', 'activiti-alfresco.service.spec.ts',
'alfresco-api.service.ts', 'alfresco-api.service.spects'];
var fileName = this.getFilename();
var fileNameReg = /^(alfresco|activiti|adf|activity)/ig;
var filenameMatch = fileNameReg.exec(fileName);
var isWhiteListName = whiteList.find((currentWhiteListName) => {
return currentWhiteListName === fileName;
});
console.log('error');
if (filenameMatch && !isWhiteListName) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING + fileName));
super.visitSourceFile(node);
}
if (fileName.indexOf('-') >= 0) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING_UNDERSCORE + fileName));
super.visitSourceFile(node);
}
if (fileName[0] == fileName[0].toUpperCase()) {
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING_UPPERCASE + fileName));
super.visitSourceFile(node);
}
}
private getFilename(): string {
const filename = this.getSourceFile().fileName;
const lastSlash = filename.lastIndexOf('/');
if (lastSlash > -1) {
return filename.substring(lastSlash + 1);
}
return filename;
}
}

View File

@ -1,34 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Lint = require("tslint");
const sprintf_js_1 = require("sprintf-js");
const ngWalker_1 = require("codelyzer/angular/ngWalker");
class Rule extends Lint.Rules.AbstractRule {
apply(sourceFile) {
return this.applyWithWalker(new ADFOutputPrefixNameRule(sourceFile, this.getOptions()));
}
}
Rule.metadata = {
ruleName: 'adf-prefix-name',
type: 'maintainability',
description: `Name events without the prefix on`,
descriptionDetails: `See more at https://angular.io/guide/styleguide#dont-prefix-output-properties`,
rationale: `Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression`,
options: null,
optionsDescription: `Not configurable.`,
typescriptOnly: true,
};
Rule.FAILURE_STRING = 'In the class "%s", the output ' +
'property "%s" should not be prefixed with on';
exports.Rule = Rule;
class ADFOutputPrefixNameRule extends ngWalker_1.NgWalker {
visitNgOutput(property, output, args) {
let className = property.parent.name.text;
let memberName = property.name.text;
if (memberName && memberName.startsWith('on')) {
let failureConfig = [className, memberName];
failureConfig.unshift(Rule.FAILURE_STRING);
this.addFailure(this.createFailure(property.getStart(), property.getWidth(), sprintf_js_1.sprintf.apply(this, failureConfig)));
}
}
}

View File

@ -1,60 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { sprintf } from 'sprintf-js';
import { NgWalker } from 'codelyzer/angular/ngWalker';
export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: 'adf-prefix-name',
type: 'maintainability',
description: `Name events without the prefix on`,
descriptionDetails: `See more at https://angular.io/guide/styleguide#dont-prefix-output-properties`,
rationale: `Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression`,
options: null,
optionsDescription: `Not configurable.`,
typescriptOnly: true
};
static FAILURE_STRING: string = 'In the class "%s", the output ' +
'property "%s" should not be prefixed with on';
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(
new ADFOutputPrefixNameRule(sourceFile,
this.getOptions()));
}
}
class ADFOutputPrefixNameRule extends NgWalker {
visitNgOutput(property: ts.PropertyDeclaration, output: ts.Decorator, args: string[]) {
const className = (<any>property).parent.name.text;
const memberName = (<any>property.name).text;
if (memberName && memberName.startsWith('on')) {
const failureConfig: string[] = [className, memberName];
failureConfig.unshift(Rule.FAILURE_STRING);
this.addFailure(
this.createFailure(
property.getStart(),
property.getWidth(),
sprintf.apply(this, failureConfig)));
}
}
}

View File

@ -1,9 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var adfClassNameRule_1 = require("./adfClassNameRule");
exports.ADFClassNameRule = adfClassNameRule_1.Rule;
var adfFileNameRule_1 = require("./adfFileNameRule");
exports.ADFComponentSelectorRule = adfFileNameRule_1.Rule;
var adfPrefixNameRule_1 = require("./adfPrefixNameRule");
exports.ADFOutputPrefixNameRule = adfPrefixNameRule_1.Rule;
exports.rulesDirectory = '.';

View File

@ -1,22 +0,0 @@
/*!
* @license
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* 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.
*/
export { Rule as ADFClassNameRule } from './adfClassNameRule';
export { Rule as ADFComponentSelectorRule } from './adfFileNameRule';
export { Rule as ADFOutputPrefixNameRule } from './adfPrefixNameRule';
export const rulesDirectory = '.';

View File

@ -1,108 +0,0 @@
{
"name": "adf-tslint-rules",
"version": "0.0.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"app-root-path": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
"integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y="
},
"css-selector-tokenizer": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
"integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
"requires": {
"cssesc": "^0.1.0",
"fastparse": "^1.1.1",
"regexpu-core": "^1.0.0"
}
},
"cssauron": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz",
"integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=",
"requires": {
"through": "X.X.X"
}
},
"cssesc": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
"integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q="
},
"fastparse": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
"integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg="
},
"jsesc": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0="
},
"regenerate": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz",
"integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA="
},
"regexpu-core": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
"integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
"requires": {
"regenerate": "^1.2.1",
"regjsgen": "^0.2.0",
"regjsparser": "^0.1.4"
}
},
"regjsgen": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc="
},
"regjsparser": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
"requires": {
"jsesc": "~0.5.0"
}
},
"semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
},
"semver-dsl": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz",
"integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=",
"requires": {
"semver": "^5.3.0"
}
},
"source-map": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"typescript": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.4.0.tgz",
"integrity": "sha1-rvWo1AS+ujatM5q/B53d3/+6ht0=",
"dev": true
}
}
}

View File

@ -1,34 +0,0 @@
{
"name": "adf-tslint-rules",
"description": "Custom Rules for the ADF project",
"version": "0.0.7",
"author": "Hyland Software, Inc. and its affiliates",
"scripts": {
"build": "tsc",
"tscv": "tsc --version",
"tsc": "tsc",
"tsc:watch": "tsc --w"
},
"contributors": [
{
"name": "Eugenio Romano",
"email": "eugenio.romano@alfresco.com"
}
],
"devDependencies": {
"typescript": "2.4.0"
},
"peerDependencies": {
"tslint": ">=5.0.0",
"codelyzer": ">=4.5.0"
},
"dependencies": {
"app-root-path": "2.0.1",
"css-selector-tokenizer": "0.7.0",
"cssauron": "1.4.0",
"semver-dsl": "1.0.1",
"source-map": "0.5.6",
"sprintf-js": "1.0.3"
},
"license": "Apache-2.0"
}

View File

@ -1,22 +0,0 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "es6",
"module": "commonjs",
"declaration": false,
"noImplicitAny": false,
"removeComments": true,
"lib": ["es6", "es2015", "dom"],
"noLib": false,
"typeRoots": [
"./node_modules/@types",
"./node_modules"
],
"types": [
"mocha",
"chai",
"node",
"sprintf-js"
]
}
}

View File

@ -1,5 +0,0 @@
{
"rules": {
"adf-file-naming": true
}
}