Merge branch 'master' into test-speedup

This commit is contained in:
Sam Rose 2025-03-05 10:50:07 +00:00 committed by GitHub
commit 5da775c2b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 89 additions and 25 deletions

View File

@ -1,9 +1,12 @@
import posthog from "posthog-js"
import { Events } from "./constants"
export default class PosthogClient {
constructor(token) {
token: string
initialised: boolean
constructor(token: string) {
this.token = token
this.initialised = false
}
init() {
@ -12,6 +15,8 @@ export default class PosthogClient {
posthog.init(this.token, {
autocapture: false,
capture_pageview: false,
// disable by default
disable_session_recording: true,
})
posthog.set_config({ persistence: "cookie" })
@ -22,7 +27,7 @@ export default class PosthogClient {
* Set the posthog context to the current user
* @param {String} id - unique user id
*/
identify(id) {
identify(id: string) {
if (!this.initialised) return
posthog.identify(id)
@ -32,7 +37,7 @@ export default class PosthogClient {
* Update user metadata associated with current user in posthog
* @param {Object} meta - user fields
*/
updateUser(meta) {
updateUser(meta: Record<string, any>) {
if (!this.initialised) return
posthog.people.set(meta)
@ -43,28 +48,22 @@ export default class PosthogClient {
* @param {String} event - event identifier
* @param {Object} props - properties for the event
*/
captureEvent(eventName, props) {
if (!this.initialised) return
captureEvent(event: string, props: Record<string, any>) {
if (!this.initialised) {
return
}
props.sourceApp = "builder"
posthog.capture(eventName, props)
posthog.capture(event, props)
}
/**
* Submit NPS feedback to posthog.
* @param {Object} values - NPS Values
*/
npsFeedback(values) {
if (!this.initialised) return
localStorage.setItem(Events.NPS.SUBMITTED, Date.now())
const prefixedFeedback = {}
for (let key in values) {
prefixedFeedback[`feedback_${key}`] = values[key]
enableSessionRecording() {
if (!this.initialised) {
return
}
posthog.capture(Events.NPS.SUBMITTED, prefixedFeedback)
posthog.set_config({
disable_session_recording: false,
})
}
/**

View File

@ -31,6 +31,10 @@ class AnalyticsHub {
posthog.captureEvent(eventName, props)
}
enableSessionRecording() {
posthog.enableSessionRecording()
}
async logout() {
posthog.logout()
}

View File

@ -8,6 +8,7 @@ import {
SystemStatusResponse,
} from "@budibase/types"
import { BudiStore } from "../BudiStore"
import Analytics from "../../analytics"
interface AdminState extends GetEnvironmentResponse {
loaded: boolean
@ -33,6 +34,8 @@ export class AdminStore extends BudiStore<AdminState> {
await this.getEnvironment()
// enable system status checks in the cloud
if (get(this.store).cloud) {
// in cloud allow this
Analytics.enableSessionRecording()
await this.getSystemStatus()
this.checkStatus()
}

View File

@ -36,6 +36,7 @@ export const HelperFunctionNames = {
ALL: "all",
LITERAL: "literal",
JS: "js",
DECODE_ID: "decodeId",
}
export const LITERAL_MARKER = "%LITERAL%"

View File

@ -25,13 +25,29 @@ function isObject(value: string | any[]) {
)
}
const HELPERS = [
export const HELPERS = [
// external helpers
new Helper(HelperFunctionNames.OBJECT, (value: any) => {
return new Handlebars.SafeString(JSON.stringify(value))
}),
// javascript helper
new Helper(HelperFunctionNames.JS, processJS, false),
new Helper(HelperFunctionNames.DECODE_ID, (_id: string | { _id: string }) => {
if (!_id) {
return []
}
// have to replace on the way back as we swapped out the double quotes
// when encoding, but JSON can't handle the single quotes
const id = typeof _id === "string" ? _id : _id._id
const decoded: string = decodeURIComponent(id).replace(/'/g, '"')
try {
const parsed = JSON.parse(decoded)
return Array.isArray(parsed) ? parsed : [parsed]
} catch (err) {
// wasn't json - likely was handlebars for a many to many
return [_id]
}
}),
// this help is applied to all statements
new Helper(
HelperFunctionNames.ALL,

View File

@ -517,3 +517,44 @@ describe("helper overlap", () => {
expect(output).toEqual("a")
})
})
describe("Test the decodeId helper", () => {
it("should decode a valid encoded ID", async () => {
const encodedId = encodeURIComponent("[42]") // "%5B42%5D"
const output = await processString("{{ decodeId id }}", { id: encodedId })
expect(output).toBe("42")
})
it("Should return an unchanged string if the string isn't encoded", async () => {
const unencodedId = "forty-two"
const output = await processString("{{ decodeId id }}", { id: unencodedId })
expect(output).toBe("forty-two")
})
it("Should return a string of comma-separated IDs when passed multiple IDs in a URI encoded array", async () => {
const encodedIds = encodeURIComponent("[1,2,3]") // "%5B1%2C2%2C3%5D"
const output = await processString("{{ decodeId id }}", { id: encodedIds })
expect(output).toBe("1,2,3")
})
it("Handles empty array gracefully", async () => {
const output = await processString("{{ decodeId value }}", {
value: [],
})
expect(output).toBe("[[]]")
})
it("Handles undefined gracefully", async () => {
const output = await processString("{{ decodeId value }}", {
value: undefined,
})
expect(output).toBe("")
})
it("Handles null gracefully", async () => {
const output = await processString("{{ decodeId value }}", {
value: undefined,
})
expect(output).toBe("")
})
})