|
6 | 6 | class="package-card" |
7 | 7 | > |
8 | 8 | <img |
9 | | - :src="'https://www.google.com/s2/favicons?domain=flows.nodered.org'" |
| 9 | + :src="getFaviconUrl(nodePackage.metadata?.source || nodePackage.url)" |
10 | 10 | alt="Node-RED" |
11 | 11 | class="package-favicon" |
12 | 12 | @error="handleImageError" |
|
15 | 15 | <div class="package-name">{{ getPackageName(nodePackage) }}</div> |
16 | 16 | <div class="package-url">{{ getPackageUrl(nodePackage) }}</div> |
17 | 17 | <div class="package-actions"> |
18 | | - <template v-if="canManagePalette"> |
| 18 | + <template v-if="canManagePalette && !isCorePackage(nodePackage)"> |
19 | 19 | <ff-button v-if="isPackageInstalled(nodePackage)" class="w-20" size="small" kind="secondary" @click.stop.prevent="managePackage(nodePackage)">Manage</ff-button> |
20 | 20 | <ff-button v-else class="w-20" size="small" kind="secondary" @click.stop.prevent="installPackage(nodePackage)">Install</ff-button> |
21 | 21 | </template> |
@@ -46,8 +46,17 @@ export default { |
46 | 46 | return typeof pkg === 'object' ? (pkg.id || pkg.name) : pkg |
47 | 47 | }, |
48 | 48 | getPackageUrl (pkg) { |
49 | | - const packageName = this.getPackageName(pkg) |
50 | | - return `https://flows.nodered.org/node/${packageName}` |
| 49 | + if (!pkg) return 'https://flows.nodered.org/' |
| 50 | + return pkg.url || pkg.metadata?.source || pkg.metadata?.url || `https://flows.nodered.org/node/${this.getPackageName(pkg)}` |
| 51 | + }, |
| 52 | + getFaviconUrl (url) { |
| 53 | + try { |
| 54 | + const urlObj = new URL(url) |
| 55 | + return `https://www.google.com/s2/favicons?domain=${urlObj.hostname}` |
| 56 | + } catch (e) { |
| 57 | + // If URL parsing fails, return empty string to trigger error handler |
| 58 | + return 'flows.nodered.org' |
| 59 | + } |
51 | 60 | }, |
52 | 61 | isPackageInstalled (pkg) { |
53 | 62 | return !!this.$store.state.product.assistant?.palette?.[pkg.id] |
@@ -77,6 +86,9 @@ export default { |
77 | 86 | const packageName = this.getPackageName(nodePackage) |
78 | 87 | this.manageNodePackage(packageName) |
79 | 88 | // TODO: hide the ff-expert panel after managing. Ideally after a "success" message is received from the assistant |
| 89 | + }, |
| 90 | + isCorePackage (nodePackage) { |
| 91 | + return nodePackage.type === 'core-node' || this.getPackageName(nodePackage).startsWith('node-red:') |
80 | 92 | } |
81 | 93 | } |
82 | 94 | } |
|
0 commit comments