mirror of
https://github.com/docmost/docmost.git
synced 2026-05-09 07:43:06 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e69924448 | |||
| 3b5fee05c1 | |||
| 9bbd62e0f0 | |||
| 0289c5cb09 | |||
| 7993532111 | |||
| 31e5c0c660 | |||
| 33c314d4e8 | |||
| 08f223899a |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.20.1",
|
"version": "0.20.3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { AppHeader } from "@/components/layouts/global/app-header.tsx";
|
|||||||
import Aside from "@/components/layouts/global/aside.tsx";
|
import Aside from "@/components/layouts/global/aside.tsx";
|
||||||
import classes from "./app-shell.module.css";
|
import classes from "./app-shell.module.css";
|
||||||
import { useTrialEndAction } from "@/ee/hooks/use-trial-end-action.tsx";
|
import { useTrialEndAction } from "@/ee/hooks/use-trial-end-action.tsx";
|
||||||
import { useClickOutside, useMergedRef } from "@mantine/hooks";
|
|
||||||
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
|
import { useToggleSidebar } from "@/components/layouts/global/hooks/hooks/use-toggle-sidebar.ts";
|
||||||
|
|
||||||
export default function GlobalAppShell({
|
export default function GlobalAppShell({
|
||||||
@@ -30,13 +29,6 @@ export default function GlobalAppShell({
|
|||||||
const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom);
|
const [sidebarWidth, setSidebarWidth] = useAtom(sidebarWidthAtom);
|
||||||
const [isResizing, setIsResizing] = useState(false);
|
const [isResizing, setIsResizing] = useState(false);
|
||||||
const sidebarRef = useRef(null);
|
const sidebarRef = useRef(null);
|
||||||
const navbarOutsideRef = useClickOutside(() => {
|
|
||||||
if (mobileOpened) {
|
|
||||||
toggleMobile();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const mergedRef = useMergedRef(sidebarRef, navbarOutsideRef);
|
|
||||||
|
|
||||||
const startResizing = React.useCallback((mouseDownEvent) => {
|
const startResizing = React.useCallback((mouseDownEvent) => {
|
||||||
mouseDownEvent.preventDefault();
|
mouseDownEvent.preventDefault();
|
||||||
@@ -112,7 +104,7 @@ export default function GlobalAppShell({
|
|||||||
<AppShell.Navbar
|
<AppShell.Navbar
|
||||||
className={classes.navbar}
|
className={classes.navbar}
|
||||||
withBorder={false}
|
withBorder={false}
|
||||||
ref={mergedRef}
|
ref={sidebarRef}
|
||||||
>
|
>
|
||||||
<div className={classes.resizeHandle} onMouseDown={startResizing} />
|
<div className={classes.resizeHandle} onMouseDown={startResizing} />
|
||||||
{isSpaceRoute && <SpaceSidebar />}
|
{isSpaceRoute && <SpaceSidebar />}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Alert } from "@mantine/core";
|
import { Alert } from "@mantine/core";
|
||||||
import { useBillingQuery } from "@/ee/billing/queries/billing-query.ts";
|
import { useBillingQuery } from "@/ee/billing/queries/billing-query.ts";
|
||||||
import useTrial from "@/ee/hooks/use-trial.tsx";
|
import useTrial from "@/ee/hooks/use-trial.tsx";
|
||||||
|
import { getBillingTrialDays } from '@/lib/config.ts';
|
||||||
|
|
||||||
export default function BillingTrial() {
|
export default function BillingTrial() {
|
||||||
const { data: billing, isLoading } = useBillingQuery();
|
const { data: billing, isLoading } = useBillingQuery();
|
||||||
@@ -15,14 +16,14 @@ export default function BillingTrial() {
|
|||||||
{trialDaysLeft > 0 && !billing && (
|
{trialDaysLeft > 0 && !billing && (
|
||||||
<Alert title="Your Trial is Active 🎉" color="blue" radius="md">
|
<Alert title="Your Trial is Active 🎉" color="blue" radius="md">
|
||||||
You have {trialDaysLeft} {trialDaysLeft === 1 ? "day" : "days"} left
|
You have {trialDaysLeft} {trialDaysLeft === 1 ? "day" : "days"} left
|
||||||
in your 7-day trial. Please subscribe to a plan before your trial
|
in your {getBillingTrialDays()}-day free trial. Please subscribe to a paid plan before your trial
|
||||||
ends.
|
ends.
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{trialDaysLeft === 0 && (
|
{trialDaysLeft === 0 && (
|
||||||
<Alert title="Your Trial has ended" color="red" radius="md">
|
<Alert title="Your Trial has ended" color="red" radius="md">
|
||||||
Your 7-day trial has come to an end. Please subscribe to a plan to
|
Your {getBillingTrialDays()}-day free trial has come to an end. Please subscribe to a paid plan to
|
||||||
continue using this service.
|
continue using this service.
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useLocation, useNavigate } from "react-router-dom";
|
import { useLocation, useNavigate } from "react-router-dom";
|
||||||
import { isCloud } from "@/lib/config.ts";
|
import { getBillingTrialDays, isCloud } from "@/lib/config.ts";
|
||||||
import APP_ROUTE from "@/lib/app-route.ts";
|
import APP_ROUTE from "@/lib/app-route.ts";
|
||||||
import useUserRole from "@/hooks/use-user-role.tsx";
|
import useUserRole from "@/hooks/use-user-role.tsx";
|
||||||
import { notifications } from "@mantine/notifications";
|
import { notifications } from "@mantine/notifications";
|
||||||
@@ -18,7 +18,7 @@ export const useTrialEndAction = () => {
|
|||||||
notifications.show({
|
notifications.show({
|
||||||
position: "top-right",
|
position: "top-right",
|
||||||
color: "red",
|
color: "red",
|
||||||
title: "Your 7-day trial has ended",
|
title: `Your ${getBillingTrialDays()}-day trial has ended`,
|
||||||
message:
|
message:
|
||||||
"Please upgrade to a paid plan or contact your workspace admin.",
|
"Please upgrade to a paid plan or contact your workspace admin.",
|
||||||
autoClose: false,
|
autoClose: false,
|
||||||
|
|||||||
@@ -74,6 +74,10 @@ export function getDrawioUrl() {
|
|||||||
return getConfigValue("DRAWIO_URL", "https://embed.diagrams.net");
|
return getConfigValue("DRAWIO_URL", "https://embed.diagrams.net");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getBillingTrialDays() {
|
||||||
|
return getConfigValue("BILLING_TRIAL_DAYS");
|
||||||
|
}
|
||||||
|
|
||||||
function getConfigValue(key: string, defaultValue: string = undefined): string {
|
function getConfigValue(key: string, defaultValue: string = undefined): string {
|
||||||
const rawValue = import.meta.env.DEV
|
const rawValue = import.meta.env.DEV
|
||||||
? process?.env?.[key]
|
? process?.env?.[key]
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
CLOUD,
|
CLOUD,
|
||||||
SUBDOMAIN_HOST,
|
SUBDOMAIN_HOST,
|
||||||
COLLAB_URL,
|
COLLAB_URL,
|
||||||
|
BILLING_TRIAL_DAYS,
|
||||||
} = loadEnv(mode, envPath, "");
|
} = loadEnv(mode, envPath, "");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -23,6 +24,7 @@ export default defineConfig(({ mode }) => {
|
|||||||
CLOUD,
|
CLOUD,
|
||||||
SUBDOMAIN_HOST,
|
SUBDOMAIN_HOST,
|
||||||
COLLAB_URL,
|
COLLAB_URL,
|
||||||
|
BILLING_TRIAL_DAYS,
|
||||||
},
|
},
|
||||||
APP_VERSION: JSON.stringify(process.env.npm_package_version),
|
APP_VERSION: JSON.stringify(process.env.npm_package_version),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "server",
|
"name": "server",
|
||||||
"version": "0.20.1",
|
"version": "0.20.3",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "",
|
"author": "",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Module, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
import { Logger, Module, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||||
import { AuthenticationExtension } from './extensions/authentication.extension';
|
import { AuthenticationExtension } from './extensions/authentication.extension';
|
||||||
import { PersistenceExtension } from './extensions/persistence.extension';
|
import { PersistenceExtension } from './extensions/persistence.extension';
|
||||||
import { CollaborationGateway } from './collaboration.gateway';
|
import { CollaborationGateway } from './collaboration.gateway';
|
||||||
@@ -22,6 +22,7 @@ import { LoggerExtension } from './extensions/logger.extension';
|
|||||||
imports: [TokenModule],
|
imports: [TokenModule],
|
||||||
})
|
})
|
||||||
export class CollaborationModule implements OnModuleInit, OnModuleDestroy {
|
export class CollaborationModule implements OnModuleInit, OnModuleDestroy {
|
||||||
|
private readonly logger = new Logger(CollaborationModule.name);
|
||||||
private collabWsAdapter: CollabWsAdapter;
|
private collabWsAdapter: CollabWsAdapter;
|
||||||
private path = '/collab';
|
private path = '/collab';
|
||||||
|
|
||||||
@@ -38,7 +39,15 @@ export class CollaborationModule implements OnModuleInit, OnModuleDestroy {
|
|||||||
|
|
||||||
wss.on('connection', (client: WebSocket, request: IncomingMessage) => {
|
wss.on('connection', (client: WebSocket, request: IncomingMessage) => {
|
||||||
this.collaborationGateway.handleConnection(client, request);
|
this.collaborationGateway.handleConnection(client, request);
|
||||||
|
|
||||||
|
client.on('error', (error) => {
|
||||||
|
this.logger.error('WebSocket client error:', error);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
wss.on('error', (error) =>
|
||||||
|
this.logger.log('WebSocket server error:', error),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async onModuleDestroy(): Promise<void> {
|
async onModuleDestroy(): Promise<void> {
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ export class PersistenceExtension implements Extension {
|
|||||||
);
|
);
|
||||||
this.contributors.delete(documentName);
|
this.contributors.delete(documentName);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.log('Contributors error:' + err?.['message']);
|
this.logger.debug('Contributors error:' + err?.['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.pageRepo.updatePage(
|
await this.pageRepo.updatePage(
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ export class PageRepo {
|
|||||||
'p.spaceId',
|
'p.spaceId',
|
||||||
'p.workspaceId',
|
'p.workspaceId',
|
||||||
])
|
])
|
||||||
.$if(opts?.includeContent, (qb) => qb.select('content'))
|
.$if(opts?.includeContent, (qb) => qb.select('p.content'))
|
||||||
.innerJoin('page_hierarchy as ph', 'p.parentPageId', 'ph.id'),
|
.innerJoin('page_hierarchy as ph', 'p.parentPageId', 'ph.id'),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
+1
-1
Submodule apps/server/src/ee updated: d3095f2d8b...4e7319ab01
@@ -68,7 +68,7 @@ function taskList(turndownService: TurndownService) {
|
|||||||
) as HTMLInputElement;
|
) as HTMLInputElement;
|
||||||
const isChecked = checkbox.checked;
|
const isChecked = checkbox.checked;
|
||||||
|
|
||||||
return `- ${isChecked ? '[x]' : '[ ]'} ${content.trim()} \n`;
|
return `- ${isChecked ? '[x]' : '[ ]'} ${content.trim()} \n`;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ export class StaticModule implements OnModuleInit {
|
|||||||
? this.environmentService.getSubdomainHost()
|
? this.environmentService.getSubdomainHost()
|
||||||
: undefined,
|
: undefined,
|
||||||
COLLAB_URL: this.environmentService.getCollabUrl(),
|
COLLAB_URL: this.environmentService.getCollabUrl(),
|
||||||
|
BILLING_TRIAL_DAYS: this.environmentService.isCloud()
|
||||||
|
? this.environmentService.getBillingTrialDays()
|
||||||
|
: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
const windowScriptContent = `<script>window.CONFIG=${JSON.stringify(configString)};</script>`;
|
const windowScriptContent = `<script>window.CONFIG=${JSON.stringify(configString)};</script>`;
|
||||||
|
|||||||
@@ -4,12 +4,7 @@ import {
|
|||||||
FastifyAdapter,
|
FastifyAdapter,
|
||||||
NestFastifyApplication,
|
NestFastifyApplication,
|
||||||
} from '@nestjs/platform-fastify';
|
} from '@nestjs/platform-fastify';
|
||||||
import {
|
import { Logger, NotFoundException, ValidationPipe } from '@nestjs/common';
|
||||||
Logger,
|
|
||||||
NotFoundException,
|
|
||||||
RequestMethod,
|
|
||||||
ValidationPipe,
|
|
||||||
} from '@nestjs/common';
|
|
||||||
import { TransformHttpResponseInterceptor } from './common/interceptors/http-response.interceptor';
|
import { TransformHttpResponseInterceptor } from './common/interceptors/http-response.interceptor';
|
||||||
import { WsRedisIoAdapter } from './ws/adapter/ws-redis.adapter';
|
import { WsRedisIoAdapter } from './ws/adapter/ws-redis.adapter';
|
||||||
import { InternalLogFilter } from './common/logger/internal-log-filter';
|
import { InternalLogFilter } from './common/logger/internal-log-filter';
|
||||||
@@ -92,6 +87,14 @@ async function bootstrap() {
|
|||||||
|
|
||||||
const logger = new Logger('NestApplication');
|
const logger = new Logger('NestApplication');
|
||||||
|
|
||||||
|
process.on('unhandledRejection', (reason, promise) => {
|
||||||
|
logger.error(`UnhandledRejection: ${promise}, reason: ${reason}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('uncaughtException', (error) => {
|
||||||
|
logger.error('UncaughtException:', error);
|
||||||
|
});
|
||||||
|
|
||||||
const port = process.env.PORT || 3000;
|
const port = process.env.PORT || 3000;
|
||||||
await app.listen(port, '0.0.0.0', () => {
|
await app.listen(port, '0.0.0.0', () => {
|
||||||
logger.log(
|
logger.log(
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "docmost",
|
"name": "docmost",
|
||||||
"homepage": "https://docmost.com",
|
"homepage": "https://docmost.com",
|
||||||
"version": "0.20.1",
|
"version": "0.20.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "nx run-many -t build",
|
"build": "nx run-many -t build",
|
||||||
|
|||||||
Reference in New Issue
Block a user