İçeriğe geç
Docs

İzinler ve Migration

Düğüm izinleri (drag, delete, duplicate, edit) ve katman sırası, resolvePermissions, kilitli düğümler; MigrationConfig ile eski sayfa verisini yeni şemaya güvenle yükseltme.

Son güncelleme:

İzin modeli#

İzinler varsayılan olarak açıktır; kısıtlamaya bir bayrağı false yaparak katılırsınız.

TypeScript
interface Permissions {
  drag: boolean;      // kanvas ve katmanlarda taşıma
  delete: boolean;    // tekli/toplu silme ve kesme
  duplicate: boolean; // çoğaltma ve yeni id ile yapıştırma
  edit: boolean;      // Inspector alanlarının düzenlenmesi
  [key: string]: boolean; // host’a özel ek izinler
}

Bir düğümün etkin izni katmanların birleşimidir; sonraki katman öncekini ezer:

Metin
varsayılan < config.permissions < component.permissions < component.resolvePermissions(props) < düğümün _locked kilidi
TypeScript
const editorConfig: StudioConfig = {
  permissions: { delete: false },            // genel: hiçbir şey silinemez
  components: {
    Header: {
      permissions: { drag: false },          // header taşınamaz
      resolvePermissions: (props) => ({ edit: !props.locked }),
      render: (p) => <header className={p.className} />,
    },
    Hero: {
      permissions: { delete: true },         // Hero için silmeye yeniden izin ver
      render: (p) => <section className={p.className} />,
    },
  },
};
  • Kısıtlar motor seviyesinde uygulanır: düğme gizlemekle kalmaz; klavye kısayolları (⌘D, Delete), sağ tık menüsü ve pano işlemleri de aynı kurala uyar.
  • edit: false Inspector alanlarını salt okunur yapar.
  • Delete izni olmayan düğümde kes işlemi düz kopyalamaya döner.
  • Eksik anahtar ya da resolvePermissions’ın fırlattığı hata izinleri sıkılaştırmaz; o katman bir alttakinden devralınır. Hatalı bir çözümleyici kullanıcıyı kilitlemez.
  • Katmanlar panelindeki kilit (_locked) aynı izin sistemini kullanır. Kilitli düğüm seçilebilir kalır (kilidi açabilmek için).

Dinamik izinler#

TypeScript
resolvePermissions?: (props: any, ctx: { changed: Record<string, boolean>; lastProps: Record<string, any> | null }) => Partial<Permissions>;

ctx.changed son çözümden beri değişen prop’ları, ctx.lastProps önceki anlık görüntüyü verir (ilk çalıştırmada null); yalnız ilgili alan değiştiğinde yeniden hesap yapmak için kullanın.

Veri migration’ı#

Bir bileşenin tip adı ya da prop şeması değiştiğinde önceden kaydedilmiş sayfalar eski şemada kalır. migrations, belge editörde yüklenirken ve TecofRender ile render edilirken otomatik uygulanır.

TypeScript
interface MigrationConfig {
  version?: number;                                   // hedef şema sürümü
  renameComponents?: Record<string, string>;          // { eskiTip: yeniTip }
  transformProps?: Record<string, (props: any) => any>; // YENİ tip adına göre
  migrate?: (doc: TecofDocument) => TecofDocument;     // son, serbest geçiş
}
TypeScript
const editorConfig: StudioConfig = {
  components,
  migrations: {
    version: 3,
    renameComponents: { OldHero: "Hero" },
    transformProps: {
      // Rename SONRASI tipe göre aranır: anahtar "Hero"
      Hero: (props) => ({ ...props, eyebrow: props.eyebrow ?? "", title: props.headline ?? props.title }),
    },
    migrate: (doc) => doc,
  },
};

Çalışma sırası#

  1. renameComponents ile her düğümün type’ı değiştirilir.
  2. Yeni tip adına göre transformProps[type] çalışır; düğüm id’si her zaman korunur.
  3. Varsa tüm belgeye migrate(doc) uygulanır.
  4. version tanımlıysa hedef sürüm root.props._schemaVersion’a yazılır.

İdempotentlik#

version verildiyse, _schemaVersion’ı zaten o sürümde ya da üstünde olan belge dokunulmadan döner. version verilmezse geçiş her yüklemede çalışır; bu durumda transformProps ve migrate kendi başlarına idempotent olmalıdır. Bir dönüşüm hata fırlatırsa o düğüm/belge değişmeden bırakılır; tek bir hata sayfayı kilitlemez.