diff --git a/dev/env/opensource/development.env b/dev/env/opensource/development.env index ec8125984b..292cfebcc2 100644 --- a/dev/env/opensource/development.env +++ b/dev/env/opensource/development.env @@ -18,3 +18,5 @@ ZITADEL_COOKIE_SECRET=!@OUVOF$@E@%F^&@$*ER!F SERVICE_CLIENT_ID=charts SERVICE_CLIENT_SECRET=uvdZDsiZJslDj8bKbTlKR43oMHqEiNGppxhMjCQWqQXkHUmGpW2iuLYNJ5tdmmlL + +US_MASTER_TOKEN=us-master-token diff --git a/src/server/components/charts-engine/components/processor/worker-chart-builder.ts b/src/server/components/charts-engine/components/processor/worker-chart-builder.ts index 82600a2841..6875852e45 100644 --- a/src/server/components/charts-engine/components/processor/worker-chart-builder.ts +++ b/src/server/components/charts-engine/components/processor/worker-chart-builder.ts @@ -54,7 +54,6 @@ export const getWizardChartBuilder = async ( const defaultColorPaletteId = getDefaultColorPaletteId({ ctx: app.nodekit.ctx, tenantSettings, - palettes, }); // Nothing happens here - just for compatibility with the editor diff --git a/src/server/components/features/features-list/EnableTenantSettingPalettes.ts b/src/server/components/features/features-list/EnableTenantSettingPalettes.ts index 45fc8e181d..3f7b73026e 100644 --- a/src/server/components/features/features-list/EnableTenantSettingPalettes.ts +++ b/src/server/components/features/features-list/EnableTenantSettingPalettes.ts @@ -4,7 +4,7 @@ import {createFeatureConfig} from '../utils'; export default createFeatureConfig({ name: Feature.EnableTenantSettingPalettes, state: { - development: false, - production: false, + development: true, + production: true, }, }); diff --git a/src/server/components/features/features-list/NewDefaultPalette.ts b/src/server/components/features/features-list/NewDefaultPalette.ts index febf836168..967e9a105e 100644 --- a/src/server/components/features/features-list/NewDefaultPalette.ts +++ b/src/server/components/features/features-list/NewDefaultPalette.ts @@ -4,7 +4,7 @@ import {createFeatureConfig} from '../utils'; export default createFeatureConfig({ name: Feature.NewDefaultPalette, state: { - development: false, - production: false, + development: true, + production: true, }, }); diff --git a/src/server/components/layout/opensource-layout-config.ts b/src/server/components/layout/opensource-layout-config.ts index 429ed0ba1a..9219afcaf3 100644 --- a/src/server/components/layout/opensource-layout-config.ts +++ b/src/server/components/layout/opensource-layout-config.ts @@ -1,6 +1,12 @@ import type {RenderParams} from '@gravity-ui/app-layout'; -import type {AppEnvironment, AppInstallation, DLGlobalData, DLUser} from '../../../shared'; +import type { + AppEnvironment, + AppInstallation, + DLGlobalData, + DLUser, + TenantSettings, +} from '../../../shared'; import {FALLBACK_LANGUAGES, Feature, Language, USER_SETTINGS_KEY} from '../../../shared'; import type {AppLayoutSettings, GetLayoutConfig} from '../../types/app-layout'; import {addTranslationsScript} from '../../utils/language'; @@ -71,6 +77,10 @@ export const getOpensourceLayoutConfig: GetLayoutConfig = async (args) => { // applying new favicon from rebranding const faviconUrl = isRebrandingEnabled ? '/os-favicon.ico' : config.faviconUrl; + const tenantSettings: TenantSettings = { + defaultColorPaletteId: res.locals.tenantDefaultColorPaletteId, + }; + const DL: DLGlobalData = { user, userSettings, @@ -96,6 +106,7 @@ export const getOpensourceLayoutConfig: GetLayoutConfig = async (args) => { docsUrl: config.docsUrl, orderedAuthRoles: config.orderedAuthRoles, authSignupDisabled: req.ctx.config.authSignupDisabled, + tenantSettings, ...appLayoutSettings.DL, }; const renderConfig: RenderParams<{DL: DLGlobalData}> = { diff --git a/src/server/middlewares/tenant-settings.ts b/src/server/middlewares/tenant-settings.ts new file mode 100644 index 0000000000..6a22dcd9f0 --- /dev/null +++ b/src/server/middlewares/tenant-settings.ts @@ -0,0 +1,44 @@ +import type {NextFunction, Request, Response} from '@gravity-ui/expresskit'; +import {REQUEST_ID_PARAM_NAME} from '@gravity-ui/nodekit'; + +import {onFail} from '../callbacks'; +import {registry} from '../registry'; +import type {DatalensGatewaySchemas} from '../types/gateway'; + +export function getTenantSettingsMiddleware() { + async function resolveTenantSettings(req: Request, res: Response, next: NextFunction) { + const {ctx} = req; + + const requestId = req.ctx.get(REQUEST_ID_PARAM_NAME); + const currentTenantId = 'common'; + + const {gatewayApi} = registry.getGatewayApi(); + const {getAuthArgsUSPrivate} = registry.common.auth.getAll(); + const authArgsUSPrivate = getAuthArgsUSPrivate(req, res); + + const tenantDetailsResponce = await gatewayApi.usPrivate._getTenantDetails({ + ctx, + headers: req.headers, + requestId: requestId ?? '', + authArgs: authArgsUSPrivate, + args: {tenantId: currentTenantId}, + }); + const resolvedTenant = tenantDetailsResponce.responseData; + res.locals.tenantDefaultColorPaletteId = resolvedTenant.settings?.defaultColorPaletteId; + + next(); + } + + return function resolveTenantSettingsMiddleware( + req: Request, + res: Response, + next: NextFunction, + ) { + resolveTenantSettings(req, res, next) + .catch((error) => { + req.ctx.logError('TENANT_RESOLVED_FAILED', error); + onFail(req, res); + }) + .catch((error) => next(error)); + }; +} diff --git a/src/server/modes/charts/plugins/datalens/js/helpers/colors/index.ts b/src/server/modes/charts/plugins/datalens/js/helpers/colors/index.ts index 57f0bf0a0f..9813d72242 100644 --- a/src/server/modes/charts/plugins/datalens/js/helpers/colors/index.ts +++ b/src/server/modes/charts/plugins/datalens/js/helpers/colors/index.ts @@ -23,6 +23,7 @@ export const getChartColorsConfig = ({ const fallbackColors = selectServerPalette({ palette: colorsConfig.palette, availablePalettes, + customColorPalettes: loadedColorPalettes, defaultColorPaletteId, }); diff --git a/src/server/modes/charts/plugins/datalens/preparers/pie/gravity-charts.ts b/src/server/modes/charts/plugins/datalens/preparers/pie/gravity-charts.ts index 0e77631bfd..798f3006a7 100644 --- a/src/server/modes/charts/plugins/datalens/preparers/pie/gravity-charts.ts +++ b/src/server/modes/charts/plugins/datalens/preparers/pie/gravity-charts.ts @@ -56,7 +56,7 @@ export function prepareD3Pie(args: PrepareFunctionArgs) { return { ...item, value: item.y, - color: String(item.color), + color: item.color, formattedValue: getFormattedValue(String(item.y), { ...measure, data_type: idToDataType[measure.guid], diff --git a/src/server/modes/opensource/routes.ts b/src/server/modes/opensource/routes.ts index 9824c74756..5c4eec3214 100644 --- a/src/server/modes/opensource/routes.ts +++ b/src/server/modes/opensource/routes.ts @@ -12,6 +12,7 @@ import {getZitadelRoutes} from '../../components/zitadel/routes'; import {ping} from '../../controllers/ping'; import {workbooksTransferController} from '../../controllers/workbook-transfer'; import {getConnectorIconsMiddleware} from '../../middlewares'; +import {getTenantSettingsMiddleware} from '../../middlewares/tenant-settings'; import type {ExtendedAppRouteDescription} from '../../types/controllers'; import {getConfiguredRoute} from '../../utils/routes'; import {applyPluginRoutes} from '../charts/init-charts-engine'; @@ -119,6 +120,7 @@ function getDataLensRoutes({ authArgs: getAuthArgs(req, res), }), }), + getTenantSettingsMiddleware(), ], ui: true, }; diff --git a/src/shared/schema/us-private/actions/index.ts b/src/shared/schema/us-private/actions/index.ts index 18d66619a9..8dd65f6ff0 100644 --- a/src/shared/schema/us-private/actions/index.ts +++ b/src/shared/schema/us-private/actions/index.ts @@ -1,5 +1,7 @@ import {entriesActions} from './entries'; +import {tenantActions} from './tenant'; export const actions = { ...entriesActions, + ...tenantActions, }; diff --git a/src/shared/schema/us-private/actions/tenant.ts b/src/shared/schema/us-private/actions/tenant.ts new file mode 100644 index 0000000000..13ad236c46 --- /dev/null +++ b/src/shared/schema/us-private/actions/tenant.ts @@ -0,0 +1,14 @@ +import {createAction} from '../../gateway-utils'; +import type {GetTenantDetailsArgs, GetTenantDetailsResponse} from '../../us/types'; + +const PRIVATE_PATH_PREFIX = '/private'; + +export const tenantActions = { + _getTenantDetails: createAction({ + method: 'GET', + path: ({tenantId}) => `${PRIVATE_PATH_PREFIX}/tenants/${tenantId}/details`, + params: (_, headers) => ({ + headers, + }), + }), +}; diff --git a/src/shared/schema/us/types/fields.ts b/src/shared/schema/us/types/fields.ts index 4bc9744f2f..8b3bc69eaf 100644 --- a/src/shared/schema/us/types/fields.ts +++ b/src/shared/schema/us/types/fields.ts @@ -95,12 +95,14 @@ export interface EntryRelationFields { isLocked: boolean; } +export interface TenantSettings { + defaultColorPaletteId?: string; +} + export interface TenantFields { tenantId: string; createdAt: string; enabled: boolean; deleting: boolean; - settings: { - defaultColorPaletteId?: string; - }; + settings: TenantSettings; } diff --git a/src/shared/schema/us/types/tenant.ts b/src/shared/schema/us/types/tenant.ts index b87bcd5c17..3cfabb0151 100644 --- a/src/shared/schema/us/types/tenant.ts +++ b/src/shared/schema/us/types/tenant.ts @@ -1,7 +1,20 @@ -import type {TenantFields} from './fields'; +import type {TenantFields, TenantSettings} from './fields'; export type SetDefaultColorPaletteArgs = { defaultColorPaletteId: string; }; export type SetDefaultColorPaletteResponse = TenantFields; + +export type GetTenantDetailsArgs = { + tenantId: string; +}; + +export type GetTenantDetailsResponse = TenantFields; + +export type ChangeTenantSettingArgs = { + key: keyof TenantSettings; + value: TenantSettings[keyof TenantSettings]; +}; + +export type ChangeTenantSettingResponse = TenantFields; diff --git a/tests/docker-compose.e2e.yml b/tests/docker-compose.e2e.yml index b3420e2fa9..a51ad5cff8 100644 --- a/tests/docker-compose.e2e.yml +++ b/tests/docker-compose.e2e.yml @@ -51,7 +51,7 @@ services: BI_COMPENG_PG_ON: 1 BI_COMPENG_PG_URL: postgresql://pg-user:postgres@postgres:5432/pg-compeng-db US_HOST: http://us:8080 - US_MASTER_TOKEN: ${US_MASTER_TOKEN:-us-master-token} + US_MASTER_TOKEN: us-master-token AUTH__TYPE: ${AUTH_TYPE:-NATIVE} AUTH__JWT_ALGORITHM: 'PS256' AUTH__JWT_KEY: -----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+HICDZMfimMIiGdd0dPr\n2N3zxHOJqiVXuvUj/aBBS7c8760rJUh4344sP/0Gid558yH/v1MtzZ0R9w09v6gb\nSNrSiNwIUNGPhbnm9Jf+kMezsI/rkcIdoVm3KJ8CFUYy6MRPzW7iJmIVRHBb82v1\nmAYCCQFU6IRtFIa9hQ8wedWwxqXZekSNS+6NB37dmmQB9kz2E3MY+KRLigOh4i3p\nCZ1ti3HVvMa9Rlgk9FmoWExzub5ECChqwm+vn8yFXjYW7kUSClcV2xx4nbQWqjrR\nyyLk6W2BNOuCFVvz0j+5XkpLAt7tljtVZc+572HBEKpF2mAdmAip5NzeDhKqucJ+\nZQIDAQAB\n-----END PUBLIC KEY----- @@ -114,6 +114,7 @@ services: environment: APP_MODE: full APP_ENV: production + US_MASTER_TOKEN: us-master-token APP_INSTALLATION: opensource AUTH_POLICY: disabled US_ENDPOINT: http://us:8080 @@ -140,6 +141,7 @@ services: environment: APP_MODE: full APP_ENV: production + US_MASTER_TOKEN: us-master-token APP_INSTALLATION: opensource AUTH_POLICY: disabled US_ENDPOINT: http://us:8080 diff --git a/tests/opensource-suites/__screenshots__/wizard/visualizations/scatter/coloring.test.ts/Wizard-Scatter-chart-Point-color-set-by-the-fake-title-of-the-field-screenshot-1.png b/tests/opensource-suites/__screenshots__/wizard/visualizations/scatter/coloring.test.ts/Wizard-Scatter-chart-Point-color-set-by-the-fake-title-of-the-field-screenshot-1.png index 3723776e46..ffddf8f1ad 100644 Binary files a/tests/opensource-suites/__screenshots__/wizard/visualizations/scatter/coloring.test.ts/Wizard-Scatter-chart-Point-color-set-by-the-fake-title-of-the-field-screenshot-1.png and b/tests/opensource-suites/__screenshots__/wizard/visualizations/scatter/coloring.test.ts/Wizard-Scatter-chart-Point-color-set-by-the-fake-title-of-the-field-screenshot-1.png differ diff --git a/tests/opensource-suites/wizard/visualizations/scatter/coloring.test.ts b/tests/opensource-suites/wizard/visualizations/scatter/coloring.test.ts index 1bfdb191f4..e3d6dc7c88 100644 --- a/tests/opensource-suites/wizard/visualizations/scatter/coloring.test.ts +++ b/tests/opensource-suites/wizard/visualizations/scatter/coloring.test.ts @@ -38,7 +38,7 @@ datalensTest.describe('Wizard', () => { // set color by fake title await wizardPage.colorDialog.open(); - await wizardPage.colorDialog.selectColor('#FF7E00'); + await wizardPage.colorDialog.selectColor('#FF8C00'); await wizardPage.colorDialog.apply(); await expect(previewLoader).not.toBeVisible();