@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
1 lines • 55.5 kB
Source Map (JSON)
{"version":3,"file":"c8y-ngx-components-branding-shared-data.mjs","sources":["../../branding/shared/data/apply-branding-locally.service.ts","../../branding/shared/data/branding-shades.service.ts","../../branding/shared/data/branding-version.service.ts","../../branding/shared/data/branding.type.ts","../../branding/shared/data/branding-tracking.service.ts","../../branding/shared/data/store-branding.service.ts","../../branding/shared/data/c8y-ngx-components-branding-shared-data.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport { OptionsService } from '@c8y/ngx-components';\nimport { BrandingOptionsJson } from './branding.type';\nimport { applyBrandingOptions, getOptionsToMerge, mergeOptions } from '@c8y/bootstrap';\n\n@Injectable({ providedIn: 'root' })\nexport class ApplyBrandingLocallyService {\n private keysToRemove: Array<string> | null;\n\n constructor(private options: OptionsService) {}\n\n applyBranding(optionsJson?: BrandingOptionsJson) {\n if (!this.keysToRemove) {\n this.keysToRemove = Object.keys(this.combineOptions());\n }\n const combinedOptions = this.combineOptions(optionsJson);\n const newKeysToRemove = Object.keys(combinedOptions);\n\n // avoid to remove keys that would actually be set again afterwards\n const keysToActuallyRemove = this.keysToRemove.filter(key => !newKeysToRemove.includes(key));\n this.removeKeysFromOptions(keysToActuallyRemove);\n\n this.keysToRemove = newKeysToRemove;\n\n applyBrandingOptions(combinedOptions);\n this.applyApplicationOptions(combinedOptions);\n }\n\n resetBranding() {\n this.applyBranding();\n }\n\n private applyApplicationOptions(optionsJson: any) {\n Object.entries(optionsJson).forEach(([key, value]) => {\n this.options.set(key, value);\n });\n }\n\n private removeKeysFromOptions(keys: string[]) {\n for (const key of keys) {\n this.options.delete(key);\n }\n }\n\n private combineOptions(optionsJson?: BrandingOptionsJson) {\n const optionsToMerge = getOptionsToMerge();\n if (!optionsToMerge) {\n // should never happen as the options should be set quite early in bootstrapping process.\n throw Error(`Failed to retrieve options for merging`);\n }\n if (optionsJson) {\n optionsToMerge.dynamicOptions = optionsJson;\n }\n return mergeOptions(optionsToMerge);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { default as chroma } from 'chroma-js';\n\n@Injectable({ providedIn: 'root' })\nexport class BrandingShadesService {\n getShadeColorBrandingCssVars(newBrandPrimary: string) {\n const shades = this.generateShades(newBrandPrimary);\n return this.shadesToObject(shades);\n }\n\n isValidShadeColor(color: string): boolean {\n try {\n return chroma.valid(color);\n } catch {\n return false;\n }\n }\n\n hasCustomShadesSet(\n previousBrandPrimary: string,\n otherVars: Record<string, string | number>\n ): boolean {\n if (previousBrandPrimary && otherVars) {\n const oldShades = this.generateShades(previousBrandPrimary);\n const oldShadesObj = this.shadesToObject(oldShades);\n for (const shadeKey of Object.keys(oldShadesObj)) {\n const fromVars = otherVars[shadeKey];\n const generated = oldShadesObj[shadeKey];\n if (fromVars === null || fromVars === undefined) {\n continue;\n }\n if (fromVars !== generated) {\n return true;\n }\n }\n }\n return false;\n }\n\n private shadesToObject(shades: string[]) {\n const brandingCssVars: Record<`c8y-brand-${number}0`, string> = {};\n let i = 1;\n for (const shade of shades) {\n const key = `c8y-brand-${i}0` as const;\n brandingCssVars[key] = shade;\n i++;\n }\n\n return brandingCssVars;\n }\n\n private generateShades(inputColor: string) {\n const referenceShades = [\n '#134158',\n '#1C5569',\n '#058192', // primary color\n '#22A6AA',\n '#3CC1B7',\n '#8ADBD5',\n '#C5EDEA',\n '#EBF9F8'\n ];\n // Calculate the luminance of the reference shades\n const referenceLuminances = referenceShades.map(color => chroma(color).luminance());\n const inputColorAsHex = chroma(inputColor);\n // Generate shades of the input color with the same luminance as the reference shades\n const generatedShades = referenceLuminances.map(luminance =>\n chroma(inputColor).luminance(luminance).hex('rgb')\n );\n // Calculate the distance between the input color and each color in the generatedShades array\n const distances = generatedShades.map(color => chroma.deltaE(inputColorAsHex, color));\n // Find the index of the color with the smallest distance\n const index = distances.indexOf(Math.min(...distances));\n generatedShades[index] = inputColorAsHex.hex('rgb');\n return generatedShades;\n }\n}\n","import { Injectable } from '@angular/core';\n\n/**\n * Service for creating and manipulating branding versions.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class BrandingVersionService {\n static readonly nameAndIterationSeparator = '-';\n\n /**\n * Creates the initial branding version for a given name.\n * @param name The name of the branding.\n * @returns The initial branding version.\n */\n createInitialBrandingVersion<T extends string>(name: T) {\n return `${name}${BrandingVersionService.nameAndIterationSeparator}${1}` as const;\n }\n\n /**\n * Splits a branding version into its name and iteration.\n * @param version The branding version to split.\n * @returns The name and iteration of the branding version.\n *\n * Errors are thrown if the version is not in the expected format.\n */\n splitBrandingIntoNameAndIteration(version: string): { name: string; iteration: number } {\n const splitted = version.split(BrandingVersionService.nameAndIterationSeparator);\n if (splitted.length < 2) {\n throw Error(\n `A valid version should at least conatin one '${BrandingVersionService.nameAndIterationSeparator}', this is not the case for '${version}'`\n );\n }\n\n const lastValueOfSplittedArray = splitted[splitted.length - 1];\n if (lastValueOfSplittedArray === '' || !/[0-9]+/.test(lastValueOfSplittedArray)) {\n throw Error(\n `The second part of the version should be a positive integer, this is not the case for '${lastValueOfSplittedArray}' from '${version}'`\n );\n }\n\n const iteration = Number.parseInt(lastValueOfSplittedArray);\n if (Number.isNaN(iteration) && iteration <= 0) {\n throw Error(\n `The second part of the version should be a positive integer, this is not the case for '${iteration}' from '${version}'`\n );\n }\n\n const name = splitted.slice(0, -1).join(BrandingVersionService.nameAndIterationSeparator);\n if (!name) {\n throw Error(\n `The first part of the version should not be empty, this is the case for '${name}' from '${version}'`\n );\n }\n\n return { iteration, name };\n }\n\n /**\n * Bumps the iteration of a branding version.\n * @param version The branding version to bump.\n * @returns The bumped branding version.\n *\n * Errors are thrown if the version is not in the expected format.\n */\n bumpBrandingIteration(version: string) {\n const { name, iteration } = this.splitBrandingIntoNameAndIteration(version);\n return `${name}${BrandingVersionService.nameAndIterationSeparator}${iteration + 1}` as const;\n }\n}\n","import type { FormBuilder, FormControl } from '@angular/forms';\nimport { Alert, colorValidator } from '@c8y/ngx-components';\nimport type { ApplicationOptions } from '@c8y/options';\n\ntype ParamIntersection<T> = {\n [K in keyof T]: (x: T[K]) => void;\n}[keyof T] extends (x: infer I) => void\n ? I\n : never;\n\nexport type BrandingFormValue = ReturnType<typeof createGenericBrandingForm>['value'];\nexport type BrandingFormKeys = keyof BrandingFormValue;\nexport type BrandingFormTopLevelKeys = (typeof brandingFormGroupTopLevelEntries)[number];\nexport type BrandingFormTopLevelKeysToUnpack =\n (typeof brandingFormGroupTopLevelEntriesToUnpack)[number];\n\nexport type TopLevelFormKeysNotToUnpack = Exclude<\n BrandingFormTopLevelKeys,\n BrandingFormTopLevelKeysToUnpack\n>;\nexport type UnpackedTopLevelFormKeys = ParamIntersection<\n Pick<BrandingFormValue, BrandingFormTopLevelKeysToUnpack>\n>;\nexport type NotUnpackedTopLevelFormKeys = Pick<BrandingFormValue, TopLevelFormKeysNotToUnpack>;\nexport type TopLevelForm = NotUnpackedTopLevelFormKeys & UnpackedTopLevelFormKeys;\nexport type TopLevelValues = TopLevelForm;\n\nexport type BrandingCSSVarsForm = Omit<BrandingFormValue, BrandingFormTopLevelKeys>;\n\nexport type BrandingCSSVarsValues = ParamIntersection<BrandingCSSVarsForm> &\n ReturnType<typeof createBrandingForm>['value'];\n\nexport type BrandingOptionsJson = TopLevelValues & {\n brandingCssVars?: BrandingCSSVarsValues;\n} & Partial<ApplicationOptions>;\n\nexport const brandingFormGroupTopLevelEntries = [\n 'cookieBanner',\n 'genericApplicationOptions',\n 'darkThemeAvailable',\n 'messageBanner'\n] as const satisfies ReadonlyArray<BrandingFormKeys>;\nexport const brandingFormGroupTopLevelEntriesToUnpack = [\n 'genericApplicationOptions'\n] as const satisfies ReadonlyArray<(typeof brandingFormGroupTopLevelEntries)[number]>;\n\nexport const numberBrandingVars = ['brand-logo-img-height', 'btn-border-radius-base'] as const;\nexport const colorBrandingVars = [\n 'brand-dark',\n 'brand-light',\n 'brand-primary',\n 'c8y-brand-10',\n 'c8y-brand-20',\n 'c8y-brand-30',\n 'c8y-brand-40',\n 'c8y-brand-50',\n 'c8y-brand-60',\n 'c8y-brand-70',\n 'c8y-brand-80',\n 'palette-status-info',\n 'palette-status-warning',\n 'palette-status-success',\n 'palette-status-danger',\n 'palette-status-info-light',\n 'palette-status-warning-light',\n 'palette-status-success-light',\n 'palette-status-danger-light',\n 'palette-status-info-dark',\n 'palette-status-warning-dark',\n 'palette-status-success-dark',\n 'palette-status-danger-dark',\n 'body-background-color',\n 'text-color',\n 'text-muted',\n 'link-color',\n 'link-hover-color',\n 'action-bar-background-default',\n 'action-bar-color-actions-hover',\n 'action-bar-color-actions',\n 'action-bar-color-default',\n 'action-bar-icon-color',\n 'header-color',\n 'header-text-color',\n 'header-hover-color',\n 'navigator-bg-color',\n 'navigator-active-bg',\n 'navigator-border-active',\n 'navigator-header-bg',\n 'navigator-title-color',\n 'navigator-separator-color',\n 'navigator-text-color',\n 'navigator-color-active',\n 'right-drawer-background-default',\n 'right-drawer-text-color-default',\n 'right-drawer-separator-color',\n 'right-drawer-link-color',\n 'right-drawer-link-color-hover',\n 'right-drawer-text-color-muted'\n] as const;\nexport const stringBrandingVars = ['brand-logo-img', 'navigator-platform-logo'] as const;\n\nexport const stringOrNumberBrandingVars = ['navigator-platform-logo-height'] as const;\n\nexport const allBrandingCSSVars = [\n ...numberBrandingVars,\n ...stringBrandingVars,\n ...colorBrandingVars\n] as const;\n\nexport function createGenericBrandingForm(formBuilder: FormBuilder) {\n const form = formBuilder.group({\n darkThemeAvailable: formBuilder.control<boolean>(false),\n cookieBanner: formBuilder.group({\n cookieBannerTitle: formBuilder.control<string>(undefined),\n cookieBannerText: formBuilder.control<string>(undefined),\n cookieBannerDisabled: formBuilder.control(false),\n policyUrl: formBuilder.control<string>(undefined),\n policyVersion: formBuilder.control<string>(undefined)\n }),\n messageBanner: formBuilder.group({\n messageBannerEnabled: formBuilder.control(false),\n messageBannerContent: formBuilder.control<string>(''),\n messageBannerType: formBuilder.control<Alert['type']>('info')\n }),\n baseTypography: formBuilder.group({\n 'font-url': formBuilder.control<string>(undefined),\n 'font-family-base': formBuilder.control<string>(undefined)\n }),\n headingsAndNavigatorTypography: formBuilder.group({\n 'font-family-headings': formBuilder.control<string>(undefined),\n 'navigator-font-family': formBuilder.control<string>('var(--font-family-base)')\n }),\n genericApplicationOptions: formBuilder.group({\n globalTitle: formBuilder.control<string>(undefined),\n faviconUrl: formBuilder.control<string>(undefined)\n })\n });\n return form;\n}\n\nexport function createBrandingForm(formBuilder: FormBuilder) {\n const colorControls = colorBrandingVars.reduce(\n (acc, key) => {\n acc[key] = formBuilder.control<string>(undefined, { asyncValidators: [colorValidator()] });\n return acc;\n },\n {} as { [key in (typeof colorBrandingVars)[number]]: FormControl<string> }\n );\n const stringControls = stringBrandingVars.reduce(\n (acc, key) => {\n acc[key] = formBuilder.control<string>(undefined);\n return acc;\n },\n {} as { [key in (typeof stringBrandingVars)[number]]: FormControl<string> }\n );\n const numberControls = numberBrandingVars.reduce(\n (acc, key) => {\n acc[key] = formBuilder.control<number>(undefined);\n return acc;\n },\n {} as { [key in (typeof numberBrandingVars)[number]]: FormControl<number> }\n );\n const stringOrNumberControls = stringOrNumberBrandingVars.reduce(\n (acc, key) => {\n acc[key] = formBuilder.control<number>(undefined);\n return acc;\n },\n {} as {\n [key in (typeof stringOrNumberBrandingVars)[number]]: FormControl<string | number>;\n }\n );\n const form = formBuilder.group({\n ...colorControls,\n ...stringControls,\n ...numberControls,\n ...stringOrNumberControls\n });\n\n return form;\n}\n","import { Injectable, Optional } from '@angular/core';\nimport { GainsightService, PxEventData } from '@c8y/ngx-components';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class BrandingTrackingService {\n readonly prefix = 'brandingManager';\n constructor(@Optional() private gainsight: GainsightService) {}\n\n getStartedUsingBranding() {\n this.triggerEvent('getStartedUsingBranding');\n }\n\n deleteAllBrandings() {\n this.triggerEvent('deleteAllBrandings');\n }\n\n exportBranding() {\n this.triggerEvent('exportBranding');\n }\n\n addNewVersion() {\n this.triggerEvent('addNewVersion');\n }\n\n duplicateVersion() {\n this.triggerEvent('duplicateVersion');\n }\n\n applyToApps(apps: string[]) {\n this.triggerEvent('applyToApps', { apps });\n }\n\n importBranding() {\n this.triggerEvent('importBranding');\n }\n\n deleteBrandingVariant() {\n this.triggerEvent('deleteBrandingVariant');\n }\n\n openPreviewForBranding() {\n this.triggerEvent('openPreviewForBranding');\n }\n\n private triggerEvent(action: string, props?: PxEventData) {\n if (!this.gainsight) {\n return;\n }\n\n const finalProps = {\n ...props,\n action\n };\n\n return this.gainsight.triggerEvent(this.prefix, finalProps);\n }\n}\n","import { Injectable } from '@angular/core';\nimport {\n ApplicationAvailability,\n ApplicationType,\n FetchClient,\n IApplication,\n IApplicationBinary,\n IManagedObject,\n InventoryBinaryService,\n InventoryService\n} from '@c8y/client';\nimport { ApplicationService } from '@c8y/client';\nimport { AppStateService, ThemeSwitcherService, ZipService } from '@c8y/ngx-components';\nimport { defer, BehaviorSubject, Observable } from 'rxjs';\nimport { map, switchMap } from 'rxjs/operators';\nimport { cloneDeep, uniq } from 'lodash-es';\nimport { BrandingVersionService } from './branding-version.service';\nimport { BrandingOptionsJson, allBrandingCSSVars, numberBrandingVars } from './branding.type';\nimport { StaticAsset, StaticAssetsService } from '@c8y/ngx-components/static-assets/data';\nimport { BrandingTrackingService } from './branding-tracking.service';\n\nexport interface BrandVersion {\n name: string;\n id: string;\n revision: number;\n version: string;\n tags: string[];\n owner?: string;\n lastUpdated?: string;\n publicOptionsApp?: IApplication;\n}\n\nexport interface BrandingFileDetails {\n fileName: string;\n blob: Blob;\n jsonContent?: any;\n}\n\nexport interface BrandingFileDetailsLegacy {\n path: string;\n value: string;\n blob?: Blob;\n fileName: string;\n urlWrapped: boolean;\n}\n\n/**\n * Service to load and store the branding of the tenant.\n */\n@Injectable({ providedIn: 'root' })\nexport class StoreBrandingService {\n readonly fileNames = {\n options: 'options.json',\n manifest: 'cumulocity.json',\n exportZipName: 'public-options.zip'\n } as const;\n readonly manifestValues = {\n name: 'public-options',\n contextPath: 'public-options',\n key: 'public-options-key',\n description: 'Application containing static assets used by e.g. branding.',\n noAppSwitcher: true,\n type: ApplicationType.HOSTED,\n availability: ApplicationAvailability.SHARED\n } as const satisfies IApplication;\n refreshTriggerBrandingVariants = new BehaviorSubject<void>(null);\n constructor(\n private applicationService: ApplicationService,\n private inventory: InventoryService,\n private binary: InventoryBinaryService,\n private zip: ZipService,\n private fetch: FetchClient,\n private brandingVersionService: BrandingVersionService,\n private appState: AppStateService,\n private staticAssets: StaticAssetsService,\n private themeSwitcher: ThemeSwitcherService,\n private brandingTracking: BrandingTrackingService\n ) {}\n\n /**\n * Sets the `latest` tag on the provided branding version. Making it the global active branding.\n */\n async markAsActive(brandingVersion: BrandVersion, app?: IApplication): Promise<void> {\n const publicOptions = app || (await this.getPublicOptionsApp());\n const tags = brandingVersion.tags || [];\n const version = brandingVersion.version;\n await this.applicationService.setPackageVersionTag(publicOptions, version, [...tags, 'latest']);\n }\n\n /**\n * Opens a new tab with to preview the branding. The branding must have been saved beforehand.\n * @param brandingName the name of the branding to be previewed\n */\n openPreviewForBranding(brandingName: string) {\n this.brandingTracking.openPreviewForBranding();\n window.open(\n `/apps/${\n this.appState.currentApplication.value?.contextPath || 'cockpit'\n }/index.html?brandingPreview=true&dynamicOptionsUrl=/apps/public/public-options@${brandingName}/options.json`,\n '_blank',\n 'noopener,noreferrer'\n );\n }\n\n /**\n * Returns the brandings of the tenant.\n * If no public options app is found, publicOptions will be undefined and variants an empty array.\n * For old brandings (created without versioning) a default version is returned.\n */\n async loadBrandingVariants(\n app?: IApplication\n ): Promise<{ publicOptions: IApplication | undefined; variants: BrandVersion[] }> {\n const publicOptions = app || (await this.getPublicOptionsApp());\n if (!publicOptions) {\n return { publicOptions: undefined, variants: [] };\n }\n const { data: versions } = await this.applicationService.listVersions(publicOptions);\n let mappedVersions: BrandVersion[] =\n versions\n ?.map(tmp => {\n try {\n const { name, iteration } =\n this.brandingVersionService.splitBrandingIntoNameAndIteration(tmp.version);\n return {\n revision: iteration,\n name: name,\n id: tmp.binaryId,\n version: tmp.version,\n tags: tmp.tags || [],\n publicOptionsApp: publicOptions\n };\n } catch (e) {\n console.warn('Failed to parse version', tmp, e);\n return undefined;\n }\n })\n ?.filter(Boolean) || [];\n if (!versions && publicOptions.activeVersionId) {\n mappedVersions = [\n {\n name: 'default',\n id: publicOptions.activeVersionId,\n version: 'default-1',\n revision: 1,\n tags: ['latest', 'default'],\n publicOptionsApp: publicOptions\n }\n ];\n }\n\n const variants = await this.getMetadataOfBrandingBinaries(mappedVersions);\n return { publicOptions, variants };\n }\n\n /**\n * As the branding is not immediately available after creation, this method will wait for the branding to be present.\n * @param version The version of the branding to be retrieved.\n */\n async waitForBrandingToBePresent(version: string): Promise<void> {\n const numberOfAttempts = 120;\n const sleepDurationInSeconds = 1;\n for (let i = 0; i < numberOfAttempts; i++) {\n try {\n // do not sleep before the first attempt\n if (i !== 0) {\n await new Promise(resolve => setTimeout(resolve, sleepDurationInSeconds * 1_000));\n }\n await this.getBrandingOptionsForVersion(version);\n console.info(`Branding \"${version}\" available now.`);\n return;\n } catch (e) {\n console.warn(\n `Branding \"${version}\" not yet present, retrying in ${sleepDurationInSeconds} seconds...`,\n e\n );\n }\n }\n throw new Error(\n `Branding \"${version}\" not available after ${numberOfAttempts * sleepDurationInSeconds} seconds, giving up.`\n );\n }\n\n /**\n * Will create a the initial branding based on the currently applied CSS variables.\n */\n async getStartedUsingBranding(): Promise<void> {\n const allVariables: Record<string, string> = {};\n const themeToRetrieveVars = ['light', 'dark'] as const;\n const unretrievableVars = new Array<string>();\n for (const theme of themeToRetrieveVars) {\n this.themeSwitcher.temporaryChangeTheme(theme);\n const styles = getComputedStyle(document.body);\n const variablesToSkip = [\n 'navigator-platform-logo',\n 'brand-logo-img'\n ] satisfies (typeof allBrandingCSSVars)[number][];\n const values = allBrandingCSSVars\n .filter(cssVar => !variablesToSkip.includes(cssVar as any))\n .reduce((prev, key) => {\n const directValue = styles.getPropertyValue(`--${key}`);\n const c8yPrefixedValue = styles.getPropertyValue(`--c8y-${key}`);\n const newKey = theme === 'light' ? key : `dark-${key}`;\n if (!directValue && !c8yPrefixedValue) {\n unretrievableVars.push(newKey);\n return prev;\n }\n let value: string | number = directValue || c8yPrefixedValue;\n if (numberBrandingVars.includes(key as any)) {\n try {\n value = Number.parseFloat(value.replace(/[A-Za-z]/g, '').trim());\n } catch (e) {\n console.warn(\n `Failed to parse number for \"${key}\" value that failed to parse: \"${value}\"`,\n e\n );\n return prev;\n }\n }\n return Object.assign(prev, { [newKey]: value });\n }, {});\n Object.assign(allVariables, values);\n }\n this.themeSwitcher.resetTemporaryTheme();\n\n try {\n await this.createPublicOptionsAppFromInheritedOptions(allVariables);\n } catch (e) {\n console.warn(e);\n }\n }\n\n getZipForBinary(\n binaryId: string,\n fileName: string = this.fileNames.exportZipName\n ): Observable<File> {\n return defer(() => this.binary.download(binaryId)).pipe(\n switchMap(response => response.blob()),\n map(blob => new File([blob], fileName))\n );\n }\n\n /**\n * Deletes the public options app and therefore all brandings.\n * The public options app can be optionally provided to avoid another request for it.\n */\n async deleteAllBrandings(publicOptions?: IApplication): Promise<void> {\n publicOptions = publicOptions || (await this.getPublicOptionsApp());\n await this.applicationService.delete(publicOptions);\n }\n\n /**\n * Enhances the provided branding versions with metadata from the linked binaries.\n * It will add the owner and lastUpdated fields to the versions.\n * The provided array is altered.\n */\n async getMetadataOfBrandingBinaries(versions: BrandVersion[]): Promise<BrandVersion[]> {\n const binaryIds = uniq(versions.map(tmp => tmp.id));\n if (!binaryIds.length) {\n return versions;\n }\n const { data: metadata } = await this.inventory.list({\n ids: binaryIds.join(','),\n pageSize: 2000\n });\n return versions.map(version => {\n const metadataForVersion =\n metadata.find(tmp => tmp.id === version.id) || ({} as IManagedObject);\n const { owner, lastUpdated } = metadataForVersion;\n return Object.assign(version, { owner, lastUpdated });\n });\n }\n\n /**\n * Saves the provided branding as a new version for the public options app.\n * The public options app can be optionally provided to avoid another request for it.\n */\n async saveBranding(\n blob: Blob | File,\n version: string,\n tags: string[] = [],\n publicOptionsApp?: IApplication\n ): Promise<{\n version: string;\n binary: IApplicationBinary;\n tags: string[];\n }> {\n const file = blob instanceof File ? blob : new File([blob], `public-options-${version}.zip`);\n const publicOptions = publicOptionsApp || (await this.getPublicOptionsApp());\n\n const { data: binary } = await this.applicationService\n .binary(publicOptions)\n .uploadApplicationVersion(file, version, tags);\n if (!publicOptions.activeVersionId || tags.includes('latest')) {\n await this.applicationService.update({\n id: publicOptions.id,\n activeVersionId: `${binary.binaryId}`\n });\n }\n this.refreshTriggerBrandingVariants.next();\n return { version, binary, tags };\n }\n\n /**\n * Removes a branding version from the public options app.\n * The public options app can be optionally provided to avoid another request for it.\n */\n async deleteBrandingVersion(version: string, publicOptions?: IApplication): Promise<void> {\n publicOptions = publicOptions || (await this.getPublicOptionsApp());\n await this.applicationService.deleteVersionPackage(publicOptions, { version });\n this.refreshTriggerBrandingVariants.next();\n }\n\n /**\n * Returns the blob of a zip file containing the provided branding options (options.json) and the manifest (cumulocity.json).\n */\n async getBrandingZip(content: Record<string, any> = {}): Promise<Blob> {\n content.lastUpdated = new Date().toISOString();\n const contentAsString = JSON.stringify(content);\n const zip = await this.zip.createZip([\n { fileName: this.fileNames.options, blob: new Blob([contentAsString]) },\n { fileName: this.fileNames.manifest, blob: new Blob([JSON.stringify(this.manifestValues)]) }\n ]);\n return zip;\n }\n\n /**\n * Adds a new branding version to the public options app.\n * The public options app can be optionally provided to avoid another request for it.\n */\n async addBranding(\n version: string,\n content: BrandingOptionsJson = {},\n tags: string[] = [],\n publicOptionsApp?: IApplication\n ): Promise<{\n version: string;\n binary: IApplicationBinary;\n tags: string[];\n }> {\n const zip = await this.getBrandingZip(content);\n\n return await this.saveBranding(zip, version, tags, publicOptionsApp);\n }\n\n /**\n * Returns the branding options for the provided version.\n * If no branding was found (e.g. status 404), an error is thrown.\n */\n async getBrandingOptionsForVersion(version?: string): Promise<BrandingOptionsJson> {\n const url = `/apps/public/public-options${version ? `@${version}` : ''}/${this.fileNames.options}?nocache=${new Date().getTime()}`;\n const response = await this.fetch.fetch(url);\n if (response.status !== 200) {\n throw Error(`Unexpected status code: ${response.status}`);\n }\n\n const content = await response.json();\n return content as BrandingOptionsJson;\n }\n\n /**\n * Saves a new iteration of an already existing branding.\n */\n async saveExistingBranding(\n branding: Record<string, any>,\n currentVersion: string,\n tagsOfCurrentVersion: string[] = [],\n newVersion?: string\n ): Promise<string> {\n const publicOptions = await this.getPublicOptionsApp();\n const versionToBeSet = newVersion\n ? this.brandingVersionService.createInitialBrandingVersion(newVersion)\n : this.brandingVersionService.bumpBrandingIteration(currentVersion);\n\n const finalTags = tagsOfCurrentVersion;\n // only apply latest tag directly\n // there seems to be some special handling for the latest tag in the backend, that allows to directly move it while uploading the new version.\n // for all other tags this results in a 409 conflict. We therefore need to first delete the old version, before setting the other tags on the new version.\n if (!newVersion) {\n tagsOfCurrentVersion = tagsOfCurrentVersion.filter(tag => tag === 'latest');\n }\n await this.addBranding(versionToBeSet, branding, tagsOfCurrentVersion, publicOptions);\n if (!newVersion) {\n try {\n await this.deleteBrandingVersion(currentVersion, publicOptions);\n } catch (e) {\n if (e.res.status !== 404) {\n throw e;\n }\n }\n await this.applicationService.setPackageVersionTag(publicOptions, versionToBeSet, finalTags);\n }\n\n return versionToBeSet;\n }\n\n /**\n * Combines current branding options with the provided branding variables and creates a new public options app.\n * Any assets in the branding will be cloned.\n */\n async createPublicOptionsAppFromInheritedOptions(brandingVars?: Record<string, string>): Promise<{\n version: string;\n binary: IApplicationBinary;\n tags: string[];\n }> {\n let currentlyAppliedBranding: BrandingOptionsJson;\n let fallBackBranding: BrandingOptionsJson = {};\n try {\n currentlyAppliedBranding = await this.getBrandingOptionsForVersion();\n fallBackBranding = cloneDeep(currentlyAppliedBranding);\n } catch (e) {\n console.warn('Failed to get currently applied branding, proceeding with empty branding.', e);\n }\n\n if (brandingVars) {\n currentlyAppliedBranding = currentlyAppliedBranding || {};\n const brandingCssVars = currentlyAppliedBranding.brandingCssVars || {};\n Object.assign(brandingCssVars, brandingVars);\n currentlyAppliedBranding.brandingCssVars = brandingCssVars;\n }\n\n if (currentlyAppliedBranding) {\n try {\n const { oldAssets, newAssets } = await this.staticAssets.cloneAssetsIntoTenant('branding');\n currentlyAppliedBranding = this.replaceBrandingAssetsInBrandingOptions(\n currentlyAppliedBranding,\n oldAssets,\n newAssets\n );\n } catch (e) {\n console.warn('Failed to relocate branding assets into current tenant.', e);\n }\n }\n\n const publicOptionsApp = await this.createPublicOptionsApp();\n\n const defaultBrandingName = `default`;\n const result = await this.addBranding(\n this.brandingVersionService.createInitialBrandingVersion(defaultBrandingName),\n currentlyAppliedBranding || {},\n ['latest', defaultBrandingName],\n publicOptionsApp\n );\n\n const fallbackBrandingName = `fallback`;\n await this.addBranding(\n this.brandingVersionService.createInitialBrandingVersion(fallbackBrandingName),\n fallBackBranding,\n [fallbackBrandingName],\n publicOptionsApp\n );\n\n return result;\n }\n\n /**\n * Replaces the assets in the branding options with the new assets.\n * Goes through the provided `oldAssets` and replaces their occurrences in the branding with the corresponding `newAssets` entry sharing the same fileName.\n * Returns the updated branding options.\n */\n replaceBrandingAssetsInBrandingOptions(\n branding: BrandingOptionsJson,\n oldAssets: StaticAsset[],\n newAssets: StaticAsset[]\n ): BrandingOptionsJson {\n let brandingAsJSONString = JSON.stringify(branding);\n for (const oldAsset of oldAssets) {\n const newLocatedAsset = newAssets.find(tmp => tmp.fileName === oldAsset.fileName);\n if (!newLocatedAsset) {\n continue;\n }\n // if the path is the same, we don't need to replace it.\n if (oldAsset.path === newLocatedAsset.path) {\n continue;\n }\n\n // TODO: use proper replaceAll once it's available with es2021\n brandingAsJSONString = brandingAsJSONString.split(oldAsset.path).join(newLocatedAsset.path);\n }\n return JSON.parse(brandingAsJSONString);\n }\n\n private async getPublicOptionsApp() {\n try {\n const { data: manifest } = await this.applicationService.getManifestOfContextPath(\n this.manifestValues.contextPath\n );\n const { data: app } = await this.applicationService.detail(manifest.id);\n if (app.owner.tenant.id !== this.appState.currentTenant.value?.name) {\n return undefined;\n }\n return app;\n } catch (e) {\n // e.g. reached when no app with the given context path exists\n return undefined;\n }\n }\n\n private async createPublicOptionsApp() {\n const { data: app } = await this.applicationService.create(this.manifestValues);\n return app;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["i1","i3.BrandingVersionService","i5.BrandingTrackingService"],"mappings":"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