mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-09-17 14:21:14 +00:00
[ACS-8365] Editing prompt - review fixes
This commit is contained in:
@@ -621,7 +621,13 @@
|
|||||||
"DISLIKE_BUTTON_LABEL": "Dislike",
|
"DISLIKE_BUTTON_LABEL": "Dislike",
|
||||||
"COPY_MESSAGE": "Copied response to clipboard",
|
"COPY_MESSAGE": "Copied response to clipboard",
|
||||||
"CANCEL": "Cancel",
|
"CANCEL": "Cancel",
|
||||||
"UPDATE": "Update"
|
"UPDATE": "Update",
|
||||||
|
"ACCESSIBILITY": {
|
||||||
|
"CANCEL_BUTTON": "Cancel editing of the query button",
|
||||||
|
"UPDATE_BUTTON": "Update query button",
|
||||||
|
"EDIT_BUTTON": "Edit query button",
|
||||||
|
"TEXT_AREA": "Update query text area"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"AGENTS_BUTTON": {
|
"AGENTS_BUTTON": {
|
||||||
"LABEL": "Ask Discovery",
|
"LABEL": "Ask Discovery",
|
||||||
|
@@ -33,9 +33,11 @@
|
|||||||
matInput
|
matInput
|
||||||
class="aca-search-ai-results-container-wrapper-form-field-input"
|
class="aca-search-ai-results-container-wrapper-form-field-input"
|
||||||
data-automation-id="toggle-edit-input-textarea"
|
data-automation-id="toggle-edit-input-textarea"
|
||||||
[attr.aria-label]="'SEARCH.INPUT.ARIA-LABEL' | translate"
|
#editTextArea
|
||||||
|
[attr.aria-label]="'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.ACCESSIBILITY.TEXT_AREA' | translate"
|
||||||
[(ngModel)]="searchQuery"
|
[(ngModel)]="searchQuery"
|
||||||
(keyup.enter)="updateInput()"
|
(keyup.enter)="updateInput()"
|
||||||
|
(keyup.escape)="cancelUpdateInput()"
|
||||||
[placeholder]="'SEARCH.INPUT.PLACEHOLDER' | translate"
|
[placeholder]="'SEARCH.INPUT.PLACEHOLDER' | translate"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
></textarea>
|
></textarea>
|
||||||
@@ -45,7 +47,7 @@
|
|||||||
<button
|
<button
|
||||||
(click)="cancelUpdateInput()"
|
(click)="cancelUpdateInput()"
|
||||||
mat-flat-button
|
mat-flat-button
|
||||||
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
[attr.aria-label]="'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.ACCESSIBILITY.CANCEL_BUTTON' | translate"
|
||||||
data-automation-id="cancel-input-button"
|
data-automation-id="cancel-input-button"
|
||||||
class="aca-search-ai-results-container-wrapper-form-field-cancel-button">
|
class="aca-search-ai-results-container-wrapper-form-field-cancel-button">
|
||||||
{{ 'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.CANCEL' | translate }}
|
{{ 'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.CANCEL' | translate }}
|
||||||
@@ -53,7 +55,7 @@
|
|||||||
<button
|
<button
|
||||||
(click)="updateInput()"
|
(click)="updateInput()"
|
||||||
mat-flat-button
|
mat-flat-button
|
||||||
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
[attr.aria-label]="'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.ACCESSIBILITY.UPDATE_BUTTON' | translate"
|
||||||
data-automation-id="update-input-button"
|
data-automation-id="update-input-button"
|
||||||
class="aca-search-ai-results-container-wrapper-form-field-update-button">
|
class="aca-search-ai-results-container-wrapper-form-field-update-button">
|
||||||
{{ 'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.UPDATE' | translate }}
|
{{ 'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.UPDATE' | translate }}
|
||||||
@@ -163,7 +165,7 @@
|
|||||||
(click)="setEditing(true)"
|
(click)="setEditing(true)"
|
||||||
[disabled]="disabled"
|
[disabled]="disabled"
|
||||||
mat-flat-button
|
mat-flat-button
|
||||||
[attr.aria-label]="'CORE.METADATA.ACCESSIBILITY.EDIT' | translate"
|
[attr.aria-label]="'KNOWLEDGE_RETRIEVAL.SEARCH.RESULTS_PAGE.ACCESSIBILITY.EDIT_BUTTON' | translate"
|
||||||
data-automation-id="toggle-edit-input-button"
|
data-automation-id="toggle-edit-input-button"
|
||||||
class="aca-search-ai-results-container-wrapper-edit-button"
|
class="aca-search-ai-results-container-wrapper-edit-button"
|
||||||
[class.aca-search-ai-results-container-wrapper-edit-button-disabled]="disabled">
|
[class.aca-search-ai-results-container-wrapper-edit-button-disabled]="disabled">
|
||||||
|
@@ -31,7 +31,8 @@
|
|||||||
width: 52%;
|
width: 52%;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
padding: 20px 15px 50px;
|
padding: 20px 15px 50px;
|
||||||
background: var(--theme-card-background-grey-color);
|
background: var(--theme-form-field-background-grey-color);
|
||||||
|
border: 1px var(--theme-light-grey-3-color) solid;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -85,8 +86,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-edit-button-disabled {
|
&-edit-button-disabled {
|
||||||
top: -15px;
|
top: -16px;
|
||||||
right: -53px;
|
right: -53px;
|
||||||
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-query {
|
&-query {
|
||||||
|
@@ -24,18 +24,20 @@
|
|||||||
|
|
||||||
import { TestBed, ComponentFixture, tick, fakeAsync } from '@angular/core/testing';
|
import { TestBed, ComponentFixture, tick, fakeAsync } from '@angular/core/testing';
|
||||||
import { SearchAiResultsComponent } from './search-ai-results.component';
|
import { SearchAiResultsComponent } from './search-ai-results.component';
|
||||||
import { ActivatedRoute, Params } from '@angular/router';
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
import { of, Subject, throwError } from 'rxjs';
|
import { of, Subject, throwError } from 'rxjs';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
import { UserPreferencesService } from '@alfresco/adf-core';
|
import { UserPreferencesService } from '@alfresco/adf-core';
|
||||||
import { MatDialogModule } from '@angular/material/dialog';
|
import { MatDialogModule } from '@angular/material/dialog';
|
||||||
import { AppTestingModule } from '../../../../testing/app-testing.module';
|
import { AppTestingModule } from '../../../../testing/app-testing.module';
|
||||||
import { MatIconTestingModule } from '@angular/material/icon/testing';
|
import { MatIconTestingModule } from '@angular/material/icon/testing';
|
||||||
import { NodesApiService, SearchAiService } from '@alfresco/adf-content-services';
|
import { AgentService, NodesApiService, SearchAiService } from '@alfresco/adf-content-services';
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { ModalAiService } from '../../../../services/modal-ai.service';
|
import { ModalAiService } from '../../../../services/modal-ai.service';
|
||||||
import { delay } from 'rxjs/operators';
|
import { delay } from 'rxjs/operators';
|
||||||
import { AiAnswer, AiAnswerEntry, QuestionModel, QuestionRequest } from '@alfresco/js-api/typings';
|
import { AiAnswer, AiAnswerEntry, QuestionModel, QuestionRequest } from '@alfresco/js-api/typings';
|
||||||
|
import { MockStore, provideMockStore } from '@ngrx/store/testing';
|
||||||
|
import { getAppSelection, getCurrentFolder, SearchByTermAiAction } from '@alfresco/aca-shared/store';
|
||||||
|
|
||||||
const questionMock: QuestionModel = { question: 'test', questionId: 'testId', restrictionQuery: { nodesIds: [] } };
|
const questionMock: QuestionModel = { question: 'test', questionId: 'testId', restrictionQuery: { nodesIds: [] } };
|
||||||
const aiAnswerMock: AiAnswer = { answer: 'Some answer', questionId: 'some id', references: [] };
|
const aiAnswerMock: AiAnswer = { answer: 'Some answer', questionId: 'some id', references: [] };
|
||||||
@@ -52,6 +54,7 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
let modalAiService: ModalAiService;
|
let modalAiService: ModalAiService;
|
||||||
let searchAiService: SearchAiService;
|
let searchAiService: SearchAiService;
|
||||||
let askSpy: jasmine.Spy<(questionRequest: QuestionRequest) => void>;
|
let askSpy: jasmine.Spy<(questionRequest: QuestionRequest) => void>;
|
||||||
|
let store: MockStore;
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
mockQueryParams = new Subject<Params>();
|
mockQueryParams = new Subject<Params>();
|
||||||
@@ -62,6 +65,7 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [AppTestingModule, SearchAiResultsComponent, MatSnackBarModule, MatDialogModule, MatIconTestingModule],
|
imports: [AppTestingModule, SearchAiResultsComponent, MatSnackBarModule, MatDialogModule, MatIconTestingModule],
|
||||||
providers: [
|
providers: [
|
||||||
|
provideMockStore(),
|
||||||
{
|
{
|
||||||
provide: NodesApiService,
|
provide: NodesApiService,
|
||||||
useValue: {
|
useValue: {
|
||||||
@@ -84,6 +88,28 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
modalAiService = TestBed.inject(ModalAiService);
|
modalAiService = TestBed.inject(ModalAiService);
|
||||||
searchAiService = TestBed.inject(SearchAiService);
|
searchAiService = TestBed.inject(SearchAiService);
|
||||||
userPreferencesService = TestBed.inject(UserPreferencesService);
|
userPreferencesService = TestBed.inject(UserPreferencesService);
|
||||||
|
spyOn(TestBed.inject(AgentService), 'getAgents').and.returnValue(of([]));
|
||||||
|
TestBed.inject(Router);
|
||||||
|
store = TestBed.inject(MockStore);
|
||||||
|
|
||||||
|
store.overrideSelector(getCurrentFolder, {
|
||||||
|
isFolder: true,
|
||||||
|
id: 'folder1',
|
||||||
|
name: '',
|
||||||
|
nodeType: '',
|
||||||
|
isFile: false,
|
||||||
|
modifiedAt: undefined,
|
||||||
|
modifiedByUser: undefined,
|
||||||
|
createdAt: undefined,
|
||||||
|
createdByUser: undefined
|
||||||
|
});
|
||||||
|
store.overrideSelector(getAppSelection, {
|
||||||
|
nodes: [],
|
||||||
|
isEmpty: true,
|
||||||
|
count: 0,
|
||||||
|
libraries: []
|
||||||
|
});
|
||||||
|
|
||||||
askSpy = spyOn(searchAiService, 'ask').and.returnValue(of(questionMock));
|
askSpy = spyOn(searchAiService, 'ask').and.returnValue(of(questionMock));
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
@@ -93,13 +119,6 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
let textArea: HTMLTextAreaElement;
|
let textArea: HTMLTextAreaElement;
|
||||||
let toggleTriggerContainer: HTMLElement;
|
let toggleTriggerContainer: HTMLElement;
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
spyOn(userPreferencesService, 'get').and.returnValue(knowledgeRetrievalNodes);
|
|
||||||
mockQueryParams.next({ query: 'test', agentId: 'agentId1' });
|
|
||||||
fixture.detectChanges();
|
|
||||||
toggleTriggerContainer = fixture.debugElement.query(By.css('[data-automation-id="toggle-edit-trigger-container"]')).nativeElement;
|
|
||||||
});
|
|
||||||
|
|
||||||
const getToggleEditInputButton = (): HTMLButtonElement | undefined => {
|
const getToggleEditInputButton = (): HTMLButtonElement | undefined => {
|
||||||
return fixture.debugElement.query(By.css('[data-automation-id="toggle-edit-input-button"]'))?.nativeElement;
|
return fixture.debugElement.query(By.css('[data-automation-id="toggle-edit-input-button"]'))?.nativeElement;
|
||||||
};
|
};
|
||||||
@@ -133,6 +152,14 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
expect(component.searchQuery).toBe('test');
|
expect(component.searchQuery).toBe('test');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(userPreferencesService, 'get').and.returnValue(knowledgeRetrievalNodes);
|
||||||
|
spyOn(searchAiService, 'getAnswer').and.returnValue(of({ entry: { answer: 'Some answer', questionId: 'some id', references: [] } }));
|
||||||
|
mockQueryParams.next({ query: 'test', agentId: 'agentId1' });
|
||||||
|
fixture.detectChanges();
|
||||||
|
toggleTriggerContainer = fixture.debugElement.query(By.css('[data-automation-id="toggle-edit-trigger-container"]')).nativeElement;
|
||||||
|
});
|
||||||
|
|
||||||
it('should show toggle edit input button on mouseenter', () => {
|
it('should show toggle edit input button on mouseenter', () => {
|
||||||
toggleTriggerContainer.dispatchEvent(new MouseEvent('mouseenter'));
|
toggleTriggerContainer.dispatchEvent(new MouseEvent('mouseenter'));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@@ -151,10 +178,12 @@ describe('SearchAiResultsComponent', () => {
|
|||||||
|
|
||||||
it('should search for a new results after typing new query and clicking update button', () => {
|
it('should search for a new results after typing new query and clicking update button', () => {
|
||||||
insertTextIntoTextArea();
|
insertTextIntoTextArea();
|
||||||
|
spyOn(store, 'dispatch');
|
||||||
|
|
||||||
getUpdateInputButton().dispatchEvent(new MouseEvent('click'));
|
getUpdateInputButton().dispatchEvent(new MouseEvent('click'));
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(store.dispatch<SearchByTermAiAction>).toHaveBeenCalledWith(new SearchByTermAiAction({ searchTerm: 'new query', agentId: 'agentId1' }));
|
||||||
expect(getToggleEditInputTextArea()).toBeUndefined();
|
expect(getToggleEditInputTextArea()).toBeUndefined();
|
||||||
expect(component.editing).toBeFalse();
|
expect(component.editing).toBeFalse();
|
||||||
expect(component.searchQuery).toBe('new query');
|
expect(component.searchQuery).toBe('new query');
|
||||||
|
@@ -22,14 +22,13 @@
|
|||||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
import { ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { PageComponent, PageLayoutComponent, ToolbarActionComponent, ToolbarComponent } from '@alfresco/aca-shared';
|
import { PageComponent, PageLayoutComponent, ToolbarActionComponent, ToolbarComponent } from '@alfresco/aca-shared';
|
||||||
import { concatMap, delay, finalize, retryWhen, skipWhile, switchMap, takeUntil } from 'rxjs/operators';
|
import { concatMap, delay, finalize, retryWhen, skipWhile, switchMap, takeUntil } from 'rxjs/operators';
|
||||||
import {
|
import {
|
||||||
AvatarComponent,
|
AvatarComponent,
|
||||||
ClipboardService,
|
ClipboardService,
|
||||||
CoreModule,
|
|
||||||
EmptyContentComponent,
|
EmptyContentComponent,
|
||||||
ThumbnailService,
|
ThumbnailService,
|
||||||
ToolbarModule,
|
ToolbarModule,
|
||||||
@@ -52,6 +51,7 @@ import { ModalAiService } from '../../../../services/modal-ai.service';
|
|||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { AiSearchByTermPayload, SearchByTermAiAction } from '@alfresco/aca-shared/store';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
standalone: true,
|
standalone: true,
|
||||||
@@ -71,7 +71,6 @@ import { FormsModule } from '@angular/forms';
|
|||||||
AvatarComponent,
|
AvatarComponent,
|
||||||
MatTooltipModule,
|
MatTooltipModule,
|
||||||
ToggleIconDirective,
|
ToggleIconDirective,
|
||||||
CoreModule,
|
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
FormsModule
|
FormsModule
|
||||||
@@ -97,6 +96,9 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
|
|||||||
|
|
||||||
searchQuery = '';
|
searchQuery = '';
|
||||||
|
|
||||||
|
@ViewChild('editTextArea')
|
||||||
|
editTextArea: ElementRef;
|
||||||
|
|
||||||
get agentId(): string {
|
get agentId(): string {
|
||||||
return this._agentId;
|
return this._agentId;
|
||||||
}
|
}
|
||||||
@@ -137,7 +139,8 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
|
|||||||
private userPreferencesService: UserPreferencesService,
|
private userPreferencesService: UserPreferencesService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
private unsavedChangesGuard: UnsavedChangesGuard,
|
private unsavedChangesGuard: UnsavedChangesGuard,
|
||||||
private modalAiService: ModalAiService
|
private modalAiService: ModalAiService,
|
||||||
|
private cdr: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
@@ -171,10 +174,19 @@ export class SearchAiResultsComponent extends PageComponent implements OnInit, O
|
|||||||
setEditing(editing: boolean) {
|
setEditing(editing: boolean) {
|
||||||
this._initSearchQuery = this.searchQuery;
|
this._initSearchQuery = this.searchQuery;
|
||||||
this._editing = editing;
|
this._editing = editing;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
if (this.editTextArea) {
|
||||||
|
this.editTextArea.nativeElement.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateInput() {
|
updateInput() {
|
||||||
if (this.searchQuery !== this._initSearchQuery && this.searchQuery.length > 0) {
|
if (this.searchQuery !== this._initSearchQuery && this.searchQuery.length > 0) {
|
||||||
|
const payload: AiSearchByTermPayload = {
|
||||||
|
searchTerm: this.searchQuery,
|
||||||
|
agentId: this._agentId
|
||||||
|
};
|
||||||
|
this.store.dispatch(new SearchByTermAiAction(payload));
|
||||||
this.performAiSearch();
|
this.performAiSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -106,6 +106,7 @@ $defaults: (
|
|||||||
--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-text-light-color: $text-light-color,
|
||||||
--theme-card-background-grey-color: $card-background-grey-color,
|
--theme-card-background-grey-color: $card-background-grey-color,
|
||||||
|
--theme-form-field-background-grey-color: $card-background-grey-color,
|
||||||
--theme-light-grey-1-color: $light-grey-1,
|
--theme-light-grey-1-color: $light-grey-1,
|
||||||
--theme-light-grey-2-color: $light-grey-2,
|
--theme-light-grey-2-color: $light-grey-2,
|
||||||
--theme-light-grey-3-color: $light-grey-3
|
--theme-light-grey-3-color: $light-grey-3
|
||||||
|
Reference in New Issue
Block a user