diff --git a/.storybook/manager.js b/.storybook/manager.js index 8d8ed89b5..a4d8ffdfe 100644 --- a/.storybook/manager.js +++ b/.storybook/manager.js @@ -2,7 +2,7 @@ import { addons } from 'storybook/manager-api'; // eslint-disable-next-line import-x/extensions import { create } from 'storybook/theming'; -import { generateDocsHref } from '../src/lib/utils.js'; +import { getDocUrl } from '../src/lib/dev-hub-url.js'; import { enhanceStoryName } from '../src/stories/lib/story-names.js'; // We could create an addon to provide a control that would switch between dark / light @@ -12,7 +12,7 @@ const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches; const cleverTheme = create({ base: isDarkMode ? 'dark' : 'light', brandTitle: 'Clever Cloud components', - brandUrl: generateDocsHref(), + brandUrl: getDocUrl(), brandImage: isDarkMode ? 'imgs/logo-clever-dark.svg' : 'imgs/logo-clever-light.svg', }); diff --git a/docs/contributing/urls.md b/docs/contributing/urls.md new file mode 100644 index 000000000..5ab6a3cc7 --- /dev/null +++ b/docs/contributing/urls.md @@ -0,0 +1,130 @@ +--- +kind: '👋 Contributing' +title: 'Documentation and asset URLs' +--- + +# Documentation and asset URLs + +When working on components, you'll often need to link to documentation, developer hub pages, or static assets. This guide explains how to handle these URLs correctly. + +## Documentation URLs + +Use `getDocUrl()` to generate URLs for documentation pages on the Clever Cloud developer hub. + +### Import the helper + +```js +import { getDocUrl } from '../../lib/dev-hub-url.js'; +``` + + + +### Use the helper + +```js +const url = getDocUrl('/billing/unified-invoices'); +// => 'https://www.clever.cloud/developers/doc/billing/unified-invoices' + +// Empty argument defaults to doc root +const url = getDocUrl(); +// => 'https://www.clever.cloud/developers/doc' +``` + +**_🧐 OBSERVATIONS:_** + +* Always use a leading slash: `getDocUrl('/path/to/doc')`. +* You can use the helper directly in templates, as a constant, or in translation files. +* The helper preserves query parameters and URL fragments. + +### Usage in translation files + +You can use `getDocUrl()` in translation files to generate documentation links: + +```js +import { getDocUrl } from '../lib/dev-hub-url.js'; + +export const translations = { + 'my-component.doc-link': () => sanitize` + Read more in the documentation. + `, +}; +``` + +## Developer hub URLs + +Use `getDevHubUrl()` to generate URLs for general developer hub pages (not under `/doc/`). + +### Import the helper + +```js +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; +``` + +### Use the helper + +```js +const url = getDevHubUrl('/api/v4'); +// => 'https://www.clever.cloud/developers/api/v4' + +// Supports fragments and query params +const url = getDevHubUrl('/api/howto/#oauth1'); +// => 'https://www.clever.cloud/developers/api/howto/#oauth1' +``` + +## Asset URLs + +Use `getAssetUrl()` to generate URLs for static assets that are not part of the components project. + +### Import the helper + +```js +import { getAssetUrl } from '../../lib/assets-url.js'; +``` + +### Use the helper + +```js +const url = getAssetUrl('/logos/java-jar.svg'); +// => 'https://assets.clever-cloud.com/logos/java-jar.svg' + +// Preserves query parameters and fragments +const url = getAssetUrl('/images/logo.png?v=2'); +// => 'https://assets.clever-cloud.com/images/logo.png?v=2' +``` + +### Helper functions for common assets + +The `remote-assets.js` file provides convenient wrapper functions for frequently used assets: + +```js +import { getFlagUrl, getInfraProviderLogoUrl } from '../../lib/remote-assets.js'; + +// Country flags +const flag = getFlagUrl('fr'); +// => 'https://assets.clever-cloud.com/flags/fr.svg' + +// Infrastructure provider logos +const logo = getInfraProviderLogoUrl('ovh'); +// => 'https://assets.clever-cloud.com/infra/ovh.svg' +``` + +## Best practices + +### Always use the helpers + +**DON'T DO THIS:** + +```js +// ❌ Hardcoded URLs +const url = 'https://www.clever.cloud/developers/doc/addons/postgresql'; +const asset = 'https://assets.clever-cloud.com/logos/java-jar.svg'; +``` + +**DO THIS:** + +```js +// ✅ Use the helpers +const url = getDocUrl('/addons/postgresql'); +const asset = getAssetUrl('/logos/java-jar.svg'); +``` + diff --git a/docs/getting-started/custom-base-urls.md b/docs/getting-started/custom-base-urls.md new file mode 100644 index 000000000..22b82d027 --- /dev/null +++ b/docs/getting-started/custom-base-urls.md @@ -0,0 +1,68 @@ +--- +kind: '🚀 Getting started' +title: 'Customizing base URLs' +--- + +# Customizing base URLs + +By default, Clever Cloud components generate URLs that point to: +* `https://www.clever.cloud/developers` for documentation and developer hub links +* `https://assets.clever-cloud.com` for static assets + +You can override these base URLs. + +## Customizing the developer hub base URL + +Use `setDevHubBaseUrl()` to change the base URL for documentation and developer hub links. + +```js +import { setDevHubBaseUrl } from '@clevercloud/components/dist/dev-hub-url.js'; + +// Set a custom base URL +setDevHubBaseUrl('https://staging.clever-cloud.com/developers'); + +// Now import components +import '@clevercloud/components/dist/cc-addon-info.js'; +``` + +After this configuration, all documentation links generated by components will use your custom base URL: + +* `getDocUrl('/addons/postgresql')` → `https://staging.clever-cloud.com/developers/doc/addons/postgresql` +* `getDevHubUrl('/api/v4')` → `https://staging.clever-cloud.com/developers/api/v4` + +## Customizing the assets base URL + +Use `setAssetsBaseUrl()` to change the base URL for static assets like logos, flags, and icons. + +```js +import { setAssetsBaseUrl } from '@clevercloud/components/dist/assets-url.js'; + +// Set a custom assets URL +setAssetsBaseUrl('https://cdn.example.com'); + +// Now import components +import '@clevercloud/components/dist/cc-addon-info.js'; +``` + +After this configuration, all asset URLs generated by components will use your custom base URL: + +* `getAssetUrl('/logos/java-jar.svg')` → `https://cdn.example.com/logos/java-jar.svg` +* `getFlagUrl('fr')` → `https://cdn.example.com/flags/fr.svg` + +## Important: call before importing components + +You **must** call `setDevHubBaseUrl()` and `setAssetsBaseUrl()` **before** importing any components. Otherwise, some URLs may still use the default base URLs. + +```js +import { setDevHubBaseUrl } from '@clevercloud/components/dist/dev-hub-url.js'; +import { setAssetsBaseUrl } from '@clevercloud/components/dist/assets-url.js'; + +// Configure base URLs first +setDevHubBaseUrl('https://staging.clever-cloud.com/developers'); +setAssetsBaseUrl('https://cdn.example.com'); + +// Then import components +import '@clevercloud/components/dist/cc-addon-info.js'; +import '@clevercloud/components/dist/cc-invoice-list.js'; +``` + diff --git a/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-keycloak.js b/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-keycloak.js index e40211152..8ed195679 100644 --- a/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-keycloak.js +++ b/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-keycloak.js @@ -1,6 +1,6 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { notifyError, notifySuccess } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonCredentialsBetaClient } from './cc-addon-credentials-beta.client.js'; @@ -30,7 +30,7 @@ const LOADING_STATE = { ], docLink: { text: i18n('cc-addon-credentials-beta.doc-link.keycloak'), - href: generateDocsHref('/addons/keycloak/#secured-multi-instances'), + href: getDocUrl('/addons/keycloak/#secured-multi-instances'), }, }, }, diff --git a/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-otoroshi.js b/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-otoroshi.js index d425ce0e2..7db62ee63 100644 --- a/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-otoroshi.js +++ b/src/components/cc-addon-credentials-beta/cc-addon-credentials-beta.smart-otoroshi.js @@ -1,7 +1,7 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { notifyError, notifySuccess } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonCredentialsBetaClient } from './cc-addon-credentials-beta.client.js'; @@ -29,7 +29,7 @@ const LOADING_STATE = { ], docLink: { text: i18n('cc-addon-credentials-beta.doc-link.otoroshi-ng'), - href: generateDocsHref('/addons/otoroshi/#use-otoroshi-in-a-network-group'), + href: getDocUrl('/addons/otoroshi/#use-otoroshi-in-a-network-group'), }, }, api: { @@ -58,7 +58,7 @@ const LOADING_STATE = { ], docLink: { text: i18n('cc-addon-credentials-beta.doc-link.otoroshi-api'), - href: generateDocsHref('/addons/otoroshi/#manage-otoroshi-from-its-api'), + href: getDocUrl('/addons/otoroshi/#manage-otoroshi-from-its-api'), }, }, }, diff --git a/src/components/cc-addon-header/cc-addon-header.smart-keycloak.js b/src/components/cc-addon-header/cc-addon-header.smart-keycloak.js index 5842c4352..0689bcba8 100644 --- a/src/components/cc-addon-header/cc-addon-header.smart-keycloak.js +++ b/src/components/cc-addon-header/cc-addon-header.smart-keycloak.js @@ -1,13 +1,13 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { notify, notifyError } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonHeaderClient } from './cc-addon-header.client.js'; import './cc-addon-header.js'; -const DOCS_URL = generateDocsHref(`/addons/keycloak`); +const DOCS_URL = getDocUrl(`/addons/keycloak`); const PROVIDER_ID = 'keycloak'; /** diff --git a/src/components/cc-addon-header/cc-addon-header.smart-matomo.js b/src/components/cc-addon-header/cc-addon-header.smart-matomo.js index ef57a2142..b8b1a9fbc 100644 --- a/src/components/cc-addon-header/cc-addon-header.smart-matomo.js +++ b/src/components/cc-addon-header/cc-addon-header.smart-matomo.js @@ -1,13 +1,13 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { notify, notifyError } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonHeaderClient } from './cc-addon-header.client.js'; import './cc-addon-header.js'; -const DOCS_URL = generateDocsHref(`/addons/matomo`); +const DOCS_URL = getDocUrl(`/addons/matomo`); const PROVIDER_ID = 'matomo'; /** diff --git a/src/components/cc-addon-header/cc-addon-header.smart-metabase.js b/src/components/cc-addon-header/cc-addon-header.smart-metabase.js index b3930c8d3..9cf301f7a 100644 --- a/src/components/cc-addon-header/cc-addon-header.smart-metabase.js +++ b/src/components/cc-addon-header/cc-addon-header.smart-metabase.js @@ -1,13 +1,13 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { notify, notifyError } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonHeaderClient } from './cc-addon-header.client.js'; import './cc-addon-header.js'; -const DOCS_URL = generateDocsHref(`/addons/metabase`); +const DOCS_URL = getDocUrl(`/addons/metabase`); const PROVIDER_ID = 'metabase'; /** diff --git a/src/components/cc-addon-header/cc-addon-header.smart-otoroshi.js b/src/components/cc-addon-header/cc-addon-header.smart-otoroshi.js index 7ce0931f2..30bc78cac 100644 --- a/src/components/cc-addon-header/cc-addon-header.smart-otoroshi.js +++ b/src/components/cc-addon-header/cc-addon-header.smart-otoroshi.js @@ -1,13 +1,13 @@ +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { notify, notifyError } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonHeaderClient } from './cc-addon-header.client.js'; import './cc-addon-header.js'; -const DOCS_URL = generateDocsHref(`/addons/otoroshi`); +const DOCS_URL = getDocUrl(`/addons/otoroshi`); const PROVIDER_ID = 'otoroshi'; /** diff --git a/src/components/cc-addon-info/cc-addon-info.client.js b/src/components/cc-addon-info/cc-addon-info.client.js index 67b9596ab..09f7085ef 100644 --- a/src/components/cc-addon-info/cc-addon-info.client.js +++ b/src/components/cc-addon-info/cc-addon-info.client.js @@ -4,8 +4,8 @@ import { get as getAddon } from '@clevercloud/client/esm/api/v2/addon.js'; import { getGrafanaOrganisation } from '@clevercloud/client/esm/api/v4/saas.js'; // @ts-expect-error FIXME: remove when clever-client exports types import { ONE_SECOND } from '@clevercloud/client/esm/with-cache.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { sendToApi } from '../../lib/send-to-api.js'; -import { generateDevHubHref } from '../../lib/utils.js'; /** * @typedef {import('./cc-addon-info.types.js').AddonInfoStateLoaded} AddonInfoStateLoaded @@ -178,7 +178,7 @@ export function formatVersionState(operatorVersionInfo) { installed: operatorVersionInfo.installed, available: operatorVersionInfo.available.filter((version) => version !== operatorVersionInfo.installed), latest: operatorVersionInfo.latest, - changelogLink: `${generateDevHubHref('/changelog')}`, + changelogLink: `${getDevHubUrl('/changelog')}`, }; } diff --git a/src/components/cc-addon-info/cc-addon-info.smart-keycloak.js b/src/components/cc-addon-info/cc-addon-info.smart-keycloak.js index 07b63b9e2..0488401a3 100644 --- a/src/components/cc-addon-info/cc-addon-info.smart-keycloak.js +++ b/src/components/cc-addon-info/cc-addon-info.smart-keycloak.js @@ -1,7 +1,7 @@ import { getAssetUrl } from '../../lib/assets-url.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { notifyError, notifySuccess } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonInfoClient, formatVersionState } from './cc-addon-info.client.js'; @@ -72,7 +72,7 @@ defineSmartComponent({ updateComponent('state', LOADING_STATE); updateComponent('docLink', { text: i18n('cc-addon-info.doc-link.keycloak'), - href: generateDocsHref('/addons/keycloak'), + href: getDocUrl('/addons/keycloak'), }); api diff --git a/src/components/cc-addon-info/cc-addon-info.smart-matomo.js b/src/components/cc-addon-info/cc-addon-info.smart-matomo.js index 47d0395e4..c775d4896 100644 --- a/src/components/cc-addon-info/cc-addon-info.smart-matomo.js +++ b/src/components/cc-addon-info/cc-addon-info.smart-matomo.js @@ -1,7 +1,7 @@ import { getAssetUrl } from '../../lib/assets-url.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { sendToApi } from '../../lib/send-to-api.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonInfoClient } from './cc-addon-info.client.js'; @@ -87,7 +87,7 @@ defineSmartComponent({ updateComponent('state', LOADING_STATE); updateComponent('docLink', { text: i18n('cc-addon-info.doc-link.matomo'), - href: generateDocsHref('/addons/matomo'), + href: getDocUrl('/addons/matomo'), }); api diff --git a/src/components/cc-addon-info/cc-addon-info.smart-metabase.js b/src/components/cc-addon-info/cc-addon-info.smart-metabase.js index bcae440f8..796bcd210 100644 --- a/src/components/cc-addon-info/cc-addon-info.smart-metabase.js +++ b/src/components/cc-addon-info/cc-addon-info.smart-metabase.js @@ -1,7 +1,7 @@ import { getAssetUrl } from '../../lib/assets-url.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { notifyError, notifySuccess } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonInfoClient, formatVersionState } from './cc-addon-info.client.js'; @@ -82,7 +82,7 @@ defineSmartComponent({ updateComponent('state', LOADING_STATE); updateComponent('docLink', { text: i18n('cc-addon-info.doc-link.metabase'), - href: generateDocsHref('/addons/metabase'), + href: getDocUrl('/addons/metabase'), }); api diff --git a/src/components/cc-addon-info/cc-addon-info.smart-otoroshi.js b/src/components/cc-addon-info/cc-addon-info.smart-otoroshi.js index 14cbc97c8..0c6ee4d7c 100644 --- a/src/components/cc-addon-info/cc-addon-info.smart-otoroshi.js +++ b/src/components/cc-addon-info/cc-addon-info.smart-otoroshi.js @@ -1,7 +1,7 @@ import { getAssetUrl } from '../../lib/assets-url.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { notifyError, notifySuccess } from '../../lib/notifications.js'; import { defineSmartComponent } from '../../lib/smart/define-smart-component.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-smart-container/cc-smart-container.js'; import { CcAddonInfoClient, formatVersionState } from './cc-addon-info.client.js'; @@ -76,7 +76,7 @@ defineSmartComponent({ updateComponent('state', LOADING_STATE); updateComponent('docLink', { text: i18n('cc-addon-info.doc-link.otoroshi'), - href: generateDocsHref('/addons/otoroshi'), + href: getDocUrl('/addons/otoroshi'), }); api diff --git a/src/components/cc-addon-info/cc-addon-info.stories.js b/src/components/cc-addon-info/cc-addon-info.stories.js index bd6bc95c1..7ba384ebc 100644 --- a/src/components/cc-addon-info/cc-addon-info.stories.js +++ b/src/components/cc-addon-info/cc-addon-info.stories.js @@ -1,4 +1,4 @@ -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { azimuttInfo, configInfo, @@ -222,7 +222,7 @@ export const materia = makeStory(conf, { ...materiaInfo, }, innerHTML: ` -

Materia KV uses our next generation of serverless distributed database, synchronously-replicated. Free of charge during testing phases, it will be available on a pay-as-you-go flexible pricing. Develop with ease, it's compatible with third-party protocols, such as Redis: learn more.

+

Materia KV uses our next generation of serverless distributed database, synchronously-replicated. Free of charge during testing phases, it will be available on a pay-as-you-go flexible pricing. Develop with ease, it's compatible with third-party protocols, such as Redis: learn more.

`, }, { @@ -232,7 +232,7 @@ export const materia = makeStory(conf, { ...materiaInfo, }, innerHTML: ` -

Materia KV uses our next generation of serverless distributed database, synchronously-replicated. Free of charge during testing phases, it will be available on a pay-as-you-go flexible pricing. Develop with ease, it's compatible with third-party protocols, such as Redis: learn more.

+

Materia KV uses our next generation of serverless distributed database, synchronously-replicated. Free of charge during testing phases, it will be available on a pay-as-you-go flexible pricing. Develop with ease, it's compatible with third-party protocols, such as Redis: learn more.

`, }, ], diff --git a/src/components/cc-domain-management/cc-domain-management.js b/src/components/cc-domain-management/cc-domain-management.js index 15c2e858e..bb6347b69 100644 --- a/src/components/cc-domain-management/cc-domain-management.js +++ b/src/components/cc-domain-management/cc-domain-management.js @@ -11,6 +11,7 @@ import { iconRemixFlaskLine as iconTest, } from '../../assets/cc-remix.icons.js'; import { LostFocusController } from '../../controllers/lost-focus-controller.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { DomainParseError, getDomainUrl, @@ -21,7 +22,6 @@ import { sortDomains, } from '../../lib/domain.js'; import { focusBySelector } from '../../lib/focus-helper.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { accessibilityStyles } from '../../styles/accessibility.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; @@ -37,11 +37,11 @@ import '../cc-loader/cc-loader.js'; import '../cc-notice/cc-notice.js'; import { CcDomainAddEvent, CcDomainDeleteEvent, CcDomainMarkAsPrimaryEvent } from './cc-domain-management.events.js'; -const DOMAIN_NAMES_DOCUMENTATION = generateDocsHref( +const DOMAIN_NAMES_DOCUMENTATION = getDocUrl( '/administrate/domain-names/#using-a-cleverappsio-free-domain-with-built-in-ssl', ); -const TLS_CERTIFICATES_DOCUMENTATION = generateDocsHref('/administrate/ssl/'); -const DNS_DOCUMENTATION = generateDocsHref('/administrate/domain-names/'); +const TLS_CERTIFICATES_DOCUMENTATION = getDocUrl('/administrate/ssl'); +const DNS_DOCUMENTATION = getDocUrl('/administrate/domain-names'); /** * @typedef {import('./cc-domain-management.types.js').DomainManagementDnsInfoState} DomainManagementDnsInfoState diff --git a/src/components/cc-elasticsearch-info/cc-elasticsearch-info.js b/src/components/cc-elasticsearch-info/cc-elasticsearch-info.js index 30c42c2e1..e63dfed3c 100644 --- a/src/components/cc-elasticsearch-info/cc-elasticsearch-info.js +++ b/src/components/cc-elasticsearch-info/cc-elasticsearch-info.js @@ -2,7 +2,7 @@ import { css, html, LitElement } from 'lit'; import { classMap } from 'lit/directives/class-map.js'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { skeletonStyles } from '../../styles/skeleton.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block/cc-block.js'; @@ -13,7 +13,7 @@ import '../cc-notice/cc-notice.js'; const ELASTICSEARCH_LOGO_URL = getAssetUrl('/logos/elastic.svg'); const KIBANA_LOGO_URL = getAssetUrl('/logos/elasticsearch-kibana.svg'); const APM_LOGO_URL = getAssetUrl('/logos/elasticsearch-apm.svg'); -const ELASTICSEARCH_DOCUMENTATION = generateDocsHref('/addons/elastic/'); +const ELASTICSEARCH_DOCUMENTATION = getDocUrl('/addons/elastic'); const linksSortOrder = ['elasticsearch', 'kibana', 'apm']; /** diff --git a/src/components/cc-env-var-form/cc-env-var-form.js b/src/components/cc-env-var-form/cc-env-var-form.js index 8da70d807..418c09788 100644 --- a/src/components/cc-env-var-form/cc-env-var-form.js +++ b/src/components/cc-env-var-form/cc-env-var-form.js @@ -1,6 +1,6 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-details/cc-block-details.js'; @@ -17,7 +17,7 @@ import '../cc-notice/cc-notice.js'; import '../cc-toggle/cc-toggle.js'; import { CcEnvVarFormSubmitEvent } from './cc-env-var-form.events.js'; -const ENV_VAR_DOCUMENTATION = generateDocsHref('/reference/reference-environment-variables/'); +const ENV_VAR_DOCUMENTATION = getDocUrl('/reference/reference-environment-variables'); /** * @typedef {import('./cc-env-var-form.types.js').EnvVarFormContextType} EnvVarFormContextType diff --git a/src/components/cc-grafana-info/cc-grafana-info.js b/src/components/cc-grafana-info/cc-grafana-info.js index 242f77ef7..81b28b299 100644 --- a/src/components/cc-grafana-info/cc-grafana-info.js +++ b/src/components/cc-grafana-info/cc-grafana-info.js @@ -1,7 +1,7 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-section/cc-block-section.js'; import '../cc-block/cc-block.js'; @@ -16,7 +16,7 @@ const GRAFANA_LOGO_URL = getAssetUrl('/logos/grafana.svg'); const GRAFANA_HOME_SCREEN = getAssetUrl('/grafana/screens/home.png'); const GRAFANA_RUNTIME_SCREEN = getAssetUrl('/grafana/screens/runtime.png'); const GRAFANA_ADDON_SCREEN = getAssetUrl('/grafana/screens/addon.png'); -const GRAFANA_DOCUMENTATION = generateDocsHref('/metrics'); +const GRAFANA_DOCUMENTATION = getDocUrl('/metrics'); /** * @typedef {import('./cc-grafana-info.types.js').GrafanaInfoState} GrafanaInfoState diff --git a/src/components/cc-heptapod-info/cc-heptapod-info.js b/src/components/cc-heptapod-info/cc-heptapod-info.js index 0986cf428..102bff51f 100644 --- a/src/components/cc-heptapod-info/cc-heptapod-info.js +++ b/src/components/cc-heptapod-info/cc-heptapod-info.js @@ -2,7 +2,7 @@ import { css, html, LitElement } from 'lit'; import { classMap } from 'lit/directives/class-map.js'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { skeletonStyles } from '../../styles/skeleton.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block/cc-block.js'; @@ -17,7 +17,7 @@ const SKELETON_STATISTICS = { price: 17.5, }; -const HEPTAPOD_DOCUMENTATION = generateDocsHref('/addons/heptapod/'); +const HEPTAPOD_DOCUMENTATION = getDocUrl('/addons/heptapod'); const HEPTAPOD_LOGO_URL = getAssetUrl('/logos/heptapod.svg'); /** diff --git a/src/components/cc-invoice-list/cc-invoice-list.js b/src/components/cc-invoice-list/cc-invoice-list.js index bc8b00c73..48875af9b 100644 --- a/src/components/cc-invoice-list/cc-invoice-list.js +++ b/src/components/cc-invoice-list/cc-invoice-list.js @@ -1,7 +1,8 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { ResizeController } from '../../controllers/resize-controller.js'; -import { generateDocsHref, sortBy, unique } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; +import { sortBy, unique } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-section/cc-block-section.js'; import '../cc-block/cc-block.js'; @@ -13,7 +14,7 @@ import '../cc-select/cc-select.js'; import '../cc-toggle/cc-toggle.js'; const BREAKPOINTS = [520]; -const INVOICE_DOCUMENTATION = generateDocsHref('/billing/unified-invoices/'); +const INVOICE_DOCUMENTATION = getDocUrl('/billing/unified-invoices'); /** * @param {string} dateString diff --git a/src/components/cc-jenkins-info/cc-jenkins-info.js b/src/components/cc-jenkins-info/cc-jenkins-info.js index 449c8bdf1..4415e0414 100644 --- a/src/components/cc-jenkins-info/cc-jenkins-info.js +++ b/src/components/cc-jenkins-info/cc-jenkins-info.js @@ -1,7 +1,7 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { skeletonStyles } from '../../styles/skeleton.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-section/cc-block-section.js'; @@ -12,7 +12,7 @@ import '../cc-link/cc-link.js'; import '../cc-notice/cc-notice.js'; const JENKINS_LOGO_URL = getAssetUrl('/logos/jenkins.svg'); -const JENKINS_DOCUMENTATION = generateDocsHref('/deploy/addon/jenkins/'); +const JENKINS_DOCUMENTATION = getDocUrl('/deploy/addon/jenkins'); /** * @typedef {import('./cc-jenkins-info.types.js').JenkinsInfoState} JenkinsInfoState diff --git a/src/components/cc-matomo-info/cc-matomo-info.js b/src/components/cc-matomo-info/cc-matomo-info.js index d08766263..77a555fdc 100644 --- a/src/components/cc-matomo-info/cc-matomo-info.js +++ b/src/components/cc-matomo-info/cc-matomo-info.js @@ -1,7 +1,7 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { skeletonStyles } from '../../styles/skeleton.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-section/cc-block-section.js'; @@ -18,7 +18,7 @@ const MATOMO_LOGO_URL = getAssetUrl('/logos/matomo.svg'); const PHP_LOGO_URL = getAssetUrl('/logos/php.svg'); const MYSQL_LOGO_URL = getAssetUrl('/logos/mysql.svg'); const REDIS_LOGO_URL = getAssetUrl('/logos/redis.svg'); -const MATOMO_DOCUMENTATION = generateDocsHref('/deploy/addon/matomo/'); +const MATOMO_DOCUMENTATION = getDocUrl('/deploy/addon/matomo'); /** * @typedef {import('./cc-matomo-info.types.js').MatomoInfoState} MatomoInfoState diff --git a/src/components/cc-oauth-consumer-form/cc-oauth-consumer-form.js b/src/components/cc-oauth-consumer-form/cc-oauth-consumer-form.js index e123b639c..1e726ef26 100644 --- a/src/components/cc-oauth-consumer-form/cc-oauth-consumer-form.js +++ b/src/components/cc-oauth-consumer-form/cc-oauth-consumer-form.js @@ -2,11 +2,11 @@ import { css, html, LitElement } from 'lit'; import { createRef, ref } from 'lit/directives/ref.js'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { ResizeController } from '../../controllers/resize-controller.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { formSubmit } from '../../lib/form/form-submit-directive.js'; import { getFormDataMap } from '../../lib/form/form-utils.js'; import { Validation } from '../../lib/form/validation.js'; -import { generateDevHubHref } from '../../lib/utils.js'; import { accessibilityStyles } from '../../styles/accessibility.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-section/cc-block-section.js'; @@ -22,7 +22,7 @@ import { const BREAKPOINTS = [450, 550, 750]; -const OAUTH_CONSUMER_DOCUMENTATION = generateDevHubHref('/api/howto/#oauth1'); +const OAUTH_CONSUMER_DOCUMENTATION = getDevHubUrl('/api/howto/#oauth1'); const URL_VALIDATOR = { /** diff --git a/src/components/cc-orga-member-list/cc-orga-member-list.js b/src/components/cc-orga-member-list/cc-orga-member-list.js index e47e8693a..711c4e566 100644 --- a/src/components/cc-orga-member-list/cc-orga-member-list.js +++ b/src/components/cc-orga-member-list/cc-orga-member-list.js @@ -4,9 +4,9 @@ import { createRef, ref } from 'lit/directives/ref.js'; import { repeat } from 'lit/directives/repeat.js'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; import { LostFocusController } from '../../controllers/lost-focus-controller.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { formSubmit } from '../../lib/form/form-submit-directive.js'; import { Validation } from '../../lib/form/validation.js'; -import { generateDocsHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-badge/cc-badge.js'; import '../cc-block-section/cc-block-section.js'; @@ -21,7 +21,7 @@ import { CcOrgaMemberCard } from '../cc-orga-member-card/cc-orga-member-card.js' import '../cc-select/cc-select.js'; import { CcOrgaMemberInviteEvent } from './cc-orga-member-list.events.js'; -const ORGA_MEMBER_DOCUMENTATION = generateDocsHref('/account/administrate-organization/'); +const ORGA_MEMBER_DOCUMENTATION = getDocUrl('/account/administrate-organization'); /** * @typedef {import('./cc-orga-member-list.types.js').OrgaMemberListState} OrgaMemberListState diff --git a/src/components/cc-ssh-key-list/cc-ssh-key-list.js b/src/components/cc-ssh-key-list/cc-ssh-key-list.js index 3c8388def..577334c5b 100644 --- a/src/components/cc-ssh-key-list/cc-ssh-key-list.js +++ b/src/components/cc-ssh-key-list/cc-ssh-key-list.js @@ -9,11 +9,12 @@ import { iconRemixKey_2Fill as iconKey, } from '../../assets/cc-remix.icons.js'; import { LostFocusController } from '../../controllers/lost-focus-controller.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { fakeString } from '../../lib/fake-strings.js'; import { focusBySelector } from '../../lib/focus-helper.js'; import { formSubmit } from '../../lib/form/form-submit-directive.js'; import { Validation } from '../../lib/form/validation.js'; -import { generateDocsHref, sortBy } from '../../lib/utils.js'; +import { sortBy } from '../../lib/utils.js'; import { skeletonStyles } from '../../styles/skeleton.js'; import { i18n } from '../../translations/translation.js'; import '../cc-badge/cc-badge.js'; @@ -27,7 +28,7 @@ import '../cc-link/cc-link.js'; import '../cc-notice/cc-notice.js'; import { CcSshKeyCreateEvent, CcSshKeyDeleteEvent, CcSshKeyImportEvent } from './cc-ssh-key-list.events.js'; -const SSH_KEY_DOCUMENTATION = generateDocsHref('/account/ssh-keys-management/'); +const SSH_KEY_DOCUMENTATION = getDocUrl('/account/ssh-keys-management'); /** * @type {SshKeyState[]} diff --git a/src/components/cc-tcp-redirection-form/cc-tcp-redirection-form.js b/src/components/cc-tcp-redirection-form/cc-tcp-redirection-form.js index 5fb7cb194..517a983ed 100644 --- a/src/components/cc-tcp-redirection-form/cc-tcp-redirection-form.js +++ b/src/components/cc-tcp-redirection-form/cc-tcp-redirection-form.js @@ -1,6 +1,6 @@ import { css, html, LitElement } from 'lit'; import { iconRemixInformationFill as iconInfo } from '../../assets/cc-remix.icons.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; import '../cc-badge/cc-badge.js'; @@ -11,7 +11,7 @@ import '../cc-link/cc-link.js'; import '../cc-notice/cc-notice.js'; import '../cc-tcp-redirection/cc-tcp-redirection.js'; -const TCP_REDIRECTION_DOCUMENTATION = generateDocsHref('/administrate/tcp-redirections/'); +const TCP_REDIRECTION_DOCUMENTATION = getDocUrl('/administrate/tcp-redirections'); /** @type {TcpRedirectionStateLoading[]} */ const SKELETON_REDIRECTIONS = [{ type: 'loading' }, { type: 'loading' }]; diff --git a/src/components/cc-token-api-creation-form/cc-token-api-creation-form.js b/src/components/cc-token-api-creation-form/cc-token-api-creation-form.js index 6d618a786..66839b6d6 100644 --- a/src/components/cc-token-api-creation-form/cc-token-api-creation-form.js +++ b/src/components/cc-token-api-creation-form/cc-token-api-creation-form.js @@ -10,9 +10,9 @@ import { } from '../../assets/cc-remix.icons.js'; import { DateFormatter } from '../../lib/date/date-formatter.js'; import { getRelativeDateFromNow, shiftDateField } from '../../lib/date/date-utils.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { FormErrorFocusController } from '../../lib/form/form-error-focus-controller.js'; import { formSubmit } from '../../lib/form/form-submit-directive.js'; -import { generateDevHubHref } from '../../lib/utils.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-details/cc-block-details.js'; @@ -377,7 +377,7 @@ export class CcTokenApiCreationForm extends LitElement {
${i18n('cc-block-details.cli.text')}
- + ${i18n('cc-token-api-creation-form.link.doc')}
diff --git a/src/components/cc-token-api-list/cc-token-api-list.js b/src/components/cc-token-api-list/cc-token-api-list.js index f16211834..d1ecafc81 100644 --- a/src/components/cc-token-api-list/cc-token-api-list.js +++ b/src/components/cc-token-api-list/cc-token-api-list.js @@ -12,8 +12,9 @@ import { } from '../../assets/cc-remix.icons.js'; import { LostFocusController } from '../../controllers/lost-focus-controller.js'; import { ResizeController } from '../../controllers/resize-controller.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { isExpirationClose } from '../../lib/tokens.js'; -import { generateDevHubHref, isStringEmpty } from '../../lib/utils.js'; +import { isStringEmpty } from '../../lib/utils.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; import '../cc-badge/cc-badge.js'; @@ -186,7 +187,7 @@ export class CcTokenApiList extends LitElement {
${i18n('cc-block-details.cli.text')}
- + ${i18n('cc-token-api-list.link.doc')}
diff --git a/src/components/cc-token-api-list/cc-token-api-list.stories.js b/src/components/cc-token-api-list/cc-token-api-list.stories.js index 158b5cd51..f297746a8 100644 --- a/src/components/cc-token-api-list/cc-token-api-list.stories.js +++ b/src/components/cc-token-api-list/cc-token-api-list.stories.js @@ -1,5 +1,5 @@ import { shiftDateField } from '../../lib/date/date-utils.js'; -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { makeStory, storyWait } from '../../stories/lib/make-story.js'; import './cc-token-api-list.js'; @@ -20,7 +20,7 @@ const conf = { const now = new Date(); -const apiTokenUpdateHref = generateDocsHref( +const apiTokenUpdateHref = getDocUrl( '/clever-components/?path=/story/🛠-profile-cc-token-api-update-form--default-story', ); diff --git a/src/components/cc-token-api-update-form/cc-token-api-update-form.js b/src/components/cc-token-api-update-form/cc-token-api-update-form.js index 24896b30c..4a302ada0 100644 --- a/src/components/cc-token-api-update-form/cc-token-api-update-form.js +++ b/src/components/cc-token-api-update-form/cc-token-api-update-form.js @@ -3,8 +3,8 @@ import { iconRemixArrowLeftLine as iconGoBack, iconRemixInformationFill as iconInfo, } from '../../assets/cc-remix.icons.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { formSubmit } from '../../lib/form/form-submit-directive.js'; -import { generateDevHubHref } from '../../lib/utils.js'; import { cliCommandsStyles } from '../../styles/cli-commands.js'; import { i18n } from '../../translations/translation.js'; import '../cc-block-details/cc-block-details.js'; @@ -79,7 +79,7 @@ export class CcTokenApiUpdateForm extends LitElement {
${i18n('cc-block-details.cli.text')}
- + ${i18n('cc-token-api-update-form.link.doc')}
diff --git a/src/components/cc-token-api-update-form/cc-token-api-update-form.stories.js b/src/components/cc-token-api-update-form/cc-token-api-update-form.stories.js index e7cb1d8f5..b70c3011a 100644 --- a/src/components/cc-token-api-update-form/cc-token-api-update-form.stories.js +++ b/src/components/cc-token-api-update-form/cc-token-api-update-form.stories.js @@ -1,8 +1,8 @@ -import { generateDocsHref } from '../../lib/utils.js'; +import { getDocUrl } from '../../lib/dev-hub-url.js'; import { makeStory, storyWait } from '../../stories/lib/make-story.js'; import './cc-token-api-update-form.js'; -const CC_TOKEN_API_LIST_STORY_HREF = generateDocsHref( +const CC_TOKEN_API_LIST_STORY_HREF = getDocUrl( '/clever-components/?path=/story/🛠-profile-cc-token-api-list--default-story', ); diff --git a/src/components/cc-token-oauth-list/cc-token-oauth-list.js b/src/components/cc-token-oauth-list/cc-token-oauth-list.js index 0a2608894..ecd082c00 100644 --- a/src/components/cc-token-oauth-list/cc-token-oauth-list.js +++ b/src/components/cc-token-oauth-list/cc-token-oauth-list.js @@ -10,8 +10,8 @@ import { } from '../../assets/cc-remix.icons.js'; import { LostFocusController } from '../../controllers/lost-focus-controller.js'; import { ResizeController } from '../../controllers/resize-controller.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { isExpirationClose } from '../../lib/tokens.js'; -import { generateDevHubHref } from '../../lib/utils.js'; import { i18n } from '../../translations/translation.js'; import '../cc-badge/cc-badge.js'; import '../cc-block/cc-block.js'; @@ -127,7 +127,7 @@ export class CcTokenOauthList extends LitElement {
- + ${i18n('cc-token-oauth-list.link.doc')}
diff --git a/src/components/cc-visual-tests-report/cc-visual-tests-report.js b/src/components/cc-visual-tests-report/cc-visual-tests-report.js index 0fb0e9b48..b8d5abbe3 100644 --- a/src/components/cc-visual-tests-report/cc-visual-tests-report.js +++ b/src/components/cc-visual-tests-report/cc-visual-tests-report.js @@ -8,7 +8,7 @@ import { iconRemixFlowChart as iconWorkflow, } from '../../assets/cc-remix.icons.js'; import { DateFormatter } from '../../lib/date/date-formatter.js'; -import { generateDevHubHref } from '../../lib/utils.js'; +import { getDevHubUrl } from '../../lib/dev-hub-url.js'; import { accessibilityStyles } from '../../styles/accessibility.js'; import '../cc-block-section/cc-block-section.js'; import '../cc-block/cc-block.js'; @@ -123,7 +123,7 @@ export class CcVisualTestsReport extends LitElement {
} a * @param {Record} b @@ -256,39 +247,6 @@ export function sleep(delay) { }); } -/** - * Rely on this helper for every reference to the Clever Cloud docs website - * - * @param {string} [path] - * @returns {string} href - */ -export function generateDocsHref(path = '') { - /** - * Ensure "/doc" is appended after the base URL, then append the provided path - * If you change the base URL here, you should probably also change it in places where it's still hard coded: - * - README.md, - * - CONTRIBUTING.md, - * - sandbox/index.html, - * - test/utils.test.js. - */ - const CC_DOCS_BASE_URL = CC_DEV_HUB_BASE_URL.replace(/\/$/, '') + '/doc/'; - // if a '/' is present at the beginning, the path is considered absolute and it is appended right after the origin - // we want the path to always be appended after the existing path of the base URL so we remove the first '/' so that it's considered relative - return new URL(path.replace(/^\//, ''), CC_DOCS_BASE_URL).href; -} - -/** - * Rely on this helper for every reference to the Clever Cloud developer hub website - * - * @param {string} [path] - * @returns {string} href - */ -export function generateDevHubHref(path = '') { - // if a '/' is present at the beginning, the path is considered absolute and it is appended right after the origin - // we want the path to always be appended after the existing path of the base URL so we remove the first '/' so that it's considered relative - return new URL(path.replace(/^\//, ''), CC_DEV_HUB_BASE_URL).href; -} - /** * Checks if a given DOM element is currently visible within a given container's bounds. * diff --git a/src/stories/fixtures/addon-info.js b/src/stories/fixtures/addon-info.js index ae473bbdd..5763a532e 100644 --- a/src/stories/fixtures/addon-info.js +++ b/src/stories/fixtures/addon-info.js @@ -1,5 +1,5 @@ import { getAssetUrl } from '../../lib/assets-url.js'; -import { generateDevHubHref, generateDocsHref } from '../../lib/utils.js'; +import { getDevHubUrl, getDocUrl } from '../../lib/dev-hub-url.js'; /** * @typedef {import('../../components/cc-addon-info/cc-addon-info.types.js').AddonInfoStateBaseProperties} AddonInfoStateBaseProperties @@ -35,7 +35,7 @@ export const matomoInfo = { link: 'https://example.com/addon', }, ], - docUrlLink: generateDocsHref('addons/matomo'), + docUrlLink: getDocUrl('addons/matomo'), } /** @type {AddonInfoStateBaseProperties} */ @@ -62,7 +62,7 @@ export const metabaseInfo = { link: 'https://example.com/addon', }, ], - docUrlLink: generateDocsHref('addons/metabase'), + docUrlLink: getDocUrl('addons/metabase'), } /** @type {AddonInfoStateBaseProperties} */ @@ -94,7 +94,7 @@ export const keycloakInfo = { link: 'https://example.com/addon', }, ], - docUrlLink: generateDocsHref('addons/keycloak'), + docUrlLink: getDocUrl('addons/keycloak'), } /** @type {AddonInfoStateBaseProperties} */ @@ -121,13 +121,13 @@ export const otoroshiInfo = { link: 'https://example.com/addon', }, ], - docUrlLink: generateDocsHref('addons/otoroshi'), + docUrlLink: getDocUrl('addons/otoroshi'), } /** @type {AddonInfoStateBaseProperties} */ export const materiaInfo = { creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/materia-kv'), + docUrlLink: getDocUrl('addons/materia-kv'), } /** @type {AddonInfoStateBaseProperties} */ @@ -161,7 +161,7 @@ export const jenkinsInfo = { }, ], creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/jenkins'), + docUrlLink: getDocUrl('addons/jenkins'), } /** @type {AddonInfoStateBaseProperties} */ @@ -211,7 +211,7 @@ export const elasticInfo = { link: 'https://example.com/addon', }, ], - docUrlLink: generateDocsHref('addons/elastic'), + docUrlLink: getDocUrl('addons/elastic'), } /** @type {AddonInfoStateBaseProperties} */ @@ -222,20 +222,20 @@ export const pulsarInfo = { latest: '4.0.6', }, creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/pulsar'), + docUrlLink: getDocUrl('addons/pulsar'), } /** @type {AddonInfoStateBaseProperties} */ export const configInfo = { creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/config-provider'), + docUrlLink: getDocUrl('addons/config-provider'), } /** @type {AddonInfoStateBaseProperties} */ export const mailpaceInfo = { plan: 'XS', creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/mailpace'), + docUrlLink: getDocUrl('addons/mailpace'), } /** @type {AddonInfoStateBaseProperties} */ @@ -269,7 +269,7 @@ export const mysqlInfo = { }, ], creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/mysql'), + docUrlLink: getDocUrl('addons/mysql'), } /** @type {AddonInfoStateBaseProperties} */ @@ -309,7 +309,7 @@ export const postgresqlInfo = { ], creationDate: '2025-06-15T10:30:00Z', role: 'Primary', - docUrlLink: generateDocsHref('addons/postgresql'), + docUrlLink: getDocUrl('addons/postgresql'), } /** @type {AddonInfoStateBaseProperties} */ @@ -348,7 +348,7 @@ export const redisInfo = { }, ], creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/redis'), + docUrlLink: getDocUrl('addons/redis'), } /** @type {AddonInfoStateBaseProperties} */ @@ -382,7 +382,7 @@ export const mongodbInfo = { }, ], creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDocsHref('addons/mongodb'), + docUrlLink: getDocUrl('addons/mongodb'), } /** @type {AddonInfoStateBaseProperties} */ @@ -416,5 +416,5 @@ export const kubernetesInfo = { latest: '1.33', }, creationDate: '2025-06-15T10:30:00Z', - docUrlLink: generateDevHubHref('guides/kubernetes-operator/'), + docUrlLink: getDevHubUrl('guides/kubernetes-operator'), } diff --git a/src/translations/translations.en.js b/src/translations/translations.en.js index c85f88235..950f41d16 100644 --- a/src/translations/translations.en.js +++ b/src/translations/translations.en.js @@ -1,3 +1,4 @@ +import { getDevHubUrl, getDocUrl } from '../lib/dev-hub-url.js'; import { prepareFormatDate, prepareFormatDateOnly, @@ -15,7 +16,6 @@ import { } from '../lib/i18n/i18n-number.js'; import { sanitize } from '../lib/i18n/i18n-sanitize.js'; import { preparePlural } from '../lib/i18n/i18n-string.js'; -import { generateDevHubHref, generateDocsHref } from '../lib/utils.js'; /** * @typedef {import('../components/common.types.js').Flavor} Flavor @@ -66,7 +66,7 @@ function formatFlavor(flavor) { } const getCliInstructions = () => - sanitize`To install Clever Tools CLI, follow the instructions from the documentation.`; + sanitize`To install Clever Tools CLI, follow the instructions from the documentation.`; export const translations = { //#region cc-addon-admin @@ -253,7 +253,7 @@ export const translations = { //#endregion //#region cc-addon-encryption-at-rest-option 'cc-addon-encryption-at-rest-option.description': () => - sanitize`Encryption at rest encrypts the entire data disk of your add-on. It prevents reading the stored data in case of a physical access to the hard drive. More information in our documentation.`, + sanitize`Encryption at rest encrypts the entire data disk of your add-on. It prevents reading the stored data in case of a physical access to the hard drive. More information in our documentation.`, 'cc-addon-encryption-at-rest-option.title': `Encryption at rest`, //#endregion //#region cc-addon-features @@ -435,12 +435,12 @@ export const translations = { //#endregion //#region cc-domain-management 'cc-domain-management.certif.automated': () => - sanitize`Whether you use cleverapps.io or your own domain names with applications hosted by Clever Cloud, a Let's Encrypt certificate is automatically issued and renewed for HTTPS/TLS access. No action is required from you, this is all automated. For specific cases, refer to Installing TLS Certificates.`, + sanitize`Whether you use cleverapps.io or your own domain names with applications hosted by Clever Cloud, a Let's Encrypt certificate is automatically issued and renewed for HTTPS/TLS access. No action is required from you, this is all automated. For specific cases, refer to Installing TLS Certificates.`, 'cc-domain-management.certif.custom': () => sanitize`You can provide your own certificate by using the Clever Cloud Certificate Manager.`, 'cc-domain-management.certif.heading': `Secure your application`, 'cc-domain-management.dns.a.desc': () => - sanitize`

If you choose to use A records, for instance with a root domain (APEX), you'll need to update them yourself. Follow our changelog or check our v4 API documentation for this.

`, + sanitize`

If you choose to use A records, for instance with a root domain (APEX), you'll need to update them yourself. Follow our changelog or check our v4 API documentation for this.

`, 'cc-domain-management.dns.a.heading': `A records`, 'cc-domain-management.dns.a.label': `A Record values`, 'cc-domain-management.dns.cli.content.diag-conf-command': `Diagnose the current configuration:`, @@ -455,7 +455,7 @@ export const translations = { 'cc-domain-management.dns.documentation.text': `DNS records - Documentation`, 'cc-domain-management.dns.heading': `Configure your DNS`, 'cc-domain-management.dns.info.desc': () => - sanitize`If you are using a dedicated load balancer, refer to its configuration or contact support. Our team can also help you to order such a service. For a domain with no subdomains (APEX) or a subdomain with its own DNS zone, refer to our DNS & Domains documentation.`, + sanitize`If you are using a dedicated load balancer, refer to its configuration or contact support. Our team can also help you to order such a service. For a domain with no subdomains (APEX) or a subdomain with its own DNS zone, refer to our DNS & Domains documentation.`, 'cc-domain-management.dns.info.heading': `Dedicated load balancers & specific cases`, 'cc-domain-management.dns.loading-error': `Something went wrong while loading DNS information`, 'cc-domain-management.form.domain.error.contains-path': /** @param {{path: string}} _ */ ({ path }) => @@ -468,7 +468,7 @@ export const translations = { sanitize`For instance: example.com, *.example.com or example.cleverapps.io`, 'cc-domain-management.form.domain.label': `Domain name`, 'cc-domain-management.form.info.cleverapps': () => - sanitize`By default, an application is automatically associated to app_id.cleverapps.io as primary domain. You can remove it or change the subdomain freely, but xxx.cleverapps.io should only be used for testing purposes (see our documentation).`, + sanitize`By default, an application is automatically associated to app_id.cleverapps.io as primary domain. You can remove it or change the subdomain freely, but xxx.cleverapps.io should only be used for testing purposes (see our documentation).`, 'cc-domain-management.form.info.docs': `You can associate one or more domain names with your application. The primary domain is the one that will be used in Console links and in e-mails sent to you. Several applications can share the same domain, each with a specific subdomain and/or route.`, 'cc-domain-management.form.path.help': () => sanitize`For example: /api or /blog`, 'cc-domain-management.form.path.label': `Route`, @@ -580,7 +580,7 @@ export const translations = { 'cc-env-var-create.errors.invalid-name': /** @param {{name: string}} _ */ ({ name }) => sanitize`Name ${name} is invalid`, 'cc-env-var-create.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, + sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, 'cc-env-var-create.name.label': `Variable name`, 'cc-env-var-create.value.label': `Variable value`, //#endregion @@ -598,9 +598,9 @@ export const translations = { 'cc-env-var-editor-expert.errors.line': `line`, 'cc-env-var-editor-expert.errors.unknown': `Unknown Error`, 'cc-env-var-editor-expert.example': () => - sanitize`Format: VARIABLE_NAME="variable value"
Every variable must be separated by a line break, learn more.`, + sanitize`Format: VARIABLE_NAME="variable value"
Every variable must be separated by a line break, learn more.`, 'cc-env-var-editor-expert.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, + sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, 'cc-env-var-editor-expert.label': `Variable editing. Format: VARIABLE_NAME="variable value". Every variable must be separated by a line break.`, //#endregion //#region cc-env-var-editor-json @@ -616,9 +616,9 @@ export const translations = { sanitize`${name} is not a valid variable name in strict mode`, 'cc-env-var-editor-json.errors.unknown': `Unknown Error`, 'cc-env-var-editor-json.example': () => - sanitize`Format: { "name": "VARIABLE_NAME", "value": "variable value" }
Array of objects following the above format, learn more.`, + sanitize`Format: { "name": "VARIABLE_NAME", "value": "variable value" }
Array of objects following the above format, learn more.`, 'cc-env-var-editor-json.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, + sanitize`Variable ${name} will only be injected as a Java property and won't be part of the environment, more details`, 'cc-env-var-editor-json.label': `Variable editing. Array of objects following the format: { "name": "VARIABLE_NAME", "value": "variable value" }.`, //#endregion //#region cc-env-var-editor-simple @@ -633,11 +633,11 @@ export const translations = { `, 'cc-env-var-form.cli.content.list-var-command': `List environment variables:`, 'cc-env-var-form.description.config-provider': /** @param {{addonName: string}} _ */ ({ addonName }) => - sanitize`Configuration exposed to dependent applications. Learn more
These variables will be injected as environment variables in applications that have the add-on ${addonName} in their service dependencies.
Every time you update your changes, all the dependent applications will be automatically restarted.`, + sanitize`Configuration exposed to dependent applications. Learn more
These variables will be injected as environment variables in applications that have the add-on ${addonName} in their service dependencies.
Every time you update your changes, all the dependent applications will be automatically restarted.`, 'cc-env-var-form.description.env-var': /** @param {{appName: string}} _ */ ({ appName }) => sanitize`These variables will be injected as environment variables in the application ${appName}.`, 'cc-env-var-form.description.exposed-config': /** @param {{appName: string}} _ */ ({ appName }) => - sanitize`Configuration exposed to dependent applications. Learn more
These variables won't be injected in the application ${appName}, they will be injected as environment variables in applications that have ${appName} in their service dependencies.`, + sanitize`Configuration exposed to dependent applications. Learn more
These variables won't be injected in the application ${appName}, they will be injected as environment variables in applications that have ${appName} in their service dependencies.`, 'cc-env-var-form.documentation.text': `Environment variables - Reference`, 'cc-env-var-form.error.loading': `Something went wrong while loading variables.`, 'cc-env-var-form.heading.config-provider': `Variables`, @@ -1319,7 +1319,7 @@ export const translations = { 'cc-orga-member-list.invite.email.label': `Email address`, 'cc-orga-member-list.invite.heading': `Invite a member`, 'cc-orga-member-list.invite.info': () => - sanitize`More information about roles in the Roles and Organisations page.`, + sanitize`More information about roles in the Roles and Organisations page.`, 'cc-orga-member-list.invite.role.accounting': `Accountant`, 'cc-orga-member-list.invite.role.admin': `Admin`, 'cc-orga-member-list.invite.role.developer': `Developer`, @@ -1831,7 +1831,7 @@ export const translations = { 'cc-token-api-list.empty': `You haven't created any API tokens yet, or none of them are active. Let's create a new one:`, 'cc-token-api-list.error': `Something went wrong while loading API tokens`, 'cc-token-api-list.intro': () => - sanitize`Below is the list of API tokens linked to your account and their associated information. You may revoke them as needed.`, + sanitize`Below is the list of API tokens linked to your account and their associated information. You may revoke them as needed.`, 'cc-token-api-list.link.doc': `API tokens - Documentation`, 'cc-token-api-list.main-heading': `API tokens`, 'cc-token-api-list.no-password.create-password-btn': `Add a password`, @@ -1875,7 +1875,7 @@ export const translations = { 'cc-token-oauth-list.empty': `You do not have any third-party applications linked to your account`, 'cc-token-oauth-list.error': `Something went wrong while loading OAuth tokens`, 'cc-token-oauth-list.intro': () => - sanitize`Below is the list of third-party applications linked to your account and their associated information. You may revoke these OAuth tokens as needed.`, + sanitize`Below is the list of third-party applications linked to your account and their associated information. You may revoke these OAuth tokens as needed.`, 'cc-token-oauth-list.link.doc': `OAuth tokens - Documentation`, 'cc-token-oauth-list.main-heading': `OAuth tokens`, 'cc-token-oauth-list.revoke-all-tokens': `Revoke all OAuth tokens`, diff --git a/src/translations/translations.fr.js b/src/translations/translations.fr.js index 8b4afaa39..5642e6fcb 100644 --- a/src/translations/translations.fr.js +++ b/src/translations/translations.fr.js @@ -1,3 +1,4 @@ +import { getDevHubUrl, getDocUrl } from '../lib/dev-hub-url.js'; import { prepareFormatDate, prepareFormatDateOnly, @@ -15,7 +16,6 @@ import { } from '../lib/i18n/i18n-number.js'; import { sanitize } from '../lib/i18n/i18n-sanitize.js'; import { preparePlural } from '../lib/i18n/i18n-string.js'; -import { generateDevHubHref, generateDocsHref } from '../lib/utils.js'; /** * @typedef {import('../components/common.types.js').Flavor} Flavor @@ -77,7 +77,7 @@ function formatFlavor(flavor) { } const getCliInstructions = () => - sanitize`Pour installer les Clever Tools (CLI), suivez les instructions de la documentation.`; + sanitize`Pour installer les Clever Tools (CLI), suivez les instructions de la documentation.`; export const translations = { //#region cc-addon-admin @@ -264,7 +264,7 @@ export const translations = { //#endregion //#region cc-addon-encryption-at-rest-option 'cc-addon-encryption-at-rest-option.description': () => - sanitize`Le chiffrement au repos chiffre l'intégralité du disque de données afin de ne pas y stocker d'informations en clair. Grâce à cette sécurité, l'accès physique au disque empêchera toute lecture des données stockées. Plus d'information dans notre documentation.`, + sanitize`Le chiffrement au repos chiffre l'intégralité du disque de données afin de ne pas y stocker d'informations en clair. Grâce à cette sécurité, l'accès physique au disque empêchera toute lecture des données stockées. Plus d'information dans notre documentation.`, 'cc-addon-encryption-at-rest-option.title': `Chiffrement au repos`, //#endregion //#region cc-addon-features @@ -446,12 +446,12 @@ export const translations = { //#endregion //#region cc-domain-management 'cc-domain-management.certif.automated': () => - sanitize`Que vous utilisiez cleverapps.io ou vos propres noms de domaine avec les applications hébergées par Clever Cloud, un certificat Let's Encrypt est automatiquement généré et renouvelé pour l'accès HTTPS/TLS. Vous n'avez rien à faire. Pour les cas spécifiques, reportez-vous à notre documentation.`, + sanitize`Que vous utilisiez cleverapps.io ou vos propres noms de domaine avec les applications hébergées par Clever Cloud, un certificat Let's Encrypt est automatiquement généré et renouvelé pour l'accès HTTPS/TLS. Vous n'avez rien à faire. Pour les cas spécifiques, reportez-vous à notre documentation.`, 'cc-domain-management.certif.custom': () => sanitize`Vous pouvez fournir votre propre certificat grâce au gestionnaire de certificats Clever Cloud.`, 'cc-domain-management.certif.heading': `Sécurisez votre application`, 'cc-domain-management.dns.a.desc': () => - sanitize`

Si vous choisissez d'utiliser des enregistrements de type A, par exemple pour un domaine racine (APEX), vous devrez vous-même assurer leur mise à jour. Pensez à suivre notre changelog ou à lire la documentation de notre API v4 pour cela.

`, + sanitize`

Si vous choisissez d'utiliser des enregistrements de type A, par exemple pour un domaine racine (APEX), vous devrez vous-même assurer leur mise à jour. Pensez à suivre notre changelog ou à lire la documentation de notre API v4 pour cela.

`, 'cc-domain-management.dns.a.heading': `Enregistrements A`, 'cc-domain-management.dns.a.label': `Valeurs d'enregistrement A`, 'cc-domain-management.dns.cli.content.diag-conf-command': `Commande pour diagnostiquer l'installation actuelle\u00A0:`, @@ -465,7 +465,7 @@ export const translations = { 'cc-domain-management.dns.documentation.text': `Enregistrements DNS - Documentation`, 'cc-domain-management.dns.heading': `Configurez vos DNS`, 'cc-domain-management.dns.info.desc': () => - sanitize`Si vous bénéficiez d'un load balancer dédié, référez-vous à sa configuration ou contactez le support. Notre équipe pourra également vous aider pour commander un tel service. Pour un domaine sans sous-domaine (APEX) ou un sous-domaine avec sa propre zone DNS, référez-vous à notre documentation.`, + sanitize`Si vous bénéficiez d'un load balancer dédié, référez-vous à sa configuration ou contactez le support. Notre équipe pourra également vous aider pour commander un tel service. Pour un domaine sans sous-domaine (APEX) ou un sous-domaine avec sa propre zone DNS, référez-vous à notre documentation.`, 'cc-domain-management.dns.info.heading': `Load balancers dédiés et cas spécifiques`, 'cc-domain-management.dns.loading-error': `Une erreur est survenue pendant le chargement des informations DNS`, 'cc-domain-management.form.domain.error.contains-path': /** @param {{path: string}} _ */ ({ path }) => @@ -478,7 +478,7 @@ export const translations = { sanitize`Par exemple\u00A0: example.com, *.example.com ou example.cleverapps.io`, 'cc-domain-management.form.domain.label': `Nom de domaine`, 'cc-domain-management.form.info.cleverapps': () => - sanitize`Par défaut, une application se voit attribuer un nom de domaine de type app_id.cleverapps.io. Vous pouvez le supprimer ou changer le sous-domaine librement, mais xxx.cleverapps.io doit uniquement être utilisé à des fins de test (voir notre documentation).`, + sanitize`Par défaut, une application se voit attribuer un nom de domaine de type app_id.cleverapps.io. Vous pouvez le supprimer ou changer le sous-domaine librement, mais xxx.cleverapps.io doit uniquement être utilisé à des fins de test (voir notre documentation).`, 'cc-domain-management.form.info.docs': `Vous pouvez associer un ou plusieurs noms de domaines à votre application. Le domaine principal sera utilisé dans les liens de la Console et dans les e-mails qui vous seront envoyés. Plusieurs applications peuvent partager un même domaine, chacune avec un sous-domaine et/ou une route spécifique.`, 'cc-domain-management.form.path.help': () => sanitize`Par exemple\u00A0: /api ou /blog`, 'cc-domain-management.form.path.label': `Route`, @@ -590,7 +590,7 @@ export const translations = { 'cc-env-var-create.errors.invalid-name': /** @param {{name: string}} _ */ ({ name }) => sanitize`Le nom ${name} n'est pas valide`, 'cc-env-var-create.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, + sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, 'cc-env-var-create.name.label': `Nom de la variable`, 'cc-env-var-create.value.label': `Valeur de la variable`, //#endregion @@ -608,9 +608,9 @@ export const translations = { 'cc-env-var-editor-expert.errors.line': `ligne`, 'cc-env-var-editor-expert.errors.unknown': `Erreur inconnue`, 'cc-env-var-editor-expert.example': () => - sanitize`Format\u00A0: NOM_DE_LA_VARIABLE="valeur de la variable"
Chaque variable doit être séparée par des sauts de ligne, en savoir plus.`, + sanitize`Format\u00A0: NOM_DE_LA_VARIABLE="valeur de la variable"
Chaque variable doit être séparée par des sauts de ligne, en savoir plus.`, 'cc-env-var-editor-expert.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, + sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, 'cc-env-var-editor-expert.label': `Edition des variables. Format\u00A0: NOM_DE_LA_VARIABLE="valeur de la variable". Chaque variable doit être séparée par des sauts de ligne.`, //#endregion //#region cc-env-var-editor-json @@ -625,9 +625,9 @@ export const translations = { sanitize`Le nom ${name} n'est pas valide en mode strict`, 'cc-env-var-editor-json.errors.unknown': `Erreur inconnue`, 'cc-env-var-editor-json.example': () => - sanitize`Format\u00A0: { "name": "NOM_DE_LA_VARIABLE", "value": "valeur de la variable" }
Tableau d'objets respectant le format ci-dessus, en savoir plus.`, + sanitize`Format\u00A0: { "name": "NOM_DE_LA_VARIABLE", "value": "valeur de la variable" }
Tableau d'objets respectant le format ci-dessus, en savoir plus.`, 'cc-env-var-editor-json.info.java-prop': /** @param {{name: string}} _ */ ({ name }) => - sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, + sanitize`La variable ${name} sera injecté sous forme de propriété Java et non en tant que variable d'environnement, plus de détails`, 'cc-env-var-editor-json.label': `Edition des variables. Tableau d'objets respectant le format\u00A0: { "name": "NOM_DE_LA_VARIABLE", "value": "valeur de la variable" }.`, //#endregion //#region cc-env-var-editor-simple @@ -642,11 +642,11 @@ export const translations = { `, 'cc-env-var-form.cli.content.list-var-command': `Lister les variables d'environnement\u00A0:`, 'cc-env-var-form.description.config-provider': /** @param {{addonName: string}} _ */ ({ addonName }) => - sanitize`Configuration publiée pour les applications dépendantes. En savoir plus
Ces seront injectées en tant que variables d'environnement dans les applications qui ont l'add-on ${addonName} dans leurs services liés.
À chaque fois que vous mettez à jour les changements, toutes les applications dépendantes seront redémarrées automatiquement.`, + sanitize`Configuration publiée pour les applications dépendantes. En savoir plus
Ces seront injectées en tant que variables d'environnement dans les applications qui ont l'add-on ${addonName} dans leurs services liés.
À chaque fois que vous mettez à jour les changements, toutes les applications dépendantes seront redémarrées automatiquement.`, 'cc-env-var-form.description.env-var': /** @param {{appName: string}} _ */ ({ appName }) => sanitize`Ces variables seront injectées en tant que variables d'environnement dans l'application ${appName}.`, 'cc-env-var-form.description.exposed-config': /** @param {{appName: string}} _ */ ({ appName }) => - sanitize`Configuration publiée pour les applications dépendantes. En savoir plus
Ces variables ne seront pas injectées dans l'application ${appName}, elles seront injectées en tant que variables d'environnement dans les applications qui ont ${appName} dans leurs services liés.`, + sanitize`Configuration publiée pour les applications dépendantes. En savoir plus
Ces variables ne seront pas injectées dans l'application ${appName}, elles seront injectées en tant que variables d'environnement dans les applications qui ont ${appName} dans leurs services liés.`, 'cc-env-var-form.documentation.text': `Variables d’environnement - Référence`, 'cc-env-var-form.error.loading': `Une erreur est survenue pendant le chargement des variables.`, 'cc-env-var-form.heading.config-provider': `Variables`, @@ -1332,7 +1332,7 @@ export const translations = { 'cc-orga-member-list.invite.email.label': `Adresse e-mail`, 'cc-orga-member-list.invite.heading': `Inviter un membre`, 'cc-orga-member-list.invite.info': () => - sanitize`Plus d'informations à propos des rôles sur la page Rôles et organisations (en anglais)`, + sanitize`Plus d'informations à propos des rôles sur la page Rôles et organisations (en anglais)`, 'cc-orga-member-list.invite.role.accounting': `Comptable`, 'cc-orga-member-list.invite.role.admin': `Admin`, 'cc-orga-member-list.invite.role.developer': `Développeur`, @@ -1858,7 +1858,7 @@ export const translations = { 'cc-token-api-list.empty': `Vous n'avez aucun token d'API, ou aucun d'eux n'est actif. Créez un nouveau token\u00A0:`, 'cc-token-api-list.error': `Une erreur est survenue pendant le chargement des tokens d'API`, 'cc-token-api-list.intro': () => - sanitize`Ci-dessous la liste des tokens d'API associés à votre compte et leurs informations. Vous pouvez les révoquer si nécessaire.`, + sanitize`Ci-dessous la liste des tokens d'API associés à votre compte et leurs informations. Vous pouvez les révoquer si nécessaire.`, 'cc-token-api-list.link.doc': `Tokens d'API - Documentation`, 'cc-token-api-list.main-heading': `Tokens d'API`, 'cc-token-api-list.no-password.create-password-btn': `Ajouter un mot de passe`, @@ -1903,7 +1903,7 @@ export const translations = { 'cc-token-oauth-list.empty': `Aucune application tierce n'est liée à votre compte`, 'cc-token-oauth-list.error': `Une erreur est survenue pendant le chargement des tokens OAuth`, 'cc-token-oauth-list.intro': () => - sanitize`Ci-dessous la liste des applications tierces liées à votre compte et leurs informations. Vous pouvez révoquer leurs tokens OAuth si vous le souhaitez.`, + sanitize`Ci-dessous la liste des applications tierces liées à votre compte et leurs informations. Vous pouvez révoquer leurs tokens OAuth si vous le souhaitez.`, 'cc-token-oauth-list.link.doc': `Tokens OAuth - Documentation`, 'cc-token-oauth-list.main-heading': `Tokens OAuth`, 'cc-token-oauth-list.revoke-all-tokens': `Révoquer tous les tokens OAuth`, diff --git a/test/assets-url.test.js b/test/resource-urls.test.js similarity index 51% rename from test/assets-url.test.js rename to test/resource-urls.test.js index 09f85fbd8..ca32bed5d 100644 --- a/test/assets-url.test.js +++ b/test/resource-urls.test.js @@ -1,5 +1,6 @@ import { expect } from '@bundled-es-modules/chai'; import { getAssetUrl, setAssetsBaseUrl } from '../src/lib/assets-url.js'; +import { getDevHubUrl, getDocUrl, setDevHubBaseUrl } from '../src/lib/dev-hub-url.js'; describe('assets-url module', () => { describe('getAssetUrl function', () => { @@ -72,3 +73,76 @@ describe('assets-url module', () => { }); }); }); + +describe('dev-hub-url module', () => { + describe('getDocUrl', () => { + it('should append /doc/ and path to base URL without trailing slash', () => { + expect(getDocUrl('foo/bar')).to.equal('https://www.clever.cloud/developers/doc/foo/bar'); + }); + + it('should handle path with leading slash', () => { + expect(getDocUrl('/foo/bar')).to.equal('https://www.clever.cloud/developers/doc/foo/bar'); + }); + + it('should handle empty path', () => { + expect(getDocUrl()).to.equal('https://www.clever.cloud/developers/doc'); + }); + }); + + describe('getDevHubUrl', () => { + it('should append path to base URL without trailing slash', () => { + expect(getDevHubUrl('foo/bar')).to.equal('https://www.clever.cloud/developers/foo/bar'); + }); + + it('should handle path with leading slash', () => { + expect(getDevHubUrl('/foo/bar')).to.equal('https://www.clever.cloud/developers/foo/bar'); + }); + + it('should handle empty path', () => { + expect(getDevHubUrl()).to.equal('https://www.clever.cloud/developers'); + }); + }); + + describe('setDevHubBaseUrl', () => { + const originalUrl = 'https://www.clever.cloud/developers'; + + afterEach(() => { + setDevHubBaseUrl(originalUrl); + }); + + it('should set custom base URL without trailing slash', () => { + setDevHubBaseUrl('https://custom-dev-hub.example.com'); + expect(getDevHubUrl('foo/bar')).to.equal('https://custom-dev-hub.example.com/foo/bar'); + }); + + it('should set custom base URL with trailing slash', () => { + setDevHubBaseUrl('https://custom-dev-hub.example.com/'); + expect(getDevHubUrl('foo/bar')).to.equal('https://custom-dev-hub.example.com/foo/bar'); + }); + + it('should affect getDocUrl', () => { + setDevHubBaseUrl('https://custom-dev-hub.example.com'); + expect(getDocUrl('foo/bar')).to.equal('https://custom-dev-hub.example.com/doc/foo/bar'); + }); + + it('should work with localhost URL', () => { + setDevHubBaseUrl('http://localhost:8080'); + expect(getDevHubUrl('foo/bar')).to.equal('http://localhost:8080/foo/bar'); + expect(getDocUrl('foo/bar')).to.equal('http://localhost:8080/doc/foo/bar'); + }); + + it('should work with relative path base URL', () => { + setDevHubBaseUrl('/local/dev-hub'); + expect(getDevHubUrl('foo/bar')).to.equal('/local/dev-hub/foo/bar'); + expect(getDocUrl('foo/bar')).to.equal('/local/dev-hub/doc/foo/bar'); + }); + + it('should reset to new URL after multiple calls', () => { + setDevHubBaseUrl('https://first-hub.example.com'); + expect(getDevHubUrl('test')).to.equal('https://first-hub.example.com/test'); + + setDevHubBaseUrl('https://second-hub.example.com/'); + expect(getDevHubUrl('test')).to.equal('https://second-hub.example.com/test'); + }); + }); +}); diff --git a/test/utils.test.js b/test/utils.test.js index 69143c9a3..c2febf9c2 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -1,14 +1,5 @@ import { expect } from '@bundled-es-modules/chai'; -import { - clampNumber, - generateDevHubHref, - generateDocsHref, - groupBy, - isStringBlank, - isStringEmpty, - randomString, - range, -} from '../src/lib/utils.js'; +import { clampNumber, groupBy, isStringBlank, isStringEmpty, randomString, range } from '../src/lib/utils.js'; describe('range function', function () { it('should return array', function () { @@ -135,31 +126,3 @@ describe('groupBy function', () => { expect(grouped).to.eql({}); }); }); - -describe('generateDocsHref', () => { - it('should append /doc/ and path to base URL without trailing slash', () => { - expect(generateDocsHref('foo/bar')).to.equal('https://www.clever.cloud/developers/doc/foo/bar'); - }); - - it('should handle path with leading slash', () => { - expect(generateDocsHref('/foo/bar')).to.equal('https://www.clever.cloud/developers/doc/foo/bar'); - }); - - it('should handle empty path', () => { - expect(generateDocsHref()).to.equal('https://www.clever.cloud/developers/doc/'); - }); -}); - -describe('generateDevHubHref', () => { - it('should append path to base URL without trailing slash', () => { - expect(generateDevHubHref('foo/bar')).to.equal('https://www.clever.cloud/developers/foo/bar'); - }); - - it('should handle path with leading slash', () => { - expect(generateDevHubHref('/foo/bar')).to.equal('https://www.clever.cloud/developers/foo/bar'); - }); - - it('should handle empty path', () => { - expect(generateDevHubHref()).to.equal('https://www.clever.cloud/developers/'); - }); -});