diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss b/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss
index 4b42cbfc1..112adcd66 100644
--- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss
+++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.scss
@@ -1,6 +1,13 @@
@import '../../../ui/mixins';
aca-search-results {
+ .aca-search-results-active-search-ai-input {
+ .aca-header-container,
+ .adf-search-results__content-header.aca-content {
+ display: none;
+ }
+ }
+
.aca-search-toolbar-spacer {
width: 100%;
}
diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts b/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts
index 2ddf74b44..0598ca69a 100644
--- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts
+++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts
@@ -77,6 +77,7 @@ import { MatIconModule } from '@angular/material/icon';
import { SearchResultsRowComponent } from '../search-results-row/search-results-row.component';
import { DocumentListPresetRef, DynamicColumnComponent } from '@alfresco/adf-extensions';
import { BulkActionsDropdownComponent } from '../../bulk-actions-dropdown/bulk-actions-dropdown.component';
+import { SearchAiInputContainerComponent } from '../../knowledge-retrieval/search-ai/search-ai-input-container/search-ai-input-container.component';
@Component({
standalone: true,
@@ -110,7 +111,8 @@ import { BulkActionsDropdownComponent } from '../../bulk-actions-dropdown/bulk-a
DateColumnHeaderComponent,
CustomEmptyContentTemplateDirective,
ViewerToolbarComponent,
- BulkActionsDropdownComponent
+ BulkActionsDropdownComponent,
+ SearchAiInputContainerComponent
],
selector: 'aca-search-results',
templateUrl: './search-results.component.html',
diff --git a/projects/aca-content/src/lib/components/shared-files/shared-files.component.html b/projects/aca-content/src/lib/components/shared-files/shared-files.component.html
index e8f446754..33e6fe8b0 100644
--- a/projects/aca-content/src/lib/components/shared-files/shared-files.component.html
+++ b/projects/aca-content/src/lib/components/shared-files/shared-files.component.html
@@ -1,10 +1,18 @@
diff --git a/projects/aca-content/src/lib/components/shared-files/shared-files.component.ts b/projects/aca-content/src/lib/components/shared-files/shared-files.component.ts
index 3c8793aad..d84d0e36f 100644
--- a/projects/aca-content/src/lib/components/shared-files/shared-files.component.ts
+++ b/projects/aca-content/src/lib/components/shared-files/shared-files.component.ts
@@ -40,6 +40,7 @@ import { DocumentListModule } from '@alfresco/adf-content-services';
import { DataTableModule, EmptyContentComponent, PaginationComponent } from '@alfresco/adf-core';
import { DocumentListDirective } from '../../directives/document-list.directive';
import { TranslateModule } from '@ngx-translate/core';
+import { SearchAiInputContainerComponent } from '../knowledge-retrieval/search-ai/search-ai-input-container/search-ai-input-container.component';
@Component({
standalone: true,
@@ -55,11 +56,13 @@ import { TranslateModule } from '@ngx-translate/core';
PageLayoutComponent,
TranslateModule,
ToolbarComponent,
+ SearchAiInputContainerComponent,
EmptyContentComponent,
DynamicColumnComponent
],
templateUrl: './shared-files.component.html',
- encapsulation: ViewEncapsulation.None
+ encapsulation: ViewEncapsulation.None,
+ selector: 'aca-shared-files'
})
export class SharedFilesComponent extends PageComponent implements OnInit {
columns: DocumentListPresetRef[] = [];
diff --git a/projects/aca-content/src/lib/services/search-ai-navigation.service.ts b/projects/aca-content/src/lib/services/search-ai-navigation.service.ts
new file mode 100644
index 000000000..5fc3cb197
--- /dev/null
+++ b/projects/aca-content/src/lib/services/search-ai-navigation.service.ts
@@ -0,0 +1,48 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { Injectable } from '@angular/core';
+import { Params, Router } from '@angular/router';
+
+@Injectable({ providedIn: 'root' })
+export class SearchAiNavigationService {
+ private readonly knowledgeRetrievalRoute = '/knowledge-retrieval';
+
+ private previousRoute = '';
+
+ constructor(private router: Router) {}
+
+ navigateToPreviousRoute(): void {
+ if (this.router.url.includes(this.knowledgeRetrievalRoute)) {
+ void this.router.navigateByUrl(this.previousRoute || '/personal-files');
+ }
+ }
+
+ navigateToSearchAi(queryParams: Params): void {
+ if (!this.router.url.includes(this.knowledgeRetrievalRoute)) {
+ this.previousRoute = this.router.url;
+ }
+ void this.router.navigate([this.knowledgeRetrievalRoute], { queryParams: queryParams });
+ }
+}
diff --git a/projects/aca-content/src/lib/store/app-store.module.ts b/projects/aca-content/src/lib/store/app-store.module.ts
index 02297d68b..dfeb5d107 100644
--- a/projects/aca-content/src/lib/store/app-store.module.ts
+++ b/projects/aca-content/src/lib/store/app-store.module.ts
@@ -41,6 +41,7 @@ import {
ContextMenuEffects
} from './effects';
import { INITIAL_STATE } from './initial-state';
+import { SearchAiEffects } from './effects/search-ai.effects';
@NgModule({
imports: [
@@ -69,6 +70,8 @@ import { INITIAL_STATE } from './initial-state';
FavoriteEffects,
TemplateEffects,
ContextMenuEffects,
+ SearchAiEffects,
+ ContextMenuEffects,
SnackbarEffects,
RouterEffects
])
diff --git a/projects/aca-content/src/lib/store/effects.ts b/projects/aca-content/src/lib/store/effects.ts
index f8eb84022..423fed8d0 100644
--- a/projects/aca-content/src/lib/store/effects.ts
+++ b/projects/aca-content/src/lib/store/effects.ts
@@ -33,3 +33,4 @@ export * from './effects/upload.effects';
export * from './effects/upload.effects';
export * from './effects/template.effects';
export * from './effects/contextmenu.effects';
+export * from './effects/search-ai.effects';
diff --git a/projects/aca-content/src/lib/store/effects/search-ai.effects.ts b/projects/aca-content/src/lib/store/effects/search-ai.effects.ts
new file mode 100644
index 000000000..6de4a8d54
--- /dev/null
+++ b/projects/aca-content/src/lib/store/effects/search-ai.effects.ts
@@ -0,0 +1,64 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { Injectable } from '@angular/core';
+import { Actions, createEffect, ofType } from '@ngrx/effects';
+import { SearchAiActionTypes, SearchByTermAiAction, ToggleAISearchInput } from '@alfresco/aca-shared/store';
+import { map } from 'rxjs/operators';
+import { SearchAiNavigationService } from '../../services/search-ai-navigation.service';
+import { SearchAiService } from '@alfresco/adf-content-services';
+
+@Injectable()
+export class SearchAiEffects {
+ constructor(private actions$: Actions, private searchNavigationService: SearchAiNavigationService, private searchAiService: SearchAiService) {}
+
+ searchByTerm$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(SearchAiActionTypes.SearchByTermAi),
+ map((action) => {
+ const queryParams = {
+ query: encodeURIComponent(action.payload.searchTerm),
+ agentId: action.payload.agentId
+ };
+ this.searchNavigationService.navigateToSearchAi(queryParams);
+ })
+ ),
+ { dispatch: false }
+ );
+
+ toggleAISearchInput$ = createEffect(
+ () =>
+ this.actions$.pipe(
+ ofType(SearchAiActionTypes.ToggleAiSearchInput),
+ map((action) =>
+ this.searchAiService.updateSearchAiInputState({
+ active: true,
+ selectedAgentId: action.agentId
+ })
+ )
+ ),
+ { dispatch: false }
+ );
+}
diff --git a/projects/aca-content/src/lib/ui/application.scss b/projects/aca-content/src/lib/ui/application.scss
index 0762b52a4..31eac5710 100644
--- a/projects/aca-content/src/lib/ui/application.scss
+++ b/projects/aca-content/src/lib/ui/application.scss
@@ -66,3 +66,11 @@ ng-component {
color: var(--adf-theme-foreground-text-color-087);
width: 100%;
}
+
+.aca-header-container {
+ display: flex;
+ flex-direction: row;
+ flex: 1;
+ align-items: center;
+ width: 100%;
+}
diff --git a/projects/aca-content/src/lib/ui/variables/variables.scss b/projects/aca-content/src/lib/ui/variables/variables.scss
index aa6ec1d4c..882a91f1a 100644
--- a/projects/aca-content/src/lib/ui/variables/variables.scss
+++ b/projects/aca-content/src/lib/ui/variables/variables.scss
@@ -46,6 +46,8 @@ $disabled-chip-background-color: #f5f5f5;
$contrast-gray: mat.get-color-from-palette($foreground, 'secondary-tex');
$search-highlight-background-color: #ffd180;
$info-snackbar-background: #1f74db;
+$text-light-color: rgba(33, 35, 40, 0.7);
+$card-background-grey-color: rgb(248, 248, 248);
// CSS Variables
$defaults: (
@@ -96,7 +98,9 @@ $defaults: (
--theme-search-chip-icon-color: $search-chip-icon-color,
--theme-disabled-chip-background-color: $disabled-chip-background-color,
--theme-secondary-text: $secondary-text,
- --theme-search-highlight-background-color: $search-highlight-background-color
+ --theme-search-highlight-background-color: $search-highlight-background-color,
+ --theme-text-light-color: $text-light-color,
+ --theme-card-background-grey-color: $card-background-grey-color
);
// propagates SCSS variables into the CSS variables scope
diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts
index d97b5f105..06a7dd369 100644
--- a/projects/aca-shared/rules/src/app.rules.ts
+++ b/projects/aca-shared/rules/src/app.rules.ts
@@ -629,3 +629,10 @@ export function isSmartFolder(context: RuleContext): boolean {
export const areTagsEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('plugins.tagsEnabled', true);
export const areCategoriesEnabled = (context: AcaRuleContext): boolean => context.appConfig.get('plugins.categoriesEnabled', true);
+
+export const canDisplayKnowledgeRetrievalButton = (context: AcaRuleContext): boolean =>
+ navigation.isPersonalFiles(context) ||
+ navigation.isSharedFiles(context) ||
+ navigation.isRecentFiles(context) ||
+ navigation.isFavorites(context) ||
+ ((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && navigation.isNotLibraries(context));
diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts
index f404b68f3..c1f1828f6 100644
--- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts
+++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts
@@ -22,7 +22,7 @@
* from Hyland Software. If not, see .
*/
-import { DocumentListComponent, DocumentListService, ShareDataRow, UploadService } from '@alfresco/adf-content-services';
+import { DocumentListComponent, DocumentListService, SearchAiInputState, SearchAiService, ShareDataRow, UploadService } from '@alfresco/adf-content-services';
import { ShowHeaderMode } from '@alfresco/adf-core';
import { ContentActionRef, DocumentListPresetRef, SelectionState } from '@alfresco/adf-extensions';
import { OnDestroy, OnInit, OnChanges, ViewChild, SimpleChanges, Directive, inject, HostListener } from '@angular/core';
@@ -81,8 +81,18 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
protected router = inject(Router);
private autoDownloadService = inject(AutoDownloadService, { optional: true });
+ protected searchAiService: SearchAiService = inject(SearchAiService);
protected subscriptions: Subscription[] = [];
+ private fileAutoDownloadService = inject(AcaFileAutoDownloadService, { optional: true });
+ private _searchAiInputState: SearchAiInputState = {
+ active: false
+ };
+
+ get searchAiInputState(): SearchAiInputState {
+ return this._searchAiInputState;
+ }
+
ngOnInit() {
this.extensions
.getCreateActions()
@@ -135,6 +145,10 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges {
.subscribe((result) => {
this.isSmallScreen = result.matches;
});
+
+ this.searchAiService.toggleSearchAiInput$
+ .pipe(takeUntil(this.onDestroy$))
+ .subscribe((searchAiInputState) => (this._searchAiInputState = searchAiInputState));
}
ngOnChanges(changes: SimpleChanges) {
diff --git a/projects/aca-shared/store/src/actions/search-ai.actions.ts b/projects/aca-shared/store/src/actions/search-ai.actions.ts
new file mode 100644
index 000000000..e4d54683e
--- /dev/null
+++ b/projects/aca-shared/store/src/actions/search-ai.actions.ts
@@ -0,0 +1,42 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+import { Action } from '@ngrx/store';
+import { AiSearchByTermPayload } from '../models/ai-search-by-term-payload';
+
+export enum SearchAiActionTypes {
+ SearchByTermAi = 'SEARCH_BY_TERM_AI',
+ ToggleAiSearchInput = 'TOGGLE_AI_SEARCH_INPUT'
+}
+
+export class SearchByTermAiAction implements Action {
+ readonly type = SearchAiActionTypes.SearchByTermAi;
+ constructor(public payload: AiSearchByTermPayload) {}
+}
+
+export class ToggleAISearchInput implements Action {
+ readonly type = SearchAiActionTypes.ToggleAiSearchInput;
+
+ constructor(public agentId: string) {}
+}
diff --git a/projects/aca-shared/store/src/models/ai-search-by-term-payload.ts b/projects/aca-shared/store/src/models/ai-search-by-term-payload.ts
new file mode 100644
index 000000000..696d555a3
--- /dev/null
+++ b/projects/aca-shared/store/src/models/ai-search-by-term-payload.ts
@@ -0,0 +1,28 @@
+/*!
+ * Copyright © 2005-2024 Hyland Software, Inc. and its affiliates. All rights reserved.
+ *
+ * Alfresco Example Content Application
+ *
+ * This file is part of the Alfresco Example Content Application.
+ * If the software was purchased under a paid Alfresco license, the terms of
+ * the paid license agreement will prevail. Otherwise, the software is
+ * provided under the following open source license terms:
+ *
+ * The Alfresco Example Content Application is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Alfresco Example Content Application is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * from Hyland Software. If not, see .
+ */
+
+export interface AiSearchByTermPayload {
+ searchTerm: string;
+ agentId: string;
+}
diff --git a/projects/aca-shared/store/src/public-api.ts b/projects/aca-shared/store/src/public-api.ts
index e23673eaf..b6ef1adba 100644
--- a/projects/aca-shared/store/src/public-api.ts
+++ b/projects/aca-shared/store/src/public-api.ts
@@ -37,10 +37,12 @@ export * from './actions/viewer.actions';
export * from './actions/metadata-aspect.actions';
export * from './actions/template.actions';
export * from './actions/contextmenu.actions';
+export * from './actions/search-ai.actions';
export * from './effects/router.effects';
export * from './effects/snackbar.effects';
+export * from './models/ai-search-by-term-payload';
export * from './models/delete-status.model';
export * from './models/deleted-node-info.model';
export * from './models/node-info.model';