Release Notes

Release notes
This commit is contained in:
Enrico Ros
2024-10-26 13:50:17 -07:00
parent 578ef40106
commit 4b405af0e4
5 changed files with 145 additions and 29 deletions
+40 -23
View File
@@ -1,7 +1,6 @@
import * as React from 'react';
import NextImage from 'next/image';
import TimeAgo from 'react-timeago';
import { AspectRatio, Box, Button, Card, CardContent, CardOverflow, Container, Grid, Sheet, Typography } from '@mui/joy';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import LaunchIcon from '@mui/icons-material/Launch';
@@ -57,13 +56,47 @@ export const newsRoadmapCallout =
</CardContent>
</Card>;
export function BuildInfoCard(props: { noMargin?: boolean }) {
return (
<Card variant='solid' color='neutral' invertedColors sx={props.noMargin ? undefined : { mb: 3 }}>
<Typography level='title-md' sx={{ my: -1 }}>
Development Build Information
</Typography>
<BuildInfoSheet />
</Card>
);
}
function BuildInfoSheet() {
const backendBuild = React.useMemo(() => getBackendCapabilities().build, []);
const frontendBuild = React.useMemo(() => Release.buildInfo('frontend'), []);
return (
<Sheet variant='soft' invertedColors sx={{
fontSize: 'xs',
// fontFamily: 'code',
color: 'text.secondary',
backgroundColor: 'background.popup',
// border: '1px solid',
// borderColor: 'divider',
borderRadius: 'sm',
// boxShadow: 'inset 1px 1px 4px -2px rgba(0,0,0,0.1)',
p: 1,
mb: -1,
mx: -1,
}}>
PL: <strong>{Release.TenantSlug}</strong> · package {backendBuild?.pkgVersion} ({Release.Monotonics.NewsVersion}).<br />
Frontend: {frontendBuild.gitSha} - deployed {frontendBuild.timestamp ? <strong><TimeAgo date={frontendBuild.timestamp} /></strong> : 'unknown'}, and
backend {backendBuild?.gitSha}{backendBuild?.timestamp === frontendBuild.timestamp ? '.' : backendBuild?.timestamp ? <TimeAgo date={backendBuild?.timestamp!} /> : 'unknown.'}<br />
Ships with -modal/-model: {Object.entries(Release.TechLevels).map(([name, version], idx, arr) => <><strong>{name}</strong> v{version}{idx < arr.length - 1 ? ', ' : ''}</>)}.<br />
Ships with intelligent functions: {Release.AiFunctions.map((name, idx, arr) => <><i>{name}</i>{idx < arr.length - 1 ? ', ' : ''}</>)}.
</Sheet>
);
}
export function AppNews() {
// state
const [lastNewsIdx, setLastNewsIdx] = React.useState<number>(NEWS_INITIAL_COUNT - 1);
const backendBuild = getBackendCapabilities().build;
// news selection
const news = NewsItems.filter((_, idx) => idx <= lastNewsIdx);
const firstNews = news[0] ?? null;
@@ -117,6 +150,9 @@ export function AppNews() {
const addPadding = false; //!firstCard; // || showExpander;
return <React.Fragment key={idx}>
{/* Inject the Build Info Sheet */}
{idx === 0 && <BuildInfoCard />}
{/* Inject the Big-AGI 2.0 item here*/}
{/*{idx === 1 && (*/}
{/* <Box sx={{ mb: 3 }}>*/}
@@ -168,26 +204,7 @@ export function AppNews() {
</ul>
)}
{idx === 0 && (
<Sheet variant='soft' invertedColors sx={{
fontSize: 'xs',
// fontFamily: 'code',
color: 'text.secondary',
// border: '1px solid',
// borderColor: 'divider',
borderRadius: 'sm',
boxShadow: 'inset 1px 1px 4px -2px rgba(0,0,0,0.1)',
p: 2,
mb: -1,
mx: -1,
}}>
PL: <strong>{Release.App.pl}</strong> · package {backendBuild?.pkgVersion} ({Release.Monotonics.NewsVersion}).<br />
Frontend: {_frontendBuild.gitSha} - deployed {_frontendBuild.timestamp ? <strong><TimeAgo date={_frontendBuild.timestamp} /></strong> : 'unknown'}, and
backend {backendBuild?.gitSha}{backendBuild?.timestamp === _frontendBuild.timestamp ? '.' : backendBuild?.timestamp ? <TimeAgo date={backendBuild?.timestamp!} /> : 'unknown.'}<br />
Ships with -modal/-model: {Object.entries(Release.TechLevels).map(([name, version], idx, arr) => <><strong>{name}</strong> v{version}{idx < arr.length - 1 ? ', ' : ''}</>)}.<br />
Ships with intelligent functions: {Release.AiFunctions.map((name, idx, arr) => <><i>{name}</i>{idx < arr.length - 1 ? ', ' : ''}</>)}.
</Sheet>
)}
{/*{idx === 0 && <BuildInfoSheet />}*/}
</CardContent>
+1
View File
@@ -16,6 +16,7 @@ export const Release = {
App: {
versionCode: '2.0.0-open-rc2', // 1.92.0 sequentially...
versionName: 'Big-AGI 2',
releaseNotes: '',
},
// Future compatibility
+99 -2
View File
@@ -1,18 +1,30 @@
import * as React from 'react';
import type { SxProps } from '@mui/joy/styles/types';
import { Box, IconButton, Typography } from '@mui/joy';
import { Box, Dropdown, IconButton, ListDivider, ListItem, ListItemDecorator, Menu, MenuButton, MenuItem, Typography } from '@mui/joy';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import EngineeringIcon from '@mui/icons-material/Engineering';
import FeedbackIcon from '@mui/icons-material/Feedback';
import LightbulbOutlinedIcon from '@mui/icons-material/LightbulbOutlined';
import MenuIcon from '@mui/icons-material/Menu';
import MoreVertIcon from '@mui/icons-material/MoreVert';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
import NewReleasesIcon from '@mui/icons-material/NewReleases';
import { BuildInfoCard } from '../../../../apps/news/AppNews';
import { blocksRenderHTMLIFrameCss } from '~/modules/blocks/code/code-renderers/RenderCodeHtmlIFrame';
import { BigAgiSquircleIcon } from '~/common/components/icons/big-agi/BigAgiSquircleIcon';
import { Brand } from '~/common/app.config';
import { GoodModal } from '~/common/components/modals/GoodModal';
import { LayoutSidebarRight } from '~/common/components/icons/LayoutSidebarRight';
import { Link } from '~/common/components/Link';
import { Release } from '~/common/app.release';
import { TooltipOutlined } from '~/common/components/TooltipOutlined';
import { checkVisibleNav, NavItemApp } from '~/common/app.nav';
import { navigateToIndex, ROUTE_INDEX } from '~/common/app.routes';
// import { useDynamicUsersnap } from '~/common/components/3rdparty/Usersnap';
import { useOverlayComponents } from '~/common/layout/overlays/useOverlayComponents';
import { InvertedBar, InvertedBarCornerItem } from '../InvertedBar';
import { PopupPanel } from '../panel/PopupPanel';
@@ -80,12 +92,51 @@ export function OptimaBar(props: { component: React.ElementType, currentApp?: Na
const appMenuAnchor = React.useRef<HTMLButtonElement>(null);
// external state
/**
* NOTE: shall we fall back to the 'standard' release notes when not available on the tenant?
* - prob not because this could be a per-company deployment, and we don't know the tenant's release notes
*/
const releaseNotesUrl = Release.App.releaseNotes;
// const { openUsersnap, loadingError: usersnapLoadingError } = useDynamicUsersnap();
const { showPromisedOverlay } = useOverlayComponents();
const hasDrawerContent = useOptimaPortalHasInputs('optima-portal-drawer');
const { panelAsPopup, panelHasContent, panelShownAsPanel, panelShownAsPopup } = useOptimaPanelOpen(props.isMobile, props.currentApp);
// derived state
const navIsShown = checkVisibleNav(props.currentApp);
// Handlers
const handleShowReleaseNotes = React.useCallback(async () => {
if (!releaseNotesUrl) return;
return await showPromisedOverlay('app-recent-changes', { rejectWithValue: false }, ({ onResolve, onUserReject }) =>
<GoodModal
open
onClose={onUserReject}
noTitleBar
themedColor='neutral'
unfilterBackdrop
sx={{ minWidth: { xs: 400, sm: 580, md: 780, lg: 890 } }}
>
<iframe
src={releaseNotesUrl}
style={{ ...blocksRenderHTMLIFrameCss, height: '70svh' }}
title='Release Notes Embed'
loading='lazy' // do not load until visible in the viewport
/>
</GoodModal>,
);
}, [releaseNotesUrl, showPromisedOverlay]);
const handleShowTechnologies = React.useCallback(async () => {
return await showPromisedOverlay<void>('app-recent-changes', {}, ({ onResolve }) =>
<GoodModal open onClose={onResolve} noTitleBar unfilterBackdrop>
<BuildInfoCard noMargin />
</GoodModal>,
);
}, [showPromisedOverlay]);
// [Desktop] optionally hide the Bar if the current app asks for it
if (props.currentApp?.hideBar && !props.isMobile && !panelHasContent)
return null;
@@ -115,7 +166,53 @@ export function OptimaBar(props: { component: React.ElementType, currentApp?: Na
{/* Pluggable Toolbar Items */}
<CenterItemsPortal currentApp={props.currentApp} />
{/* Panel/Menu button */}
{/* (PREVIEW) Preview Menu */}
{!props.isMobile && (
<Dropdown>
<MenuButton
aria-label='Notifications Menu'
slots={{ root: IconButton }}
slotProps={{ root: { size: 'md' } }}
>
{/*<NotificationsNoneOutlinedIcon />*/}
<LightbulbOutlinedIcon />
{/*<FeedbackOutlinedIcon />*/}
</MenuButton>
<Menu placement='bottom-end' sx={{ minWidth: 220 }}>
<ListItem>
<Typography level='body-xs' sx={{ textTransform: 'uppercase' }}>
{Release.App.versionName}
</Typography>
</ListItem>
{!!releaseNotesUrl && (
<MenuItem onClick={handleShowReleaseNotes}>
<ListItemDecorator><NewReleasesIcon /></ListItemDecorator>
Release Notes
</MenuItem>
)}
<MenuItem onClick={handleShowTechnologies}>
{/*<ListItemDecorator><EventNoteOutlinedIcon /></ListItemDecorator>*/}
<ListItemDecorator><EngineeringIcon /></ListItemDecorator>
Build Info
</MenuItem>
{/*<ListDivider />*/}
{/*<TooltipOutlined title={usersnapLoadingError}>*/}
{/* <MenuItem onClick={openUsersnap}>*/}
{/* <ListItemDecorator><FeedbackIcon /></ListItemDecorator>*/}
{/* Feedback -&gt; Enrico*/}
{/* </MenuItem>*/}
{/*</TooltipOutlined>*/}
</Menu>
</Dropdown>
)}
{/* Panel Open: has content always on Mobile (the app menu) */}
{panelHasContent && (
<InvertedBarCornerItem>
{/*<Tooltip disableInteractive title={contentToPopup ? (panelIsOpen ? 'Close' : 'Open') + ' Menu' : (panelIsOpen ? 'Close' : 'Open')}>*/}
@@ -17,6 +17,7 @@ interface OverlayItem {
}
export type GlobalOverlayId = // string - disabled so we keep an orderliness
| 'app-recent-changes' // Recent changes in the app, only private branch
| 'chat-attachments-clear'
| 'chat-delete-confirmation'
| 'chat-reset-confirmation'
@@ -8,7 +8,7 @@ body { min-height: 100vh; line-height: 1.5; -webkit-font-smoothing: antialiased;
img, picture, svg, video { display: block;max-width: 100%; }
`;
const customIFrameCss: React.CSSProperties = {
export const blocksRenderHTMLIFrameCss: React.CSSProperties = {
flexGrow: 1,
width: '100%',
height: '54svh',
@@ -18,8 +18,8 @@ const customIFrameCss: React.CSSProperties = {
maxHeight: '100%',
} as const;
const customIFrameFullscreenCss: React.CSSProperties = {
...customIFrameCss,
const blocksRenderHTMLIFrameFullScreenCss: React.CSSProperties = {
...blocksRenderHTMLIFrameCss,
height: undefined,
flex: 1,
} as const;
@@ -86,7 +86,7 @@ export function RenderCodeHtmlIFrame(props: { htmlCode: string, isFullscreen?: b
return (
<iframe
ref={iframeRef}
style={props.isFullscreen ? customIFrameFullscreenCss : customIFrameCss}
style={props.isFullscreen ? blocksRenderHTMLIFrameFullScreenCss : blocksRenderHTMLIFrameCss}
title='Sandboxed Web Content'
aria-label='Interactive content frame'
sandbox='allow-scripts allow-same-origin allow-forms' // restrict to only these