Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Table Field Laravel Package

outl1ne/nova-table-field

Nova Table Field adds an editable table field to Laravel Nova, letting you manage rows and columns of structured data directly inside resource forms. Configure columns, row limits, and formatting to store lightweight tabular data without extra models or migrations.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. This is a Nova field, not a standalone component — it is inert without an already-licensed Laravel Nova install, and the Nova seat cost, not the MIT package, is the real procurement question. Architecturally it inverts the usual data-modelling decision: an entire editable grid persists as one JSON blob on a single Eloquent attribute via an array cast. That fits admin-curated, semi-structured configuration (rate cards, tiered discounts, per-region tax tables, feature matrices) where a fixed relational schema would mean recurring migrations. It does not fit anything that needs joins, aggregates, foreign keys, per-cell permissions, or individual-row reporting. The two-part contract — columns() in the resource is the form definition, the JSON blob is the data — has no enforcement mechanism, so schema ownership lands squarely on the application team. That ownership needs a named person, not a tacit assumption.

Integration feasibility. Mechanically cheap: composer require, one nullable JSON migration, an array cast, a Table::make(...)->columns([...]) registration, a normalizing observer, and wildcard validation rules. The package source is small enough that reading vendor/outl1ne/nova-table-field/src and the Vue component is the documentation — a half-day spike, not a week. A bespoke CRUD grid (controller, form request, views, tests) collapses into a few resource lines, moving internal-tooling epics from days to hours.

Technical risk. Concentrated in four places. (1) Supply chain: 40 stars, zero dependents, single maintainer, and a Vue component that tracks Nova majors — every Nova upgrade is an unowned breakage risk until proven otherwise. (2) Schema drift: renaming a column key orphans existing data silently; the grid renders blank and users retype. (3) Payload hygiene: the component can emit blank or partially-filled rows and non-sequential keys, producing {"0": {...}} in the column. (4) Capability ceiling: supported cell types are exactly what the shipped component implements — a date picker or formatted currency input means editing vendor/ or forking. ->sortable() on a JSON attribute is a trap across MySQL/Postgres dialects.

Key questions to settle before adoption.

  • Will the business ever need to query, join, filter, or report on these rows individually? If yes, normalize now.
  • Who is the named owner of the "only ever viewed inside Nova" assumption, and what is its review date?
  • Is an audit trail (who changed which price, when) a requirement? A rate card without one is a compliance problem, not an engineering detail — write that requirement before rollout.
  • Who is allowed to edit this grid? Field-level ->canSee() / ->readonly() is cheap and should be configured, not deferred.
  • Who has actually read the Vue component, and is a private-registry fork budgeted if needed?
  • What does the exit cost — JSON → relational migration — look like, and is it accepted?

Integration Approach

Stack fit. Laravel + Nova with a recorded PHP/Nova version matrix. Both MySQL and Postgres work but diverge in semantics: MySQL rejects malformed JSON at write time, Postgres jsonb reorders keys. Never assert on raw JSON strings in tests — compare decoded arrays.

Migration path (the sequence that de-risks this).

  1. Spike: read the vendor source and component; confirm the column types you need actually exist there.
  2. Pick one real grid — a shipping rate card on Product, a tax table on a settings resource — not a hypothetical.
  3. Migration + cast: nullable JSON column, 'rate_card' => 'array'.
  4. Verify the shape immediately via php artisan tinker: confirm [['region' => 'eu', 'price' => 10], ...], not [{"0": ...}]. Fix it here or every downstream read, export, and migration inherits the defect.
  5. Normalize on save with a model observer: filter() empty rows, cast types, values() to reindex. This is where the blob becomes trustworthy and where derived invariants (sort, dedupe, reject overlapping bands) belong.
  6. Validate with wildcards in the FormRequest or Resource::rules(): rate_card.*.price etc., plus a max:200 guard rail — a mis-paste into an admin form can otherwise drop thousands of rows into one cell.
  7. Hide the raw blob: ->onlyOnForms()->hideFromIndex() on the field, with a purpose-built Text display for detail and index.
  8. Expose a DTO (RateCard/RateRow) as the single seam for non-Nova consumers, so a later relational migration changes one class.
  9. Version the stored shape: a sibling rate_card_version column, with the normalizer branching on it.
  10. Feature-test the round trip through the Nova API endpoint, not the Vue widget.

Compatibility. Pin the exact version (no caret) for the first release; record Nova and PHP versions in the ADR; add a CI branch that bumps Nova to surface breakage before an unrelated upgrade does. Confirm cell types against the component source during the spike and price the fork if a required input type is missing.

Sequencing. Ship the read/write admin surface first with normalization, validation, and permissions. Treat DTO, schema versioning, and the exit plan as part of the same release, not a follow-up — they are cheap on day one and expensive to retrofit.

Operational Impact

Maintenance. Single-maintainer dependency; assume you may carry a fork. Budget for it explicitly — MIT makes forking real, but only if someone has read the component. Keep the version pinned, the Nova matrix recorded, and the schema version column live so key renames become a match statement instead of archaeology.

Support. Expect tickets from two sources: users losing grid state on a 422 (test this path in a real browser — add rows, break a rule, submit), and silent blank cells after a column-key rename. Give the on-call dev a runbook: $model->getRawOriginal('rate_card') and logging inside the observer to see what Nova actually posted, rather than guessing.

Scaling. Right-sized for dozens to low hundreds of rows edited by a handful of trusted internal users. Enforce that with the max:200 rule. Beyond that, or the moment finance wants these values in the warehouse or BI, JSON-in-a-column stops being the answer — flattening/ETL or a relational migration is the next ticket, and the DTO plus schema version are what make it a command with a validation report rather than a rewrite. Field-level permissions are all-or-nothing at the grid level; there is no per-cell permission story.

Failure modes to register. Silent data orphaning on column rename; blank/partial rows becoming non-list JSON; Postgres key reordering breaking naive assertions; MySQL rejecting a payload on an apparently valid save; ->sortable() producing dialect-specific SQL nobody wants to own; a Nova major upgrade breaking the Vue component; and unauthorized edits to business rules because canSee/readonly were never set.

Ramp-up. Low for a Laravel developer — hours, assuming they read the vendor source first. Higher for the product side: the JSON-vs-normalized decision, the audit-trail requirement, the "Nova-only consumption" assumption with a named owner and review date, and the exit budget all need to be written down before adoption. Prototype use is legitimate and valuable — standing up a realistic admin surface for user testing before committing to a permanent schema is exactly the de-risking this field is good at.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console