Migrate Files surfaces to interface patterns

This commit is contained in:
2026-08-03 09:35:52 +02:00
parent 6baf2a421b
commit d8ae506ff8
9 changed files with 229 additions and 54 deletions
@@ -0,0 +1,46 @@
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
function read(relativePath) {
return readFileSync(fileURLToPath(new URL(relativePath, import.meta.url)), "utf8");
}
const connector = read("../src/features/files/FileConnectorSettingsPanel.tsx");
const filesPage = read("../src/features/files/FilesPage.tsx");
const moduleSource = read("../src/module.ts");
const styles = read("../src/styles/file-manager.css");
const migration = read("../../docs/INTERFACE_PATTERN_MIGRATION.md");
assert.match(connector, /ActionBlockerHint,[\s\S]*AdvancedOptionsPanel,[\s\S]*DocumentationHelpLink/);
assert.match(connector, /ConnectionTree,[\s\S]*ConfirmDialog,[\s\S]*Dialog,[\s\S]*LoadingFrame/);
assert.match(connector, /topicId: "files\.governed-connectors-and-provenance"/);
assert.match(connector, /documentation=\{CONNECTOR_DOCUMENTATION\}/);
assert.match(connector, /disabledReason=\{profileSaveDisabledReason\}/);
assert.match(connector, /disabledReason=\{credentialSaveDisabledReason\}/);
assert.match(connector, /disabledReason: mutationBlocker/);
assert.match(connector, /<AdvancedOptionsPanel title="Connection metadata JSON"/);
assert.match(connector, /<AdvancedOptionsPanel title="Credential metadata JSON"/);
assert.doesNotMatch(connector, /window\.(?:alert|confirm)\(/);
assert.match(filesPage, /DocumentationHelpLink/);
assert.match(filesPage, /topicId: "files\.workflow\.organize-managed-files"/);
assert.match(filesPage, /disabledReason=\{uploadBlocker\}/);
assert.match(filesPage, /disabledReason=\{deleteBlocker\}/);
assert.match(filesPage, /<ConfirmDialog[\s\S]*tone="danger"/);
assert.match(filesPage, /className="workspace-data-page module-entry-page file-manager-page file-manager-fullscreen files-page"/);
assert.doesNotMatch(filesPage, /window\.(?:alert|confirm)\(/);
assert.doesNotMatch(`${connector}\n${filesPage}\n${moduleSource}`, /@govoplan\/(?:campaign|mail|docs)-webui|govoplan_(?:campaign|mail|docs)/);
assert.match(moduleSource, /"files\.connectors"/);
assert.match(moduleSource, /"files\.fileExplorer"/);
assert.match(styles, /@media \(max-width: 1050px\)[\s\S]*\.files-page \.file-manager-shell[\s\S]*grid-template-columns: 1fr/);
assert.match(styles, /@media \(max-width: 760px\)[\s\S]*\.file-connector-profile-row[\s\S]*grid-template-columns: 1fr/);
for (const archetype of ["Directory/explorer", "Adaptive create/edit", "Effective-policy editor", "Dashboard widget"]) {
assert.match(migration, new RegExp(archetype.replace("/", "\\/")));
}
assert.match(migration, /Shared `Dialog` owns focus entry, Escape handling and focus return/);
assert.match(migration, /Secret values are[\s\S]*never returned for rendering/);
console.log("Files surfaces satisfy the recorded interface pattern-language contract.");