ACS-7390: Core and Content Services as Standalone components (#10001)

This commit is contained in:
Denys Vuika
2024-08-09 18:14:56 -04:00
committed by GitHub
parent 0277376c79
commit 93f9e80348
284 changed files with 2256 additions and 2497 deletions

View File

@@ -16,11 +16,18 @@
*/
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { AspectListDialogComponentData } from './aspect-list-dialog-data.interface';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { AspectListComponent } from './aspect-list.component';
import { AutoFocusDirective } from '../directives/auto-focus.directive';
import { CommonModule } from '@angular/common';
@Component({
selector: 'adf-aspect-list-dialog',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatButtonModule, AspectListComponent, AutoFocusDirective],
templateUrl: './aspect-list-dialog.component.html',
styleUrls: ['./aspect-list-dialog.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -119,7 +119,7 @@ describe('AspectListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
imports: [ContentTestingModule, AspectListComponent],
providers: [AspectListService]
});
});

View File

@@ -20,10 +20,18 @@ import { NodesApiService } from '../common/services/nodes-api.service';
import { Observable, Subject, zip } from 'rxjs';
import { concatMap, map, takeUntil, tap } from 'rxjs/operators';
import { AspectListService } from './services/aspect-list.service';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
import { AspectEntry } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatTableModule } from '@angular/material/table';
import { TranslateModule } from '@ngx-translate/core';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
@Component({
selector: 'adf-aspect-list',
standalone: true,
imports: [CommonModule, MatExpansionModule, MatCheckboxModule, MatTableModule, TranslateModule, MatProgressSpinnerModule],
templateUrl: './aspect-list.component.html',
styleUrls: ['./aspect-list.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -15,34 +15,15 @@
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { AspectListComponent } from './aspect-list.component';
import { MatTableModule } from '@angular/material/table';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { PipeModule } from '@alfresco/adf-core';
import { TranslateModule } from '@ngx-translate/core';
import { MatDialogModule } from '@angular/material/dialog';
import { AspectListDialogComponent } from './aspect-list-dialog.component';
import { MatButtonModule } from '@angular/material/button';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ContentDirectiveModule } from '../directives/content-directive.module';
export const ASPECT_LIST_DIRECTIVES = [AspectListComponent, AspectListDialogComponent] as const;
/** @deprecated use `...ASPECT_LIST_DIRECTIVES` or import the individual components */
@NgModule({
imports: [
CommonModule,
MatTableModule,
MatExpansionModule,
MatCheckboxModule,
PipeModule,
TranslateModule,
MatDialogModule,
MatButtonModule,
MatProgressSpinnerModule,
ContentDirectiveModule
],
exports: [AspectListComponent, AspectListDialogComponent],
declarations: [AspectListComponent, AspectListDialogComponent]
imports: [...ASPECT_LIST_DIRECTIVES],
exports: [...ASPECT_LIST_DIRECTIVES]
})
export class AspectListModule {}

View File

@@ -21,8 +21,8 @@ import { forkJoin, Observable, of, Subject, zip } from 'rxjs';
import {
AppConfigService,
CardViewBaseItemModel,
CardViewComponent,
CardViewItem,
CardViewModule,
NotificationService,
TranslationService,
UpdateNotification
@@ -68,12 +68,12 @@ enum DefaultPanels {
MatButtonModule,
TranslateModule,
MatIconModule,
CardViewModule,
MatChipsModule,
CategoriesManagementComponent,
DynamicExtensionComponent,
MatProgressBarModule,
TagsCreatorComponent
TagsCreatorComponent,
CardViewComponent
],
templateUrl: './content-metadata.component.html',
styleUrls: ['./content-metadata.component.scss'],

View File

@@ -44,8 +44,7 @@
{{ 'SEARCH.SEARCH_HEADER.TITLE' | translate }}
</button>
<div class="adf-content-node-selector-search-panel-container">
<adf-search-panel *ngIf="searchPanelExpanded">
</adf-search-panel>
<adf-search-panel *ngIf="searchPanelExpanded"></adf-search-panel>
<div class="adf-content-node-selector-document-list-container">
<adf-toolbar>
<adf-toolbar-title>

View File

@@ -23,10 +23,15 @@ import {
InfinitePaginationComponent,
PaginatedComponent,
DataSorting,
ShowHeaderMode
ShowHeaderMode,
ToolbarTitleComponent,
ToolbarComponent,
DataColumnListComponent,
DataColumnComponent,
CustomEmptyContentTemplateDirective
} from '@alfresco/adf-core';
import { NodesApiService, UploadService, FileUploadCompleteEvent, FileUploadDeleteEvent, SitesService } from '../../common';
import { UntypedFormControl } from '@angular/forms';
import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms';
import { Node, NodePaging, Pagination, SiteEntry, SitePaging, NodeEntry, SearchRequest, RequestScope } from '@alfresco/js-api';
import { DocumentListComponent } from '../../document-list/components/document-list.component';
import { RowFilter } from '../../document-list/data/row-filter.model';
@@ -36,8 +41,20 @@ import { ShareDataRow } from '../../document-list/data/share-data-row.model';
import { NodeEntryEvent } from '../../document-list/components/node.event';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { SearchQueryBuilderService } from '../../search';
import { ContentNodeSelectorPanelService } from './content-node-selector-panel.service';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { TranslateModule } from '@ngx-translate/core';
import { MatInputModule } from '@angular/material/input';
import { AutoFocusDirective } from '../../directives/auto-focus.directive';
import { NodeCounterDirective } from '../../directives/node-counter.directive';
import { MatIconModule } from '@angular/material/icon';
import { DropdownSitesComponent } from '../site-dropdown/sites-dropdown.component';
import { MatButtonModule } from '@angular/material/button';
import { NameLocationCellComponent } from '../name-location-cell/name-location-cell.component';
import { DropdownBreadcrumbComponent } from '../../breadcrumb/dropdown-breadcrumb.component';
import { SearchQueryBuilderService } from '../../search/services/search-query-builder.service';
import { SearchPanelComponent } from '../../search/components/search-panel/search-panel.component';
export type ValidationFunction = (entry: Node) => boolean;
@@ -45,6 +62,30 @@ export const defaultValidation = () => true;
@Component({
selector: 'adf-content-node-selector-panel',
standalone: true,
imports: [
CommonModule,
MatFormFieldModule,
TranslateModule,
MatInputModule,
ReactiveFormsModule,
AutoFocusDirective,
MatIconModule,
DropdownSitesComponent,
MatButtonModule,
ToolbarTitleComponent,
ToolbarComponent,
DropdownBreadcrumbComponent,
NodeCounterDirective,
DocumentListComponent,
HighlightDirective,
DataColumnListComponent,
DataColumnComponent,
NameLocationCellComponent,
InfinitePaginationComponent,
CustomEmptyContentTemplateDirective,
SearchPanelComponent
],
templateUrl: './content-node-selector-panel.component.html',
styleUrls: ['./content-node-selector-panel.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { CUSTOM_ELEMENTS_SCHEMA, EventEmitter } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ContentNodeSelectorComponent } from './content-node-selector.component';
@@ -28,7 +28,6 @@ import { of } from 'rxjs';
import { ContentTestingModule } from '../testing/content.testing.module';
import { DocumentListService } from '../document-list/services/document-list.service';
import { DocumentListComponent } from '../document-list/components/document-list.component';
import { UploadModule } from '../upload';
import { ContentNodeSelectorPanelComponent } from './content-node-selector-panel/content-node-selector-panel.component';
import { NodeAction } from '../document-list/models/node-action.enum';
import { SitesService } from '../common/services/sites.service';
@@ -60,7 +59,7 @@ describe('ContentNodeSelectorComponent', () => {
};
TestBed.configureTestingModule({
imports: [ContentTestingModule, MatDialogModule, UploadModule],
imports: [ContentTestingModule, ContentNodeSelectorComponent],
providers: [
{ provide: MAT_DIALOG_DATA, useValue: data },
{

View File

@@ -16,8 +16,8 @@
*/
import { Component, Inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { TranslationService, NotificationService } from '@alfresco/adf-core';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { TranslationService, NotificationService, ToolbarTitleComponent, ToolbarComponent, EmptyListComponent } from '@alfresco/adf-core';
import { Node } from '@alfresco/js-api';
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
import { ContentService } from '../common/services/content.service';
@@ -28,9 +28,38 @@ import { NodeAction } from '../document-list/models/node-action.enum';
import { OverlayContainer } from '@angular/cdk/overlay';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { MatTabsModule } from '@angular/material/tabs';
import { TranslateModule } from '@ngx-translate/core';
import { DropdownBreadcrumbComponent } from '../breadcrumb/dropdown-breadcrumb.component';
import { NodeCounterDirective } from '../directives/node-counter.directive';
import { MatIconModule } from '@angular/material/icon';
import { UploadDragAreaComponent } from '../upload/components/upload-drag-area.component';
import { FileUploadingDialogComponent } from '../upload/components/file-uploading-dialog.component';
import { ContentNodeSelectorPanelComponent } from './content-node-selector-panel/content-node-selector-panel.component';
import { UploadButtonComponent } from '../upload/components/upload-button.component';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-content-node-selector',
standalone: true,
imports: [
CommonModule,
MatDialogModule,
MatTabsModule,
TranslateModule,
ToolbarTitleComponent,
ToolbarComponent,
DropdownBreadcrumbComponent,
NodeCounterDirective,
MatIconModule,
UploadDragAreaComponent,
FileUploadingDialogComponent,
EmptyListComponent,
ContentNodeSelectorPanelComponent,
UploadButtonComponent,
MatButtonModule
],
templateUrl: './content-node-selector.component.html',
styleUrls: ['./content-node-selector.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -15,39 +15,22 @@
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MaterialModule } from '../material.module';
import { ContentNodeSelectorPanelComponent } from './content-node-selector-panel/content-node-selector-panel.component';
import { ContentNodeSelectorComponent } from './content-node-selector.component';
import { BREADCRUMB_DIRECTIVES } from '../breadcrumb/breadcrumb.module';
import { SearchModule } from '../search/search.module';
import { CoreModule } from '@alfresco/adf-core';
import { DocumentListModule } from '../document-list/document-list.module';
import { NameLocationCellComponent } from './name-location-cell/name-location-cell.component';
import { CONTENT_UPLOAD_DIRECTIVES } from '../upload/upload.module';
import { SearchQueryBuilderService } from '../search/services/search-query-builder.service';
import { CONTENT_DIRECTIVES } from '../directives/content-directive.module';
import { DropdownSitesComponent } from './site-dropdown/sites-dropdown.component';
export const CONTENT_NODE_SELECTOR_DIRECTIVES = [
ContentNodeSelectorPanelComponent,
NameLocationCellComponent,
ContentNodeSelectorComponent,
DropdownSitesComponent
];
/** @deprecated use `...CONTENT_NODE_SELECTOR_DIRECTIVES` or import the individual components */
@NgModule({
imports: [
FormsModule,
ReactiveFormsModule,
CoreModule,
CommonModule,
MaterialModule,
DropdownSitesComponent,
...BREADCRUMB_DIRECTIVES,
SearchModule,
DocumentListModule,
NameLocationCellComponent,
CONTENT_DIRECTIVES,
...CONTENT_UPLOAD_DIRECTIVES
],
exports: [ContentNodeSelectorPanelComponent, NameLocationCellComponent, ContentNodeSelectorComponent],
declarations: [ContentNodeSelectorPanelComponent, ContentNodeSelectorComponent],
providers: [SearchQueryBuilderService]
imports: [...CONTENT_NODE_SELECTOR_DIRECTIVES],
exports: [...CONTENT_NODE_SELECTOR_DIRECTIVES]
})
export class ContentNodeSelectorModule {}

View File

@@ -23,7 +23,7 @@ import { Subject } from 'rxjs';
import { ContentService } from '../common/services/content.service';
import { SharedLinksApiService } from './services/shared-links-api.service';
import { SharedLinkBodyCreate } from '@alfresco/js-api';
import { ClipboardModule, ConfirmDialogComponent } from '@alfresco/adf-core';
import { ClipboardDirective, ConfirmDialogComponent } from '@alfresco/adf-core';
import { ContentNodeShareSettings } from './content-node-share.settings';
import { RenditionService } from '../common/services/rendition.service';
import { format, add, endOfDay, isBefore } from 'date-fns';
@@ -53,8 +53,8 @@ interface SharedDialogFormProps {
MatFormFieldModule,
MatDatepickerModule,
MatInputModule,
ClipboardModule,
MatButtonModule
MatButtonModule,
ClipboardDirective
],
templateUrl: './content-node-share.dialog.html',
styleUrls: ['./content-node-share.dialog.scss'],

View File

@@ -1,7 +1,7 @@
<div class="adf-content-type-dialog">
<h2 mat-dialog-title class="adf-content-type-dialog-title" data-automation-id="content-type-dialog-title">{{title |
translate}}</h2>
<mat-dialog-content class="mat-typography" class="adf-content-type-dialog-content"
<mat-dialog-content class="mat-typography adf-content-type-dialog-content"
data-automation-id="content-type-dialog-content">
<h4 data-automation-id="content-type-dialog-description">{{description | translate}}</h4>
<p data-automation-id="content-type-dialog-confirm-message">{{confirmMessage | translate}}</p>
@@ -39,7 +39,7 @@
<button mat-button mat-dialog-close
id="content-type-dialog-actions-cancel">{{'CORE.METADATA.CONTENT_TYPE.DIALOG.CANCEL' | translate }}</button>
<button mat-button class="adf-content-type-dialog-apply-button" id="content-type-dialog-apply-button"
[mat-dialog-close]="true" cdkFocusInitial (click)="onApply()">{{'CORE.METADATA.CONTENT_TYPE.DIALOG.APPLY' |
[mat-dialog-close]="true" (click)="onApply()">{{'CORE.METADATA.CONTENT_TYPE.DIALOG.APPLY' |
translate}}</button>
</mat-dialog-actions>
</div>

View File

@@ -17,18 +17,24 @@
import { TypeEntry } from '@alfresco/js-api';
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { ContentTypeDialogComponentData } from './content-type-metadata.interface';
import { ContentTypeService } from './content-type.service';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatTableModule } from '@angular/material/table';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-content-type-dialog',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatExpansionModule, MatTableModule, MatButtonModule],
templateUrl: './content-type-dialog.component.html',
styleUrls: ['./content-type-dialog.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ContentTypeDialogComponent implements OnInit {
title: string;
description: string;
nodeType: string;
@@ -39,9 +45,11 @@ export class ContentTypeDialogComponent implements OnInit {
propertyColumns: string[] = ['name', 'title', 'dataType'];
constructor(private dialog: MatDialogRef<ContentTypeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: ContentTypeDialogComponentData,
private contentTypeService: ContentTypeService) {
constructor(
private dialog: MatDialogRef<ContentTypeDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: ContentTypeDialogComponentData,
private contentTypeService: ContentTypeService
) {
this.title = data.title;
this.description = data.description;
this.confirmMessage = data.confirmMessage;
@@ -49,7 +57,9 @@ export class ContentTypeDialogComponent implements OnInit {
this.contentTypeService.getContentTypeByPrefix(this.nodeType).subscribe((contentTypeEntry) => {
this.currentContentType = contentTypeEntry;
this.typeProperties = this.currentContentType.entry.properties.filter((property) => property.id.startsWith(this.currentContentType.entry.model.namespacePrefix));
this.typeProperties = this.currentContentType.entry.properties.filter((property) =>
property.id.startsWith(this.currentContentType.entry.model.namespacePrefix)
);
});
}

View File

@@ -1,45 +0,0 @@
/*!
* @license
* Copyright © 2005-2024 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 { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { TranslateModule } from '@ngx-translate/core';
import { MatDialogModule } from '@angular/material/dialog';
import { MatButtonModule } from '@angular/material/button';
import { ContentTypeDialogComponent } from './content-type-dialog.component';
@NgModule({
imports: [
CommonModule,
MatTableModule,
MatExpansionModule,
MatCheckboxModule,
TranslateModule,
MatDialogModule,
MatButtonModule
],
exports: [
ContentTypeDialogComponent
],
declarations: [
ContentTypeDialogComponent
]
})
export class ContentTypeModule { }

View File

@@ -18,5 +18,3 @@
export * from './content-type.service';
export * from './content-type-metadata.interface';
export * from './content-type-dialog.component';
export * from './content-type.module';

View File

@@ -15,81 +15,75 @@
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule, ModuleWithProviders, APP_INITIALIZER } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CoreModule, SearchTextModule, provideTranslations } from '@alfresco/adf-core';
import { MaterialModule } from './material.module';
import { provideTranslations } from '@alfresco/adf-core';
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
import { CONTENT_TAG_DIRECTIVES } from './tag/tag.module';
import { DocumentListModule } from './document-list/document-list.module';
import { SearchModule } from './search/search.module';
import { DOCUMENT_LIST_DIRECTIVES } from './document-list/document-list.module';
import { CONTENT_SEARCH_DIRECTIVES } from './search/search.module';
import { BREADCRUMB_DIRECTIVES } from './breadcrumb/breadcrumb.module';
import { CONTENT_VERSION_DIRECTIVES } from './version-manager/version-manager.module';
import { ContentNodeSelectorModule } from './content-node-selector/content-node-selector.module';
import { CONTENT_NODE_SELECTOR_DIRECTIVES } from './content-node-selector/content-node-selector.module';
import { CONTENT_NODE_SHARE_DIRECTIVES } from './content-node-share/content-node-share.module';
import { CONTENT_DIRECTIVES } from './directives/content-directive.module';
import { CONTENT_DIALOG_DIRECTIVES } from './dialogs/dialog.module';
import { CONTENT_METADATA_DIRECTIVES } from './content-metadata/content-metadata.module';
import { CONTENT_PERMISSION_MANAGER_DIRECTIVES } from './permission-manager/permission-manager.module';
import { ContentTypeModule } from './content-type/content-type.module';
import { AspectListModule } from './aspect-list/aspect-list.module';
import { ASPECT_LIST_DIRECTIVES } from './aspect-list/aspect-list.module';
import { versionCompatibilityFactory } from './version-compatibility/version-compatibility-factory';
import { VersionCompatibilityService } from './version-compatibility/version-compatibility.service';
import { CONTENT_PIPES } from './pipes/content-pipe.module';
import { NodeCommentsModule } from './node-comments/node-comments.module';
import { AlfrescoViewerModule } from './viewer/alfresco-viewer.module';
import { contentAuthLoaderFactory } from './auth-loader/content-auth-loader-factory';
import { ContentAuthLoaderService } from './auth-loader/content-auth-loader.service';
import { DropdownSitesComponent } from './content-node-selector/site-dropdown/sites-dropdown.component';
import { CategoriesManagementComponent } from './category';
import { TreeComponent } from './tree';
import { NewVersionUploaderDialogComponent } from './new-version-uploader';
import { VersionCompatibilityDirective } from './version-compatibility';
import { CONTENT_UPLOAD_DIRECTIVES } from './upload';
import { TreeViewComponent } from './tree-view';
import { NodeCommentsComponent } from './node-comments';
import { AlfrescoViewerComponent } from './viewer';
import { ContentTypeDialogComponent } from './content-type';
import { MaterialModule } from './material.module';
@NgModule({
imports: [
...CONTENT_PIPES,
CoreModule,
...CONTENT_TAG_DIRECTIVES,
CommonModule,
FormsModule,
ReactiveFormsModule,
...CONTENT_DIALOG_DIRECTIVES,
SearchModule,
DocumentListModule,
...CONTENT_UPLOAD_DIRECTIVES,
MaterialModule,
DropdownSitesComponent,
MatDatetimepickerModule,
MatNativeDatetimeModule,
...CONTENT_PIPES,
...CONTENT_TAG_DIRECTIVES,
...CONTENT_DIALOG_DIRECTIVES,
...CONTENT_SEARCH_DIRECTIVES,
...DOCUMENT_LIST_DIRECTIVES,
...CONTENT_UPLOAD_DIRECTIVES,
...BREADCRUMB_DIRECTIVES,
ContentNodeSelectorModule,
...CONTENT_NODE_SELECTOR_DIRECTIVES,
...CONTENT_NODE_SHARE_DIRECTIVES,
...CONTENT_METADATA_DIRECTIVES,
...CONTENT_DIRECTIVES,
...CONTENT_PERMISSION_MANAGER_DIRECTIVES,
...CONTENT_VERSION_DIRECTIVES,
TreeViewComponent,
ContentTypeModule,
AspectListModule,
ContentTypeDialogComponent,
...ASPECT_LIST_DIRECTIVES,
VersionCompatibilityDirective,
NodeCommentsModule,
NodeCommentsComponent,
TreeComponent,
SearchTextModule,
AlfrescoViewerModule,
AlfrescoViewerComponent,
CategoriesManagementComponent,
NewVersionUploaderDialogComponent
],
providers: [provideTranslations('adf-content-services', 'assets/adf-content-services')],
exports: [
MaterialModule,
...CONTENT_PIPES,
...CONTENT_TAG_DIRECTIVES,
DocumentListModule,
...DOCUMENT_LIST_DIRECTIVES,
...CONTENT_UPLOAD_DIRECTIVES,
SearchModule,
DropdownSitesComponent,
...CONTENT_SEARCH_DIRECTIVES,
...BREADCRUMB_DIRECTIVES,
ContentNodeSelectorModule,
...CONTENT_NODE_SELECTOR_DIRECTIVES,
...CONTENT_NODE_SHARE_DIRECTIVES,
...CONTENT_METADATA_DIRECTIVES,
...CONTENT_DIALOG_DIRECTIVES,
@@ -97,13 +91,12 @@ import { TreeViewComponent } from './tree-view';
...CONTENT_PERMISSION_MANAGER_DIRECTIVES,
...CONTENT_VERSION_DIRECTIVES,
TreeViewComponent,
AspectListModule,
ContentTypeModule,
...ASPECT_LIST_DIRECTIVES,
ContentTypeDialogComponent,
VersionCompatibilityDirective,
NodeCommentsModule,
NodeCommentsComponent,
TreeComponent,
SearchTextModule,
AlfrescoViewerModule,
AlfrescoViewerComponent,
CategoriesManagementComponent,
NewVersionUploaderDialogComponent
]
@@ -131,6 +124,10 @@ export class ContentModule {
};
}
/**
* @deprecated use `ContentModule` instead
* @returns ModuleWithProviders<ContentModule>
*/
static forChild(): ModuleWithProviders<ContentModule> {
return {
ngModule: ContentModule

View File

@@ -20,7 +20,6 @@ import { ContentService } from '../common/services/content.service';
import { CheckAllowableOperationDirective } from './check-allowable-operation.directive';
import { TestBed } from '@angular/core/testing';
import { NodeAllowableOperationSubject } from '../interfaces/node-allowable-operation-subject.interface';
import { ContentDirectiveModule } from './content-directive.module';
import { RedirectAuthService } from '@alfresco/adf-core';
import { EMPTY, of } from 'rxjs';
import { HttpClientTestingModule } from '@angular/common/http/testing';
@@ -38,7 +37,7 @@ describe('CheckAllowableOperationDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentDirectiveModule, HttpClientTestingModule],
imports: [HttpClientTestingModule],
providers: [{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }]
});
changeDetectorMock = { detectChanges: () => {} } as ChangeDetectorRef;

View File

@@ -20,7 +20,6 @@ import { LibraryMembershipDirective } from './library-membership.directive';
import { SimpleChange } from '@angular/core';
import { of, throwError, Subject } from 'rxjs';
import { AlfrescoApiService, AlfrescoApiServiceMock } from '@alfresco/adf-core';
import { ContentDirectiveModule } from './content-directive.module';
import { SitesService } from '../common/services/sites.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
@@ -38,7 +37,7 @@ describe('LibraryMembershipDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, ContentDirectiveModule],
imports: [HttpClientTestingModule],
providers: [SitesService, { provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }]
});

View File

@@ -19,13 +19,15 @@ import { Component, DebugElement, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NodeDeleteDirective } from './node-delete.directive';
import { ContentDirectiveModule } from './content-directive.module';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TranslateModule } from '@ngx-translate/core';
import { RedirectAuthService, TranslationMock, TranslationService } from '@alfresco/adf-core';
import { EMPTY, of } from 'rxjs';
import { CheckAllowableOperationDirective } from './check-allowable-operation.directive';
@Component({
standalone: true,
imports: [NodeDeleteDirective],
template: `<div id="delete-component" [adf-delete]="selection" (delete)="onDelete()"></div>`
})
class TestComponent {
@@ -38,10 +40,12 @@ class TestComponent {
}
@Component({
template: `<div id="delete-component" [adf-check-allowable-operation]="selection" [adf-delete]="selection" (delete)="onDelete($event)"></div>`
standalone: true,
imports: [NodeDeleteDirective, CheckAllowableOperationDirective],
template: `<div id="delete-component" [adf-check-allowable-operation]="'delete'" [adf-delete]="selection" (delete)="onDelete($event)"></div>`
})
class TestWithPermissionsComponent {
selection = [];
selection: any[] = [];
@ViewChild(NodeDeleteDirective, { static: true })
deleteDirective: NodeDeleteDirective;
@@ -50,6 +54,8 @@ class TestWithPermissionsComponent {
}
@Component({
standalone: true,
imports: [NodeDeleteDirective],
template: ` delete permanent
<div id="delete-permanent" [adf-delete]="selection" [permanent]="permanent" (delete)="onDelete($event)"></div>`
})
@@ -79,12 +85,11 @@ describe('NodeDeleteDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentDirectiveModule, HttpClientTestingModule, TranslateModule.forRoot()],
imports: [HttpClientTestingModule, TranslateModule.forRoot(), TestComponent, TestWithPermissionsComponent, TestDeletePermanentComponent],
providers: [
{ provide: TranslationService, useClass: TranslationMock },
{ provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of() } }
],
declarations: [TestComponent, TestWithPermissionsComponent, TestDeletePermanentComponent]
]
});
fixture = TestBed.createComponent(TestComponent);
fixtureWithPermissions = TestBed.createComponent(TestWithPermissionsComponent);

View File

@@ -21,18 +21,20 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog';
import { Component, DebugElement, ViewChild } from '@angular/core';
import { AlfrescoApiService, AlfrescoApiServiceMock } from '@alfresco/adf-core';
import { NodeDownloadDirective } from './node-download.directive';
import { ContentDirectiveModule } from '@alfresco/adf-content-services';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ContentApi } from '@alfresco/js-api';
@Component({
standalone: true,
imports: [NodeDownloadDirective],
template: '<div [adfNodeDownload]="selection" [version]="version"></div>'
})
class TestComponent {
@ViewChild(NodeDownloadDirective, { static: true })
downloadDirective: NodeDownloadDirective;
selection;
version;
selection: any[];
version: any;
}
describe('NodeDownloadDirective', () => {
@@ -41,8 +43,9 @@ describe('NodeDownloadDirective', () => {
let element: DebugElement;
let dialog: MatDialog;
let apiService: AlfrescoApiService;
let contentService;
let dialogSpy;
let contentService: ContentApi;
let dialogSpy: jasmine.Spy;
const mockOauth2Auth: any = {
oauth2Auth: {
callCustomApi: () => Promise.resolve()
@@ -53,8 +56,7 @@ describe('NodeDownloadDirective', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentDirectiveModule, HttpClientTestingModule, MatDialogModule],
declarations: [TestComponent],
imports: [HttpClientTestingModule, MatDialogModule, TestComponent],
providers: [{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }]
});
fixture = TestBed.createComponent(TestComponent);
@@ -62,7 +64,7 @@ describe('NodeDownloadDirective', () => {
element = fixture.debugElement.query(By.directive(NodeDownloadDirective));
dialog = TestBed.inject(MatDialog);
apiService = TestBed.inject(AlfrescoApiService);
contentService = component.downloadDirective['contentApi'];
contentService = component.downloadDirective.contentApi;
dialogSpy = spyOn(dialog, 'open');
});

View File

@@ -20,15 +20,17 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { NodeRestoreDirective } from './node-restore.directive';
import { TranslationMock, TranslationService } from '@alfresco/adf-core';
import { ContentDirectiveModule } from './content-directive.module';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { TranslateModule } from '@ngx-translate/core';
import { TrashcanApi } from '@alfresco/js-api';
@Component({
standalone: true,
imports: [NodeRestoreDirective],
template: ` <div [adf-restore]="selection" (restore)="doneSpy()"></div>`
})
class TestComponent {
selection = [];
selection: any[] = [];
doneSpy = jasmine.createSpy('doneSpy');
}
@@ -37,25 +39,24 @@ describe('NodeRestoreDirective', () => {
let fixture: ComponentFixture<TestComponent>;
let element: DebugElement;
let component: TestComponent;
let trashcanApi;
let directiveInstance;
let trashcanApi: TrashcanApi;
let directiveInstance: NodeRestoreDirective;
let restoreNodeSpy: any;
let translationService: TranslationService;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentDirectiveModule, HttpClientTestingModule, TranslateModule.forRoot()],
providers: [{ provide: TranslationService, useClass: TranslationMock }],
declarations: [TestComponent]
imports: [HttpClientTestingModule, TranslateModule.forRoot(), TestComponent],
providers: [{ provide: TranslationService, useClass: TranslationMock }]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
element = fixture.debugElement.query(By.directive(NodeRestoreDirective));
directiveInstance = element.injector.get(NodeRestoreDirective);
trashcanApi = directiveInstance['trashcanApi'];
trashcanApi = directiveInstance.trashcanApi;
restoreNodeSpy = spyOn(trashcanApi, 'restoreDeletedNode').and.returnValue(Promise.resolve());
restoreNodeSpy = spyOn(trashcanApi, 'restoreDeletedNode').and.returnValue(Promise.resolve({} as any));
spyOn(trashcanApi, 'listDeletedNodes').and.returnValue(
Promise.resolve({
list: { entries: [] }
@@ -115,16 +116,6 @@ describe('NodeRestoreDirective', () => {
});
});
it('should reset status', () => {
directiveInstance.restoreProcessStatus.fail = [{}];
directiveInstance.restoreProcessStatus.success = [{}];
directiveInstance.restoreProcessStatus.reset();
expect(directiveInstance.restoreProcessStatus.fail).toEqual([]);
expect(directiveInstance.restoreProcessStatus.success).toEqual([]);
});
it('should emit event on finish', (done) => {
spyOn(element.nativeElement, 'dispatchEvent');

View File

@@ -15,21 +15,19 @@
* limitations under the License.
*/
/* eslint-disable @angular-eslint/component-selector */
/* eslint-disable @angular-eslint/component-selector */
import { Component } from '@angular/core';
import { ContentActionModel } from './../../models/content-action.model';
import { DocumentListComponent } from './../document-list.component';
@Component({
selector: 'content-actions',
template: ''
template: '',
standalone: true
})
export class ContentActionListComponent {
constructor(private documentList: DocumentListComponent) {
}
constructor(private documentList: DocumentListComponent) {}
/**
* Registers action handler within the parent document list component.

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
/* eslint-disable @angular-eslint/component-selector */
/* eslint-disable @angular-eslint/component-selector */
import { Component, EventEmitter, Input, OnInit, Output, OnChanges, SimpleChanges, OnDestroy } from '@angular/core';
@@ -28,14 +28,11 @@ import { Subscription } from 'rxjs';
@Component({
selector: 'content-action',
standalone: true,
template: '',
providers: [
DocumentActionsService,
FolderActionsService
]
providers: [DocumentActionsService, FolderActionsService]
})
export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
/** The title of the action as shown in the menu. */
@Input()
title: string = 'Action';
@@ -98,8 +95,8 @@ export class ContentActionComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private list: ContentActionListComponent,
private documentActions: DocumentActionsService,
private folderActions: FolderActionsService) {
}
private folderActions: FolderActionsService
) {}
ngOnInit() {
if (this.target === ContentActionTarget.All) {

View File

@@ -18,11 +18,11 @@
import {
AppConfigService,
AuthenticationService,
CustomLoadingContentTemplateDirective,
DataColumn,
DataColumnComponent,
DataColumnListComponent,
DataTableComponent,
DataTableModule,
ObjectDataTableAdapter,
ShowHeaderMode,
ThumbnailService
@@ -56,13 +56,13 @@ import { ImageResolver } from '../data/image-resolver.model';
import { RowFilter } from '../data/row-filter.model';
import { ShareDataRow } from '../data/share-data-row.model';
import { ShareDataTableAdapter } from '../data/share-datatable-adapter';
import { DocumentListModule } from '../document-list.module';
import { ContentActionModel } from '../models/content-action.model';
import { DocumentLoaderNode } from '../models/document-folder.model';
import { MatDialog } from '@angular/material/dialog';
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
import { DocumentListComponent } from './document-list.component';
import { CustomResourcesService, DocumentListService } from '../public-api';
import { CommonModule } from '@angular/common';
const mockDialog = {
open: jasmine.createSpy('open')
@@ -87,7 +87,7 @@ describe('DocumentList', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
imports: [ContentTestingModule, DocumentListComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [{ provide: MatDialog, useValue: mockDialog }]
});
@@ -109,7 +109,7 @@ describe('DocumentList', () => {
spyFolder = spyOn(documentListService, 'getFolder').and.returnValue(of({ list: {} }));
spyFolderNode = spyOn(documentListService, 'getFolderNode').and.returnValue(of(new NodeEntry({ entry: new Node() })));
spyOn(documentList['nodesApi'], 'getNode').and.returnValue(Promise.resolve(new NodeEntry({ entry: new Node() })));
spyOn(documentList.nodesApi, 'getNode').and.returnValue(Promise.resolve(new NodeEntry({ entry: new Node() })));
documentList.ngOnInit();
documentList.currentFolderId = 'no-node';
@@ -1608,6 +1608,9 @@ describe('DocumentList', () => {
});
it('should display fileAutoDownload dialog if node size exceeds appConfig.viewer.fileAutoDownloadSizeThresholdInMB', async () => {
const dialog = fixture.debugElement.injector.get(MatDialog);
spyOn(dialog, 'open').and.stub();
appConfigService.config = {
...appConfigService.config,
viewer: {
@@ -1630,7 +1633,7 @@ describe('DocumentList', () => {
fixture.detectChanges();
await fixture.whenStable();
expect(mockDialog.open).toHaveBeenCalledWith(FileAutoDownloadComponent, { disableClose: true, data: node });
expect(dialog.open).toHaveBeenCalledWith(FileAutoDownloadComponent, { disableClose: true, data: node });
});
describe('Preselect nodes', () => {
@@ -1870,6 +1873,8 @@ describe('DocumentList', () => {
});
@Component({
standalone: true,
imports: [CommonModule, DocumentListComponent, CustomLoadingContentTemplateDirective],
template: `
<adf-document-list #customDocumentList>
<adf-custom-loading-content-template>
@@ -1896,8 +1901,7 @@ describe('DocumentListComponent rendering', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [CustomTemplateComponent],
imports: [ContentTestingModule, DataTableModule, DocumentListModule]
imports: [ContentTestingModule, CustomTemplateComponent]
});
fixture = TestBed.createComponent(CustomTemplateComponent);
component = fixture.componentInstance;

View File

@@ -21,6 +21,7 @@
import {
AlfrescoApiService,
AppConfigService,
ColumnsSelectorComponent,
CustomEmptyContentTemplateDirective,
CustomLoadingContentTemplateDirective,
CustomNoPermissionTemplateDirective,
@@ -33,6 +34,11 @@ import {
DataTableComponent,
DataTableSchema,
DataTableService,
EmptyListComponent,
LoadingContentTemplateDirective,
MainMenuDataTableTemplateDirective,
NoContentTemplateDirective,
NoPermissionTemplateDirective,
PaginatedComponent,
PaginationModel,
RequestPaginationModel,
@@ -75,11 +81,31 @@ import { LockService } from '../services/lock.service';
import { ADF_DOCUMENT_PARENT_COMPONENT } from './document-list.token';
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
import { NodeEntityEvent, NodeEntryEvent } from './node.event';
import { CommonModule } from '@angular/common';
import { FilterHeaderComponent } from './filter-header/filter-header.component';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
const BYTES_TO_MB_CONVERSION_VALUE = 1048576;
@Component({
selector: 'adf-document-list',
standalone: true,
imports: [
CommonModule,
DataTableComponent,
FilterHeaderComponent,
NoContentTemplateDirective,
EmptyListComponent,
TranslateModule,
NoPermissionTemplateDirective,
MatIconModule,
LoadingContentTemplateDirective,
MatProgressSpinnerModule,
MainMenuDataTableTemplateDirective,
ColumnsSelectorComponent
],
templateUrl: './document-list.component.html',
styleUrls: ['./document-list.component.scss'],
providers: [

View File

@@ -23,7 +23,7 @@ import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';
import { TranslationMock, TranslationService } from '@alfresco/adf-core';
import { MatButtonModule } from '@angular/material/button';
import { NodeDownloadDirective } from '../../../directives';
import { NodeDownloadDirective } from '../../../directives/node-download.directive';
import { HttpClientTestingModule } from '@angular/common/http/testing';
const mockDialog = {
@@ -37,8 +37,14 @@ describe('FileAutoDownloadComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, TranslateModule.forRoot(), MatDialogModule, MatButtonModule, NodeDownloadDirective],
declarations: [FileAutoDownloadComponent],
imports: [
HttpClientTestingModule,
TranslateModule.forRoot(),
MatDialogModule,
MatButtonModule,
NodeDownloadDirective,
FileAutoDownloadComponent
],
providers: [
{ provide: MatDialogRef, useValue: mockDialog },
{ provide: MAT_DIALOG_DATA, useValue: null },

View File

@@ -16,12 +16,18 @@
*/
import { Component, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { NodeEntry } from '@alfresco/js-api';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { NodeDownloadDirective } from '../../../directives/node-download.directive';
@Component({
selector: 'adf-file-auto-download',
templateUrl: './file-auto-download.component.html'
selector: 'adf-file-auto-download',
standalone: true,
imports: [CommonModule, MatDialogModule, TranslateModule, MatButtonModule, NodeDownloadDirective],
templateUrl: './file-auto-download.component.html'
})
export class FileAutoDownloadComponent {
constructor(@Inject(MAT_DIALOG_DATA) public node: NodeEntry) {}

View File

@@ -48,7 +48,7 @@ describe('FilterHeaderComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
imports: [ContentTestingModule, FilterHeaderComponent],
providers: [
{ provide: ADF_DOCUMENT_PARENT_COMPONENT, useExisting: DocumentListComponent },
{ provide: SearchService, useValue: searchMock },

View File

@@ -16,15 +16,19 @@
*/
import { Component, Inject, OnInit, OnChanges, SimpleChanges, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
import { PaginationModel, DataSorting } from '@alfresco/adf-core';
import { PaginationModel, DataSorting, HeaderFilterTemplateDirective } from '@alfresco/adf-core';
import { SearchHeaderQueryBuilderService } from '../../../search/services/search-header-query-builder.service';
import { FilterSearch } from './../../../search/models/filter-search.interface';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ADF_DOCUMENT_PARENT_COMPONENT } from '../document-list.token';
import { CommonModule } from '@angular/common';
import { SearchFilterContainerComponent } from '../../../search/components/search-filter-container/search-filter-container.component';
@Component({
selector: 'adf-filter-header',
standalone: true,
imports: [CommonModule, HeaderFilterTemplateDirective, SearchFilterContainerComponent],
templateUrl: './filter-header.component.html'
})
export class FilterHeaderComponent implements OnInit, OnChanges, OnDestroy {

View File

@@ -27,7 +27,7 @@ describe('LibraryNameColumnComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
imports: [ContentTestingModule, LibraryNameColumnComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
});
node = {

View File

@@ -22,9 +22,13 @@ import { NodesApiService } from '../../../common/services/nodes-api.service';
import { BehaviorSubject, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-library-name-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span
role="link"

View File

@@ -26,7 +26,7 @@ describe('LibraryRoleColumnComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule],
imports: [ContentTestingModule, LibraryRoleColumnComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA]
});
fixture = TestBed.createComponent(LibraryRoleColumnComponent);

View File

@@ -21,9 +21,13 @@ import { SiteEntry, Site } from '@alfresco/js-api';
import { ShareDataRow } from '../../data/share-data-row.model';
import { takeUntil } from 'rxjs/operators';
import { NodesApiService } from '../../../common/services/nodes-api.service';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-library-role-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span class="adf-datatable-cell-value" title="{{ displayText$ | async | translate }}">
{{ displayText$ | async | translate }}

View File

@@ -21,9 +21,13 @@ import { BehaviorSubject, Subject } from 'rxjs';
import { Site, SiteEntry } from '@alfresco/js-api';
import { ShareDataRow } from '../../data/share-data-row.model';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-library-status-column',
standalone: true,
imports: [CommonModule, TranslateModule],
template: `
<span class="adf-datatable-cell-value" title="{{ displayText$ | async | translate }}">
{{ displayText$ | async | translate }}

View File

@@ -27,7 +27,7 @@ describe('NameColumnComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule]
imports: [ContentTestingModule, NameColumnComponent]
});
fixture = TestBed.createComponent(NameColumnComponent);

View File

@@ -21,9 +21,14 @@ import { BehaviorSubject, Subject } from 'rxjs';
import { NodesApiService } from '../../../common/services/nodes-api.service';
import { ShareDataRow } from '../../data/share-data-row.model';
import { takeUntil } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { NodeNameTooltipPipe } from '../../../pipes/node-name-tooltip.pipe';
@Component({
selector: 'adf-name-column',
standalone: true,
imports: [CommonModule, TranslateModule, NodeNameTooltipPipe],
template: `
<span
role="link"

View File

@@ -18,9 +18,13 @@
import { Component, ChangeDetectionStrategy, ViewEncapsulation, OnInit, Input } from '@angular/core';
import { NodeEntry } from '@alfresco/js-api';
import { ShareDataRow } from '../../data/share-data-row.model';
import { CommonModule } from '@angular/common';
import { NodeNameTooltipPipe } from '../../../pipes/node-name-tooltip.pipe';
@Component({
selector: 'adf-trashcan-name-column',
standalone: true,
imports: [CommonModule, NodeNameTooltipPipe],
template: `
<ng-container *ngIf="!isLibrary">
<span class="adf-datatable-cell-value" title="{{ node | adfNodeNameTooltip }}">{{ displayText }}</span>

View File

@@ -15,18 +15,10 @@
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { CoreModule, EditJsonDialogModule } from '@alfresco/adf-core';
import { MaterialModule } from '../material.module';
import { UploadModule } from '../upload/upload.module';
import { SearchModule } from './../search/search.module';
import { ContentActionListComponent } from './components/content-action/content-action-list.component';
import { ContentActionComponent } from './components/content-action/content-action.component';
import { DocumentListComponent } from './components/document-list.component';
import { TrashcanNameColumnComponent } from './components/trashcan-name-column/trashcan-name-column.component';
import { LibraryStatusColumnComponent } from './components/library-status-column/library-status-column.component';
import { LibraryRoleColumnComponent } from './components/library-role-column/library-role-column.component';
@@ -34,42 +26,23 @@ import { LibraryNameColumnComponent } from './components/library-name-column/lib
import { NameColumnComponent } from './components/name-column/name-column.component';
import { FilterHeaderComponent } from './components/filter-header/filter-header.component';
import { FileAutoDownloadComponent } from './components/file-auto-download/file-auto-download.component';
import { ContentDirectiveModule } from '../directives/content-directive.module';
import { NodeNameTooltipPipe } from '../pipes';
export const DOCUMENT_LIST_DIRECTIVES = [
ContentActionComponent,
FileAutoDownloadComponent,
FilterHeaderComponent,
LibraryNameColumnComponent,
LibraryRoleColumnComponent,
LibraryStatusColumnComponent,
NameColumnComponent,
TrashcanNameColumnComponent,
ContentActionListComponent,
DocumentListComponent
] as const;
/** @deprecated use `...DOCUMENT_LIST_DIRECTIVES` or import standalone components */
@NgModule({
imports: [
CoreModule,
CommonModule,
MaterialModule,
UploadModule,
EditJsonDialogModule,
SearchModule,
ContentDirectiveModule,
NodeNameTooltipPipe
],
declarations: [
DocumentListComponent,
TrashcanNameColumnComponent,
LibraryStatusColumnComponent,
LibraryRoleColumnComponent,
LibraryNameColumnComponent,
NameColumnComponent,
ContentActionComponent,
ContentActionListComponent,
FilterHeaderComponent,
FileAutoDownloadComponent
],
exports: [
DocumentListComponent,
TrashcanNameColumnComponent,
LibraryStatusColumnComponent,
LibraryRoleColumnComponent,
LibraryNameColumnComponent,
NameColumnComponent,
ContentActionComponent,
ContentActionListComponent,
FilterHeaderComponent
]
imports: [...DOCUMENT_LIST_DIRECTIVES],
exports: [...DOCUMENT_LIST_DIRECTIVES]
})
export class DocumentListModule {}

View File

@@ -24,6 +24,8 @@ export interface NewVersionUploaderDialogData {
file?: File;
currentVersion?: Version;
showVersionsOnly?: boolean;
showComments?: boolean;
allowDownload?: boolean;
}
export type NewVersionUploaderData = VersionManagerUploadData | ViewVersion | RefreshData;

View File

@@ -18,8 +18,8 @@
<div class="adf-version-list-table">
<adf-version-list
[node]="data.node"
[showComments]="'adf-version-manager.allowComments' | adfAppConfig: true"
[allowDownload]="'adf-version-manager.allowDownload' | adfAppConfig: true"
[showComments]="data.showComments"
[allowDownload]="data.allowDownload"
(deleted)="refresh($event)"
(restored)="refresh($event)"
(viewVersion)="onViewingVersion($event)"

View File

@@ -20,15 +20,24 @@ import { Component, EventEmitter, Inject, OnInit, Output, ViewEncapsulation } fr
import { MatDialogRef, MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import { NewVersionUploaderDialogData, NewVersionUploaderData, NewVersionUploaderDataAction } from './models';
import { CommonModule } from '@angular/common';
import { VersionManagerModule } from '../version-manager';
import { AppConfigPipe } from '@alfresco/adf-core';
import { VersionComparisonComponent } from '../version-manager/version-comparison.component';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { VersionUploadComponent } from '../version-manager/version-upload.component';
import { VersionListComponent } from '../version-manager/version-list.component';
@Component({
selector: 'adf-new-version-uploader-dialog',
standalone: true,
imports: [CommonModule, VersionManagerModule, MatDialogModule, AppConfigPipe, TranslateModule, MatButtonModule],
imports: [
CommonModule,
MatDialogModule,
TranslateModule,
MatButtonModule,
VersionComparisonComponent,
VersionUploadComponent,
VersionListComponent
],
templateUrl: './new-version-uploader.dialog.html',
styleUrls: ['./new-version-uploader.dialog.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -85,7 +85,9 @@ describe('NewVersionUploaderService', () => {
);
mockNewVersionUploaderDialogData = {
node: mockNode,
file: mockFile
file: mockFile,
showComments: true,
allowDownload: true
};
});
@@ -170,7 +172,9 @@ describe('NewVersionUploaderService', () => {
const mockNewVersionUploaderDialogDataWithVersionsOnly = {
node: mockNode,
file: mockFile,
showVersionsOnly: true
showVersionsOnly: true,
showComments: true,
allowDownload: true
};
service.openUploadNewVersionDialog(mockNewVersionUploaderDialogDataWithVersionsOnly).toPromise();
tick();

View File

@@ -18,9 +18,8 @@
import { Injectable } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { AlfrescoApiService } from '@alfresco/adf-core';
import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog';
import { VersionPaging, VersionsApi } from '@alfresco/js-api';
import { VersionsApi } from '@alfresco/js-api';
import { NewVersionUploaderData, NewVersionUploaderDialogData } from './models';
import { Observable } from 'rxjs';
import { OverlayContainer } from '@angular/cdk/overlay';
@@ -53,18 +52,19 @@ export class NewVersionUploaderService {
config?: MatDialogConfig,
selectorAutoFocusedOnClose?: string
): Observable<NewVersionUploaderData> {
const { file, node, showVersionsOnly } = data;
const showComments = true;
const allowDownload = true;
const { file, node, showVersionsOnly, showComments, allowDownload } = data;
return new Observable((observer) => {
this.versionsApi.listVersionHistory(node.id).then((versionPaging: VersionPaging) => {
const dialogRef = this.dialog.open(NewVersionUploaderDialogComponent, {
data: { file, node, currentVersion: versionPaging.list.entries[0].entry, showComments, allowDownload, showVersionsOnly },
panelClass: this.composePanelClass(showVersionsOnly),
width: '630px',
...(config && Object.keys(config).length > 0 && config)
});
this.versionsApi.listVersionHistory(node.id).then((versionPaging) => {
const dialogRef = this.dialog.open<NewVersionUploaderDialogComponent, NewVersionUploaderDialogData>(
NewVersionUploaderDialogComponent,
{
data: { file, node, currentVersion: versionPaging.list.entries[0].entry, showComments, allowDownload, showVersionsOnly },
panelClass: this.composePanelClass(showVersionsOnly),
width: '630px',
...(config && Object.keys(config).length > 0 && config)
}
);
dialogRef.componentInstance.dialogAction.asObservable().subscribe((newVersionUploaderData) => {
observer.next(newVersionUploaderData);
});

View File

@@ -16,20 +16,23 @@
*/
import { Component, Input, ViewEncapsulation } from '@angular/core';
import { ADF_COMMENTS_SERVICE } from '@alfresco/adf-core';
import { ADF_COMMENTS_SERVICE, CommentsComponent } from '@alfresco/adf-core';
import { NodeCommentsService } from './services/node-comments.service';
@Component({
selector: 'adf-node-comments',
standalone: true,
imports: [CommentsComponent],
templateUrl: './node-comments.component.html',
encapsulation: ViewEncapsulation.None,
providers: [{
provide: ADF_COMMENTS_SERVICE,
useClass: NodeCommentsService
}]
providers: [
{
provide: ADF_COMMENTS_SERVICE,
useClass: NodeCommentsService
}
]
})
export class NodeCommentsComponent {
/** nodeId of the document that has comments */
@Input()
nodeId: string;

View File

@@ -16,13 +16,11 @@
*/
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { NodeCommentsComponent } from './node-comments.component';
import { CoreModule } from '@alfresco/adf-core';
/** @deprecated import NodeCommentsComponent standalone component directly */
@NgModule({
imports: [CommonModule, CoreModule],
declarations: [NodeCommentsComponent],
imports: [NodeCommentsComponent],
exports: [NodeCommentsComponent]
})
export class NodeCommentsModule {}

View File

@@ -16,7 +16,5 @@
*/
export * from './node-comments.component';
export * from './services/node-comments.service';
export * from './node-comments.module';

View File

@@ -29,7 +29,6 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { SearchModule } from '../../../search';
import { UserIconColumnComponent } from '../user-icon-column/user-icon-column.component';
@Component({
@@ -42,9 +41,9 @@ import { UserIconColumnComponent } from '../user-icon-column/user-icon-column.co
TranslateModule,
ReactiveFormsModule,
MatIconModule,
SearchModule,
MatListModule,
UserIconColumnComponent
UserIconColumnComponent,
SearchComponent
],
templateUrl: './add-permission-panel.component.html',
styleUrls: ['./add-permission-panel.component.scss'],

View File

@@ -19,6 +19,7 @@ import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'adf-empty-search-result',
standalone: true,
templateUrl: './empty-search-result.component.html',
encapsulation: ViewEncapsulation.None
})

View File

@@ -19,7 +19,8 @@ import { Directive, HostListener } from '@angular/core';
import { SearchFacetFiltersService } from '../services/search-facet-filters.service';
@Directive({
selector: '[adf-reset-search]'
selector: '[adf-reset-search]',
standalone: true
})
export class ResetSearchDirective {
@HostListener('click')
@@ -27,5 +28,5 @@ export class ResetSearchDirective {
this.filterService.reset();
}
constructor(private filterService: SearchFacetFiltersService) { }
constructor(private filterService: SearchFacetFiltersService) {}
}

View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { AuthenticationService, ThumbnailService, SearchTextInputComponent } from '@alfresco/adf-core';
import { AuthenticationService, ThumbnailService, SearchTextInputComponent, HighlightPipe } from '@alfresco/adf-core';
import {
Component,
EventEmitter,
@@ -32,11 +32,16 @@ import {
import { NodeEntry } from '@alfresco/js-api';
import { Subject } from 'rxjs';
import { SearchComponent } from './search.component';
import { MatListItem } from '@angular/material/list';
import { MatListItem, MatListModule } from '@angular/material/list';
import { EmptySearchResultComponent } from './empty-search-result.component';
import { CommonModule } from '@angular/common';
import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-search-control',
standalone: true,
imports: [CommonModule, SearchTextInputComponent, SearchComponent, MatListModule, MatIconModule, HighlightPipe, TranslateModule],
templateUrl: './search-control.component.html',
styleUrls: ['./search-control.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -61,8 +61,7 @@ describe('SearchDateRangeTabbedComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchDateRangeTabbedComponent, SearchFilterTabbedComponent, SearchDateRangeComponent],
imports: [ContentTestingModule],
imports: [ContentTestingModule, SearchFilterTabbedComponent, SearchDateRangeComponent, SearchDateRangeTabbedComponent],
providers: [
{ provide: SearchFilterTabbedComponent, useClass: MockSearchFilterTabbedComponent },
{ provide: SearchDateRangeComponent, useClass: MockSearchDateRangeComponent }

View File

@@ -25,14 +25,20 @@ import { SearchQueryBuilderService } from '../../services/search-query-builder.s
import { InLastDateType } from './search-date-range/in-last-date-type';
import { TranslationService } from '@alfresco/adf-core';
import { endOfDay, endOfToday, format, formatISO, startOfDay, startOfMonth, startOfWeek, subDays, subMonths, subWeeks } from 'date-fns';
import { CommonModule } from '@angular/common';
import { SearchFilterTabbedComponent } from '../search-filter-tabbed/search-filter-tabbed.component';
import { SearchDateRangeComponent } from './search-date-range/search-date-range.component';
import { SearchFilterTabDirective } from '../search-filter-tabbed/search-filter-tab.directive';
const DEFAULT_DATE_DISPLAY_FORMAT = 'dd-MMM-yy';
@Component({
selector: 'adf-search-date-range-tabbed',
templateUrl: './search-date-range-tabbed.component.html',
styleUrls: [ './search-date-range-tabbed.component.scss'],
encapsulation: ViewEncapsulation.None
selector: 'adf-search-date-range-tabbed',
standalone: true,
imports: [CommonModule, SearchFilterTabbedComponent, SearchDateRangeComponent, SearchFilterTabDirective],
templateUrl: './search-date-range-tabbed.component.html',
styleUrls: ['./search-date-range-tabbed.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class SearchDateRangeTabbedComponent implements SearchWidget, OnInit {
displayValue$ = new Subject<string>();

View File

@@ -36,8 +36,7 @@ describe('SearchDateRangeComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchDateRangeComponent],
imports: [ContentTestingModule]
imports: [ContentTestingModule, SearchDateRangeComponent]
});
fixture = TestBed.createComponent(SearchDateRangeComponent);

View File

@@ -23,22 +23,40 @@ import { DateFnsAdapter, MAT_DATE_FNS_FORMATS } from '@angular/material-date-fns
import { InLastDateType } from './in-last-date-type';
import { DateRangeType } from './date-range-type';
import { SearchDateRange } from './search-date-range';
import { FormBuilder, UntypedFormControl, Validators } from '@angular/forms';
import { FormBuilder, ReactiveFormsModule, UntypedFormControl, Validators } from '@angular/forms';
import { takeUntil } from 'rxjs/operators';
import { UserPreferencesService, UserPreferenceValues, DateFnsUtils } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { MatRadioModule } from '@angular/material/radio';
import { TranslateModule } from '@ngx-translate/core';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { MatDatepickerModule } from '@angular/material/datepicker';
const DEFAULT_DATE_DISPLAY_FORMAT = 'dd-MMM-yy';
@Component({
selector: 'adf-search-date-range',
standalone: true,
imports: [
CommonModule,
MatRadioModule,
ReactiveFormsModule,
TranslateModule,
MatFormFieldModule,
MatInputModule,
MatSelectModule,
MatDatepickerModule
],
templateUrl: './search-date-range.component.html',
styleUrls: ['./search-date-range.component.scss'],
providers: [
{ provide: DateAdapter, useClass: DateFnsAdapter, deps: [ MAT_DATE_LOCALE ] },
{ provide: DateAdapter, useClass: DateFnsAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MAT_DATE_FNS_FORMATS }
],
encapsulation: ViewEncapsulation.None,
host: {class: 'adf-search-date-range'}
host: { class: 'adf-search-date-range' }
})
export class SearchDateRangeComponent implements OnInit, OnDestroy {
@Input()
@@ -74,12 +92,14 @@ export class SearchDateRangeComponent implements OnInit, OnDestroy {
readonly DateRangeType = DateRangeType;
readonly InLastDateType = InLastDateType;
constructor(private formBuilder: FormBuilder,
private userPreferencesService: UserPreferencesService,
private dateAdapter: DateAdapter<DateFnsAdapter>,
@Inject(MAT_DATE_FORMATS) private dateFormatConfig: MatDateFormats) {}
constructor(
private formBuilder: FormBuilder,
private userPreferencesService: UserPreferencesService,
private dateAdapter: DateAdapter<DateFnsAdapter>,
@Inject(MAT_DATE_FORMATS) private dateFormatConfig: MatDateFormats
) {}
readonly endDateValidator = (formControl: UntypedFormControl): ({ [key: string]: boolean } | null) => {
readonly endDateValidator = (formControl: UntypedFormControl): { [key: string]: boolean } | null => {
if (isBefore(formControl.value, this.betweenStartDateFormControl.value) || isAfter(formControl.value, this.convertedMaxDate)) {
return {
invalidDate: true
@@ -90,16 +110,15 @@ export class SearchDateRangeComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.dateFormatConfig.display.dateInput = this.dateFormat;
this.convertedMaxDate = endOfDay(this.maxDate && this.maxDate !== 'today' ?
parse(this.maxDate, this.dateFormat, new Date()) : new Date());
this.convertedMaxDate = endOfDay(this.maxDate && this.maxDate !== 'today' ? parse(this.maxDate, this.dateFormat, new Date()) : new Date());
this.userPreferencesService
.select(UserPreferenceValues.Locale)
.pipe(takeUntil(this.destroy$))
.subscribe(locale => this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale)));
this.form.controls.dateRangeType.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe((locale) => this.dateAdapter.setLocale(DateFnsUtils.getLocaleFromString(locale)));
this.form.controls.dateRangeType.valueChanges
.pipe(takeUntil(this.destroy$))
.subscribe((dateRangeType) => this.updateValidators(dateRangeType));
this.form.valueChanges.pipe(takeUntil(this.destroy$))
.subscribe(() => this.onChange());
this.form.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => this.onChange());
}
ngOnDestroy() {
@@ -108,7 +127,7 @@ export class SearchDateRangeComponent implements OnInit, OnDestroy {
}
private updateValidators(dateRangeType: DateRangeType) {
switch(dateRangeType) {
switch (dateRangeType) {
case DateRangeType.BETWEEN:
this.betweenStartDateFormControl.setValidators(Validators.required);
this.betweenEndDateFormControl.setValidators([Validators.required, this.endDateValidator]);
@@ -140,7 +159,7 @@ export class SearchDateRangeComponent implements OnInit, OnDestroy {
dateChanged(event: Event, formControl: UntypedFormControl) {
if (event?.target['value']?.trim()) {
const date = parse(event.target['value'], this.dateFormat, new Date());
if(!isValid(date)) {
if (!isValid(date)) {
formControl.setErrors({
...formControl.errors,
required: false,
@@ -165,7 +184,7 @@ export class SearchDateRangeComponent implements OnInit, OnDestroy {
}
preventIncorrectNumberCharacters(event: KeyboardEvent): boolean {
switch(event.key) {
switch (event.key) {
case '.':
case '-':
case 'e':

View File

@@ -32,7 +32,7 @@ describe('SearchDatetimeRangeComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ContentTestingModule]
imports: [ContentTestingModule, SearchDatetimeRangeComponent]
});
fixture = TestBed.createComponent(SearchDatetimeRangeComponent);
component = fixture.componentInstance;

View File

@@ -16,16 +16,20 @@
*/
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { FormControl, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
import { ADF_DATE_FORMATS, ADF_DATETIME_FORMATS, AdfDateFnsAdapter, AdfDateTimeFnsAdapter, DateFnsUtils } from '@alfresco/adf-core';
import { SearchWidget } from '../../models/search-widget.interface';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
import { Subject } from 'rxjs';
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerInputEvent } from '@mat-datetimepicker/core';
import { DatetimeAdapter, MAT_DATETIME_FORMATS, MatDatetimepickerInputEvent, MatDatetimepickerModule } from '@mat-datetimepicker/core';
import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core';
import { isValid, isBefore, startOfMinute, endOfMinute } from 'date-fns';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
export interface DatetimeRangeValue {
from: string;
@@ -41,6 +45,8 @@ export const DEFAULT_DATETIME_FORMAT: string = 'dd/MM/yyyy HH:mm';
@Component({
selector: 'adf-search-datetime-range',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, TranslateModule, MatDatetimepickerModule],
templateUrl: './search-datetime-range.component.html',
styleUrls: ['./search-datetime-range.component.scss'],
providers: [
@@ -70,8 +76,7 @@ export class SearchDatetimeRangeComponent implements SearchWidget, OnInit {
enableChangeUpdate: boolean;
displayValue$: Subject<string> = new Subject<string>();
constructor(private dateAdapter: DateAdapter<Date>,
private dateTimeAdapter: DatetimeAdapter<Date>) {}
constructor(private dateAdapter: DateAdapter<Date>, private dateTimeAdapter: DatetimeAdapter<Date>) {}
getFromValidationMessage(): string {
return this.from.hasError('invalidOnChange') || this.hasParseError(this.from)
@@ -235,7 +240,6 @@ export class SearchDatetimeRangeComponent implements SearchWidget, OnInit {
}
setFromMaxDatetime() {
this.fromMaxDatetime =
!this.to.value || (this.maxDatetime && isBefore(this.maxDatetime, this.to.value)) ? this.maxDatetime : this.to.value;
this.fromMaxDatetime = !this.to.value || (this.maxDatetime && isBefore(this.maxDatetime, this.to.value)) ? this.maxDatetime : this.to.value;
}
}

View File

@@ -17,16 +17,25 @@
import { Component, inject, Input, ViewEncapsulation } from '@angular/core';
import { FacetField } from '../../models/facet-field.interface';
import { MatCheckboxChange } from '@angular/material/checkbox';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
import { FacetFieldBucket } from '../../models/facet-field-bucket.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
import { FacetWidget } from '../../models/facet-widget.interface';
import { TranslationService } from '@alfresco/adf-core';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'adf-search-facet-field',
standalone: true,
imports: [CommonModule, MatButtonModule, MatIconModule, MatFormFieldModule, MatInputModule, TranslateModule, FormsModule, MatCheckboxModule],
templateUrl: './search-facet-field.component.html',
styleUrls: ['./search-facet-field.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -30,8 +30,7 @@ describe('SearchFilterAutocompleteChipsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchFilterAutocompleteChipsComponent],
imports: [ContentTestingModule],
imports: [ContentTestingModule, SearchFilterAutocompleteChipsComponent],
providers: [
{
provide: TagService,

View File

@@ -24,9 +24,15 @@ import { SearchFilterList } from '../../models/search-filter-list.model';
import { TagService } from '../../../tag/services/tag.service';
import { CategoryService } from '../../../category/services/category.service';
import { AutocompleteField, AutocompleteOption } from '../../models/autocomplete-option.interface';
import { CommonModule } from '@angular/common';
import { SearchChipAutocompleteInputComponent } from '../search-chip-autocomplete-input';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-search-filter-autocomplete-chips',
standalone: true,
imports: [CommonModule, SearchChipAutocompleteInputComponent, TranslateModule, MatButtonModule],
templateUrl: './search-filter-autocomplete-chips.component.html',
encapsulation: ViewEncapsulation.None
})
@@ -98,19 +104,17 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI
}
optionComparator(option1: AutocompleteOption, option2: AutocompleteOption): boolean {
return option1.id
? option1.id.toUpperCase() === option2.id.toUpperCase()
: option1.value.toUpperCase() === option2.value.toUpperCase();
return option1.id ? option1.id.toUpperCase() === option2.id.toUpperCase() : option1.value.toUpperCase() === option2.value.toUpperCase();
}
private updateQuery() {
this.displayValue$.next(this.selectedOptions.map(option => option.value).join(', '));
this.displayValue$.next(this.selectedOptions.map((option) => option.value).join(', '));
if (this.context && this.settings && this.settings.field) {
let queryFragments;
if (this.settings.field === AutocompleteField.CATEGORIES) {
queryFragments = this.selectedOptions.map(val => `${this.settings.field}:"workspace://SpacesStore/${val.id}"`);
queryFragments = this.selectedOptions.map((val) => `${this.settings.field}:"workspace://SpacesStore/${val.id}"`);
} else {
queryFragments = this.selectedOptions.map(val => val.query ?? `${this.settings.field}:"${val.value}"`);
queryFragments = this.selectedOptions.map((val) => val.query ?? `${this.settings.field}:"${val.value}"`);
}
this.context.queryFragments[this.id] = queryFragments.join(' OR ');
this.context.update();
@@ -120,10 +124,12 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI
private setOptions() {
switch (this.settings.field) {
case AutocompleteField.TAG:
this.tagService.getAllTheTags().subscribe(tagPaging => {
this.autocompleteOptionsSubject$.next(tagPaging.list.entries.map(tag => ({
value: tag.entry.tag
})));
this.tagService.getAllTheTags().subscribe((tagPaging) => {
this.autocompleteOptionsSubject$.next(
tagPaging.list.entries.map((tag) => ({
value: tag.entry.tag
}))
);
});
break;
case AutocompleteField.CATEGORIES:
@@ -136,11 +142,13 @@ export class SearchFilterAutocompleteChipsComponent implements SearchWidget, OnI
private searchForExistingCategories(searchTerm: string) {
this.categoryService.searchCategories(searchTerm, 0, 15).subscribe((existingCategoriesResult) => {
this.autocompleteOptionsSubject$.next(existingCategoriesResult.list.entries.map((rowEntry) => {
const path = rowEntry.entry.path.name.split('/').splice(3).join('/');
const fullPath = path ? `${path}/${rowEntry.entry.name}` : rowEntry.entry.name;
return {id: rowEntry.entry.id, value: rowEntry.entry.name, fullPath};
}));
this.autocompleteOptionsSubject$.next(
existingCategoriesResult.list.entries.map((rowEntry) => {
const path = rowEntry.entry.path.name.split('/').splice(3).join('/');
const fullPath = path ? `${path}/${rowEntry.entry.name}` : rowEntry.entry.name;
return { id: rowEntry.entry.id, value: rowEntry.entry.name, fullPath };
})
);
});
}
}

View File

@@ -1,9 +1,9 @@
<mat-chip-option [attr.data-automation-id]="'search-filter-chip-tabbed-' + tabbedFacet.label"
disableRipple
[disableRipple]="true"
class="adf-search-filter-chip-tabbed"
[class.adf-search-toggle-chip]="displayValue || menuTrigger.menuOpen"
[disabled]="!isPopulated"
tabIndex="0"
tabindex="0"
role="button"
[matMenuTriggerFor]="menu"
(menuOpened)="onMenuOpen()"

View File

@@ -17,12 +17,30 @@
import { ChangeDetectorRef, Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { TabbedFacetField } from '../../../models/tabbed-facet-field.interface';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatChipsModule } from '@angular/material/chips';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { SearchFacetTabbedContentComponent } from './search-facet-tabbed-content.component';
import { MatButtonModule } from '@angular/material/button';
import { SearchFilterMenuCardComponent } from '../search-filter-menu-card/search-filter-menu-card.component';
@Component({
selector: 'adf-search-facet-chip-tabbed',
standalone: true,
imports: [
CommonModule,
MatChipsModule,
MatMenuModule,
TranslateModule,
MatIconModule,
SearchFacetTabbedContentComponent,
MatButtonModule,
SearchFilterMenuCardComponent
],
templateUrl: './search-facet-chip-tabbed.component.html',
styleUrls: ['./search-facet-chip-tabbed.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -24,9 +24,15 @@ import { AutocompleteOption } from '../../../models/autocomplete-option.interfac
import { takeUntil } from 'rxjs/operators';
import { TabbedFacetField } from '../../../models/tabbed-facet-field.interface';
import { SearchFacetFiltersService } from '../../../services/search-facet-filters.service';
import { CommonModule } from '@angular/common';
import { SearchChipAutocompleteInputComponent } from '../../search-chip-autocomplete-input';
import { SearchFilterTabbedComponent } from '../../search-filter-tabbed/search-filter-tabbed.component';
import { SearchFilterTabDirective } from '../../search-filter-tabbed';
@Component({
selector: 'adf-search-facet-tabbed-content',
standalone: true,
imports: [CommonModule, SearchChipAutocompleteInputComponent, SearchFilterTabbedComponent, SearchFilterTabDirective],
templateUrl: './search-facet-tabbed-content.component.html',
encapsulation: ViewEncapsulation.None
})

View File

@@ -1,9 +1,9 @@
<mat-chip-option [attr.data-automation-id]="'search-filter-chip-' + field.label"
disableRipple
[disableRipple]="true"
class="adf-search-filter-chip adf-search-filter-facet-chip"
[class.adf-search-toggle-chip]="(facetField.displayValue$ | async) || menuTrigger.menuOpen"
[disabled]="!isPopulated()"
tabIndex="0"
tabindex="0"
role="button"
[matMenuTriggerFor]="menu"
(menuOpened)="onMenuOpen()"

View File

@@ -18,14 +18,31 @@
import { Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
import { FacetField } from '../../../models/facet-field.interface';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { SearchFacetFieldComponent } from '../../search-facet-field/search-facet-field.component';
import { CommonModule } from '@angular/common';
import { MatChipsModule } from '@angular/material/chips';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { SearchFilterMenuCardComponent } from '../search-filter-menu-card/search-filter-menu-card.component';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-search-facet-chip',
templateUrl: './search-facet-chip.component.html',
styleUrls: ['./search-facet-chip.component.scss'],
encapsulation: ViewEncapsulation.None
selector: 'adf-search-facet-chip',
standalone: true,
imports: [
CommonModule,
MatChipsModule,
MatMenuModule,
TranslateModule,
MatIconModule,
SearchFilterMenuCardComponent,
MatButtonModule,
SearchFacetFieldComponent
],
templateUrl: './search-facet-chip.component.html',
styleUrls: ['./search-facet-chip.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class SearchFacetChipComponent {
@Input()

View File

@@ -21,9 +21,17 @@ import { SearchQueryBuilderService } from '../../services/search-query-builder.s
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { FacetField, SearchCategory, TabbedFacetField } from '../../models';
import { CommonModule } from '@angular/common';
import { MatChipsModule } from '@angular/material/chips';
import { TranslateModule } from '@ngx-translate/core';
import { SearchFacetChipTabbedComponent } from './search-facet-chip-tabbed/search-facet-chip-tabbed.component';
import { SearchFacetChipComponent } from './search-facet-chip/search-facet-chip.component';
import { SearchWidgetChipComponent } from './search-widget-chip/search-widget-chip.component';
@Component({
selector: 'adf-search-filter-chips',
standalone: true,
imports: [CommonModule, MatChipsModule, TranslateModule, SearchFacetChipTabbedComponent, SearchFacetChipComponent, SearchWidgetChipComponent],
templateUrl: './search-filter-chips.component.html',
styleUrls: ['./search-filter-chips.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -6,9 +6,7 @@
aria-hidden="false"
(click)="onClose()"
[title]="'SEARCH.FILTER.BUTTONS.CLOSE' | translate">
<mat-icon>
close
</mat-icon>
<mat-icon>close</mat-icon>
</button>
</div>

View File

@@ -16,12 +16,19 @@
*/
import { Component, EventEmitter, Output, ViewEncapsulation } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { MatDividerModule } from '@angular/material/divider';
@Component({
selector: 'adf-search-filter-menu-card',
templateUrl: './search-filter-menu-card.component.html',
styleUrls: ['./search-filter-menu-card.component.scss'],
encapsulation: ViewEncapsulation.None
selector: 'adf-search-filter-menu-card',
standalone: true,
imports: [CommonModule, MatButtonModule, TranslateModule, MatIconModule, MatDividerModule],
templateUrl: './search-filter-menu-card.component.html',
styleUrls: ['./search-filter-menu-card.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class SearchFilterMenuCardComponent {
@Output()

View File

@@ -1,8 +1,8 @@
<mat-chip [attr.data-automation-id]="'search-filter-chip-' + category.name"
disableRipple
[disableRipple]="true"
class="adf-search-filter-chip"
[class.adf-search-toggle-chip]="(widget.getDisplayValue() | async) || menuTrigger.menuOpen"
tabIndex="0"
tabindex="0"
role="button"
[matMenuTriggerFor]="menu"
(menuOpened)="onMenuOpen()"

View File

@@ -18,11 +18,28 @@
import { Component, ElementRef, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { SearchCategory } from '../../../models/search-category.interface';
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { SearchWidgetContainerComponent } from '../../search-widget-container/search-widget-container.component';
import { CommonModule } from '@angular/common';
import { MatChipsModule } from '@angular/material/chips';
import { TranslateModule } from '@ngx-translate/core';
import { MatIconModule } from '@angular/material/icon';
import { SearchFilterMenuCardComponent } from '../search-filter-menu-card/search-filter-menu-card.component';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-search-widget-chip',
standalone: true,
imports: [
CommonModule,
MatChipsModule,
MatMenuModule,
TranslateModule,
MatIconModule,
SearchFilterMenuCardComponent,
SearchWidgetContainerComponent,
MatButtonModule
],
templateUrl: './search-widget-chip.component.html',
styles: [
`

View File

@@ -17,16 +17,32 @@
import { Component, Input, Output, OnInit, EventEmitter, ViewEncapsulation, ViewChild, OnDestroy, ElementRef } from '@angular/core';
import { ConfigurableFocusTrapFactory, ConfigurableFocusTrap } from '@angular/cdk/a11y';
import { DataColumn, TranslationService } from '@alfresco/adf-core';
import { DataColumn, IconComponent, TranslationService } from '@alfresco/adf-core';
import { SearchWidgetContainerComponent } from '../search-widget-container/search-widget-container.component';
import { SearchHeaderQueryBuilderService } from '../../services/search-header-query-builder.service';
import { SearchCategory } from '../../models/search-category.interface';
import { Subject } from 'rxjs';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
import { FilterSearch } from '../../models/filter-search.interface';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { MatBadgeModule } from '@angular/material/badge';
import { TranslateModule } from '@ngx-translate/core';
import { MatDialogModule } from '@angular/material/dialog';
@Component({
selector: 'adf-search-filter-container',
standalone: true,
imports: [
CommonModule,
MatButtonModule,
MatMenuModule,
IconComponent,
MatBadgeModule,
SearchWidgetContainerComponent,
TranslateModule,
MatDialogModule
],
templateUrl: './search-filter-container.component.html',
styleUrls: ['./search-filter-container.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -18,11 +18,12 @@
import { Directive, Input, TemplateRef } from '@angular/core';
@Directive({
selector: '[adf-search-filter-tab]'
selector: '[adf-search-filter-tab]',
standalone: true
})
export class SearchFilterTabDirective {
@Input('adf-search-filter-tab')
name: string;
constructor(public readonly templateRef: TemplateRef<any>) { }
constructor(public readonly templateRef: TemplateRef<any>) {}
}

View File

@@ -17,12 +17,17 @@
import { Component, ContentChildren, QueryList, ViewEncapsulation } from '@angular/core';
import { SearchFilterTabDirective } from './search-filter-tab.directive';
import { CommonModule } from '@angular/common';
import { MatTabsModule } from '@angular/material/tabs';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-search-filter-tabbed',
templateUrl: './search-filter-tabbed.component.html',
styleUrls: ['./search-filter-tabbed.component.scss'],
encapsulation: ViewEncapsulation.None
selector: 'adf-search-filter-tabbed',
standalone: true,
imports: [CommonModule, MatTabsModule, TranslateModule],
templateUrl: './search-filter-tabbed.component.html',
styleUrls: ['./search-filter-tabbed.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class SearchFilterTabbedComponent {
@ContentChildren(SearchFilterTabDirective)

View File

@@ -18,9 +18,14 @@
import { Component, Input, ViewChild, ViewEncapsulation } from '@angular/core';
import { SearchWidgetContainerComponent } from '../../search-widget-container/search-widget-container.component';
import { SearchCategory } from '../../../models/search-category.interface';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-search-filter-card',
standalone: true,
imports: [CommonModule, SearchWidgetContainerComponent, TranslateModule, MatButtonModule],
templateUrl: './search-filter-card.component.html',
encapsulation: ViewEncapsulation.None
})

View File

@@ -16,9 +16,7 @@
{{ category.name | translate }}
</mat-panel-title>
</mat-expansion-panel-header>
<adf-search-filter-card
[category]="category">
</adf-search-filter-card>
<adf-search-filter-card [category]="category"></adf-search-filter-card>
</mat-expansion-panel>
<ng-container *ngIf="facetFiltersService.tabbedFacet && showContextFacets">

View File

@@ -20,9 +20,28 @@ import { SearchQueryBuilderService } from '../../services/search-query-builder.s
import { FacetFieldBucket } from '../../models/facet-field-bucket.interface';
import { FacetField } from '../../models/facet-field.interface';
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
import { CommonModule } from '@angular/common';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { SearchFilterCardComponent } from './search-filter-card/search-filter-card.component';
import { ResetSearchDirective } from '../reset-search.directive';
import { SearchFacetFieldComponent } from '../search-facet-field';
import { SearchFacetTabbedContentComponent } from '../search-filter-chips';
@Component({
selector: 'adf-search-filter',
standalone: true,
imports: [
CommonModule,
MatExpansionModule,
MatButtonModule,
TranslateModule,
SearchFilterCardComponent,
ResetSearchDirective,
SearchFacetFieldComponent,
SearchFacetTabbedContentComponent
],
templateUrl: './search-filter.component.html',
styleUrls: ['./search-filter.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -18,9 +18,16 @@
import { Component, EventEmitter, inject, Output, ViewEncapsulation } from '@angular/core';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchForm } from '../../models/search-form.interface';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
import { MatMenuModule } from '@angular/material/menu';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'adf-search-form',
standalone: true,
imports: [CommonModule, MatButtonModule, TranslateModule, MatMenuModule, MatIconModule],
templateUrl: './search-form.component.html',
styleUrls: ['./search-form.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -26,8 +26,7 @@ describe('SearchLogicalFilterComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchLogicalFilterComponent],
imports: [ContentTestingModule]
imports: [ContentTestingModule, SearchLogicalFilterComponent]
});
fixture = TestBed.createComponent(SearchLogicalFilterComponent);

View File

@@ -21,6 +21,10 @@ import { SearchWidgetSettings } from '../../models/search-widget-settings.interf
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { Subject } from 'rxjs';
import { TranslationService } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { TranslateModule } from '@ngx-translate/core';
import { FormsModule } from '@angular/forms';
export enum LogicalSearchFields {
MATCH_ALL = 'matchAll',
@@ -35,6 +39,8 @@ export interface LogicalSearchCondition extends LogicalSearchConditionEnumValued
@Component({
selector: 'adf-search-logical-filter',
standalone: true,
imports: [CommonModule, MatFormFieldModule, TranslateModule, FormsModule],
templateUrl: './search-logical-filter.component.html',
styleUrls: ['./search-logical-filter.component.scss'],
encapsulation: ViewEncapsulation.None

View File

@@ -16,22 +16,28 @@
*/
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { ReactiveFormsModule, UntypedFormControl, UntypedFormGroup, Validators } from '@angular/forms';
import { SearchWidget } from '../../models/search-widget.interface';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { LiveErrorStateMatcher } from '../../forms/live-error-state-matcher';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
@Component({
selector: 'adf-search-number-range',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, TranslateModule, MatButtonModule],
templateUrl: './search-number-range.component.html',
styleUrls: ['./search-number-range.component.scss'],
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-search-number-range' }
})
export class SearchNumberRangeComponent implements SearchWidget, OnInit {
from: UntypedFormControl;
to: UntypedFormControl;
@@ -53,17 +59,12 @@ export class SearchNumberRangeComponent implements SearchWidget, OnInit {
displayValue$: Subject<string> = new Subject<string>();
ngOnInit(): void {
if (this.settings) {
this.field = this.settings.field;
this.format = this.settings.format || '[{FROM} TO {TO}]';
}
this.validators = Validators.compose([
Validators.required,
Validators.pattern(/^-?(0|[1-9]\d*)?$/),
Validators.min(0)
]);
this.validators = Validators.compose([Validators.required, Validators.pattern(/^-?(0|[1-9]\d*)?$/), Validators.min(0)]);
if (this.startValue) {
this.from = new UntypedFormControl(this.startValue['from'], this.validators);
@@ -73,17 +74,20 @@ export class SearchNumberRangeComponent implements SearchWidget, OnInit {
this.to = new UntypedFormControl('', this.validators);
}
this.form = new UntypedFormGroup({
from: this.from,
to: this.to
}, this.formValidator);
this.form = new UntypedFormGroup(
{
from: this.from,
to: this.to
},
this.formValidator
);
this.enableChangeUpdate = this.settings?.allowUpdateOnChange ?? true;
this.updateDisplayValue();
}
formValidator(formGroup: UntypedFormGroup) {
return parseInt(formGroup.get('from').value, 10) < parseInt(formGroup.get('to').value, 10) ? null : {mismatch: true};
return parseInt(formGroup.get('from').value, 10) < parseInt(formGroup.get('to').value, 10) ? null : { mismatch: true };
}
apply(model: { from: string; to: string }, isValid: boolean) {

View File

@@ -18,9 +18,13 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { ContentNodeSelectorPanelService } from '../../../content-node-selector/content-node-selector-panel/content-node-selector-panel.service';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { CommonModule } from '@angular/common';
import { SearchFilterComponent } from '../search-filter';
@Component({
selector: 'adf-search-panel',
standalone: true,
imports: [CommonModule, SearchFilterComponent],
templateUrl: './search-panel.component.html',
styleUrls: ['./search-panel.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -60,8 +60,7 @@ describe('SearchPropertiesComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [SearchPropertiesComponent],
imports: [ContentTestingModule]
imports: [ContentTestingModule, SearchPropertiesComponent]
}).compileComponents();
fixture = TestBed.createComponent(SearchPropertiesComponent);

View File

@@ -16,7 +16,7 @@
*/
import { AfterViewChecked, Component, ElementRef, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { FileSizeCondition } from './file-size-condition';
import { FileSizeOperator } from './file-size-operator.enum';
import { FileSizeUnit } from './file-size-unit.enum';
@@ -24,12 +24,18 @@ import { Subject } from 'rxjs';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchProperties } from './search-properties';
import { TranslateService } from '@ngx-translate/core';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { SearchWidget } from '../../models/search-widget.interface';
import { AutocompleteOption } from '../../models/autocomplete-option.interface';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { SearchChipAutocompleteInputComponent } from '../search-chip-autocomplete-input';
@Component({
selector: 'adf-search-properties',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, TranslateModule, MatFormFieldModule, MatSelectModule, SearchChipAutocompleteInputComponent],
templateUrl: './search-properties.component.html',
styleUrls: ['./search-properties.component.scss'],
encapsulation: ViewEncapsulation.None
@@ -47,7 +53,7 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
fileSize: undefined,
fileSizeUnit: FileSizeUnit.KB
});
private _fileSizeOperators = Object.keys(FileSizeOperator).map<string>(key => FileSizeOperator[key]);
private _fileSizeOperators = Object.keys(FileSizeOperator).map<string>((key) => FileSizeOperator[key]);
private _fileSizeUnits = [FileSizeUnit.KB, FileSizeUnit.MB, FileSizeUnit.GB];
private canvas = document.createElement('canvas');
private _fileSizeOperatorsMaxWidth: number;
@@ -56,7 +62,7 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
private sizeField: string;
private nameField: string;
@ViewChild('fileSizeOperatorSelect', {read: ElementRef})
@ViewChild('fileSizeOperatorSelect', { read: ElementRef })
fileSizeOperatorSelectElement: ElementRef;
get form(): SearchPropertiesComponent['_form'] {
@@ -102,8 +108,12 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
if (this.fileSizeOperatorSelectElement?.nativeElement.clientWidth && !this._fileSizeOperatorsMaxWidth) {
setTimeout(() => {
const extraFreeSpace = 20;
this._fileSizeOperatorsMaxWidth = Math.max(...this._fileSizeOperators.map((operator) =>
this.getOperatorNameWidth(operator, this.getCanvasFont(this.fileSizeOperatorSelectElement.nativeElement)))) +
this._fileSizeOperatorsMaxWidth =
Math.max(
...this._fileSizeOperators.map((operator) =>
this.getOperatorNameWidth(operator, this.getCanvasFont(this.fileSizeOperatorSelectElement.nativeElement))
)
) +
this.fileSizeOperatorSelectElement.nativeElement.querySelector('.mat-mdc-select-arrow-wrapper').clientWidth +
extraFreeSpace;
});
@@ -144,7 +154,9 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
const extensionWithDot = filterValue.startsWith('.');
return extensions.filter((option) => {
const optionLowerCase = option.value.toLowerCase();
return extensionWithDot && filterValueLowerCase ? optionLowerCase.startsWith(filterValueLowerCase) : optionLowerCase.includes(filterValue);
return extensionWithDot && filterValueLowerCase
? optionLowerCase.startsWith(filterValueLowerCase)
: optionLowerCase.includes(filterValue);
});
};
@@ -163,7 +175,9 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
let query = '';
let displayedValue = '';
if (this.form.value.fileSize !== undefined && this.form.value.fileSize !== null) {
displayedValue = `${this.translateService.instant(this.form.value.fileSizeOperator)} ${this.form.value.fileSize} ${this.translateService.instant(this.form.value.fileSizeUnit.abbreviation)}`;
displayedValue = `${this.translateService.instant(this.form.value.fileSizeOperator)} ${
this.form.value.fileSize
} ${this.translateService.instant(this.form.value.fileSizeUnit.abbreviation)}`;
const size = this.form.value.fileSize * this.form.value.fileSizeUnit.bytes;
switch (this.form.value.fileSizeOperator) {
case FileSizeOperator.AT_MOST:
@@ -208,11 +222,11 @@ export class SearchPropertiesComponent implements OnInit, AfterViewChecked, Sear
}
private parseToAutocompleteOptions(array: string[]): AutocompleteOption[] {
return array.map(value => ({value}));
return array.map((value) => ({ value }));
}
private parseFromAutocompleteOptions(array: AutocompleteOption[]): string[] {
return array.flatMap(option => option.value);
return array.flatMap((option) => option.value);
}
private getOperatorNameWidth(operator: string, font: string): number {

View File

@@ -16,13 +16,18 @@
*/
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { MatRadioChange } from '@angular/material/radio';
import { MatRadioChange, MatRadioModule } from '@angular/material/radio';
import { SearchWidget } from '../../models/search-widget.interface';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchFilterList } from '../../models/search-filter-list.model';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
export interface SearchRadioOption {
name: string;
@@ -31,13 +36,14 @@ export interface SearchRadioOption {
@Component({
selector: 'adf-search-radio',
standalone: true,
imports: [CommonModule, MatRadioModule, FormsModule, TranslateModule, MatButtonModule, MatIconModule],
templateUrl: './search-radio.component.html',
styleUrls: ['./search-radio.component.scss'],
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-search-radio' }
})
export class SearchRadioComponent implements SearchWidget, OnInit {
/** The value of the selected radio button. */
@Input()
value: string;
@@ -61,9 +67,7 @@ export class SearchRadioComponent implements SearchWidget, OnInit {
this.pageSize = this.settings.pageSize || 5;
if (this.settings.options && this.settings.options.length > 0) {
this.options = new SearchFilterList<SearchRadioOption>(
this.settings.options, this.pageSize
);
this.options = new SearchFilterList<SearchRadioOption>(this.settings.options, this.pageSize);
}
}
@@ -119,7 +123,7 @@ export class SearchRadioComponent implements SearchWidget, OnInit {
}
updateDisplayValue(): void {
const selectOptions = this.options.items.find(({ value}) => value === this.value);
const selectOptions = this.options.items.find(({ value }) => value === this.value);
if (selectOptions) {
this.displayValue$.next(selectOptions.name);
} else {

View File

@@ -20,9 +20,16 @@ import { SearchWidget } from '../../models/search-widget.interface';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatSliderModule } from '@angular/material/slider';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-search-slider',
standalone: true,
imports: [CommonModule, MatSliderModule, FormsModule, MatButtonModule, TranslateModule],
templateUrl: './search-slider.component.html',
styleUrls: ['./search-slider.component.scss'],
encapsulation: ViewEncapsulation.None,
@@ -105,7 +112,7 @@ export class SearchSliderComponent implements SearchWidget, OnInit {
}
private updateQuery(value: number | null) {
this.displayValue$.next( this.value ? `${this.value} ${this.settings.unit ?? ''}` : '' );
this.displayValue$.next(this.value ? `${this.value} ${this.settings.unit ?? ''}` : '');
if (this.id && this.context && this.settings && this.settings.field) {
if (value === null) {
this.context.queryFragments[this.id] = '';
@@ -115,5 +122,4 @@ export class SearchSliderComponent implements SearchWidget, OnInit {
this.context.update();
}
}
}

View File

@@ -18,9 +18,13 @@
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { SearchSortingDefinition } from '../../models/search-sorting-definition.interface';
import { CommonModule } from '@angular/common';
import { SortingPickerComponent } from '@alfresco/adf-core';
@Component({
selector: 'adf-search-sorting-picker',
standalone: true,
imports: [CommonModule, SortingPickerComponent],
templateUrl: './search-sorting-picker.component.html',
styleUrls: ['./search-sorting-picker.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -20,16 +20,24 @@ import { SearchWidget } from '../../models/search-widget.interface';
import { SearchWidgetSettings } from '../../models/search-widget-settings.interface';
import { SearchQueryBuilderService } from '../../services/search-query-builder.service';
import { Subject } from 'rxjs';
import { CommonModule } from '@angular/common';
import { MatFormFieldModule } from '@angular/material/form-field';
import { TranslateModule } from '@ngx-translate/core';
import { MatInputModule } from '@angular/material/input';
import { MatButtonModule } from '@angular/material/button';
import { FormsModule } from '@angular/forms';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'adf-search-text',
standalone: true,
imports: [CommonModule, MatFormFieldModule, TranslateModule, MatInputModule, MatButtonModule, FormsModule, MatIconModule],
templateUrl: './search-text.component.html',
styleUrls: ['./search-text.component.scss'],
encapsulation: ViewEncapsulation.None,
host: { class: 'adf-search-text' }
})
export class SearchTextComponent implements SearchWidget, OnInit {
/** The content of the text box. */
@Input()
value = '';
@@ -46,8 +54,7 @@ export class SearchTextComponent implements SearchWidget, OnInit {
if (this.context && this.settings && this.settings.pattern) {
const pattern = new RegExp(this.settings.pattern, 'g');
const match = pattern.exec(this.context.queryFragments[this.id] || '');
if (this.settings.allowUpdateOnChange !== undefined &&
this.settings.allowUpdateOnChange !== null) {
if (this.settings.allowUpdateOnChange !== undefined && this.settings.allowUpdateOnChange !== null) {
this.enableChangeUpdate = this.settings.allowUpdateOnChange;
}
@@ -115,5 +122,4 @@ export class SearchTextComponent implements SearchWidget, OnInit {
private getSearchSuffix(): string {
return this.settings.searchSuffix ? this.settings.searchSuffix : '';
}
}

View File

@@ -15,24 +15,14 @@
* limitations under the License.
*/
import {
Component,
Input,
ViewChild,
ViewContainerRef,
OnInit,
OnDestroy,
ComponentRef,
SimpleChanges,
OnChanges,
Injector
} from '@angular/core';
import { Component, Input, ViewChild, ViewContainerRef, OnInit, OnDestroy, ComponentRef, SimpleChanges, OnChanges, Injector } from '@angular/core';
import { SearchFilterService } from '../../services/search-filter.service';
import { Observable } from 'rxjs';
import {SearchHeaderQueryBuilderService, SearchQueryBuilderService} from '../../services';
import { SearchHeaderQueryBuilderService, SearchQueryBuilderService } from '../../services';
@Component({
selector: 'adf-search-widget-container',
standalone: true,
template: '<div #content></div>'
})
export class SearchWidgetContainerComponent implements OnInit, OnDestroy, OnChanges {
@@ -59,8 +49,7 @@ export class SearchWidgetContainerComponent implements OnInit, OnDestroy, OnChan
componentRef: ComponentRef<any>;
constructor(private searchFilterService: SearchFilterService, private injector: Injector) {
}
constructor(private searchFilterService: SearchFilterService, private injector: Injector) {}
ngOnInit() {
const componentType = this.searchFilterService.widgets[this.selector];

View File

@@ -35,9 +35,13 @@ import { NodePaging, ResultSetPaging } from '@alfresco/js-api';
import { Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { SearchComponentInterface } from '@alfresco/adf-core';
import { CommonModule } from '@angular/common';
import { TranslateModule } from '@ngx-translate/core';
@Component({
selector: 'adf-search',
standalone: true,
imports: [CommonModule, TranslateModule],
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss'],
encapsulation: ViewEncapsulation.None,

View File

@@ -15,13 +15,7 @@
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MaterialModule } from '../material.module';
import { CoreModule, SearchTextModule } from '@alfresco/adf-core';
import { SearchControlComponent } from './components/search-control.component';
import { SearchComponent } from './components/search.component';
import { EmptySearchResultComponent } from './components/empty-search-result.component';
@@ -55,82 +49,46 @@ import { SearchDateRangeTabbedComponent } from './components/search-date-range-t
import { SearchFilterTabDirective } from './components/search-filter-tabbed/search-filter-tab.directive';
import { SearchFacetChipTabbedComponent } from './components/search-filter-chips/search-facet-chip-tabbed/search-facet-chip-tabbed.component';
import { SearchFacetTabbedContentComponent } from './components/search-filter-chips/search-facet-chip-tabbed/search-facet-tabbed-content.component';
import { SearchInputComponent } from './components/search-input';
export const CONTENT_SEARCH_DIRECTIVES = [SearchCheckListComponent, SearchChipAutocompleteInputComponent, SearchChipListComponent] as const;
export const CONTENT_SEARCH_DIRECTIVES = [
SearchCheckListComponent,
SearchChipAutocompleteInputComponent,
SearchChipListComponent,
EmptySearchResultComponent,
SearchFilterComponent,
SearchFilterCardComponent,
SearchWidgetContainerComponent,
SearchTextComponent,
SearchFilterAutocompleteChipsComponent,
SearchDatetimeRangeComponent,
SearchFacetFieldComponent,
ResetSearchDirective,
SearchDateRangeComponent,
SearchFilterMenuCardComponent,
SearchFacetChipTabbedComponent,
SearchFacetTabbedContentComponent,
SearchFilterTabbedComponent,
SearchFilterTabDirective,
SearchDateRangeTabbedComponent,
SearchSortingPickerComponent,
SearchSliderComponent,
SearchNumberRangeComponent,
SearchPanelComponent,
SearchRadioComponent,
SearchFilterContainerComponent,
SearchFormComponent,
SearchFilterChipsComponent,
SearchWidgetChipComponent,
SearchFacetChipComponent,
SearchLogicalFilterComponent,
SearchPropertiesComponent,
SearchComponent,
SearchControlComponent
] as const;
/** @deprecated use `...CONTENT_SEARCH_DIRECTIVES` or import the specific component */
@NgModule({
imports: [
...CONTENT_SEARCH_DIRECTIVES,
CommonModule,
FormsModule,
ReactiveFormsModule,
MaterialModule,
CoreModule,
SearchTextModule,
SearchInputComponent
],
declarations: [
SearchComponent,
SearchControlComponent,
EmptySearchResultComponent,
SearchFilterComponent,
SearchFilterCardComponent,
SearchWidgetContainerComponent,
SearchTextComponent,
SearchFilterAutocompleteChipsComponent,
SearchRadioComponent,
SearchSliderComponent,
SearchNumberRangeComponent,
SearchPanelComponent,
SearchDatetimeRangeComponent,
SearchSortingPickerComponent,
SearchFilterContainerComponent,
SearchFormComponent,
SearchFilterChipsComponent,
SearchFilterMenuCardComponent,
SearchFacetFieldComponent,
SearchWidgetChipComponent,
SearchFacetChipComponent,
SearchLogicalFilterComponent,
ResetSearchDirective,
SearchPropertiesComponent,
SearchFilterTabbedComponent,
SearchDateRangeComponent,
SearchDateRangeTabbedComponent,
SearchFilterTabDirective,
SearchFacetChipTabbedComponent,
SearchFacetTabbedContentComponent
],
exports: [
SearchComponent,
SearchControlComponent,
EmptySearchResultComponent,
SearchFilterComponent,
SearchFilterCardComponent,
SearchWidgetContainerComponent,
SearchTextComponent,
SearchFilterAutocompleteChipsComponent,
SearchRadioComponent,
SearchSliderComponent,
SearchNumberRangeComponent,
SearchPanelComponent,
...CONTENT_SEARCH_DIRECTIVES,
SearchDatetimeRangeComponent,
SearchSortingPickerComponent,
SearchFilterContainerComponent,
SearchFormComponent,
SearchFilterChipsComponent,
SearchFilterMenuCardComponent,
SearchFacetFieldComponent,
SearchWidgetChipComponent,
SearchLogicalFilterComponent,
SearchFilterTabbedComponent,
SearchDateRangeComponent,
SearchDateRangeTabbedComponent,
ResetSearchDirective,
SearchFacetChipTabbedComponent,
SearchFacetTabbedContentComponent
]
imports: [...CONTENT_SEARCH_DIRECTIVES],
exports: [...CONTENT_SEARCH_DIRECTIVES]
})
export class SearchModule {}

View File

@@ -15,9 +15,9 @@
* limitations under the License.
*/
export * from './tag-actions.component';
export * from './tag-list.component';
export * from './tag-node-list.component';
export * from './tag-actions/tag-actions.component';
export * from './tag-list/tag-list.component';
export * from './tag-node-list/tag-node-list.component';
export * from './services/tag.service';
@@ -25,4 +25,3 @@ export * from './tag.module';
export * from './tags-creator/tags-creator-mode';
export * from './tags-creator/tags-creator.component';

View File

@@ -17,9 +17,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TagActionsComponent } from './tag-actions.component';
import { TagService } from './services/tag.service';
import { TagService } from '../services/tag.service';
import { of } from 'rxjs';
import { ContentTestingModule } from '../testing/content.testing.module';
import { ContentTestingModule } from '../../testing/content.testing.module';
describe('TagActionsComponent', () => {
const dataTag = {

View File

@@ -17,7 +17,7 @@
import { TranslationService } from '@alfresco/adf-core';
import { Component, EventEmitter, Input, OnChanges, Output, ViewEncapsulation, OnDestroy, OnInit } from '@angular/core';
import { TagService } from './services/tag.service';
import { TagService } from '../services/tag.service';
import { Subject } from 'rxjs';
import { TagPaging } from '@alfresco/js-api';
import { takeUntil } from 'rxjs/operators';

View File

@@ -16,10 +16,10 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TagService } from './services/tag.service';
import { TagListComponent } from '././tag-list.component';
import { TagService } from '../services/tag.service';
import { TagListComponent } from './tag-list.component';
import { of } from 'rxjs';
import { ContentTestingModule } from '../testing/content.testing.module';
import { ContentTestingModule } from '../../testing/content.testing.module';
describe('TagList', () => {
const dataTag = {

View File

@@ -16,7 +16,7 @@
*/
import { Component, EventEmitter, OnInit, Output, ViewEncapsulation, OnDestroy } from '@angular/core';
import { TagService } from './services/tag.service';
import { TagService } from '../services/tag.service';
import { PaginationModel } from '@alfresco/adf-core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

View File

@@ -17,9 +17,9 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TagNodeListComponent } from './tag-node-list.component';
import { TagService } from './services/tag.service';
import { TagService } from '../services/tag.service';
import { Observable, of, Subject } from 'rxjs';
import { ContentTestingModule } from '../testing/content.testing.module';
import { ContentTestingModule } from '../../testing/content.testing.module';
import { Tag, TagEntry, TagPaging } from '@alfresco/js-api';
import { DynamicChipListComponent } from '@alfresco/adf-core';
import { By } from '@angular/platform-browser';

Some files were not shown because too many files have changed in this diff Show More