feat: add main editor resource tabs

This commit is contained in:
lix-2026
2026-05-20 14:20:48 +08:00
parent 322c7ffdce
commit 03173e2363
9 changed files with 1490 additions and 38 deletions
@@ -297,7 +297,34 @@ pub fn DocumentPage(
data-testid="mnote-document-workspace"
data-has-secondary-pane={secondary_visible.to_string()}
>
<DocumentPane model={primary_model} />
<section class="document-main-editor-group" data-testid="mnote-main-editor-tab-host">
<div class="mnote-main-tab-strip" data-mnote-main-tab-strip="true" role="tablist" aria-label="主编辑区标签页">
<button
type="button"
class="mnote-main-tab is-active"
data-mnote-main-tab="page"
data-mnote-tab-kind="page"
role="tab"
aria-selected="true"
>
<span class="material-symbols-outlined" aria-hidden="true">"description"</span>
<span class="mnote-main-tab-title">{title.clone()}</span>
</button>
</div>
<div class="mnote-main-tab-panels">
<div data-mnote-page-tab-panel="true">
<DocumentPane model={primary_model} />
</div>
<section
class="mnote-resource-tab-host"
data-mnote-resource-tab-host="true"
data-testid="mnote-resource-tab-host"
hidden=true
>
<div class="mnote-resource-tab-panel-root" data-mnote-resource-tab-panel-root="true"></div>
</section>
</div>
</section>
<div
class="document-pane-resizer"
data-testid="mnote-secondary-pane-resizer"
+89 -4
View File
@@ -2062,7 +2062,7 @@ const SIDEBAR_TREE_JS: &str = r##"
return '/onlyoffice?' + params.toString();
}
function buildLocalOnlyOfficeOpenUrl(relativePath, fileName, documentId, assetId) {
function buildLocalOnlyOfficeOpenUrl(relativePath, fileName, documentId, assetId, mode) {
var fileType = inferOnlyOfficeFileType(fileName || relativePath || '', '');
if (!fileType) return '';
var fileUrl = buildLocalFileOpenUrl(relativePath, false);
@@ -2074,7 +2074,7 @@ const SIDEBAR_TREE_JS: &str = r##"
assetId: assetId || ('local-file:' + relativePath),
documentId: documentId || currentDocumentId() || '',
userId: '',
mode: 'edit'
mode: mode || 'edit'
});
}
@@ -2150,6 +2150,29 @@ const SIDEBAR_TREE_JS: &str = r##"
return url.toString();
}
async function openLocalResourceInActiveTab(input) {
if (typeof window.__mnoteDocumentPaneRuntime?.openResourceInActiveTab !== 'function') return false;
var relativePath = String(input && input.path || '').trim();
var rootUri = String(input && input.rootUri || currentRootUri() || '').trim();
if (!relativePath || !rootUri) return false;
var title = String(input && input.title || '').trim() || relativePath.split('/').pop() || relativePath;
var kind = String(input && input.kind || fileTreeIconKindForFileName(title) || '').trim();
var objectIdentity = 'resource:file:' + rootUri + ':' + relativePath;
return await window.__mnoteDocumentPaneRuntime.openResourceInActiveTab({
objectIdentity: objectIdentity,
assetId: String(input && input.assetId || '').trim() || 'local-file:' + relativePath,
title: title,
fileName: title,
kind: kind,
rootUri: rootUri,
path: relativePath,
href: String(input && input.href || buildLocalFileOpenUrl(relativePath, false) || '').trim(),
officeUrl: String(input && input.officeUrl || '').trim(),
documentId: String(input && input.documentId || currentDocumentId() || '').trim(),
workspaceId: String(input && input.workspaceId || resolveWorkspaceId(document.body) || '').trim()
});
}
function readFileTreeObjectIdentity(row) {
if (!row) return null;
var raw = row.getAttribute('data-object-identity') || '';
@@ -2179,6 +2202,7 @@ const SIDEBAR_TREE_JS: &str = r##"
async function openConvexAssetFromFileTree(detail) {
var assetId = String(detail && detail.assetId || '').trim();
if (!assetId) return;
var forceNewWindow = String(detail && detail.openTarget || '').trim() === 'new-window';
var localFilePath = localFilePathFromAssetId(assetId);
if (localFilePath) {
var localFileName = localFilePath.split('/').pop() || localFilePath;
@@ -2188,13 +2212,33 @@ const SIDEBAR_TREE_JS: &str = r##"
navigateToMindmapObject(String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, String(detail.workspaceId || '').trim());
return;
}
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId);
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail && detail.documentId || currentDocumentId() || '').trim(), assetId, forceNewWindow ? 'edit' : 'view');
if (localOfficeUrl) {
if (!forceNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: 'office',
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
officeUrl: localOfficeUrl
})) return;
window.open(localOfficeUrl, '_blank', 'noopener,noreferrer');
return;
}
var localFileUrl = buildLocalFileOpenUrl(localFilePath, false);
if (localFileUrl) window.open(localFileUrl, '_blank', 'noopener,noreferrer');
if (localFileUrl) {
if (!forceNewWindow && await openLocalResourceInActiveTab({
path: localFilePath,
title: localFileName,
kind: fileTreeIconKindForFileName(localFileName),
assetId: assetId,
documentId: String(detail && detail.documentId || currentDocumentId() || '').trim(),
workspaceId: String(detail.workspaceId || '').trim(),
href: localFileUrl
})) return;
window.open(localFileUrl, '_blank', 'noopener,noreferrer');
}
return;
}
var documentId = String(detail && detail.documentId || '').trim();
@@ -3319,6 +3363,10 @@ const SIDEBAR_TREE_JS: &str = r##"
openEditorAttachmentDetail(detail);
return;
}
if (action === 'new-window') {
openEditorAttachmentNewWindow(detail);
return;
}
if (action === 'right-preview') {
dispatchSidebarEvent('tree.attachment.open-right', detail);
return;
@@ -3334,6 +3382,10 @@ const SIDEBAR_TREE_JS: &str = r##"
var workspaceId = detail.workspaceId || resolveWorkspaceId(trigger || document.body);
var title = detail.title || '';
var isAsset = detail.contextKind === 'filetree' && detail.assetId && detail.rowKind !== 'document' && detail.rowKind !== 'index';
if (isAsset && action === 'new-window') {
void openConvexAssetFromFileTree({ ...detail, openTarget: 'new-window' });
return;
}
if (action === 'open-right') {
dispatchSidebarEvent('tree.page.open-right', detail);
return;
@@ -3502,6 +3554,7 @@ const SIDEBAR_TREE_JS: &str = r##"
{ separator: true },
{ action: 'popup-preview', icon: 'preview', label: '' },
{ action: 'right-preview', icon: 'right_panel_open', label: '' },
{ action: 'new-window', icon: 'open_in_new', label: '' },
{ action: 'download', icon: 'download', label: '' },
{ action: 'replace-file', icon: 'sync', label: '' },
{ action: 'rename-attachment', icon: 'drive_file_rename_outline', label: '' },
@@ -3511,6 +3564,7 @@ const SIDEBAR_TREE_JS: &str = r##"
{ action: 'color', icon: 'format_paint', label: '' }
] : isAsset ? [
{ action: 'open-right', icon: 'open_in_new', label: '', shortcut: 'Alt + O' },
{ action: 'new-window', icon: 'open_in_new', label: '' },
{ action: 'rename', icon: 'edit', label: '', shortcut: 'F2' },
{ action: 'copy-id', icon: 'tag', label: ' ID' },
{ action: 'delete-trash', icon: 'delete', label: '', shortcut: 'Del', danger: true },
@@ -7218,6 +7272,24 @@ const SIDEBAR_TREE_JS: &str = r##"
function openEditorAttachmentDetail(detail) {
if (!detail || !detail.href) return;
var localFilePath = localFilePathFromAssetId(detail.assetId);
if (localFilePath) {
var localFileName = localFilePath.split('/').pop() || localFilePath;
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail.documentId || currentDocumentId() || '').trim(), detail.assetId, 'view');
void openLocalResourceInActiveTab({
path: localFilePath,
title: detail.fileName || localFileName,
kind: localOfficeUrl ? 'office' : fileTreeIconKindForFileName(detail.fileName || localFileName),
assetId: detail.assetId,
documentId: detail.documentId || currentDocumentId() || '',
workspaceId: detail.workspaceId || resolveWorkspaceId(document.body) || '',
href: buildLocalFileOpenUrl(localFilePath, false),
officeUrl: localOfficeUrl
}).then(function(opened) {
if (!opened) window.open(localOfficeUrl || buildLocalFileOpenUrl(localFilePath, false) || detail.href, '_blank', 'noopener,noreferrer');
});
return;
}
if (isPdfAttachmentFileName(detail.fileName)) {
void openPdfEditorAttachment(detail);
return;
@@ -7229,6 +7301,19 @@ const SIDEBAR_TREE_JS: &str = r##"
window.open(detail.href, '_blank', 'noopener,noreferrer');
}
function openEditorAttachmentNewWindow(detail) {
if (!detail) return;
var localFilePath = localFilePathFromAssetId(detail.assetId);
if (localFilePath) {
var localFileName = localFilePath.split('/').pop() || localFilePath;
var localOfficeUrl = buildLocalOnlyOfficeOpenUrl(localFilePath, localFileName, String(detail.documentId || currentDocumentId() || '').trim(), detail.assetId, 'edit');
var localFileUrl = buildLocalFileOpenUrl(localFilePath, false);
window.open(localOfficeUrl || localFileUrl || detail.href, '_blank', 'noopener,noreferrer');
return;
}
window.open(detail.href || detail.fileUrl, '_blank', 'noopener,noreferrer');
}
async function resolveEditorAttachmentUrl(detail) {
var assetId = String(detail && detail.assetId || '').trim();
var localFilePath = localFilePathFromAssetId(assetId);
+112
View File
@@ -2372,6 +2372,118 @@ body {
grid-template-columns: minmax(0, 1fr) var(--mnote-secondary-pane-resizer-width) var(--mnote-secondary-pane-width);
}
.document-main-editor-group {
min-width: 0;
}
.mnote-main-tab-strip {
min-height: 36px;
display: flex;
align-items: flex-end;
gap: 1px;
border-bottom: 1px solid #E9E9E8;
background: #FAFAF9;
padding: 0 10px;
position: sticky;
top: 0;
z-index: 20;
}
.mnote-main-tab {
height: 34px;
max-width: 240px;
min-width: 0;
display: inline-flex;
align-items: center;
gap: 7px;
border: 0;
border-radius: 6px 6px 0 0;
background: transparent;
color: #6B6862;
padding: 0 9px;
cursor: pointer;
font-size: 13px;
line-height: 1;
}
.mnote-main-tab:hover {
background: #F4F3F3;
color: #1B1C1C;
}
.mnote-main-tab.is-active {
background: #FFF;
color: #1B1C1C;
box-shadow: inset 0 1px 0 #E9E9E8, inset 1px 0 0 #E9E9E8, inset -1px 0 0 #E9E9E8;
}
.mnote-main-tab .material-symbols-outlined {
font-size: 16px;
flex: 0 0 auto;
}
.mnote-main-tab-title {
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mnote-main-tab-close {
width: 18px;
height: 18px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 0;
border-radius: 4px;
background: transparent;
color: inherit;
padding: 0;
cursor: pointer;
}
.mnote-main-tab-close:hover {
background: rgba(55, 53, 47, 0.12);
}
.mnote-main-tab-panels {
min-width: 0;
}
.mnote-resource-tab-host[hidden],
.mnote-resource-tab-panel[hidden],
[data-mnote-page-tab-panel][hidden] {
display: none !important;
}
.mnote-resource-tab-panel {
min-height: calc(100vh - 76px);
}
.mnote-resource-tab-frame,
.mnote-resource-tab-image,
.mnote-resource-tab-text-shell {
width: 100%;
min-height: calc(100vh - 80px);
border: 0;
background: #FFF;
}
.mnote-resource-tab-image {
display: block;
object-fit: contain;
padding: 28px;
}
.mnote-resource-tab-text-shell {
padding: 34px 48px;
}
.mnote-resource-tab-editor-root {
min-height: calc(100vh - 112px);
}
.document-pane {
min-width: 0;
}