|
1 | | -import {getCurrentPlatformOrGuide} from 'sentry-docs/docTree'; |
| 1 | +import {getCurrentPlatformOrGuide, getPlatform} from 'sentry-docs/docTree'; |
2 | 2 | import {serverContext} from 'sentry-docs/serverContext'; |
| 3 | +import {Platform, PlatformGuide} from 'sentry-docs/types'; |
3 | 4 |
|
4 | 5 | import {SmartLink} from './smartLink'; |
5 | 6 |
|
| 7 | +function getPlatformsWithFallback( |
| 8 | + rootNode: any, |
| 9 | + platformOrGuide: Platform | PlatformGuide |
| 10 | +) { |
| 11 | + const result = [platformOrGuide.key]; |
| 12 | + let curPlatform: Platform | PlatformGuide | undefined = platformOrGuide; |
| 13 | + while (curPlatform?.fallbackPlatform) { |
| 14 | + result.push(curPlatform.fallbackPlatform); |
| 15 | + curPlatform = getPlatform(rootNode, curPlatform.fallbackPlatform); |
| 16 | + } |
| 17 | + return result; |
| 18 | +} |
| 19 | + |
| 20 | +const isSupported = ( |
| 21 | + platformKey: string, |
| 22 | + supported: string[], |
| 23 | + notSupported: string[] |
| 24 | +): boolean | null => { |
| 25 | + if (supported.length && supported.find(p => p === platformKey)) { |
| 26 | + return true; |
| 27 | + } |
| 28 | + if (notSupported.length && notSupported.find(p => p === platformKey)) { |
| 29 | + return false; |
| 30 | + } |
| 31 | + return null; |
| 32 | +}; |
| 33 | + |
6 | 34 | type Props = { |
7 | 35 | children: React.ReactNode; |
| 36 | + notSupported?: string[]; |
| 37 | + supported?: string[]; |
8 | 38 | to?: string; |
9 | 39 | }; |
10 | 40 |
|
11 | | -export function PlatformLink({children, to}: Props) { |
| 41 | +export function PlatformLink({children, to, supported = [], notSupported = []}: Props) { |
12 | 42 | if (!to) { |
13 | 43 | return children; |
14 | 44 | } |
15 | 45 |
|
16 | 46 | const {rootNode, path} = serverContext(); |
17 | 47 | const currentPlatformOrGuide = getCurrentPlatformOrGuide(rootNode, path); |
| 48 | + |
| 49 | + // Check platform support if we have a current platform and support constraints |
| 50 | + if (currentPlatformOrGuide && (supported.length > 0 || notSupported.length > 0)) { |
| 51 | + const platformsToSearch = getPlatformsWithFallback(rootNode, currentPlatformOrGuide); |
| 52 | + |
| 53 | + let result: boolean | null = null; |
| 54 | + // eslint-disable-next-line no-cond-assign |
| 55 | + for (let platformKey: string, i = 0; (platformKey = platformsToSearch[i]); i++) { |
| 56 | + if (!platformKey) { |
| 57 | + continue; |
| 58 | + } |
| 59 | + result = isSupported(platformKey, supported, notSupported); |
| 60 | + if (result === false) { |
| 61 | + // Platform is not supported, hide completely |
| 62 | + return null; |
| 63 | + } |
| 64 | + if (result === true) { |
| 65 | + break; |
| 66 | + } |
| 67 | + } |
| 68 | + if (result === null && supported.length) { |
| 69 | + // No supported platform found, hide completely |
| 70 | + return null; |
| 71 | + } |
| 72 | + } |
| 73 | + |
18 | 74 | let href: string; |
19 | 75 | if (currentPlatformOrGuide) { |
20 | 76 | href = currentPlatformOrGuide.url + to.slice(1); |
|
0 commit comments