@kodaris/krubble-app-components 1.0.126 → 1.0.128
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.
- package/dist/chatbot.d.ts +6 -13
- package/dist/chatbot.d.ts.map +1 -1
- package/dist/chatbot.js +121 -100
- package/dist/chatbot.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/krubble-app.bundled.js +218 -100
- package/dist/krubble-app.bundled.js.map +1 -1
- package/dist/krubble-app.bundled.min.js +59 -21
- package/dist/krubble-app.bundled.min.js.map +1 -1
- package/dist/krubble-app.umd.js +218 -100
- package/dist/krubble-app.umd.js.map +1 -1
- package/dist/krubble-app.umd.min.js +61 -23
- package/dist/krubble-app.umd.min.js.map +1 -1
- package/dist/screen-nav.d.ts +40 -0
- package/dist/screen-nav.d.ts.map +1 -1
- package/dist/screen-nav.js +97 -0
- package/dist/screen-nav.js.map +1 -1
- package/package.json +1 -1
|
@@ -3470,10 +3470,9 @@ class KRChatbot extends i$3 {
|
|
|
3470
3470
|
}
|
|
3471
3471
|
}
|
|
3472
3472
|
// `this.load` is always set by here (defaulted above when the consumer didn't
|
|
3473
|
-
// supply one)
|
|
3474
|
-
//
|
|
3475
|
-
|
|
3476
|
-
resolveConversationId.then(() => load()).then((messages) => {
|
|
3473
|
+
// supply one); the `!` is because TS can't narrow the nullable property across
|
|
3474
|
+
// the promise boundary.
|
|
3475
|
+
resolveConversationId.then(() => this.load()).then((messages) => {
|
|
3477
3476
|
if (messages && messages.length) {
|
|
3478
3477
|
this.messages = messages;
|
|
3479
3478
|
}
|
|
@@ -3742,11 +3741,10 @@ class KRChatbot extends i$3 {
|
|
|
3742
3741
|
}
|
|
3743
3742
|
_saveState() {
|
|
3744
3743
|
try {
|
|
3745
|
-
// `toolDetail`
|
|
3746
|
-
//
|
|
3747
|
-
// stale conversation list.
|
|
3744
|
+
// `toolDetail` is a transient peek, not a saved view — persist only the two
|
|
3745
|
+
// real preference views so a reload never reopens a stale tool.
|
|
3748
3746
|
let persistedDrawerView = this._drawerView;
|
|
3749
|
-
if (persistedDrawerView === 'toolDetail'
|
|
3747
|
+
if (persistedDrawerView === 'toolDetail') {
|
|
3750
3748
|
persistedDrawerView = 'settings';
|
|
3751
3749
|
}
|
|
3752
3750
|
const state = {
|
|
@@ -3805,8 +3803,14 @@ class KRChatbot extends i$3 {
|
|
|
3805
3803
|
this._showToolInputs = state.showToolInputs === 'true';
|
|
3806
3804
|
this._showConfirmationInput = state.showConfirmationInput === 'true';
|
|
3807
3805
|
this._drawerOpen = state.drawerOpen === 'true';
|
|
3808
|
-
if (state.drawerView === 'settings' || state.drawerView === 'debug') {
|
|
3806
|
+
if (state.drawerView === 'settings' || state.drawerView === 'debug' || state.drawerView === 'history') {
|
|
3809
3807
|
this._drawerView = state.drawerView;
|
|
3808
|
+
// History's list isn't persisted (it can go stale); refetch it so a reload
|
|
3809
|
+
// that was on the conversations panel comes back to a populated list rather
|
|
3810
|
+
// than an empty one.
|
|
3811
|
+
if (state.drawerView === 'history') {
|
|
3812
|
+
this._loadConversations();
|
|
3813
|
+
}
|
|
3810
3814
|
}
|
|
3811
3815
|
const w = Number(state.drawerWidth);
|
|
3812
3816
|
if (w >= 300) {
|
|
@@ -4950,41 +4954,47 @@ class KRChatbot extends i$3 {
|
|
|
4950
4954
|
else {
|
|
4951
4955
|
this._drawerOpen = true;
|
|
4952
4956
|
this._drawerView = view;
|
|
4953
|
-
// Opening the history view refetches the
|
|
4954
|
-
//
|
|
4955
|
-
// shows without a reload. Ownership is enforced server-side (the endpoint
|
|
4956
|
-
// scopes to the current administrator), so we only filter to active ones.
|
|
4957
|
+
// Opening the history view refetches the list so a just-created or renamed
|
|
4958
|
+
// conversation shows without a reload.
|
|
4957
4959
|
if (view === 'history') {
|
|
4958
|
-
this.
|
|
4959
|
-
KRHttp.fetch({
|
|
4960
|
-
url: '/api/system/conversation/list',
|
|
4961
|
-
method: 'POST',
|
|
4962
|
-
body: {
|
|
4963
|
-
page: 0,
|
|
4964
|
-
size: 50,
|
|
4965
|
-
sortBy: 'lastModified',
|
|
4966
|
-
sortDirection: 'desc',
|
|
4967
|
-
filterFields: [{
|
|
4968
|
-
name: 'active',
|
|
4969
|
-
operation: 'IS',
|
|
4970
|
-
value: 'true',
|
|
4971
|
-
}],
|
|
4972
|
-
},
|
|
4973
|
-
})
|
|
4974
|
-
.then((r) => r.json())
|
|
4975
|
-
.then((res) => {
|
|
4976
|
-
this._conversations = res?.data?.content || [];
|
|
4977
|
-
})
|
|
4978
|
-
.catch(() => {
|
|
4979
|
-
this._conversations = [];
|
|
4980
|
-
})
|
|
4981
|
-
.then(() => {
|
|
4982
|
-
this._conversationsLoading = false;
|
|
4983
|
-
});
|
|
4960
|
+
this._loadConversations();
|
|
4984
4961
|
}
|
|
4985
4962
|
}
|
|
4986
4963
|
this._saveState();
|
|
4987
4964
|
}
|
|
4965
|
+
/**
|
|
4966
|
+
* Fetch the user's previous conversations for the history list, most-recently
|
|
4967
|
+
* modified first. Ownership is enforced server-side (the endpoint scopes to the
|
|
4968
|
+
* current administrator), so we only filter to active ones.
|
|
4969
|
+
*/
|
|
4970
|
+
_loadConversations() {
|
|
4971
|
+
this._conversationsLoading = true;
|
|
4972
|
+
KRHttp.fetch({
|
|
4973
|
+
url: '/api/system/conversation/list',
|
|
4974
|
+
method: 'POST',
|
|
4975
|
+
body: {
|
|
4976
|
+
page: 0,
|
|
4977
|
+
size: 50,
|
|
4978
|
+
sortBy: 'lastModified',
|
|
4979
|
+
sortDirection: 'desc',
|
|
4980
|
+
filterFields: [{
|
|
4981
|
+
name: 'active',
|
|
4982
|
+
operation: 'IS',
|
|
4983
|
+
value: 'true',
|
|
4984
|
+
}],
|
|
4985
|
+
},
|
|
4986
|
+
})
|
|
4987
|
+
.then((r) => r.json())
|
|
4988
|
+
.then((res) => {
|
|
4989
|
+
this._conversations = res?.data?.content || [];
|
|
4990
|
+
})
|
|
4991
|
+
.catch(() => {
|
|
4992
|
+
this._conversations = [];
|
|
4993
|
+
})
|
|
4994
|
+
.then(() => {
|
|
4995
|
+
this._conversationsLoading = false;
|
|
4996
|
+
});
|
|
4997
|
+
}
|
|
4988
4998
|
/**
|
|
4989
4999
|
* Switch the floating widget to a previously-created conversation (clicked in the
|
|
4990
5000
|
* history list): stop any live turn, reset the transient turn/context state, pin
|
|
@@ -5003,7 +5013,22 @@ class KRChatbot extends i$3 {
|
|
|
5003
5013
|
// one, so the header falls back to the default label).
|
|
5004
5014
|
this._conversationTitle = this._conversations.find((c) => c.conversationID === conversationID)?.title || '';
|
|
5005
5015
|
this._persistConversationId();
|
|
5006
|
-
|
|
5016
|
+
// Clear the transient, per-conversation state so it doesn't bleed into the one
|
|
5017
|
+
// we're switching to — pending confirmations, context banners, errors, the
|
|
5018
|
+
// reconnect counter, and staged composer files (the transcript is loaded below).
|
|
5019
|
+
this._pendingActions = [];
|
|
5020
|
+
this._inlineConfirm = true;
|
|
5021
|
+
this._contextWarning = '';
|
|
5022
|
+
this._contextLimitReached = false;
|
|
5023
|
+
this._contextLimitMessage = '';
|
|
5024
|
+
this._error = '';
|
|
5025
|
+
this._reconnectAttempts = 0;
|
|
5026
|
+
this._pendingConversationFiles.forEach((p) => {
|
|
5027
|
+
if (p.previewUrl) {
|
|
5028
|
+
URL.revokeObjectURL(p.previewUrl);
|
|
5029
|
+
}
|
|
5030
|
+
});
|
|
5031
|
+
this._pendingConversationFiles = [];
|
|
5007
5032
|
this._drawerOpen = false;
|
|
5008
5033
|
this._saveState();
|
|
5009
5034
|
if (this.load) {
|
|
@@ -5030,17 +5055,9 @@ class KRChatbot extends i$3 {
|
|
|
5030
5055
|
this._conversationTitle = '';
|
|
5031
5056
|
this._persistConversationId();
|
|
5032
5057
|
this.messages = [];
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
}
|
|
5037
|
-
/**
|
|
5038
|
-
* Clear the transient, per-conversation state that must not bleed across a
|
|
5039
|
-
* conversation switch/new — pending confirmations, context banners, errors, the
|
|
5040
|
-
* reconnect counter, and staged composer files. The transcript itself is set by
|
|
5041
|
-
* the caller (loaded for a switch, emptied for new).
|
|
5042
|
-
*/
|
|
5043
|
-
_resetConversationState() {
|
|
5058
|
+
// Clear the transient, per-conversation state so it doesn't bleed into the new
|
|
5059
|
+
// conversation — pending confirmations, context banners, errors, the reconnect
|
|
5060
|
+
// counter, and staged composer files.
|
|
5044
5061
|
this._pendingActions = [];
|
|
5045
5062
|
this._inlineConfirm = true;
|
|
5046
5063
|
this._contextWarning = '';
|
|
@@ -5054,6 +5071,8 @@ class KRChatbot extends i$3 {
|
|
|
5054
5071
|
}
|
|
5055
5072
|
});
|
|
5056
5073
|
this._pendingConversationFiles = [];
|
|
5074
|
+
this._drawerOpen = false;
|
|
5075
|
+
this._saveState();
|
|
5057
5076
|
}
|
|
5058
5077
|
/** Close the drawer. `_drawerView` is left intact so its content stays visible
|
|
5059
5078
|
* while the drawer slides shut. */
|
|
@@ -5936,55 +5955,58 @@ class KRChatbot extends i$3 {
|
|
|
5936
5955
|
<div class="history__empty">No previous conversations</div>
|
|
5937
5956
|
` : b `
|
|
5938
5957
|
<div class="history__list">
|
|
5939
|
-
${this._conversations.map((conversation) =>
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
'
|
|
5944
|
-
|
|
5958
|
+
${this._conversations.map((conversation) => {
|
|
5959
|
+
// Format lastModified for the row: today shows the time, this year
|
|
5960
|
+
// shows month/day, older shows month/day/year; the raw value if it
|
|
5961
|
+
// isn't a parseable date. Empty when the conversation has no date.
|
|
5962
|
+
let dateLabel = '';
|
|
5963
|
+
if (conversation.lastModified) {
|
|
5964
|
+
const date = new Date(conversation.lastModified);
|
|
5965
|
+
const now = new Date();
|
|
5966
|
+
if (isNaN(date.getTime())) {
|
|
5967
|
+
dateLabel = conversation.lastModified;
|
|
5968
|
+
}
|
|
5969
|
+
else if (date.toDateString() === now.toDateString()) {
|
|
5970
|
+
dateLabel = date.toLocaleTimeString('en-US', {
|
|
5971
|
+
hour: 'numeric',
|
|
5972
|
+
minute: '2-digit',
|
|
5973
|
+
});
|
|
5974
|
+
}
|
|
5975
|
+
else if (date.getFullYear() === now.getFullYear()) {
|
|
5976
|
+
dateLabel = date.toLocaleDateString('en-US', {
|
|
5977
|
+
month: 'short',
|
|
5978
|
+
day: 'numeric',
|
|
5979
|
+
});
|
|
5980
|
+
}
|
|
5981
|
+
else {
|
|
5982
|
+
dateLabel = date.toLocaleDateString('en-US', {
|
|
5983
|
+
month: 'short',
|
|
5984
|
+
day: 'numeric',
|
|
5985
|
+
year: 'numeric',
|
|
5986
|
+
});
|
|
5987
|
+
}
|
|
5988
|
+
}
|
|
5989
|
+
return b `
|
|
5990
|
+
<button
|
|
5991
|
+
type="button"
|
|
5992
|
+
class=${e({
|
|
5993
|
+
'history__item': true,
|
|
5994
|
+
'history__item--active': conversation.conversationID === this.conversationId,
|
|
5995
|
+
})}
|
|
5996
|
+
@click=${() => this._handleSwitchConversation(conversation.conversationID)}
|
|
5997
|
+
>
|
|
5998
|
+
<span class="history__item-title">${conversation.title || 'Untitled conversation'}</span>
|
|
5999
|
+
${dateLabel ? b `
|
|
6000
|
+
<span class="history__item-date">${dateLabel}</span>
|
|
6001
|
+
` : A}
|
|
6002
|
+
</button>
|
|
6003
|
+
`;
|
|
5945
6004
|
})}
|
|
5946
|
-
@click=${() => this._handleSwitchConversation(conversation.conversationID)}
|
|
5947
|
-
>
|
|
5948
|
-
<span class="history__item-title">${conversation.title || 'Untitled conversation'}</span>
|
|
5949
|
-
${conversation.lastModified ? b `
|
|
5950
|
-
<span class="history__item-date">${this._renderConversationDate(conversation.lastModified)}</span>
|
|
5951
|
-
` : A}
|
|
5952
|
-
</button>
|
|
5953
|
-
`)}
|
|
5954
6005
|
</div>
|
|
5955
6006
|
`}
|
|
5956
6007
|
</div>
|
|
5957
6008
|
`;
|
|
5958
6009
|
}
|
|
5959
|
-
/**
|
|
5960
|
-
* Format a conversation's lastModified for the history list: today shows the
|
|
5961
|
-
* time, this year shows month/day, older shows month/day/year. Falls back to the
|
|
5962
|
-
* raw value if it isn't a parseable date.
|
|
5963
|
-
*/
|
|
5964
|
-
_renderConversationDate(lastModified) {
|
|
5965
|
-
const date = new Date(lastModified);
|
|
5966
|
-
if (isNaN(date.getTime())) {
|
|
5967
|
-
return lastModified;
|
|
5968
|
-
}
|
|
5969
|
-
const now = new Date();
|
|
5970
|
-
if (date.toDateString() === now.toDateString()) {
|
|
5971
|
-
return date.toLocaleTimeString('en-US', {
|
|
5972
|
-
hour: 'numeric',
|
|
5973
|
-
minute: '2-digit',
|
|
5974
|
-
});
|
|
5975
|
-
}
|
|
5976
|
-
if (date.getFullYear() === now.getFullYear()) {
|
|
5977
|
-
return date.toLocaleDateString('en-US', {
|
|
5978
|
-
month: 'short',
|
|
5979
|
-
day: 'numeric',
|
|
5980
|
-
});
|
|
5981
|
-
}
|
|
5982
|
-
return date.toLocaleDateString('en-US', {
|
|
5983
|
-
month: 'short',
|
|
5984
|
-
day: 'numeric',
|
|
5985
|
-
year: 'numeric',
|
|
5986
|
-
});
|
|
5987
|
-
}
|
|
5988
6010
|
/**
|
|
5989
6011
|
* The side drawer — one sliding panel that holds the Settings, Debug, History,
|
|
5990
6012
|
* and tool-detail views. The header buttons switch `_drawerView`; the title and
|
|
@@ -6015,25 +6037,24 @@ class KRChatbot extends i$3 {
|
|
|
6015
6037
|
// In the floating widget the drawer fills the panel over the transcript (a
|
|
6016
6038
|
// full-panel view with a back button) rather than sliding in beside it — the
|
|
6017
6039
|
// panel is too narrow to show both. Inline keeps the side-drawer behavior.
|
|
6018
|
-
const fullPanel = this.variant === 'floating';
|
|
6019
6040
|
return b `
|
|
6020
6041
|
<div
|
|
6021
6042
|
class=${e({
|
|
6022
6043
|
'drawer': true,
|
|
6023
6044
|
'drawer--open': this._drawerOpen,
|
|
6024
6045
|
'drawer--resizing': this._isDrawerResizing,
|
|
6025
|
-
'drawer--full':
|
|
6046
|
+
'drawer--full': this.variant === 'floating',
|
|
6026
6047
|
})}
|
|
6027
|
-
style=${o(
|
|
6048
|
+
style=${o(this.variant === 'floating' ? {} : { width: `${this._drawerWidth}px` })}
|
|
6028
6049
|
>
|
|
6029
|
-
${
|
|
6050
|
+
${this.variant === 'floating' ? A : b `
|
|
6030
6051
|
<div
|
|
6031
6052
|
class="drawer__resize"
|
|
6032
6053
|
@mousedown=${this._handleDrawerResizeMouseDown}
|
|
6033
6054
|
></div>
|
|
6034
6055
|
`}
|
|
6035
6056
|
<div class="drawer__header">
|
|
6036
|
-
${
|
|
6057
|
+
${this.variant === 'floating' ? b `
|
|
6037
6058
|
<button
|
|
6038
6059
|
class="header-action"
|
|
6039
6060
|
@click=${this._handleCloseDrawer}
|
|
@@ -6081,7 +6102,7 @@ class KRChatbot extends i$3 {
|
|
|
6081
6102
|
New conversation
|
|
6082
6103
|
</kr-button>
|
|
6083
6104
|
` : A}
|
|
6084
|
-
${
|
|
6105
|
+
${this.variant === 'floating' ? A : b `
|
|
6085
6106
|
<button
|
|
6086
6107
|
class="header-action"
|
|
6087
6108
|
@click=${this._handleCloseDrawer}
|
|
@@ -11487,17 +11508,31 @@ var __decorate$2 = (undefined && undefined.__decorate) || function (decorators,
|
|
|
11487
11508
|
* { id: 'activity', label: 'Activity', url: '/companies/123/activity' },
|
|
11488
11509
|
* ]}
|
|
11489
11510
|
* activeId="overview"
|
|
11511
|
+
* .actions=${[
|
|
11512
|
+
* { id: 'edit', label: 'Edit', variant: 'flat' },
|
|
11513
|
+
* { id: 'archive', label: 'Archive' },
|
|
11514
|
+
* { id: 'delete', label: 'Delete' },
|
|
11515
|
+
* { id: 'export', label: 'Export' },
|
|
11516
|
+
* ]}
|
|
11490
11517
|
* >
|
|
11491
11518
|
* <div>Screen content here</div>
|
|
11492
11519
|
* </kr-screen-nav>
|
|
11493
11520
|
* ```
|
|
11494
11521
|
*
|
|
11522
|
+
* Actions render in a footer at the bottom of the nav column. With more than
|
|
11523
|
+
* `maxVisibleActions` (default 3), the overflow collapses into a "More" dropdown.
|
|
11524
|
+
* Listen for `action-click` to handle a click: `e.detail.action` is the action id.
|
|
11525
|
+
*
|
|
11495
11526
|
* @slot - The main screen content
|
|
11496
11527
|
*
|
|
11497
11528
|
* @property {string} label - Main label (e.g., entity name like "Acme Corporation")
|
|
11498
11529
|
* @property {string} subLabel - Sub label (e.g., entity type like "Company")
|
|
11499
11530
|
* @property {KRScreenNavItem[]} items - Navigation items as JSON array
|
|
11500
11531
|
* @property {string} activeId - Currently active item ID
|
|
11532
|
+
* @property {KRScreenNavAction[]} actions - Action buttons rendered in the nav footer
|
|
11533
|
+
* @property {number} maxVisibleActions - Max inline actions before collapsing into a "More" dropdown (default 3)
|
|
11534
|
+
*
|
|
11535
|
+
* @fires action-click - When an action button (inline or overflow) is clicked; detail is `{ action: id }`
|
|
11501
11536
|
*/
|
|
11502
11537
|
class KRScreenNav extends i$3 {
|
|
11503
11538
|
constructor() {
|
|
@@ -11519,6 +11554,17 @@ class KRScreenNav extends i$3 {
|
|
|
11519
11554
|
* Can be set explicitly by the parent to override.
|
|
11520
11555
|
*/
|
|
11521
11556
|
this.activeId = '';
|
|
11557
|
+
/**
|
|
11558
|
+
* Action buttons rendered in the nav footer.
|
|
11559
|
+
*/
|
|
11560
|
+
this.actions = [];
|
|
11561
|
+
/**
|
|
11562
|
+
* Max number of inline action buttons before the overflow collapses into a
|
|
11563
|
+
* "More" dropdown. When actions exceed this count, the last visible slot is
|
|
11564
|
+
* used for the "More" button so the total footer button count never exceeds
|
|
11565
|
+
* this value.
|
|
11566
|
+
*/
|
|
11567
|
+
this.maxVisibleActions = 3;
|
|
11522
11568
|
this.handlePopstate = () => {
|
|
11523
11569
|
this.syncActiveFromUrl();
|
|
11524
11570
|
};
|
|
@@ -11579,7 +11625,35 @@ class KRScreenNav extends i$3 {
|
|
|
11579
11625
|
this.activeId = match.id;
|
|
11580
11626
|
}
|
|
11581
11627
|
}
|
|
11628
|
+
handleActionClick(e, action) {
|
|
11629
|
+
this.dispatchEvent(new CustomEvent('action-click', {
|
|
11630
|
+
detail: { action: action.id },
|
|
11631
|
+
bubbles: true,
|
|
11632
|
+
composed: true,
|
|
11633
|
+
}));
|
|
11634
|
+
}
|
|
11635
|
+
// Fired by the "More" kr-button when an overflow option is chosen; detail is { id, label }.
|
|
11636
|
+
handleMoreSelect(e) {
|
|
11637
|
+
this.dispatchEvent(new CustomEvent('action-click', {
|
|
11638
|
+
detail: { action: e.detail.id },
|
|
11639
|
+
bubbles: true,
|
|
11640
|
+
composed: true,
|
|
11641
|
+
}));
|
|
11642
|
+
}
|
|
11582
11643
|
render() {
|
|
11644
|
+
const hasOverflow = this.actions.length > this.maxVisibleActions;
|
|
11645
|
+
// When collapsing, the last visible slot is the "More" button, so only
|
|
11646
|
+
// show the first (maxVisibleActions - 1) actions inline.
|
|
11647
|
+
let inlineActions = this.actions;
|
|
11648
|
+
let overflowOptions = [];
|
|
11649
|
+
if (hasOverflow) {
|
|
11650
|
+
inlineActions = this.actions.slice(0, this.maxVisibleActions - 1);
|
|
11651
|
+
// Everything past the inline slots goes into the "More" dropdown.
|
|
11652
|
+
overflowOptions = this.actions.slice(this.maxVisibleActions - 1).map((action) => ({
|
|
11653
|
+
id: action.id,
|
|
11654
|
+
label: action.label,
|
|
11655
|
+
}));
|
|
11656
|
+
}
|
|
11583
11657
|
return b `
|
|
11584
11658
|
<nav class="nav">
|
|
11585
11659
|
${this.label ? b `
|
|
@@ -11606,6 +11680,31 @@ class KRScreenNav extends i$3 {
|
|
|
11606
11680
|
`)}
|
|
11607
11681
|
</div>
|
|
11608
11682
|
</div>
|
|
11683
|
+
${this.actions.length ? b `
|
|
11684
|
+
<div class="nav-actions">
|
|
11685
|
+
${inlineActions.map((action) => b `
|
|
11686
|
+
<kr-button
|
|
11687
|
+
class="nav-actions__button"
|
|
11688
|
+
variant=${action.variant || 'outline'}
|
|
11689
|
+
size="small"
|
|
11690
|
+
@click=${(e) => this.handleActionClick(e, action)}
|
|
11691
|
+
>
|
|
11692
|
+
${action.label}
|
|
11693
|
+
</kr-button>
|
|
11694
|
+
`)}
|
|
11695
|
+
${hasOverflow ? b `
|
|
11696
|
+
<kr-button
|
|
11697
|
+
class="nav-actions__button"
|
|
11698
|
+
variant="outline"
|
|
11699
|
+
size="small"
|
|
11700
|
+
.options=${overflowOptions}
|
|
11701
|
+
@option-select=${this.handleMoreSelect}
|
|
11702
|
+
>
|
|
11703
|
+
More
|
|
11704
|
+
</kr-button>
|
|
11705
|
+
` : A}
|
|
11706
|
+
</div>
|
|
11707
|
+
` : A}
|
|
11609
11708
|
</nav>
|
|
11610
11709
|
<main class="content">
|
|
11611
11710
|
<div class="content__main">
|
|
@@ -11694,6 +11793,19 @@ KRScreenNav.styles = i$6 `
|
|
|
11694
11793
|
font-weight: 700;
|
|
11695
11794
|
}
|
|
11696
11795
|
|
|
11796
|
+
.nav-actions {
|
|
11797
|
+
display: flex;
|
|
11798
|
+
flex-direction: column;
|
|
11799
|
+
gap: 8px;
|
|
11800
|
+
padding: 12px 16px;
|
|
11801
|
+
border-top: 1px solid rgba(0, 0, 0, 0.08);
|
|
11802
|
+
flex-shrink: 0;
|
|
11803
|
+
}
|
|
11804
|
+
|
|
11805
|
+
.nav-actions__button {
|
|
11806
|
+
width: 100%;
|
|
11807
|
+
}
|
|
11808
|
+
|
|
11697
11809
|
.content {
|
|
11698
11810
|
flex: 1;
|
|
11699
11811
|
min-width: 0;
|
|
@@ -11718,6 +11830,12 @@ __decorate$2([
|
|
|
11718
11830
|
__decorate$2([
|
|
11719
11831
|
n$1({ type: String })
|
|
11720
11832
|
], KRScreenNav.prototype, "activeId", void 0);
|
|
11833
|
+
__decorate$2([
|
|
11834
|
+
n$1({ type: Array })
|
|
11835
|
+
], KRScreenNav.prototype, "actions", void 0);
|
|
11836
|
+
__decorate$2([
|
|
11837
|
+
n$1({ type: Number })
|
|
11838
|
+
], KRScreenNav.prototype, "maxVisibleActions", void 0);
|
|
11721
11839
|
// Guarded registration: no-op if the tag is already defined, so a second copy of krubble on
|
|
11722
11840
|
// the page (e.g. the Operations shell loads krubble globally while an embedded app bundled its
|
|
11723
11841
|
// own copy) doesn't throw. First definition wins.
|