@techdocs/cli 1.6.1-next.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/cjs/{mkdocs-571e2dc0.cjs.js → mkdocs-062c745e.cjs.js} +11 -4
- package/dist/cjs/mkdocs-062c745e.cjs.js.map +1 -0
- package/dist/cjs/{serve-bf2ff8e3.cjs.js → serve-d8eba600.cjs.js} +11 -4
- package/dist/cjs/serve-d8eba600.cjs.js.map +1 -0
- package/dist/cjs/{mkdocsServer-107b8efd.cjs.js → utils-fa60b533.cjs.js} +20 -1
- package/dist/cjs/utils-fa60b533.cjs.js.map +1 -0
- package/dist/embedded-app/index.html +1 -1
- package/dist/embedded-app/static/1600.ec5e759e.chunk.js +3 -0
- package/dist/embedded-app/static/1600.ec5e759e.chunk.js.map +1 -0
- package/dist/embedded-app/static/{5914.111b8c95.chunk.js → 5914.633b2934.chunk.js} +2 -2
- package/dist/embedded-app/static/{5914.111b8c95.chunk.js.map → 5914.633b2934.chunk.js.map} +1 -1
- package/dist/embedded-app/static/7241.a066d2d0.chunk.js +3 -0
- package/dist/embedded-app/static/7241.a066d2d0.chunk.js.map +1 -0
- package/dist/embedded-app/static/{8096.60ff0c3e.chunk.js → 8096.752da27d.chunk.js} +3 -3
- package/dist/embedded-app/static/{8096.60ff0c3e.chunk.js.map → 8096.752da27d.chunk.js.map} +1 -1
- package/dist/embedded-app/static/8629.ee337616.chunk.js +7 -0
- package/dist/embedded-app/static/8629.ee337616.chunk.js.map +1 -0
- package/dist/embedded-app/static/main.6ea4af3c.js +487 -0
- package/dist/embedded-app/static/main.6ea4af3c.js.map +1 -0
- package/dist/embedded-app/static/{module-react-beautiful-dnd.0ca788d0.js → module-react-beautiful-dnd.71ae82d9.js} +2 -2
- package/dist/embedded-app/static/{module-react-beautiful-dnd.0ca788d0.js.map → module-react-beautiful-dnd.71ae82d9.js.map} +1 -1
- package/dist/embedded-app/static/module-react-router-dom.9e5a6865.js +22 -0
- package/dist/embedded-app/static/module-react-router-dom.9e5a6865.js.map +1 -0
- package/dist/embedded-app/static/module-react-router.d96a5b36.js +22 -0
- package/dist/embedded-app/static/module-react-router.d96a5b36.js.map +1 -0
- package/dist/embedded-app/static/{runtime.21f1591c.js → runtime.6ea4af3c.js} +3 -3
- package/dist/embedded-app/static/runtime.6ea4af3c.js.map +1 -0
- package/dist/embedded-app/static/vendor.6ea4af3c.js +207 -0
- package/dist/embedded-app/static/vendor.6ea4af3c.js.map +1 -0
- package/dist/index.cjs.js +3 -3
- package/package.json +4 -4
- package/dist/cjs/mkdocs-571e2dc0.cjs.js.map +0 -1
- package/dist/cjs/mkdocsServer-107b8efd.cjs.js.map +0 -1
- package/dist/cjs/serve-bf2ff8e3.cjs.js.map +0 -1
- package/dist/embedded-app/static/1600.ef4a7196.chunk.js +0 -3
- package/dist/embedded-app/static/1600.ef4a7196.chunk.js.map +0 -1
- package/dist/embedded-app/static/3893.118c937c.chunk.js +0 -3
- package/dist/embedded-app/static/3893.118c937c.chunk.js.map +0 -1
- package/dist/embedded-app/static/8629.34b012ba.chunk.js +0 -7
- package/dist/embedded-app/static/8629.34b012ba.chunk.js.map +0 -1
- package/dist/embedded-app/static/main.21f1591c.js +0 -487
- package/dist/embedded-app/static/main.21f1591c.js.map +0 -1
- package/dist/embedded-app/static/module-react-router-dom.8eff32d7.js +0 -22
- package/dist/embedded-app/static/module-react-router-dom.8eff32d7.js.map +0 -1
- package/dist/embedded-app/static/module-react-router.05179f87.js +0 -22
- package/dist/embedded-app/static/module-react-router.05179f87.js.map +0 -1
- package/dist/embedded-app/static/runtime.21f1591c.js.map +0 -1
- package/dist/embedded-app/static/vendor.21f1591c.js +0 -206
- package/dist/embedded-app/static/vendor.21f1591c.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @techdocs/cli
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8600b86820: validate Docker status before running mkdocs server
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
- @backstage/plugin-techdocs-node@1.10.0
|
|
13
|
+
- @backstage/backend-common@0.19.9
|
|
14
|
+
- @backstage/catalog-model@1.4.3
|
|
15
|
+
- @backstage/cli-common@0.1.13
|
|
16
|
+
- @backstage/config@1.1.1
|
|
17
|
+
|
|
3
18
|
## 1.6.1-next.2
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var openBrowser = require('react-dev-utils/openBrowser');
|
|
4
4
|
var utility = require('./utility-3c0df5a9.cjs.js');
|
|
5
|
-
var
|
|
5
|
+
var utils = require('./utils-fa60b533.cjs.js');
|
|
6
6
|
var pluginTechdocsNode = require('@backstage/plugin-techdocs-node');
|
|
7
7
|
var fs = require('fs-extra');
|
|
8
8
|
require('winston');
|
|
9
9
|
require('stream');
|
|
10
10
|
require('process');
|
|
11
11
|
require('child_process');
|
|
12
|
+
require('util');
|
|
12
13
|
|
|
13
14
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
15
|
|
|
@@ -20,6 +21,12 @@ async function serveMkdocs(opts) {
|
|
|
20
21
|
const dockerAddr = `http://0.0.0.0:${opts.port}`;
|
|
21
22
|
const localAddr = `http://127.0.0.1:${opts.port}`;
|
|
22
23
|
const expectedDevAddr = opts.docker ? dockerAddr : localAddr;
|
|
24
|
+
if (opts.docker) {
|
|
25
|
+
const isDockerOperational = await utils.checkIfDockerIsOperational(logger);
|
|
26
|
+
if (!isDockerOperational) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
23
30
|
const { path: mkdocsYmlPath, configIsTemporary } = await pluginTechdocsNode.getMkdocsYml(
|
|
24
31
|
"./",
|
|
25
32
|
opts.siteName
|
|
@@ -42,7 +49,7 @@ Starting mkdocs server on ${localAddr}
|
|
|
42
49
|
}
|
|
43
50
|
});
|
|
44
51
|
};
|
|
45
|
-
const childProcess = await
|
|
52
|
+
const childProcess = await utils.runMkdocsServer({
|
|
46
53
|
port: opts.port,
|
|
47
54
|
dockerImage: opts.dockerImage,
|
|
48
55
|
dockerEntrypoint: opts.dockerEntrypoint,
|
|
@@ -51,7 +58,7 @@ Starting mkdocs server on ${localAddr}
|
|
|
51
58
|
stdoutLogFunc: logFunc,
|
|
52
59
|
stderrLogFunc: logFunc
|
|
53
60
|
});
|
|
54
|
-
await
|
|
61
|
+
await utils.waitForSignal([childProcess]);
|
|
55
62
|
if (configIsTemporary) {
|
|
56
63
|
process.on("exit", async () => {
|
|
57
64
|
fs__default["default"].rmSync(mkdocsYmlPath, {});
|
|
@@ -60,4 +67,4 @@ Starting mkdocs server on ${localAddr}
|
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
exports["default"] = serveMkdocs;
|
|
63
|
-
//# sourceMappingURL=mkdocs-
|
|
70
|
+
//# sourceMappingURL=mkdocs-062c745e.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mkdocs-062c745e.cjs.js","sources":["../../src/commands/serve/mkdocs.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { OptionValues } from 'commander';\nimport openBrowser from 'react-dev-utils/openBrowser';\nimport { createLogger } from '../../lib/utility';\nimport { runMkdocsServer } from '../../lib/mkdocsServer';\nimport { LogFunc, waitForSignal } from '../../lib/run';\nimport { getMkdocsYml } from '@backstage/plugin-techdocs-node';\nimport fs from 'fs-extra';\nimport { checkIfDockerIsOperational } from './utils';\n\nexport default async function serveMkdocs(opts: OptionValues) {\n const logger = createLogger({ verbose: opts.verbose });\n\n const dockerAddr = `http://0.0.0.0:${opts.port}`;\n const localAddr = `http://127.0.0.1:${opts.port}`;\n const expectedDevAddr = opts.docker ? dockerAddr : localAddr;\n\n if (opts.docker) {\n const isDockerOperational = await checkIfDockerIsOperational(logger);\n if (!isDockerOperational) {\n return;\n }\n }\n\n const { path: mkdocsYmlPath, configIsTemporary } = await getMkdocsYml(\n './',\n opts.siteName,\n );\n\n // We want to open browser only once based on a log.\n let boolOpenBrowserTriggered = false;\n\n const logFunc: LogFunc = data => {\n // Sometimes the lines contain an unnecessary extra new line in between\n const logLines = data.toString().split('\\n');\n const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]';\n logLines.forEach(line => {\n if (line === '') {\n return;\n }\n\n // Logs from container is verbose.\n logger.verbose(`${logPrefix} ${line}`);\n\n // When the server has started, open a new browser tab for the user.\n if (\n !boolOpenBrowserTriggered &&\n line.includes(`Serving on ${expectedDevAddr}`)\n ) {\n // Always open the local address, since 0.0.0.0 belongs to docker\n logger.info(`\\nStarting mkdocs server on ${localAddr}\\n`);\n openBrowser(localAddr);\n boolOpenBrowserTriggered = true;\n }\n });\n };\n // mkdocs writes all of its logs to stderr by default, and not stdout.\n // https://github.com/mkdocs/mkdocs/issues/879#issuecomment-203536006\n // Had me questioning this whole implementation for half an hour.\n\n // Commander stores --no-docker in cmd.docker variable\n const childProcess = await runMkdocsServer({\n port: opts.port,\n dockerImage: opts.dockerImage,\n dockerEntrypoint: opts.dockerEntrypoint,\n dockerOptions: opts.dockerOption,\n useDocker: opts.docker,\n stdoutLogFunc: logFunc,\n stderrLogFunc: logFunc,\n });\n\n // Keep waiting for user to cancel the process\n await waitForSignal([childProcess]);\n\n if (configIsTemporary) {\n process.on('exit', async () => {\n fs.rmSync(mkdocsYmlPath, {});\n });\n }\n}\n"],"names":["createLogger","checkIfDockerIsOperational","getMkdocsYml","openBrowser","runMkdocsServer","waitForSignal","fs"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,eAA8B,YAAY,IAAoB,EAAA;AAC5D,EAAA,MAAM,SAASA,oBAAa,CAAA,EAAE,OAAS,EAAA,IAAA,CAAK,SAAS,CAAA,CAAA;AAErD,EAAM,MAAA,UAAA,GAAa,CAAkB,eAAA,EAAA,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA;AAC9C,EAAM,MAAA,SAAA,GAAY,CAAoB,iBAAA,EAAA,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA;AAC/C,EAAM,MAAA,eAAA,GAAkB,IAAK,CAAA,MAAA,GAAS,UAAa,GAAA,SAAA,CAAA;AAEnD,EAAA,IAAI,KAAK,MAAQ,EAAA;AACf,IAAM,MAAA,mBAAA,GAAsB,MAAMC,gCAAA,CAA2B,MAAM,CAAA,CAAA;AACnE,IAAA,IAAI,CAAC,mBAAqB,EAAA;AACxB,MAAA,OAAA;AAAA,KACF;AAAA,GACF;AAEA,EAAA,MAAM,EAAE,IAAA,EAAM,aAAe,EAAA,iBAAA,KAAsB,MAAMC,+BAAA;AAAA,IACvD,IAAA;AAAA,IACA,IAAK,CAAA,QAAA;AAAA,GACP,CAAA;AAGA,EAAA,IAAI,wBAA2B,GAAA,KAAA,CAAA;AAE/B,EAAA,MAAM,UAAmB,CAAQ,IAAA,KAAA;AAE/B,IAAA,MAAM,QAAW,GAAA,IAAA,CAAK,QAAS,EAAA,CAAE,MAAM,IAAI,CAAA,CAAA;AAC3C,IAAM,MAAA,SAAA,GAAY,IAAK,CAAA,MAAA,GAAS,iBAAoB,GAAA,UAAA,CAAA;AACpD,IAAA,QAAA,CAAS,QAAQ,CAAQ,IAAA,KAAA;AACvB,MAAA,IAAI,SAAS,EAAI,EAAA;AACf,QAAA,OAAA;AAAA,OACF;AAGA,MAAA,MAAA,CAAO,OAAQ,CAAA,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,CAAA,CAAA;AAGrC,MAAA,IACE,CAAC,wBACD,IAAA,IAAA,CAAK,SAAS,CAAc,WAAA,EAAA,eAAe,EAAE,CAC7C,EAAA;AAEA,QAAA,MAAA,CAAO,IAAK,CAAA,CAAA;AAAA,0BAAA,EAA+B,SAAS,CAAA;AAAA,CAAI,CAAA,CAAA;AACxD,QAAAC,+BAAA,CAAY,SAAS,CAAA,CAAA;AACrB,QAA2B,wBAAA,GAAA,IAAA,CAAA;AAAA,OAC7B;AAAA,KACD,CAAA,CAAA;AAAA,GACH,CAAA;AAMA,EAAM,MAAA,YAAA,GAAe,MAAMC,qBAAgB,CAAA;AAAA,IACzC,MAAM,IAAK,CAAA,IAAA;AAAA,IACX,aAAa,IAAK,CAAA,WAAA;AAAA,IAClB,kBAAkB,IAAK,CAAA,gBAAA;AAAA,IACvB,eAAe,IAAK,CAAA,YAAA;AAAA,IACpB,WAAW,IAAK,CAAA,MAAA;AAAA,IAChB,aAAe,EAAA,OAAA;AAAA,IACf,aAAe,EAAA,OAAA;AAAA,GAChB,CAAA,CAAA;AAGD,EAAM,MAAAC,mBAAA,CAAc,CAAC,YAAY,CAAC,CAAA,CAAA;AAElC,EAAA,IAAI,iBAAmB,EAAA;AACrB,IAAQ,OAAA,CAAA,EAAA,CAAG,QAAQ,YAAY;AAC7B,MAAGC,sBAAA,CAAA,MAAA,CAAO,aAAe,EAAA,EAAE,CAAA,CAAA;AAAA,KAC5B,CAAA,CAAA;AAAA,GACH;AACF;;;;"}
|
|
@@ -7,13 +7,14 @@ var serveHandler = require('serve-handler');
|
|
|
7
7
|
var http = require('http');
|
|
8
8
|
var httpProxy = require('http-proxy');
|
|
9
9
|
var utility = require('./utility-3c0df5a9.cjs.js');
|
|
10
|
-
var
|
|
10
|
+
var utils = require('./utils-fa60b533.cjs.js');
|
|
11
11
|
var pluginTechdocsNode = require('@backstage/plugin-techdocs-node');
|
|
12
12
|
var fs = require('fs-extra');
|
|
13
13
|
require('winston');
|
|
14
14
|
require('stream');
|
|
15
15
|
require('process');
|
|
16
16
|
require('child_process');
|
|
17
|
+
require('util');
|
|
17
18
|
|
|
18
19
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
19
20
|
|
|
@@ -127,6 +128,12 @@ async function serve(opts) {
|
|
|
127
128
|
name: siteName,
|
|
128
129
|
mkdocsConfigFileName
|
|
129
130
|
});
|
|
131
|
+
if (opts.docker) {
|
|
132
|
+
const isDockerOperational = await utils.checkIfDockerIsOperational(logger);
|
|
133
|
+
if (!isDockerOperational) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
130
137
|
let mkdocsServerHasStarted = false;
|
|
131
138
|
const mkdocsLogFunc = (data) => {
|
|
132
139
|
const logLines = data.toString().split("\n");
|
|
@@ -142,7 +149,7 @@ async function serve(opts) {
|
|
|
142
149
|
});
|
|
143
150
|
};
|
|
144
151
|
logger.info("Starting mkdocs server.");
|
|
145
|
-
const mkdocsChildProcess = await
|
|
152
|
+
const mkdocsChildProcess = await utils.runMkdocsServer({
|
|
146
153
|
port: opts.mkdocsPort,
|
|
147
154
|
dockerImage: opts.dockerImage,
|
|
148
155
|
dockerEntrypoint: opts.dockerEntrypoint,
|
|
@@ -183,7 +190,7 @@ async function serve(opts) {
|
|
|
183
190
|
Opening browser.`
|
|
184
191
|
);
|
|
185
192
|
});
|
|
186
|
-
await
|
|
193
|
+
await utils.waitForSignal([mkdocsChildProcess]);
|
|
187
194
|
if (configIsTemporary) {
|
|
188
195
|
process.on("exit", async () => {
|
|
189
196
|
fs__default["default"].rmSync(mkdocsYmlPath, {});
|
|
@@ -192,4 +199,4 @@ Opening browser.`
|
|
|
192
199
|
}
|
|
193
200
|
|
|
194
201
|
exports["default"] = serve;
|
|
195
|
-
//# sourceMappingURL=serve-
|
|
202
|
+
//# sourceMappingURL=serve-d8eba600.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-d8eba600.cjs.js","sources":["../../src/lib/httpServer.ts","../../src/commands/serve/serve.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport serveHandler from 'serve-handler';\nimport http from 'http';\nimport httpProxy from 'http-proxy';\nimport { createLogger } from './utility';\n\nexport default class HTTPServer {\n private readonly proxyEndpoint: string;\n private readonly backstageBundleDir: string;\n private readonly backstagePort: number;\n private readonly mkdocsTargetAddress: string;\n private readonly verbose: boolean;\n\n constructor(\n backstageBundleDir: string,\n backstagePort: number,\n mkdocsTargetAddress: string,\n verbose: boolean,\n ) {\n this.proxyEndpoint = '/api/techdocs/';\n this.backstageBundleDir = backstageBundleDir;\n this.backstagePort = backstagePort;\n this.mkdocsTargetAddress = mkdocsTargetAddress;\n this.verbose = verbose;\n }\n\n // Create a Proxy for mkdocs server\n private createProxy() {\n const proxy = httpProxy.createProxyServer({\n target: this.mkdocsTargetAddress,\n });\n\n return (request: http.IncomingMessage): [httpProxy, string] => {\n // If the request path is prefixed with this.proxyEndpoint, remove it.\n const proxyEndpointPath = new RegExp(`^${this.proxyEndpoint}`, 'i');\n const forwardPath = request.url?.replace(proxyEndpointPath, '') || '';\n\n return [proxy, forwardPath];\n };\n }\n\n public async serve(): Promise<http.Server> {\n return new Promise<http.Server>((resolve, reject) => {\n const proxyHandler = this.createProxy();\n const server = http.createServer(\n (request: http.IncomingMessage, response: http.ServerResponse) => {\n if (request.url?.startsWith(this.proxyEndpoint)) {\n const [proxy, forwardPath] = proxyHandler(request);\n\n proxy.on('error', (error: Error) => {\n reject(error);\n });\n\n response.setHeader('Access-Control-Allow-Origin', '*');\n response.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');\n\n request.url = forwardPath;\n proxy.web(request, response);\n return;\n }\n\n // This endpoint is used by the frontend to detect where the backend is running.\n if (request.url === '/.detect') {\n response.setHeader('Content-Type', 'text/plain');\n response.end('techdocs-cli-server');\n return;\n }\n\n serveHandler(request, response, {\n public: this.backstageBundleDir,\n trailingSlash: true,\n rewrites: [{ source: '**', destination: 'index.html' }],\n });\n },\n );\n\n const logger = createLogger({ verbose: false });\n server.listen(this.backstagePort, () => {\n if (this.verbose) {\n logger.info(\n `[techdocs-preview-bundle] Running local version of Backstage at http://localhost:${this.backstagePort}`,\n );\n }\n resolve(server);\n });\n\n server.on('error', (error: Error) => {\n reject(error);\n });\n });\n }\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { OptionValues } from 'commander';\nimport path from 'path';\nimport openBrowser from 'react-dev-utils/openBrowser';\nimport { findPaths } from '@backstage/cli-common';\nimport HTTPServer from '../../lib/httpServer';\nimport { runMkdocsServer } from '../../lib/mkdocsServer';\nimport { LogFunc, waitForSignal } from '../../lib/run';\nimport { createLogger } from '../../lib/utility';\nimport { getMkdocsYml } from '@backstage/plugin-techdocs-node';\nimport fs from 'fs-extra';\nimport { checkIfDockerIsOperational } from './utils';\n\nfunction findPreviewBundlePath(): string {\n try {\n return path.join(\n path.dirname(require.resolve('techdocs-cli-embedded-app/package.json')),\n 'dist',\n );\n } catch {\n // If the techdocs-cli-embedded-app package is not available it means we're\n // running a published package. For published packages the preview bundle is\n // copied to dist/embedded-app be the prepack script.\n //\n // This can be tested by running `yarn pack` and extracting the resulting tarball into a directory.\n // Within the extracted directory, run `npm install --only=prod`.\n // Once that's done you can test the CLI in any directory using `node <tmp-dir>/package <command>`.\n // eslint-disable-next-line no-restricted-syntax\n return findPaths(__dirname).resolveOwn('dist/embedded-app');\n }\n}\n\nfunction getPreviewAppPath(opts: OptionValues): string {\n return opts.previewAppBundlePath ?? findPreviewBundlePath();\n}\n\nexport default async function serve(opts: OptionValues) {\n const logger = createLogger({ verbose: opts.verbose });\n\n // Determine if we want to run in local dev mode or not\n // This will run the backstage http server on a different port and only used\n // for proxying mkdocs to the backstage app running locally (e.g. with webpack-dev-server)\n const isDevMode = Object.keys(process.env).includes('TECHDOCS_CLI_DEV_MODE')\n ? true\n : false;\n\n const backstageBackendPort = 7007;\n\n const mkdocsDockerAddr = `http://0.0.0.0:${opts.mkdocsPort}`;\n const mkdocsLocalAddr = `http://127.0.0.1:${opts.mkdocsPort}`;\n const mkdocsExpectedDevAddr = opts.docker\n ? mkdocsDockerAddr\n : mkdocsLocalAddr;\n const mkdocsConfigFileName = opts.mkdocsConfigFileName;\n const siteName = opts.siteName;\n\n const { path: mkdocsYmlPath, configIsTemporary } = await getMkdocsYml('./', {\n name: siteName,\n mkdocsConfigFileName,\n });\n\n // Validate that Docker is up and running\n if (opts.docker) {\n const isDockerOperational = await checkIfDockerIsOperational(logger);\n if (!isDockerOperational) {\n return;\n }\n }\n\n let mkdocsServerHasStarted = false;\n const mkdocsLogFunc: LogFunc = data => {\n // Sometimes the lines contain an unnecessary extra new line\n const logLines = data.toString().split('\\n');\n const logPrefix = opts.docker ? '[docker/mkdocs]' : '[mkdocs]';\n logLines.forEach(line => {\n if (line === '') {\n return;\n }\n\n logger.verbose(`${logPrefix} ${line}`);\n\n // When the server has started, open a new browser tab for the user.\n if (\n !mkdocsServerHasStarted &&\n line.includes(`Serving on ${mkdocsExpectedDevAddr}`)\n ) {\n mkdocsServerHasStarted = true;\n }\n });\n };\n // mkdocs writes all of its logs to stderr by default, and not stdout.\n // https://github.com/mkdocs/mkdocs/issues/879#issuecomment-203536006\n // Had me questioning this whole implementation for half an hour.\n logger.info('Starting mkdocs server.');\n const mkdocsChildProcess = await runMkdocsServer({\n port: opts.mkdocsPort,\n dockerImage: opts.dockerImage,\n dockerEntrypoint: opts.dockerEntrypoint,\n dockerOptions: opts.dockerOption,\n useDocker: opts.docker,\n stdoutLogFunc: mkdocsLogFunc,\n stderrLogFunc: mkdocsLogFunc,\n mkdocsConfigFileName: mkdocsYmlPath,\n });\n\n // Wait until mkdocs server has started so that Backstage starts with docs loaded\n // Takes 1-5 seconds\n for (let attempt = 0; attempt < 30; attempt++) {\n await new Promise(r => setTimeout(r, 3000));\n if (mkdocsServerHasStarted) {\n break;\n }\n logger.info('Waiting for mkdocs server to start...');\n }\n\n if (!mkdocsServerHasStarted) {\n logger.error(\n 'mkdocs server did not start. Exiting. Try re-running command with -v option for more details.',\n );\n }\n\n const port = isDevMode ? backstageBackendPort : opts.previewAppPort;\n const previewAppPath = getPreviewAppPath(opts);\n const httpServer = new HTTPServer(\n previewAppPath,\n port,\n mkdocsExpectedDevAddr,\n opts.verbose,\n );\n\n httpServer\n .serve()\n .catch(err => {\n logger.error('Failed to start HTTP server', err);\n mkdocsChildProcess.kill();\n process.exit(1);\n })\n .then(() => {\n // The last three things default/component/local/ don't matter. They can be anything.\n openBrowser(`http://localhost:${port}/docs/default/component/local/`);\n logger.info(\n `Serving docs in Backstage at http://localhost:${port}/docs/default/component/local/\\nOpening browser.`,\n );\n });\n\n await waitForSignal([mkdocsChildProcess]);\n\n if (configIsTemporary) {\n process.on('exit', async () => {\n fs.rmSync(mkdocsYmlPath, {});\n });\n }\n}\n"],"names":["httpProxy","http","serveHandler","createLogger","path","findPaths","getMkdocsYml","checkIfDockerIsOperational","runMkdocsServer","openBrowser","waitForSignal","fs"],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var child_process = require('child_process');
|
|
4
|
+
var util = require('util');
|
|
4
5
|
|
|
5
6
|
const run = async (name, args = [], options = {}) => {
|
|
6
7
|
var _a;
|
|
@@ -101,6 +102,24 @@ const runMkdocsServer = async (options) => {
|
|
|
101
102
|
);
|
|
102
103
|
};
|
|
103
104
|
|
|
105
|
+
async function checkIfDockerIsOperational(logger) {
|
|
106
|
+
logger.info("Checking Docker status...");
|
|
107
|
+
try {
|
|
108
|
+
const runCheck = util.promisify(child_process.execFile);
|
|
109
|
+
await runCheck("docker", ["info"], { shell: true });
|
|
110
|
+
logger.info(
|
|
111
|
+
"Docker is up and running. Proceed to starting up mkdocs server"
|
|
112
|
+
);
|
|
113
|
+
return true;
|
|
114
|
+
} catch {
|
|
115
|
+
logger.error(
|
|
116
|
+
"Docker is not running. Exiting. Please check status of Docker daemon with `docker info` before re-running"
|
|
117
|
+
);
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
exports.checkIfDockerIsOperational = checkIfDockerIsOperational;
|
|
104
123
|
exports.runMkdocsServer = runMkdocsServer;
|
|
105
124
|
exports.waitForSignal = waitForSignal;
|
|
106
|
-
//# sourceMappingURL=
|
|
125
|
+
//# sourceMappingURL=utils-fa60b533.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-fa60b533.cjs.js","sources":["../../src/lib/run.ts","../../src/lib/mkdocsServer.ts","../../src/commands/serve/utils.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { spawn, SpawnOptions, ChildProcess } from 'child_process';\n\nexport type LogFunc = (data: Buffer | string) => void;\ntype SpawnOptionsPartialEnv = Omit<SpawnOptions, 'env'> & {\n env?: Partial<NodeJS.ProcessEnv>;\n // Pipe stdout to this log function\n stdoutLogFunc?: LogFunc;\n // Pipe stderr to this log function\n stderrLogFunc?: LogFunc;\n};\n\n// TODO: Accept log functions to pipe logs with.\n// Runs a child command, returning the child process instance.\n// Use it along with waitForSignal to run a long running process e.g. mkdocs serve\nexport const run = async (\n name: string,\n args: string[] = [],\n options: SpawnOptionsPartialEnv = {},\n): Promise<ChildProcess> => {\n const { stdoutLogFunc, stderrLogFunc } = options;\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n FORCE_COLOR: 'true',\n ...(options.env ?? {}),\n };\n\n // Refer: https://nodejs.org/api/child_process.html#child_process_subprocess_stdio\n const stdio = [\n 'inherit',\n stdoutLogFunc ? 'pipe' : 'inherit',\n stderrLogFunc ? 'pipe' : 'inherit',\n ] as ('inherit' | 'pipe')[];\n\n const childProcess = spawn(name, args, {\n stdio: stdio,\n ...options,\n env,\n });\n\n if (stdoutLogFunc && childProcess.stdout) {\n childProcess.stdout.on('data', stdoutLogFunc);\n }\n if (stderrLogFunc && childProcess.stderr) {\n childProcess.stderr.on('data', stderrLogFunc);\n }\n\n return childProcess;\n};\n\n// Block indefinitely and wait for a signal to stop the child process(es)\n// Throw error if any child process errors\n// Resolves only when all processes exit with status code 0\nexport async function waitForSignal(\n childProcesses: Array<ChildProcess>,\n): Promise<void> {\n const promises: Array<Promise<void>> = [];\n\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n process.on(signal, () => {\n childProcesses.forEach(childProcess => {\n childProcess.kill();\n });\n });\n }\n\n childProcesses.forEach(childProcess => {\n if (typeof childProcess.exitCode === 'number') {\n if (childProcess.exitCode) {\n throw new Error(`Non zero exit code from child process`);\n }\n return;\n }\n\n promises.push(\n new Promise<void>((resolve, reject) => {\n childProcess.once('error', reject);\n childProcess.once('exit', resolve);\n }),\n );\n });\n\n await Promise.all(promises);\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ChildProcess } from 'child_process';\nimport { run, LogFunc } from './run';\n\nexport const runMkdocsServer = async (options: {\n port?: string;\n useDocker?: boolean;\n dockerImage?: string;\n dockerEntrypoint?: string;\n dockerOptions?: string[];\n stdoutLogFunc?: LogFunc;\n stderrLogFunc?: LogFunc;\n mkdocsConfigFileName?: string;\n}): Promise<ChildProcess> => {\n const port = options.port ?? '8000';\n const useDocker = options.useDocker ?? true;\n const dockerImage = options.dockerImage ?? 'spotify/techdocs';\n\n if (useDocker) {\n return await run(\n 'docker',\n [\n 'run',\n '--rm',\n '-w',\n '/content',\n '-v',\n `${process.cwd()}:/content`,\n '-p',\n `${port}:${port}`,\n '-it',\n ...(options.dockerEntrypoint\n ? ['--entrypoint', options.dockerEntrypoint]\n : []),\n ...(options.dockerOptions || []),\n dockerImage,\n 'serve',\n '--dev-addr',\n `0.0.0.0:${port}`,\n ...(options.mkdocsConfigFileName\n ? ['--config-file', options.mkdocsConfigFileName]\n : []),\n ],\n {\n stdoutLogFunc: options.stdoutLogFunc,\n stderrLogFunc: options.stderrLogFunc,\n },\n );\n }\n\n return await run(\n 'mkdocs',\n [\n 'serve',\n '--dev-addr',\n `127.0.0.1:${port}`,\n ...(options.mkdocsConfigFileName\n ? ['--config-file', options.mkdocsConfigFileName]\n : []),\n ],\n {\n stdoutLogFunc: options.stdoutLogFunc,\n stderrLogFunc: options.stderrLogFunc,\n },\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { promisify } from 'util';\nimport * as winston from 'winston';\nimport { execFile } from 'child_process';\n\nexport async function checkIfDockerIsOperational(\n logger: winston.Logger,\n): Promise<boolean> {\n logger.info('Checking Docker status...');\n try {\n const runCheck = promisify(execFile);\n await runCheck('docker', ['info'], { shell: true });\n logger.info(\n 'Docker is up and running. Proceed to starting up mkdocs server',\n );\n return true;\n } catch {\n logger.error(\n 'Docker is not running. Exiting. Please check status of Docker daemon with `docker info` before re-running',\n );\n return false;\n }\n}\n"],"names":["spawn","promisify","execFile"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Backstage is an open platform for building developer portals"/><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"/><link rel="icon" href="/favicon.ico"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"/><title>Techdocs Preview App</title><script defer="defer" src="/static/runtime.
|
|
1
|
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Backstage is an open platform for building developer portals"/><link rel="manifest" href="/manifest.json" crossorigin="use-credentials"/><link rel="icon" href="/favicon.ico"/><link rel="shortcut icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"/><title>Techdocs Preview App</title><script defer="defer" src="/static/runtime.6ea4af3c.js"></script><script defer="defer" src="/static/module-material-ui.263ce9b5.js"></script><script defer="defer" src="/static/module-lodash.fa492ce2.js"></script><script defer="defer" src="/static/module-date-fns.b8b6c380.js"></script><script defer="defer" src="/static/module-material-table.3c68edc1.js"></script><script defer="defer" src="/static/module-react-dom.f7ae1c8b.js"></script><script defer="defer" src="/static/module-react-router.d96a5b36.js"></script><script defer="defer" src="/static/module-react-router-dom.9e5a6865.js"></script><script defer="defer" src="/static/module-zod.9e0f365e.js"></script><script defer="defer" src="/static/module-i18next.db8a27ed.js"></script><script defer="defer" src="/static/module-react-beautiful-dnd.71ae82d9.js"></script><script defer="defer" src="/static/vendor.6ea4af3c.js"></script><script defer="defer" src="/static/main.6ea4af3c.js"></script></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";(()=>{(self.webpackChunktechdocs_cli_embedded_app=self.webpackChunktechdocs_cli_embedded_app||[]).push([[1600],{59119:function(ft,B,t){t.d(B,{O:function(){return W}});var e=t(52322),v=t(79692),I=t(80030),z=t(2784),U=t(15277),N=t.n(U),$=t(29862);const H=(0,v.Z)({container:{overflow:"visible !important"}},{name:"BackstageOverflowTooltip"});function W(T){const[V,Q]=(0,z.useState)(!1),b=(0,$.t)(),E=H(),G=O=>{b()&&Q(O)};var Z;return(0,e.jsx)(I.ZP,{title:(Z=T.title)!==null&&Z!==void 0?Z:T.text||"",placement:T.placement,disableHoverListener:!V,children:(0,e.jsx)(N(),{text:T.text,line:T.line,onToggled:G,containerClassName:E.container})})}},51600:function(ft,B,t){t.r(B),t.d(B,{BaseCatalogPage:function(){return ct},CatalogPage:function(){return ue},DefaultCatalogPage:function(){return ut}});var e=t(52322),v=t(2784),I=t(73557),z=t(32166),U=t(42398),N=t(30706),$=t(77277),H=t(61837),W=t(41156),T=t(71597),V=t(88188);function Q(n){const{title:l,to:a}=n,s=(0,W.Z)(d=>d.breakpoints.down("xs"));return a?s?(0,e.jsx)(H.Z,{component:T.rU,color:"primary",title:l,size:"small",to:a,children:(0,e.jsx)(V.Z,{})}):(0,e.jsx)($.Z,{component:T.rU,variant:"contained",color:"primary",to:a,children:l}):null}var b=t(13788),E=t(44394),G=t(6542),Z=t(37321),O=t(25942),X=t(30389),q=t(35879),_=t(78847),Y=t(62774),F=t(4967),tt=t(64279),et=t(88624);function pt(){const n=(0,E.h_)(et.A),{error:l,loading:a,value:s}=(0,tt.default)(async()=>await n.getEntityFacets({facets:["kind"]}).then(o=>{var r;return((r=o.facets.kind)===null||r===void 0?void 0:r.map(i=>i.value).sort())||[]}),[n]);return{loading:a,error:l,allKinds:s!=null?s:[]}}function yt(n,l,a){let s=n;return l&&(s=s.filter(o=>l.some(r=>r.toLocaleLowerCase("en-US")===o.toLocaleLowerCase("en-US")))),a&&!n.some(o=>o.toLocaleLowerCase("en-US")===a.toLocaleLowerCase("en-US"))&&(s=s.concat([a])),s.sort().reduce((o,r)=>(o[r.toLocaleLowerCase("en-US")]=r,o),{})}function gt(n){var l;const{filters:a,queryParameters:{kind:s},updateFilters:d}=(0,O.wp)(),o=(0,v.useMemo)(()=>[s].flat()[0],[s]);var r;const[i,c]=(0,v.useState)((r=o!=null?o:(l=a.kind)===null||l===void 0?void 0:l.value)!==null&&r!==void 0?r:n.initialFilter);(0,v.useEffect)(()=>{o&&c(o)},[o]),(0,v.useEffect)(()=>{var P;if(!((P=a.kind)===null||P===void 0)&&P.value){var S;c((S=a.kind)===null||S===void 0?void 0:S.value)}},[a.kind]),(0,v.useEffect)(()=>{d({kind:i?new F.zo(i):void 0})},[i,d]);const{allKinds:u,loading:f,error:h}=pt();return{loading:f,error:h,allKinds:u!=null?u:[],selectedKind:i,setSelectedKind:c}}const ht=n=>{const{allowedKinds:l,hidden:a,initialFilter:s="component"}=n,d=(0,E.h_)(_.$),{error:o,allKinds:r,selectedKind:i,setSelectedKind:c}=gt({initialFilter:s});if((0,v.useEffect)(()=>{o&&d.post({message:"Failed to load entity kinds",severity:"error"})},[o,d]),o)return null;const u=yt(r,l,i),f=Object.keys(u).map(h=>({value:h,label:u[h]}));return a?null:(0,e.jsx)(Y.Z,{pb:1,pt:1,children:(0,e.jsx)(q.H,{label:"Kind",items:f,selected:i.toLocaleLowerCase("en-US"),onChange:h=>c(String(h))})})};var Ct=t(18149),xt=t.n(Ct),St=t(829),jt=t.n(St);function Et(){const n=(0,E.h_)(et.A),{filters:{kind:l,type:a},queryParameters:{type:s},updateFilters:d}=(0,O.wp)(),o=(0,v.useMemo)(()=>[s].flat().filter(Boolean),[s]);var r;const[i,c]=(0,v.useState)(o.length?o:(r=a==null?void 0:a.getTypes())!==null&&r!==void 0?r:[]);(0,v.useEffect)(()=>{o.length&&c(o)},[o]);const[u,f]=(0,v.useState)([]),h=(0,v.useMemo)(()=>l==null?void 0:l.value,[l]),{error:P,loading:S,value:x}=(0,tt.default)(async()=>h?await n.getEntityFacets({filter:{kind:h},facets:["spec.type"]}).then(A=>A.facets["spec.type"]||[]):[],[h,n]),j=(0,v.useRef)(x);return(0,v.useEffect)(()=>{const M=j.current;if(j.current=x,S||!h||M===x||!x)return;const A=[...new Set(jt()(x,L=>-L.count).map(L=>L.value.toLocaleLowerCase("en-US")))];f(A);const K=i.filter(L=>A.includes(L));xt()(i,K)||c(K)},[S,h,i,c,x]),(0,v.useEffect)(()=>{d({type:i.length?new F.Bf(i):void 0})},[i,d]),{loading:S,error:P,availableTypes:u,selectedTypes:i,setSelectedTypes:c}}const Tt=n=>{const{hidden:l,initialFilter:a}=n,s=(0,E.h_)(_.$),{error:d,availableTypes:o,selectedTypes:r,setSelectedTypes:i}=Et();if((0,v.useEffect)(()=>{d&&s.post({message:"Failed to load entity types",severity:"error"}),a&&i([a])},[d,s,a,i]),o.length===0||d)return null;const c=[{value:"all",label:"all"},...o.map(f=>({value:f,label:f}))];var u;return l?null:(0,e.jsx)(Y.Z,{pb:1,pt:1,children:(0,e.jsx)(q.H,{label:"Type",items:c,selected:(u=c.length>1?r[0]:void 0)!==null&&u!==void 0?u:"all",onChange:f=>i(f==="all"?[]:[String(f)])})})};var Pt=t(32494),Ot=t(63833),J=t(79692),nt=t(77605);const Lt=(0,J.Z)({input:{}},{name:"CatalogReactEntityLifecyclePicker"}),Ft=n=>{const{initialFilter:l=[]}=n,a=Lt();return(0,e.jsx)(nt.K,{label:"Lifecycle",name:"lifecycles",path:"spec.lifecycle",Filter:F.zH,InputProps:{className:a.input},initialSelectedOptions:l})};var At=t(97894),D=t(90436),Kt=t(5806),Zt=t(21324),Rt=t(86619),Mt=t(19996),Bt=t(25505),Dt=t(38016),It=t(88013);const zt=(0,J.Z)({input:{}},{name:"CatalogReactEntityProcessingStatusPickerPicker"}),Ut=(0,e.jsx)(Bt.Z,{fontSize:"small"}),Nt=(0,e.jsx)(Mt.Z,{fontSize:"small"}),$t=()=>{const n=zt(),{updateFilters:l}=(0,O.wp)(),[a,s]=(0,v.useState)([]);function d(i){l({orphan:i?new F.mM(i):void 0})}function o(i){l({error:i?new F.A5(i):void 0})}const r=["Is Orphan","Has Error"];return(0,e.jsx)(Y.Z,{pb:1,pt:1,children:(0,e.jsxs)(D.Z,{variant:"button",component:"label",children:["Processing Status",(0,e.jsx)(It.ZP,{multiple:!0,disableCloseOnSelect:!0,options:r,value:a,onChange:(i,c)=>{s(c),d(c.includes("Is Orphan")),o(c.includes("Has Error"))},renderOption:(i,{selected:c})=>(0,e.jsx)(Kt.Z,{control:(0,e.jsx)(Zt.Z,{icon:Ut,checkedIcon:Nt,checked:c}),onClick:u=>u.preventDefault(),label:i}),size:"small",popupIcon:(0,e.jsx)(Dt.Z,{"data-testid":"processing-status-picker-expand"}),renderInput:i=>(0,e.jsx)(Rt.Z,{...i,className:n.input,variant:"outlined"})})]})})},Ht=(0,J.Z)({input:{}},{name:"CatalogReactEntityNamespacePicker"}),Wt=()=>{const n=Ht();return(0,e.jsx)(nt.K,{label:"Namespace",name:"namespace",path:"metadata.namespace",Filter:F.Qe,InputProps:{className:n.input}})};var Vt=t(65524),at=t(34106),lt=t(8709),Qt=t(74314),bt=t(538),Gt=t(9791),Xt=t(84462),R=t(86540),Yt=t(42870),st=t(75435),Jt=t(15459),k=t(93750),kt=t(27604),wt=t(2997),qt=t(11640),_t=t(28347),te=t(76635),ee=t(19928),ne=t.n(ee),ae=t(84719),ot=t(51194),it=t(7089),rt=t(59119);const g=Object.freeze({createNameColumn(n){function l(a){var s;return((s=a.metadata)===null||s===void 0?void 0:s.title)||(0,R.$)(a,{defaultKind:n==null?void 0:n.defaultKind})}return{title:"Name",field:"resolved.entityRef",highlight:!0,customSort({entity:a},{entity:s}){return l(a).localeCompare(l(s))},render:({entity:a})=>(0,e.jsx)(ae.d,{entityRef:a,defaultKind:(n==null?void 0:n.defaultKind)||"Component"})}},createSystemColumn(){return{title:"System",field:"resolved.partOfSystemRelationTitle",render:({resolved:n})=>(0,e.jsx)(ot.r,{entityRefs:n.partOfSystemRelations,defaultKind:"system"})}},createOwnerColumn(){return{title:"Owner",field:"resolved.ownedByRelationsTitle",render:({resolved:n})=>(0,e.jsx)(ot.r,{entityRefs:n.ownedByRelations,defaultKind:"group"})}},createSpecTargetsColumn(){return{title:"Targets",field:"entity.spec.targets",render:({entity:n})=>{var l,a;return(0,e.jsx)(e.Fragment,{children:((n==null||(l=n.spec)===null||l===void 0?void 0:l.targets)||(n==null||(a=n.spec)===null||a===void 0?void 0:a.target))&&(0,e.jsx)(rt.O,{text:(n.spec.targets||[n.spec.target]).join(", "),placement:"bottom-start"})})}}},createSpecTypeColumn(){return{title:"Type",field:"entity.spec.type",hidden:!0,width:"auto"}},createSpecLifecycleColumn(){return{title:"Lifecycle",field:"entity.spec.lifecycle"}},createMetadataDescriptionColumn(){return{title:"Description",field:"entity.metadata.description",render:({entity:n})=>(0,e.jsx)(rt.O,{text:n.metadata.description,placement:"bottom-start"}),width:"auto"}},createTagsColumn(){return{title:"Tags",field:"entity.metadata.tags",cellStyle:{padding:"0px 16px 0px 20px"},render:({entity:n})=>(0,e.jsx)(e.Fragment,{children:n.metadata.tags&&n.metadata.tags.map(l=>(0,e.jsx)(it.Z,{label:l,size:"small",variant:"outlined",style:{marginBottom:"0px"}},l))}),width:"auto"}},createTitleColumn(n){return{title:"Title",field:"entity.metadata.title",hidden:n==null?void 0:n.hidden,searchable:!0}},createLabelColumn(n,l){return{title:(l==null?void 0:l.title)||"Label",field:"entity.metadata.labels",cellStyle:{padding:"0px 16px 0px 20px"},render:({entity:a})=>{var s;const d=(s=a.metadata)===null||s===void 0?void 0:s.labels,o=d&&d[n]||(l==null?void 0:l.defaultValue);return(0,e.jsx)(e.Fragment,{children:o&&(0,e.jsx)(it.Z,{label:o,size:"small",variant:"outlined"},o)})},width:"auto"}},createNamespaceColumn(){return{title:"Namespace",field:"entity.metadata.namespace",width:"auto"}}}),le=(0,Jt.Z)({root:{color:"#f3ba37"}})(qt.Z),se=(n,l)=>{const a=s=>s.metadata.title||(0,R.$)(s,{defaultKind:"Component"});return a(n).localeCompare(a(l))},w=n=>{var l,a,s,d;const{columns:o,actions:r,tableOptions:i,subtitle:c,emptyContent:u}=n,{isStarredEntity:f,toggleStarredEntity:h}=(0,Yt.C)(),{loading:P,error:S,entities:x,filters:j}=(0,O.wp)(),M=(0,v.useMemo)(()=>{var m;return[g.createTitleColumn({hidden:!0}),g.createNameColumn({defaultKind:(m=j.kind)===null||m===void 0?void 0:m.value}),...y(),g.createMetadataDescriptionColumn(),g.createTagsColumn()];function y(){var p;const C=[g.createSystemColumn(),g.createOwnerColumn(),g.createSpecTypeColumn(),g.createSpecLifecycleColumn()];switch((p=j.kind)===null||p===void 0?void 0:p.value){case"user":return[];case"domain":case"system":return[g.createOwnerColumn()];case"group":case"template":return[g.createSpecTypeColumn()];case"location":return[g.createSpecTypeColumn(),g.createSpecTargetsColumn()];default:return x.every(ge=>ge.metadata.namespace==="default")?C:[...C,g.createNamespaceColumn()]}}},[(l=j.kind)===null||l===void 0?void 0:l.value,x]),A=j.type===void 0;var K;const L=(0,te.capitalize)((K=(a=j.user)===null||a===void 0?void 0:a.value)!==null&&K!==void 0?K:"all");if(S)return(0,e.jsx)("div",{children:(0,e.jsx)(bt.G,{severity:"error",title:"Could not fetch catalog entities.",children:(0,e.jsx)(Gt.O,{language:"text",text:S.toString()})})});const ve=[({entity:m})=>{var y;const p=(y=m.metadata.annotations)===null||y===void 0?void 0:y[at.l2],C="View";return{icon:()=>(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(D.Z,{style:k.Z,children:C}),(0,e.jsx)(wt.Z,{fontSize:"small"})]}),tooltip:C,disabled:!p,onClick:()=>{p&&window.open(p,"_blank")}}},({entity:m})=>{var y;const p=(y=m.metadata.annotations)===null||y===void 0?void 0:y[at.Tf],C="Edit";return{icon:()=>(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(D.Z,{style:k.Z,children:C}),(0,e.jsx)(kt.Z,{fontSize:"small"})]}),tooltip:C,disabled:!p,onClick:()=>{p&&window.open(p,"_blank")}}},({entity:m})=>{const y=f(m),p=y?"Remove from favorites":"Add to favorites";return{cellStyle:{paddingLeft:"1em"},icon:()=>(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(D.Z,{style:k.Z,children:p}),y?(0,e.jsx)(le,{}):(0,e.jsx)(_t.Z,{})]}),tooltip:p,onClick:()=>h(m)}}],vt=x.sort(se).map(m=>{const y=(0,st.h)(m,lt.cz,{kind:"system"}),p=(0,st.h)(m,lt.S4);return{entity:m,resolved:{name:(0,R.$)(m,{defaultKind:"Component"}),entityRef:(0,Qt.eE)(m),ownedByRelationsTitle:p.map(C=>(0,R.$)(C,{defaultKind:"group"})).join(", "),ownedByRelations:p,partOfSystemRelationTitle:y.map(C=>(0,R.$)(C,{defaultKind:"system"})).join(", "),partOfSystemRelations:y}}}),mt=(o||M).find(m=>m.title==="Type");mt&&(mt.hidden=!A);const me=vt.length>20,fe=((s=j.kind)===null||s===void 0?void 0:s.value)||"",pe=((d=j.type)===null||d===void 0?void 0:d.value)||"",ye=[L,pe,ne()(fe)].filter(m=>m).join(" ");return(0,e.jsx)(Xt.i,{isLoading:P,columns:o||M,options:{paging:me,pageSize:20,actionsColumnIndex:-1,loadingType:"linear",showEmptyDataSourceMessage:!P,padding:"dense",pageSizeOptions:[20,50,100],...i},title:`${ye} (${x.length})`,data:vt,actions:r||ve,subtitle:c,emptyContent:u})};w.columns=g;var oe=t(35304);const ie=(0,oe.F)({id:"catalog",messages:{catalog_page_title:"{{orgName}} Catalog",catalog_page_create_button_title:"Create"}});var re=t(58513),de=t(96253);const dt=new WeakSet,ce=n=>{const l=(0,E.h_)(re.V),a=(0,E.h_)(de.o),[s,d]=(0,v.useState)(()=>a.getTranslation(n)),o=(0,v.useMemo)(()=>a.translation$(n),[a,n]),r=(0,v.useCallback)(c=>{if(!dt.has(n)){const u=`Failed to load translation resource '${n.id}'; caused by ${c}`;console.error(u),l.post(new Error(u)),dt.add(n)}},[l,n]);(0,v.useEffect)(()=>{const c=o.subscribe({next(u){u.ready&&d(u)},error(u){r(u)}});return()=>{c.unsubscribe()}},[o,r]);const i=(0,v.useRef)(!0);if((0,v.useEffect)(()=>{i.current?i.current=!1:d(a.getTranslation(n))},[a,n]),!s.ready)throw new Promise(c=>{const u=o.subscribe({next(f){f.ready&&(u.unsubscribe(),c())},error(f){u.unsubscribe(),r(f),c()}})});return{t:s.t}};function ct(n){const{filters:l,content:a=(0,e.jsx)(w,{})}=n;var s;const d=(s=(0,E.h_)(G.D).getOptionalString("organization.name"))!==null&&s!==void 0?s:"Backstage",o=(0,Z.t)(Vt.yw),{t:r}=ce(ie);return(0,e.jsx)(z.g,{title:r("catalog_page_title",{orgName:d}),themeId:"home",children:(0,e.jsxs)(U.V,{children:[(0,e.jsxs)(N.y,{title:"",children:[(0,e.jsx)(Q,{title:r("catalog_page_create_button_title"),to:o&&o()}),(0,e.jsx)(b.q,{children:"All your software catalog entities"})]}),(0,e.jsx)(O.UO,{children:(0,e.jsxs)(X._i,{children:[(0,e.jsx)(X._i.Filters,{children:l}),(0,e.jsx)(X._i.Content,{children:a})]})})]})})}function ut(n){const{columns:l,actions:a,initiallySelectedFilter:s="owned",initialKind:d="component",tableOptions:o={},emptyContent:r,ownerPickerMode:i}=n;return(0,e.jsx)(ct,{filters:(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(ht,{initialFilter:d}),(0,e.jsx)(Tt,{}),(0,e.jsx)(Pt.E,{initialFilter:s}),(0,e.jsx)(Ot.d,{mode:i}),(0,e.jsx)(Ft,{}),(0,e.jsx)(At.x,{}),(0,e.jsx)($t,{}),(0,e.jsx)(Wt,{})]}),content:(0,e.jsx)(w,{columns:l,actions:a,tableOptions:o,emptyContent:r})})}function ue(n){return(0,I.pC)()||(0,e.jsx)(ut,{...n})}}}]);})();
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=1600.ec5e759e.chunk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static/1600.ec5e759e.chunk.js","mappings":"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","sources":["webpack://techdocs-cli-embedded-app/../core-components/src/components/OverflowTooltip/OverflowTooltip.tsx","webpack://techdocs-cli-embedded-app/../core-components/src/components/CreateButton/CreateButton.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/kindFilterUtils.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityKindPicker/EntityKindPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/hooks/useEntityTypeFilter.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityTypePicker/EntityTypePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityLifecyclePicker/EntityLifecyclePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityProcessingStatusPicker/EntityProcessingStatusPicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog-react/src/components/EntityNamespacePicker/EntityNamespacePicker.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/columns.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogTable/CatalogTable.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/translation.ts","webpack://techdocs-cli-embedded-app/../core-plugin-api/src/translation/useTranslationRef.ts","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/catalog/src/components/CatalogPage/CatalogPage.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Tooltip, { TooltipProps } from '@material-ui/core/Tooltip';\nimport React, { useState } from 'react';\nimport TextTruncate, { TextTruncateProps } from 'react-text-truncate';\nimport { useIsMounted } from '@react-hookz/web';\n\ntype Props = {\n text: TextTruncateProps['text'];\n line?: TextTruncateProps['line'];\n element?: TextTruncateProps['element'];\n title?: TooltipProps['title'];\n placement?: TooltipProps['placement'];\n};\n\nexport type OverflowTooltipClassKey = 'container';\n\nconst useStyles = makeStyles(\n {\n container: {\n overflow: 'visible !important',\n },\n },\n { name: 'BackstageOverflowTooltip' },\n);\n\nexport function OverflowTooltip(props: Props) {\n const [hover, setHover] = useState(false);\n const isMounted = useIsMounted();\n const classes = useStyles();\n\n const handleToggled = (truncated: boolean) => {\n if (isMounted()) {\n setHover(truncated);\n }\n };\n\n return (\n <Tooltip\n title={props.title ?? (props.text || '')}\n placement={props.placement}\n disableHoverListener={!hover}\n >\n <TextTruncate\n text={props.text}\n line={props.line}\n onToggled={handleToggled}\n containerClassName={classes.container}\n />\n </Tooltip>\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { BackstageTheme } from '@backstage/theme';\nimport Button from '@material-ui/core/Button';\nimport IconButton from '@material-ui/core/IconButton';\nimport useMediaQuery from '@material-ui/core/useMediaQuery';\nimport React from 'react';\nimport { Link as RouterLink, LinkProps } from 'react-router-dom';\nimport AddCircleOutline from '@material-ui/icons/AddCircleOutline';\n\n/**\n * Properties for {@link CreateButton}\n *\n * @public\n */\nexport type CreateButtonProps = {\n title: string;\n} & Partial<Pick<LinkProps, 'to'>>;\n\n/**\n * Responsive Button giving consistent UX for creation of different things\n *\n * @public\n */\nexport function CreateButton(props: CreateButtonProps) {\n const { title, to } = props;\n const isXSScreen = useMediaQuery<BackstageTheme>(theme =>\n theme.breakpoints.down('xs'),\n );\n\n if (!to) {\n return null;\n }\n\n return isXSScreen ? (\n <IconButton\n component={RouterLink}\n color=\"primary\"\n title={title}\n size=\"small\"\n to={to}\n >\n <AddCircleOutline />\n </IconButton>\n ) : (\n <Button component={RouterLink} variant=\"contained\" color=\"primary\" to={to}>\n {title}\n </Button>\n );\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport useAsync from 'react-use/lib/useAsync';\nimport { catalogApiRef } from '../../api';\n\n/**\n * Fetch and return all availible kinds.\n */\nexport function useAllKinds(): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n} {\n const catalogApi = useApi(catalogApiRef);\n\n const {\n error,\n loading,\n value: allKinds,\n } = useAsync(async () => {\n const items = await catalogApi\n .getEntityFacets({ facets: ['kind'] })\n .then(response => response.facets.kind?.map(f => f.value).sort() || []);\n return items;\n }, [catalogApi]);\n\n return { loading, error, allKinds: allKinds ?? [] };\n}\n\n/**\n * Filter and capitalize accessible kinds.\n */\nexport function filterKinds(\n allKinds: string[],\n allowedKinds?: string[],\n forcedKinds?: string,\n): Record<string, string> {\n // Before allKinds is loaded, or when a kind is entered manually in the URL, selectedKind may not\n // be present in allKinds. It should still be shown in the dropdown, but may not have the nice\n // enforced casing from the catalog-backend. This makes a key/value record for the Select options,\n // including selectedKind if it's unknown - but allows the selectedKind to get clobbered by the\n // more proper catalog kind if it exists.\n let availableKinds = allKinds;\n if (allowedKinds) {\n availableKinds = availableKinds.filter(k =>\n allowedKinds.some(\n a => a.toLocaleLowerCase('en-US') === k.toLocaleLowerCase('en-US'),\n ),\n );\n }\n if (\n forcedKinds &&\n !allKinds.some(\n a =>\n a.toLocaleLowerCase('en-US') === forcedKinds.toLocaleLowerCase('en-US'),\n )\n ) {\n availableKinds = availableKinds.concat([forcedKinds]);\n }\n\n const kindsMap = availableKinds.sort().reduce((acc, kind) => {\n acc[kind.toLocaleLowerCase('en-US')] = kind;\n return acc;\n }, {} as Record<string, string>);\n\n return kindsMap;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Select } from '@backstage/core-components';\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Box } from '@material-ui/core';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport { EntityKindFilter } from '../../filters';\nimport { useEntityList } from '../../hooks';\nimport { filterKinds, useAllKinds } from './kindFilterUtils';\n\nfunction useEntityKindFilter(opts: { initialFilter: string }): {\n loading: boolean;\n error?: Error;\n allKinds: string[];\n selectedKind: string;\n setSelectedKind: (kind: string) => void;\n} {\n const {\n filters,\n queryParameters: { kind: kindParameter },\n updateFilters,\n } = useEntityList();\n\n const queryParamKind = useMemo(\n () => [kindParameter].flat()[0],\n [kindParameter],\n );\n\n const [selectedKind, setSelectedKind] = useState(\n queryParamKind ?? filters.kind?.value ?? opts.initialFilter,\n );\n\n // Set selected kinds on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (queryParamKind) {\n setSelectedKind(queryParamKind);\n }\n }, [queryParamKind]);\n\n // Set selected kind from filters; this happens when the kind filter is\n // updated from another component\n useEffect(() => {\n if (filters.kind?.value) {\n setSelectedKind(filters.kind?.value);\n }\n }, [filters.kind]);\n\n useEffect(() => {\n updateFilters({\n kind: selectedKind ? new EntityKindFilter(selectedKind) : undefined,\n });\n }, [selectedKind, updateFilters]);\n\n const { allKinds, loading, error } = useAllKinds();\n\n return {\n loading,\n error,\n allKinds: allKinds ?? [],\n selectedKind,\n setSelectedKind,\n };\n}\n\n/**\n * Props for {@link EntityKindPicker}.\n *\n * @public\n */\nexport interface EntityKindPickerProps {\n /**\n * Entity kinds to show in the dropdown; by default all kinds are fetched from the catalog and\n * displayed.\n */\n allowedKinds?: string[];\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityKindPicker = (props: EntityKindPickerProps) => {\n const { allowedKinds, hidden, initialFilter = 'component' } = props;\n\n const alertApi = useApi(alertApiRef);\n\n const { error, allKinds, selectedKind, setSelectedKind } =\n useEntityKindFilter({\n initialFilter: initialFilter,\n });\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load entity kinds`,\n severity: 'error',\n });\n }\n }, [error, alertApi]);\n\n if (error) return null;\n\n const options = filterKinds(allKinds, allowedKinds, selectedKind);\n\n const items = Object.keys(options).map(key => ({\n value: key,\n label: options[key],\n }));\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label=\"Kind\"\n items={items}\n selected={selectedKind.toLocaleLowerCase('en-US')}\n onChange={value => setSelectedKind(String(value))}\n />\n </Box>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport useAsync from 'react-use/lib/useAsync';\nimport isEqual from 'lodash/isEqual';\nimport sortBy from 'lodash/sortBy';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { catalogApiRef } from '../api';\nimport { useEntityList } from './useEntityListProvider';\nimport { EntityTypeFilter } from '../filters';\n\n/**\n * A hook built on top of `useEntityList` for enabling selection of valid `spec.type` values\n * based on the selected EntityKindFilter.\n * @public\n */\nexport function useEntityTypeFilter(): {\n loading: boolean;\n error?: Error;\n availableTypes: string[];\n selectedTypes: string[];\n setSelectedTypes: (types: string[]) => void;\n} {\n const catalogApi = useApi(catalogApiRef);\n const {\n filters: { kind: kindFilter, type: typeFilter },\n queryParameters: { type: typeParameter },\n updateFilters,\n } = useEntityList();\n\n const flattenedQueryTypes = useMemo(\n () => [typeParameter].flat().filter(Boolean) as string[],\n [typeParameter],\n );\n\n const [selectedTypes, setSelectedTypes] = useState(\n flattenedQueryTypes.length\n ? flattenedQueryTypes\n : typeFilter?.getTypes() ?? [],\n );\n\n // Set selected types on query parameter updates; this happens at initial page load and from\n // external updates to the page location.\n useEffect(() => {\n if (flattenedQueryTypes.length) {\n setSelectedTypes(flattenedQueryTypes);\n }\n }, [flattenedQueryTypes]);\n\n const [availableTypes, setAvailableTypes] = useState<string[]>([]);\n const kind = useMemo(() => kindFilter?.value, [kindFilter]);\n\n // Load all valid spec.type values straight from the catalogApi, paying attention to only the\n // kind filter for a complete list.\n const {\n error,\n loading,\n value: facets,\n } = useAsync(async () => {\n if (kind) {\n const items = await catalogApi\n .getEntityFacets({\n filter: { kind },\n facets: ['spec.type'],\n })\n .then(response => response.facets['spec.type'] || []);\n return items;\n }\n return [];\n }, [kind, catalogApi]);\n\n const facetsRef = useRef(facets);\n useEffect(() => {\n const oldFacets = facetsRef.current;\n facetsRef.current = facets;\n // Delay processing hook until kind and facets load updates have settled to generate list of types;\n // This prevents resetting the type filter due to saved type value from query params not matching the\n // empty set of type values while values are still being loaded; also only run this hook on changes\n // to facets\n if (loading || !kind || oldFacets === facets || !facets) {\n return;\n }\n\n // Sort by facet count descending, so the most common types appear on top\n const newTypes = [\n ...new Set(\n sortBy(facets, f => -f.count).map(f =>\n f.value.toLocaleLowerCase('en-US'),\n ),\n ),\n ];\n setAvailableTypes(newTypes);\n\n // Update type filter to only valid values when the list of available types has changed\n const stillValidTypes = selectedTypes.filter(value =>\n newTypes.includes(value),\n );\n if (!isEqual(selectedTypes, stillValidTypes)) {\n setSelectedTypes(stillValidTypes);\n }\n }, [loading, kind, selectedTypes, setSelectedTypes, facets]);\n\n useEffect(() => {\n updateFilters({\n type: selectedTypes.length\n ? new EntityTypeFilter(selectedTypes)\n : undefined,\n });\n }, [selectedTypes, updateFilters]);\n\n return {\n loading,\n error,\n availableTypes,\n selectedTypes,\n setSelectedTypes,\n };\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect } from 'react';\nimport { Box } from '@material-ui/core';\nimport { useEntityTypeFilter } from '../../hooks/useEntityTypeFilter';\n\nimport { alertApiRef, useApi } from '@backstage/core-plugin-api';\nimport { Select } from '@backstage/core-components';\n\n/**\n * Props for {@link EntityTypePicker}.\n *\n * @public\n */\nexport interface EntityTypePickerProps {\n initialFilter?: string;\n hidden?: boolean;\n}\n\n/** @public */\nexport const EntityTypePicker = (props: EntityTypePickerProps) => {\n const { hidden, initialFilter } = props;\n const alertApi = useApi(alertApiRef);\n const { error, availableTypes, selectedTypes, setSelectedTypes } =\n useEntityTypeFilter();\n\n useEffect(() => {\n if (error) {\n alertApi.post({\n message: `Failed to load entity types`,\n severity: 'error',\n });\n }\n if (initialFilter) {\n setSelectedTypes([initialFilter]);\n }\n }, [error, alertApi, initialFilter, setSelectedTypes]);\n\n if (availableTypes.length === 0 || error) return null;\n\n const items = [\n { value: 'all', label: 'all' },\n ...availableTypes.map((type: string) => ({\n value: type,\n label: type,\n })),\n ];\n\n return hidden ? null : (\n <Box pb={1} pt={1}>\n <Select\n label=\"Type\"\n items={items}\n selected={(items.length > 1 ? selectedTypes[0] : undefined) ?? 'all'}\n onChange={value =>\n setSelectedTypes(value === 'all' ? [] : [String(value)])\n }\n />\n </Box>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core';\nimport React from 'react';\nimport { EntityLifecycleFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\n\n/** @public */\nexport type CatalogReactEntityLifecyclePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n {\n name: 'CatalogReactEntityLifecyclePicker',\n },\n);\n\n/** @public */\nexport const EntityLifecyclePicker = (props: { initialFilter?: string[] }) => {\n const { initialFilter = [] } = props;\n const classes = useStyles();\n\n return (\n <EntityAutocompletePicker\n label=\"Lifecycle\"\n name=\"lifecycles\"\n path=\"spec.lifecycle\"\n Filter={EntityLifecycleFilter}\n InputProps={{ className: classes.input }}\n initialSelectedOptions={initialFilter}\n />\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { EntityErrorFilter, EntityOrphanFilter } from '../../filters';\nimport {\n Box,\n Checkbox,\n FormControlLabel,\n makeStyles,\n TextField,\n Typography,\n} from '@material-ui/core';\nimport CheckBoxIcon from '@material-ui/icons/CheckBox';\nimport CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport React, { useState } from 'react';\nimport { useEntityList } from '../../hooks';\nimport { Autocomplete } from '@material-ui/lab';\n\n/** @public */\nexport type CatalogReactEntityProcessingStatusPickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n {\n name: 'CatalogReactEntityProcessingStatusPickerPicker',\n },\n);\n\nconst icon = <CheckBoxOutlineBlankIcon fontSize=\"small\" />;\nconst checkedIcon = <CheckBoxIcon fontSize=\"small\" />;\n\n/** @public */\nexport const EntityProcessingStatusPicker = () => {\n const classes = useStyles();\n const { updateFilters } = useEntityList();\n\n const [selectedAdvancedItems, setSelectedAdvancedItems] = useState<string[]>(\n [],\n );\n\n function orphanChange(value: boolean) {\n updateFilters({\n orphan: value ? new EntityOrphanFilter(value) : undefined,\n });\n }\n\n function errorChange(value: boolean) {\n updateFilters({\n error: value ? new EntityErrorFilter(value) : undefined,\n });\n }\n\n const availableAdvancedItems = ['Is Orphan', 'Has Error'];\n\n return (\n <Box pb={1} pt={1}>\n <Typography variant=\"button\" component=\"label\">\n Processing Status\n <Autocomplete\n multiple\n disableCloseOnSelect\n options={availableAdvancedItems}\n value={selectedAdvancedItems}\n onChange={(_: object, value: string[]) => {\n setSelectedAdvancedItems(value);\n orphanChange(value.includes('Is Orphan'));\n errorChange(value.includes('Has Error'));\n }}\n renderOption={(option, { selected }) => (\n <FormControlLabel\n control={\n <Checkbox\n icon={icon}\n checkedIcon={checkedIcon}\n checked={selected}\n />\n }\n onClick={event => event.preventDefault()}\n label={option}\n />\n )}\n size=\"small\"\n popupIcon={\n <ExpandMoreIcon data-testid=\"processing-status-picker-expand\" />\n }\n renderInput={params => (\n <TextField\n {...params}\n className={classes.input}\n variant=\"outlined\"\n />\n )}\n />\n </Typography>\n </Box>\n );\n};\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { makeStyles } from '@material-ui/core';\n\nimport React from 'react';\nimport { EntityNamespaceFilter } from '../../filters';\nimport { EntityAutocompletePicker } from '../EntityAutocompletePicker';\n\n/** @public */\nexport type CatalogReactEntityNamespacePickerClassKey = 'input';\n\nconst useStyles = makeStyles(\n {\n input: {},\n },\n {\n name: 'CatalogReactEntityNamespacePicker',\n },\n);\n\n/** @public */\nexport const EntityNamespacePicker = () => {\n const classes = useStyles();\n return (\n <EntityAutocompletePicker\n label=\"Namespace\"\n name=\"namespace\"\n path=\"metadata.namespace\"\n Filter={EntityNamespaceFilter}\n InputProps={{ className: classes.input }}\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n humanizeEntityRef,\n EntityRefLink,\n EntityRefLinks,\n} from '@backstage/plugin-catalog-react';\nimport { Chip } from '@material-ui/core';\nimport { CatalogTableRow } from './types';\nimport { OverflowTooltip, TableColumn } from '@backstage/core-components';\nimport { Entity } from '@backstage/catalog-model';\nimport { JsonArray } from '@backstage/types';\n\n// The columnFactories symbol is not directly exported, but through the\n// CatalogTable.columns field.\n/** @public */\nexport const columnFactories = Object.freeze({\n createNameColumn(options?: {\n defaultKind?: string;\n }): TableColumn<CatalogTableRow> {\n function formatContent(entity: Entity): string {\n return (\n entity.metadata?.title ||\n humanizeEntityRef(entity, {\n defaultKind: options?.defaultKind,\n })\n );\n }\n\n return {\n title: 'Name',\n field: 'resolved.entityRef',\n highlight: true,\n customSort({ entity: entity1 }, { entity: entity2 }) {\n // TODO: We could implement this more efficiently by comparing field by field.\n // This has similar issues as above.\n return formatContent(entity1).localeCompare(formatContent(entity2));\n },\n render: ({ entity }) => (\n <EntityRefLink\n entityRef={entity}\n defaultKind={options?.defaultKind || 'Component'}\n />\n ),\n };\n },\n createSystemColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'System',\n field: 'resolved.partOfSystemRelationTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.partOfSystemRelations}\n defaultKind=\"system\"\n />\n ),\n };\n },\n createOwnerColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Owner',\n field: 'resolved.ownedByRelationsTitle',\n render: ({ resolved }) => (\n <EntityRefLinks\n entityRefs={resolved.ownedByRelations}\n defaultKind=\"group\"\n />\n ),\n };\n },\n createSpecTargetsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Targets',\n field: 'entity.spec.targets',\n render: ({ entity }) => (\n <>\n {(entity?.spec?.targets || entity?.spec?.target) && (\n <OverflowTooltip\n text={(\n (entity!.spec!.targets as JsonArray) || [entity.spec.target]\n ).join(', ')}\n placement=\"bottom-start\"\n />\n )}\n </>\n ),\n };\n },\n createSpecTypeColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Type',\n field: 'entity.spec.type',\n hidden: true,\n width: 'auto',\n };\n },\n createSpecLifecycleColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Lifecycle',\n field: 'entity.spec.lifecycle',\n };\n },\n createMetadataDescriptionColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Description',\n field: 'entity.metadata.description',\n render: ({ entity }) => (\n <OverflowTooltip\n text={entity.metadata.description}\n placement=\"bottom-start\"\n />\n ),\n width: 'auto',\n };\n },\n createTagsColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Tags',\n field: 'entity.metadata.tags',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }) => (\n <>\n {entity.metadata.tags &&\n entity.metadata.tags.map(t => (\n <Chip\n key={t}\n label={t}\n size=\"small\"\n variant=\"outlined\"\n style={{ marginBottom: '0px' }}\n />\n ))}\n </>\n ),\n width: 'auto',\n };\n },\n createTitleColumn(options?: {\n hidden?: boolean;\n }): TableColumn<CatalogTableRow> {\n return {\n title: 'Title',\n field: 'entity.metadata.title',\n hidden: options?.hidden,\n searchable: true,\n };\n },\n createLabelColumn(\n key: string,\n options?: { title?: string; defaultValue?: string },\n ): TableColumn<CatalogTableRow> {\n return {\n title: options?.title || 'Label',\n field: 'entity.metadata.labels',\n cellStyle: {\n padding: '0px 16px 0px 20px',\n },\n render: ({ entity }: { entity: Entity }) => {\n const labels: Record<string, string> | undefined =\n entity.metadata?.labels;\n const specifiedLabelValue =\n (labels && labels[key]) || options?.defaultValue;\n return (\n <>\n {specifiedLabelValue && (\n <Chip\n key={specifiedLabelValue}\n label={specifiedLabelValue}\n size=\"small\"\n variant=\"outlined\"\n />\n )}\n </>\n );\n },\n width: 'auto',\n };\n },\n createNamespaceColumn(): TableColumn<CatalogTableRow> {\n return {\n title: 'Namespace',\n field: 'entity.metadata.namespace',\n width: 'auto',\n };\n },\n});\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n ANNOTATION_EDIT_URL,\n ANNOTATION_VIEW_URL,\n Entity,\n RELATION_OWNED_BY,\n RELATION_PART_OF,\n stringifyEntityRef,\n} from '@backstage/catalog-model';\nimport {\n CodeSnippet,\n Table,\n TableColumn,\n TableProps,\n WarningPanel,\n} from '@backstage/core-components';\nimport {\n getEntityRelations,\n humanizeEntityRef,\n useEntityList,\n useStarredEntities,\n} from '@backstage/plugin-catalog-react';\nimport Typography from '@material-ui/core/Typography';\nimport { withStyles } from '@material-ui/core/styles';\nimport { visuallyHidden } from '@mui/utils';\nimport Edit from '@material-ui/icons/Edit';\nimport OpenInNew from '@material-ui/icons/OpenInNew';\nimport Star from '@material-ui/icons/Star';\nimport StarBorder from '@material-ui/icons/StarBorder';\nimport { capitalize } from 'lodash';\nimport pluralize from 'pluralize';\nimport React, { ReactNode, useMemo } from 'react';\nimport { columnFactories } from './columns';\nimport { CatalogTableRow } from './types';\n\n/**\n * Props for {@link CatalogTable}.\n *\n * @public\n */\nexport interface CatalogTableProps {\n columns?: TableColumn<CatalogTableRow>[];\n actions?: TableProps<CatalogTableRow>['actions'];\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n subtitle?: string;\n}\n\nconst YellowStar = withStyles({\n root: {\n color: '#f3ba37',\n },\n})(Star);\n\nconst refCompare = (a: Entity, b: Entity) => {\n const toRef = (entity: Entity) =>\n entity.metadata.title ||\n humanizeEntityRef(entity, {\n defaultKind: 'Component',\n });\n\n return toRef(a).localeCompare(toRef(b));\n};\n\n/** @public */\nexport const CatalogTable = (props: CatalogTableProps) => {\n const { columns, actions, tableOptions, subtitle, emptyContent } = props;\n const { isStarredEntity, toggleStarredEntity } = useStarredEntities();\n const { loading, error, entities, filters } = useEntityList();\n\n const defaultColumns: TableColumn<CatalogTableRow>[] = useMemo(() => {\n return [\n columnFactories.createTitleColumn({ hidden: true }),\n columnFactories.createNameColumn({ defaultKind: filters.kind?.value }),\n ...createEntitySpecificColumns(),\n columnFactories.createMetadataDescriptionColumn(),\n columnFactories.createTagsColumn(),\n ];\n\n function createEntitySpecificColumns(): TableColumn<CatalogTableRow>[] {\n const baseColumns = [\n columnFactories.createSystemColumn(),\n columnFactories.createOwnerColumn(),\n columnFactories.createSpecTypeColumn(),\n columnFactories.createSpecLifecycleColumn(),\n ];\n switch (filters.kind?.value) {\n case 'user':\n return [];\n case 'domain':\n case 'system':\n return [columnFactories.createOwnerColumn()];\n case 'group':\n case 'template':\n return [columnFactories.createSpecTypeColumn()];\n case 'location':\n return [\n columnFactories.createSpecTypeColumn(),\n columnFactories.createSpecTargetsColumn(),\n ];\n default:\n return entities.every(\n entity => entity.metadata.namespace === 'default',\n )\n ? baseColumns\n : [...baseColumns, columnFactories.createNamespaceColumn()];\n }\n }\n }, [filters.kind?.value, entities]);\n\n const showTypeColumn = filters.type === undefined;\n // TODO(timbonicus): remove the title from the CatalogTable once using EntitySearchBar\n const titlePreamble = capitalize(filters.user?.value ?? 'all');\n\n if (error) {\n return (\n <div>\n <WarningPanel\n severity=\"error\"\n title=\"Could not fetch catalog entities.\"\n >\n <CodeSnippet language=\"text\" text={error.toString()} />\n </WarningPanel>\n </div>\n );\n }\n\n const defaultActions: TableProps<CatalogTableRow>['actions'] = [\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_VIEW_URL];\n const title = 'View';\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <OpenInNew fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const url = entity.metadata.annotations?.[ANNOTATION_EDIT_URL];\n const title = 'Edit';\n\n return {\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n <Edit fontSize=\"small\" />\n </>\n ),\n tooltip: title,\n disabled: !url,\n onClick: () => {\n if (!url) return;\n window.open(url, '_blank');\n },\n };\n },\n ({ entity }) => {\n const isStarred = isStarredEntity(entity);\n const title = isStarred ? 'Remove from favorites' : 'Add to favorites';\n\n return {\n cellStyle: { paddingLeft: '1em' },\n icon: () => (\n <>\n <Typography style={visuallyHidden}>{title}</Typography>\n {isStarred ? <YellowStar /> : <StarBorder />}\n </>\n ),\n tooltip: title,\n onClick: () => toggleStarredEntity(entity),\n };\n },\n ];\n\n const rows = entities.sort(refCompare).map(entity => {\n const partOfSystemRelations = getEntityRelations(entity, RELATION_PART_OF, {\n kind: 'system',\n });\n const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY);\n\n return {\n entity,\n resolved: {\n // This name is here for backwards compatibility mostly; the\n // presentation of refs in the table should in general be handled with\n // EntityRefLink / EntityName components\n name: humanizeEntityRef(entity, {\n defaultKind: 'Component',\n }),\n entityRef: stringifyEntityRef(entity),\n ownedByRelationsTitle: ownedByRelations\n .map(r => humanizeEntityRef(r, { defaultKind: 'group' }))\n .join(', '),\n ownedByRelations,\n partOfSystemRelationTitle: partOfSystemRelations\n .map(r =>\n humanizeEntityRef(r, {\n defaultKind: 'system',\n }),\n )\n .join(', '),\n partOfSystemRelations,\n },\n };\n });\n\n const typeColumn = (columns || defaultColumns).find(c => c.title === 'Type');\n if (typeColumn) {\n typeColumn.hidden = !showTypeColumn;\n }\n const showPagination = rows.length > 20;\n const currentKind = filters.kind?.value || '';\n const currentType = filters.type?.value || '';\n const titleDisplay = [titlePreamble, currentType, pluralize(currentKind)]\n .filter(s => s)\n .join(' ');\n\n return (\n <Table<CatalogTableRow>\n isLoading={loading}\n columns={columns || defaultColumns}\n options={{\n paging: showPagination,\n pageSize: 20,\n actionsColumnIndex: -1,\n loadingType: 'linear',\n showEmptyDataSourceMessage: !loading,\n padding: 'dense',\n pageSizeOptions: [20, 50, 100],\n ...tableOptions,\n }}\n title={`${titleDisplay} (${entities.length})`}\n data={rows}\n actions={actions || defaultActions}\n subtitle={subtitle}\n emptyContent={emptyContent}\n />\n );\n};\n\nCatalogTable.columns = columnFactories;\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { createTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @alpha */\nexport const catalogTranslationRef = createTranslationRef({\n id: 'catalog',\n messages: {\n catalog_page_title: `{{orgName}} Catalog`,\n catalog_page_create_button_title: 'Create',\n },\n});\n","/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { errorApiRef, useApi } from '../apis';\nimport {\n translationApiRef,\n TranslationFunction,\n TranslationSnapshot,\n} from '../apis/alpha';\nimport { TranslationRef } from './TranslationRef';\n\n// Make sure we don't fill the logs with loading errors for the same ref\nconst loggedRefs = new WeakSet<TranslationRef<string, {}>>();\n\n/** @alpha */\nexport const useTranslationRef = <\n TMessages extends { [key in string]: string },\n>(\n translationRef: TranslationRef<string, TMessages>,\n): { t: TranslationFunction<TMessages> } => {\n const errorApi = useApi(errorApiRef);\n const translationApi = useApi(translationApiRef);\n\n const [snapshot, setSnapshot] = useState<TranslationSnapshot<TMessages>>(() =>\n translationApi.getTranslation(translationRef),\n );\n const observable = useMemo(\n () => translationApi.translation$(translationRef),\n [translationApi, translationRef],\n );\n\n const onError = useCallback(\n (error: Error) => {\n if (!loggedRefs.has(translationRef)) {\n const errMsg = `Failed to load translation resource '${translationRef.id}'; caused by ${error}`;\n // eslint-disable-next-line no-console\n console.error(errMsg);\n errorApi.post(new Error(errMsg));\n loggedRefs.add(translationRef);\n }\n },\n [errorApi, translationRef],\n );\n\n useEffect(() => {\n const subscription = observable.subscribe({\n next(next) {\n if (next.ready) {\n setSnapshot(next);\n }\n },\n error(error) {\n onError(error);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [observable, onError]);\n\n // Keep track of if the provided translation ref changes, and in that case update the snapshot\n const initialRenderRef = useRef(true);\n useEffect(() => {\n if (initialRenderRef.current) {\n initialRenderRef.current = false;\n } else {\n setSnapshot(translationApi.getTranslation(translationRef));\n }\n }, [translationApi, translationRef]);\n\n if (!snapshot.ready) {\n throw new Promise<void>(resolve => {\n const subscription = observable.subscribe({\n next(next) {\n if (next.ready) {\n subscription.unsubscribe();\n resolve();\n }\n },\n error(error) {\n subscription.unsubscribe();\n onError(error);\n resolve();\n },\n });\n });\n }\n\n return { t: snapshot.t };\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n Content,\n ContentHeader,\n CreateButton,\n PageWithHeader,\n SupportButton,\n TableColumn,\n TableProps,\n} from '@backstage/core-components';\nimport { configApiRef, useApi, useRouteRef } from '@backstage/core-plugin-api';\nimport {\n CatalogFilterLayout,\n EntityLifecyclePicker,\n EntityListProvider,\n EntityProcessingStatusPicker,\n EntityOwnerPicker,\n EntityTagPicker,\n EntityTypePicker,\n UserListFilterKind,\n UserListPicker,\n EntityKindPicker,\n EntityNamespacePicker,\n EntityOwnerPickerProps,\n} from '@backstage/plugin-catalog-react';\nimport React, { ReactNode } from 'react';\nimport { createComponentRouteRef } from '../../routes';\nimport { CatalogTable, CatalogTableRow } from '../CatalogTable';\nimport { catalogTranslationRef } from '../../translation';\nimport { useTranslationRef } from '@backstage/core-plugin-api/alpha';\n\n/** @internal */\nexport interface BaseCatalogPageProps {\n filters: ReactNode;\n content?: ReactNode;\n}\n\n/** @internal */\nexport function BaseCatalogPage(props: BaseCatalogPageProps) {\n const { filters, content = <CatalogTable /> } = props;\n const orgName =\n useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage';\n const createComponentLink = useRouteRef(createComponentRouteRef);\n const { t } = useTranslationRef(catalogTranslationRef);\n\n return (\n <PageWithHeader title={t('catalog_page_title', { orgName })} themeId=\"home\">\n <Content>\n <ContentHeader title=\"\">\n <CreateButton\n title={t('catalog_page_create_button_title')}\n to={createComponentLink && createComponentLink()}\n />\n <SupportButton>All your software catalog entities</SupportButton>\n </ContentHeader>\n <EntityListProvider>\n <CatalogFilterLayout>\n <CatalogFilterLayout.Filters>{filters}</CatalogFilterLayout.Filters>\n <CatalogFilterLayout.Content>{content}</CatalogFilterLayout.Content>\n </CatalogFilterLayout>\n </EntityListProvider>\n </Content>\n </PageWithHeader>\n );\n}\n\n/**\n * Props for root catalog pages.\n *\n * @public\n */\nexport interface DefaultCatalogPageProps {\n initiallySelectedFilter?: UserListFilterKind;\n columns?: TableColumn<CatalogTableRow>[];\n actions?: TableProps<CatalogTableRow>['actions'];\n initialKind?: string;\n tableOptions?: TableProps<CatalogTableRow>['options'];\n emptyContent?: ReactNode;\n ownerPickerMode?: EntityOwnerPickerProps['mode'];\n}\n\nexport function DefaultCatalogPage(props: DefaultCatalogPageProps) {\n const {\n columns,\n actions,\n initiallySelectedFilter = 'owned',\n initialKind = 'component',\n tableOptions = {},\n emptyContent,\n ownerPickerMode,\n } = props;\n\n return (\n <BaseCatalogPage\n filters={\n <>\n <EntityKindPicker initialFilter={initialKind} />\n <EntityTypePicker />\n <UserListPicker initialFilter={initiallySelectedFilter} />\n <EntityOwnerPicker mode={ownerPickerMode} />\n <EntityLifecyclePicker />\n <EntityTagPicker />\n <EntityProcessingStatusPicker />\n <EntityNamespacePicker />\n </>\n }\n content={\n <CatalogTable\n columns={columns}\n actions={actions}\n tableOptions={tableOptions}\n emptyContent={emptyContent}\n />\n }\n />\n );\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { useOutlet } from 'react-router-dom';\nimport {\n DefaultCatalogPage,\n DefaultCatalogPageProps,\n} from './DefaultCatalogPage';\n\nexport function CatalogPage(props: DefaultCatalogPageProps) {\n const outlet = useOutlet();\n\n return outlet || <DefaultCatalogPage {...props} />;\n}\n"],"names":["useStyles","makeStyles","container","overflow","name","OverflowTooltip","props","hover","setHover","useState","isMounted","useIsMounted","classes","handleToggled","truncated","Tooltip","title","text","placement","disableHoverListener","TextTruncate","line","onToggled","containerClassName","CreateButton","to","isXSScreen","useMediaQuery","theme","breakpoints","down","IconButton","component","RouterLink","color","size","AddCircleOutline","Button","variant","useAllKinds","catalogApi","useApi","catalogApiRef","error","loading","value","allKinds","useAsync","getEntityFacets","facets","then","response","kind","map","f","sort","filterKinds","allowedKinds","forcedKinds","availableKinds","filter","k","some","a","toLocaleLowerCase","concat","reduce","acc","useEntityKindFilter","opts","filters","queryParameters","kindParameter","updateFilters","useEntityList","queryParamKind","useMemo","flat","selectedKind","setSelectedKind","initialFilter","useEffect","EntityKindFilter","undefined","EntityKindPicker","hidden","alertApi","alertApiRef","post","message","severity","options","items","Object","keys","key","label","Box","pb","pt","Select","selected","onChange","String","useEntityTypeFilter","kindFilter","type","typeFilter","typeParameter","flattenedQueryTypes","Boolean","selectedTypes","setSelectedTypes","length","getTypes","availableTypes","setAvailableTypes","facetsRef","useRef","oldFacets","current","newTypes","Set","sortBy","count","stillValidTypes","includes","isEqual","EntityTypeFilter","EntityTypePicker","input","EntityLifecyclePicker","EntityAutocompletePicker","path","Filter","EntityLifecycleFilter","InputProps","className","initialSelectedOptions","icon","CheckBoxOutlineBlankIcon","fontSize","checkedIcon","CheckBoxIcon","EntityProcessingStatusPicker","selectedAdvancedItems","setSelectedAdvancedItems","orphanChange","orphan","EntityOrphanFilter","errorChange","EntityErrorFilter","availableAdvancedItems","Typography","Autocomplete","multiple","disableCloseOnSelect","_","renderOption","option","FormControlLabel","control","Checkbox","checked","onClick","event","preventDefault","popupIcon","ExpandMoreIcon","data-testid","renderInput","params","TextField","EntityNamespacePicker","EntityNamespaceFilter","columnFactories","freeze","createNameColumn","formatContent","entity","metadata","humanizeEntityRef","defaultKind","field","highlight","customSort","entity1","entity2","localeCompare","render","EntityRefLink","entityRef","createSystemColumn","resolved","EntityRefLinks","entityRefs","partOfSystemRelations","createOwnerColumn","ownedByRelations","createSpecTargetsColumn","spec","targets","target","join","createSpecTypeColumn","width","createSpecLifecycleColumn","createMetadataDescriptionColumn","description","createTagsColumn","cellStyle","padding","tags","t","Chip","style","marginBottom","createTitleColumn","searchable","createLabelColumn","labels","specifiedLabelValue","defaultValue","createNamespaceColumn","YellowStar","withStyles","root","Star","refCompare","b","toRef","CatalogTable","columns","actions","tableOptions","subtitle","emptyContent","isStarredEntity","toggleStarredEntity","useStarredEntities","entities","defaultColumns","createEntitySpecificColumns","baseColumns","every","namespace","showTypeColumn","titlePreamble","capitalize","user","div","WarningPanel","CodeSnippet","language","toString","defaultActions","url","annotations","ANNOTATION_VIEW_URL","visuallyHidden","OpenInNew","tooltip","disabled","window","open","ANNOTATION_EDIT_URL","Edit","isStarred","paddingLeft","StarBorder","rows","getEntityRelations","RELATION_PART_OF","RELATION_OWNED_BY","stringifyEntityRef","ownedByRelationsTitle","r","partOfSystemRelationTitle","typeColumn","find","c","showPagination","currentKind","currentType","titleDisplay","pluralize","s","Table","isLoading","paging","pageSize","actionsColumnIndex","loadingType","showEmptyDataSourceMessage","pageSizeOptions","data","catalogTranslationRef","createTranslationRef","id","messages","catalog_page_title","catalog_page_create_button_title","loggedRefs","WeakSet","useTranslationRef","translationRef","errorApi","errorApiRef","translationApi","translationApiRef","snapshot","setSnapshot","getTranslation","observable","translation$","onError","useCallback","has","errMsg","console","Error","add","subscription","subscribe","next","ready","unsubscribe","initialRenderRef","Promise","resolve","BaseCatalogPage","content","orgName","configApiRef","getOptionalString","createComponentLink","useRouteRef","createComponentRouteRef","PageWithHeader","themeId","Content","ContentHeader","SupportButton","EntityListProvider","CatalogFilterLayout","Filters","DefaultCatalogPage","initiallySelectedFilter","initialKind","ownerPickerMode","UserListPicker","EntityOwnerPicker","mode","EntityTagPicker","CatalogPage","useOutlet"],"sourceRoot":""}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";(()=>{(self.webpackChunktechdocs_cli_embedded_app=self.webpackChunktechdocs_cli_embedded_app||[]).push([[5914],{61811:function(v,a,t){t.d(a,{O:function(){return o}});var e=t(73557);function o(h){return(0,e.UO)()}},31685:function(v,a,t){t.d(a,{I:function(){return f},r:function(){return O}});var e=t(52322),o=t(2784),h=t(73557),D=t(67880),P=t(2296),M=t(68979),T=t(
|
|
1
|
+
"use strict";(()=>{(self.webpackChunktechdocs_cli_embedded_app=self.webpackChunktechdocs_cli_embedded_app||[]).push([[5914],{61811:function(v,a,t){t.d(a,{O:function(){return o}});var e=t(73557);function o(h){return(0,e.UO)()}},31685:function(v,a,t){t.d(a,{I:function(){return f},r:function(){return O}});var e=t(52322),o=t(2784),h=t(73557),D=t(67880),P=t(2296),M=t(68979),T=t(14540),L=t(65386),m=t(24992),A=t(95573),I=t(61811),d=t(62584);const O=_=>{const{withSearch:l,withHeader:s=!0}=_;return(0,e.jsxs)(D.T,{themeId:"documentation",children:[s&&(0,e.jsx)(L.S,{}),(0,e.jsx)(m.b,{}),(0,e.jsx)(T.F,{withSearch:l})]})},f=_=>{const{kind:l,name:s,namespace:g}=(0,I.O)(A.Fw),{children:c,entityRef:i={kind:l,name:s,namespace:g}}=_,C=(0,h.pC)();if(!c){const r=(C?o.Children.toArray(C.props.children):[]).flatMap(n=>{var u,B;return(B=n==null||(u=n.props)===null||u===void 0?void 0:u.children)!==null&&B!==void 0?B:[]}).find(n=>!(0,d.I)(n,P.Zz)&&!(0,d.I)(n,P.jM));return(0,e.jsx)(M.Z,{entityRef:i,children:r||(0,e.jsx)(O,{})})}return(0,e.jsx)(M.Z,{entityRef:i,children:({metadata:R,entityMetadata:E,onReady:r})=>(0,e.jsx)("div",{className:"techdocs-reader-page",children:(0,e.jsx)(D.T,{themeId:"documentation",children:c instanceof Function?c({entityRef:i,techdocsMetadataValue:R.value,entityMetadataValue:E.value,onReady:r}):c})})})}},35914:function(v,a,t){t.r(a),t.d(a,{TechDocsReaderLayout:function(){return e.r},TechDocsReaderPage:function(){return e.I}});var e=t(31685)},24992:function(v,a,t){t.d(a,{b:function(){return f}});var e=t(52322),o=t(2784),h=t(79692),D=t(15223),P=t(62774),M=t(80030),T=t(61837),L=t(48348),m=t(47603),A=t(68979),I=t(2296),d=t(57058);const O=(0,h.Z)(_=>({root:{gridArea:"pageSubheader",flexDirection:"column",minHeight:"auto",padding:_.spacing(3,3,0),"@media print":{display:"none"}}})),f=_=>{const l=O(),[s,g]=(0,o.useState)(null),c=(0,o.useCallback)(u=>{g(u.currentTarget)},[]),i=(0,o.useCallback)(()=>{g(null)},[]),{entityMetadata:{value:C,loading:R}}=(0,A.x)(),E=(0,I.$L)(),r=E.renderComponentsByLocation(d.o.Subheader),n=E.renderComponentsByLocation(d.o.Settings);return!r&&!n||R===!1&&!C?null:(0,e.jsx)(D.Z,{classes:l,..._.toolbarProps,children:(0,e.jsxs)(P.Z,{display:"flex",justifyContent:"flex-end",width:"100%",flexWrap:"wrap",children:[r,n?(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(M.ZP,{title:"Settings",children:(0,e.jsx)(T.Z,{"aria-controls":"tech-docs-reader-page-settings","aria-haspopup":"true",onClick:c,children:(0,e.jsx)(m.Z,{})})}),(0,e.jsx)(L.Z,{id:"tech-docs-reader-page-settings",getContentAnchorEl:null,anchorEl:s,anchorOrigin:{vertical:"bottom",horizontal:"right"},open:Boolean(s),onClose:i,keepMounted:!0,children:(0,e.jsx)("div",{children:n})})]}):null]})})}}}]);})();
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=5914.
|
|
3
|
+
//# sourceMappingURL=5914.633b2934.chunk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static/5914.111b8c95.chunk.js","mappings":"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","sources":["webpack://techdocs-cli-embedded-app/../core-plugin-api/src/routing/useRouteRefParams.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { RouteRef, AnyParams, SubRouteRef } from './types';\n\n/**\n * React hook for retrieving dynamic params from the current URL.\n * @param _routeRef - Ref of the current route.\n * @public\n */\nexport function useRouteRefParams<Params extends AnyParams>(\n _routeRef: RouteRef<Params> | SubRouteRef<Params>,\n): Params {\n return useParams() as Params;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactNode, Children, ReactElement } from 'react';\nimport { useOutlet } from 'react-router-dom';\n\nimport { Page } from '@backstage/core-components';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n TECHDOCS_ADDONS_WRAPPER_KEY,\n TECHDOCS_ADDONS_KEY,\n TechDocsReaderPageProvider,\n} from '@backstage/plugin-techdocs-react';\n\nimport { TechDocsReaderPageRenderFunction } from '../../../types';\n\nimport { TechDocsReaderPageContent } from '../TechDocsReaderPageContent';\nimport { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader';\nimport { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader';\nimport { rootDocsRouteRef } from '../../../routes';\nimport {\n getComponentData,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\n\n/* An explanation for the multiple ways of customizing the TechDocs reader page\n\nPlease refer to this page on the microsite for the latest recommended approach:\nhttps://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-reader-page\n\nThe <TechDocsReaderPage> component is responsible for rendering the <TechDocsReaderPageProvider> and\nits contained version of a <Page>, which in turn renders the <TechDocsReaderPageContent>.\n\nHistorically, there have been different approaches on how this <Page> can be customized, and how the\n<TechDocsReaderPageContent> inside could be exchanged for a custom implementation (which was not\npossible before). Also, the current implementation supports every scenario to avoid breaking default\nconfigurations of TechDocs.\n\nIn particular, there are 4 different TechDocs page configurations:\n\nCONFIGURATION 1: <TechDocsReaderPage> only, no children\n\n<Route path=\"/docs/:namespace/:kind/:name/*\" element={<TechDocsReaderPage />} >\n\nThis is the simplest way to use TechDocs. Only a full page is passed, assuming that it comes with\nits content inside. Since we allowed customizing it, we started providing <TechDocsReaderLayout> as\na default implementation (which contains <TechDocsReaderPageContent>).\n\nCONFIGURATION 2 (not advised): <TechDocsReaderPage> with element children\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {techdocsPage}\n </TechDocsReaderPage>\n }\n/>\n\nPreviously, there were two ways of passing children to <TechDocsReaderPage>: either as elements (as\nshown above), or as a render function (described below in CONFIGURATION 3). The \"techdocsPage\" is\nlocated in packages/app/src/components/techdocs and is the default implementation of the content\ninside.\n\nCONFIGURATION 3 (not advised): <TechDocsReaderPage> with render function as child\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {({ metadata, entityMetadata, onReady }) => (\n techdocsPage\n )}\n </TechDocsReaderPage>\n }\n/>\n\nSimilar to CONFIGURATION 2, the direct children will be passed to the <TechDocsReaderPage> but in\nthis case interpreted as render prop.\n\nCONFIGURATION 4: <TechDocsReaderPage> and provided content in <Route>\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n>\n {techDocsPage}\n <TechDocsAddons>\n <ExpandableNavigation />\n <ReportIssue />\n <TextSize />\n <LightBox />\n </TechDocsAddons>\n</Route>\n\nThis is the current state in packages/app/src/App.tsx and moved the location of children from inside\nthe element prop in the <Route> to the children of the <Route>. Then, in <TechDocsReaderPage> they\nare retrieved using the useOutlet hook from React Router.\n\nNOTE: Render functions are no longer supported in this approach.\n*/\n\n/**\n * Props for {@link TechDocsReaderLayout}\n * @public\n */\nexport type TechDocsReaderLayoutProps = {\n /**\n * Show or hide the header, defaults to true.\n */\n withHeader?: boolean;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\n/**\n * Default TechDocs reader page structure composed with a header and content\n * @public\n */\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <Page themeId=\"documentation\">\n {withHeader && <TechDocsReaderPageHeader />}\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent withSearch={withSearch} />\n </Page>\n );\n};\n\n/**\n * @public\n */\nexport type TechDocsReaderPageProps = {\n entityRef?: CompoundEntityRef;\n children?: TechDocsReaderPageRenderFunction | ReactNode;\n};\n\n/**\n * An addon-aware implementation of the TechDocsReaderPage.\n *\n * @public\n */\nexport const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {\n const { kind, name, namespace } = useRouteRefParams(rootDocsRouteRef);\n const { children, entityRef = { kind, name, namespace } } = props;\n\n const outlet = useOutlet();\n\n if (!children) {\n const childrenList = outlet ? Children.toArray(outlet.props.children) : [];\n\n const grandChildren = childrenList.flatMap<ReactElement>(\n child => (child as ReactElement)?.props?.children ?? [],\n );\n\n const page: React.ReactNode = grandChildren.find(\n grandChild =>\n !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&\n !getComponentData(grandChild, TECHDOCS_ADDONS_KEY),\n );\n\n // As explained above, \"page\" is configuration 4 and <TechDocsReaderLayout> is 1\n return (\n <TechDocsReaderPageProvider entityRef={entityRef}>\n {(page as JSX.Element) || <TechDocsReaderLayout />}\n </TechDocsReaderPageProvider>\n );\n }\n\n // As explained above, a render function is configuration 3 and React element is 2\n return (\n <TechDocsReaderPageProvider entityRef={entityRef}>\n {({ metadata, entityMetadata, onReady }) => (\n <div className=\"techdocs-reader-page\">\n <Page themeId=\"documentation\">\n {children instanceof Function\n ? children({\n entityRef,\n techdocsMetadataValue: metadata.value,\n entityMetadataValue: entityMetadata.value,\n onReady,\n })\n : children}\n </Page>\n </div>\n )}\n </TechDocsReaderPageProvider>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { MouseEvent, useState, useCallback } from 'react';\n\nimport {\n Box,\n makeStyles,\n Toolbar,\n ToolbarProps,\n Menu,\n Tooltip,\n IconButton,\n} from '@material-ui/core';\nimport SettingsIcon from '@material-ui/icons/Settings';\n\nimport {\n TechDocsAddonLocations as locations,\n useTechDocsAddons,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageSubheader',\n flexDirection: 'column',\n minHeight: 'auto',\n padding: theme.spacing(3, 3, 0),\n '@media print': {\n display: 'none',\n },\n },\n}));\n\n/**\n * Renders the reader page subheader.\n * Please use the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageSubheader = (props: {\n toolbarProps?: ToolbarProps;\n}) => {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const handleClick = useCallback((event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n }, []);\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const {\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n const addons = useTechDocsAddons();\n\n const subheaderAddons = addons.renderComponentsByLocation(\n locations.Subheader,\n );\n\n const settingsAddons = addons.renderComponentsByLocation(locations.Settings);\n\n if (!subheaderAddons && !settingsAddons) return null;\n\n // No entity metadata = 404. Don't render subheader on 404.\n if (entityMetadataLoading === false && !entityMetadata) return null;\n\n return (\n <Toolbar classes={classes} {...props.toolbarProps}>\n <Box\n display=\"flex\"\n justifyContent=\"flex-end\"\n width=\"100%\"\n flexWrap=\"wrap\"\n >\n {subheaderAddons}\n {settingsAddons ? (\n <>\n <Tooltip title=\"Settings\">\n <IconButton\n aria-controls=\"tech-docs-reader-page-settings\"\n aria-haspopup=\"true\"\n onClick={handleClick}\n >\n <SettingsIcon />\n </IconButton>\n </Tooltip>\n <Menu\n id=\"tech-docs-reader-page-settings\"\n getContentAnchorEl={null}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n open={Boolean(anchorEl)}\n onClose={handleClose}\n keepMounted\n >\n <div>{settingsAddons}</div>\n </Menu>\n </>\n ) : null}\n </Box>\n </Toolbar>\n );\n};\n"],"names":["useRouteRefParams","_routeRef","useParams","TechDocsReaderLayout","props","withSearch","withHeader","Page","themeId","TechDocsReaderPageHeader","TechDocsReaderPageSubheader","TechDocsReaderPageContent","TechDocsReaderPage","kind","name","namespace","rootDocsRouteRef","children","entityRef","outlet","useOutlet","page","Children","toArray","flatMap","child","find","grandChild","getComponentData","TECHDOCS_ADDONS_WRAPPER_KEY","TECHDOCS_ADDONS_KEY","TechDocsReaderPageProvider","metadata","entityMetadata","onReady","div","className","Function","techdocsMetadataValue","value","entityMetadataValue","useStyles","makeStyles","theme","root","gridArea","flexDirection","minHeight","padding","spacing","display","classes","anchorEl","setAnchorEl","useState","handleClick","useCallback","event","currentTarget","handleClose","loading","entityMetadataLoading","useTechDocsReaderPage","addons","useTechDocsAddons","subheaderAddons","renderComponentsByLocation","locations","Subheader","settingsAddons","Settings","Toolbar","toolbarProps","Box","justifyContent","width","flexWrap","Tooltip","title","IconButton","aria-controls","aria-haspopup","onClick","SettingsIcon","Menu","id","getContentAnchorEl","anchorOrigin","vertical","horizontal","open","Boolean","onClose","keepMounted"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"file":"static/5914.633b2934.chunk.js","mappings":"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","sources":["webpack://techdocs-cli-embedded-app/../core-plugin-api/src/routing/useRouteRefParams.ts","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPage/TechDocsReaderPage.tsx","webpack://techdocs-cli-embedded-app/../../plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { RouteRef, AnyParams, SubRouteRef } from './types';\n\n/**\n * React hook for retrieving dynamic params from the current URL.\n * @param _routeRef - Ref of the current route.\n * @public\n */\nexport function useRouteRefParams<Params extends AnyParams>(\n _routeRef: RouteRef<Params> | SubRouteRef<Params>,\n): Params {\n return useParams() as Params;\n}\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactNode, Children, ReactElement } from 'react';\nimport { useOutlet } from 'react-router-dom';\n\nimport { Page } from '@backstage/core-components';\nimport { CompoundEntityRef } from '@backstage/catalog-model';\nimport {\n TECHDOCS_ADDONS_WRAPPER_KEY,\n TECHDOCS_ADDONS_KEY,\n TechDocsReaderPageProvider,\n} from '@backstage/plugin-techdocs-react';\n\nimport { TechDocsReaderPageRenderFunction } from '../../../types';\n\nimport { TechDocsReaderPageContent } from '../TechDocsReaderPageContent';\nimport { TechDocsReaderPageHeader } from '../TechDocsReaderPageHeader';\nimport { TechDocsReaderPageSubheader } from '../TechDocsReaderPageSubheader';\nimport { rootDocsRouteRef } from '../../../routes';\nimport {\n getComponentData,\n useRouteRefParams,\n} from '@backstage/core-plugin-api';\n\n/* An explanation for the multiple ways of customizing the TechDocs reader page\n\nPlease refer to this page on the microsite for the latest recommended approach:\nhttps://backstage.io/docs/features/techdocs/how-to-guides#how-to-customize-the-techdocs-reader-page\n\nThe <TechDocsReaderPage> component is responsible for rendering the <TechDocsReaderPageProvider> and\nits contained version of a <Page>, which in turn renders the <TechDocsReaderPageContent>.\n\nHistorically, there have been different approaches on how this <Page> can be customized, and how the\n<TechDocsReaderPageContent> inside could be exchanged for a custom implementation (which was not\npossible before). Also, the current implementation supports every scenario to avoid breaking default\nconfigurations of TechDocs.\n\nIn particular, there are 4 different TechDocs page configurations:\n\nCONFIGURATION 1: <TechDocsReaderPage> only, no children\n\n<Route path=\"/docs/:namespace/:kind/:name/*\" element={<TechDocsReaderPage />} >\n\nThis is the simplest way to use TechDocs. Only a full page is passed, assuming that it comes with\nits content inside. Since we allowed customizing it, we started providing <TechDocsReaderLayout> as\na default implementation (which contains <TechDocsReaderPageContent>).\n\nCONFIGURATION 2 (not advised): <TechDocsReaderPage> with element children\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {techdocsPage}\n </TechDocsReaderPage>\n }\n/>\n\nPreviously, there were two ways of passing children to <TechDocsReaderPage>: either as elements (as\nshown above), or as a render function (described below in CONFIGURATION 3). The \"techdocsPage\" is\nlocated in packages/app/src/components/techdocs and is the default implementation of the content\ninside.\n\nCONFIGURATION 3 (not advised): <TechDocsReaderPage> with render function as child\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={\n <TechDocsReaderPage>\n {({ metadata, entityMetadata, onReady }) => (\n techdocsPage\n )}\n </TechDocsReaderPage>\n }\n/>\n\nSimilar to CONFIGURATION 2, the direct children will be passed to the <TechDocsReaderPage> but in\nthis case interpreted as render prop.\n\nCONFIGURATION 4: <TechDocsReaderPage> and provided content in <Route>\n\n<Route\n path=\"/docs/:namespace/:kind/:name/*\"\n element={<TechDocsReaderPage />}\n>\n {techDocsPage}\n <TechDocsAddons>\n <ExpandableNavigation />\n <ReportIssue />\n <TextSize />\n <LightBox />\n </TechDocsAddons>\n</Route>\n\nThis is the current state in packages/app/src/App.tsx and moved the location of children from inside\nthe element prop in the <Route> to the children of the <Route>. Then, in <TechDocsReaderPage> they\nare retrieved using the useOutlet hook from React Router.\n\nNOTE: Render functions are no longer supported in this approach.\n*/\n\n/**\n * Props for {@link TechDocsReaderLayout}\n * @public\n */\nexport type TechDocsReaderLayoutProps = {\n /**\n * Show or hide the header, defaults to true.\n */\n withHeader?: boolean;\n /**\n * Show or hide the content search bar, defaults to true.\n */\n withSearch?: boolean;\n};\n\n/**\n * Default TechDocs reader page structure composed with a header and content\n * @public\n */\nexport const TechDocsReaderLayout = (props: TechDocsReaderLayoutProps) => {\n const { withSearch, withHeader = true } = props;\n return (\n <Page themeId=\"documentation\">\n {withHeader && <TechDocsReaderPageHeader />}\n <TechDocsReaderPageSubheader />\n <TechDocsReaderPageContent withSearch={withSearch} />\n </Page>\n );\n};\n\n/**\n * @public\n */\nexport type TechDocsReaderPageProps = {\n entityRef?: CompoundEntityRef;\n children?: TechDocsReaderPageRenderFunction | ReactNode;\n};\n\n/**\n * An addon-aware implementation of the TechDocsReaderPage.\n *\n * @public\n */\nexport const TechDocsReaderPage = (props: TechDocsReaderPageProps) => {\n const { kind, name, namespace } = useRouteRefParams(rootDocsRouteRef);\n const { children, entityRef = { kind, name, namespace } } = props;\n\n const outlet = useOutlet();\n\n if (!children) {\n const childrenList = outlet ? Children.toArray(outlet.props.children) : [];\n\n const grandChildren = childrenList.flatMap<ReactElement>(\n child => (child as ReactElement)?.props?.children ?? [],\n );\n\n const page: React.ReactNode = grandChildren.find(\n grandChild =>\n !getComponentData(grandChild, TECHDOCS_ADDONS_WRAPPER_KEY) &&\n !getComponentData(grandChild, TECHDOCS_ADDONS_KEY),\n );\n\n // As explained above, \"page\" is configuration 4 and <TechDocsReaderLayout> is 1\n return (\n <TechDocsReaderPageProvider entityRef={entityRef}>\n {(page as JSX.Element) || <TechDocsReaderLayout />}\n </TechDocsReaderPageProvider>\n );\n }\n\n // As explained above, a render function is configuration 3 and React element is 2\n return (\n <TechDocsReaderPageProvider entityRef={entityRef}>\n {({ metadata, entityMetadata, onReady }) => (\n <div className=\"techdocs-reader-page\">\n <Page themeId=\"documentation\">\n {children instanceof Function\n ? children({\n entityRef,\n techdocsMetadataValue: metadata.value,\n entityMetadataValue: entityMetadata.value,\n onReady,\n })\n : children}\n </Page>\n </div>\n )}\n </TechDocsReaderPageProvider>\n );\n};\n","/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { MouseEvent, useState, useCallback } from 'react';\n\nimport {\n Box,\n makeStyles,\n Toolbar,\n ToolbarProps,\n Menu,\n Tooltip,\n IconButton,\n} from '@material-ui/core';\nimport SettingsIcon from '@material-ui/icons/Settings';\n\nimport {\n TechDocsAddonLocations as locations,\n useTechDocsAddons,\n useTechDocsReaderPage,\n} from '@backstage/plugin-techdocs-react';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageSubheader',\n flexDirection: 'column',\n minHeight: 'auto',\n padding: theme.spacing(3, 3, 0),\n '@media print': {\n display: 'none',\n },\n },\n}));\n\n/**\n * Renders the reader page subheader.\n * Please use the Tech Docs add-ons to customize it\n * @public\n */\nexport const TechDocsReaderPageSubheader = (props: {\n toolbarProps?: ToolbarProps;\n}) => {\n const classes = useStyles();\n const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);\n\n const handleClick = useCallback((event: MouseEvent<HTMLButtonElement>) => {\n setAnchorEl(event.currentTarget);\n }, []);\n\n const handleClose = useCallback(() => {\n setAnchorEl(null);\n }, []);\n\n const {\n entityMetadata: { value: entityMetadata, loading: entityMetadataLoading },\n } = useTechDocsReaderPage();\n\n const addons = useTechDocsAddons();\n\n const subheaderAddons = addons.renderComponentsByLocation(\n locations.Subheader,\n );\n\n const settingsAddons = addons.renderComponentsByLocation(locations.Settings);\n\n if (!subheaderAddons && !settingsAddons) return null;\n\n // No entity metadata = 404. Don't render subheader on 404.\n if (entityMetadataLoading === false && !entityMetadata) return null;\n\n return (\n <Toolbar classes={classes} {...props.toolbarProps}>\n <Box\n display=\"flex\"\n justifyContent=\"flex-end\"\n width=\"100%\"\n flexWrap=\"wrap\"\n >\n {subheaderAddons}\n {settingsAddons ? (\n <>\n <Tooltip title=\"Settings\">\n <IconButton\n aria-controls=\"tech-docs-reader-page-settings\"\n aria-haspopup=\"true\"\n onClick={handleClick}\n >\n <SettingsIcon />\n </IconButton>\n </Tooltip>\n <Menu\n id=\"tech-docs-reader-page-settings\"\n getContentAnchorEl={null}\n anchorEl={anchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n open={Boolean(anchorEl)}\n onClose={handleClose}\n keepMounted\n >\n <div>{settingsAddons}</div>\n </Menu>\n </>\n ) : null}\n </Box>\n </Toolbar>\n );\n};\n"],"names":["useRouteRefParams","_routeRef","useParams","TechDocsReaderLayout","props","withSearch","withHeader","Page","themeId","TechDocsReaderPageHeader","TechDocsReaderPageSubheader","TechDocsReaderPageContent","TechDocsReaderPage","kind","name","namespace","rootDocsRouteRef","children","entityRef","outlet","useOutlet","page","Children","toArray","flatMap","child","find","grandChild","getComponentData","TECHDOCS_ADDONS_WRAPPER_KEY","TECHDOCS_ADDONS_KEY","TechDocsReaderPageProvider","metadata","entityMetadata","onReady","div","className","Function","techdocsMetadataValue","value","entityMetadataValue","useStyles","makeStyles","theme","root","gridArea","flexDirection","minHeight","padding","spacing","display","classes","anchorEl","setAnchorEl","useState","handleClick","useCallback","event","currentTarget","handleClose","loading","entityMetadataLoading","useTechDocsReaderPage","addons","useTechDocsAddons","subheaderAddons","renderComponentsByLocation","locations","Subheader","settingsAddons","Settings","Toolbar","toolbarProps","Box","justifyContent","width","flexWrap","Tooltip","title","IconButton","aria-controls","aria-haspopup","onClick","SettingsIcon","Menu","id","getContentAnchorEl","anchorOrigin","vertical","horizontal","open","Boolean","onClose","keepMounted"],"sourceRoot":""}
|