fix(core): ui state (#14933)

#### PR Dependency Tree


* **PR #14933** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
  * Added draft tab option to AI chat interface
* Introduced "Current document" session history view in chat history
popover
  * Added control to show/hide "New Chat" button

* **Improvements**
  * Enhanced chat history preservation when switching between sessions
  * Prevented duplicate session creation requests
  * Improved message handling during session transitions and generation

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/toeverything/AFFiNE/pull/14933)

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-05-09 23:33:37 +08:00
committed by GitHub
parent fcc45a3f44
commit 417d31cabe
11 changed files with 487 additions and 53 deletions
@@ -85,6 +85,18 @@ class NonThrottledController {
}
}
@UseGuards(CloudThrottlerGuard)
@Throttle('strict')
@Controller('/strict-throttled')
class StrictThrottledController {
@Public()
@SkipThrottle()
@Get('/skip')
skip() {
return 'skip';
}
}
test.before(async t => {
const app = await createTestingApp({
imports: [
@@ -100,7 +112,11 @@ test.before(async t => {
}),
AppModule,
],
controllers: [ThrottledController, NonThrottledController],
controllers: [
ThrottledController,
NonThrottledController,
StrictThrottledController,
],
});
t.context.storage = app.get(ThrottlerStorage);
@@ -244,6 +260,18 @@ test('should skip throttler for unauthenticated user when specified', async t =>
t.is(headers.reset, undefined!);
});
test('should skip class-level strict throttler when specified', async t => {
const { app } = t.context;
const res = await app.GET('/strict-throttled/skip').expect(200);
const headers = rateLimitHeaders(res);
t.is(headers.limit, undefined!);
t.is(headers.remaining, undefined!);
t.is(headers.reset, undefined!);
});
test('should use specified throttler for unauthenticated user', async t => {
const { app } = t.context;
@@ -1,5 +1,8 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import { SkipThrottle, Throttle as RawThrottle } from '@nestjs/throttler';
import {
SkipThrottle as RawSkipThrottle,
Throttle as RawThrottle,
} from '@nestjs/throttler';
import { ThrottlerType } from './config';
@@ -38,4 +41,11 @@ export function Throttle(
);
}
export { SkipThrottle };
export function SkipThrottle(
skip: Partial<Record<ThrottlerType, boolean>> = {
default: true,
strict: true,
}
): MethodDecorator & ClassDecorator {
return RawSkipThrottle(skip);
}