{"version":3,"file":"c8y-ngx-components-translation-editor-data.mjs","sources":["../../translation-editor/data/translation-store.service.ts","../../translation-editor/data/c8y-ngx-components-translation-editor-data.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\nimport {\n  ApplicationAvailability,\n  ApplicationService,\n  ApplicationType,\n  FetchClient,\n  IApplication\n} from '@c8y/client';\nimport { AppStateService, ZipService } from '@c8y/ngx-components';\nimport { uniq } from 'lodash-es';\n\nexport interface TranslationLocale {\n  label: string;\n  locale: string;\n}\n\n@Injectable({\n  providedIn: 'root'\n})\nexport class TranslationStoreService {\n  protected readonly translationAppName = 'User defined translations';\n  protected readonly translationAppContextPath = 'user-defined-translations';\n\n  constructor(\n    private appService: ApplicationService,\n    private appState: AppStateService,\n    private zip: ZipService,\n    private fetchClient: FetchClient\n  ) {}\n\n  /**\n   * Retrieves a list of available translations for the given locales from all the hosted apps available on the tenant.\n   */\n  async getAvailableTranslations(locales: string[]) {\n    const { data: hostedApps } = await this.appService.list({\n      tenant: this.appState.currentTenant.value.name,\n      type: 'HOSTED',\n      pageSize: 2000\n    });\n\n    const uniqueContextPaths = uniq(\n      hostedApps\n        .filter(app => app.contextPath && app.manifest?.webSdkVersion)\n        .map(app => app.contextPath)\n    );\n\n    const translations: { [key: string]: { [locale: string]: string } } = {};\n    for (const contextPath of uniqueContextPaths) {\n      for (const locale of locales) {\n        try {\n          const translationsForLanguageAndApp = await this.getFileFromPath(\n            `/apps/${contextPath}/${locale}.json`\n          );\n          const translationsForLang = translationsForLanguageAndApp[locale];\n          for (const key of Object.keys(translationsForLang)) {\n            if (!translations[key]) {\n              translations[key] = {};\n            }\n            translations[key][locale] = translationsForLang[key];\n          }\n        } catch (e) {\n          continue;\n        }\n      }\n    }\n\n    return translations;\n  }\n\n  /**\n   * Retrieves the translations for the given locale from the translation app.\n   */\n  async getTranslationsForLocale<T extends string>(locale: T): Promise<{ [key: string]: string }> {\n    try {\n      const translations = await this.getFileFromTranslationApp(`${locale}.json`);\n      if (translations[locale]) {\n        return translations[locale];\n      }\n    } catch (e) {\n      // do nothing.\n    }\n    return {};\n  }\n\n  /**\n   * Retrieves the translations for the given locales from the translation app.\n   */\n  async loadTranslationsForLocales(locales: string[]): Promise<{\n    [key: string]: {\n      [key: string]: string;\n    };\n  }> {\n    const translations: {\n      [key: string]: { [key: string]: string };\n    } = {};\n\n    const loadAndAddLocale = async (locale: string) => {\n      translations[locale] = await this.getTranslationsForLocale(locale);\n    };\n\n    await Promise.all(locales.map(loadAndAddLocale));\n\n    return translations;\n  }\n\n  /**\n   * Retrieves a combined list of translations for all the provided locales.\n   * The locales are combined into a single object per key and an array of these objects is returned.\n   */\n  async getCombinedListOfTranslationsForPerKey(\n    locales: string[]\n  ): Promise<{ key: string; [locale: string]: string }[]> {\n    const translations = await this.loadTranslationsForLocales(locales);\n    const translationMap: { [key: string]: { [locale: string]: string } } = {};\n\n    for (const locale of Object.keys(translations)) {\n      for (const key of Object.keys(translations[locale])) {\n        let translationsForKey = translationMap[key];\n        if (!translationsForKey) {\n          translationsForKey = {};\n          translationMap[key] = translationsForKey;\n        }\n\n        translationsForKey[locale] = translations[locale][key];\n      }\n    }\n\n    const keys = Object.keys(translationMap).sort((a, b) => a.localeCompare(b));\n\n    return keys.map(key => Object.assign({ key }, translationMap[key]));\n  }\n\n  /**\n   * Updates the files of the translation application with the provided translations.\n   */\n  async updateTranslations(\n    translations: { key: string; [locale: string]: string }[]\n  ): Promise<void> {\n    const filesToUpload = new Array<{ path: string; contents: File }>();\n    const translationsPerLocale: { [locale: string]: { [key: string]: string } } = {};\n    for (const entry of translations) {\n      const key = entry.key;\n      for (const locale of Object.keys(entry)) {\n        if (locale === 'key') {\n          continue;\n        }\n        if (!translationsPerLocale[locale]) {\n          translationsPerLocale[locale] = {};\n        }\n\n        if (entry[locale]) {\n          translationsPerLocale[locale][key] = entry[locale];\n        }\n      }\n    }\n\n    const langs = this.appState.state.langs as string[];\n\n    for (const locale of langs) {\n      const fileName = `${locale}.json`;\n      filesToUpload.push({\n        path: fileName,\n        contents: new File(\n          [JSON.stringify({ [locale]: translationsPerLocale[locale] || {} })],\n          fileName\n        )\n      });\n    }\n    const app = await this.getOrCreateTranslationApp();\n    await this.appService.binary(app).updateFiles(filesToUpload);\n  }\n\n  /**\n   * @returns The translation app for the current tenant. If it does not exist, it will be created.\n   */\n  async getOrCreateTranslationApp(): Promise<IApplication> {\n    const { data: apps } = await this.appService.listByName(this.translationAppName);\n    const ownApp = apps.find(\n      app =>\n        app.contextPath === this.translationAppContextPath &&\n        app.owner.tenant.id === this.appState.currentTenant.value.name\n    );\n    if (ownApp) {\n      return ownApp;\n    }\n\n    const { data: app } = await this.appService.create({\n      name: this.translationAppName,\n      contextPath: this.translationAppContextPath,\n      key: `${this.translationAppContextPath}-app-key`,\n      type: ApplicationType.HOSTED,\n      availability: ApplicationAvailability.MARKET,\n      config: {\n        icon: {\n          class: 'language1'\n        }\n      },\n      noAppSwitcher: true,\n      description: 'Providing user defined translations'\n    });\n    const zip = await this.zip.createZip([]);\n\n    const { data: binary } = await this.appService.binary(app).upload(zip, 'translations.zip');\n    const { data: updatedApp } = await this.appService.update({\n      id: app.id,\n      activeVersionId: binary.id as string\n    });\n    return updatedApp;\n  }\n\n  private async getFileFromTranslationApp(file: string) {\n    return this.getFileFromPath(`/apps/public/${this.translationAppContextPath}/${file}`);\n  }\n\n  private async getFileFromPath(path: string) {\n    const finalPath = `${path}?nocache=${Date.now()}`;\n\n    // using fetch client instead of fetch directly here to ensure loading indicator is shown during these requests\n    const response = await this.fetchClient.fetch(finalPath);\n\n    if (response.status !== 200) {\n      throw new Error(`Failed to fetch file from ${path}`);\n    }\n\n    return response.json();\n  }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}