(core) Floating formula editor

Summary:
Adding a way to detach an editor. Initially only implemented for the formula editor, includes redesign for the AI part.
- Initially, the detached editor is tight with the formula assistant and both are behind GRIST_FORMULA_ASSISTANT flag, but this can be relaxed
later on, as the detached editor can be used on its own.

- Detached editor is only supported in regular fields and on the creator panel. It is not supported yet for conditional styles, due to preview limitations.
- Old code for the assistant was removed completely, as it was only a temporary solution, but the AI conversation part was copied to the new one.
- Prompting was not modified in this diff, it will be included in the follow-up with more test cases.

Test Plan: Added only new tests; existing tests should pass.

Reviewers: JakubSerafin

Reviewed By: JakubSerafin

Differential Revision: https://phab.getgrist.com/D3863
This commit is contained in:
Jarosław Sadziński
2023-06-02 13:25:14 +02:00
parent e10067ff78
commit da323fb741
36 changed files with 2022 additions and 823 deletions

View File

@@ -285,7 +285,7 @@ export class AppModelImpl extends Disposable implements AppModel {
this.showNewSiteModal(state.params?.planType);
}
G.window.resetSeenPopups = (seen = false) => {
G.window.resetDismissedPopups = (seen = false) => {
this.dismissedPopups.set(seen ? DismissedPopup.values : []);
this.behavioralPromptsManager.reset();
};

View File

@@ -375,7 +375,7 @@ export class DocPageModelImpl extends Disposable implements DocPageModel {
const comparison = comparisonUrlId ?
await this._api.getDocAPI(urlId).compareDoc(comparisonUrlId, { detail: true }) : undefined;
const gristDoc = gdModule.GristDoc.create(flow, this._appObj, docComm, this, openDocResponse,
const gristDoc = gdModule.GristDoc.create(flow, this._appObj, this.appModel, docComm, this, openDocResponse,
this.appModel.topAppModel.plugins, {comparison});
// Move ownership of docComm to GristDoc.

View File

@@ -200,7 +200,11 @@ export interface ChatMessage {
/**
* The formula returned from the AI. It is only set when the sender is the AI.
*/
formula?: string;
formula?: string|null;
/**
* Suggested actions returned from the AI.
*/
action?: any;
}
/**

View File

@@ -135,9 +135,26 @@ export function createViewFieldRec(this: ViewFieldRec, docModel: DocModel): void
// CSS class to add to formula cells, incl. to show that we are editing this field's formula.
this.formulaCssClass = ko.pureComputed<string|null>(() => {
const col = this.column();
return this.column().isTransforming() ? "transform_field" :
(this.editingFormula() ? "formula_field_edit" :
(col.isFormula() && col.formula() !== "" ? "formula_field" : null));
// If the current column is transforming, assign the CSS class "transform_field"
if (col.isTransforming()) {
if ( col.origCol().isFormula() && col.origCol().formula() !== "") {
return "transform_field formula_field";
}
return "transform_field";
}
// If the column is not transforming but a formula is being edited
else if (this.editingFormula()) {
return "formula_field_edit";
}
// If a formula exists and it is not empty
else if (col.isFormula() && col.formula() !== "") {
return "formula_field";
}
// If none of the above conditions are met, assign null
else {
return null;
}
});
// The fields's display column