Skip to content

Commit

Permalink
Merge main into next
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions committed Jan 15, 2025
2 parents faf8161 + 0bb181a commit c81e495
Show file tree
Hide file tree
Showing 27 changed files with 1,016 additions and 32 deletions.
6 changes: 6 additions & 0 deletions .changeset/blue-flies-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@comet/cms-admin": patch
"@comet/cms-api": patch
---

Fix page tree node slug validation to prevent URL encoded characters
5 changes: 5 additions & 0 deletions .changeset/cyan-shoes-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/admin": minor
---

Hide group title in `CrudMoreActionsMenu` when only one group is present
5 changes: 5 additions & 0 deletions .changeset/smooth-shrimps-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/cli": minor
---

Add option for base64 encoding in `inject-site-configs` command
5 changes: 5 additions & 0 deletions .changeset/violet-goats-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@comet/admin": patch
---

`usePersistentColumnState`: Prevent Data Grids with the same name to overwrite each others pinned and column-visibility states
1 change: 1 addition & 0 deletions demo/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"lint:prettier": "npx prettier --check './**/*.{js,json,md,yml,yaml}'",
"lint:tsc": "tsc --project .",
"lint:generated-files-not-modified": "$npm_execpath admin-generator && git diff --exit-code HEAD -- src/**/generated",
"serve": "node server",
"start": "run-s intl:compile && run-p gql:types generate-block-types && dotenv -e .env.site-configs -- chokidar --initial -s \"../../packages/admin/*/src/**\" -c \"kill-port $ADMIN_PORT && vite --force\""
},
"dependencies": {
Expand Down
69 changes: 69 additions & 0 deletions demo/admin/server/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* eslint-disable no-undef */
const express = require("express");
const compression = require("compression");
const helmet = require("helmet");
const fs = require("fs");

const app = express();
const port = process.env.APP_PORT ?? 3000;

let indexFile = fs.readFileSync("./build/index.html", "utf8");

// Replace environment variables
indexFile = indexFile.replace(/\$([A-Z_]+)/g, (match, p1) => {
return process.env[p1] || "";
});

app.use(compression());
app.use(
helmet({
contentSecurityPolicy: {
directives: {
"script-src": ["'self'", "'unsafe-inline'"],
"img-src": ["'self'", "https:", "data:"],
"default-src": ["'self'", "https:"],
"media-src": ["'self'", "https:"],
"style-src": ["'self'", "https:", "'unsafe-inline'"],
"font-src": ["'self'", "https:", "data:"],
},
},
xXssProtection: false,
strictTransportSecurity: {
maxAge: 63072000,
includeSubDomains: true,
preload: true,
},
}),
);

app.get("/status/health", (req, res) => {
res.send("OK!");
});

app.use(
express.static("./build", {
index: false, // Don't send index.html for requests to "/" as it will be handled by the fallback route (with replaced environment variables)
setHeaders: (res, path, stat) => {
if (path.endsWith(".js")) {
// The js file is static and the index.html uses a parameter as cache buster
// implemented as suggested by https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#caching_static_assets
res.setHeader("cache-control", "public, max-age=31536000, immutable");
} else {
// Icons and Fonts could be changed over time, cache for 7d
res.setHeader("cache-control", "public, max-age=604800, immutable");
}
},
}),
);

// As a fallback, route everything to index.html
app.get("*", (req, res) => {
// Don't cache the index.html at all to make sure applications updates are applied
// implemented as suggested by https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#preventing_storing
res.setHeader("cache-control", "no-store");
res.send(indexFile);
});

app.listen(port, () => {
console.log(`Admin app listening at http://localhost:${port}`);
});
9 changes: 8 additions & 1 deletion demo/admin/server/package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
{
"name": "comet-demo-admin-server",
"version": "1.0.0",
"private": true,
"dependencies": {
"compression": "^1.7.5",
<<<<<<< HEAD
"express": "^4.21.2",
"helmet": "^7.2.0"
},
"scripts": {
"serve": "node server.js"
=======
"express": "^4.21.1",
"helmet": "^7.2.0"
},
"engines": {
"node": "22"
>>>>>>> main
}
}
2 changes: 1 addition & 1 deletion demo/admin/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function App() {
siteConfig.scope.domain === "secondary"
? `${siteConfig.url}/block-preview`
: `${siteConfig.url}/block-preview/${scope.domain}/${scope.language}`,
sitePreviewApiUrl: `${siteConfig.url}/api/site-preview`,
sitePreviewApiUrl: `${siteConfig.url}/site-preview`,
};
},
}}
Expand Down
2 changes: 1 addition & 1 deletion demo/admin/src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function createConfig() {
...cometConfig,
apiUrl: environmentVariables.API_URL,
adminUrl: environmentVariables.ADMIN_URL,
sitesConfig: JSON.parse(environmentVariables.PUBLIC_SITE_CONFIGS) as PublicSiteConfig[],
sitesConfig: JSON.parse(atob(environmentVariables.PUBLIC_SITE_CONFIGS)) as PublicSiteConfig[],
buildDate: environmentVariables.BUILD_DATE,
buildNumber: environmentVariables.BUILD_NUMBER,
commitSha: environmentVariables.COMMIT_SHA,
Expand Down
2 changes: 1 addition & 1 deletion demo/api/src/config/environment-variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,6 @@ export class EnvironmentVariables {
SITE_PREVIEW_SECRET: string;

@IsArray()
@Transform(({ value }) => JSON.parse(value))
@Transform(({ value }) => JSON.parse(Buffer.from(value, "base64").toString()))
PRIVATE_SITE_CONFIGS: PrivateSiteConfig[];
}
7 changes: 7 additions & 0 deletions demo/site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@
"@opentelemetry/exporter-trace-otlp-http": "^0.53.0",
"@opentelemetry/instrumentation-runtime-node": "^0.11.0",
"@opentelemetry/sdk-node": "^0.53.0",
<<<<<<< HEAD
"cache-manager": "^5.7.6",
=======
"cache-manager": "^5.5.3",
"express": "^4.0.0",
"filesize": "^10.1.6",
"fs-extra": "^9.0.0",
>>>>>>> main
"graphql": "^15.0.0",
"ioredis": "^5.4.2",
"lru-cache": "^11.0.1",
Expand Down
File renamed without changes.
File renamed without changes.
22 changes: 15 additions & 7 deletions demo/site/src/common/blocks/CallToActionBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";
import { PropsWithData, withPreview } from "@comet/cms-site";
import { CallToActionBlockData } from "@src/blocks.generated";
import { filesize } from "filesize";

import { Button, ButtonVariant } from "../components/Button";
import { HiddenIfInvalidLink } from "../helpers/HiddenIfInvalidLink";
Expand All @@ -13,12 +14,19 @@ const buttonVariantMap: Record<CallToActionBlockData["variant"], ButtonVariant>
};

export const CallToActionBlock = withPreview(
({ data: { textLink, variant } }: PropsWithData<CallToActionBlockData>) => (
<HiddenIfInvalidLink link={textLink.link}>
<Button as={LinkBlock} data={textLink.link} variant={buttonVariantMap[variant]}>
{textLink.text}
</Button>
</HiddenIfInvalidLink>
),
({ data: { textLink, variant } }: PropsWithData<CallToActionBlockData>) => {
const linkBlock = textLink.link.block;
let buttonText = textLink.text;
if (linkBlock && linkBlock.type === "damFileDownload" && "file" in linkBlock.props && linkBlock.props.file) {
buttonText = `${buttonText} (${filesize(linkBlock?.props.file?.size)})`;
}
return (
<HiddenIfInvalidLink link={textLink.link}>
<Button as={LinkBlock} data={textLink.link} variant={buttonVariantMap[variant]}>
{buttonText}
</Button>
</HiddenIfInvalidLink>
);
},
{ label: "Call To Action" },
);
25 changes: 25 additions & 0 deletions demo/site/src/common/blocks/TextLinkBlock.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"use client";
import { PropsWithData, withPreview } from "@comet/cms-site";
import { TextLinkBlockData } from "@src/blocks.generated";
import { filesize } from "filesize";
import styled from "styled-components";

import { LinkBlock } from "./LinkBlock";

export const TextLinkBlock = withPreview(
({ data: { link, text } }: PropsWithData<TextLinkBlockData>) => {
if (link.block && link.block.type === "damFileDownload" && "file" in link.block.props && link.block.props.file) {
return <Link data={link}>{`${text} (${filesize(link.block.props.file.size)})`}</Link>;
}

return <Link data={link}>{text}</Link>;
},
{ label: "Link" },
);

const Link = styled(LinkBlock)`
color: ${({ theme }) => theme.palette.text.primary};
&:hover {
color: ${({ theme }) => theme.palette.primary.main};
}
`;
7 changes: 3 additions & 4 deletions demo/site/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { withAdminRedirectMiddleware } from "./middleware/adminRedirect";
import { withBlockPreviewMiddleware } from "./middleware/blockPreview";
import { chain } from "./middleware/chain";
import { withCspHeadersMiddleware } from "./middleware/cspHeaders";
import { withDamRewriteMiddleware } from "./middleware/damRewrite";
import { withDomainRewriteMiddleware } from "./middleware/domainRewrite";
import { withPredefinedPagesMiddleware } from "./middleware/predefinedPages";
import { withPreviewMiddleware } from "./middleware/preview";
import { withRedirectToMainHostMiddleware } from "./middleware/redirectToMainHost";
import { withSitePreviewMiddleware } from "./middleware/sitePreview";

Expand All @@ -14,7 +14,7 @@ export default chain([
withAdminRedirectMiddleware,
withDamRewriteMiddleware,
withCspHeadersMiddleware, // order matters: after redirects (that don't need csp headers), before everything else that needs csp headers
withBlockPreviewMiddleware,
withPreviewMiddleware,
withPredefinedPagesMiddleware,
withDomainRewriteMiddleware, // must be last (rewrites all urls)
]);
Expand All @@ -23,14 +23,13 @@ export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico, favicon.svg, favicon.png
* - manifest.json
* - robots.txt
*/
"/((?!api|_next/static|_next/image|favicon.ico|favicon.svg|favicon.png|manifest.json|robots.txt).*)",
"/((?!_next/static|_next/image|favicon.ico|favicon.svg|favicon.png|manifest.json|robots.txt).*)",
],
// TODO find a better solution for this (https://nextjs.org/docs/messages/edge-dynamic-code-evaluation)
unstable_allowDynamic: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { NextRequest, NextResponse } from "next/server";

import { CustomMiddleware } from "./chain";

export function withBlockPreviewMiddleware(middleware: CustomMiddleware) {
export function withPreviewMiddleware(middleware: CustomMiddleware) {
return async (request: NextRequest) => {
if (request.nextUrl.pathname.startsWith("/block-preview/")) {
if (request.nextUrl.pathname.startsWith("/block-preview/") || request.nextUrl.pathname === "/site-preview") {
// don't apply any other middlewares
return NextResponse.next();
}
Expand Down
2 changes: 1 addition & 1 deletion demo/site/src/util/siteConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export function getSiteConfigs() {
if (!siteConfigs) {
const json = process.env.PUBLIC_SITE_CONFIGS;
if (!json) throw new Error("process.env.PUBLIC_SITE_CONFIGS must be set.");
siteConfigs = JSON.parse(json) as PublicSiteConfig[];
siteConfigs = JSON.parse(atob(json)) as PublicSiteConfig[];
}
return siteConfigs;
}
Expand Down
1 change: 1 addition & 0 deletions docs/docs/3-features-modules/5-console-commands/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ npm run console:prod demo-command

## Best practices

- Use kebab case for command names and arguments.
- Dangerous commands (e.g. resetting the database) should check the `NODE_ENV` and only run locally.

```ts
Expand Down
8 changes: 8 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
},
"license": "BSD-2-Clause",
"scripts": {
<<<<<<< HEAD
"create-site-configs-env": "npx @comet/cli inject-site-configs -f demo/site-configs/site-configs.ts -i demo/.env.site-configs.tpl -o demo/.env.site-configs -d",
"build:storybook": "pnpm --recursive --filter '@comet/*admin*' --filter '@comet/eslint-plugin' --filter '@comet/cli' run build && pnpm --filter comet-storybook run build-storybook",
"build:packages": "pnpm --recursive --filter '@comet/*' run build",
"build:docs": "pnpm --recursive --filter '@comet/eslint-plugin' --filter '@comet/admin*' --filter 'comet-docs' run build",
"clean": "pnpm --recursive run clean",
=======
"create-site-configs-env": "npx @comet/cli inject-site-configs -f demo/site-configs/site-configs.ts -i demo/.env.site-configs.tpl -o demo/.env.site-configs --base64",
"build:storybook": "pnpm recursive --filter '@comet/*admin*' --filter '@comet/eslint-plugin' --filter '@comet/cli' run build && pnpm --filter comet-storybook run build-storybook",
"build:packages": "pnpm recursive --filter '@comet/*' run build",
"build:docs": "pnpm recursive --filter '@comet/eslint-plugin' --filter '@comet/admin*' --filter 'comet-docs' run build",
"clean": "pnpm recursive run clean",
>>>>>>> main
"copy-schema-files": "node copy-schema-files.js",
"dev:admin": "dev-pm start @comet-admin",
"dev:cms": "dev-pm start @cms",
Expand Down
32 changes: 25 additions & 7 deletions packages/admin/admin/src/dataGrid/CrudMoreActionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface CrudMoreActionsMenuProps
}

interface CrudMoreActionsGroupProps {
groupTitle: ReactNode;
groupTitle?: ReactNode;
menuListProps?: MenuListProps;
typographyProps?: ComponentProps<typeof Typography>;
}
Expand All @@ -54,9 +54,17 @@ function CrudMoreActionsGroup({ groupTitle, children, menuListProps, typographyP
const { palette } = useTheme();
return (
<>
<<<<<<< HEAD
<Typography variant="overline" color={palette.grey[500]} sx={{ padding: "20px 15px 0 15px" }} {...typographyProps}>
{groupTitle}
</Typography>
=======
{groupTitle && (
<Typography variant="overline" color={(theme) => theme.palette.grey[500]} sx={{ padding: "20px 15px 0 15px" }} {...typographyProps}>
{groupTitle}
</Typography>
)}
>>>>>>> main
<MenuList {...menuListProps}>{children}</MenuList>
</>
);
Expand Down Expand Up @@ -118,11 +126,13 @@ export function CrudMoreActionsMenu({ slotProps, overallActions, selectiveAction
const handleClick = (event: MouseEvent<HTMLButtonElement>) => setAnchorEl(event.currentTarget);

const handleClose = () => setAnchorEl(null);
const hasOverallActions = !!overallActions?.length;
const hasSelectiveActions = !!selectiveActions?.length;

return (
<>
<MoreActionsButton variant="text" color="inherit" endIcon={<MoreVertical />} {...buttonProps} onClick={handleClick}>
<FormattedMessage id="comet.crudMoreActions.title" defaultMessage="More actions" />
<FormattedMessage id="comet.crudMoreActions.title" defaultMessage="More" />
{!!selectionSize && <MoreActionsSelectedItemsChip size="small" color="primary" {...chipProps} label={selectionSize} />}
</MoreActionsButton>
<Menu
Expand All @@ -136,9 +146,13 @@ export function CrudMoreActionsMenu({ slotProps, overallActions, selectiveAction
menuProps?.onClose?.(event, reason);
}}
>
{!!overallActions?.length && (
{hasOverallActions && (
<CrudMoreActionsGroup
groupTitle={<FormattedMessage id="comet.crudMoreActions.overallActions" defaultMessage="Overall actions" />}
groupTitle={
hasSelectiveActions ? (
<FormattedMessage id="comet.crudMoreActions.overallActions" defaultMessage="Overall actions" />
) : undefined
}
{...groupProps}
>
{overallActions.map((item, index) => {
Expand Down Expand Up @@ -167,11 +181,15 @@ export function CrudMoreActionsMenu({ slotProps, overallActions, selectiveAction
</CrudMoreActionsGroup>
)}

{!!overallActions?.length && !!selectiveActions?.length && <CrudMoreActionsDivider {...dividerProps} />}
{hasOverallActions && hasSelectiveActions && <CrudMoreActionsDivider {...dividerProps} />}

{!!selectiveActions?.length && (
{hasSelectiveActions && (
<CrudMoreActionsGroup
groupTitle={<FormattedMessage id="comet.crudMoreActions.selectiveActions" defaultMessage="Selective actions" />}
groupTitle={
hasOverallActions ? (
<FormattedMessage id="comet.crudMoreActions.selectiveActions" defaultMessage="Selective actions" />
) : undefined
}
{...groupProps}
>
{selectiveActions.map((item, index) => {
Expand Down
Loading

0 comments on commit c81e495

Please sign in to comment.