Files
upstream-affine/blocksuite/playground/apps/_common/components/docs-panel.ts
upstream-mirror 50f788e799
Some checks failed
Build & Test / Analyze (javascript, blocksuite) (push) Failing after 3s
Build & Test / Rust test filter (push) Failing after 3s
Build & Test / E2E BlockSuite Test (2) (push) Failing after 3s
Build & Test / E2E BlockSuite Test (3) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (4) (push) Failing after 3s
Build & Test / E2E BlockSuite Cross Browser Test (push) Failing after 3s
Build & Test / E2E Mobile Test (1) (push) Failing after 3s
Build & Test / E2E Mobile Test (2) (push) Failing after 3s
Build & Test / Build AFFiNE native (x86_64-unknown-linux-gnu) (push) Failing after 4s
Build & Test / Unit Test (1) (push) Has been skipped
Build & Test / Unit Test (2) (push) Has been skipped
Build & Test / Unit Test (3) (push) Has been skipped
Build & Test / Build Server native (push) Failing after 3s
Build & Test / Check Git Status (push) Has been skipped
Build & Test / Server Test (0, 4) (push) Has been skipped
Build & Test / Server Test (1, 4) (push) Has been skipped
Build & Test / Analyze (javascript, affine) (push) Failing after 3s
Build & Test / Analyze (typescript, affine) (push) Failing after 3s
Build & Test / Analyze (typescript, blocksuite) (push) Failing after 3s
Build & Test / Mobile native build filter (push) Failing after 3s
Build & Test / Check yarn binary (push) Failing after 3s
Build & Test / E2E BlockSuite Test (1) (push) Failing after 4s
Build & Test / E2E BlockSuite Test (5) (push) Failing after 3s
Build & Test / Unit Test (4) (push) Has been skipped
Build & Test / Unit Test (5) (push) Has been skipped
Build & Test / Native Unit Test (push) Has been skipped
Build & Test / Server Test (2, 4) (push) Has been skipped
Build & Test / Server Test (3, 4) (push) Has been skipped
Build & Test / Server Test with Elasticsearch (push) Has been skipped
Build & Test / Server Test with Embedded Search (push) Has been skipped
Build & Test / Server Test with Manticore Search (push) Has been skipped
Build & Test / Server E2E Test (push) Has been skipped
Build & Test / Cloud Desktop E2E Test (push) Has been skipped
Build & Test / Cloud E2E Test 1/2 (push) Has been skipped
Build & Test / Cloud E2E Test 2/2 (push) Has been skipped
Build & Test / Build @affine/electron renderer (push) Failing after 3s
Build & Test / Copilot test filter (push) Failing after 4s
Build & Test / Lint Rust (push) Has been skipped
Build & Test / Build Android app (push) Has been skipped
Build & Test / Test Android app (push) Has been skipped
Build & Test / Run native tests (push) Has been skipped
Build & Test / Server Copilot Api Test (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (3, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (4, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (1, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (2, 5) (push) Has been skipped
Build & Test / Frontend Copilot E2E Test (5, 5) (push) Has been skipped
Build & Test / Desktop Test (ubuntu-latest, linux, x64, x86_64-unknown-linux-gnu, true) (push) Has been cancelled
Build & Test / Desktop Test (windows-latest, windows, x64, x86_64-pc-windows-msvc, true) (push) Has been cancelled
Build & Test / 3, 2, 1 Launch (push) Has been cancelled
Build & Test / Lint (push) Has been cancelled
Build & Test / Typecheck (push) Has been cancelled
Build & Test / Build iOS app (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-apple-darwin) (push) Has been cancelled
Build & Test / E2E Test (1) (push) Has been cancelled
Build & Test / E2E Test (2) (push) Has been cancelled
Build & Test / E2E Test (3) (push) Has been cancelled
Build & Test / E2E Test (4) (push) Has been cancelled
Build & Test / E2E Test (5) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-apple-darwin) (push) Has been cancelled
Build & Test / Build AFFiNE native (aarch64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Build AFFiNE native (x86_64-pc-windows-msvc) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, arm64, aarch64-apple-darwin, true) (push) Has been cancelled
Build & Test / Desktop Test (macos-latest, macos, x64, x86_64-apple-darwin, false) (push) Has been cancelled
snapshot of https://github.com/toeverything/AFFiNE.git (canary, 2026-09-16; blobs > 131072B omitted)
2026-09-16 00:31:07 +05:00

182 lines
5.1 KiB
TypeScript

import { WithDisposable } from '@blocksuite/affine/global/lit';
import { GenerateDocUrlProvider } from '@blocksuite/affine/shared/services';
import { createDefaultDoc } from '@blocksuite/affine/shared/utils';
import { ShadowlessElement } from '@blocksuite/affine/std';
import type { Doc, Workspace } from '@blocksuite/affine/store';
import { CloseIcon } from '@blocksuite/icons/lit';
import type { TestAffineEditorContainer } from '@blocksuite/integration-test';
import { css, html, nothing } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { repeat } from 'lit/directives/repeat.js';
import { styleMap } from 'lit/directives/style-map.js';
import { removeModeFromStorage } from '../mock-services.js';
@customElement('docs-panel')
export class DocsPanel extends WithDisposable(ShadowlessElement) {
static override styles = css`
docs-panel {
display: flex;
flex-direction: column;
width: 100%;
background-color: var(--affine-background-secondary-color);
font-family: var(--affine-font-family);
height: 100%;
padding: 12px;
gap: 4px;
}
.doc-item:hover .delete-doc-icon {
display: flex;
}
.doc-item {
color: var(--affine-text-primary-color);
}
.delete-doc-icon {
display: none;
padding: 2px;
border-radius: 4px;
}
.delete-doc-icon:hover {
background-color: var(--affine-hover-color);
}
.delete-doc-icon svg {
width: 14px;
height: 14px;
color: var(--affine-secondary-color);
fill: var(--affine-secondary-color);
}
.new-doc-button {
margin-bottom: 16px;
border: 1px solid var(--affine-border-color);
border-radius: 4px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: var(--affine-text-primary-color);
}
.new-doc-button:hover {
background-color: var(--affine-hover-color);
}
`;
createDoc = () => {
createDocBlock(this.editor.doc.workspace);
};
gotoDoc = (doc: Doc) => {
const url = this.editor.std
.getOptional(GenerateDocUrlProvider)
?.generateDocUrl(doc.id);
if (url) history.pushState({}, '', url);
this.editor.doc = doc.getStore();
this.editor.doc.load();
this.editor.doc.resetHistory();
this.requestUpdate();
};
private get collection() {
return this.editor.doc.workspace;
}
private get docs() {
return [...this.collection.docs.values()];
}
override connectedCallback() {
super.connectedCallback();
requestAnimationFrame(() => {
const handleClickOutside = (event: MouseEvent) => {
if (!(event.target instanceof Node)) return;
const toggleButton = document.querySelector(
'sl-button[data-docs-panel-toggle]'
);
if (toggleButton?.contains(event.target as Node)) return;
if (!this.contains(event.target)) {
this.onClose?.();
}
};
document.addEventListener('click', handleClickOutside);
this.disposables.add(() => {
document.removeEventListener('click', handleClickOutside);
});
});
this.disposables.add(
this.editor.doc.workspace.slots.docListUpdated.subscribe(() => {
this.requestUpdate();
})
);
}
protected override render(): unknown {
const { docs, collection } = this;
return html`
<div @click="${this.createDoc}" class="new-doc-button">New Doc</div>
${repeat(
docs,
v => v.id,
doc => {
const style = styleMap({
backgroundColor:
this.editor.doc.id === doc.id
? 'var(--affine-hover-color)'
: undefined,
padding: '4px 4px 4px 8px',
borderRadius: '4px',
cursor: 'pointer',
display: 'flex',
justifyContent: 'space-between',
});
const click = () => {
this.gotoDoc(doc);
};
const deleteDoc = (e: MouseEvent) => {
e.stopPropagation();
const isDeleteCurrent = doc.id === this.editor.doc.id;
collection.removeDoc(doc.id);
removeModeFromStorage(doc.id);
// When delete the current doc, we need to set the editor doc to the first remaining doc
if (isDeleteCurrent) {
this.editor.doc = this.docs[0].getStore();
}
};
return html`<div class="doc-item" @click="${click}" style="${style}">
${doc.meta?.title || 'Untitled'}
${
docs.length > 1
? html`<div @click="${deleteDoc}" class="delete-doc-icon">
${CloseIcon()}
</div>`
: nothing
}
</div>`;
}
)}
`;
}
@property({ attribute: false })
accessor editor!: TestAffineEditorContainer;
@property({ attribute: false })
accessor onClose!: () => void;
}
function createDocBlock(collection: Workspace) {
const id = collection.idGenerator();
createDefaultDoc(collection, { id });
}
declare global {
interface HTMLElementTagNameMap {
'docs-panel': DocsPanel;
}
}