blixify-ui-web-mcp 0.1.65 → 0.1.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -759,8 +759,8 @@ Column types with monday.com counterparts. The value maths is in `src/components
759
759
  | Column | Schema | Stored value | Where it shows |
760
760
  | --- | --- | --- | --- |
761
761
  | Button | `type: "button"`, `buttonLabel?`, `buttonColour?`, `buttonConfirm?` | nothing | table, list, kanban and read view; never in a form. A tap calls `organise.onButtonClick(columnId, row)` and the button stays busy until the returned promise settles, ignoring taps meanwhile. `buttonConfirm` asks first. Disabled without `onButtonClick` or update rights |
762
- | Time tracking | `type: "timeTracking"` | `{ totalSeconds, running, startedAt?, sessions? }` | table and read view show the total with start / stop, ticking each second inside the cell only; a form shows the total read-only. Start / stop saves that one field. `handleStartTimeTracking` / `handleStopTimeTracking` are idempotent, so a flow can drive the same value. Sorts on `<id>.totalSeconds`; formulas read hours (`handleGetTimeTrackingHours`) |
763
- | Date range | `type: "dateRange"`, `minDate?`, `maxDate?` | `{ start, end }` | `12 – 18 Nov`; a range picker in the form; filters and sorts on `<id>.start`. A calendar or timeline tab can use `<id>.start` and `<id>.end` as its dates |
762
+ | Time tracking | `type: "timeTracking"` | `{ totalSeconds, running, startedAt?, sessions? }` | table, read view and the record form show the total with start / stop, ticking each second inside the cell only; the form draws it as a field box, read-only on a record not created yet or without update rights. Start / stop saves at once, apart from Submit, and a form save never sends the timer. With `organise.onTimeTrackingAction` a click sends only `"start"` / `"stop"` and shows the value the host's server stored, timed on the server's clock (the cell ticks at once and is corrected to the reply, or put back if it fails); without it the cell works the value out and saves that one field. `handleStartTimeTracking` / `handleStopTimeTracking` are idempotent, so a flow can drive the same value. Sorts on `<id>.totalSeconds`; formulas read hours (`handleGetTimeTrackingHours`) |
763
+ | Date range | `type: "dateRange"`, `minDate?`, `maxDate?` | `{ start, end }` | `12 – 18 Nov`; a range picker in the form; in an editable table the whole cell opens it, with the inline date cell's border on hover; filters and sorts on `<id>.start`. A calendar or timeline tab can use `<id>.start` and `<id>.end` as its dates |
764
764
  | Rating | `type: "number"`, `ratingMax` | a number | stars in every view; a tap saves the number, tapping the current rating clears it |
765
765
 
766
766
  `bareSettings.bareSystemColumns` adds the server-stamped columns without declaring them: Created At / By (`baseCreatedAt`, `baseCreatedBy`), Updated At / By (`baseUpdatedAt`, `baseUpdatedBy`), Record ID (the record's `_id`) and Number (`baseNumber`). They start hidden; showing one is kept per view (`shownSystemColumnIds`) and never written back through `onChangeHide` or `onChangeDrag`. They are read-only, sortable and filterable, empty on a record the server never stamped, and a form save never sends them (nor a timer or a button).
@@ -1065,7 +1065,7 @@ const devSettings = parseWorkspaceSettings(
1065
1065
  | `uploadEndpoint` | `string` | Upload endpoint (required when `imageEndpoint` is custom) |
1066
1066
  | `bucketName` | `string` | Storage bucket name (required for AWS/GCS) |
1067
1067
  | `maxFileSize` | `number` | Global max file size in MB for uploads |
1068
- | `organisationMembers` | `Option[]` | Member list used for `person` / `listPerson` field types |
1068
+ | `organisationMembers` | `Option[]` | Member list used for `person` / `listPerson` field types. An option's `image` is the member's photo, shown in cells, the person picker and its tags; a member without one shows their initials |
1069
1069
  | `roleOptions` | `Option[]` | Role list used for `roles` field type |
1070
1070
  | `currentUser` | `{ userEmail: string; userName: string }` | Current user info used for export email and QR features |
1071
1071
  | `importEndpoint` | `string` | Firebase CSV import function URL |
@@ -1099,7 +1099,7 @@ modal is also opened through the imperative `handleDeleteModal`.
1099
1099
  | Inline cell edit and its write | `listEditable && !disabledUpdate` |
1100
1100
  | Kanban boolean checkbox and its write | `listEditable && !disabledUpdate` |
1101
1101
  | Read-view Update button | `allEditable && !disabledUpdate` |
1102
- | List Update column | `allEditable && !disabledUpdate`, or `bareListMultipleSelectAddtionalActions` |
1102
+ | List Update column | `allEditable && !disabledUpdate`, or `bareListMultipleSelectAddtionalActions`. Under `bareNewDTW` there is no Update column: a record opens from its title (Update is in the record), cells edit in place and the comment bubble sits beside the title. An Actions column shows only when `bareListActionBtns` is given, with just those buttons |
1103
1103
  | Batch update, clone, change-to-draft | `allEditable && !disabledUpdate && !disableBatchUpdate` (the batch Update button also requires a non-Firebase backend) |
1104
1104
  | Delete button, batch delete, map delete | `deleteBtn` (independent of `allEditable`) |
1105
1105
  | Map polygon select | batch-update or delete permission |
@@ -1208,7 +1208,7 @@ Which field types can be edited from the list table, and how. Types not listed u
1208
1208
  | `addColumnEnabled` | `boolean` | Shows an add-column button in the table header |
1209
1209
  | `persistViewState` | `"persistent" \| "session"` | Remembers the list's sort, filters, hidden columns, page, rows per page, search and reading position per collection, so a Back navigation lands where the user left. `"persistent"` uses `localStorage`; `"session"` writes `sessionStorage` and reads it first, falling back to `localStorage`. The reading position is restored on mount and on returning from a record, not on a tab switch; with several lists on one page, only the list a record was last opened from restores (tracked in `blixify-dtw-persist-last-drill`). Covers table, list, grid, kanban and feeds; not map. List view only |
1210
1210
  | `persistKey` | `string` | Keeps a separate saved view state for this instance: the storage key becomes `blixify-dtw-persist-<collectionId>-<persistKey>`. Saved state is read once, on mount, so give the component a React `key` that changes with `persistKey` |
1211
- | `savedViews` | `boolean` | Shows a row of view tags under the tab bar: save the current filters, flex filters, sort, rows per page, grouping and columns under a name, reapply it, update it or delete it. Views belong to the tab they were saved on and are kept in `localStorage` under `blixify-dtw-views-<collectionId>[-<persistKey>][-<currentUser.userEmail>]`. Sort is held by the template while it is on, as with `persistViewState`, and applying a view calls `onChangeSort`, `onChangeGroupBy`, `onChangePagination(0)` and `bareListHandleFilter` when those change. Each write re-reads storage first, so views saved in another browser tab are kept. With `onChangeHide` / `onChangeDrag`, a view's hides and column order stay on screen only: a toggle or reorder after applying one writes back the schema's columns plus that single change |
1211
+ | `savedViews` | `boolean` | Shows a row of view tags under the tab bar: save the current filters, flex filters, sort, rows per page, grouping, columns and column widths under a name, reapply it, update it or delete it. Views belong to the tab they were saved on and are kept in `localStorage` under `blixify-dtw-views-<collectionId>[-<persistKey>][-<currentUser.userEmail>]`. Sort is held by the template while it is on, as with `persistViewState`, and applying a view calls `onChangeSort`, `onChangeGroupBy`, `onChangePagination(0)` and `bareListHandleFilter` when those change. Each write re-reads storage first, so views saved in another browser tab are kept. With `onChangeHide` / `onChangeDrag`, a view's hides and column order stay on screen only: a toggle or reorder after applying one writes back the schema's columns plus that single change |
1212
1212
  | `defaultSavedViews` | `DefaultSavedView[]` | Views provided by the app (`{ id?, name, tabId?, state }`), listed before the user's own and never deleted. Without `tabId` a view is listed on every tab. A field left out of `state` is reset to its default when the view is applied. `id` must be unique; without one the view gets `default-<index>`, its position in the whole array |
1213
1213
  | `sharedViews` | `SharedSavedView[]` | Views the app stores for everyone (`{ id, name, tabId, state }`), e.g. on the record the list belongs to. Given, it replaces this browser's storage: the list shows only these, saving goes to `onChangeSharedViews`, and nothing is read from or written to `localStorage` |
1214
1214
  | `onChangeSharedViews` | `(views: SharedSavedView[]) => void` | Called with the whole list after a view is saved, updated or deleted, for the app to store and pass back as `sharedViews`; a second change before it comes back builds on the list just sent. The whole list is replaced each time, so two editors saving at once is last-writer-wins. Without it the app's views are read-only and “+ Save view” is hidden |
@@ -1217,6 +1217,9 @@ Which field types can be edited from the list table, and how. Types not listed u
1217
1217
  | `initialSavedViewId` | `string` | A view the list opens on, once, in place of the ★ default — e.g. a page embedding a datasheet opens it on a chosen view. A view that no longer exists, or is on another tab, leaves the list on All. Opening on it does not call `onChangeSort` |
1218
1218
  | `groupBy` | `string` | Column ID to group list results by. With `bareNewDTW` the groups are bands in one table. Grouped by a `list` or `boolean` column, every option (in option order, with its colour) plus "Unknown" (a value outside the options) and "No Value" (missing or blank) is a band with its real total that reads its own rows under the list's filters, search and sort: in scroll mode each band loads more as it scrolls, in page mode each band has its own pager and the list-wide pager is hidden. Grouped by any other column (a `person` column's sections follow the member order), page mode groups the rows of the current page and scroll mode keeps the normal scroll; a section built from loaded rows draws 50 rows and a "Show more" at a time. A search, filter, sort or regroup starts every band over. Firebase and `bareListMobileView` keep the normal pagination. Saved views store and restore it |
1219
1219
  | `onButtonClick` | `(columnId: string, row: any) => Promise<any> \| void` | Called when a `button` column is tapped, with the stored record. The button is busy until the promise settles. See Button, time tracking … columns |
1220
+ | `onTimeTrackingAction` | `(columnId: string, row: any, action: "start" \| "stop") => Promise<any>` | Starts or stops a `timeTracking` timer on the host's server, with the stored record. Resolve with the value the server stored; the timer shows it, and goes back to where it was if the promise rejects. Without it a timer works its value out on the device and saves it through the single-field update |
1221
+ | `allView` | `PersistedViewState` | All's settings as the app stores them for everyone (`{}` when none are saved yet): sort, grouping, filters, hidden columns, column order, column widths (`columnWidths`, `"180px"` by column id) and rows per page. A setting left out falls back to the model and the props. Needs `savedViews`. Given, the list opens on it, and every change a person makes to All or a saved view is kept in their browser (`blixify-dtw-draft-<collectionId>[-<persistKey>][-<currentUser.userEmail>]-<all \| view id>`) until they choose Update or Reset; a saved view with no width of its own for a column follows All's |
1222
+ | `onChangeAllView` | `(state: PersistedViewState) => void` | Saves All's settings for everyone. Given, “Update All” shows beside “+ Save view” while All on screen differs from `allView`. Without it a person's changes stay in their own browser; “Reset” goes back to the stored view either way |
1220
1223
  | `onChangeGroupBy` | `(groupBy: string) => void` | Called when the user picks another grouping in the group-by selector or by applying a saved view (`""` for none), so the app can store it with the tab. Not called when the list opens on a view |
1221
1224
  | `groupIdCollapsible` | `{ [key: string]: boolean }` | Initial collapsed/expanded state per group ID |
1222
1225
  | `sortGroupByAlphabetically` | `boolean` | Sorts group-by values alphabetically |
@@ -1302,7 +1305,7 @@ Injects custom React components and callbacks into the list, read, and update vi
1302
1305
  | `bareReadHandleData` | `(data: any, rawData?: any) => void` | Called when read view data is loaded. `data` is display data (labels + elements); `rawData` is the untouched DB doc |
1303
1306
  | `bareReadListTabs` | `boolean` | Shows list-style tabs in read view |
1304
1307
  | `bareListComponent` | `(data, prettierData, loading, pageIndex) => any` | Fully replaces the list UI. `data` is the fetched records (`_id` exposed as `id`), `prettierData` the display rows |
1305
- | `bareListActionBtns` | `(data: any) => ReactElement[]` | Extra icon buttons on each list row. `data` is the raw fetched record |
1308
+ | `bareListActionBtns` | `(data: any) => ReactElement[]` | Extra icon buttons on each list row. `data` is the raw fetched record. Under `bareNewDTW` they are the only content of the table's Actions column |
1306
1309
  | `bareListMultipleSelectAddtionalActions` | `{ text: string; className?: string; onClick: (ids, selectAll, query) => void }[]` | Extra bulk-action buttons shown when rows are selected |
1307
1310
  | `bareListGridComponent` | `(data: any, rawData?: any) => any` | Custom card renderer for grid/kanban view. `data` is display data; `rawData` is the fetched record for that card (`_id` exposed as `id`) |
1308
1311
  | `bareListGridColClassName` | `string` | Tailwind class for grid column width |
@@ -56,17 +56,23 @@ With `mobileView`, `mobileTooltip` adds row data to the collapsed row and to a h
56
56
  Drag the grip on a header's right border to resize that column. The line is
57
57
  invisible at rest, fades in when the header is hovered so the affordance is
58
58
  discoverable, and turns primary when the grip itself is hovered. The hit area is
59
- 8px and straddles the border, so it does not need pixel hunting. The width is held
60
- in component state, keyed by column key — a resize is a per-viewer preference, and
61
- there is no storage for it yet, so it resets when the list unmounts.
62
-
63
- `col.width` stays the way a consumer sets a static width (a Tailwind class such as
64
- `w-48`). A dragged width overrides it through an inline style, because Tailwind
65
- generates classes at build time and cannot emit a runtime `w-[Npx]`. Resolution
66
- order is dragged width → `col.width` class → measured / auto, and pinned columns
67
- measure from the dragged width once one is set. The default minimum is 80px, but a column configured narrower than that (a 40px
68
- icon column, say) keeps its own width as the floor — a resize never forces a
69
- column wider than the consumer asked for.
59
+ 8px and straddles the border, so it does not need pixel hunting.
60
+
61
+ `advSettings.onResizeColumn(columnId, width)` is called once, when the drag is
62
+ released and only if the width changed, with the width in pixels. Given, the
63
+ caller keeps the width and passes it back as the column's `width` (DataTemplate
64
+ does, as `"180px"`). Without it the dragged width is held in component state and
65
+ resets when the list unmounts.
66
+
67
+ `col.width` is read in any of the forms a schema stores: `"180px"`, `"180"`, a
68
+ Tailwind arbitrary width (`w-[180px]`) or a spacing class (`w-48`). Any of them
69
+ is drawn as an inline style, because Tailwind generates classes at build time
70
+ and cannot emit a runtime `w-[Npx]`; anything else (`"200%"`, `w-full`) stays a
71
+ class. Resolution order is dragged width → `col.width` → measured / auto, and
72
+ pinned columns measure from the same width. The default minimum is 80px, but a
73
+ column configured narrower than that (a 40px icon column, say) keeps its own
74
+ width as the floor — a resize never forces a column wider than the consumer
75
+ asked for.
70
76
 
71
77
  The grip is part of `NewTable` itself, so it appears wherever the component is
72
78
  used, not only inside a DataTemplate.
@@ -95,6 +95,7 @@ Async / database search:
95
95
  | `size` | `"xs"` | — | Compact field that looks 12px everywhere: on phones it keeps 16px text and draws the trigger at 75%, so iOS Safari does not zoom on focus; from `sm` up it is a plain 12px field |
96
96
  | `dropdownClassName` | `string` | — | Tailwind classes for the dropdown list |
97
97
  | `imageClassName` | `string` | — | Tailwind classes for option images (used with `type="button"`) |
98
+ | `showOptionAvatar` | `boolean` | `false` | Options are people: each option, the picked value and each tag shows the option's `image` as a 24px round photo, or its initials on a colour from its label when it has none or the photo fails to load |
98
99
  | `onChange` | `(value: string \| string[]) => void` | — | Called with the updated value when selection changes |
99
100
  | `onSearch` | `(value: string) => void` | — | Called as the user types. Use to fetch options dynamically |
100
101
  | `cellInput` | `CellInput` | — | Cell input config for use inside a Table component |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blixify-ui-web-mcp",
3
- "version": "0.1.65",
3
+ "version": "0.1.66",
4
4
  "license": "MIT",
5
5
  "main": "lib/mcp/server.js",
6
6
  "bin": {