blixify-ui-web-mcp 0.1.48 → 0.1.50
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.
|
@@ -1013,6 +1013,7 @@ const devSettings = parseWorkspaceSettings(
|
|
|
1013
1013
|
| `dbUserToken` | `string` | Per-user auth token (pass `""` if not used) |
|
|
1014
1014
|
| `schemaEndpoint` | `string` | Schema API endpoint URL |
|
|
1015
1015
|
| `schemaEndpointToken` | `string` | Optional token for schema endpoint |
|
|
1016
|
+
| `schemaEndpointUserToken` | `string` | Optional signed-in user token sent with schema reads |
|
|
1016
1017
|
| `schemaReference` | `{ [key: string]: DataStructure[] }` | Hardcoded schema reference (bypasses schema endpoint) |
|
|
1017
1018
|
| `imageEndpoint` | `string` | Asset retrieval base URL |
|
|
1018
1019
|
| `uploadEndpoint` | `string` | Upload endpoint (required when `imageEndpoint` is custom) |
|
|
@@ -1127,7 +1128,7 @@ Which field types can be edited from the list table, and how. Types not listed u
|
|
|
1127
1128
|
| `sort` | `Sort` | Default sort applied to list queries |
|
|
1128
1129
|
| `pageIndex` | `number` | Initial page index |
|
|
1129
1130
|
| `viewId` | `string` | Active view type: `"general"`, `"calendar"`, `"grid"`, `"list"`, `"feeds"`, `"kanban"`, etc. |
|
|
1130
|
-
| `idField` | `string` | DataStructure column ID whose value becomes the new record's ID on creation |
|
|
1131
|
+
| `idField` | `string` | DataStructure column ID whose value becomes the new record's ID on creation. A new record is saved as an upsert on that ID; when the column is also the schema's `unique` field it is saved as a create instead, so an existing value is refused rather than overwritten |
|
|
1131
1132
|
| `extendedTabs` | `ExtendedTabs[]` | Additional tabs rendered alongside the main view — see Extended Tab below |
|
|
1132
1133
|
| `additionalQuery` | `AdditionalQuery[]` | Filter/search controls rendered above the list — see Additional Query below |
|
|
1133
1134
|
| `darkMode` | `boolean` | Applies dark colour scheme to the organise bar |
|
|
@@ -31,7 +31,7 @@ You can still pass `organise` for everything else (`breadcrumbType`, `tabAlign`,
|
|
|
31
31
|
`DevSettings`, because it maps to what a workspace record actually stores. Some
|
|
32
32
|
app-level values have no place on a workspace and so cannot travel that way:
|
|
33
33
|
|
|
34
|
-
- `schemaEndpoint` / `schemaEndpointToken` — schema editing
|
|
34
|
+
- `schemaEndpoint` / `schemaEndpointToken` — schema editing; `schemaEndpointUserToken` sends the signed-in user's token with schema reads
|
|
35
35
|
- `roleOptions` — role pickers in forms
|
|
36
36
|
- `currentUser` — activity log attribution
|
|
37
37
|
|
|
@@ -97,6 +97,39 @@ const navigation = [
|
|
|
97
97
|
/>;
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
+
##### Icon rail
|
|
101
|
+
|
|
102
|
+
A narrow column of icons left of the sidebar — the two-level layout of tools like monday.com. The rail switches between whole areas of the app (a workspace tree, chat, agents, notifications); the sidebar beside it navigates inside the area that is open. Without `railItems` nothing changes.
|
|
103
|
+
|
|
104
|
+
```jsx
|
|
105
|
+
import { BellIcon, ChatBubbleLeftRightIcon, Cog6ToothIcon, Squares2X2Icon } from "@heroicons/react/24/outline";
|
|
106
|
+
|
|
107
|
+
const [railId, setRailId] = useState("workspace");
|
|
108
|
+
|
|
109
|
+
<LeftNav
|
|
110
|
+
railItems={[
|
|
111
|
+
{ id: "workspace", name: "Workspace", icon: Squares2X2Icon },
|
|
112
|
+
{ id: "chat", name: "Chat", icon: ChatBubbleLeftRightIcon, href: "/chat" },
|
|
113
|
+
{ id: "notifications", name: "Alerts", icon: BellIcon, badge: 9 },
|
|
114
|
+
]}
|
|
115
|
+
railFooterItems={[{ id: "settings", name: "Settings", icon: Cog6ToothIcon }]}
|
|
116
|
+
selectedRailId={railId}
|
|
117
|
+
handleRailOnClick={(id) => setRailId(id)}
|
|
118
|
+
{...otherProps}
|
|
119
|
+
/>;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
| Name | Type | Description |
|
|
123
|
+
| ------------------ | ---------------------- | ------------------------------------------------------------------------------------------------ |
|
|
124
|
+
| `railItems` | `RailItem[]` | Icons at the top of the rail. Turns the rail on. |
|
|
125
|
+
| `railFooterItems` | `RailItem[]` | Icons pinned to the bottom of the rail, for settings-type entries. |
|
|
126
|
+
| `selectedRailId` | `string` | The `id` of the open area, highlighted. |
|
|
127
|
+
| `handleRailOnClick`| `(id: string) => void` | Called with the item `id` on every click, link or not. |
|
|
128
|
+
|
|
129
|
+
`RailItem` is `{ id, name, icon, href?, badge? }`. With `href` the item is a link through the same `linkType` / `custom` as the sidebar; without it the item only reports `handleRailOnClick`. `badge` shows a count on the icon — `0`, empty or absent hides it, and a number over 99 reads `99+`.
|
|
130
|
+
|
|
131
|
+
Below `lg` the rail moves into the mobile drawer as a row of icons above the sidebar's list.
|
|
132
|
+
|
|
100
133
|
##### Required props
|
|
101
134
|
|
|
102
135
|
| Name | Type | Description |
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BellIcon,
|
|
3
|
+
ChatBubbleLeftRightIcon,
|
|
4
|
+
Cog6ToothIcon,
|
|
5
|
+
CpuChipIcon,
|
|
2
6
|
FolderIcon,
|
|
3
7
|
FunnelIcon,
|
|
4
8
|
HomeIcon,
|
|
9
|
+
Squares2X2Icon,
|
|
5
10
|
UsersIcon,
|
|
6
11
|
} from "@heroicons/react/24/outline";
|
|
7
12
|
import React, { useState } from "react";
|
|
8
|
-
import { LeftNav as LeftNavImpl, Navigation } from ".";
|
|
13
|
+
import { LeftNav as LeftNavImpl, Navigation, RailItem } from ".";
|
|
9
14
|
import { BarMove } from "../bars";
|
|
10
15
|
import { StorySection } from "../../storyUtils";
|
|
11
16
|
import Logo from "../../../assets/logo.png";
|
|
@@ -221,6 +226,74 @@ const workspaceNavigation = [
|
|
|
221
226
|
},
|
|
222
227
|
];
|
|
223
228
|
|
|
229
|
+
// INFO: the rail switches between whole areas; the sidebar beside it lists the
|
|
230
|
+
// pages inside the area that is open
|
|
231
|
+
const railItems: RailItem[] = [
|
|
232
|
+
{ id: "workspace", name: "Workspace", icon: Squares2X2Icon },
|
|
233
|
+
{ id: "chat", name: "Chat", icon: ChatBubbleLeftRightIcon },
|
|
234
|
+
{ id: "agents", name: "Agents", icon: CpuChipIcon },
|
|
235
|
+
{ id: "notifications", name: "Alerts", icon: BellIcon, badge: 9 },
|
|
236
|
+
];
|
|
237
|
+
|
|
238
|
+
// INFO: each area brings its own sidebar list
|
|
239
|
+
const railNavigation: { [railId: string]: Navigation[] } = {
|
|
240
|
+
chat: [
|
|
241
|
+
{
|
|
242
|
+
id: "chat-new",
|
|
243
|
+
name: "New chat",
|
|
244
|
+
href: "/chat",
|
|
245
|
+
icon: ChatBubbleLeftRightIcon,
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
id: "chat-1",
|
|
249
|
+
name: "Quarterly sales recap",
|
|
250
|
+
href: "/chat/1",
|
|
251
|
+
icon: ChatBubbleLeftRightIcon,
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
agents: [
|
|
255
|
+
{
|
|
256
|
+
id: "agent-1",
|
|
257
|
+
name: "Lead qualifier",
|
|
258
|
+
href: "/agents/1",
|
|
259
|
+
icon: CpuChipIcon,
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
id: "agent-2",
|
|
263
|
+
name: "Support triage",
|
|
264
|
+
href: "/agents/2",
|
|
265
|
+
icon: CpuChipIcon,
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
notifications: [
|
|
269
|
+
{ id: "note-all", name: "All", href: "/alerts", icon: BellIcon },
|
|
270
|
+
{
|
|
271
|
+
id: "note-unread",
|
|
272
|
+
name: "Unread",
|
|
273
|
+
href: "/alerts/unread",
|
|
274
|
+
icon: BellIcon,
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
settings: [
|
|
278
|
+
{
|
|
279
|
+
id: "set-members",
|
|
280
|
+
name: "Members",
|
|
281
|
+
href: "/settings/members",
|
|
282
|
+
icon: UsersIcon,
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: "set-workspace",
|
|
286
|
+
name: "Workspace",
|
|
287
|
+
href: "/settings/workspace",
|
|
288
|
+
icon: Cog6ToothIcon,
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const railFooterItems: RailItem[] = [
|
|
294
|
+
{ id: "settings", name: "Settings", icon: Cog6ToothIcon },
|
|
295
|
+
];
|
|
296
|
+
|
|
224
297
|
const renderLogo = (collapse?: boolean) => (
|
|
225
298
|
<div className="flex items-center flex-shrink-0 px-6 cursor-pointer">
|
|
226
299
|
<img
|
|
@@ -285,6 +358,8 @@ export const LeftNav = () => {
|
|
|
285
358
|
// button, so each story needs its own open state for that button to work on
|
|
286
359
|
// a phone
|
|
287
360
|
const [mobileStoryId, setMobileStoryId] = useState("");
|
|
361
|
+
const [railId, setRailId] = useState("workspace");
|
|
362
|
+
const [darkRailId, setDarkRailId] = useState("workspace");
|
|
288
363
|
|
|
289
364
|
const handleMobileMenu = (storyId: string) => ({
|
|
290
365
|
leftNavMobileMenu: mobileStoryId === storyId,
|
|
@@ -639,6 +714,63 @@ export const LeftNav = () => {
|
|
|
639
714
|
</div>
|
|
640
715
|
</StorySection>
|
|
641
716
|
|
|
717
|
+
<StorySection
|
|
718
|
+
title="Icon Rail"
|
|
719
|
+
description="railItems adds a narrow column of icons left of the sidebar, the two-level layout of tools like monday.com: the rail switches between whole areas (workspace, chat, agents, alerts), the sidebar beside it navigates inside the open one. selectedRailId highlights the open area, badge shows a count (over 99 reads 99+), and railFooterItems sit at the bottom for settings-type entries. An item with href is a link; without one it only reports handleRailOnClick. Without railItems nothing changes. Below lg the rail moves into the drawer as a row of icons above the list — open the menu at phone width to see it."
|
|
720
|
+
>
|
|
721
|
+
<div className="w-full h-96 relative overflow-hidden border rounded-lg">
|
|
722
|
+
<LeftNavImpl
|
|
723
|
+
selectedId={workspaceSelectedId}
|
|
724
|
+
navigation={
|
|
725
|
+
railId === "workspace"
|
|
726
|
+
? workspaceNavigation
|
|
727
|
+
: (railNavigation[railId] ?? [])
|
|
728
|
+
}
|
|
729
|
+
{...handleMobileMenu("story-rail")}
|
|
730
|
+
compactMode={true}
|
|
731
|
+
railItems={railItems}
|
|
732
|
+
railFooterItems={railFooterItems}
|
|
733
|
+
selectedRailId={railId}
|
|
734
|
+
handleRailOnClick={(id) => setRailId(id)}
|
|
735
|
+
handleBarsOnClick={(id) => setWorkspaceSelectedId(id)}
|
|
736
|
+
renderDashboardLogo={() => renderLogo()}
|
|
737
|
+
renderDashboardContent={() => (
|
|
738
|
+
<div className="p-6 text-sm text-gray-500">
|
|
739
|
+
{`Open area: ${railId}`}
|
|
740
|
+
</div>
|
|
741
|
+
)}
|
|
742
|
+
renderDashboardHeaderContent={renderHeader}
|
|
743
|
+
/>
|
|
744
|
+
</div>
|
|
745
|
+
</StorySection>
|
|
746
|
+
|
|
747
|
+
<StorySection
|
|
748
|
+
title="Icon Rail — Dark Mode"
|
|
749
|
+
description="The rail follows darkMode and navbarBgColor like the sidebar, so the two read as one surface."
|
|
750
|
+
dark
|
|
751
|
+
>
|
|
752
|
+
<div className="w-full h-96 relative overflow-hidden border border-gray-700 rounded-lg">
|
|
753
|
+
<LeftNavImpl
|
|
754
|
+
selectedId={selectedId}
|
|
755
|
+
navigation={navigation}
|
|
756
|
+
{...handleMobileMenu("story-rail-dark")}
|
|
757
|
+
darkMode={true}
|
|
758
|
+
railItems={railItems}
|
|
759
|
+
railFooterItems={railFooterItems}
|
|
760
|
+
selectedRailId={darkRailId}
|
|
761
|
+
handleRailOnClick={(id) => setDarkRailId(id)}
|
|
762
|
+
handleBarsOnClick={(id) => setSelectedId(id)}
|
|
763
|
+
renderDashboardLogo={() => renderLogo()}
|
|
764
|
+
renderDashboardContent={() => (
|
|
765
|
+
<div className="p-6 text-gray-400 text-sm">
|
|
766
|
+
{`Open area: ${darkRailId}`}
|
|
767
|
+
</div>
|
|
768
|
+
)}
|
|
769
|
+
renderDashboardHeaderContent={renderHeader}
|
|
770
|
+
/>
|
|
771
|
+
</div>
|
|
772
|
+
</StorySection>
|
|
773
|
+
|
|
642
774
|
<StorySection
|
|
643
775
|
title="Transparent"
|
|
644
776
|
description="transparent makes the TOP HEADER BAR see-through, dropping its background, shadow and bottom border so a page can run its own hero or image up under it — the same pair Header carries. mobileOpaque keeps that bar solid below lg, where it holds the hamburger and is the only way back to the nav. The sidebar itself is unaffected. Shown over a gradient page so the effect is visible."
|