feat(core): experimental features ui (#5338)

fix TOV-280

experimental features ui
- enabled in the workspace settings for a cloud workspace; only show for workspace owner + early access
- a disclaimer prompt will be shown before going to the next feature setting page
- for now only show the ai poc switch, which controls the display of the ai tab in editor's sidepanel
This commit is contained in:
Peng Xiao
2024-01-18 07:53:15 +00:00
parent cabedef426
commit 9a944048e8
24 changed files with 2297 additions and 146 deletions
@@ -40,10 +40,9 @@ const activeExtensionAtom = selectAtom(
);
const widthAtom = selectAtom(baseStateAtom, state => state.width);
export const editorExtensionsAtom = selectAtom(baseStateAtom, state =>
state.extensions.filter(e => {
return e.name !== 'copilot' || runtimeConfig.enableCopilot;
})
export const editorExtensionsAtom = selectAtom(
baseStateAtom,
state => state.extensions
);
// get/set sidebar open state
@@ -1,6 +1,9 @@
import { IconButton } from '@affine/component';
import { useWorkspaceEnabledFeatures } from '@affine/core/hooks/use-workspace-features';
import { FeatureType } from '@affine/graphql';
import { assignInlineVars } from '@vanilla-extract/dynamic';
import { useAtom, useAtomValue } from 'jotai';
import { useEffect } from 'react';
import {
editorExtensionsAtom,
@@ -11,13 +14,25 @@ import * as styles from './extensions.css';
// provide a switcher for active extensions
// will be used in global top header (MacOS) or sidebar (Windows)
export const ExtensionTabs = () => {
const exts = useAtomValue(editorExtensionsAtom);
// todo: filter in editorExtensionsAtom instead?
const copilotEnabled = useWorkspaceEnabledFeatures().includes(
FeatureType.Copilot
);
const exts = useAtomValue(editorExtensionsAtom).filter(ext => {
if (ext.name === 'copilot' && !copilotEnabled) return false;
return true;
});
const [selected, setSelected] = useAtom(editorSidebarActiveExtensionAtom);
const vars = assignInlineVars({
[styles.activeIdx]: String(
exts.findIndex(ext => ext.name === selected?.name) ?? 0
),
});
useEffect(() => {
if (!selected || !exts.some(e => selected.name === e.name)) {
setSelected(exts[0].name);
}
}, [exts, selected, setSelected]);
return (
<div className={styles.switchRoot} style={vars}>
{exts.map(extension => {