-
+
+
+
+
{{ property.displayValue }}
-
- {{ property.displayValue }}
+
+
+
-
+
+ {{ property.displayValue }}
+
-
- clear
-
-
-
-
-
-
-
-
-
-
-
-
- {{ property.default | translate }}
-
+
+ clear
+
-
-
-
- {{ propertyValue }}
- cancel
-
-
+
+
+
-
-
-
+
+
+ {{ property.default | translate }}
+
+
+
+
+
+ {{ propertyValue }}
+ cancel
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.scss b/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.scss
index dd6aa7bc54f..f85b9940fca 100644
--- a/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.scss
+++ b/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.scss
@@ -6,7 +6,6 @@
padding-bottom: 6px;
line-height: 20px;
color: var(--adf-metadata-property-panel-title-color);
- border-bottom: 1px solid var(--adf-metadata-property-panel-border-color);
margin-top: 10px;
&.adf-property-value-editable {
@@ -14,8 +13,8 @@
align-items: center;
justify-content: flex-end;
border-radius: 6px;
- border-bottom: inherit;
margin-bottom: 18px;
+ width: 100%;
}
&.adf-property-readonly-value {
diff --git a/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.ts b/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
index 6f83a51cbb4..d214556bc43 100644
--- a/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
+++ b/lib/core/src/lib/card-view/components/card-view-dateitem/card-view-dateitem.component.ts
@@ -49,6 +49,9 @@ export class CardViewDateItemComponent extends BaseCardView
;
diff --git a/lib/core/src/lib/card-view/components/card-view-item-dispatcher/card-view-item-dispatcher.component.ts b/lib/core/src/lib/card-view/components/card-view-item-dispatcher/card-view-item-dispatcher.component.ts
index 0217cbc9b82..122bf2801b4 100644
--- a/lib/core/src/lib/card-view/components/card-view-item-dispatcher/card-view-item-dispatcher.component.ts
+++ b/lib/core/src/lib/card-view/components/card-view-item-dispatcher/card-view-item-dispatcher.component.ts
@@ -32,27 +32,30 @@ export class CardViewItemDispatcherComponent implements OnChanges {
editable: boolean;
@Input()
- displayEmpty: boolean = true;
+ displayEmpty = true;
@Input()
- displayNoneOption: boolean = true;
+ displayNoneOption = true;
@Input()
- displayClearAction: boolean = true;
+ displayClearAction = true;
@Input()
- copyToClipboardAction: boolean = true;
+ copyToClipboardAction = true;
@Input()
- useChipsForMultiValueProperty: boolean = true;
+ useChipsForMultiValueProperty = true;
@Input()
- multiValueSeparator: string = DEFAULT_SEPARATOR;
+ multiValueSeparator = DEFAULT_SEPARATOR;
@Input()
- displayLabelForChips: boolean = false;
+ displayLabelForChips = false;
- private loaded: boolean = false;
+ @Input()
+ hasContentEnrichment = false;
+
+ private loaded = false;
private componentReference: any = null;
public ngOnInit;
@@ -104,6 +107,7 @@ export class CardViewItemDispatcherComponent implements OnChanges {
this.componentReference.instance.useChipsForMultiValueProperty = this.useChipsForMultiValueProperty;
this.componentReference.instance.multiValueSeparator = this.multiValueSeparator;
this.componentReference.instance.displayLabelForChips = this.displayLabelForChips;
+ this.componentReference.instance.hasContentEnrichment = this.hasContentEnrichment;
}
private proxy(methodName, ...args) {
diff --git a/lib/core/src/lib/card-view/components/card-view-selectitem/card-view-selectitem.component.html b/lib/core/src/lib/card-view/components/card-view-selectitem/card-view-selectitem.component.html
index 8aeacf38062..0e4e88991b1 100644
--- a/lib/core/src/lib/card-view/components/card-view-selectitem/card-view-selectitem.component.html
+++ b/lib/core/src/lib/card-view/components/card-view-selectitem/card-view-selectitem.component.html
@@ -12,9 +12,12 @@
*ngIf="!isEditable"
class="adf-property-value adf-property-read-only"
[attr.data-automation-id]="'select-readonly-value-' + property.key"
- data-automation-class="read-only-value">{{ (property.displayValue | async) | translate }}
+ data-automation-class="read-only-value">
+
+ {{ (property.displayValue | async) | translate }}
-
+
+
[]>;
@Input()
- displayNoneOption: boolean = true;
+ displayNoneOption = true;
@Input()
- displayEmpty: boolean = true;
+ displayEmpty = true;
+
+ @Input()
+ hasContentEnrichment = false;
value: string | number;
filter$ = new BehaviorSubject('');
@@ -50,6 +53,7 @@ export class CardViewSelectItemComponent extends BaseCardView
+
diff --git a/lib/core/src/lib/card-view/components/card-view/card-view.component.scss b/lib/core/src/lib/card-view/components/card-view/card-view.component.scss
index d1e713bd530..dbcfe8aa0d2 100644
--- a/lib/core/src/lib/card-view/components/card-view/card-view.component.scss
+++ b/lib/core/src/lib/card-view/components/card-view/card-view.component.scss
@@ -24,6 +24,16 @@
margin-bottom: 12px;
}
+ .adf-property-value-wrapper {
+ display: flex;
+ align-items: center;
+ border-bottom: 1px solid var(--adf-metadata-property-panel-border-color);
+
+ adf-content-enrichment-menu button.adf-ai-button {
+ margin-left: -10px;
+ }
+ }
+
.adf-property {
.adf-property-field {
width: 100%;
@@ -48,6 +58,7 @@
#{$mat-form--text-field-infix} {
border-top-width: 0;
+ position: initial;
}
#{$mat-form-field-flex} {
diff --git a/lib/core/src/lib/card-view/interfaces/base-card-view-update.interface.ts b/lib/core/src/lib/card-view/interfaces/base-card-view-update.interface.ts
index b23c4f52c4d..b4f61d461d0 100644
--- a/lib/core/src/lib/card-view/interfaces/base-card-view-update.interface.ts
+++ b/lib/core/src/lib/card-view/interfaces/base-card-view-update.interface.ts
@@ -19,13 +19,16 @@ import { Subject } from 'rxjs';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
import { UpdateNotification } from './update-notification.interface';
import { ClickNotification } from './click-notification.interface';
+import { PredictionStatusUpdate } from '../../prediction';
export interface BaseCardViewUpdate {
itemUpdated$: Subject
;
itemClicked$: Subject;
updateItem$: Subject;
+ predictionStatusChanged$: Subject;
update(property: CardViewBaseItemModel, newValue: any);
clicked(property: CardViewBaseItemModel);
updateElement(notification: CardViewBaseItemModel);
+ onPredictionStatusChanged(notification: PredictionStatusUpdate[]);
}
diff --git a/lib/core/src/lib/card-view/interfaces/card-view-item-properties.interface.ts b/lib/core/src/lib/card-view/interfaces/card-view-item-properties.interface.ts
index 04d49ef525e..cc5db8d91f1 100644
--- a/lib/core/src/lib/card-view/interfaces/card-view-item-properties.interface.ts
+++ b/lib/core/src/lib/card-view/interfaces/card-view-item-properties.interface.ts
@@ -16,6 +16,7 @@
*/
import { CardViewItemValidator } from './card-view-item-validator.interface';
+import { Prediction } from '@alfresco/js-api';
export interface CardViewItemProperties {
label: string;
@@ -36,4 +37,5 @@ export interface CardViewItemProperties {
parameters?: { [key: string]: any };
}>;
multivalued?: boolean;
+ prediction?: Prediction;
}
diff --git a/lib/core/src/lib/card-view/interfaces/card-view-item.interface.ts b/lib/core/src/lib/card-view/interfaces/card-view-item.interface.ts
index 0dccaa0e3b5..846305a87bc 100644
--- a/lib/core/src/lib/card-view/interfaces/card-view-item.interface.ts
+++ b/lib/core/src/lib/card-view/interfaces/card-view-item.interface.ts
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+import { Prediction } from '@alfresco/js-api';
+
export interface CardViewItem {
label: string;
value: any;
@@ -24,4 +26,5 @@ export interface CardViewItem {
displayValue: any;
editable?: boolean;
icon?: string;
+ prediction?: Prediction;
}
diff --git a/lib/core/src/lib/card-view/models/card-view-baseitem.model.ts b/lib/core/src/lib/card-view/models/card-view-baseitem.model.ts
index 953d131b172..331678b69fb 100644
--- a/lib/core/src/lib/card-view/models/card-view-baseitem.model.ts
+++ b/lib/core/src/lib/card-view/models/card-view-baseitem.model.ts
@@ -17,6 +17,7 @@
import { CardViewItemProperties, CardViewItemValidator } from '../interfaces/card-view.interfaces';
import validatorsMap from '../validators/validators.map';
+import { Prediction } from '@alfresco/js-api';
export abstract class CardViewBaseItemModel {
label: string;
@@ -31,6 +32,7 @@ export abstract class CardViewBaseItemModel {
data?: any;
type?: string;
multivalued?: boolean;
+ prediction?: Prediction;
constructor(props: CardViewItemProperties) {
this.label = props.label || '';
@@ -44,6 +46,7 @@ export abstract class CardViewBaseItemModel {
this.validators = props.validators || [];
this.data = props.data || null;
this.multivalued = !!props.multivalued;
+ this.prediction = props.prediction || null;
if (props?.constraints?.length ?? 0) {
for (const constraint of props.constraints) {
diff --git a/lib/core/src/lib/card-view/models/card-view-selectitem.model.spec.ts b/lib/core/src/lib/card-view/models/card-view-selectitem.model.spec.ts
index e0715c5a845..9b56397eca3 100644
--- a/lib/core/src/lib/card-view/models/card-view-selectitem.model.spec.ts
+++ b/lib/core/src/lib/card-view/models/card-view-selectitem.model.spec.ts
@@ -57,5 +57,14 @@ describe('CardViewSelectItemModel', () => {
expect(itemModel.displayNoneOption).toBe(false);
}));
+
+ it('should update the value when new value is set', (done) => {
+ const itemModel = new CardViewSelectItemModel(properties);
+ itemModel.setValue('three');
+ itemModel.displayValue.subscribe((value) => {
+ expect(value).toBe(mockData[2].label);
+ done();
+ });
+ });
});
});
diff --git a/lib/core/src/lib/card-view/models/card-view-selectitem.model.ts b/lib/core/src/lib/card-view/models/card-view-selectitem.model.ts
index 836f6bcd39b..fb2b4d47833 100644
--- a/lib/core/src/lib/card-view/models/card-view-selectitem.model.ts
+++ b/lib/core/src/lib/card-view/models/card-view-selectitem.model.ts
@@ -19,8 +19,8 @@ import { CardViewItem } from '../interfaces/card-view-item.interface';
import { DynamicComponentModel } from '../../common/services/dynamic-component-mapper.service';
import { CardViewBaseItemModel } from './card-view-baseitem.model';
import { CardViewSelectItemProperties, CardViewSelectItemOption } from '../interfaces/card-view.interfaces';
-import { Observable, of } from 'rxjs';
-import { switchMap } from 'rxjs/operators';
+import { BehaviorSubject, Observable } from 'rxjs';
+import { map, switchMap } from 'rxjs/operators';
export class CardViewSelectItemModel extends CardViewBaseItemModel implements CardViewItem, DynamicComponentModel {
type = 'select';
@@ -29,6 +29,8 @@ export class CardViewSelectItemModel extends CardViewBaseItemModel implements
valueFetch$: Observable = null;
+ private valueSubject = new BehaviorSubject(this.value);
+
constructor(cardViewSelectItemProperties: CardViewSelectItemProperties) {
super(cardViewSelectItemProperties);
@@ -36,11 +38,13 @@ export class CardViewSelectItemModel extends CardViewBaseItemModel implements
this.options$ = cardViewSelectItemProperties.options$;
- this.valueFetch$ = this.options$.pipe(
- switchMap((options) => {
- const option = options.find((o) => o.key === this.value?.toString());
- return of(option ? option.label : '');
- })
+ this.valueFetch$ = this.valueSubject.pipe(
+ switchMap((value) => this.options$.pipe(
+ map((options) => {
+ const option = options.find((o) => o.key === value?.toString());
+ return option ? option.label : '';
+ })
+ ))
);
}
@@ -50,5 +54,6 @@ export class CardViewSelectItemModel extends CardViewBaseItemModel implements
setValue(value: any) {
this.value = value;
+ this.valueSubject.next(value);
}
}
diff --git a/lib/core/src/lib/card-view/services/card-view-update.service.spec.ts b/lib/core/src/lib/card-view/services/card-view-update.service.spec.ts
index 9cafb71390b..882c96e102d 100644
--- a/lib/core/src/lib/card-view/services/card-view-update.service.spec.ts
+++ b/lib/core/src/lib/card-view/services/card-view-update.service.spec.ts
@@ -18,6 +18,7 @@
import { fakeAsync, TestBed } from '@angular/core/testing';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
import { CardViewUpdateService, transformKeyToObject } from './card-view-update.service';
+import { PredictionStatusUpdate } from '../../prediction/interfaces/prediction-status-update.interface';
describe('CardViewUpdateService', () => {
@@ -82,5 +83,14 @@ describe('CardViewUpdateService', () => {
);
cardViewUpdateService.clicked(property);
}));
+
+ it('should emit predictionStatusChanged$ when onPredictionStatusChanged is called', (done) => {
+ const mockPredictionStatusUpdate: PredictionStatusUpdate[] = [{ key: 'test', previousValue: 'value' }];
+ cardViewUpdateService.predictionStatusChanged$.subscribe((value) => {
+ expect(value).toEqual(mockPredictionStatusUpdate);
+ done();
+ });
+ cardViewUpdateService.onPredictionStatusChanged(mockPredictionStatusUpdate);
+ });
});
});
diff --git a/lib/core/src/lib/card-view/services/card-view-update.service.ts b/lib/core/src/lib/card-view/services/card-view-update.service.ts
index 5a625b3dbad..1c6b61ab71f 100644
--- a/lib/core/src/lib/card-view/services/card-view-update.service.ts
+++ b/lib/core/src/lib/card-view/services/card-view-update.service.ts
@@ -21,6 +21,7 @@ import { BaseCardViewUpdate } from '../interfaces/base-card-view-update.interfac
import { ClickNotification } from '../interfaces/click-notification.interface';
import { UpdateNotification } from '../interfaces/update-notification.interface';
import { CardViewBaseItemModel } from '../models/card-view-baseitem.model';
+import { PredictionStatusUpdate } from '../../prediction/interfaces/prediction-status-update.interface';
export const transformKeyToObject = (key: string, value): any => {
const objectLevels: string[] = key.split('.').reverse();
@@ -36,6 +37,7 @@ export class CardViewUpdateService implements BaseCardViewUpdate {
itemUpdated$ = new Subject();
itemClicked$ = new Subject();
updateItem$ = new Subject();
+ predictionStatusChanged$ = new Subject();
update(property: CardViewBaseItemModel, newValue: any) {
this.itemUpdated$.next({
@@ -59,4 +61,7 @@ export class CardViewUpdateService implements BaseCardViewUpdate {
this.updateItem$.next(notification);
}
+ onPredictionStatusChanged(notification: PredictionStatusUpdate[]) {
+ this.predictionStatusChanged$.next(notification);
+ }
}
diff --git a/lib/core/src/lib/common/services/thumbnail.service.ts b/lib/core/src/lib/common/services/thumbnail.service.ts
index 053e794b7aa..d54345db424 100644
--- a/lib/core/src/lib/common/services/thumbnail.service.ts
+++ b/lib/core/src/lib/common/services/thumbnail.service.ts
@@ -158,7 +158,8 @@ export class ThumbnailService {
'save-as': './assets/images/save-as.svg',
save: './assets/images/save.svg',
task: './assets/images/task.svg',
- 'multipart/related': './assets/images/ft_ic_website.svg'
+ 'multipart/related': './assets/images/ft_ic_website.svg',
+ 'ai-sparkles': './assets/images/ai-sparkles.svg'
};
constructor(matIconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
diff --git a/lib/core/src/lib/common/utils/object-utils.spec.ts b/lib/core/src/lib/common/utils/object-utils.spec.ts
index 4794504062d..6fa5bc01742 100644
--- a/lib/core/src/lib/common/utils/object-utils.spec.ts
+++ b/lib/core/src/lib/common/utils/object-utils.spec.ts
@@ -18,7 +18,6 @@
import { ObjectUtils } from './object-utils';
describe('ObjectUtils', () => {
-
it('should get top level property value', () => {
const obj = {
id: 1
@@ -246,4 +245,19 @@ describe('ObjectUtils', () => {
expect(ObjectUtils.booleanPrettify(obj, enhancer)).toBe('✅ testOnetest\n❌ testTwotest');
});
});
+
+ describe('isValueDefined', () => {
+ it('should return true for defined values', () => {
+ expect(ObjectUtils.isValueDefined(0)).toBe(true);
+ expect(ObjectUtils.isValueDefined('')).toBe(true);
+ expect(ObjectUtils.isValueDefined([])).toBe(true);
+ expect(ObjectUtils.isValueDefined({})).toBe(true);
+ expect(ObjectUtils.isValueDefined(false)).toBe(true);
+ });
+
+ it('should return false for undefined or null values', () => {
+ expect(ObjectUtils.isValueDefined(undefined)).toBe(false);
+ expect(ObjectUtils.isValueDefined(null)).toBe(false);
+ });
+ });
});
diff --git a/lib/core/src/lib/common/utils/object-utils.ts b/lib/core/src/lib/common/utils/object-utils.ts
index 67cf7dddea6..7d647846347 100644
--- a/lib/core/src/lib/common/utils/object-utils.ts
+++ b/lib/core/src/lib/common/utils/object-utils.ts
@@ -25,7 +25,6 @@ export class ObjectUtils {
* @returns object property value
*/
static getValue(target: any, key: string): any {
-
if (!target || !key) {
return undefined;
}
@@ -80,47 +79,43 @@ export class ObjectUtils {
}
static isBooleanObject(target: any): boolean {
- return Object.values(target).every(value => typeof value === 'boolean');
+ return Object.values(target).every((value) => typeof value === 'boolean');
}
static booleanPrettify(target: any, enhancer?: (param: string) => string): string {
-
- if (
- !target ||
- ObjectUtils.isEmpty(target) ||
- !ObjectUtils.isBooleanObject(target)
- ) {
+ if (!target || ObjectUtils.isEmpty(target) || !ObjectUtils.isBooleanObject(target)) {
return '';
}
- if (
- !ObjectUtils.isObject(target) ||
- !ObjectUtils.hasKeys(target)
- ) {
+ if (!ObjectUtils.isObject(target) || !ObjectUtils.hasKeys(target)) {
return target.toString();
}
const greenBorderWhiteCheckSymbol = '✅';
const redCrossSymbol = '❌';
- target = Object.keys(target).map((key) => {
- if (target[key]) {
+ target = Object.keys(target)
+ .map((key) => {
+ if (target[key]) {
+ if (enhancer) {
+ return `${greenBorderWhiteCheckSymbol} ${enhancer(key)}`;
+ } else {
+ return `${greenBorderWhiteCheckSymbol} ${key}`;
+ }
+ }
+
if (enhancer) {
- return `${greenBorderWhiteCheckSymbol} ${enhancer(key)}`;
+ return `${redCrossSymbol} ${enhancer(key)}`;
} else {
- return `${greenBorderWhiteCheckSymbol} ${key}`;
+ return `${redCrossSymbol} ${key}`;
}
-
- }
-
- if (enhancer) {
- return `${redCrossSymbol} ${enhancer(key)}`;
- } else {
- return `${redCrossSymbol} ${key}`;
- }
-
- }).join('\n');
+ })
+ .join('\n');
return target;
}
+
+ static isValueDefined(value: any): boolean {
+ return value !== undefined && value !== null;
+ }
}
diff --git a/lib/core/src/lib/i18n/en.json b/lib/core/src/lib/i18n/en.json
index 72e69bb1736..0442aa1452a 100644
--- a/lib/core/src/lib/i18n/en.json
+++ b/lib/core/src/lib/i18n/en.json
@@ -248,6 +248,19 @@
"DATEPICKER": "Use the arrow keys to navigate between dates. Up and down move to the next or previous week but on the same day. Left and right move to the next or previous day. Press Enter or Return to select a date.",
"COPY_TO_CLIPBOARD_MESSAGE": "Value copied to clipboard",
"EDIT_ASPECTS": "Edit Aspect"
+ },
+ "CONTENT_ENRICHMENT": {
+ "ACCURACY_LEVEL": "Accuracy Level",
+ "ACCURACY_DESCRIPTION": "This score represents the quality of the suggestion.",
+ "LAST_VALUE": "Last user value",
+ "CURRENT_VALUE": "Current Value",
+ "ACTIONS": {
+ "REVERT": "Revert",
+ "CONFIRM": "Confirm"
+ },
+ "ARIA-LABEL": {
+ "OPEN-MENU": "Open content enrichment menu"
+ }
}
},
"SEARCH": {
diff --git a/lib/core/src/lib/pipes/user-like.interface.ts b/lib/core/src/lib/pipes/user-like.interface.ts
index 4e6daf35bec..c7d0fc722c6 100644
--- a/lib/core/src/lib/pipes/user-like.interface.ts
+++ b/lib/core/src/lib/pipes/user-like.interface.ts
@@ -20,4 +20,4 @@ export interface UserLike {
firstName?: string;
lastName?: string;
email?: string;
-};
+}
diff --git a/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.html b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.html
new file mode 100644
index 00000000000..c76735add2b
--- /dev/null
+++ b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.html
@@ -0,0 +1,56 @@
+
+
+
diff --git a/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.scss b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.scss
new file mode 100644
index 00000000000..178f7b79cc0
--- /dev/null
+++ b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.scss
@@ -0,0 +1,135 @@
+adf-content-enrichment-menu {
+ svg {
+ height: 17px;
+ width: 17px;
+ }
+}
+
+.adf-ai-mat-menu {
+ border: 1px solid transparent;
+ border-radius: 6px;
+ background-image: linear-gradient(var(--adf-theme-background-dialog-color), var(--adf-theme-background-dialog-color)),
+ var(--adf-ai-border-gradient);
+ background-origin: border-box;
+ background-clip: content-box, border-box;
+}
+
+.adf-content-enrichment-menu {
+ padding: 5px 10px;
+
+ &__accuracy {
+ display: flex;
+ align-items: center;
+ margin-bottom: 18px;
+ justify-content: space-between;
+
+ &__title {
+ span {
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 16px;
+ letter-spacing: 0.5px;
+ text-align: left;
+ }
+
+ p {
+ font-size: 12px;
+ font-weight: 400;
+ line-height: 16px;
+ letter-spacing: 0.5px;
+ text-align: left;
+ margin: 0;
+ }
+ }
+
+ &__level {
+ display: flex;
+ align-items: center;
+
+ span {
+ width: 0;
+ position: relative;
+ left: 14px;
+ font-size: 17.96px;
+ font-weight: 700;
+ line-height: 25.66px;
+ letter-spacing: 0.1924px;
+ }
+
+ .adf-accuracy-level-spinner circle {
+ stroke: var(--theme-accent-color);
+ }
+ }
+ }
+
+ &__content {
+ padding: 18px 10px;
+ border: 1px solid var(--adf-metadata-property-panel-border-color);
+ border-radius: 12px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 30px;
+
+ &__label {
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 20px;
+ letter-spacing: 0.25px;
+ text-align: left;
+ margin: 0 0 4px;
+
+ span {
+ font-size: 10px;
+ font-weight: 500;
+ line-height: 16px;
+ letter-spacing: 0.2px;
+ text-align: left;
+ }
+ }
+
+ &__last {
+ width: 100%;
+
+ &__value {
+ background: var(--adf-theme-foreground-text-color-007);
+ border-radius: 6px;
+ padding: 7px;
+ min-height: 19px;
+ }
+ }
+
+ &__current {
+ width: 100%;
+
+ &__value {
+ padding: 7px;
+ border: 2px dashed var(--adf-metadata-property-panel-border-color);
+ border-radius: 6px;
+ display: flex;
+ align-items: center;
+
+ mat-icon {
+ width: 17px;
+ height: 17px;
+ margin-right: 10px;
+ }
+ }
+ }
+
+ mat-icon {
+ color: var(--adf-theme-foreground-text-color-054);
+ }
+ }
+
+ &__footer {
+ margin-top: 18px;
+ text-align: end;
+
+ .adf-confirm-button {
+ margin-left: 8px;
+ color: var(--adf-theme-foreground-base-color);
+ background-color: var(--theme-grey-text-background-color);
+ }
+ }
+}
diff --git a/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.spec.ts b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.spec.ts
new file mode 100644
index 00000000000..e89870e66a1
--- /dev/null
+++ b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.spec.ts
@@ -0,0 +1,172 @@
+/*!
+ * @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 { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { By } from '@angular/platform-browser';
+import { of } from 'rxjs';
+import { ContentEnrichmentMenuComponent } from './content-enrichment-menu.component';
+import { PredictionService } from '../../services';
+import { CoreTestingModule } from '../../../testing/core.testing.module';
+import { LocalizedDatePipe } from '../../../pipes/localized-date.pipe';
+import { Prediction, ReviewStatus } from '@alfresco/js-api';
+
+describe('ContentEnrichmentMenuComponent', () => {
+ let component: ContentEnrichmentMenuComponent;
+ let fixture: ComponentFixture;
+ let predictionService: PredictionService;
+ let localizedDatePipe: LocalizedDatePipe;
+
+ const predictionMock: Prediction = {
+ confidenceLevel: 0.9,
+ predictionDateTime: new Date(2022, 1, 1),
+ modelId: 'test-model-id',
+ property: 'test:test',
+ id: 'test-prediction-id',
+ previousValue: 'previous value',
+ predictionValue: 'new value',
+ updateType: 'AUTOCORRECT',
+ reviewStatus: ReviewStatus.UNREVIEWED
+ };
+
+ const openMenu = () => {
+ const button = fixture.debugElement.query(By.css('.adf-ai-button')).nativeElement;
+ button.click();
+ fixture.detectChanges();
+ };
+
+ beforeEach(async () => {
+ const predictionServiceMock = {
+ reviewPrediction: jasmine.createSpy('reviewPrediction').and.returnValue(of(null)),
+ predictionStatusUpdated$: {next: jasmine.createSpy('next')}
+ };
+
+ await TestBed.configureTestingModule({
+ imports: [ContentEnrichmentMenuComponent, CoreTestingModule, MatProgressSpinnerModule],
+ providers: [{provide: PredictionService, useValue: predictionServiceMock}]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(ContentEnrichmentMenuComponent);
+ component = fixture.componentInstance;
+ component.prediction = {...predictionMock};
+ predictionService = TestBed.inject(PredictionService);
+ localizedDatePipe = TestBed.inject(LocalizedDatePipe);
+ fixture.detectChanges();
+ });
+
+ it('should initialize properties when prediction is provided', () => {
+ expect(component.confidencePercentage).toBe(90);
+ expect(component.previousValue).toBe('previous value');
+ expect(component.predictionValue).toBe('new value');
+ expect(component.predictionDateTime).toEqual(predictionMock.predictionDateTime);
+ });
+
+ it('should initialize properties with default values when prediction is not provided', () => {
+ component.prediction = null;
+ component.ngOnInit();
+
+ expect(component.confidencePercentage).toBe(0);
+ expect(component.previousValue).toBe('');
+ expect(component.predictionValue).toBe('');
+ expect(component.predictionDateTime).toBeNull();
+ });
+
+ it('should correctly set boolean values', () => {
+ component.prediction.previousValue = false;
+ component.prediction.predictionValue = true;
+ component.ngOnInit();
+
+ expect(component.previousValue).toBeFalse();
+ expect(component.predictionValue).toBeTrue();
+ });
+
+ it('should call reviewPrediction with REJECTED on revert', () => {
+ component.onRevert();
+ expect(predictionService.reviewPrediction).toHaveBeenCalledWith(component.prediction.id, ReviewStatus.REJECTED);
+ });
+
+ it('should call reviewPrediction with CONFIRMED on confirm', () => {
+ component.onConfirm();
+ expect(predictionService.reviewPrediction).toHaveBeenCalledWith(component.prediction.id, ReviewStatus.CONFIRMED);
+ });
+
+ it('should emit predictionStatusUpdated$ on confirm', () => {
+ component.onConfirm();
+ expect(predictionService.predictionStatusUpdated$.next).toHaveBeenCalledWith({key: component.prediction.property});
+ });
+
+ it('should emit predictionStatusUpdated$ on revert', () => {
+ component.onRevert();
+ expect(predictionService.predictionStatusUpdated$.next).toHaveBeenCalledWith({
+ key: component.prediction.property,
+ previousValue: component.previousValue
+ });
+ });
+
+ it('should close the menu on revert', () => {
+ const menuTriggerSpy = spyOn(component.menuTrigger, 'closeMenu');
+ component.onRevert();
+ expect(menuTriggerSpy).toHaveBeenCalled();
+ });
+
+ it('should close the menu on confirm', () => {
+ const menuTriggerSpy = spyOn(component.menuTrigger, 'closeMenu');
+ component.onConfirm();
+ expect(menuTriggerSpy).toHaveBeenCalled();
+ });
+
+ it('should open the menu on button click', () => {
+ spyOn(component, 'onMenuOpen');
+ openMenu();
+ expect(component.onMenuOpen).toHaveBeenCalled();
+ });
+
+ it('should correctly format predictionDateTime using adfLocalizedDate', () => {
+ const formattedDate = localizedDatePipe.transform(component.predictionDateTime, 'MM/dd/yyyy');
+ openMenu();
+ const dateElement = fixture.debugElement.query(By.css('.adf-content-enrichment-menu__content__label span')).nativeElement;
+ expect(dateElement.textContent).toContain(formattedDate);
+ });
+
+ it('should render progress spinner with correct value', () => {
+ openMenu();
+ const spinnerElement = fixture.debugElement.query(By.css('.adf-accuracy-level-spinner'));
+ expect(spinnerElement.nativeElement).toBeDefined();
+ expect(spinnerElement.componentInstance.value).toEqual(component.confidencePercentage);
+ });
+
+ it('should render previous human entered value', () => {
+ openMenu();
+ const previousValueElement = fixture.debugElement.query(By.css('.adf-content-enrichment-menu__content__last__value')).nativeElement;
+ expect(previousValueElement.textContent).toContain(component.previousValue);
+ });
+
+ it('should display "None" as previous value when previousValue is not defined', () => {
+ component.prediction.previousValue = null;
+ component.ngOnInit();
+ openMenu();
+ const previousValueElement = fixture.debugElement.query(By.css('.adf-content-enrichment-menu__content__last__value')).nativeElement;
+ expect(previousValueElement.textContent).toContain('None');
+ });
+
+ it('should render predicted value', () => {
+ openMenu();
+ const predictionValueElement = fixture.debugElement.query(By.css('.adf-content-enrichment-menu__content__current__value span')).nativeElement;
+ expect(predictionValueElement.textContent).toContain(component.predictionValue);
+ });
+});
diff --git a/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.ts b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.ts
new file mode 100644
index 00000000000..cb1b9286af2
--- /dev/null
+++ b/lib/core/src/lib/prediction/components/content-enrichment-menu/content-enrichment-menu.component.ts
@@ -0,0 +1,98 @@
+/*!
+ * @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 { Component, ElementRef, Input, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
+import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { MatMenuModule, MatMenuTrigger } from '@angular/material/menu';
+import { MatIconModule } from '@angular/material/icon';
+import { MatButtonModule } from '@angular/material/button';
+import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from '@angular/cdk/a11y';
+import { TranslateModule } from '@ngx-translate/core';
+import { Prediction, ReviewStatus } from '@alfresco/js-api';
+import { IconComponent } from '../../../icon';
+import { LocalizedDatePipe } from '../../../pipes';
+import { PredictionService } from '../../services';
+import { ObjectUtils } from '../../../common';
+
+@Component({
+ standalone: true,
+ selector: 'adf-content-enrichment-menu',
+ templateUrl: './content-enrichment-menu.component.html',
+ styleUrls: ['./content-enrichment-menu.component.scss'],
+ encapsulation: ViewEncapsulation.None,
+ imports: [
+ MatProgressSpinnerModule,
+ MatTooltipModule,
+ MatButtonModule,
+ IconComponent,
+ MatMenuModule,
+ MatIconModule,
+ TranslateModule,
+ LocalizedDatePipe
+ ]
+})
+export class ContentEnrichmentMenuComponent implements OnInit {
+ @Input()
+ prediction: Prediction;
+
+ @ViewChild('menuContainer', { static: false })
+ menuContainer: ElementRef;
+
+ @ViewChild('menuTrigger', { static: false })
+ menuTrigger: MatMenuTrigger;
+
+ focusTrap: ConfigurableFocusTrap;
+ confidencePercentage: number;
+ previousValue: any;
+ predictionValue: any;
+ predictionDateTime: Date;
+
+ constructor(private predictionService: PredictionService, private focusTrapFactory: ConfigurableFocusTrapFactory) {}
+
+ ngOnInit() {
+ this.confidencePercentage = this.prediction?.confidenceLevel * 100 || 0;
+ this.previousValue = ObjectUtils.isValueDefined(this.prediction?.previousValue) ? this.prediction.previousValue : '';
+ this.predictionValue = ObjectUtils.isValueDefined(this.prediction?.predictionValue) ? this.prediction.predictionValue : '';
+ this.predictionDateTime = this.prediction?.predictionDateTime || null;
+ }
+
+ onMenuOpen() {
+ if (this.menuContainer && !this.focusTrap) {
+ this.focusTrap = this.focusTrapFactory.create(this.menuContainer.nativeElement);
+ }
+ }
+
+ onRevert() {
+ this.predictionService.reviewPrediction(this.prediction.id, ReviewStatus.REJECTED).subscribe(() => {
+ this.predictionService.predictionStatusUpdated$.next({ key: this.prediction.property, previousValue: this.previousValue });
+ this.menuTrigger.closeMenu();
+ });
+ }
+
+ onConfirm() {
+ this.predictionService.reviewPrediction(this.prediction.id, ReviewStatus.CONFIRMED).subscribe(() => {
+ this.predictionService.predictionStatusUpdated$.next({ key: this.prediction.property });
+ this.menuTrigger.closeMenu();
+ });
+ }
+
+ onClosed() {
+ this.focusTrap.destroy();
+ this.focusTrap = null;
+ }
+}
diff --git a/lib/core/src/lib/prediction/feature-flag.ts b/lib/core/src/lib/prediction/feature-flag.ts
new file mode 100644
index 00000000000..c0c0dd2e960
--- /dev/null
+++ b/lib/core/src/lib/prediction/feature-flag.ts
@@ -0,0 +1,20 @@
+/*!
+ * @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.
+ */
+
+export enum CONTENT_ENRICHMENT {
+ EXPERIENCE_INSIGHT = 'content-enrichment-with-experience-insight'
+}
diff --git a/lib/content-services/src/lib/prediction/index.ts b/lib/core/src/lib/prediction/index.ts
similarity index 100%
rename from lib/content-services/src/lib/prediction/index.ts
rename to lib/core/src/lib/prediction/index.ts
diff --git a/lib/core/src/lib/prediction/interfaces/prediction-status-update.interface.ts b/lib/core/src/lib/prediction/interfaces/prediction-status-update.interface.ts
new file mode 100644
index 00000000000..3c5227da525
--- /dev/null
+++ b/lib/core/src/lib/prediction/interfaces/prediction-status-update.interface.ts
@@ -0,0 +1,21 @@
+/*!
+ * @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.
+ */
+
+export interface PredictionStatusUpdate {
+ key: string;
+ previousValue?: any;
+}
diff --git a/lib/content-services/src/lib/prediction/public-api.ts b/lib/core/src/lib/prediction/public-api.ts
similarity index 87%
rename from lib/content-services/src/lib/prediction/public-api.ts
rename to lib/core/src/lib/prediction/public-api.ts
index fda9d52bde5..266c0d63b1f 100644
--- a/lib/content-services/src/lib/prediction/public-api.ts
+++ b/lib/core/src/lib/prediction/public-api.ts
@@ -16,3 +16,5 @@
*/
export * from './services';
+export * from './interfaces/prediction-status-update.interface';
+export * from './feature-flag';
diff --git a/lib/content-services/src/lib/prediction/services/index.ts b/lib/core/src/lib/prediction/services/index.ts
similarity index 100%
rename from lib/content-services/src/lib/prediction/services/index.ts
rename to lib/core/src/lib/prediction/services/index.ts
diff --git a/lib/content-services/src/lib/prediction/services/prediction.service.spec.ts b/lib/core/src/lib/prediction/services/prediction.service.spec.ts
similarity index 94%
rename from lib/content-services/src/lib/prediction/services/prediction.service.spec.ts
rename to lib/core/src/lib/prediction/services/prediction.service.spec.ts
index 8e88c503936..817979f0cef 100644
--- a/lib/content-services/src/lib/prediction/services/prediction.service.spec.ts
+++ b/lib/core/src/lib/prediction/services/prediction.service.spec.ts
@@ -16,8 +16,8 @@
*/
import { PredictionService } from './prediction.service';
+import { CoreTestingModule } from '../../testing/core.testing.module';
import { TestBed } from '@angular/core/testing';
-import { ContentTestingModule } from '../../testing/content.testing.module';
import { Prediction, PredictionEntry, PredictionPaging, PredictionPagingList, ReviewStatus } from '@alfresco/js-api';
describe('PredictionService', () => {
@@ -33,7 +33,7 @@ describe('PredictionService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
- imports: [ContentTestingModule]
+ imports: [CoreTestingModule]
});
service = TestBed.inject(PredictionService);
});
diff --git a/lib/content-services/src/lib/prediction/services/prediction.service.ts b/lib/core/src/lib/prediction/services/prediction.service.ts
similarity index 83%
rename from lib/content-services/src/lib/prediction/services/prediction.service.ts
rename to lib/core/src/lib/prediction/services/prediction.service.ts
index 020749f8199..5d59d7334d9 100644
--- a/lib/content-services/src/lib/prediction/services/prediction.service.ts
+++ b/lib/core/src/lib/prediction/services/prediction.service.ts
@@ -16,14 +16,20 @@
*/
import { Injectable } from '@angular/core';
-import { AlfrescoApiService } from '@alfresco/adf-core';
+import { AlfrescoApiService } from '../../services/alfresco-api.service';
import { PredictionsApi, PredictionPaging, ReviewStatus } from '@alfresco/js-api';
-import { from, Observable } from 'rxjs';
+import { from, Observable, Subject } from 'rxjs';
+import { PredictionStatusUpdate } from '../interfaces/prediction-status-update.interface';
@Injectable({ providedIn: 'root' })
export class PredictionService {
private _predictionsApi: PredictionsApi;
+ /**
+ * Gets emitted when prediction status updated
+ */
+ predictionStatusUpdated$ = new Subject();
+
get predictionsApi(): PredictionsApi {
this._predictionsApi = this._predictionsApi ?? new PredictionsApi(this.apiService.getInstance());
return this._predictionsApi;
diff --git a/lib/core/src/lib/styles/_components-variables.scss b/lib/core/src/lib/styles/_components-variables.scss
index 06e7cc9ec54..1e27bba7157 100644
--- a/lib/core/src/lib/styles/_components-variables.scss
+++ b/lib/core/src/lib/styles/_components-variables.scss
@@ -89,7 +89,8 @@
--adf-danger-button-background: $adf-danger-button-background,
--adf-secondary-button-background: $adf-secondary-button-background,
- --adf-display-external-property-widget-preview-selection-color: mat.get-color-from-palette($foreground, secondary-text)
+ --adf-display-external-property-widget-preview-selection-color: mat.get-color-from-palette($foreground, secondary-text),
+ --adf-ai-border-gradient: $adf-ref-ai-border-gradient
);
// propagates SCSS variables into the CSS variables scope
diff --git a/lib/core/src/lib/styles/_reference-variables.scss b/lib/core/src/lib/styles/_reference-variables.scss
index 6f72688cbeb..9d250d4c01f 100644
--- a/lib/core/src/lib/styles/_reference-variables.scss
+++ b/lib/core/src/lib/styles/_reference-variables.scss
@@ -27,3 +27,4 @@ $adf-ref-header-icon-color: inherit;
$adf-ref-header-icon-border-radius: 50%;
$adf-danger-button-background: #ba1b1b;
$adf-secondary-button-background: #2121210d;
+$adf-ref-ai-border-gradient: linear-gradient(180deg, #94B7FF 0%, #9E00FF 100%);
diff --git a/lib/core/src/public-api.ts b/lib/core/src/public-api.ts
index 645edf1c464..6e9374494b1 100644
--- a/lib/core/src/public-api.ts
+++ b/lib/core/src/public-api.ts
@@ -49,6 +49,7 @@ export * from './lib/blank-page/index';
export * from './lib/search-text/index';
export * from './lib/snackbar-content/index';
export * from './lib/translation/index';
+export * from './lib/prediction/index';
export * from './lib/common/utils/index';
export * from './lib/interface/index';
diff --git a/lib/js-api/src/api/hxi-connector-api/api/predictions.api.ts b/lib/js-api/src/api/hxi-connector-api/api/predictions.api.ts
index eb97b1a25f9..052956b8a72 100644
--- a/lib/js-api/src/api/hxi-connector-api/api/predictions.api.ts
+++ b/lib/js-api/src/api/hxi-connector-api/api/predictions.api.ts
@@ -52,14 +52,17 @@ export class PredictionsApi extends BaseApi {
throwIfNotDefined(reviewStatus, 'reviewStatus');
const pathParams = {
- predictionId,
+ predictionId
+ };
+
+ const queryParams = {
reviewStatus
};
return this.post({
path: '/predictions/{predictionId}/review',
pathParams,
- returnType: Promise
+ queryParams
});
}
}
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer.widget.spec.ts
index 4bb0210d254..acd176ba94a 100644
--- a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer.widget.spec.ts
+++ b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer-wrapper/properties-viewer.widget.spec.ts
@@ -21,6 +21,8 @@ import { ProcessServiceCloudTestingModule } from '../../../../../testing/process
import { of } from 'rxjs';
import { fakeNodeWithProperties } from '../../../../mocks/attach-file-cloud-widget.mock';
import { NodesApiService, BasicPropertiesService } from '@alfresco/adf-content-services';
+import { provideMockFeatureFlags } from '@alfresco/adf-core/feature-flags';
+import { CONTENT_ENRICHMENT } from '@alfresco/adf-core';
describe('PropertiesViewerWidgetComponent', () => {
let component: PropertiesViewerWrapperComponent;
@@ -30,7 +32,11 @@ describe('PropertiesViewerWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule],
- providers: [NodesApiService, { provide: BasicPropertiesService, useValue: { getProperties: () => [] } }]
+ providers: [
+ NodesApiService,
+ { provide: BasicPropertiesService, useValue: { getProperties: () => [] } },
+ provideMockFeatureFlags({[CONTENT_ENRICHMENT.EXPERIENCE_INSIGHT]: false})
+ ]
});
fixture = TestBed.createComponent(PropertiesViewerWrapperComponent);
component = fixture.componentInstance;
diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer.widget.spec.ts
index 51e33185377..eea2ebec2a4 100644
--- a/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer.widget.spec.ts
+++ b/lib/process-services-cloud/src/lib/form/components/widgets/properties-viewer/properties-viewer.widget.spec.ts
@@ -16,13 +16,14 @@
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { FormFieldModel, FormModel } from '@alfresco/adf-core';
+import { CONTENT_ENRICHMENT, FormFieldModel, FormModel } from '@alfresco/adf-core';
import { PropertiesViewerWidgetComponent } from './properties-viewer.widget';
import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module';
import { fakeNodeWithProperties } from '../../../mocks/attach-file-cloud-widget.mock';
import { PropertiesViewerWrapperComponent } from './properties-viewer-wrapper/properties-viewer-wrapper.component';
import { NodesApiService, BasicPropertiesService } from '@alfresco/adf-content-services';
import { of } from 'rxjs';
+import { provideMockFeatureFlags } from '@alfresco/adf-core/feature-flags';
describe('PropertiesViewerWidgetComponent', () => {
let widget: PropertiesViewerWidgetComponent;
@@ -49,7 +50,11 @@ describe('PropertiesViewerWidgetComponent', () => {
TestBed.configureTestingModule({
imports: [ProcessServiceCloudTestingModule],
declarations: [PropertiesViewerWrapperComponent],
- providers: [NodesApiService, { provide: BasicPropertiesService, useValue: { getProperties: () => [] } }]
+ providers: [
+ NodesApiService,
+ { provide: BasicPropertiesService, useValue: { getProperties: () => [] } },
+ provideMockFeatureFlags({[CONTENT_ENRICHMENT.EXPERIENCE_INSIGHT]: false})
+ ]
});
fixture = TestBed.createComponent(PropertiesViewerWidgetComponent);
nodesApiService = TestBed.inject(NodesApiService);