fix(server): use new LocalWorkspace ServerFeature instead (#13091)

keep compatibility

close AF-2720



#### PR Dependency Tree


* **PR #13091** 👈

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

## Summary by CodeRabbit

* **New Features**
* Added a new `LocalWorkspace` feature flag to server configuration,
enabling more flexible feature management.

* **Deprecations**
* The `allowGuestDemoWorkspace` flag is now deprecated and will be
removed in version 0.25.0. Please use the `features` array for feature
checks instead.

* **Bug Fixes**
* Updated UI and logic throughout the app to rely on the new
`LocalWorkspace` feature flag rather than the deprecated boolean flag.

* **Chores**
* Removed references to `allowGuestDemoWorkspace` from configuration,
queries, and type definitions for improved consistency.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


#### PR Dependency Tree


* **PR #13091** 👈

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
This commit is contained in:
fengmk2
2025-07-08 23:23:42 +08:00
committed by GitHub
parent 15db657b1c
commit 95f88c378c
18 changed files with 79 additions and 37 deletions

View File

@@ -2,6 +2,7 @@
/**
* @vitest-environment happy-dom
*/
import { ServerFeature } from '@affine/graphql';
import { renderHook, waitFor } from '@testing-library/react';
import { beforeEach, describe, expect, test, vi } from 'vitest';
@@ -24,8 +25,10 @@ vi.mock('@toeverything/infra', () => {
server: {
config$: {
value: {
get allowGuestDemoWorkspace() {
return allowGuestDemo;
get features() {
return allowGuestDemo !== false
? [ServerFeature.LocalWorkspace]
: [];
},
},
},

View File

@@ -5,6 +5,7 @@ import {
} from '@affine/component';
import { AuthService, DefaultServerService } from '@affine/core/modules/cloud';
import { UserFriendlyError } from '@affine/error';
import { ServerFeature } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { useService, useServices } from '@toeverything/infra';
import { useCallback } from 'react';
@@ -32,12 +33,15 @@ export const useSignOut = ({
const signOut = useCallback(async () => {
onConfirm?.()?.catch(console.error);
const enableLocalWorkspace =
BUILD_CONFIG.isNative ||
defaultServerService.server.config$.value.features.includes(
ServerFeature.LocalWorkspace
);
try {
await authService.signOut();
if (
defaultServerService.server.config$.value.allowGuestDemoWorkspace !==
false
) {
if (enableLocalWorkspace) {
jumpToIndex();
} else {
jumpToSignIn();

View File

@@ -1,5 +1,6 @@
import { MenuItem } from '@affine/component/ui/menu';
import { DefaultServerService } from '@affine/core/modules/cloud';
import { ServerFeature } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { ImportIcon, PlusIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra';
@@ -15,10 +16,13 @@ export const AddWorkspace = ({
}) => {
const t = useI18n();
const defaultServerService = useService(DefaultServerService);
const allowGuestDemo = useLiveData(
defaultServerService.server.config$.selector(c => c.allowGuestDemoWorkspace)
const enableLocalWorkspace = useLiveData(
defaultServerService.server.config$.selector(
c =>
c.features.includes(ServerFeature.LocalWorkspace) ||
BUILD_CONFIG.isNative
)
);
const guestDemoEnabled = allowGuestDemo !== false;
return (
<>
@@ -45,7 +49,7 @@ export const AddWorkspace = ({
className={styles.ItemContainer}
>
<div className={styles.ItemText}>
{guestDemoEnabled
{enableLocalWorkspace
? t['com.affine.workspaceList.addWorkspace.create']()
: t['com.affine.workspaceList.addWorkspace.create-cloud']()}
</div>

View File

@@ -3,6 +3,7 @@ import { MenuItem } from '@affine/component/ui/menu';
import { AuthService, DefaultServerService } from '@affine/core/modules/cloud';
import { GlobalDialogService } from '@affine/core/modules/dialogs';
import { type WorkspaceMetadata } from '@affine/core/modules/workspace';
import { ServerFeature } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import { Logo1Icon } from '@blocksuite/icons/rc';
@@ -74,11 +75,12 @@ export const UserWithWorkspaceList = ({
}, [globalDialogService]);
const onNewWorkspace = useCallback(() => {
if (
!isAuthenticated &&
defaultServerService.server.config$.value.allowGuestDemoWorkspace ===
false
) {
const enableLocalWorkspace =
BUILD_CONFIG.isNative ||
defaultServerService.server.config$.value.features.includes(
ServerFeature.LocalWorkspace
);
if (!isAuthenticated && !enableLocalWorkspace) {
return openSignInModal();
}
track.$.navigationPanel.workspaceList.createWorkspace();

View File

@@ -5,6 +5,7 @@ import {
buildShowcaseWorkspace,
createFirstAppData,
} from '@affine/core/utils/first-app-data';
import { ServerFeature } from '@affine/graphql';
import {
useLiveData,
useService,
@@ -52,10 +53,12 @@ export const Component = ({
const loggedIn = useLiveData(
authService.session.status$.map(s => s === 'authenticated')
);
const allowGuestDemo =
const enableLocalWorkspace =
useLiveData(
defaultServerService.server.config$.selector(
c => c.allowGuestDemoWorkspace
c =>
c.features.includes(ServerFeature.LocalWorkspace) ||
BUILD_CONFIG.isNative
)
) ?? true;
@@ -92,7 +95,7 @@ export const Component = ({
return;
}
if (!allowGuestDemo && !loggedIn) {
if (!enableLocalWorkspace && !loggedIn) {
localStorage.removeItem('last_workspace_id');
jumpToSignIn();
return;
@@ -125,7 +128,7 @@ export const Component = ({
openPage(openWorkspace.id, defaultIndexRoute, RouteLogic.REPLACE);
}
}, [
allowGuestDemo,
enableLocalWorkspace,
createCloudWorkspace,
list,
openPage,

View File

@@ -17,7 +17,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
// since we never build desktop app in selfhosted mode, so it's fine
config: {
serverName: 'Affine Selfhost',
features: [],
features: [ServerFeature.LocalWorkspace],
oauthProviders: [],
type: ServerDeploymentType.Selfhosted,
credentialsRequirement: {
@@ -26,7 +26,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]
@@ -45,6 +44,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
ServerFeature.CopilotEmbedding,
ServerFeature.OAuth,
ServerFeature.Payment,
ServerFeature.LocalWorkspace,
],
oauthProviders: [
OAuthProviderType.Google,
@@ -57,7 +57,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]
@@ -78,6 +77,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
ServerFeature.CopilotEmbedding,
ServerFeature.OAuth,
ServerFeature.Payment,
ServerFeature.LocalWorkspace,
],
oauthProviders: [
OAuthProviderType.Google,
@@ -90,7 +90,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]
@@ -111,6 +110,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
ServerFeature.CopilotEmbedding,
ServerFeature.OAuth,
ServerFeature.Payment,
ServerFeature.LocalWorkspace,
],
oauthProviders: [
OAuthProviderType.Google,
@@ -123,7 +123,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]
@@ -140,6 +139,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
ServerFeature.CopilotEmbedding,
ServerFeature.OAuth,
ServerFeature.Payment,
ServerFeature.LocalWorkspace,
],
oauthProviders: [
OAuthProviderType.Google,
@@ -152,7 +152,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]
@@ -171,6 +170,7 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
ServerFeature.CopilotEmbedding,
ServerFeature.OAuth,
ServerFeature.Payment,
ServerFeature.LocalWorkspace,
],
oauthProviders: [
OAuthProviderType.Google,
@@ -183,7 +183,6 @@ export const BUILD_IN_SERVERS: (ServerMetadata & { config: ServerConfig })[] =
maxLength: 32,
},
},
allowGuestDemoWorkspace: true,
},
},
]

View File

@@ -82,7 +82,6 @@ export class Server extends Entity<{
credentialsRequirement: config.credentialsRequirement,
features: config.features,
oauthProviders: config.oauthProviders,
allowGuestDemoWorkspace: config.allowGuestDemoWorkspace,
serverName: config.name,
type: config.type,
version: config.version,

View File

@@ -82,7 +82,6 @@ export class ServersService extends Service {
credentialsRequirement: config.credentialsRequirement,
features: config.features,
oauthProviders: config.oauthProviders,
allowGuestDemoWorkspace: config.allowGuestDemoWorkspace,
serverName: config.name,
type: config.type,
initialized: config.initialized,

View File

@@ -14,7 +14,6 @@ export interface ServerMetadata {
export interface ServerConfig {
serverName: string;
features: ServerFeature[];
allowGuestDemoWorkspace: boolean;
oauthProviders: OAuthProviderType[];
type: ServerDeploymentType;
initialized?: boolean;