diff --git a/packages/server/src/api/controllers/screen.ts b/packages/server/src/api/controllers/screen.ts index 99a6b5ab52..403059efde 100644 --- a/packages/server/src/api/controllers/screen.ts +++ b/packages/server/src/api/controllers/screen.ts @@ -1,4 +1,4 @@ -import { getScreenParams, generateScreenID, DocumentType } from "../../db/utils" +import { generateScreenID, DocumentType } from "../../db/utils" import { events, context, @@ -17,20 +17,14 @@ import { SaveScreenResponse, DeleteScreenResponse, UsageScreenResponse, + ScreenUsage, } from "@budibase/types" import { builderSocket } from "../../websockets" import sdk from "../../sdk" +import { sdk as sharedSdk } from "@budibase/shared-core" export async function fetch(ctx: UserCtx) { - const db = context.getAppDB() - - const screens = ( - await db.allDocs( - getScreenParams(null, { - include_docs: true, - }) - ) - ).rows.map((el: any) => el.doc) + const screens = await sdk.screens.fetch() const roleId = ctx.user?.role?._id as string if (!roleId) { @@ -146,4 +140,18 @@ function findPlugins(component: ScreenProps, foundPlugins: string[]) { export async function usage(ctx: UserCtx) { const sourceId = ctx.params.sourceId const sourceType = sdk.common.getSourceType(sourceId) + const allScreens = await sdk.screens.fetch() + const response: ScreenUsage[] = [] + for (let screen of allScreens) { + if (sharedSdk.screens.findInSettings(screen, sourceId)) { + response.push({ + url: screen.routing.route, + _id: screen._id!, + }) + } + } + ctx.body = { + sourceType, + screens: response, + } } diff --git a/packages/server/src/sdk/app/screens/index.ts b/packages/server/src/sdk/app/screens/index.ts new file mode 100644 index 0000000000..84f4bad6bb --- /dev/null +++ b/packages/server/src/sdk/app/screens/index.ts @@ -0,0 +1 @@ +export * from "./screens" diff --git a/packages/server/src/sdk/app/screens/screens.ts b/packages/server/src/sdk/app/screens/screens.ts new file mode 100644 index 0000000000..c600825efb --- /dev/null +++ b/packages/server/src/sdk/app/screens/screens.ts @@ -0,0 +1,15 @@ +import { getScreenParams } from "../../../db/utils" +import { context } from "@budibase/backend-core" +import { Screen } from "@budibase/types" + +export async function fetch(): Promise { + const db = context.getAppDB() + + return ( + await db.allDocs( + getScreenParams(null, { + include_docs: true, + }) + ) + ).rows.map(el => el.doc!) +} diff --git a/packages/server/src/sdk/index.ts b/packages/server/src/sdk/index.ts index 91dd3dffff..e3e88c25c4 100644 --- a/packages/server/src/sdk/index.ts +++ b/packages/server/src/sdk/index.ts @@ -11,6 +11,7 @@ import { default as plugins } from "./plugins" import * as views from "./app/views" import * as permissions from "./app/permissions" import * as rowActions from "./app/rowActions" +import * as screens from "./app/screens" import * as common from "./app/common" const sdk = { @@ -23,6 +24,7 @@ const sdk = { datasources, queries, plugins, + screens, views, permissions, links, diff --git a/packages/shared-core/src/sdk/documents/index.ts b/packages/shared-core/src/sdk/documents/index.ts index 4b17c1ea08..502e968a15 100644 --- a/packages/shared-core/src/sdk/documents/index.ts +++ b/packages/shared-core/src/sdk/documents/index.ts @@ -1,3 +1,4 @@ export * as applications from "./applications" export * as automations from "./automations" export * as users from "./users" +export * as screens from "./screens" diff --git a/packages/shared-core/src/sdk/documents/screens.ts b/packages/shared-core/src/sdk/documents/screens.ts new file mode 100644 index 0000000000..8fdd7087c8 --- /dev/null +++ b/packages/shared-core/src/sdk/documents/screens.ts @@ -0,0 +1,24 @@ +import { Screen } from "@budibase/types" +import { flattenObject } from "../../utils" + +export function findInSettings(screen: Screen, toFind: string) { + const flattened = flattenObject(screen.props) + const foundIn: { setting: string; value: string }[] = [] + for (let key of Object.keys(flattened)) { + let found = false + if (typeof flattened[key] === "string") { + found = flattened[key].includes(toFind) + } else if (Array.isArray(flattened[key])) { + found = flattened[key].find( + (el: any) => typeof el === "string" && el.includes(toFind) + ) + } + if (found) { + foundIn.push({ + setting: key, + value: flattened[key], + }) + } + } + return foundIn +} diff --git a/packages/shared-core/src/utils.ts b/packages/shared-core/src/utils.ts index fac8fa61ee..afc1c8872b 100644 --- a/packages/shared-core/src/utils.ts +++ b/packages/shared-core/src/utils.ts @@ -173,3 +173,20 @@ export function processSearchFilters( ], } } + +export function flattenObject( + obj: Record, + parentKey: string = "", + state: Record = {} +) { + for (const key of Object.keys(obj)) { + const newKey = parentKey.length ? `${parentKey}.${key}` : key + const value = obj[key] + if (value && typeof value === "object" && !Array.isArray(value)) { + flattenObject(value, newKey, state) + } else { + state[newKey] = value + } + } + return state +} diff --git a/packages/types/src/api/web/app/screen.ts b/packages/types/src/api/web/app/screen.ts index f7cd5c0bf7..280c623216 100644 --- a/packages/types/src/api/web/app/screen.ts +++ b/packages/types/src/api/web/app/screen.ts @@ -1,4 +1,4 @@ -import { ScreenRoutingJson, Screen } from "../../../documents" +import { ScreenRoutingJson, Screen, SourceType } from "../../../documents" export interface FetchScreenRoutingResponse { routes: ScreenRoutingJson @@ -16,9 +16,12 @@ export interface DeleteScreenResponse { message: string } -export interface UsageScreenResponse { - screens: { - url: string - _id: string - }[] +export interface ScreenUsage { + url: string + _id: string +} + +export interface UsageScreenResponse { + sourceType: SourceType + screens: ScreenUsage[] }