Use ScmIntegrationsApi
Signed-off-by: Erik Larsson <erik.larsson@schibsted.com>
This commit is contained in:
@@ -34,6 +34,8 @@
|
||||
"@backstage/config": "^0.1.4",
|
||||
"@backstage/catalog-model": "^0.7.7",
|
||||
"@backstage/core": "^0.7.7",
|
||||
"@backstage/integration": "^0.5.0",
|
||||
"@backstage/integration-react": "^0.1.1",
|
||||
"@backstage/plugin-catalog-react": "^0.1.4",
|
||||
"@backstage/theme": "^0.2.6",
|
||||
"@backstage/errors": "^0.1.1",
|
||||
|
||||
@@ -13,21 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
configApiRef,
|
||||
@@ -39,6 +24,10 @@ import {
|
||||
discoveryApiRef,
|
||||
identityApiRef,
|
||||
} from '@backstage/core';
|
||||
import {
|
||||
ScmIntegrationsApi,
|
||||
scmIntegrationsApiRef,
|
||||
} from '@backstage/integration-react';
|
||||
import { techdocsApiRef, techdocsStorageApiRef } from './api';
|
||||
import { TechDocsClient, TechDocsStorageClient } from './client';
|
||||
|
||||
@@ -60,6 +49,11 @@ export const rootCatalogDocsRouteRef = createRouteRef({
|
||||
export const techdocsPlugin = createPlugin({
|
||||
id: 'techdocs',
|
||||
apis: [
|
||||
createApiFactory({
|
||||
api: scmIntegrationsApiRef,
|
||||
deps: { configApi: configApiRef },
|
||||
factory: ({ configApi }) => ScmIntegrationsApi.fromConfig(configApi),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: techdocsStorageApiRef,
|
||||
deps: {
|
||||
|
||||
@@ -14,7 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ApiProvider, ApiRegistry } from '@backstage/core';
|
||||
import {
|
||||
ScmIntegrationsApi,
|
||||
scmIntegrationsApiRef,
|
||||
} from '@backstage/integration-react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { act, render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
@@ -39,9 +44,15 @@ describe('<Reader />', () => {
|
||||
entityId: 'Component::backstage',
|
||||
});
|
||||
|
||||
const scmIntegrationsApi: ScmIntegrationsApi = ScmIntegrationsApi.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {},
|
||||
}),
|
||||
);
|
||||
const techdocsStorageApi: Partial<TechDocsStorageApi> = {};
|
||||
|
||||
const apiRegistry = ApiRegistry.from([
|
||||
[scmIntegrationsApiRef, scmIntegrationsApi],
|
||||
[techdocsStorageApiRef, techdocsStorageApi],
|
||||
]);
|
||||
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { EntityName } from '@backstage/catalog-model';
|
||||
import { configApiRef, useApi } from '@backstage/core';
|
||||
import { useApi } from '@backstage/core';
|
||||
import { scmIntegrationsApiRef } from '@backstage/integration-react';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { useTheme } from '@material-ui/core';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
@@ -54,7 +55,7 @@ export const Reader = ({ entityId, onReady }: Props) => {
|
||||
const [loadedPath, setLoadedPath] = useState('');
|
||||
const [atInitialLoad, setAtInitialLoad] = useState(true);
|
||||
const [newerDocsExist, setNewerDocsExist] = useState(false);
|
||||
const configApi = useApi(configApiRef);
|
||||
const scmIntegrationsApi = useApi(scmIntegrationsApiRef);
|
||||
|
||||
const {
|
||||
value: isSynced,
|
||||
@@ -145,7 +146,7 @@ export const Reader = ({ entityId, onReady }: Props) => {
|
||||
rewriteDocLinks(),
|
||||
removeMkdocsHeader(),
|
||||
simplifyMkdocsFooter(),
|
||||
addGitFeedbackLink(configApi),
|
||||
addGitFeedbackLink(scmIntegrationsApi),
|
||||
injectCss({
|
||||
css: `
|
||||
body {
|
||||
@@ -327,7 +328,7 @@ export const Reader = ({ entityId, onReady }: Props) => {
|
||||
theme.palette.background.default,
|
||||
newerDocsExist,
|
||||
isSynced,
|
||||
configApi,
|
||||
scmIntegrationsApi,
|
||||
]);
|
||||
|
||||
// docLoadError not considered an error state if sync request is still ongoing
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
import React from 'react';
|
||||
import { TechDocsPage } from './TechDocsPage';
|
||||
import { render, act } from '@testing-library/react';
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import {
|
||||
ScmIntegrationsApi,
|
||||
scmIntegrationsApiRef,
|
||||
} from '@backstage/integration-react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import { ApiRegistry, ApiProvider } from '@backstage/core';
|
||||
import {
|
||||
@@ -50,6 +55,11 @@ describe('<TechDocsPage />', () => {
|
||||
entityId: 'Component::backstage',
|
||||
});
|
||||
|
||||
const scmIntegrationsApi: ScmIntegrationsApi = ScmIntegrationsApi.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {},
|
||||
}),
|
||||
);
|
||||
const techdocsApi: Partial<TechDocsApi> = {
|
||||
getEntityMetadata: () =>
|
||||
Promise.resolve({
|
||||
@@ -72,6 +82,7 @@ describe('<TechDocsPage />', () => {
|
||||
};
|
||||
|
||||
const apiRegistry = ApiRegistry.from([
|
||||
[scmIntegrationsApiRef, scmIntegrationsApi],
|
||||
[techdocsApiRef, techdocsApi],
|
||||
[techdocsStorageApiRef, techdocsStorageApi],
|
||||
]);
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ConfigReader } from '@backstage/config';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
import { createTestShadowDom } from '../../test-utils';
|
||||
import { addGitFeedbackLink } from './addGitFeedbackLink';
|
||||
|
||||
const configApi = {
|
||||
getOptionalConfigArray: function getOptionalConfigArray(key: string) {
|
||||
return key === 'integrations.github'
|
||||
? [{ data: { host: 'self-hosted-git-hub-provider.com' } }]
|
||||
: undefined;
|
||||
},
|
||||
};
|
||||
const integrations = ScmIntegrations.fromConfig(
|
||||
new ConfigReader({
|
||||
integrations: {
|
||||
github: [{ host: 'self-hosted-git-hub-provider.com' }],
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
describe('addGitFeedbackLink', () => {
|
||||
it('adds a feedback link when a Gitlab source edit link is available', () => {
|
||||
@@ -38,7 +40,7 @@ describe('addGitFeedbackLink', () => {
|
||||
</html>
|
||||
`,
|
||||
{
|
||||
preTransformers: [addGitFeedbackLink(configApi)],
|
||||
preTransformers: [addGitFeedbackLink(integrations)],
|
||||
postTransformers: [],
|
||||
},
|
||||
);
|
||||
@@ -63,7 +65,7 @@ describe('addGitFeedbackLink', () => {
|
||||
</html>
|
||||
`,
|
||||
{
|
||||
preTransformers: [addGitFeedbackLink(configApi)],
|
||||
preTransformers: [addGitFeedbackLink(integrations)],
|
||||
postTransformers: [],
|
||||
},
|
||||
);
|
||||
@@ -87,7 +89,7 @@ describe('addGitFeedbackLink', () => {
|
||||
</html>
|
||||
`,
|
||||
{
|
||||
preTransformers: [addGitFeedbackLink(configApi)],
|
||||
preTransformers: [addGitFeedbackLink(integrations)],
|
||||
postTransformers: [],
|
||||
},
|
||||
);
|
||||
@@ -107,7 +109,7 @@ describe('addGitFeedbackLink', () => {
|
||||
</html>
|
||||
`,
|
||||
{
|
||||
preTransformers: [addGitFeedbackLink(configApi)],
|
||||
preTransformers: [addGitFeedbackLink(integrations)],
|
||||
postTransformers: [],
|
||||
},
|
||||
);
|
||||
@@ -127,7 +129,7 @@ describe('addGitFeedbackLink', () => {
|
||||
</html>
|
||||
`,
|
||||
{
|
||||
preTransformers: [addGitFeedbackLink(configApi)],
|
||||
preTransformers: [addGitFeedbackLink(integrations)],
|
||||
postTransformers: [],
|
||||
},
|
||||
);
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
|
||||
import type { Transformer } from './index';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import FeedbackOutlinedIcon from '@material-ui/icons/FeedbackOutlined';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
// requires repo
|
||||
export const addGitFeedbackLink = (configApi: any): Transformer => {
|
||||
export const addGitFeedbackLink = (
|
||||
scmIntegrationsApi: ScmIntegrationRegistry,
|
||||
): Transformer => {
|
||||
return dom => {
|
||||
// attempting to use selectors that are more likely to be static as MkDocs updates over time
|
||||
const sourceAnchor = dom.querySelector(
|
||||
@@ -34,21 +37,13 @@ export const addGitFeedbackLink = (configApi: any): Transformer => {
|
||||
let gitHost = '';
|
||||
|
||||
const sourceURL = new URL(sourceAnchor.href);
|
||||
const githubHosts = configApi
|
||||
.getOptionalConfigArray('integrations.github')
|
||||
?.map((integration: any) => integration.data.host);
|
||||
const gitlabHosts = configApi
|
||||
.getOptionalConfigArray('integrations.gitlab')
|
||||
?.map((integration: any) => integration.data.host);
|
||||
const integration = scmIntegrationsApi.byUrl(sourceURL);
|
||||
|
||||
// don't show if can't identify edit link hostname as a gitlab/github hosting
|
||||
if (
|
||||
githubHosts?.includes(sourceURL.hostname) ||
|
||||
sourceURL.origin.includes('github')
|
||||
) {
|
||||
if (integration?.type === 'github' || sourceURL.origin.includes('github')) {
|
||||
gitHost = 'github';
|
||||
} else if (
|
||||
gitlabHosts?.includes(sourceURL.hostname) ||
|
||||
integration?.type === 'gitlab' ||
|
||||
sourceURL.origin.includes('gitlab')
|
||||
) {
|
||||
gitHost = 'gitlab';
|
||||
|
||||
Reference in New Issue
Block a user