From ca65b31ba827b9cbef44bb4a3c93cb31c1f06061 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Wed, 17 Apr 2024 15:44:21 +0200 Subject: [PATCH 01/23] WIP [ci skip] start implementing upgrade banner --- frontend/javascripts/maintenance_banner.tsx | 44 ++++++- frontend/javascripts/navbar.tsx | 135 ++++++++++---------- 2 files changed, 111 insertions(+), 68 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index ed709633d0c..7f4d9c30425 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -1,10 +1,12 @@ import { + getBuildInfo, listCurrentAndUpcomingMaintenances, updateNovelUserExperienceInfos, } from "admin/admin_rest_api"; import { Alert } from "antd"; import FormattedDate from "components/formatted_date"; -import { useInterval } from "libs/react_helpers"; +import dayjs from "dayjs"; +import { useFetch, useInterval } from "libs/react_helpers"; import _ from "lodash"; import constants from "oxalis/constants"; import { setNavbarHeightAction } from "oxalis/model/actions/ui_actions"; @@ -17,6 +19,7 @@ import { MaintenanceInfo } from "types/api_flow_types"; const INITIAL_DELAY = 5000; const INTERVAL_TO_FETCH_MAINTENANCES_MS = 60000; // 1min +const UPGRADE_BANNER_LOCAL_STORAGE_KEY = "upgradeBannerWasClickedAway"; const BANNER_STYLE: React.CSSProperties = { position: "absolute", @@ -144,3 +147,42 @@ export function MaintenanceBanner() { return null; } + +export function UpgradeVersionBanner() { + //require('dayjs/locale/es'); + const customParseFormat = require('dayjs/plugin/customParseFormat') + dayjs.extend(customParseFormat) + const currentDate = dayjs(); + + const isVersionOutdated = useFetch(async () => { + const buildInfo = await getBuildInfo(); + const commitDateWithoutWeekday = buildInfo.webknossos.commitDate.replace(/(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, ""); + console.log(commitDateWithoutWeekday) + const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM DD HH:mm:ss YYYY ZZ"); // todo two digit dates? test more once time tracking is merged + console.log(lastCommitDate) + const needsUpdate = currentDate.diff(lastCommitDate, 'month') >= 6; + console.log(needsUpdate); + return needsUpdate; + }, false, []) + + const shouldBannerBeShown = () => { + const lastTimeBannerWasClickedAway = localStorage.getItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY); + if (lastTimeBannerWasClickedAway != null) { + const parsedDate = dayjs(lastTimeBannerWasClickedAway); + lastTimeBannerWasClickedAway.diff(currentDate, "days")) + } + } + + return ( + + Update me! + + } + type="warning" + banner + style={BANNER_STYLE} + /> + ); +} \ No newline at end of file diff --git a/frontend/javascripts/navbar.tsx b/frontend/javascripts/navbar.tsx index fd81ad84fb1..0b2f53dffad 100644 --- a/frontend/javascripts/navbar.tsx +++ b/frontend/javascripts/navbar.tsx @@ -61,7 +61,7 @@ import { PricingEnforcedSpan } from "components/pricing_enforcers"; import { ItemType, MenuItemType, SubMenuType } from "antd/lib/menu/hooks/useItems"; import { MenuClickEventHandler } from "rc-menu/lib/interface"; import constants from "oxalis/constants"; -import { MaintenanceBanner } from "maintenance_banner"; +import { MaintenanceBanner, UpgradeVersionBanner } from "maintenance_banner"; import { getSystemColorTheme } from "theme"; const { Header } = Layout; @@ -200,34 +200,34 @@ function getAdministrationSubMenu(collapse: boolean, activeUser: APIUser) { const adminstrationSubMenuItems = isAdminOrTeamManager ? [ - { key: "/users", label: Users }, - { key: "/teams", label: Teams }, - { - key: "/projects", - label: ( - - Projects - - ), - }, - { - key: "/tasks", - label: ( - - Tasks - - ), - }, - { - key: "/taskTypes", - label: ( - - Task Types - - ), - }, - { key: "/scripts", label: Scripts }, - ] + { key: "/users", label: Users }, + { key: "/teams", label: Teams }, + { + key: "/projects", + label: ( + + Projects + + ), + }, + { + key: "/tasks", + label: ( + + Tasks + + ), + }, + { + key: "/taskTypes", + label: ( + + Task Types + + ), + }, + { key: "/scripts", label: Scripts }, + ] : []; if (features().jobsEnabled) @@ -342,15 +342,15 @@ function getHelpSubMenu( ), }, (!features().discussionBoardRequiresAdmin || isAdminOrManager) && - features().discussionBoard !== false + features().discussionBoard !== false ? { - key: "discussion-board", - label: ( - - Community Support - - ), - } + key: "discussion-board", + label: ( + + Community Support + + ), + } : null, { key: "frontend-api", @@ -591,17 +591,17 @@ function LoggedInAvatar({ const maybeOrganizationFilterInput = switchableOrganizations.length > ORGANIZATION_COUNT_THRESHOLD_FOR_SEARCH_INPUT ? [ - { - key: "input", - label: ( - - ), - }, - ] + { + key: "input", + label: ( + + ), + }, + ] : []; const isMultiMember = switchableOrganizations.length > 0; @@ -638,28 +638,28 @@ function LoggedInAvatar({ }, activeOrganization && Utils.isUserAdmin(activeUser) ? { - key: "manage-organization", - label: ( - - Manage Organization - - ), - } + key: "manage-organization", + label: ( + + Manage Organization + + ), + } : null, isMultiMember ? { - key: "switch-organization", - label: "Switch Organization", - popupClassName: "organization-switch-menu", - children: [ - ...maybeOrganizationFilterInput, - ...filteredOrganizations.slice(0, MAX_RENDERED_ORGANIZATION).map((org) => ({ - key: org.name, - onClick: () => switchTo(org), - label: org.displayName || org.name, - })), - ], - } + key: "switch-organization", + label: "Switch Organization", + popupClassName: "organization-switch-menu", + children: [ + ...maybeOrganizationFilterInput, + ...filteredOrganizations.slice(0, MAX_RENDERED_ORGANIZATION).map((org) => ({ + key: org.name, + onClick: () => switchTo(org), + label: org.displayName || org.name, + })), + ], + } : null, { key: "resetpassword", @@ -899,6 +899,7 @@ function Navbar({ })} > + Date: Wed, 17 Apr 2024 17:49:53 +0200 Subject: [PATCH 02/23] style banner and add more conditions --- frontend/javascripts/maintenance_banner.tsx | 98 ++++++++++----- frontend/javascripts/navbar.tsx | 132 ++++++++++---------- frontend/javascripts/oxalis/constants.ts | 1 + 3 files changed, 137 insertions(+), 94 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 7f4d9c30425..08f3e9d6d71 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -3,7 +3,7 @@ import { listCurrentAndUpcomingMaintenances, updateNovelUserExperienceInfos, } from "admin/admin_rest_api"; -import { Alert } from "antd"; +import { Alert, Button, Space } from "antd"; import FormattedDate from "components/formatted_date"; import dayjs from "dayjs"; import { useFetch, useInterval } from "libs/react_helpers"; @@ -149,40 +149,82 @@ export function MaintenanceBanner() { } export function UpgradeVersionBanner() { - //require('dayjs/locale/es'); - const customParseFormat = require('dayjs/plugin/customParseFormat') - dayjs.extend(customParseFormat) + const UPGRADE_BANNER_STYLE: React.CSSProperties = { + position: "absolute", + top: 0, + left: 0, + height: constants.UPGRADE_BANNER_HEIGHT, + textAlign: "center", + backgroundColor: "var(--ant-color-primary)", + color: "var(--ant-color-text-primary)", + fontWeight: 600, + fontSize: "medium", + }; + const customParseFormat = require("dayjs/plugin/customParseFormat"); + dayjs.extend(customParseFormat); const currentDate = dayjs(); - const isVersionOutdated = useFetch(async () => { - const buildInfo = await getBuildInfo(); - const commitDateWithoutWeekday = buildInfo.webknossos.commitDate.replace(/(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, ""); - console.log(commitDateWithoutWeekday) - const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM DD HH:mm:ss YYYY ZZ"); // todo two digit dates? test more once time tracking is merged - console.log(lastCommitDate) - const needsUpdate = currentDate.diff(lastCommitDate, 'month') >= 6; - console.log(needsUpdate); - return needsUpdate; - }, false, []) - - const shouldBannerBeShown = () => { + const isVersionOutdated = useFetch( + async () => { + const buildInfo = await getBuildInfo(); + const commitDateWithoutWeekday = buildInfo.webknossos.commitDate.replace( + /(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, + "", + ); + console.log(commitDateWithoutWeekday); + const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM DD HH:mm:ss YYYY ZZ"); // todo two digit dates? test more once time tracking is merged + console.log(lastCommitDate); + const needsUpdate = currentDate.diff(lastCommitDate, "month") >= 6; + console.log(needsUpdate); + return needsUpdate; + }, + false, + [], + ); + + const getShouldBannerBeShown = () => { + if (!isVersionOutdated) return true; // TODO const lastTimeBannerWasClickedAway = localStorage.getItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY); - if (lastTimeBannerWasClickedAway != null) { - const parsedDate = dayjs(lastTimeBannerWasClickedAway); - lastTimeBannerWasClickedAway.diff(currentDate, "days")) + console.log(lastTimeBannerWasClickedAway); + if (lastTimeBannerWasClickedAway == null) return true; + const parsedDate = dayjs(lastTimeBannerWasClickedAway); + return parsedDate.diff(currentDate, "days") >= 3; + }; + + const shouldBannerBeShown = getShouldBannerBeShown(); + + useEffect(() => { + if (shouldBannerBeShown) { + setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.UPGRADE_BANNER_HEIGHT); + } else { + setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT); } - } + }, [shouldBannerBeShown]); - return ( + return shouldBannerBeShown ? ( - Update me! - + + You are using an old version of WEBKNOSSOS. Switch to webknossos.org for automatic + updates and exclusive features! + + } - type="warning" banner - style={BANNER_STYLE} + style={UPGRADE_BANNER_STYLE} + closable + onClose={() => { + localStorage.setItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY, dayjs().toISOString()); + setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT); + }} + type="info" + showIcon={false} /> - ); -} \ No newline at end of file + ) : null; +} diff --git a/frontend/javascripts/navbar.tsx b/frontend/javascripts/navbar.tsx index 0b2f53dffad..6f659e17181 100644 --- a/frontend/javascripts/navbar.tsx +++ b/frontend/javascripts/navbar.tsx @@ -200,34 +200,34 @@ function getAdministrationSubMenu(collapse: boolean, activeUser: APIUser) { const adminstrationSubMenuItems = isAdminOrTeamManager ? [ - { key: "/users", label: Users }, - { key: "/teams", label: Teams }, - { - key: "/projects", - label: ( - - Projects - - ), - }, - { - key: "/tasks", - label: ( - - Tasks - - ), - }, - { - key: "/taskTypes", - label: ( - - Task Types - - ), - }, - { key: "/scripts", label: Scripts }, - ] + { key: "/users", label: Users }, + { key: "/teams", label: Teams }, + { + key: "/projects", + label: ( + + Projects + + ), + }, + { + key: "/tasks", + label: ( + + Tasks + + ), + }, + { + key: "/taskTypes", + label: ( + + Task Types + + ), + }, + { key: "/scripts", label: Scripts }, + ] : []; if (features().jobsEnabled) @@ -342,15 +342,15 @@ function getHelpSubMenu( ), }, (!features().discussionBoardRequiresAdmin || isAdminOrManager) && - features().discussionBoard !== false + features().discussionBoard !== false ? { - key: "discussion-board", - label: ( - - Community Support - - ), - } + key: "discussion-board", + label: ( + + Community Support + + ), + } : null, { key: "frontend-api", @@ -591,17 +591,17 @@ function LoggedInAvatar({ const maybeOrganizationFilterInput = switchableOrganizations.length > ORGANIZATION_COUNT_THRESHOLD_FOR_SEARCH_INPUT ? [ - { - key: "input", - label: ( - - ), - }, - ] + { + key: "input", + label: ( + + ), + }, + ] : []; const isMultiMember = switchableOrganizations.length > 0; @@ -638,28 +638,28 @@ function LoggedInAvatar({ }, activeOrganization && Utils.isUserAdmin(activeUser) ? { - key: "manage-organization", - label: ( - - Manage Organization - - ), - } + key: "manage-organization", + label: ( + + Manage Organization + + ), + } : null, isMultiMember ? { - key: "switch-organization", - label: "Switch Organization", - popupClassName: "organization-switch-menu", - children: [ - ...maybeOrganizationFilterInput, - ...filteredOrganizations.slice(0, MAX_RENDERED_ORGANIZATION).map((org) => ({ - key: org.name, - onClick: () => switchTo(org), - label: org.displayName || org.name, - })), - ], - } + key: "switch-organization", + label: "Switch Organization", + popupClassName: "organization-switch-menu", + children: [ + ...maybeOrganizationFilterInput, + ...filteredOrganizations.slice(0, MAX_RENDERED_ORGANIZATION).map((org) => ({ + key: org.name, + onClick: () => switchTo(org), + label: org.displayName || org.name, + })), + ], + } : null, { key: "resetpassword", diff --git a/frontend/javascripts/oxalis/constants.ts b/frontend/javascripts/oxalis/constants.ts index 7f62ad3177e..17b8d2bcb8e 100644 --- a/frontend/javascripts/oxalis/constants.ts +++ b/frontend/javascripts/oxalis/constants.ts @@ -314,6 +314,7 @@ const Constants = { VIEWPORT_WIDTH, DEFAULT_NAVBAR_HEIGHT: 48, MAINTENANCE_BANNER_HEIGHT: 38, + UPGRADE_BANNER_HEIGHT: 50, // For reference, the area of a large brush size (let's say, 300px) corresponds to // pi * 300 ^ 2 == 282690. // We multiply this with 5, since the labeling is not done From 6b9336620c0c8f37302b429b1416de8da7d28b38 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Wed, 17 Apr 2024 22:52:48 +0200 Subject: [PATCH 03/23] style banner --- frontend/javascripts/maintenance_banner.tsx | 13 ++++++------- frontend/javascripts/oxalis/constants.ts | 2 +- frontend/stylesheets/trace_view/_tracing_view.less | 9 +++++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 08f3e9d6d71..d3e4a10f34b 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -204,13 +204,12 @@ export function UpgradeVersionBanner() { return shouldBannerBeShown ? ( - You are using an old version of WEBKNOSSOS. Switch to webknossos.org for automatic - updates and exclusive features! - diff --git a/frontend/javascripts/oxalis/constants.ts b/frontend/javascripts/oxalis/constants.ts index 17b8d2bcb8e..309e5fa4e88 100644 --- a/frontend/javascripts/oxalis/constants.ts +++ b/frontend/javascripts/oxalis/constants.ts @@ -314,7 +314,7 @@ const Constants = { VIEWPORT_WIDTH, DEFAULT_NAVBAR_HEIGHT: 48, MAINTENANCE_BANNER_HEIGHT: 38, - UPGRADE_BANNER_HEIGHT: 50, + UPGRADE_BANNER_HEIGHT: 38, // For reference, the area of a large brush size (let's say, 300px) corresponds to // pi * 300 ^ 2 == 282690. // We multiply this with 5, since the labeling is not done diff --git a/frontend/stylesheets/trace_view/_tracing_view.less b/frontend/stylesheets/trace_view/_tracing_view.less index 7773a418953..8466eab4ad3 100644 --- a/frontend/stylesheets/trace_view/_tracing_view.less +++ b/frontend/stylesheets/trace_view/_tracing_view.less @@ -383,6 +383,15 @@ img.keyboard-mouse-icon:first-child { background-color: @dark-border !important; } } + + &.upgrade-banner { + color: var(--ant-color-primary) !important; + background: var(--ant-color-bg-container) !important; + font-weight: 700; + height: 30px; + display: flex; + align-items: center; + } } .ant-btn[disabled], From 67be3a5c8f36c2c00c0771b06839c35c3340e3e2 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 22 Apr 2024 20:06:34 +0200 Subject: [PATCH 04/23] [ci skip] WIP: styling banner --- frontend/javascripts/maintenance_banner.tsx | 14 ++++++--- .../stylesheets/trace_view/_tracing_view.less | 30 ++++++++++++------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index d3e4a10f34b..cca1d21e926 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -149,15 +149,17 @@ export function MaintenanceBanner() { } export function UpgradeVersionBanner() { + const white = "var(--ant-color-text-primary)"; + const blue = "var(--ant-color-primary)"; const UPGRADE_BANNER_STYLE: React.CSSProperties = { position: "absolute", top: 0, left: 0, height: constants.UPGRADE_BANNER_HEIGHT, textAlign: "center", - backgroundColor: "var(--ant-color-primary)", - color: "var(--ant-color-text-primary)", - fontWeight: 600, + backgroundColor: blue, + color: white, + //fontWeight: 600, fontSize: "medium", }; const customParseFormat = require("dayjs/plugin/customParseFormat"); @@ -203,13 +205,17 @@ export function UpgradeVersionBanner() { return shouldBannerBeShown ? ( You are using an old version of WEBKNOSSOS. Switch to webknossos.org for automatic updates and exclusive features! - diff --git a/frontend/stylesheets/trace_view/_tracing_view.less b/frontend/stylesheets/trace_view/_tracing_view.less index 8466eab4ad3..3c35b18c96f 100644 --- a/frontend/stylesheets/trace_view/_tracing_view.less +++ b/frontend/stylesheets/trace_view/_tracing_view.less @@ -321,6 +321,14 @@ img.keyboard-mouse-icon:first-child { color: rgba(255, 255, 255, 0.67); z-index: 1000; + .upgrade-banner{ + .ant-alert-close-icon { + .anticon, .anticon-close { + color: var(--ant-color-primary-bg) + } + } + } + &.statusbar-footer { left: 0px; bottom: 0px; @@ -357,11 +365,21 @@ img.keyboard-mouse-icon:first-child { .ant-input, .ant-input-number, .ant-radio-button-wrapper, - .ant-select > .ant-select-selector { + .ant-select > .ant-select-selector{ background-color: @dark-bg !important; color: @dark-fg !important; border-color: @dark-border; + &.upgrade-banner-button{ + background-color: var(--ant-button-primary-color) !important; + color: var(--ant-color-primary) !important; + border-color: var(--ant-button-primary-color); + height: 30px; + display: flex; + align-items: center; + + } + &:hover { border-color: var(--color-blue-zircon) !important; z-index: 1 !important; @@ -383,15 +401,7 @@ img.keyboard-mouse-icon:first-child { background-color: @dark-border !important; } } - - &.upgrade-banner { - color: var(--ant-color-primary) !important; - background: var(--ant-color-bg-container) !important; - font-weight: 700; - height: 30px; - display: flex; - align-items: center; - } + } .ant-btn[disabled], From 713cb2a2a20f6935c18a2e612dc03ce5d8a0cb14 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Wed, 24 Apr 2024 09:30:02 +0200 Subject: [PATCH 05/23] adjust styling more --- frontend/javascripts/maintenance_banner.tsx | 15 ++++++++------- frontend/javascripts/navbar.tsx | 16 ++++------------ frontend/javascripts/oxalis/constants.ts | 3 +-- .../stylesheets/trace_view/_tracing_view.less | 4 +--- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index cca1d21e926..755e3a5fe18 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -25,7 +25,7 @@ const BANNER_STYLE: React.CSSProperties = { position: "absolute", top: 0, left: 0, - height: constants.MAINTENANCE_BANNER_HEIGHT, + height: constants.BANNER_HEIGHT, }; function setNavbarHeight(newNavbarHeight: number) { @@ -119,7 +119,7 @@ export function MaintenanceBanner() { useEffect(() => { if (currentMaintenance || closestUpcomingMaintenance) { - setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.MAINTENANCE_BANNER_HEIGHT); + setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.BANNER_HEIGHT); } if (currentMaintenance == null && closestUpcomingMaintenance == null) { @@ -155,11 +155,10 @@ export function UpgradeVersionBanner() { position: "absolute", top: 0, left: 0, - height: constants.UPGRADE_BANNER_HEIGHT, + height: constants.BANNER_HEIGHT, textAlign: "center", backgroundColor: blue, color: white, - //fontWeight: 600, fontSize: "medium", }; const customParseFormat = require("dayjs/plugin/customParseFormat"); @@ -197,7 +196,7 @@ export function UpgradeVersionBanner() { useEffect(() => { if (shouldBannerBeShown) { - setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.UPGRADE_BANNER_HEIGHT); + setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.BANNER_HEIGHT); } else { setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT); } @@ -209,12 +208,14 @@ export function UpgradeVersionBanner() { message={ - You are using an old version of WEBKNOSSOS. Switch to webknossos.org for - automatic updates and exclusive features! + You are using an old version of WEBKNOSSOS. Switch to{" "} + webknossos.org for automatic updates and exclusive + features! } From 9f95bcb0804a3123ce2b0a2005d7a735469d9ba9 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Thu, 25 Apr 2024 19:21:17 +0200 Subject: [PATCH 10/23] improve styling and add testing options --- frontend/javascripts/maintenance_banner.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 5a434d11115..8dedd6d140f 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -160,6 +160,7 @@ export function UpgradeVersionBanner() { backgroundColor: blue, color: white, fontSize: "medium", + minWidth: "fit-content", }; const customParseFormat = require("dayjs/plugin/customParseFormat"); dayjs.extend(customParseFormat); @@ -167,7 +168,8 @@ export function UpgradeVersionBanner() { const isVersionOutdated = useFetch( async () => { - const buildInfo = await getBuildInfo(); + let buildInfo = await getBuildInfo(); + buildInfo.webknossos.commitDate = "Wed Apr 24 22:40:38 2023 +0200"; // one year back for testing purposes, TODO remove const commitDateWithoutWeekday = buildInfo.webknossos.commitDate.replace( /(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, "", @@ -185,7 +187,7 @@ export function UpgradeVersionBanner() { const lastTimeBannerWasClickedAway = localStorage.getItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY); if (lastTimeBannerWasClickedAway == null) return true; const parsedDate = dayjs(lastTimeBannerWasClickedAway); - return parsedDate.diff(currentDate, "days") >= 3; + return currentDate.diff(parsedDate, "day") >= 3; }; const shouldBannerBeShown = getShouldBannerBeShown(); From f630f9412924d1f534035edd0bbb554890948471 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 29 Apr 2024 19:29:35 +0200 Subject: [PATCH 11/23] fix commit date format --- frontend/javascripts/maintenance_banner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 8dedd6d140f..56da5b5a878 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -174,7 +174,7 @@ export function UpgradeVersionBanner() { /(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, "", ); - const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM DD HH:mm:ss YYYY ZZ"); // todo two digit dates? test more once time tracking is merged + const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM D HH:mm:ss YYYY ZZ"); const needsUpdate = currentDate.diff(lastCommitDate, "month") >= 6; return needsUpdate; }, From 68418e35cc48a39222a3db676a9901a004a98a1a Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 29 Apr 2024 20:10:22 +0200 Subject: [PATCH 12/23] add helper to parse date --- frontend/javascripts/libs/utils.ts | 10 ++++++++++ frontend/javascripts/maintenance_banner.tsx | 7 ++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frontend/javascripts/libs/utils.ts b/frontend/javascripts/libs/utils.ts index d2905ee3213..5279755dfcd 100644 --- a/frontend/javascripts/libs/utils.ts +++ b/frontend/javascripts/libs/utils.ts @@ -15,6 +15,7 @@ import type { } from "oxalis/constants"; import window, { document, location } from "libs/window"; import { ArbitraryObject, Comparator } from "types/globals"; +import dayjs from "dayjs"; type UrlParams = Record; // Fix JS modulo bug @@ -555,6 +556,15 @@ export function isFileExtensionEqualTo( return passedExtension === extensionOrExtensions; } +// Parses dates in format "Thu Jan 1 00:00:00 1970 +0000". +export function parseCTimeDefaultDate(dateString: string) { + const commitDateWithoutWeekday = dateString.replace( + /(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, + "", + ); + return dayjs(commitDateWithoutWeekday, "MMM D HH:mm:ss YYYY ZZ"); +} + // Only use this function if you really need a busy wait (useful // for testing performance-related edge cases). Prefer `sleep` // otherwise. diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 56da5b5a878..363f5782cc9 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -7,6 +7,7 @@ import { Alert, Button, Space } from "antd"; import FormattedDate from "components/formatted_date"; import dayjs from "dayjs"; import { useFetch, useInterval } from "libs/react_helpers"; +import { parseCTimeDefaultDate } from "libs/utils"; import _ from "lodash"; import constants from "oxalis/constants"; import { setNavbarHeightAction } from "oxalis/model/actions/ui_actions"; @@ -170,11 +171,7 @@ export function UpgradeVersionBanner() { async () => { let buildInfo = await getBuildInfo(); buildInfo.webknossos.commitDate = "Wed Apr 24 22:40:38 2023 +0200"; // one year back for testing purposes, TODO remove - const commitDateWithoutWeekday = buildInfo.webknossos.commitDate.replace( - /(Mon)|(Tue)|(Wed)|(Thu)|(Fri)|(Sat)|(Sun)\w*/, - "", - ); - const lastCommitDate = dayjs(commitDateWithoutWeekday, "MMM D HH:mm:ss YYYY ZZ"); + const lastCommitDate = parseCTimeDefaultDate(buildInfo.webknossos.commitDate); const needsUpdate = currentDate.diff(lastCommitDate, "month") >= 6; return needsUpdate; }, From 5ea5ed787642fdc0d61e67177c4fe4b58d69454c Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 29 Apr 2024 22:39:24 +0200 Subject: [PATCH 13/23] add changelog --- CHANGELOG.unreleased.md | 1 + frontend/javascripts/maintenance_banner.tsx | 2 +- .../stylesheets/trace_view/_tracing_view.less | 16 ++++++++-------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 71163ef8d6d..d97c7839ac1 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -11,6 +11,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released [Commits](https://github.com/scalableminds/webknossos/compare/24.05.0...HEAD) ### Added +- If a self-hosted WEBKNOSSOS instance has not been updated for six months or more, a closable banner proposes an upgrade to webknossos.org. [#7768](https://github.com/scalableminds/webknossos/pull/7768) ### Changed diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 363f5782cc9..f49a441247b 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -20,7 +20,7 @@ import { MaintenanceInfo } from "types/api_flow_types"; const INITIAL_DELAY = 5000; const INTERVAL_TO_FETCH_MAINTENANCES_MS = 60000; // 1min -const UPGRADE_BANNER_LOCAL_STORAGE_KEY = "upgradeBannerWasClickedAway"; +const UPGRADE_BANNER_LOCAL_STORAGE_KEY = "upgradeBannerWasClickedAwayy"; const BANNER_STYLE: React.CSSProperties = { position: "absolute", diff --git a/frontend/stylesheets/trace_view/_tracing_view.less b/frontend/stylesheets/trace_view/_tracing_view.less index c8ca78bd07c..345a480ba53 100644 --- a/frontend/stylesheets/trace_view/_tracing_view.less +++ b/frontend/stylesheets/trace_view/_tracing_view.less @@ -321,14 +321,6 @@ img.keyboard-mouse-icon:first-child { color: rgba(255, 255, 255, 0.67); z-index: 1000; - .upgrade-banner{ - .ant-alert-close-icon { - .anticon, .anticon-close { - color: var(--ant-color-primary-bg) - } - } - } - &.statusbar-footer { left: 0px; bottom: 0px; @@ -481,6 +473,14 @@ img.keyboard-mouse-icon:first-child { .right-border-button.footer-button { right: 8px; } + + .upgrade-banner{ + .ant-alert-close-icon { + .anticon, .anticon-close { + color: var(--ant-color-primary-bg) + } + } + } } .left-border-button, From 1e0c83cd716c753379864c2e927adcd55256bd11 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Tue, 30 Apr 2024 20:44:45 +0200 Subject: [PATCH 14/23] [ci skip] WIP: address review --- frontend/javascripts/maintenance_banner.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index f49a441247b..986d0c1e115 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -17,10 +17,11 @@ import { OxalisState } from "oxalis/store"; import React, { useEffect, useState } from "react"; import { useSelector } from "react-redux"; import { MaintenanceInfo } from "types/api_flow_types"; +import * as Utils from "libs/utils"; const INITIAL_DELAY = 5000; const INTERVAL_TO_FETCH_MAINTENANCES_MS = 60000; // 1min -const UPGRADE_BANNER_LOCAL_STORAGE_KEY = "upgradeBannerWasClickedAwayy"; +const UPGRADE_BANNER_DISMISSAL_TIMESTAMP_LOCAL_STORAGE_KEY = "upgradeBannerWasClickedAwayy"; const BANNER_STYLE: React.CSSProperties = { position: "absolute", @@ -169,6 +170,7 @@ export function UpgradeVersionBanner() { const isVersionOutdated = useFetch( async () => { + Utils.sleep(INITIAL_DELAY); let buildInfo = await getBuildInfo(); buildInfo.webknossos.commitDate = "Wed Apr 24 22:40:38 2023 +0200"; // one year back for testing purposes, TODO remove const lastCommitDate = parseCTimeDefaultDate(buildInfo.webknossos.commitDate); @@ -181,7 +183,9 @@ export function UpgradeVersionBanner() { const getShouldBannerBeShown = () => { if (!isVersionOutdated) return false; - const lastTimeBannerWasClickedAway = localStorage.getItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY); + const lastTimeBannerWasClickedAway = localStorage.getItem( + UPGRADE_BANNER_DISMISSAL_TIMESTAMP_LOCAL_STORAGE_KEY, + ); if (lastTimeBannerWasClickedAway == null) return true; const parsedDate = dayjs(lastTimeBannerWasClickedAway); return currentDate.diff(parsedDate, "day") >= 3; @@ -220,7 +224,10 @@ export function UpgradeVersionBanner() { style={UPGRADE_BANNER_STYLE} closable onClose={() => { - localStorage.setItem(UPGRADE_BANNER_LOCAL_STORAGE_KEY, dayjs().toISOString()); + localStorage.setItem( + UPGRADE_BANNER_DISMISSAL_TIMESTAMP_LOCAL_STORAGE_KEY, + dayjs().toISOString(), + ); setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT); }} type="info" From 9592cf12cfdffa095252ad2b1e8575f351708da3 Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Wed, 1 May 2024 15:12:04 +0200 Subject: [PATCH 15/23] WIP[ci skip] address review 2 --- frontend/javascripts/libs/format_utils.ts | 2 ++ frontend/javascripts/maintenance_banner.tsx | 25 ++++++++++++--------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/javascripts/libs/format_utils.ts b/frontend/javascripts/libs/format_utils.ts index d6e80e21aa6..85e75799287 100644 --- a/frontend/javascripts/libs/format_utils.ts +++ b/frontend/javascripts/libs/format_utils.ts @@ -8,6 +8,7 @@ import duration from "dayjs/plugin/duration"; import updateLocale from "dayjs/plugin/updateLocale"; import relativeTime from "dayjs/plugin/relativeTime"; import localizedFormat from "dayjs/plugin/localizedFormat"; +import customParseFormat from "dayjs/plugin/customParseFormat"; import calendar from "dayjs/plugin/calendar"; import utc from "dayjs/plugin/utc"; import weekday from "dayjs/plugin/weekday"; @@ -22,6 +23,7 @@ dayjs.extend(relativeTime); dayjs.extend(utc); dayjs.extend(calendar); dayjs.extend(weekday); +dayjs.extend(customParseFormat); dayjs.extend(localeData); dayjs.extend(localizedFormat); dayjs.updateLocale("en", { diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index 986d0c1e115..d8f645adcf9 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -120,7 +120,10 @@ export function MaintenanceBanner() { } useEffect(() => { - if (currentMaintenance || closestUpcomingMaintenance) { + const shouldShowUpcomingMaintenanceBanner = + closestUpcomingMaintenance != null && activeUser != null; + + if (currentMaintenance || shouldShowUpcomingMaintenanceBanner) { setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT + constants.BANNER_HEIGHT); } @@ -128,7 +131,7 @@ export function MaintenanceBanner() { // Reset Navbar height if maintenance is over setNavbarHeight(constants.DEFAULT_NAVBAR_HEIGHT); } - }, [currentMaintenance, closestUpcomingMaintenance]); + }, [currentMaintenance, closestUpcomingMaintenance, activeUser]); useEffect(() => { // Do an initial fetch of the maintenance status so that users are notified @@ -164,10 +167,9 @@ export function UpgradeVersionBanner() { fontSize: "medium", minWidth: "fit-content", }; - const customParseFormat = require("dayjs/plugin/customParseFormat"); - dayjs.extend(customParseFormat); const currentDate = dayjs(); + const activeUser = useSelector((state: OxalisState) => state.activeUser); const isVersionOutdated = useFetch( async () => { Utils.sleep(INITIAL_DELAY); @@ -181,17 +183,18 @@ export function UpgradeVersionBanner() { [], ); - const getShouldBannerBeShown = () => { - if (!isVersionOutdated) return false; + const [shouldBannerBeShown, setShouldBannerBeShown] = useState(false); + + useEffect(() => { + if (!isVersionOutdated || activeUser == null) setShouldBannerBeShown(false); const lastTimeBannerWasClickedAway = localStorage.getItem( UPGRADE_BANNER_DISMISSAL_TIMESTAMP_LOCAL_STORAGE_KEY, ); - if (lastTimeBannerWasClickedAway == null) return true; + if (lastTimeBannerWasClickedAway == null) setShouldBannerBeShown(true); + // todo doesnt work yet, look into custom parse format const parsedDate = dayjs(lastTimeBannerWasClickedAway); - return currentDate.diff(parsedDate, "day") >= 3; - }; - - const shouldBannerBeShown = getShouldBannerBeShown(); + setShouldBannerBeShown(currentDate.diff(parsedDate, "day") >= 3); + }, [activeUser, isVersionOutdated]); useEffect(() => { if (shouldBannerBeShown) { From 7e2508a847cf1677125bc10e3ca41ab66c0b644c Mon Sep 17 00:00:00 2001 From: Charlie Meister Date: Mon, 6 May 2024 19:13:52 +0200 Subject: [PATCH 16/23] add WK link and improve style --- frontend/javascripts/maintenance_banner.tsx | 27 ++++++++++++++----- .../stylesheets/trace_view/_tracing_view.less | 14 ++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/frontend/javascripts/maintenance_banner.tsx b/frontend/javascripts/maintenance_banner.tsx index d8f645adcf9..d7abd31be0f 100644 --- a/frontend/javascripts/maintenance_banner.tsx +++ b/frontend/javascripts/maintenance_banner.tsx @@ -186,15 +186,21 @@ export function UpgradeVersionBanner() { const [shouldBannerBeShown, setShouldBannerBeShown] = useState(false); useEffect(() => { - if (!isVersionOutdated || activeUser == null) setShouldBannerBeShown(false); + if (!isVersionOutdated || activeUser == null) { + setShouldBannerBeShown(false); + return; + } const lastTimeBannerWasClickedAway = localStorage.getItem( UPGRADE_BANNER_DISMISSAL_TIMESTAMP_LOCAL_STORAGE_KEY, ); - if (lastTimeBannerWasClickedAway == null) setShouldBannerBeShown(true); - // todo doesnt work yet, look into custom parse format + if (lastTimeBannerWasClickedAway == null) { + setShouldBannerBeShown(true); + return; + } + const parsedDate = dayjs(lastTimeBannerWasClickedAway); - setShouldBannerBeShown(currentDate.diff(parsedDate, "day") >= 3); - }, [activeUser, isVersionOutdated]); + setShouldBannerBeShown(currentDate.diff(parsedDate, "minutes") >= 3); + }, [activeUser, isVersionOutdated, currentDate]); useEffect(() => { if (shouldBannerBeShown) { @@ -211,8 +217,15 @@ export function UpgradeVersionBanner() { You are using an old version of WEBKNOSSOS. Switch to - webknossos.org for automatic updates and exclusive - features! + + webknossos.org + + for automatic updates and exclusive features!