From 96e75ff1dd73d64d65d3b635d33b4e9371187057 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Fri, 11 Jul 2025 13:37:55 +0000 Subject: [PATCH 01/13] Added ui element for release notes --- components/centraldashboard/package-lock.json | 37 +++++++++++++++++++ components/centraldashboard/package.json | 1 + .../public/assets/i18n/languages.json | 4 ++ .../public/components/dashboard-view.css | 13 +++++++ .../public/components/dashboard-view.js | 10 +++++ .../public/components/dashboard-view.pug | 7 ++++ 6 files changed, 72 insertions(+) diff --git a/components/centraldashboard/package-lock.json b/components/centraldashboard/package-lock.json index deefb19eadb..6f9fdcd76aa 100644 --- a/components/centraldashboard/package-lock.json +++ b/components/centraldashboard/package-lock.json @@ -25,6 +25,7 @@ "@polymer/iron-media-query": "^3.0.1", "@polymer/iron-pages": "^3.0.0", "@polymer/iron-selector": "^3.0.0", + "@polymer/marked-element": "^3.0.1", "@polymer/neon-animation": "^3.0.1", "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", @@ -2240,6 +2241,16 @@ "@polymer/polymer": "^3.0.0" } }, + "node_modules/@polymer/marked-element": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@polymer/marked-element/-/marked-element-3.0.1.tgz", + "integrity": "sha512-WJQzQetxdStVGQbyTBUBgd+hSI0Rl39uJg7b2zL3r6EfMnibzmA/YNT06M8jVZdxPF+B4SumrFWRtasVtGQRUQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@polymer/polymer": "^3.0.0", + "marked": "~0.3.9" + } + }, "node_modules/@polymer/neon-animation": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/neon-animation/-/neon-animation-3.0.1.tgz", @@ -12141,6 +12152,18 @@ "node": ">=0.10.0" } }, + "node_modules/marked": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", + "license": "MIT", + "bin": { + "marked": "bin/marked" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -20906,6 +20929,15 @@ "@polymer/polymer": "^3.0.0" } }, + "@polymer/marked-element": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@polymer/marked-element/-/marked-element-3.0.1.tgz", + "integrity": "sha512-WJQzQetxdStVGQbyTBUBgd+hSI0Rl39uJg7b2zL3r6EfMnibzmA/YNT06M8jVZdxPF+B4SumrFWRtasVtGQRUQ==", + "requires": { + "@polymer/polymer": "^3.0.0", + "marked": "~0.3.9" + } + }, "@polymer/neon-animation": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/neon-animation/-/neon-animation-3.0.1.tgz", @@ -28699,6 +28731,11 @@ "object-visit": "^1.0.0" } }, + "marked": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", diff --git a/components/centraldashboard/package.json b/components/centraldashboard/package.json index cf136ad2394..d106e5398c3 100644 --- a/components/centraldashboard/package.json +++ b/components/centraldashboard/package.json @@ -57,6 +57,7 @@ "@polymer/iron-media-query": "^3.0.1", "@polymer/iron-pages": "^3.0.0", "@polymer/iron-selector": "^3.0.0", + "@polymer/marked-element": "^3.0.1", "@polymer/neon-animation": "^3.0.1", "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index fd802f45875..e6fdc10783d 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -27,6 +27,8 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Official Kubeflow Docs", "dashboardView.docItemOfficialKubeflowDocsDesc": "Advanced documentation for installing, running, and using Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", + "dashboardView.releaseNotes": "Latest changes in our beta images (english only)", + "dashboardView.releaseNotesError": "Error generating release notes", "activityView.msgSelectNamespace": "Select a workspace to see recent events", "activityView.errNoActivities": "No activities for workspace {namespace}", "activityView.errRetrivingActivities": "Error retrieving activities for workspace {namespace}", @@ -180,6 +182,8 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Documents Kubeflow Officiels", "dashboardView.docItemOfficialKubeflowDocsDesc": "Documentation avancé pour installer, exécuter et utiliser Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", + "dashboardView.releaseNotes": "Derniers changements dans nos images bêta (anglais seulement)", + "dashboardView.releaseNotesError": "Erreur lors de la génération des notes de version", "activityView.msgSelectNamespace": "Sélectionner un espace de travail pour voir les activités récentes", "activityView.errNoActivities": "Aucune activité pour l'espace de travail {namespace}", "activityView.errRetrivingActivities": "Erreur en récupérant les activités pour l'espace de travail {namespace}", diff --git a/components/centraldashboard/public/components/dashboard-view.css b/components/centraldashboard/public/components/dashboard-view.css index b7a0912b377..f754e629775 100644 --- a/components/centraldashboard/public/components/dashboard-view.css +++ b/components/centraldashboard/public/components/dashboard-view.css @@ -23,6 +23,19 @@ margin: 0 auto; } +.release-notes { + width: 80%; + margin: 0 auto; +} + +.release-notes-markdown { + padding: 0.5em 1em; +} + +.release-notes-markdown a { + color: revert; +} + .security-messages { width: 80%; margin: 0 auto; diff --git a/components/centraldashboard/public/components/dashboard-view.js b/components/centraldashboard/public/components/dashboard-view.js index 3f5eb1ce89a..ecb881b4b10 100644 --- a/components/centraldashboard/public/components/dashboard-view.js +++ b/components/centraldashboard/public/components/dashboard-view.js @@ -4,6 +4,7 @@ import '@polymer/paper-card/paper-card.js'; import '@polymer/paper-ripple/paper-ripple.js'; import '@polymer/paper-item/paper-icon-item.js'; import '@polymer/paper-icon-button/paper-icon-button.js'; +import '@polymer/marked-element/marked-element.js'; // eslint-disable-next-line max-len import {AppLocalizeBehavior} from '@polymer/app-localize-behavior/app-localize-behavior.js'; import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js'; @@ -63,6 +64,15 @@ export class DashboardView extends mixinBehaviors([AppLocalizeBehavior], utiliti this.platformDetails = getGCPData(gcpProject); } } + + _onGetReleaseNotes(ev) { + const releaseNotes = ev.detail.response.body; + this.releaseNotes = releaseNotes; + } + + _onErrorReleaseNotes(ev) { + this.releaseNotes = this.localize('dashboardView.releaseNotesError'); + } } customElements.define('dashboard-view', DashboardView); diff --git a/components/centraldashboard/public/components/dashboard-view.pug b/components/centraldashboard/public/components/dashboard-view.pug index 5a00060a078..ec0b41af0b9 100644 --- a/components/centraldashboard/public/components/dashboard-view.pug +++ b/components/centraldashboard/public/components/dashboard-view.pug @@ -1,3 +1,5 @@ +iron-ajax(auto, url='https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', handle-as='json', + on-response='_onGetReleaseNotes', on-error='_onErrorReleaseNotes', loading='{{notesLoading}}') template(is='dom-if', if='[[securityMessages.length]]') div.security-messages security-messages-card(messages='[[securityMessages]]') @@ -57,3 +59,8 @@ div#grid aside(secondary) [[item.desc]] paper-icon-button.button(icon='open-in-new', slot='item-icon', alt='[[item.text]]', tabindex=-1) +.release-notes + paper-card(heading="{{localize('dashboardView.releaseNotes')}}") + marked-element.release-notes-markdown(markdown="[[releaseNotes]]") + div(slot="markdown-html") + \ No newline at end of file From af49fce21e31af2e39cfb628f94c75967fcd5179 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 28 Jul 2025 12:41:50 +0000 Subject: [PATCH 02/13] updated release notes in centraldashboard --- .../centraldashboard/public/assets/i18n/languages.json | 8 ++++++-- .../centraldashboard/public/components/dashboard-view.css | 7 ++++++- .../centraldashboard/public/components/dashboard-view.js | 4 ++-- .../centraldashboard/public/components/dashboard-view.pug | 5 +++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index e6fdc10783d..e04ae386778 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -27,7 +27,9 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Official Kubeflow Docs", "dashboardView.docItemOfficialKubeflowDocsDesc": "Advanced documentation for installing, running, and using Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", - "dashboardView.releaseNotes": "Latest changes in our beta images (english only)", + "dashboardView.releaseNotes": "Latest changes in our notebook images", + "dashboardView.releaseNotesLastUpdated": "Last updated", + "dashboardView.releaseNotesEnglish": "(Release notes in english only)", "dashboardView.releaseNotesError": "Error generating release notes", "activityView.msgSelectNamespace": "Select a workspace to see recent events", "activityView.errNoActivities": "No activities for workspace {namespace}", @@ -182,7 +184,9 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Documents Kubeflow Officiels", "dashboardView.docItemOfficialKubeflowDocsDesc": "Documentation avancé pour installer, exécuter et utiliser Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", - "dashboardView.releaseNotes": "Derniers changements dans nos images bêta (anglais seulement)", + "dashboardView.releaseNotes": "Derniers changements dans nos images de bloc-notes", + "dashboardView.releaseNotesLastUpdated": "Dernière mise à jour", + "dashboardView.releaseNotesEnglish": "(Notes de changements en anglais uniquement)", "dashboardView.releaseNotesError": "Erreur lors de la génération des notes de version", "activityView.msgSelectNamespace": "Sélectionner un espace de travail pour voir les activités récentes", "activityView.errNoActivities": "Aucune activité pour l'espace de travail {namespace}", diff --git a/components/centraldashboard/public/components/dashboard-view.css b/components/centraldashboard/public/components/dashboard-view.css index f754e629775..4bd870deb83 100644 --- a/components/centraldashboard/public/components/dashboard-view.css +++ b/components/centraldashboard/public/components/dashboard-view.css @@ -28,8 +28,13 @@ margin: 0 auto; } +.release-notes aside { + padding-left: 16px; + color: var(--paper-item-body-secondary-color, var(--secondary-text-color)) +} + .release-notes-markdown { - padding: 0.5em 1em; + padding-left: 16px; } .release-notes-markdown a { diff --git a/components/centraldashboard/public/components/dashboard-view.js b/components/centraldashboard/public/components/dashboard-view.js index ecb881b4b10..d1b2860d811 100644 --- a/components/centraldashboard/public/components/dashboard-view.js +++ b/components/centraldashboard/public/components/dashboard-view.js @@ -66,8 +66,8 @@ export class DashboardView extends mixinBehaviors([AppLocalizeBehavior], utiliti } _onGetReleaseNotes(ev) { - const releaseNotes = ev.detail.response.body; - this.releaseNotes = releaseNotes; + this.releaseNotes = ev.detail.response.body; + this.releaseNotesDateTime = ev.detail.response.published_at; } _onErrorReleaseNotes(ev) { diff --git a/components/centraldashboard/public/components/dashboard-view.pug b/components/centraldashboard/public/components/dashboard-view.pug index ec0b41af0b9..b553303c5a7 100644 --- a/components/centraldashboard/public/components/dashboard-view.pug +++ b/components/centraldashboard/public/components/dashboard-view.pug @@ -61,6 +61,11 @@ div#grid slot='item-icon', alt='[[item.text]]', tabindex=-1) .release-notes paper-card(heading="{{localize('dashboardView.releaseNotes')}}") + aside(secondary) + p + | {{localize('dashboardView.releaseNotesLastUpdated')}}: [[releaseNotesDateTime]] + br + | {{localize('dashboardView.releaseNotesEnglish')}} marked-element.release-notes-markdown(markdown="[[releaseNotes]]") div(slot="markdown-html") \ No newline at end of file From b05c299c61ec82c4edb8dbc9865eb601e004bbd5 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 17:13:47 +0000 Subject: [PATCH 03/13] updated github release notes api call to cache results --- components/centraldashboard/app/api.ts | 53 +++++++++++++++++++ components/centraldashboard/app/server.ts | 5 +- components/centraldashboard/package-lock.json | 37 +++++++++++++ components/centraldashboard/package.json | 1 + .../public/assets/i18n/languages.json | 4 +- .../public/components/dashboard-view.css | 2 +- .../public/components/dashboard-view.pug | 13 ++--- 7 files changed, 105 insertions(+), 10 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index 98d85ba33c1..e5a1ea9d3df 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -3,6 +3,7 @@ import {KubernetesService} from './k8s_service'; import {Interval, MetricsService} from './metrics_service'; import {readFile} from 'fs/promises'; import {resolve} from 'path'; +import NodeCache from 'node-cache'; export const ERRORS = { no_metrics_service_configured: 'No metrics service configured', @@ -19,8 +20,11 @@ export const ERRORS = { invalid_delete_existing_shares: 'Failed to delete existing shares configmap' , invalid_get_shares_errors: 'Failed to load shares errors', invalid_delete_shares_errors: 'Failed to delete from shares errors', + invalid_release_notes: 'Failed to get latest release notes for zone-kubeflow-containers', }; +const releaseNotesCache = "releaseNotes"; + export function apiError(a: {res: Response, error: string, code?: number}) { const {res, error} = a; const code = a.code || 400; @@ -31,6 +35,7 @@ export function apiError(a: {res: Response, error: string, code?: number}) { export class Api { constructor( + private cache: NodeCache, private k8sService: KubernetesService, private metricsService?: MetricsService, ) {} @@ -232,6 +237,54 @@ export class Api { error: ERRORS.invalid_delete_shares_errors, }); } + }) + .get( + '/releaseNotes', + async (req: Request, res: Response) => { + try { + const releaseNotesData = this.cache.get(releaseNotesCache); + console.log("cache", releaseNotesData); + + if(releaseNotesData){ + console.log("cache2"); + res.json(releaseNotesData); + }else{ + console.log("cache3"); + const headers: Headers = new Headers() + headers.set('Content-Type', 'application/json') + headers.set('Accept', 'application/json') + + const request: RequestInfo = new Request('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { + method: 'GET', + headers: headers + }) + + const data = await fetch(request) + .then(res=>{ + if(!res.ok){ + const message = ERRORS.invalid_release_notes+': '+res.statusText; + console.error(message); + + throw new Error(message); + }else{ + return res.json(); + } + }); + + // sets the release notes in a cache + // to help with the github rate limit. + // TTL is in seconds + this.cache.set(releaseNotesCache, data, 60*60); + console.log("d", data.body); + + res.json(data); + } + }catch(e){ + return apiError({ + res, code: 500, + error: ERRORS.invalid_release_notes, + }); + } }); } diff --git a/components/centraldashboard/app/server.ts b/components/centraldashboard/app/server.ts index c88e9a5fbd8..b27db2a5f02 100644 --- a/components/centraldashboard/app/server.ts +++ b/components/centraldashboard/app/server.ts @@ -11,6 +11,9 @@ import {getMetricsService} from './metrics_service_factory'; import {PrometheusMetricsService} from "./prometheus_metrics_service"; import {PrometheusDriver} from "prometheus-query"; +import NodeCache from 'node-cache'; +const cache = new NodeCache(); + const isProduction = process.env.NODE_ENV === 'production'; const codeEnvironment = isProduction?'production':'development'; const defaultKfam = isProduction @@ -74,7 +77,7 @@ async function main() { message: `I tick, therfore I am!`, }); }); - app.use('/api', new Api(k8sService, metricsService).routes()); + app.use('/api', new Api(cache, k8sService, metricsService).routes()); app.use('/api/workgroup', new WorkgroupApi(profilesService, k8sService, registrationFlowAllowed, USERID_HEADER).routes()); app.use('/api', (req: Request, res: Response) => apiError({ diff --git a/components/centraldashboard/package-lock.json b/components/centraldashboard/package-lock.json index 6f9fdcd76aa..83bb19264a8 100644 --- a/components/centraldashboard/package-lock.json +++ b/components/centraldashboard/package-lock.json @@ -47,6 +47,7 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", + "node-cache": "^5.1.2", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" @@ -12789,6 +12790,27 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", + "dependencies": { + "clone": "2.x" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/node-cache/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/node-emoji": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", @@ -29259,6 +29281,21 @@ } } }, + "node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "requires": { + "clone": "2.x" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" + } + } + }, "node-emoji": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", diff --git a/components/centraldashboard/package.json b/components/centraldashboard/package.json index d106e5398c3..4cfe21f20e5 100644 --- a/components/centraldashboard/package.json +++ b/components/centraldashboard/package.json @@ -79,6 +79,7 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", + "node-cache": "^5.1.2", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index e04ae386778..ded1014ff85 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -30,7 +30,7 @@ "dashboardView.releaseNotes": "Latest changes in our notebook images", "dashboardView.releaseNotesLastUpdated": "Last updated", "dashboardView.releaseNotesEnglish": "(Release notes in english only)", - "dashboardView.releaseNotesError": "Error generating release notes", + "dashboardView.releaseNotesError": "Error generating release notes - Click here to see them in Github.", "activityView.msgSelectNamespace": "Select a workspace to see recent events", "activityView.errNoActivities": "No activities for workspace {namespace}", "activityView.errRetrivingActivities": "Error retrieving activities for workspace {namespace}", @@ -187,7 +187,7 @@ "dashboardView.releaseNotes": "Derniers changements dans nos images de bloc-notes", "dashboardView.releaseNotesLastUpdated": "Dernière mise à jour", "dashboardView.releaseNotesEnglish": "(Notes de changements en anglais uniquement)", - "dashboardView.releaseNotesError": "Erreur lors de la génération des notes de version", + "dashboardView.releaseNotesError": "Erreur lors de la génération des notes de changements - Cliquez ici pour les voir dans Github.", "activityView.msgSelectNamespace": "Sélectionner un espace de travail pour voir les activités récentes", "activityView.errNoActivities": "Aucune activité pour l'espace de travail {namespace}", "activityView.errRetrivingActivities": "Erreur en récupérant les activités pour l'espace de travail {namespace}", diff --git a/components/centraldashboard/public/components/dashboard-view.css b/components/centraldashboard/public/components/dashboard-view.css index 4bd870deb83..1f05e5a3e46 100644 --- a/components/centraldashboard/public/components/dashboard-view.css +++ b/components/centraldashboard/public/components/dashboard-view.css @@ -30,7 +30,7 @@ .release-notes aside { padding-left: 16px; - color: var(--paper-item-body-secondary-color, var(--secondary-text-color)) + color: var(--paper-item-body-secondary-color, var(--secondary-text-color)); } .release-notes-markdown { diff --git a/components/centraldashboard/public/components/dashboard-view.pug b/components/centraldashboard/public/components/dashboard-view.pug index b553303c5a7..039cf40b9da 100644 --- a/components/centraldashboard/public/components/dashboard-view.pug +++ b/components/centraldashboard/public/components/dashboard-view.pug @@ -1,4 +1,4 @@ -iron-ajax(auto, url='https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', handle-as='json', +iron-ajax(auto, url='/api/releaseNotes', handle-as='json', on-response='_onGetReleaseNotes', on-error='_onErrorReleaseNotes', loading='{{notesLoading}}') template(is='dom-if', if='[[securityMessages.length]]') div.security-messages @@ -61,11 +61,12 @@ div#grid slot='item-icon', alt='[[item.text]]', tabindex=-1) .release-notes paper-card(heading="{{localize('dashboardView.releaseNotes')}}") - aside(secondary) - p - | {{localize('dashboardView.releaseNotesLastUpdated')}}: [[releaseNotesDateTime]] - br - | {{localize('dashboardView.releaseNotesEnglish')}} + aside(secondary) + p + span {{localize('dashboardView.releaseNotesEnglish')}} + template(is='dom-if', if='[[releaseNotesDateTime]]') + br + span {{localize('dashboardView.releaseNotesLastUpdated')}}: [[releaseNotesDateTime]] marked-element.release-notes-markdown(markdown="[[releaseNotes]]") div(slot="markdown-html") \ No newline at end of file From d71c2e622f5bb10ed6f71096d187756b9bd3bc06 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 17:33:44 +0000 Subject: [PATCH 04/13] fixed linting --- components/centraldashboard/app/api.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index e5a1ea9d3df..a4f4254035c 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -250,14 +250,14 @@ export class Api { res.json(releaseNotesData); }else{ console.log("cache3"); - const headers: Headers = new Headers() - headers.set('Content-Type', 'application/json') - headers.set('Accept', 'application/json') + const headers: Headers = new Headers(); + headers.set('Content-Type', 'application/json'); + headers.set('Accept', 'application/json'); const request: RequestInfo = new Request('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { method: 'GET', - headers: headers - }) + headers, + }); const data = await fetch(request) .then(res=>{ From f143e432ffe61cc8770d3f6ba5d9d56111be54d2 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 17:42:16 +0000 Subject: [PATCH 05/13] added debugging logs --- components/centraldashboard/app/api.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index a4f4254035c..5a0ee50ad18 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -280,6 +280,8 @@ export class Api { res.json(data); } }catch(e){ + console.error(e); + return apiError({ res, code: 500, error: ERRORS.invalid_release_notes, From abf4714c77920ec53354ed890572ae4b9b1c0709 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 18:05:35 +0000 Subject: [PATCH 06/13] updatede headers --- components/centraldashboard/app/api.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index 5a0ee50ad18..e7e6473f929 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -250,13 +250,13 @@ export class Api { res.json(releaseNotesData); }else{ console.log("cache3"); - const headers: Headers = new Headers(); - headers.set('Content-Type', 'application/json'); - headers.set('Accept', 'application/json'); const request: RequestInfo = new Request('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { method: 'GET', - headers, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }, }); const data = await fetch(request) @@ -281,7 +281,7 @@ export class Api { } }catch(e){ console.error(e); - + return apiError({ res, code: 500, error: ERRORS.invalid_release_notes, From 7ec3ac205d828f343f9079f52f0cf5278628733a Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 18:22:02 +0000 Subject: [PATCH 07/13] updated request code --- components/centraldashboard/app/api.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index e7e6473f929..4f7dcc511ee 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -251,15 +251,13 @@ export class Api { }else{ console.log("cache3"); - const request: RequestInfo = new Request('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { + const data = await fetch('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { method: 'GET', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, - }); - - const data = await fetch(request) + }) .then(res=>{ if(!res.ok){ const message = ERRORS.invalid_release_notes+': '+res.statusText; From ab583de1dd4f6b2f11589e0a6e273f05e7b20295 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 18:44:05 +0000 Subject: [PATCH 08/13] added fetch import --- components/centraldashboard/app/api.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index 4f7dcc511ee..cbeec07fd94 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -1,8 +1,7 @@ import {Router, Request, Response, NextFunction} from 'express'; import {KubernetesService} from './k8s_service'; import {Interval, MetricsService} from './metrics_service'; -import {readFile} from 'fs/promises'; -import {resolve} from 'path'; +import fetch from 'node-fetch'; import NodeCache from 'node-cache'; export const ERRORS = { From 43118e866e9e7bab33e29808b0f05fc22bc29dd0 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 11 Aug 2025 20:30:20 +0000 Subject: [PATCH 09/13] updated node-cache version --- components/centraldashboard/app/api.ts | 7 ++-- components/centraldashboard/app/server.ts | 5 +-- components/centraldashboard/package-lock.json | 42 ++++++++++++++----- components/centraldashboard/package.json | 3 +- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index cbeec07fd94..16b5bdbf759 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -2,7 +2,9 @@ import {Router, Request, Response, NextFunction} from 'express'; import {KubernetesService} from './k8s_service'; import {Interval, MetricsService} from './metrics_service'; import fetch from 'node-fetch'; + import NodeCache from 'node-cache'; +const cache = new NodeCache(); export const ERRORS = { no_metrics_service_configured: 'No metrics service configured', @@ -34,7 +36,6 @@ export function apiError(a: {res: Response, error: string, code?: number}) { export class Api { constructor( - private cache: NodeCache, private k8sService: KubernetesService, private metricsService?: MetricsService, ) {} @@ -241,7 +242,7 @@ export class Api { '/releaseNotes', async (req: Request, res: Response) => { try { - const releaseNotesData = this.cache.get(releaseNotesCache); + const releaseNotesData = cache.get(releaseNotesCache); console.log("cache", releaseNotesData); if(releaseNotesData){ @@ -271,7 +272,7 @@ export class Api { // sets the release notes in a cache // to help with the github rate limit. // TTL is in seconds - this.cache.set(releaseNotesCache, data, 60*60); + cache.set(releaseNotesCache, data, 60*60); console.log("d", data.body); res.json(data); diff --git a/components/centraldashboard/app/server.ts b/components/centraldashboard/app/server.ts index b27db2a5f02..c88e9a5fbd8 100644 --- a/components/centraldashboard/app/server.ts +++ b/components/centraldashboard/app/server.ts @@ -11,9 +11,6 @@ import {getMetricsService} from './metrics_service_factory'; import {PrometheusMetricsService} from "./prometheus_metrics_service"; import {PrometheusDriver} from "prometheus-query"; -import NodeCache from 'node-cache'; -const cache = new NodeCache(); - const isProduction = process.env.NODE_ENV === 'production'; const codeEnvironment = isProduction?'production':'development'; const defaultKfam = isProduction @@ -77,7 +74,7 @@ async function main() { message: `I tick, therfore I am!`, }); }); - app.use('/api', new Api(cache, k8sService, metricsService).routes()); + app.use('/api', new Api(k8sService, metricsService).routes()); app.use('/api/workgroup', new WorkgroupApi(profilesService, k8sService, registrationFlowAllowed, USERID_HEADER).routes()); app.use('/api', (req: Request, res: Response) => apiError({ diff --git a/components/centraldashboard/package-lock.json b/components/centraldashboard/package-lock.json index 83bb19264a8..0dc99a0f287 100644 --- a/components/centraldashboard/package-lock.json +++ b/components/centraldashboard/package-lock.json @@ -47,7 +47,7 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", - "node-cache": "^5.1.2", + "node-cache": "4.1", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" @@ -62,6 +62,7 @@ "@types/express-serve-static-core": "^4.19.0", "@types/gapi.client.monitoring": "^3.0.1", "@types/jasmine": "^3.4.2", + "@types/node-cache": "^4.1.3", "@types/node-fetch": "^2.5.2", "@types/puppeteer": "^2.0.0", "@types/serve-static": "^1.15.5", @@ -2736,6 +2737,16 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/node-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/node-cache/-/node-cache-4.1.3.tgz", + "integrity": "sha512-3hsqnv3H1zkOhjygJaJUYmgz5+FcPO3vejBX7cE9/cnuINOJYrzkfOnUCvpwGe9kMZANIHJA7J5pOdeyv52OEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node-fetch": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.2.tgz", @@ -12791,15 +12802,16 @@ "dev": true }, "node_modules/node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz", + "integrity": "sha512-1IdglJ3+6RO7j2jGVSbWG7CD/H7axG770BbuopZNDqKpQu1ol89xC4Qc+hd6uBEewjsoCZ6xRIY8BRa5PkHgTQ==", "license": "MIT", "dependencies": { - "clone": "2.x" + "clone": "2.x", + "lodash": "4.x" }, "engines": { - "node": ">= 8.0.0" + "node": ">= 0.4.6" } }, "node_modules/node-cache/node_modules/clone": { @@ -21440,6 +21452,15 @@ "undici-types": "~5.26.4" } }, + "@types/node-cache": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/node-cache/-/node-cache-4.1.3.tgz", + "integrity": "sha512-3hsqnv3H1zkOhjygJaJUYmgz5+FcPO3vejBX7cE9/cnuINOJYrzkfOnUCvpwGe9kMZANIHJA7J5pOdeyv52OEw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/node-fetch": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.2.tgz", @@ -29282,11 +29303,12 @@ } }, "node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz", + "integrity": "sha512-1IdglJ3+6RO7j2jGVSbWG7CD/H7axG770BbuopZNDqKpQu1ol89xC4Qc+hd6uBEewjsoCZ6xRIY8BRa5PkHgTQ==", "requires": { - "clone": "2.x" + "clone": "2.x", + "lodash": "4.x" }, "dependencies": { "clone": { diff --git a/components/centraldashboard/package.json b/components/centraldashboard/package.json index 4cfe21f20e5..bdad6d58158 100644 --- a/components/centraldashboard/package.json +++ b/components/centraldashboard/package.json @@ -79,7 +79,7 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", - "node-cache": "^5.1.2", + "node-cache": "4.1", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" @@ -94,6 +94,7 @@ "@types/express-serve-static-core": "^4.19.0", "@types/gapi.client.monitoring": "^3.0.1", "@types/jasmine": "^3.4.2", + "@types/node-cache": "^4.1.3", "@types/node-fetch": "^2.5.2", "@types/puppeteer": "^2.0.0", "@types/serve-static": "^1.15.5", From 6a015a91eedd4ea5f4ac37d6c0f89e380cd5fa95 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Tue, 12 Aug 2025 12:59:52 +0000 Subject: [PATCH 10/13] updated to use a different node-cache fork --- components/centraldashboard/app/api.ts | 2 +- components/centraldashboard/package-lock.json | 139 ++++++++++-------- components/centraldashboard/package.json | 3 +- 3 files changed, 82 insertions(+), 62 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index 16b5bdbf759..b5d7e912368 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -3,7 +3,7 @@ import {KubernetesService} from './k8s_service'; import {Interval, MetricsService} from './metrics_service'; import fetch from 'node-fetch'; -import NodeCache from 'node-cache'; +import NodeCache from '@cacheable/node-cache'; const cache = new NodeCache(); export const ERRORS = { diff --git a/components/centraldashboard/package-lock.json b/components/centraldashboard/package-lock.json index 0dc99a0f287..1e3181e2536 100644 --- a/components/centraldashboard/package-lock.json +++ b/components/centraldashboard/package-lock.json @@ -10,6 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/polyfill": "^7.6.0", + "@cacheable/node-cache": "^1.6.1", "@google-cloud/monitoring": "^4.1.0", "@grpc/grpc-js": "^1.10.8", "@kubernetes/client-node": "^0.19.0", @@ -47,7 +48,6 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", - "node-cache": "4.1", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" @@ -62,7 +62,6 @@ "@types/express-serve-static-core": "^4.19.0", "@types/gapi.client.monitoring": "^3.0.1", "@types/jasmine": "^3.4.2", - "@types/node-cache": "^4.1.3", "@types/node-fetch": "^2.5.2", "@types/puppeteer": "^2.0.0", "@types/serve-static": "^1.15.5", @@ -1252,6 +1251,17 @@ "node": ">=6.9.0" } }, + "node_modules/@cacheable/node-cache": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.6.1.tgz", + "integrity": "sha512-EhLZ7xC9RjzXK/0Hi64LtvEYp4ZPjVtt26eBXWEitE2M6yLAatwLhI6KJ8iWSkDb/2Q0BGe5nkwPcV4OuMjkJw==", + "license": "MIT", + "dependencies": { + "cacheable": "^1.10.3", + "hookified": "^1.10.0", + "keyv": "^5.4.0" + } + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -1787,6 +1797,12 @@ "jsep": "^0.4.0||^1.0.0" } }, + "node_modules/@keyv/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", + "license": "MIT" + }, "node_modules/@kubernetes/client-node": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.19.0.tgz", @@ -2737,16 +2753,6 @@ "undici-types": "~5.26.4" } }, - "node_modules/@types/node-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/node-cache/-/node-cache-4.1.3.tgz", - "integrity": "sha512-3hsqnv3H1zkOhjygJaJUYmgz5+FcPO3vejBX7cE9/cnuINOJYrzkfOnUCvpwGe9kMZANIHJA7J5pOdeyv52OEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node-fetch": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.2.tgz", @@ -4647,6 +4653,16 @@ "node": ">=0.10.0" } }, + "node_modules/cacheable": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", + "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", + "license": "MIT", + "dependencies": { + "hookified": "^1.10.0", + "keyv": "^5.4.0" + } + }, "node_modules/cachedir": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", @@ -9485,6 +9501,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "node_modules/hookified": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", + "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==", + "license": "MIT" + }, "node_modules/hosted-git-info": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", @@ -11447,6 +11469,15 @@ "node": ">=10" } }, + "node_modules/keyv": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", + "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.0" + } + }, "node_modules/kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -12801,28 +12832,6 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, - "node_modules/node-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz", - "integrity": "sha512-1IdglJ3+6RO7j2jGVSbWG7CD/H7axG770BbuopZNDqKpQu1ol89xC4Qc+hd6uBEewjsoCZ6xRIY8BRa5PkHgTQ==", - "license": "MIT", - "dependencies": { - "clone": "2.x", - "lodash": "4.x" - }, - "engines": { - "node": ">= 0.4.6" - } - }, - "node_modules/node-cache/node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "node_modules/node-emoji": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", @@ -20143,6 +20152,16 @@ "@babel/helper-validator-identifier": "^7.25.9" } }, + "@cacheable/node-cache": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.6.1.tgz", + "integrity": "sha512-EhLZ7xC9RjzXK/0Hi64LtvEYp4ZPjVtt26eBXWEitE2M6yLAatwLhI6KJ8iWSkDb/2Q0BGe5nkwPcV4OuMjkJw==", + "requires": { + "cacheable": "^1.10.3", + "hookified": "^1.10.0", + "keyv": "^5.4.0" + } + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -20552,6 +20571,11 @@ "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", "requires": {} }, + "@keyv/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==" + }, "@kubernetes/client-node": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.19.0.tgz", @@ -21452,15 +21476,6 @@ "undici-types": "~5.26.4" } }, - "@types/node-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/node-cache/-/node-cache-4.1.3.tgz", - "integrity": "sha512-3hsqnv3H1zkOhjygJaJUYmgz5+FcPO3vejBX7cE9/cnuINOJYrzkfOnUCvpwGe9kMZANIHJA7J5pOdeyv52OEw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/node-fetch": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.2.tgz", @@ -23018,6 +23033,15 @@ "unset-value": "^1.0.0" } }, + "cacheable": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", + "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", + "requires": { + "hookified": "^1.10.0", + "keyv": "^5.4.0" + } + }, "cachedir": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", @@ -26715,6 +26739,11 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hookified": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", + "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==" + }, "hosted-git-info": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", @@ -28217,6 +28246,14 @@ } } }, + "keyv": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", + "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", + "requires": { + "@keyv/serialize": "^1.1.0" + } + }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -29302,22 +29339,6 @@ } } }, - "node-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz", - "integrity": "sha512-1IdglJ3+6RO7j2jGVSbWG7CD/H7axG770BbuopZNDqKpQu1ol89xC4Qc+hd6uBEewjsoCZ6xRIY8BRa5PkHgTQ==", - "requires": { - "clone": "2.x", - "lodash": "4.x" - }, - "dependencies": { - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==" - } - } - }, "node-emoji": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", diff --git a/components/centraldashboard/package.json b/components/centraldashboard/package.json index bdad6d58158..c142008f7f7 100644 --- a/components/centraldashboard/package.json +++ b/components/centraldashboard/package.json @@ -42,6 +42,7 @@ "homepage": "https://github.com/kubeflow/kubeflow#readme", "dependencies": { "@babel/polyfill": "^7.6.0", + "@cacheable/node-cache": "^1.6.1", "@google-cloud/monitoring": "^4.1.0", "@grpc/grpc-js": "^1.10.8", "@kubernetes/client-node": "^0.19.0", @@ -79,7 +80,6 @@ "chartjs-plugin-crosshair": "^1.1.4", "express": "^4.21.2", "lodash": "^4.17.21", - "node-cache": "4.1", "node-fetch": "^2.6.7", "prometheus-query": "^3.3.2", "web-animations-js": "^2.3.2" @@ -94,7 +94,6 @@ "@types/express-serve-static-core": "^4.19.0", "@types/gapi.client.monitoring": "^3.0.1", "@types/jasmine": "^3.4.2", - "@types/node-cache": "^4.1.3", "@types/node-fetch": "^2.5.2", "@types/puppeteer": "^2.0.0", "@types/serve-static": "^1.15.5", From f42829a5b2572831a48eb3521d0b324d5670dbe0 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Tue, 12 Aug 2025 13:33:16 +0000 Subject: [PATCH 11/13] cleaned out calls to github --- .../public/assets/i18n/languages.json | 10 ++++------ .../public/components/dashboard-view.css | 13 ------------- .../public/components/dashboard-view.js | 11 +---------- .../public/components/dashboard-view.pug | 19 +++++++++---------- 4 files changed, 14 insertions(+), 39 deletions(-) diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index ded1014ff85..cdd3f538b89 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -27,10 +27,9 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Official Kubeflow Docs", "dashboardView.docItemOfficialKubeflowDocsDesc": "Advanced documentation for installing, running, and using Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", - "dashboardView.releaseNotes": "Latest changes in our notebook images", - "dashboardView.releaseNotesLastUpdated": "Last updated", + "dashboardView.releaseNotes": "Latest changes in our notebook server images", "dashboardView.releaseNotesEnglish": "(Release notes in english only)", - "dashboardView.releaseNotesError": "Error generating release notes - Click here to see them in Github.", + "dashboardView.releaseNotesMessage": "View the latest release notes for our notebook server images.", "activityView.msgSelectNamespace": "Select a workspace to see recent events", "activityView.errNoActivities": "No activities for workspace {namespace}", "activityView.errRetrivingActivities": "Error retrieving activities for workspace {namespace}", @@ -184,10 +183,9 @@ "dashboardView.docItemOfficialKubeflowDocsText": "Documents Kubeflow Officiels", "dashboardView.docItemOfficialKubeflowDocsDesc": "Documentation avancé pour installer, exécuter et utiliser Kubeflow", "dashboardView.docItemOfficialKubeflowDocsLink": "https://www.kubeflow.org/docs/", - "dashboardView.releaseNotes": "Derniers changements dans nos images de bloc-notes", - "dashboardView.releaseNotesLastUpdated": "Dernière mise à jour", + "dashboardView.releaseNotes": "Derniers changements dans nos images de serveurs bloc-notes", "dashboardView.releaseNotesEnglish": "(Notes de changements en anglais uniquement)", - "dashboardView.releaseNotesError": "Erreur lors de la génération des notes de changements - Cliquez ici pour les voir dans Github.", + "dashboardView.releaseNotesMessage": "Consultez les dernières notes de changements de nos images de serveurs bloc-notes.", "activityView.msgSelectNamespace": "Sélectionner un espace de travail pour voir les activités récentes", "activityView.errNoActivities": "Aucune activité pour l'espace de travail {namespace}", "activityView.errRetrivingActivities": "Erreur en récupérant les activités pour l'espace de travail {namespace}", diff --git a/components/centraldashboard/public/components/dashboard-view.css b/components/centraldashboard/public/components/dashboard-view.css index 1f05e5a3e46..1741b6dfacd 100644 --- a/components/centraldashboard/public/components/dashboard-view.css +++ b/components/centraldashboard/public/components/dashboard-view.css @@ -28,19 +28,6 @@ margin: 0 auto; } -.release-notes aside { - padding-left: 16px; - color: var(--paper-item-body-secondary-color, var(--secondary-text-color)); -} - -.release-notes-markdown { - padding-left: 16px; -} - -.release-notes-markdown a { - color: revert; -} - .security-messages { width: 80%; margin: 0 auto; diff --git a/components/centraldashboard/public/components/dashboard-view.js b/components/centraldashboard/public/components/dashboard-view.js index d1b2860d811..a4baa087f6f 100644 --- a/components/centraldashboard/public/components/dashboard-view.js +++ b/components/centraldashboard/public/components/dashboard-view.js @@ -4,7 +4,7 @@ import '@polymer/paper-card/paper-card.js'; import '@polymer/paper-ripple/paper-ripple.js'; import '@polymer/paper-item/paper-icon-item.js'; import '@polymer/paper-icon-button/paper-icon-button.js'; -import '@polymer/marked-element/marked-element.js'; + // eslint-disable-next-line max-len import {AppLocalizeBehavior} from '@polymer/app-localize-behavior/app-localize-behavior.js'; import {mixinBehaviors} from '@polymer/polymer/lib/legacy/class.js'; @@ -64,15 +64,6 @@ export class DashboardView extends mixinBehaviors([AppLocalizeBehavior], utiliti this.platformDetails = getGCPData(gcpProject); } } - - _onGetReleaseNotes(ev) { - this.releaseNotes = ev.detail.response.body; - this.releaseNotesDateTime = ev.detail.response.published_at; - } - - _onErrorReleaseNotes(ev) { - this.releaseNotes = this.localize('dashboardView.releaseNotesError'); - } } customElements.define('dashboard-view', DashboardView); diff --git a/components/centraldashboard/public/components/dashboard-view.pug b/components/centraldashboard/public/components/dashboard-view.pug index 039cf40b9da..287fb93399a 100644 --- a/components/centraldashboard/public/components/dashboard-view.pug +++ b/components/centraldashboard/public/components/dashboard-view.pug @@ -1,5 +1,3 @@ -iron-ajax(auto, url='/api/releaseNotes', handle-as='json', - on-response='_onGetReleaseNotes', on-error='_onErrorReleaseNotes', loading='{{notesLoading}}') template(is='dom-if', if='[[securityMessages.length]]') div.security-messages security-messages-card(messages='[[securityMessages]]') @@ -61,12 +59,13 @@ div#grid slot='item-icon', alt='[[item.text]]', tabindex=-1) .release-notes paper-card(heading="{{localize('dashboardView.releaseNotes')}}") - aside(secondary) - p - span {{localize('dashboardView.releaseNotesEnglish')}} - template(is='dom-if', if='[[releaseNotesDateTime]]') - br - span {{localize('dashboardView.releaseNotesLastUpdated')}}: [[releaseNotesDateTime]] - marked-element.release-notes-markdown(markdown="[[releaseNotes]]") - div(slot="markdown-html") + a.link(href='https://github.com/StatCan/zone-kubeflow-containers/releases/latest', tabindex='-1', + target='_blank', rel='noopener noreferrer') + paper-icon-item.external + paper-ripple + paper-item-body(two-line) + .header {{localize('dashboardView.releaseNotesMessage')}} + aside(secondary) {{localize('dashboardView.releaseNotesEnglish')}} + paper-icon-button.button(icon='open-in-new', + slot='item-icon', alt="{{localize('dashboardView.releaseNotesMessage')}}", tabindex=-1) \ No newline at end of file From cd050a63b712c4ba3e5909f405f606bcffbb9a52 Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Tue, 12 Aug 2025 13:36:16 +0000 Subject: [PATCH 12/13] reverted server side changes for calling github api --- components/centraldashboard/app/api.ts | 59 +-------- components/centraldashboard/package-lock.json | 117 ------------------ components/centraldashboard/package.json | 2 - 3 files changed, 3 insertions(+), 175 deletions(-) diff --git a/components/centraldashboard/app/api.ts b/components/centraldashboard/app/api.ts index b5d7e912368..1bd2f3a96f6 100644 --- a/components/centraldashboard/app/api.ts +++ b/components/centraldashboard/app/api.ts @@ -1,10 +1,8 @@ import {Router, Request, Response, NextFunction} from 'express'; import {KubernetesService} from './k8s_service'; import {Interval, MetricsService} from './metrics_service'; -import fetch from 'node-fetch'; - -import NodeCache from '@cacheable/node-cache'; -const cache = new NodeCache(); +import {readFile} from 'fs/promises'; +import {resolve} from 'path'; export const ERRORS = { no_metrics_service_configured: 'No metrics service configured', @@ -21,11 +19,8 @@ export const ERRORS = { invalid_delete_existing_shares: 'Failed to delete existing shares configmap' , invalid_get_shares_errors: 'Failed to load shares errors', invalid_delete_shares_errors: 'Failed to delete from shares errors', - invalid_release_notes: 'Failed to get latest release notes for zone-kubeflow-containers', }; -const releaseNotesCache = "releaseNotes"; - export function apiError(a: {res: Response, error: string, code?: number}) { const {res, error} = a; const code = a.code || 400; @@ -237,54 +232,6 @@ export class Api { error: ERRORS.invalid_delete_shares_errors, }); } - }) - .get( - '/releaseNotes', - async (req: Request, res: Response) => { - try { - const releaseNotesData = cache.get(releaseNotesCache); - console.log("cache", releaseNotesData); - - if(releaseNotesData){ - console.log("cache2"); - res.json(releaseNotesData); - }else{ - console.log("cache3"); - - const data = await fetch('https://api.github.com/repos/statcan/zone-kubeflow-containers/releases/latest', { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, - }) - .then(res=>{ - if(!res.ok){ - const message = ERRORS.invalid_release_notes+': '+res.statusText; - console.error(message); - - throw new Error(message); - }else{ - return res.json(); - } - }); - - // sets the release notes in a cache - // to help with the github rate limit. - // TTL is in seconds - cache.set(releaseNotesCache, data, 60*60); - console.log("d", data.body); - - res.json(data); - } - }catch(e){ - console.error(e); - - return apiError({ - res, code: 500, - error: ERRORS.invalid_release_notes, - }); - } }); } @@ -302,4 +249,4 @@ export class Api { const languagelist = Array.from(new Set(languages.map(lang => lang.split(/-|;/)[0]))); return languagelist; } -} +} \ No newline at end of file diff --git a/components/centraldashboard/package-lock.json b/components/centraldashboard/package-lock.json index 1e3181e2536..deefb19eadb 100644 --- a/components/centraldashboard/package-lock.json +++ b/components/centraldashboard/package-lock.json @@ -10,7 +10,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/polyfill": "^7.6.0", - "@cacheable/node-cache": "^1.6.1", "@google-cloud/monitoring": "^4.1.0", "@grpc/grpc-js": "^1.10.8", "@kubernetes/client-node": "^0.19.0", @@ -26,7 +25,6 @@ "@polymer/iron-media-query": "^3.0.1", "@polymer/iron-pages": "^3.0.0", "@polymer/iron-selector": "^3.0.0", - "@polymer/marked-element": "^3.0.1", "@polymer/neon-animation": "^3.0.1", "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", @@ -1251,17 +1249,6 @@ "node": ">=6.9.0" } }, - "node_modules/@cacheable/node-cache": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.6.1.tgz", - "integrity": "sha512-EhLZ7xC9RjzXK/0Hi64LtvEYp4ZPjVtt26eBXWEitE2M6yLAatwLhI6KJ8iWSkDb/2Q0BGe5nkwPcV4OuMjkJw==", - "license": "MIT", - "dependencies": { - "cacheable": "^1.10.3", - "hookified": "^1.10.0", - "keyv": "^5.4.0" - } - }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -1797,12 +1784,6 @@ "jsep": "^0.4.0||^1.0.0" } }, - "node_modules/@keyv/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==", - "license": "MIT" - }, "node_modules/@kubernetes/client-node": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.19.0.tgz", @@ -2259,16 +2240,6 @@ "@polymer/polymer": "^3.0.0" } }, - "node_modules/@polymer/marked-element": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/marked-element/-/marked-element-3.0.1.tgz", - "integrity": "sha512-WJQzQetxdStVGQbyTBUBgd+hSI0Rl39uJg7b2zL3r6EfMnibzmA/YNT06M8jVZdxPF+B4SumrFWRtasVtGQRUQ==", - "license": "BSD-3-Clause", - "dependencies": { - "@polymer/polymer": "^3.0.0", - "marked": "~0.3.9" - } - }, "node_modules/@polymer/neon-animation": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/neon-animation/-/neon-animation-3.0.1.tgz", @@ -4653,16 +4624,6 @@ "node": ">=0.10.0" } }, - "node_modules/cacheable": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", - "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", - "license": "MIT", - "dependencies": { - "hookified": "^1.10.0", - "keyv": "^5.4.0" - } - }, "node_modules/cachedir": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", @@ -9501,12 +9462,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/hookified": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", - "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==", - "license": "MIT" - }, "node_modules/hosted-git-info": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", @@ -11469,15 +11424,6 @@ "node": ">=10" } }, - "node_modules/keyv": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", - "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", - "license": "MIT", - "dependencies": { - "@keyv/serialize": "^1.1.0" - } - }, "node_modules/kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -12195,18 +12141,6 @@ "node": ">=0.10.0" } }, - "node_modules/marked": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", - "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", - "license": "MIT", - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -20152,16 +20086,6 @@ "@babel/helper-validator-identifier": "^7.25.9" } }, - "@cacheable/node-cache": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.6.1.tgz", - "integrity": "sha512-EhLZ7xC9RjzXK/0Hi64LtvEYp4ZPjVtt26eBXWEitE2M6yLAatwLhI6KJ8iWSkDb/2Q0BGe5nkwPcV4OuMjkJw==", - "requires": { - "cacheable": "^1.10.3", - "hookified": "^1.10.0", - "keyv": "^5.4.0" - } - }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -20571,11 +20495,6 @@ "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", "requires": {} }, - "@keyv/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-RlDgexML7Z63Q8BSaqhXdCYNBy/JQnqYIwxofUrNLGCblOMHp+xux2Q8nLMLlPpgHQPoU0Do8Z6btCpRBEqZ8g==" - }, "@kubernetes/client-node": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@kubernetes/client-node/-/client-node-0.19.0.tgz", @@ -20987,15 +20906,6 @@ "@polymer/polymer": "^3.0.0" } }, - "@polymer/marked-element": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/marked-element/-/marked-element-3.0.1.tgz", - "integrity": "sha512-WJQzQetxdStVGQbyTBUBgd+hSI0Rl39uJg7b2zL3r6EfMnibzmA/YNT06M8jVZdxPF+B4SumrFWRtasVtGQRUQ==", - "requires": { - "@polymer/polymer": "^3.0.0", - "marked": "~0.3.9" - } - }, "@polymer/neon-animation": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/neon-animation/-/neon-animation-3.0.1.tgz", @@ -23033,15 +22943,6 @@ "unset-value": "^1.0.0" } }, - "cacheable": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.10.3.tgz", - "integrity": "sha512-M6p10iJ/VT0wT7TLIGUnm958oVrU2cUK8pQAVU21Zu7h8rbk/PeRtRWrvHJBql97Bhzk3g1N6+2VKC+Rjxna9Q==", - "requires": { - "hookified": "^1.10.0", - "keyv": "^5.4.0" - } - }, "cachedir": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", @@ -26739,11 +26640,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hookified": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.11.0.tgz", - "integrity": "sha512-aDdIN3GyU5I6wextPplYdfmWCo+aLmjjVbntmX6HLD5RCi/xKsivYEBhnRD+d9224zFf008ZpLMPlWF0ZodYZw==" - }, "hosted-git-info": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", @@ -28246,14 +28142,6 @@ } } }, - "keyv": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.0.tgz", - "integrity": "sha512-QG7qR2tijh1ftOvClut4YKKg1iW6cx3GZsKoGyJPxHkGWK9oJhG9P3j5deP0QQOGDowBMVQFaP+Vm4NpGYvmIQ==", - "requires": { - "@keyv/serialize": "^1.1.0" - } - }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", @@ -28811,11 +28699,6 @@ "object-visit": "^1.0.0" } }, - "marked": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", - "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==" - }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", diff --git a/components/centraldashboard/package.json b/components/centraldashboard/package.json index c142008f7f7..cf136ad2394 100644 --- a/components/centraldashboard/package.json +++ b/components/centraldashboard/package.json @@ -42,7 +42,6 @@ "homepage": "https://github.com/kubeflow/kubeflow#readme", "dependencies": { "@babel/polyfill": "^7.6.0", - "@cacheable/node-cache": "^1.6.1", "@google-cloud/monitoring": "^4.1.0", "@grpc/grpc-js": "^1.10.8", "@kubernetes/client-node": "^0.19.0", @@ -58,7 +57,6 @@ "@polymer/iron-media-query": "^3.0.1", "@polymer/iron-pages": "^3.0.0", "@polymer/iron-selector": "^3.0.0", - "@polymer/marked-element": "^3.0.1", "@polymer/neon-animation": "^3.0.1", "@polymer/paper-button": "^3.0.1", "@polymer/paper-card": "^3.0.1", From 48b13207937cabacf826c6f9add5d7ce5c1a90bc Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Tue, 12 Aug 2025 23:31:14 +0000 Subject: [PATCH 13/13] updated styling of paper card rows on home dashboard page --- .../public/components/dashboard-view.css | 15 ++- .../public/components/dashboard-view.pug | 119 +++++++++--------- 2 files changed, 68 insertions(+), 66 deletions(-) diff --git a/components/centraldashboard/public/components/dashboard-view.css b/components/centraldashboard/public/components/dashboard-view.css index 1741b6dfacd..da6cadec6b3 100644 --- a/components/centraldashboard/public/components/dashboard-view.css +++ b/components/centraldashboard/public/components/dashboard-view.css @@ -16,21 +16,20 @@ } } +.dashboard-cards{ + display: flex; + align-items: center; + justify-content: center; +} + #grid { display: grid; grid-gap: .75em; /* 12px */ grid-template-columns: repeat(3, 1fr); - margin: 0 auto; -} - -.release-notes { - width: 80%; - margin: 0 auto; } -.security-messages { +.single-column { width: 80%; - margin: 0 auto; } .column { diff --git a/components/centraldashboard/public/components/dashboard-view.pug b/components/centraldashboard/public/components/dashboard-view.pug index 287fb93399a..adafef65a16 100644 --- a/components/centraldashboard/public/components/dashboard-view.pug +++ b/components/centraldashboard/public/components/dashboard-view.pug @@ -1,22 +1,57 @@ template(is='dom-if', if='[[securityMessages.length]]') - div.security-messages - security-messages-card(messages='[[securityMessages]]') -div#grid - .column - notebook-default-card(namespace='[[namespace]]', language='[[language]]', resources='[[resources]]') - .column - paper-card#Quick-Links(heading="{{localize('dashboardView.headingQuickLinks')}}") - template(is='dom-repeat', items='[[quickLinks]]') - template(is='dom-if', if='[[equals(item.type, "internal")]]') - iframe-link.link(href$="[[item.link]]") - paper-icon-item.external - paper-ripple - paper-item-body(two-line) - .header [[item.text]] - aside(secondary) [[item.desc]] - iron-icon(icon='kubeflow:bolt', slot='item-icon') - template(is='dom-if', if='[[equals(item.type, "external")]]') - a.link(href$='[[item.link]]', tabindex='-1', target='_blank') + .dashboard-cards + .single-column + security-messages-card(messages='[[securityMessages]]') +.dashboard-cards + div#grid + .column + notebook-default-card(namespace='[[namespace]]', language='[[language]]', resources='[[resources]]') + .column + paper-card#Quick-Links(heading="{{localize('dashboardView.headingQuickLinks')}}") + template(is='dom-repeat', items='[[quickLinks]]') + template(is='dom-if', if='[[equals(item.type, "internal")]]') + iframe-link.link(href$="[[item.link]]") + paper-icon-item.external + paper-ripple + paper-item-body(two-line) + .header [[item.text]] + aside(secondary) [[item.desc]] + iron-icon(icon='kubeflow:bolt', slot='item-icon') + template(is='dom-if', if='[[equals(item.type, "external")]]') + a.link(href$='[[item.link]]', tabindex='-1', target='_blank') + paper-icon-item.external + paper-ripple + paper-item-body(two-line) + .header [[item.text]] + aside(secondary) [[item.desc]] + paper-icon-button.button(icon='open-in-new', + slot='item-icon', alt='[[item.text]]', tabindex=-1) + template(is='dom-if', if='[[metrics.resourceChartsLinkText]]') + resource-chart(header-text='Cluster CPU Utilization', metric='cpu', + interval='Last60m', + external-link='[[metrics.resourceChartsLink]]', + external-link-text='[[metrics.resourceChartsLinkText]]') + resource-chart(header-text='Pod CPU Utilization', metric='podcpu', + interval='Last60m', + external-link='[[metrics.resourceChartsLink]]' + external-link-text='[[metrics.resourceChartsLinkText]]') + .column + template(is='dom-if', if='[[platformDetails.links]]') + paper-card#Platform-Links(class$='[[platformDetails.name]]', + heading='[[platformDetails.title]]', image='[[platformDetails.logo]]') + template(is='dom-repeat', items='[[platformDetails.links]]') + a.link(href$='[[item.link]]', tabindex='-1', target='_blank') + paper-icon-item.external + paper-ripple + paper-item-body(two-line) + .header [[item.headerText]] + aside(secondary) [[item.secondaryText]] + paper-icon-button.button(icon='open-in-new', + slot='item-icon', alt='[[item.text]]', tabindex=-1) + paper-card#Documentation(heading="{{localize('dashboardView.headingDocumentation')}}") + template(is='dom-repeat', items='[[documentationItems]]') + a.link(href$='[[item.link]]', tabindex='-1', + target='_blank') paper-icon-item.external paper-ripple paper-item-body(two-line) @@ -24,48 +59,16 @@ div#grid aside(secondary) [[item.desc]] paper-icon-button.button(icon='open-in-new', slot='item-icon', alt='[[item.text]]', tabindex=-1) - template(is='dom-if', if='[[metrics.resourceChartsLinkText]]') - resource-chart(header-text='Cluster CPU Utilization', metric='cpu', - interval='Last60m', - external-link='[[metrics.resourceChartsLink]]', - external-link-text='[[metrics.resourceChartsLinkText]]') - resource-chart(header-text='Pod CPU Utilization', metric='podcpu', - interval='Last60m', - external-link='[[metrics.resourceChartsLink]]' - external-link-text='[[metrics.resourceChartsLinkText]]') - .column - template(is='dom-if', if='[[platformDetails.links]]') - paper-card#Platform-Links(class$='[[platformDetails.name]]', - heading='[[platformDetails.title]]', image='[[platformDetails.logo]]') - template(is='dom-repeat', items='[[platformDetails.links]]') - a.link(href$='[[item.link]]', tabindex='-1', target='_blank') +.dashboard-cards + .single-column + paper-card(heading="{{localize('dashboardView.releaseNotes')}}") + a.link(href='https://github.com/StatCan/zone-kubeflow-containers/releases/latest', tabindex='-1', + target='_blank', rel='noopener noreferrer') paper-icon-item.external paper-ripple paper-item-body(two-line) - .header [[item.headerText]] - aside(secondary) [[item.secondaryText]] + .header {{localize('dashboardView.releaseNotesMessage')}} + aside(secondary) {{localize('dashboardView.releaseNotesEnglish')}} paper-icon-button.button(icon='open-in-new', - slot='item-icon', alt='[[item.text]]', tabindex=-1) - paper-card#Documentation(heading="{{localize('dashboardView.headingDocumentation')}}") - template(is='dom-repeat', items='[[documentationItems]]') - a.link(href$='[[item.link]]', tabindex='-1', - target='_blank') - paper-icon-item.external - paper-ripple - paper-item-body(two-line) - .header [[item.text]] - aside(secondary) [[item.desc]] - paper-icon-button.button(icon='open-in-new', - slot='item-icon', alt='[[item.text]]', tabindex=-1) -.release-notes - paper-card(heading="{{localize('dashboardView.releaseNotes')}}") - a.link(href='https://github.com/StatCan/zone-kubeflow-containers/releases/latest', tabindex='-1', - target='_blank', rel='noopener noreferrer') - paper-icon-item.external - paper-ripple - paper-item-body(two-line) - .header {{localize('dashboardView.releaseNotesMessage')}} - aside(secondary) {{localize('dashboardView.releaseNotesEnglish')}} - paper-icon-button.button(icon='open-in-new', - slot='item-icon', alt="{{localize('dashboardView.releaseNotesMessage')}}", tabindex=-1) + slot='item-icon', alt="{{localize('dashboardView.releaseNotesMessage')}}", tabindex=-1) \ No newline at end of file