Skip to content

Commit

Permalink
Refactor AI events #7977
Browse files Browse the repository at this point in the history
  • Loading branch information
edloidas committed Oct 22, 2024
1 parent 4d35497 commit 4af6a1c
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 134 deletions.
1 change: 1 addition & 0 deletions modules/app/src/main/resources/admin/tools/main/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

{{#aiTranslatorAssetsUrl}}
<!-- Append AI Translator -->
<link rel="stylesheet" type="text/css" href="{{aiTranslatorAssetsUrl}}/style.css">
<script type="text/javascript" src="{{aiTranslatorAssetsUrl}}/index.js" data-asset-url="{{aiTranslatorAssetsUrl}}" async></script>
{{/aiTranslatorAssetsUrl}}
</head>
Expand Down
94 changes: 56 additions & 38 deletions modules/lib/src/main/resources/assets/js/app/ai/AI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import {AiHelper} from '@enonic/lib-admin-ui/ai/AiHelper';
import {AiHelperState} from '@enonic/lib-admin-ui/ai/AiHelperState';
import {ApplicationConfig} from '@enonic/lib-admin-ui/application/ApplicationConfig';
import {PropertyTree} from '@enonic/lib-admin-ui/data/PropertyTree';
import {DefaultErrorHandler} from '@enonic/lib-admin-ui/DefaultErrorHandler';
import {Locale} from '@enonic/lib-admin-ui/locale/Locale';
import {IsAuthenticatedRequest} from '@enonic/lib-admin-ui/security/auth/IsAuthenticatedRequest';
import {LoginResult} from '@enonic/lib-admin-ui/security/auth/LoginResult';
import {CONFIG} from '@enonic/lib-admin-ui/util/Config';
import {StringHelper} from '@enonic/lib-admin-ui/util/StringHelper';
import {Content} from '../content/Content';
import {ContentType} from '../inputtype/schema/ContentType';
import {GetLocalesRequest} from '../resource/GetLocalesRequest';
import {ContentData, ContentLanguage, ContentSchema} from './event/data/AiData';
import {EnonicAiAppliedData} from './event/data/EnonicAiAppliedData';
import {ContentData} from './event/data/EnonicAiContentData';
import {EnonicAiContentOperatorSetupData} from './event/data/EnonicAiContentOperatorSetupData';
import {EnonicAiTranslatorSetupData} from './event/data/EnonicAiTranslatorSetupData';
import {AiContentOperatorDialogShownEvent} from './event/incoming/AiContentOperatorDialogShownEvent';
import {AiContentOperatorRenderedEvent} from './event/incoming/AiContentOperatorRenderedEvent';
import {AiContentOperatorResultAppliedEvent} from './event/incoming/AiContentOperatorResultAppliedEvent';
import {AiTranslatorCompletedEvent} from './event/incoming/AiTranslatorCompletedEvent';
import {AiTranslatorStartedEvent} from './event/incoming/AiTranslatorStartedEvent';
Expand All @@ -38,7 +39,6 @@ interface EnonicAi {
setup(setupData: EnonicAiTranslatorSetupData): void;
render(container: HTMLElement): void;
translate(language?: string): Promise<boolean>;
isAvailable(): boolean;
}
}

Expand All @@ -53,12 +53,14 @@ export class AI {

private static instance: AI;

private content: Content;

private currentData: ContentData | undefined;

private content: Content;

private contentType: ContentType;

private locales: Locale[];

private instructions: Record<EnonicAiPlugin, string | undefined>;

private resultReceivedListeners: ((data: EnonicAiAppliedData) => void)[] = [];
Expand All @@ -71,8 +73,6 @@ export class AI {
return;
}

AiContentOperatorRenderedEvent.on(this.showContentOperatorEventListener);
AiContentOperatorDialogShownEvent.on(this.showContentOperatorEventListener);
AiContentOperatorResultAppliedEvent.on(this.applyContentOperatorEventListener);
AiTranslatorStartedEvent.on(this.translatorStartedEventListener);
AiTranslatorCompletedEvent.on(this.translatorCompletedEventListener);
Expand All @@ -85,33 +85,42 @@ export class AI {
const fullName = currentUser.getDisplayName();
const names = fullName.split(' ').map(word => word.substring(0, 1));
const shortName = (names.length >= 2 ? names.join('') : fullName).substring(0, 2).toUpperCase();
const user = {fullName, shortName} as const;
new AiContentOperatorConfigureEvent({user}).fire();
}).catch(DefaultErrorHandler.handle);

new AiContentOperatorConfigureEvent({
user: {
fullName,
shortName,
}
}).fire();
});
new GetLocalesRequest().sendAndParse().then((locales) => {
this.setLocales(locales);
}).catch(DefaultErrorHandler.handle);
}

static get(): AI {
return AI.instance ?? (AI.instance = new AI());
}

setContentContext(content: Content): void {
setContent(content: Content): void {
this.content = content;
new AiUpdateDataEvent({
data: this.createContentData(),
language: this.createContentLanguage(),
}).fire();
this.checkAndNotifyReady();
}

setContentTypeContext(contentType: ContentType): void {
setContentType(contentType: ContentType): void {
this.contentType = contentType;
new AiUpdateDataEvent({schema: this.createContentSchema()}).fire();
this.checkAndNotifyReady();
}

setCurrentData(data: ContentData): void {
this.currentData = data;
new AiUpdateDataEvent({data}).fire();
new AiUpdateDataEvent({data: this.createContentData()}).fire();
}

setLocales(locales: Locale[]): void {
this.locales = locales;
new AiUpdateDataEvent({language: this.createContentLanguage()}).fire();
}

updateInstructions(configs: ApplicationConfig[]): void {
Expand Down Expand Up @@ -163,12 +172,12 @@ export class AI {
this.getContentOperator()?.render(container);
}

translate(language: string): Promise<boolean> {
return this.getTranslator()?.translate(language) ?? Promise.resolve(false);
renderTranslator(container: HTMLElement): void {
this.getTranslator()?.render(container);
}

canTranslate(): boolean {
return this.getTranslator()?.isAvailable() ?? false;
translate(language: string): Promise<boolean> {
return this.getTranslator()?.translate(language) ?? Promise.resolve(false);
}

private translatorStartedEventListener = (event: AiTranslatorStartedEvent) => {
Expand All @@ -181,23 +190,32 @@ export class AI {
helper?.setState(AiHelperState.COMPLETED);
};

private showContentOperatorEventListener = () => {
new AiUpdateDataEvent({
data: {
fields: this.content.getContentData().toJson(),
topic: this.content.getDisplayName(),
language: this.content.getLanguage(),
},
schema: {
form: this.contentType.getForm().toJson(),
name: this.contentType.getDisplayName()
},
}).fire();
private createContentData(): ContentData | undefined {
// TODO: Add structuredClone, when target upgraded to ES2022
return this.currentData || (this.content && {
fields: this.content.getContentData().toJson(),
topic: this.content.getDisplayName(),
});
}

if (this.currentData) {
new AiUpdateDataEvent({data: this.currentData}).fire();
private createContentLanguage(): ContentLanguage | undefined {
if (!this.content) {
return;
}
};

const tag = this.content.getLanguage();
const locale = this.locales?.find(l => l.getTag() === tag);
const name = locale ? locale.getDisplayName() : tag;

return {tag, name};
}

private createContentSchema(): ContentSchema | undefined {
return this.contentType && {
form: this.contentType.getForm().toJson(),
name: this.contentType.getDisplayName(),
};
}

private applyContentOperatorEventListener = (event: AiContentOperatorResultAppliedEvent) => {
const {topic} = event.result;
Expand Down Expand Up @@ -226,7 +244,7 @@ export class AI {
}

private isReady(): boolean {
return this.content != null && this.contentType != null && this.instructions != null;
return this.content != null && this.contentType != null && this.instructions != null && this.locales != null;
}

private checkAndNotifyReady(): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {PropertyArrayJson} from '@enonic/lib-admin-ui/data/PropertyArrayJson';
import {FormJson} from '@enonic/lib-admin-ui/form/json/FormJson';

export interface AiData {
data?: ContentData;
schema?: ContentSchema;
language?: ContentLanguage;
}

export interface ContentData {
fields: PropertyArrayJson[];
topic: string;
}

export interface ContentSchema {
form: FormJson;
name: string;
}

export interface ContentLanguage {
tag: string;
name: string;
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import {ClassHelper} from '@enonic/lib-admin-ui/ClassHelper';
import {Event} from '@enonic/lib-admin-ui/event/Event';

export class AiTranslatorDialogShownEvent
export class AiTranslatorOpenDialogEvent
extends Event {

private constructor() {
super();
}

static on(handler: (event: AiTranslatorDialogShownEvent) => void) {
static on(handler: (event: AiTranslatorOpenDialogEvent) => void) {
Event.bind(ClassHelper.getFullName(this), handler);
}

static un(handler?: (event: AiTranslatorDialogShownEvent) => void) {
static un(handler?: (event: AiTranslatorOpenDialogEvent) => void) {
Event.unbind(ClassHelper.getFullName(this), handler);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import {ClassHelper} from '@enonic/lib-admin-ui/ClassHelper';
import {Event} from '@enonic/lib-admin-ui/event/Event';
import {EnonicAiContentData} from '../data/EnonicAiContentData';
import {AiData} from '../data/AiData';

export class AiUpdateDataEvent
extends Event {

private readonly payload: EnonicAiContentData;
private readonly payload: AiData;

constructor(data: EnonicAiContentData) {
constructor(data: AiData) {
super();

this.payload = data;
}

getData(): EnonicAiContentData {
getData(): AiData {
return this.payload;
}

Expand Down
Loading

0 comments on commit 4af6a1c

Please sign in to comment.