Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refresh view api support #80

Merged
merged 4 commits into from
Nov 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/formula-evaluator.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 0 additions & 6 deletions .idea/jsLibraryMappings.xml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {api} from 'lwc';
import TwElement from "c/twElement";
import {NavigationMixin} from "lightning/navigation";
import {RefreshEvent} from "lightning/refresh";
import execute from '@salesforce/apex/FormulaEvaluatorUiController.execute';
import {classNames} from 'c/utils';

Expand All @@ -13,15 +14,15 @@ export default class BaseButton extends NavigationMixin(TwElement) {

/**
* @typedef ApexFunctionCallback
* @property { "navigate__namedPage" | "navigate__url" } type
* @property { "navigate__namedPage" | "navigate__url", "reload", "refresh" } type
* @property { string } name
* @property { Object } args
*/

/**
* The action to execute when the button is clicked
* @property {string} label
* @property {"action" | "navigation_namedPage" | "navigation_url" } type
* @property {"action", "submit" | "navigation_namedPage" | "navigation_url" } type
* @property {string | ApexFunction} src
* @property {ApexFunctionCallback} callback
*/
Expand All @@ -32,6 +33,7 @@ export default class BaseButton extends NavigationMixin(TwElement) {
@api variant = "primary";

disabled = false;

get btnClasses() {
switch (this.variant) {
case "primary":
Expand Down Expand Up @@ -62,14 +64,20 @@ export default class BaseButton extends NavigationMixin(TwElement) {
const evt = new CustomEvent('submit',
{
bubbles: true,
detail: {action: execute, fnReference: this.action.src, callback: this.actionCallback},
detail: {
action: execute, fnReference: this.action.src, callback: () => {
this.actionCallback();
this.disabled = false;
}
},
composed: true
});
this.dispatchEvent(evt);
} else if (this.action.type === "action") {
try {
const result = await execute({fnReference: this.action.src});
this.actionCallback(result);
this.disabled = false;
} catch (e) {
console.error(e);
}
Expand Down Expand Up @@ -99,16 +107,28 @@ export default class BaseButton extends NavigationMixin(TwElement) {
get displayAsButton() {
return this.action.type === "submit" || this.action.type === "action";
}

actionCallback = (result) => {
if (this.action.callback.type === 'reload') {
// Reload is not handled by the navigation mixin, so we handle it here
// as a special case.
location.reload();
} else {
this[NavigationMixin.Navigate](this._getNavigationObjectFromActionResult(result));
switch (this.action.callback.type) {
case "reload":
this.dispatchEvent(new RefreshEvent());
break;
case "refresh":
this.dispatchEvent(new CustomEvent('expression_refresh', {bubbles: true, composed: true}));
break;
case "navigate__namedPage":
case "navigate__url":
this._navigate(result);
break;
default:
throw new Error(`Unknown callback type: ${this.action.callback.type}`);
}
}

_navigate(result) {
this[NavigationMixin.Navigate](this._getNavigationObjectFromActionResult(result));
}

_getNavigationObjectFromActionResult = (result) => {
return {
type: this._mapApexCallbackToNavigationMixinType(this.action.callback.type),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<template lwc:if={loading}>
<template lwc:if={showLoading}>
<div class="animate-pulse flex space-x-4 h-20">
<div class="flex-1 space-y-6 py-1">
<div class="bg-slate-200 rounded h-full"></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ export default class ExpressionElementContainer extends LightningElement {
@api cannotShowPreview = false;
@api error = null;
@api loading = false;

get showLoading() {
return this.loading && !this.cannotShowPreview;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import TwElement from "c/twElement";
import {refreshApex} from '@salesforce/apex';
import evaluate from '@salesforce/apex/FormulaEvaluatorUiController.evaluate';
import { CurrentPageReference } from "lightning/navigation";
import { wire } from "lwc";
import {CurrentPageReference} from "lightning/navigation";
import {wire} from "lwc";

export default class ExpressionSiteElement extends TwElement {
// These 4 need to be set by the extending class as `@api` properties.
Expand All @@ -14,6 +15,15 @@ export default class ExpressionSiteElement extends TwElement {
computed;
error;
contextId = null
evaluatedWire;

connectedCallback() {
window.addEventListener('expression_refresh', this.refreshHandler);
}

disconnectedCallback() {
window.removeEventListener('expression_refresh', this.refreshHandler);
}

@wire(CurrentPageReference)
setCurrentPageReference(currentPageReference) {
Expand All @@ -24,7 +34,9 @@ export default class ExpressionSiteElement extends TwElement {
}

@wire(evaluate, {recordId: '$contextId', formula: '$expr', respectSharing: '$respectSharing'})
evaluate({error, data}) {
evaluate(evaluatedWire) {
this.evaluatedWire = evaluatedWire;
const {error, data} = evaluatedWire;
if (error) {
console.error(error);
this.error = error.body.message;
Expand All @@ -34,6 +46,10 @@ export default class ExpressionSiteElement extends TwElement {
}
}

refreshHandler = () => {
return refreshApex(this.evaluatedWire);
}

get loading() {
return !this.computed && !this.error;
}
Expand Down Expand Up @@ -64,5 +80,6 @@ export default class ExpressionSiteElement extends TwElement {
return false;
}

validate() {}
validate() {
}
}
15 changes: 15 additions & 0 deletions expression-src/main/api/tests/CollectionFunctionsTest.cls
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,21 @@ private class CollectionFunctionsTest {
Assert.areEqual('Child2', result[0]);
}

@IsTest
private static void combiningWhereAndMap_withRelationshipsBetweenDifferentSObjectTypes() {
Account parentAccount = new Account(Name = 'Parent');
insert parentAccount;

Contact childContact = new Contact(LastName = 'Child', AccountId = parentAccount.Id);
insert childContact;

String expr = 'MAP(WHERE(Contacts, BEGINS(LastName, "C")), Name)';
List<Object> result = (List<Object>) Evaluator.run(expr, parentAccount.Id);

Assert.areEqual(1, result.size());
Assert.areEqual('Child', result[0]);
}

@IsTest
private static void nestingWheres() {
Account parentAccount = new Account(Name = 'Parent');
Expand Down
6 changes: 6 additions & 0 deletions expression-src/main/src/helpers/tests/AstPrinterTest.cls
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@IsTest
private class AstPrinterTest {
@IsTest
static void testBehavior() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>58.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ public with sharing class ActionVariableResolver implements IGlobalVariableResol
'type' => 'reload'
};
}
when 'refresh' {
return new Map<String, Object> {
'type' => 'refresh'
};
}
when else {
throw new ActionVariableResolverException('Unknown LWC action: ' + referenceName);
}
Expand Down
9 changes: 5 additions & 4 deletions expression-src/main/src/interpreter/ContextResolver.cls
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,14 @@ public with sharing class ContextResolver implements Visitor {
return null;
}

private Set<String> cachedFields;
private final Map<SObjectType, Set<String>> cachedFieldsBySObjectType = new Map<SObjectType, Set<String>>();
private Set<String> getFields() {
if (cachedFields == null) {
cachedFields = new Set<String>();
cachedFields = this.queryContext.objectType.getDescribe().fields.getMap().keySet();
if (cachedFieldsBySObjectType.containsKey(this.queryContext.objectType)) {
return cachedFieldsBySObjectType.get(this.queryContext.objectType);
}

Set<String> cachedFields = this.queryContext.objectType.getDescribe().fields.getMap().keySet();
cachedFieldsBySObjectType.put(this.queryContext.objectType, cachedFields);
return cachedFields;
}

Expand Down
Loading