Compare commits
No commits in common. "d353b5b335bf651ed0b4889a7a852e1f0fe3c2a0" and "41aeefc1828b06576b168373cdf274ded734cb0a" have entirely different histories.
d353b5b335
...
41aeefc182
|
|
@ -49,11 +49,11 @@ No account, cloud service or sync server is required for local use.
|
|||
|
||||
| Overview: return to a Deal and see its recent work, captures and items that need attention. | Files: manage ordinary folders and documents inside a Deal. |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
| Notes: keep Markdown notes next to the Deal they describe. | Journal: record a completed session and retain its context. |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
## Main features
|
||||
|
||||
|
|
|
|||
|
|
@ -49,11 +49,11 @@
|
|||
|
||||
| Обзор: возвращает к делу и показывает недавнюю работу, входящие и то, что требует внимания. | Файлы: обычные папки и документы прямо внутри дела. |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
| Заметки: Markdown-заметки остаются рядом с делом, которое они описывают. | Журнал: фиксирует завершённую работу и её контекст. |
|
||||
| --- | --- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
## Основные возможности
|
||||
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
|
@ -175,10 +175,10 @@ test.describe('F: Default Editor Plugin', () => {
|
|||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
const title = workbench.locator('.workbench-title');
|
||||
await expect(title).toHaveText('readme.md');
|
||||
await expect(title).toHaveText('Docs/readme.md');
|
||||
});
|
||||
|
||||
test('opening a note uses its title rather than its technical path', async ({ page }) => {
|
||||
test('open .md with notes context routes to highest-priority provider', async ({ page }) => {
|
||||
await page.evaluate(async () => {
|
||||
const [result, err] = await window.go.api.App.OpenWorkbenchResource('verstak.platform-test', {
|
||||
kind: 'vault-file',
|
||||
|
|
@ -193,7 +193,7 @@ test.describe('F: Default Editor Plugin', () => {
|
|||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
const title = workbench.locator('.workbench-title');
|
||||
await expect(title).toHaveText('Overview');
|
||||
await expect(title).toHaveText('Notes/Overview.md');
|
||||
});
|
||||
|
||||
test('default-editor plugin is listed as loaded in plugin manager', async ({ page }) => {
|
||||
|
|
|
|||
|
|
@ -513,7 +513,7 @@ test.describe('G: Files Plugin', () => {
|
|||
|
||||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('readme.md');
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('Docs/readme.md');
|
||||
|
||||
const preview = page.locator('.de-preview');
|
||||
await expect(preview).toBeVisible({ timeout: 10000 });
|
||||
|
|
@ -535,7 +535,7 @@ test.describe('G: Files Plugin', () => {
|
|||
|
||||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('Overview');
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('Notes/Overview.md');
|
||||
});
|
||||
|
||||
test('files plugin card shows openProviders in contributions', async ({ page }) => {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ test.describe('D: Plugin API bridge', () => {
|
|||
|
||||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('Overview');
|
||||
await expect(workbench.locator('.workbench-title')).toHaveText('Notes/Overview.md');
|
||||
});
|
||||
|
||||
test('workbench routes markdown files to default-editor provider', async ({ page }) => {
|
||||
|
|
@ -76,7 +76,7 @@ test.describe('D: Plugin API bridge', () => {
|
|||
const workbench = page.locator('.workbench-host');
|
||||
await expect(workbench).toBeVisible({ timeout: 10000 });
|
||||
const title = workbench.locator('.workbench-title');
|
||||
await expect(title).toHaveText('readme.md');
|
||||
await expect(title).toHaveText('Docs/readme.md');
|
||||
});
|
||||
|
||||
test('workbench shows no-provider fallback when no provider matches', async ({ page }) => {
|
||||
|
|
@ -91,10 +91,8 @@ test.describe('D: Plugin API bridge', () => {
|
|||
window.dispatchEvent(new CustomEvent('verstak:workbench-opened', { detail: result }));
|
||||
});
|
||||
|
||||
const fallback = page.locator('[data-workbench-status="no-provider"]');
|
||||
await expect(fallback).toBeVisible();
|
||||
await expect(fallback).toContainText('No viewer/editor available');
|
||||
await expect(fallback).not.toContainText('generic-text');
|
||||
await expect(page.locator('[data-workbench-status="no-provider"]')).toBeVisible();
|
||||
await expect(page.locator('[data-workbench-status="no-provider"]')).toContainText('No viewer/editor available');
|
||||
});
|
||||
|
||||
test('sync plugin API routes through mocked Wails bridge', async ({ page }) => {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
$: requestContext = openedResource?.request?.context?.notesMode || openedResource?.request?.context?.isInsideNotesFolder
|
||||
? 'notes-markdown'
|
||||
: ((openedResource?.request?.extension === '.md' || openedResource?.request?.extension === '.markdown') ? 'generic-markdown' : 'generic-text');
|
||||
$: resourceTitle = resourceDisplayTitle(resourcePath, requestContext);
|
||||
$: componentProps = openedResource || {};
|
||||
$: mountKey = [
|
||||
providerPluginId,
|
||||
|
|
@ -32,11 +31,6 @@
|
|||
requestContext,
|
||||
].join(':');
|
||||
|
||||
function resourceDisplayTitle(path, context) {
|
||||
const fileName = String(path || '').split('/').filter(Boolean).pop() || String(path || '');
|
||||
return context === 'notes-markdown' ? fileName.replace(/\.(md|markdown)$/i, '') : fileName;
|
||||
}
|
||||
|
||||
function closeWorkbench() {
|
||||
window.dispatchEvent(new CustomEvent('verstak:close-workbench', { cancelable: true }));
|
||||
}
|
||||
|
|
@ -47,7 +41,7 @@
|
|||
<div class="workbench-host vt-page">
|
||||
{#if openedResource?.status === 'no-provider'}
|
||||
<div class="workbench-header vt-page-header">
|
||||
<span class="workbench-title vt-page-title">{resourceTitle}</span>
|
||||
<span class="workbench-title vt-page-title">{resourcePath}</span>
|
||||
<span class="workbench-provider vt-badge">{tr('workbench.noProvider')}</span>
|
||||
<button class="close-btn btn-ghost btn-icon" type="button" title={tr('common.close')} aria-label={tr('common.close')} on:click={closeWorkbench}>
|
||||
<Icon name="x" size={18} />
|
||||
|
|
@ -55,13 +49,11 @@
|
|||
</div>
|
||||
<div class="workbench-empty no-provider vt-empty-state" data-workbench-status="no-provider">
|
||||
<p class="vt-empty-title">{tr('workbench.noViewer')}</p>
|
||||
{#if debug.isEnabled()}
|
||||
<p class="workbench-meta">{requestMode} · {requestContext}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{:else if openedResource}
|
||||
<div class="workbench-header vt-page-header">
|
||||
<span class="workbench-title vt-page-title">{resourceTitle}</span>
|
||||
<span class="workbench-title vt-page-title">{resourcePath}</span>
|
||||
{#if debug.isEnabled() && providerId}
|
||||
<span class="workbench-provider vt-badge accent" data-debug-provider>{providerId}</span>
|
||||
{/if}
|
||||
|
|
|
|||