commit
de2afcae60
|
@ -2,7 +2,7 @@ import env from "../environment"
|
||||||
import { SEPARATOR, DocumentType } from "../db/constants"
|
import { SEPARATOR, DocumentType } from "../db/constants"
|
||||||
import cls from "./FunctionContext"
|
import cls from "./FunctionContext"
|
||||||
import { dangerousGetDB, closeDB } from "../db"
|
import { dangerousGetDB, closeDB } from "../db"
|
||||||
import { baseGlobalDBName } from "../tenancy/utils"
|
import { baseGlobalDBName } from "../db/tenancy"
|
||||||
import { IdentityContext } from "@budibase/types"
|
import { IdentityContext } from "@budibase/types"
|
||||||
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
import { DEFAULT_TENANT_ID as _DEFAULT_TENANT_ID } from "../constants"
|
||||||
import { ContextKey } from "./constants"
|
import { ContextKey } from "./constants"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { DEFAULT_TENANT_ID } from "../constants"
|
import { DEFAULT_TENANT_ID } from "../constants"
|
||||||
import { StaticDatabases, SEPARATOR } from "../db/constants"
|
import { StaticDatabases, SEPARATOR } from "./constants"
|
||||||
import { getTenantId } from "../context"
|
import { getTenantId } from "../context"
|
||||||
|
|
||||||
export const getGlobalDBName = (tenantId?: string) => {
|
export const getGlobalDBName = (tenantId?: string) => {
|
|
@ -3,7 +3,7 @@ import { DEFAULT_TENANT_ID, Configs } from "../constants"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { SEPARATOR, DocumentType, UNICODE_MAX, ViewName } from "./constants"
|
import { SEPARATOR, DocumentType, UNICODE_MAX, ViewName } from "./constants"
|
||||||
import { getTenantId, getGlobalDB } from "../context"
|
import { getTenantId, getGlobalDB } from "../context"
|
||||||
import { getGlobalDBName } from "../tenancy"
|
import { getGlobalDBName } from "./tenancy"
|
||||||
import fetch from "node-fetch"
|
import fetch from "node-fetch"
|
||||||
import { doWithDB, allDbs } from "./index"
|
import { doWithDB, allDbs } from "./index"
|
||||||
import { getCouchInfo } from "./pouch"
|
import { getCouchInfo } from "./pouch"
|
||||||
|
@ -16,6 +16,7 @@ import * as events from "../events"
|
||||||
export * from "./constants"
|
export * from "./constants"
|
||||||
export * from "./conversions"
|
export * from "./conversions"
|
||||||
export { default as Replication } from "./Replication"
|
export { default as Replication } from "./Replication"
|
||||||
|
export * from "./tenancy"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new app ID.
|
* Generates a new app ID.
|
||||||
|
|
|
@ -3,12 +3,8 @@ import { doWithDB } from "../db"
|
||||||
import { DocumentType, StaticDatabases } from "../db/constants"
|
import { DocumentType, StaticDatabases } from "../db/constants"
|
||||||
import { getAllApps } from "../db/utils"
|
import { getAllApps } from "../db/utils"
|
||||||
import environment from "../environment"
|
import environment from "../environment"
|
||||||
import {
|
import { doInTenant, getTenantIds, getTenantId } from "../tenancy"
|
||||||
doInTenant,
|
import { getGlobalDBName } from "../db/tenancy"
|
||||||
getTenantIds,
|
|
||||||
getGlobalDBName,
|
|
||||||
getTenantId,
|
|
||||||
} from "../tenancy"
|
|
||||||
import * as context from "../context"
|
import * as context from "../context"
|
||||||
import { DEFINITIONS } from "."
|
import { DEFINITIONS } from "."
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import * as context from "../context"
|
import * as context from "../context"
|
||||||
import * as tenancy from "./tenancy"
|
import * as tenancy from "./tenancy"
|
||||||
import * as utils from "./utils"
|
|
||||||
|
|
||||||
const pkg = {
|
const pkg = {
|
||||||
...context,
|
...context,
|
||||||
...tenancy,
|
...tenancy,
|
||||||
...utils,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export = pkg
|
export = pkg
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { doWithDB } from "../db"
|
import { doWithDB } from "../db"
|
||||||
import { queryPlatformView } from "../db/views"
|
import { queryPlatformView } from "../db/views"
|
||||||
import { StaticDatabases, ViewName } from "../db/constants"
|
import { StaticDatabases, ViewName } from "../db/constants"
|
||||||
import { getGlobalDBName } from "./utils"
|
import { getGlobalDBName } from "../db/tenancy"
|
||||||
import {
|
import {
|
||||||
getTenantId,
|
getTenantId,
|
||||||
DEFAULT_TENANT_ID,
|
DEFAULT_TENANT_ID,
|
||||||
|
@ -9,7 +9,7 @@ import {
|
||||||
getTenantIDFromAppID,
|
getTenantIDFromAppID,
|
||||||
} from "../context"
|
} from "../context"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
import { PlatformUser, PlatformUserByEmail } from "@budibase/types"
|
import { PlatformUser } from "@budibase/types"
|
||||||
|
|
||||||
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
|
const TENANT_DOC = StaticDatabases.PLATFORM_INFO.docs.tenants
|
||||||
const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
|
const PLATFORM_INFO_DB = StaticDatabases.PLATFORM_INFO.name
|
||||||
|
|
|
@ -97,7 +97,7 @@
|
||||||
backgroundColour={templateEntry.background}
|
backgroundColour={templateEntry.background}
|
||||||
icon={templateEntry.icon}
|
icon={templateEntry.icon}
|
||||||
>
|
>
|
||||||
{#if $licensing?.usageMetrics?.apps < 100}
|
{#if !($licensing?.usageMetrics?.apps >= 100)}
|
||||||
<Button
|
<Button
|
||||||
cta
|
cta
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import { ExpiringKeys } from "./constants"
|
import { ExpiringKeys } from "./constants"
|
||||||
import { getBanners } from "./licensingBanners"
|
import { getBanners } from "./licensingBanners"
|
||||||
import { banner } from "@budibase/bbui"
|
import { banner } from "@budibase/bbui"
|
||||||
|
import { FEATURE_FLAGS, isEnabled } from "../../../helpers/featureFlags"
|
||||||
|
|
||||||
const oneDayInSeconds = 86400
|
const oneDayInSeconds = 86400
|
||||||
|
|
||||||
|
@ -81,7 +82,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (userLoaded && licensingLoaded && loaded) {
|
$: if (
|
||||||
|
userLoaded &&
|
||||||
|
licensingLoaded &&
|
||||||
|
loaded &&
|
||||||
|
isEnabled(FEATURE_FLAGS.LICENSING)
|
||||||
|
) {
|
||||||
queuedModals = processModals()
|
queuedModals = processModals()
|
||||||
queuedBanners = getBanners()
|
queuedBanners = getBanners()
|
||||||
showNextModal()
|
showNextModal()
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
{
|
{
|
||||||
title: "Plugins",
|
title: "Plugins",
|
||||||
href: "/builder/portal/manage/plugins",
|
href: "/builder/portal/manage/plugins",
|
||||||
badge: "New",
|
badge: "Beta",
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,10 +3,12 @@ import { API } from "api"
|
||||||
import { auth } from "stores/portal"
|
import { auth } from "stores/portal"
|
||||||
import { Constants } from "@budibase/frontend-core"
|
import { Constants } from "@budibase/frontend-core"
|
||||||
import { StripeStatus } from "components/portal/licensing/constants"
|
import { StripeStatus } from "components/portal/licensing/constants"
|
||||||
|
import { FEATURE_FLAGS, isEnabled } from "../../helpers/featureFlags"
|
||||||
|
|
||||||
export const createLicensingStore = () => {
|
export const createLicensingStore = () => {
|
||||||
const DEFAULT = {
|
const DEFAULT = {
|
||||||
plans: {},
|
plans: {},
|
||||||
|
usageMetrics: {},
|
||||||
}
|
}
|
||||||
const oneDayInMilliseconds = 86400000
|
const oneDayInMilliseconds = 86400000
|
||||||
|
|
||||||
|
@ -27,78 +29,80 @@ export const createLicensingStore = () => {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getUsageMetrics: async () => {
|
getUsageMetrics: async () => {
|
||||||
const quota = get(store).quotaUsage
|
if (isEnabled(FEATURE_FLAGS.LICENSING)) {
|
||||||
const license = get(auth).user.license
|
const quota = get(store).quotaUsage
|
||||||
const now = new Date()
|
const license = get(auth).user.license
|
||||||
|
const now = new Date()
|
||||||
|
|
||||||
const getMetrics = (keys, license, quota) => {
|
const getMetrics = (keys, license, quota) => {
|
||||||
if (!license || !quota || !keys) {
|
if (!license || !quota || !keys) {
|
||||||
return {}
|
return {}
|
||||||
|
}
|
||||||
|
return keys.reduce((acc, key) => {
|
||||||
|
const quotaLimit = license[key].value
|
||||||
|
const quotaUsed = (quota[key] / quotaLimit) * 100
|
||||||
|
acc[key] = quotaLimit > -1 ? Math.round(quotaUsed) : -1
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
}
|
}
|
||||||
return keys.reduce((acc, key) => {
|
const monthlyMetrics = getMetrics(
|
||||||
const quotaLimit = license[key].value
|
["dayPasses", "queries", "automations"],
|
||||||
const quotaUsed = (quota[key] / quotaLimit) * 100
|
license.quotas.usage.monthly,
|
||||||
acc[key] = quotaLimit > -1 ? Math.round(quotaUsed) : -1
|
quota.monthly.current
|
||||||
return acc
|
)
|
||||||
}, {})
|
const staticMetrics = getMetrics(
|
||||||
}
|
["apps", "rows"],
|
||||||
const monthlyMetrics = getMetrics(
|
license.quotas.usage.static,
|
||||||
["dayPasses", "queries", "automations"],
|
quota.usageQuota
|
||||||
license.quotas.usage.monthly,
|
|
||||||
quota.monthly.current
|
|
||||||
)
|
|
||||||
const staticMetrics = getMetrics(
|
|
||||||
["apps", "rows"],
|
|
||||||
license.quotas.usage.static,
|
|
||||||
quota.usageQuota
|
|
||||||
)
|
|
||||||
|
|
||||||
const getDaysBetween = (dateStart, dateEnd) => {
|
|
||||||
return dateEnd > dateStart
|
|
||||||
? Math.round(
|
|
||||||
(dateEnd.getTime() - dateStart.getTime()) / oneDayInMilliseconds
|
|
||||||
)
|
|
||||||
: 0
|
|
||||||
}
|
|
||||||
|
|
||||||
const quotaResetDate = new Date(quota.quotaReset)
|
|
||||||
const quotaResetDaysRemaining = getDaysBetween(now, quotaResetDate)
|
|
||||||
|
|
||||||
const accountDowngraded =
|
|
||||||
license?.billing?.subscription?.downgradeAt &&
|
|
||||||
license?.billing?.subscription?.downgradeAt <= now.getTime() &&
|
|
||||||
license?.billing?.subscription?.status === StripeStatus.PAST_DUE &&
|
|
||||||
license?.plan.type === Constants.PlanType.FREE
|
|
||||||
|
|
||||||
const pastDueAtMilliseconds = license?.billing?.subscription?.pastDueAt
|
|
||||||
const downgradeAtMilliseconds =
|
|
||||||
license?.billing?.subscription?.downgradeAt
|
|
||||||
let pastDueDaysRemaining
|
|
||||||
let pastDueEndDate
|
|
||||||
|
|
||||||
if (pastDueAtMilliseconds && downgradeAtMilliseconds) {
|
|
||||||
pastDueEndDate = new Date(downgradeAtMilliseconds)
|
|
||||||
pastDueDaysRemaining = getDaysBetween(
|
|
||||||
new Date(pastDueAtMilliseconds),
|
|
||||||
pastDueEndDate
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
store.update(state => {
|
const getDaysBetween = (dateStart, dateEnd) => {
|
||||||
return {
|
return dateEnd > dateStart
|
||||||
...state,
|
? Math.round(
|
||||||
usageMetrics: { ...monthlyMetrics, ...staticMetrics },
|
(dateEnd.getTime() - dateStart.getTime()) / oneDayInMilliseconds
|
||||||
quotaResetDaysRemaining,
|
)
|
||||||
quotaResetDate,
|
: 0
|
||||||
accountDowngraded,
|
|
||||||
accountPastDue: pastDueAtMilliseconds != null,
|
|
||||||
pastDueEndDate,
|
|
||||||
pastDueDaysRemaining,
|
|
||||||
isFreePlan: () => {
|
|
||||||
return license?.plan.type === Constants.PlanType.FREE
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
const quotaResetDate = new Date(quota.quotaReset)
|
||||||
|
const quotaResetDaysRemaining = getDaysBetween(now, quotaResetDate)
|
||||||
|
|
||||||
|
const accountDowngraded =
|
||||||
|
license?.billing?.subscription?.downgradeAt &&
|
||||||
|
license?.billing?.subscription?.downgradeAt <= now.getTime() &&
|
||||||
|
license?.billing?.subscription?.status === StripeStatus.PAST_DUE &&
|
||||||
|
license?.plan.type === Constants.PlanType.FREE
|
||||||
|
|
||||||
|
const pastDueAtMilliseconds = license?.billing?.subscription?.pastDueAt
|
||||||
|
const downgradeAtMilliseconds =
|
||||||
|
license?.billing?.subscription?.downgradeAt
|
||||||
|
let pastDueDaysRemaining
|
||||||
|
let pastDueEndDate
|
||||||
|
|
||||||
|
if (pastDueAtMilliseconds && downgradeAtMilliseconds) {
|
||||||
|
pastDueEndDate = new Date(downgradeAtMilliseconds)
|
||||||
|
pastDueDaysRemaining = getDaysBetween(
|
||||||
|
new Date(pastDueAtMilliseconds),
|
||||||
|
pastDueEndDate
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
store.update(state => {
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
usageMetrics: { ...monthlyMetrics, ...staticMetrics },
|
||||||
|
quotaResetDaysRemaining,
|
||||||
|
quotaResetDate,
|
||||||
|
accountDowngraded,
|
||||||
|
accountPastDue: pastDueAtMilliseconds != null,
|
||||||
|
pastDueEndDate,
|
||||||
|
pastDueDaysRemaining,
|
||||||
|
isFreePlan: () => {
|
||||||
|
return license?.plan.type === Constants.PlanType.FREE
|
||||||
|
},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
export const PlanType = {
|
export const PlanType = {
|
||||||
FREE: "free",
|
FREE: "free",
|
||||||
|
PRO: "pro",
|
||||||
TEAM: "team",
|
TEAM: "team",
|
||||||
BUSINESS: "business",
|
BUSINESS: "business",
|
||||||
ENTERPRISE: "enterprise",
|
ENTERPRISE: "enterprise",
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { isFreePlan } from "./utils.js"
|
// import { isFreePlan } from "./utils.js"
|
||||||
|
|
||||||
export const logoEnabled = () => {
|
export const logoEnabled = () => {
|
||||||
return isFreePlan()
|
return false
|
||||||
|
// return isFreePlan()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
const env = require("../../environment")
|
const env = require("../../environment")
|
||||||
const { getAllApps } = require("@budibase/backend-core/db")
|
const { getAllApps, getGlobalDBName } = require("@budibase/backend-core/db")
|
||||||
const {
|
const {
|
||||||
exportDB,
|
exportDB,
|
||||||
sendTempFile,
|
sendTempFile,
|
||||||
readFileSync,
|
readFileSync,
|
||||||
} = require("../../utilities/fileSystem")
|
} = require("../../utilities/fileSystem")
|
||||||
const { stringToReadStream } = require("../../utilities")
|
const { stringToReadStream } = require("../../utilities")
|
||||||
const {
|
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||||
getGlobalDBName,
|
|
||||||
getGlobalDB,
|
|
||||||
} = require("@budibase/backend-core/tenancy")
|
|
||||||
const { create } = require("./application")
|
const { create } = require("./application")
|
||||||
const { getDocParams, DocumentType, isDevAppID } = require("../../db/utils")
|
const { getDocParams, DocumentType, isDevAppID } = require("../../db/utils")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue