@nuraly/lumenui 0.3.5 → 0.3.7
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/nuralyui.bundle.js +2577 -1486
- package/dist/nuralyui.bundle.js.gz +0 -0
- package/dist/src/components/button/bundle.js +130 -39
- package/dist/src/components/button/bundle.js.gz +0 -0
- package/dist/src/components/button/button.component.js +7 -4
- package/dist/src/components/button/button.style.js +92 -2
- package/dist/src/components/canvas/base-canvas.component.d.ts +8 -0
- package/dist/src/components/canvas/base-canvas.component.js +75 -3
- package/dist/src/components/canvas/bundle.js +2540 -1201
- package/dist/src/components/canvas/bundle.js.gz +0 -0
- package/dist/src/components/canvas/controllers/collaboration.controller.d.ts +24 -11
- package/dist/src/components/canvas/controllers/collaboration.controller.js +176 -120
- package/dist/src/components/canvas/controllers/selection.controller.js +20 -0
- package/dist/src/components/canvas/interfaces/collaboration.interface.d.ts +8 -0
- package/dist/src/components/canvas/templates/index.d.ts +1 -0
- package/dist/src/components/canvas/templates/index.js +2 -0
- package/dist/src/components/canvas/templates/lock-overlay.template.d.ts +20 -0
- package/dist/src/components/canvas/templates/lock-overlay.template.js +33 -0
- package/dist/src/components/canvas/workflow-canvas.component.js +52 -24
- package/dist/src/components/canvas/workflow-canvas.style.js +62 -1
- package/dist/src/components/canvas/workflow-canvas.types.js +50 -4
- package/dist/src/components/chat-panel/bundle.js +10 -10
- package/dist/src/components/chat-panel/bundle.js.gz +0 -0
- package/dist/src/components/chat-panel/chat-panel.component.js +8 -8
- package/dist/src/components/chatbot/bundle.js +400 -242
- package/dist/src/components/chatbot/bundle.js.gz +0 -0
- package/dist/src/components/chatbot/chatbot.style.js +156 -22
- package/dist/src/components/chatbot/chatbot.types.d.ts +1 -0
- package/dist/src/components/chatbot/core/chatbot-core.controller.js +13 -7
- package/dist/src/components/chatbot/plugins/artifact-plugin.js +0 -19
- package/dist/src/components/chatbot/plugins/flight-card-plugin.js +0 -35
- package/dist/src/components/chatbot/plugins/markdown-plugin.js +0 -4
- package/dist/src/components/chatbot/plugins/print-job-card-plugin.js +0 -36
- package/dist/src/components/chatbot/plugins/selection-card-plugin.js +0 -34
- package/dist/src/components/chatbot/providers/workflow-socket-provider.js +1 -2
- package/dist/src/components/chatbot/templates/input-box.template.js +58 -30
- package/dist/src/components/chatbot/templates/message.template.js +41 -31
- package/dist/src/components/chatbot/templates/thread-sidebar.template.js +38 -39
- package/dist/src/components/colorpicker/bundle.js +15 -10
- package/dist/src/components/colorpicker/bundle.js.gz +0 -0
- package/dist/src/components/colorpicker/color-picker.component.js +15 -10
- package/dist/src/components/datepicker/bundle.js +10 -10
- package/dist/src/components/datepicker/bundle.js.gz +0 -0
- package/dist/src/components/datepicker/datepicker.component.js +14 -22
- package/dist/src/components/dropdown/bundle.js +15 -14
- package/dist/src/components/dropdown/bundle.js.gz +0 -0
- package/dist/src/components/dropdown/dropdown.component.js +10 -9
- package/dist/src/components/dropdown/dropdown.style.js +2 -2
- package/dist/src/components/file-upload/bundle.js +15 -14
- package/dist/src/components/file-upload/bundle.js.gz +0 -0
- package/dist/src/components/file-upload/file-upload.component.js +15 -14
- package/dist/src/components/icon/bundle.js +7 -7
- package/dist/src/components/icon/bundle.js.gz +0 -0
- package/dist/src/components/icon/icon-paths.js +15 -0
- package/dist/src/components/iconpicker/bundle.js +216 -124
- package/dist/src/components/iconpicker/bundle.js.gz +0 -0
- package/dist/src/components/iconpicker/icon-picker.component.js +4 -4
- package/dist/src/components/menu/bundle.js +5 -2
- package/dist/src/components/menu/bundle.js.gz +0 -0
- package/dist/src/components/menu/menu.component.js +5 -2
- package/dist/src/components/modal/bundle.js +16 -13
- package/dist/src/components/modal/bundle.js.gz +0 -0
- package/dist/src/components/modal/modal.component.js +16 -13
- package/dist/src/components/panel/bundle.js +28 -28
- package/dist/src/components/panel/bundle.js.gz +0 -0
- package/dist/src/components/popconfirm/bundle.js +135 -41
- package/dist/src/components/popconfirm/bundle.js.gz +0 -0
- package/dist/src/components/popconfirm/popconfirm.component.d.ts +15 -119
- package/dist/src/components/popconfirm/popconfirm.component.js +158 -162
- package/dist/src/components/popconfirm/popconfirm.style.js +94 -0
- package/dist/src/components/presence/bundle.js +2 -1
- package/dist/src/components/presence/bundle.js.gz +0 -0
- package/dist/src/components/presence/presence.component.js +2 -1
- package/dist/src/components/table/bundle.js +3 -2
- package/dist/src/components/table/bundle.js.gz +0 -0
- package/dist/src/components/table/table.component.js +3 -2
- package/dist/src/components/tabs/bundle.js +3 -3
- package/dist/src/components/tabs/bundle.js.gz +0 -0
- package/dist/src/components/timepicker/bundle.js +3 -3
- package/dist/src/components/timepicker/bundle.js.gz +0 -0
- package/package.json +1 -1
- package/packages/common/dist/VERSIONS.md +1 -1
- package/packages/common/dist/shared/controllers/dropdown.controller.d.ts +4 -0
- package/packages/common/dist/shared/controllers/dropdown.controller.d.ts.map +1 -1
- package/packages/common/dist/shared/controllers/dropdown.controller.js +29 -3
- package/packages/common/dist/shared/controllers/dropdown.controller.js.map +1 -1
|
@@ -472,25 +472,31 @@ let WorkflowCanvasElement = class WorkflowCanvasElement extends BaseCanvasElemen
|
|
|
472
472
|
const previewNode = this.getPreviewNode();
|
|
473
473
|
if (!previewNode || !((_a = this.workflow) === null || _a === void 0 ? void 0 : _a.id))
|
|
474
474
|
return;
|
|
475
|
+
const config = previewNode.configuration || {};
|
|
476
|
+
const httpPath = config.httpPath || '/webhook';
|
|
477
|
+
const httpMethod = (config.httpMethod || 'POST').toUpperCase();
|
|
478
|
+
const methodHasBody = httpMethod !== 'GET' && httpMethod !== 'HEAD' && httpMethod !== 'OPTIONS';
|
|
475
479
|
this.httpPreviewLoading = true;
|
|
476
480
|
this.httpPreviewError = '';
|
|
477
481
|
this.httpPreviewResponse = '';
|
|
478
482
|
this.nodeStatuses = {};
|
|
479
483
|
try {
|
|
480
|
-
let body;
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
let body = undefined;
|
|
485
|
+
if (methodHasBody) {
|
|
486
|
+
try {
|
|
487
|
+
body = JSON.parse(this.httpPreviewBody);
|
|
488
|
+
}
|
|
489
|
+
catch (_b) {
|
|
490
|
+
throw new Error('Invalid JSON in request body');
|
|
491
|
+
}
|
|
486
492
|
}
|
|
487
493
|
const baseUrl = typeof window !== 'undefined' ? window.location.origin : 'http://localhost:8000';
|
|
488
|
-
const triggerUrl = `${baseUrl}/api/v1/workflows/${this.workflow.id}/trigger
|
|
489
|
-
console.log('[Canvas] Sending HTTP preview request:', triggerUrl, body);
|
|
494
|
+
const triggerUrl = `${baseUrl}/api/v1/workflows/${this.workflow.id}/trigger${httpPath}`;
|
|
495
|
+
console.log('[Canvas] Sending HTTP preview request:', httpMethod, triggerUrl, body);
|
|
490
496
|
const response = yield fetch(triggerUrl, {
|
|
491
|
-
method:
|
|
492
|
-
headers: { 'Content-Type': 'application/json' },
|
|
493
|
-
body: JSON.stringify(body),
|
|
497
|
+
method: httpMethod,
|
|
498
|
+
headers: methodHasBody ? { 'Content-Type': 'application/json' } : {},
|
|
499
|
+
body: methodHasBody ? JSON.stringify(body) : undefined,
|
|
494
500
|
});
|
|
495
501
|
const executionIdHeader = response.headers.get('X-Execution-Id');
|
|
496
502
|
let responseData;
|
|
@@ -1083,8 +1089,21 @@ let WorkflowCanvasElement = class WorkflowCanvasElement extends BaseCanvasElemen
|
|
|
1083
1089
|
`;
|
|
1084
1090
|
}
|
|
1085
1091
|
renderHttpPreviewPanel(previewNode, panelStyle) {
|
|
1092
|
+
var _a;
|
|
1086
1093
|
const config = previewNode.configuration || {};
|
|
1087
1094
|
const httpPath = config.httpPath || '/webhook';
|
|
1095
|
+
const httpMethod = (config.httpMethod || 'POST').toUpperCase();
|
|
1096
|
+
const httpAuth = config.httpAuth || 'none';
|
|
1097
|
+
const wfId = ((_a = this.workflow) === null || _a === void 0 ? void 0 : _a.id) || '{workflowId}';
|
|
1098
|
+
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
1099
|
+
const webhookUrl = `${origin}/api/v1/workflows/${wfId}/trigger${httpPath}`;
|
|
1100
|
+
const methodHasBody = httpMethod !== 'GET' && httpMethod !== 'HEAD' && httpMethod !== 'OPTIONS';
|
|
1101
|
+
const authLabel = {
|
|
1102
|
+
none: '',
|
|
1103
|
+
api_key: `API Key required (header: ${config.httpAuthHeaderName || 'X-API-Key'})`,
|
|
1104
|
+
bearer: 'Bearer token required (Authorization header)',
|
|
1105
|
+
basic: 'Basic auth required (Authorization header)',
|
|
1106
|
+
};
|
|
1088
1107
|
return html `
|
|
1089
1108
|
<div class="chatbot-preview-panel http-preview-panel" style=${styleMap(panelStyle)} data-theme=${this.currentTheme}>
|
|
1090
1109
|
<div class="chatbot-preview-header">
|
|
@@ -1098,19 +1117,27 @@ let WorkflowCanvasElement = class WorkflowCanvasElement extends BaseCanvasElemen
|
|
|
1098
1117
|
</div>
|
|
1099
1118
|
<div class="http-preview-content">
|
|
1100
1119
|
<div class="http-preview-url">
|
|
1101
|
-
<span class="http-method"
|
|
1102
|
-
<span class="http-path">${
|
|
1103
|
-
</div>
|
|
1104
|
-
<div class="http-preview-section">
|
|
1105
|
-
<label>Request Body (JSON)</label>
|
|
1106
|
-
<textarea
|
|
1107
|
-
class="http-request-body"
|
|
1108
|
-
.value=${this.httpPreviewBody}
|
|
1109
|
-
@input=${(e) => this.httpPreviewBody = e.target.value}
|
|
1110
|
-
placeholder='{ "key": "value" }'
|
|
1111
|
-
?disabled=${this.httpPreviewLoading}
|
|
1112
|
-
></textarea>
|
|
1120
|
+
<span class="http-method">${httpMethod}</span>
|
|
1121
|
+
<span class="http-path" title=${webhookUrl}>${webhookUrl}</span>
|
|
1113
1122
|
</div>
|
|
1123
|
+
${httpAuth !== 'none' ? html `
|
|
1124
|
+
<div class="http-preview-auth-hint">
|
|
1125
|
+
<nr-icon name="shield" size="small"></nr-icon>
|
|
1126
|
+
<span>${authLabel[httpAuth]}</span>
|
|
1127
|
+
</div>
|
|
1128
|
+
` : ''}
|
|
1129
|
+
${methodHasBody ? html `
|
|
1130
|
+
<div class="http-preview-section">
|
|
1131
|
+
<label>Request Body (JSON)</label>
|
|
1132
|
+
<textarea
|
|
1133
|
+
class="http-request-body"
|
|
1134
|
+
.value=${this.httpPreviewBody}
|
|
1135
|
+
@input=${(e) => this.httpPreviewBody = e.target.value}
|
|
1136
|
+
placeholder='{ "key": "value" }'
|
|
1137
|
+
?disabled=${this.httpPreviewLoading}
|
|
1138
|
+
></textarea>
|
|
1139
|
+
</div>
|
|
1140
|
+
` : ''}
|
|
1114
1141
|
<div class="http-preview-actions">
|
|
1115
1142
|
<button
|
|
1116
1143
|
class="http-send-btn"
|
|
@@ -1122,7 +1149,7 @@ let WorkflowCanvasElement = class WorkflowCanvasElement extends BaseCanvasElemen
|
|
|
1122
1149
|
<span>Sending...</span>
|
|
1123
1150
|
` : html `
|
|
1124
1151
|
<nr-icon name="send" size="small"></nr-icon>
|
|
1125
|
-
<span>Send
|
|
1152
|
+
<span>Send ${httpMethod}</span>
|
|
1126
1153
|
`}
|
|
1127
1154
|
</button>
|
|
1128
1155
|
</div>
|
|
@@ -1441,6 +1468,7 @@ let WorkflowCanvasElement = class WorkflowCanvasElement extends BaseCanvasElemen
|
|
|
1441
1468
|
></workflow-node>
|
|
1442
1469
|
`;
|
|
1443
1470
|
})}
|
|
1471
|
+
${this.renderNodeLockOverlays()}
|
|
1444
1472
|
</div>
|
|
1445
1473
|
</div>
|
|
1446
1474
|
|
|
@@ -567,6 +567,24 @@ export const workflowCanvasStyles = css `
|
|
|
567
567
|
background: rgba(0, 0, 0, 0.05);
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
+
.config-panel-help {
|
|
571
|
+
background: none;
|
|
572
|
+
border: none;
|
|
573
|
+
color: #8d8d8d;
|
|
574
|
+
cursor: pointer;
|
|
575
|
+
padding: 0.125rem;
|
|
576
|
+
display: flex;
|
|
577
|
+
align-items: center;
|
|
578
|
+
justify-content: center;
|
|
579
|
+
border-radius: 4px;
|
|
580
|
+
transition: all 0.15s ease;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.config-panel-help:hover {
|
|
584
|
+
color: #0f62fe;
|
|
585
|
+
background: rgba(15, 98, 254, 0.08);
|
|
586
|
+
}
|
|
587
|
+
|
|
570
588
|
.config-panel-content {
|
|
571
589
|
flex: 1;
|
|
572
590
|
overflow-y: auto;
|
|
@@ -1788,7 +1806,7 @@ export const workflowCanvasStyles = css `
|
|
|
1788
1806
|
.canvas-wrapper[data-theme="default"] .node-palette,
|
|
1789
1807
|
.canvas-wrapper[data-theme="default"] .context-menu,
|
|
1790
1808
|
.canvas-wrapper[data-theme="default"] .config-panel {
|
|
1791
|
-
background:
|
|
1809
|
+
background: rgb(255 255 255);
|
|
1792
1810
|
border-color: #e0e0e0;
|
|
1793
1811
|
}
|
|
1794
1812
|
|
|
@@ -2119,6 +2137,23 @@ export const workflowCanvasStyles = css `
|
|
|
2119
2137
|
|
|
2120
2138
|
.http-path {
|
|
2121
2139
|
color: #525252;
|
|
2140
|
+
overflow: hidden;
|
|
2141
|
+
text-overflow: ellipsis;
|
|
2142
|
+
white-space: nowrap;
|
|
2143
|
+
min-width: 0;
|
|
2144
|
+
flex: 1;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
.http-preview-auth-hint {
|
|
2148
|
+
display: flex;
|
|
2149
|
+
align-items: center;
|
|
2150
|
+
gap: 0.375rem;
|
|
2151
|
+
padding: 0.375rem 0.625rem;
|
|
2152
|
+
background: #fff8e1;
|
|
2153
|
+
border: 1px solid #ffe082;
|
|
2154
|
+
border-radius: 4px;
|
|
2155
|
+
font-size: 0.75rem;
|
|
2156
|
+
color: #8a6d3b;
|
|
2122
2157
|
}
|
|
2123
2158
|
|
|
2124
2159
|
.http-preview-section {
|
|
@@ -2934,6 +2969,32 @@ export const workflowCanvasStyles = css `
|
|
|
2934
2969
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
2935
2970
|
}
|
|
2936
2971
|
|
|
2972
|
+
/* ========================================
|
|
2973
|
+
* COLLABORATION: NODE LOCK PILL
|
|
2974
|
+
* ======================================== */
|
|
2975
|
+
|
|
2976
|
+
.node-lock-pill {
|
|
2977
|
+
position: absolute;
|
|
2978
|
+
pointer-events: none;
|
|
2979
|
+
display: inline-flex;
|
|
2980
|
+
align-items: center;
|
|
2981
|
+
gap: 4px;
|
|
2982
|
+
padding: 3px 8px;
|
|
2983
|
+
border-radius: 10px;
|
|
2984
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
2985
|
+
font-size: 11px;
|
|
2986
|
+
font-weight: 600;
|
|
2987
|
+
color: #ffffff;
|
|
2988
|
+
white-space: nowrap;
|
|
2989
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
|
|
2990
|
+
z-index: 20;
|
|
2991
|
+
}
|
|
2992
|
+
|
|
2993
|
+
.node-lock-pill svg {
|
|
2994
|
+
display: block;
|
|
2995
|
+
flex: none;
|
|
2996
|
+
}
|
|
2997
|
+
|
|
2937
2998
|
/* ========================================
|
|
2938
2999
|
* COLLABORATION: PRESENCE BAR
|
|
2939
3000
|
* ======================================== */
|
|
@@ -1751,7 +1751,17 @@ export const NODE_TEMPLATES = [
|
|
|
1751
1751
|
icon: NODE_ICONS[WorkflowNodeType.SLACK_SOCKET],
|
|
1752
1752
|
color: NODE_COLORS[WorkflowNodeType.SLACK_SOCKET],
|
|
1753
1753
|
category: 'trigger',
|
|
1754
|
-
defaultConfig: {
|
|
1754
|
+
defaultConfig: {
|
|
1755
|
+
appTokenPath: '',
|
|
1756
|
+
botTokenPath: '',
|
|
1757
|
+
eventTypes: [],
|
|
1758
|
+
interactionTypes: [],
|
|
1759
|
+
slashCommands: '',
|
|
1760
|
+
allowedTeamIds: '',
|
|
1761
|
+
allowedChannelIds: '',
|
|
1762
|
+
allowedUserIds: '',
|
|
1763
|
+
ignoreBots: true,
|
|
1764
|
+
},
|
|
1755
1765
|
defaultPorts: {
|
|
1756
1766
|
inputs: [],
|
|
1757
1767
|
outputs: [
|
|
@@ -1767,7 +1777,15 @@ export const NODE_TEMPLATES = [
|
|
|
1767
1777
|
icon: NODE_ICONS[WorkflowNodeType.DISCORD_BOT],
|
|
1768
1778
|
color: NODE_COLORS[WorkflowNodeType.DISCORD_BOT],
|
|
1769
1779
|
category: 'trigger',
|
|
1770
|
-
defaultConfig: {
|
|
1780
|
+
defaultConfig: {
|
|
1781
|
+
botTokenPath: '',
|
|
1782
|
+
intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT'],
|
|
1783
|
+
eventTypes: [],
|
|
1784
|
+
allowedGuildIds: '',
|
|
1785
|
+
allowedChannelIds: '',
|
|
1786
|
+
allowedUserIds: '',
|
|
1787
|
+
ignoreBots: true,
|
|
1788
|
+
},
|
|
1771
1789
|
defaultPorts: {
|
|
1772
1790
|
inputs: [],
|
|
1773
1791
|
outputs: [
|
|
@@ -1783,7 +1801,17 @@ export const NODE_TEMPLATES = [
|
|
|
1783
1801
|
icon: NODE_ICONS[WorkflowNodeType.WHATSAPP_WEBHOOK],
|
|
1784
1802
|
color: NODE_COLORS[WorkflowNodeType.WHATSAPP_WEBHOOK],
|
|
1785
1803
|
category: 'trigger',
|
|
1786
|
-
defaultConfig: {
|
|
1804
|
+
defaultConfig: {
|
|
1805
|
+
phoneNumberId: '',
|
|
1806
|
+
businessAccountId: '',
|
|
1807
|
+
accessTokenPath: '',
|
|
1808
|
+
appSecretPath: '',
|
|
1809
|
+
verifyToken: '',
|
|
1810
|
+
webhookFields: ['messages'],
|
|
1811
|
+
messageTypes: [],
|
|
1812
|
+
allowedSenders: '',
|
|
1813
|
+
ignoreStatusUpdates: false,
|
|
1814
|
+
},
|
|
1787
1815
|
defaultPorts: {
|
|
1788
1816
|
inputs: [],
|
|
1789
1817
|
outputs: [
|
|
@@ -1799,7 +1827,25 @@ export const NODE_TEMPLATES = [
|
|
|
1799
1827
|
icon: NODE_ICONS[WorkflowNodeType.CUSTOM_WEBSOCKET],
|
|
1800
1828
|
color: NODE_COLORS[WorkflowNodeType.CUSTOM_WEBSOCKET],
|
|
1801
1829
|
category: 'trigger',
|
|
1802
|
-
defaultConfig: {
|
|
1830
|
+
defaultConfig: {
|
|
1831
|
+
url: '',
|
|
1832
|
+
subprotocol: '',
|
|
1833
|
+
authMode: 'none',
|
|
1834
|
+
tokenPath: '',
|
|
1835
|
+
username: '',
|
|
1836
|
+
passwordPath: '',
|
|
1837
|
+
headerName: '',
|
|
1838
|
+
headerValuePath: '',
|
|
1839
|
+
queryParamName: 'token',
|
|
1840
|
+
queryParamValuePath: '',
|
|
1841
|
+
initialMessage: '',
|
|
1842
|
+
autoReconnect: true,
|
|
1843
|
+
reconnectDelayMs: 5000,
|
|
1844
|
+
maxReconnectAttempts: 0,
|
|
1845
|
+
pingIntervalSec: 30,
|
|
1846
|
+
messageFormat: 'json',
|
|
1847
|
+
filterExpression: '',
|
|
1848
|
+
},
|
|
1803
1849
|
defaultPorts: {
|
|
1804
1850
|
inputs: [],
|
|
1805
1851
|
outputs: [
|
|
@@ -127,9 +127,9 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
127
127
|
* @license
|
|
128
128
|
* Copyright 2024 Nuraly, Laabidi Aymen
|
|
129
129
|
* SPDX-License-Identifier: MIT
|
|
130
|
-
*/;var d=function(t,e,i,o){for(var s,n=arguments.length,a=n<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,i):o,r=t.length-1;r>=0;r--)(s=t[r])&&(a=(n<3?s(a):n>3?s(e,i,a):s(e,i))||a);return n>3&&a&&Object.defineProperty(e,i,a),a};const l=[{key:"👍",label:"Like"},{key:"❤️",label:"Love"},{key:"😂",label:"Haha"},{key:"😮",label:"Wow"},{key:"😢",label:"Sad"},{key:"🔥",label:"Fire"}],c=["😀","😂","🥰","😎","🤔","🎉","✨","🙏","💯","🚀","👏","😍","🤣","💪","😊","🥳","😤","💀","🫡","👀","💜","🤝","⭐","🙌"],p=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>`,
|
|
130
|
+
*/;var d=function(t,e,i,o){for(var s,n=arguments.length,a=n<3?e:null===o?o=Object.getOwnPropertyDescriptor(e,i):o,r=t.length-1;r>=0;r--)(s=t[r])&&(a=(n<3?s(a):n>3?s(e,i,a):s(e,i))||a);return n>3&&a&&Object.defineProperty(e,i,a),a};const l=[{key:"👍",label:"Like"},{key:"❤️",label:"Love"},{key:"😂",label:"Haha"},{key:"😮",label:"Wow"},{key:"😢",label:"Sad"},{key:"🔥",label:"Fire"}],c=["😀","😂","🥰","😎","🤔","🎉","✨","🙏","💯","🚀","👏","😍","🤣","💪","😊","🥳","😤","💀","🫡","👀","💜","🤝","⭐","🙌"],p=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="20 6 9 17 4 12"/></svg>`,u=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="18 6 7 17 2 12"/><polyline points="23 6 12 17" opacity="0.5"/></svg>`,g=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2"><polyline points="18 6 7 17 2 12"/><polyline points="23 6 12 17"/></svg>`,h=e`<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>`,x=e`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>`,m=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>`,v=e`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>`,b=e`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>`,f=e`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.67A2 2 0 014.11 2h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z"/></svg>`,y=e`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>`,w=e`<svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>`,k=e`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48"/></svg>`,$=e`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>`;let j=class extends i{constructor(){super(...arguments),this.messages=[],this.currentUser=null,this.conversationId="",this.isGroup=!1,this.loading=!1,this.compact=!1,this.emptyText="No messages yet",this.hideInput=!1,this._showEmoji=!1,this._contextMenu=null,this._replyTo=null,this._editingIdx=null,this._typing=[],this._typingTimer=null,this._longPressTimer=null,this._touchMoved=!1}updated(t){t.has("messages")&&requestAnimationFrame(()=>{var t;const e=null===(t=this.shadowRoot)||void 0===t?void 0:t.querySelector(".chat-messages");e&&(e.scrollTop=e.scrollHeight)})}addTyping(t){this._typing.includes(t)||(this._typing=[...this._typing,t])}removeTyping(t){this._typing=this._typing.filter(e=>e!==t)}_sendMessage(){var t;const e=null===(t=this.shadowRoot)||void 0===t?void 0:t.querySelector(".chat-input textarea");if(!(null==e?void 0:e.value.trim()))return;const i=e.value.trim();e.value="",e.focus(),this.dispatchEvent(new CustomEvent("message-send",{detail:{text:i,replyTo:this._replyTo||void 0},bubbles:!0,composed:!0})),this._replyTo=null,this._showEmoji=!1,this._playSound()}_onInputKeydown(t){if("Enter"===t.key&&!t.shiftKey)return t.preventDefault(),void this._sendMessage();this.dispatchEvent(new CustomEvent("typing-start",{bubbles:!0,composed:!0})),clearTimeout(this._typingTimer),this._typingTimer=setTimeout(()=>{this.dispatchEvent(new CustomEvent("typing-stop",{bubbles:!0,composed:!0}))},2e3)}_toggleEmoji(){this._showEmoji=!this._showEmoji}_insertEmoji(t){var e;const i=null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector(".chat-input textarea");i&&(i.value+=t,i.focus()),this._showEmoji=!1}_menuPos(t){const e=t.closest(".msg-bubble")||t.closest(".msg-row");if(!e)return{y:0,left:0};const i=e.getBoundingClientRect(),o=!!t.closest(".msg-row.me"),s=o?140:80,n=i.top>s+12?i.top-s-4:i.bottom+4;return o?{y:n,right:Math.max(8,window.innerWidth-i.right)}:{y:n,left:Math.max(8,i.left)}}_showContextMenuHandler(t,e){t.preventDefault(),this._contextMenu=Object.assign({msgIdx:e},this._menuPos(t.target))}_onTouchStart(t,e){this._touchMoved=!1,this._longPressTimer=setTimeout(()=>{var i;t.preventDefault(),null===(i=window.getSelection())||void 0===i||i.removeAllRanges(),this._contextMenu=Object.assign({msgIdx:e},this._menuPos(t.target)),this._touchMoved=!0},500)}_onTouchEnd(){clearTimeout(this._longPressTimer)}_onTouchMove(){this._touchMoved=!0,clearTimeout(this._longPressTimer)}_onMsgTap(t,e){if(!window.matchMedia("(max-width: 640px)").matches)return;if(this._touchMoved)return;const i=t.target;i.closest(".reaction")||i.closest(".audio-play-btn")||i.closest(".file-card")||i.closest(".edit-inline")||(t.stopPropagation(),this._contextMenu=Object.assign({msgIdx:e},this._menuPos(i)))}_hideContextMenu(){this._contextMenu=null}_deleteMsg(t){const e=this.messages[t];(null==e?void 0:e.id)&&this.dispatchEvent(new CustomEvent("message-delete",{detail:{messageId:e.id},bubbles:!0,composed:!0})),this._contextMenu=null}_replyMsg(t){var e,i;const o=this.messages[t];o&&(this._replyTo={text:o.text,from:o.from},null===(i=null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector(".chat-input textarea"))||void 0===i||i.focus()),this._contextMenu=null}_editMsg(t){this._editingIdx=t,this._contextMenu=null,requestAnimationFrame(()=>{var t;const e=null===(t=this.shadowRoot)||void 0===t?void 0:t.querySelector(".edit-input");e&&(e.focus(),e.select())})}_confirmEdit(t){var e;const i=null===(e=this.shadowRoot)||void 0===e?void 0:e.querySelector(".edit-input"),o=null==i?void 0:i.value.trim();if(!o)return void(this._editingIdx=null);const s=this.messages[t];(null==s?void 0:s.id)&&this.dispatchEvent(new CustomEvent("message-edit",{detail:{messageId:s.id,content:o},bubbles:!0,composed:!0})),this._editingIdx=null}_onEditKeydown(t,e){"Enter"!==t.key||t.shiftKey?"Escape"===t.key&&(this._editingIdx=null):(t.preventDefault(),this._confirmEdit(e))}_reactMsg(t,e){const i=this.messages[t];(null==i?void 0:i.id)&&this.dispatchEvent(new CustomEvent("message-react",{detail:{messageId:i.id,emoji:e},bubbles:!0,composed:!0})),this._contextMenu=null}_toggleAudioPlay(t){var e;const i=t.currentTarget.closest(".audio-msg"),o=null==i?void 0:i.querySelector("audio");o&&(o.paused?(null===(e=this.shadowRoot)||void 0===e||e.querySelectorAll(".audio-msg audio").forEach(t=>{t===o||t.paused||(t.pause(),t.currentTime=0)}),o.play().catch(()=>{})):o.pause())}_onAudioTimeUpdate(t){const e=t.target,i=e.closest(".audio-msg");if(!i||!e.duration)return;const o=i.querySelectorAll(".a-bar"),s=e.currentTime/e.duration,n=Math.floor(s*o.length);o.forEach((t,e)=>t.classList.toggle("played",e<=n))}_onAudioEnded(t){const e=t.target.closest(".audio-msg");null==e||e.querySelectorAll(".a-bar").forEach(t=>t.classList.remove("played"))}_pickFile(t=!1){const e=document.createElement("input");e.type="file",t&&(e.accept="image/jpeg,image/png,image/gif,image/webp,image/heic,image/heif"),e.style.cssText="position:fixed;top:-9999px;left:-9999px;opacity:0",document.body.appendChild(e),e.onchange=()=>{var i;const o=null===(i=e.files)||void 0===i?void 0:i[0];o&&this.dispatchEvent(new CustomEvent("file-select",{detail:{file:o,imageOnly:t},bubbles:!0,composed:!0}));try{document.body.removeChild(e)}catch(t){}},e.click()}_playSound(){try{const t=new AudioContext,e=t.createGain();e.connect(t.destination),e.gain.value=.12;const i=t.createOscillator();i.connect(e),i.type="sine",i.frequency.setValueAtTime(600,t.currentTime),i.frequency.setValueAtTime(900,t.currentTime+.08),e.gain.exponentialRampToValueAtTime(.001,t.currentTime+.15),i.start(t.currentTime),i.stop(t.currentTime+.15),setTimeout(()=>t.close(),500)}catch(t){}}render(){return this.loading?e`<div class="loading">Loading...</div>`:e`
|
|
131
131
|
${0===this.messages.length?e`<div class="empty-state">${w}<span>${this.emptyText}</span></div>`:e`
|
|
132
|
-
<div class="chat-messages" @click=${()=>this._hideContextMenu()} @touchstart=${()=>{this._contextMenu&&this._hideContextMenu()}}>
|
|
132
|
+
<div class="chat-messages" part="messages" @click=${()=>this._hideContextMenu()} @touchstart=${()=>{this._contextMenu&&this._hideContextMenu()}}>
|
|
133
133
|
${this.messages.map((t,e,i)=>this._renderMessage(t,e,i))}
|
|
134
134
|
</div>
|
|
135
135
|
`}
|
|
@@ -137,7 +137,7 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
137
137
|
${this._contextMenu?this._renderContextMenu():o}
|
|
138
138
|
${this._typing.length>0?e`<div class="typing-indicator">${this._typing.join(", ")} typing...</div>`:o}
|
|
139
139
|
${this._replyTo?e`
|
|
140
|
-
<div class="reply-bar">
|
|
140
|
+
<div class="reply-bar" part="reply-bar">
|
|
141
141
|
<span class="reply-text">Replying to: ${this._replyTo.text}</span>
|
|
142
142
|
<button @click=${()=>{this._replyTo=null}}>✕</button>
|
|
143
143
|
</div>
|
|
@@ -159,7 +159,7 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
159
159
|
${this._editingIdx===i?e`<div class="edit-inline"><input class="edit-input" type="text" .value=${t.text||""} @keydown=${t=>this._onEditKeydown(t,i)}><button class="edit-confirm" @click=${()=>this._confirmEdit(i)}>✓</button><button class="edit-cancel" @click=${()=>{this._editingIdx=null}}>✕</button></div>`:t.text?e`<div class="msg ${t.from}">${t.text}${t.edited?e` <span class="msg-edited">(edited)</span>`:o}${t.encrypted?e`<span class="msg-e2e" title="End-to-end encrypted">🔒</span>`:o}</div>`:o}
|
|
160
160
|
<div class="msg-footer ${t.from}">
|
|
161
161
|
<span class="msg-time">${t.time||""}</span>
|
|
162
|
-
${"me"===t.from?e`<span class="msg-read">${"read"===t.status?
|
|
162
|
+
${"me"===t.from?e`<span class="msg-read">${"read"===t.status?g:"delivered"===t.status?u:p}</span>`:o}
|
|
163
163
|
</div>
|
|
164
164
|
${(null===(n=t.reactions)||void 0===n?void 0:n.length)?e`
|
|
165
165
|
<div class="msg-reactions">
|
|
@@ -186,7 +186,7 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
186
186
|
<div style="flex:1;min-width:0"><div style="font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${s.name||"File"}</div>${s.fileSize?e`<div style="font-size:10px;color:var(--text-secondary);margin-top:1px">${(s.fileSize/1024).toFixed(0)} KB</div>`:o}</div>
|
|
187
187
|
${b}
|
|
188
188
|
</a></div>`}_renderContextMenu(){const t=this._contextMenu,i=this.messages[t.msgIdx],s="me"===(null==i?void 0:i.from);return e`
|
|
189
|
-
<div class="ctx-menu" @mousedown=${t=>t.preventDefault()} @touchstart=${t=>t.stopPropagation()} style="top:${t.y}px;${null!=t.right?`right:${t.right}px`:`left:${t.left}px`}">
|
|
189
|
+
<div class="ctx-menu" part="context-menu" @mousedown=${t=>t.preventDefault()} @touchstart=${t=>t.stopPropagation()} style="top:${t.y}px;${null!=t.right?`right:${t.right}px`:`left:${t.left}px`}">
|
|
190
190
|
<div class="ctx-reactions">
|
|
191
191
|
${l.map(i=>e`<button @click=${()=>this._reactMsg(t.msgIdx,i.key)} title=${i.label}>${i.key}</button>`)}
|
|
192
192
|
</div>
|
|
@@ -195,7 +195,7 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
195
195
|
${s&&!(null==i?void 0:i.deleted)?e`<button class="danger" @click=${()=>this._deleteMsg(t.msgIdx)}>🗑 Delete</button>`:o}
|
|
196
196
|
</div>
|
|
197
197
|
`}_renderEmojiPicker(){return e`
|
|
198
|
-
<div class="emoji-picker" @mousedown=${t=>t.preventDefault()}>
|
|
198
|
+
<div class="emoji-picker" part="emoji-picker" @mousedown=${t=>t.preventDefault()}>
|
|
199
199
|
<div class="emoji-quick">
|
|
200
200
|
${l.map(t=>e`<button @click=${()=>this._insertEmoji(t.key)} title=${t.label}>${t.key}</button>`)}
|
|
201
201
|
</div>
|
|
@@ -204,13 +204,13 @@ import{css as t,html as e,LitElement as i,nothing as o}from"lit";import{property
|
|
|
204
204
|
</div>
|
|
205
205
|
</div>
|
|
206
206
|
`}_renderInputBar(){return e`
|
|
207
|
-
<div class="chat-input">
|
|
208
|
-
<div class="input-tools">
|
|
207
|
+
<div class="chat-input" part="input">
|
|
208
|
+
<div class="input-tools" part="input-tools">
|
|
209
209
|
<button @click=${()=>this._pickFile()} title="Attach file">${k}</button>
|
|
210
210
|
<button @click=${()=>this._pickFile(!0)} title="Send image">${$}</button>
|
|
211
211
|
<button @click=${()=>this._toggleEmoji()} title="Emoji">${x}</button>
|
|
212
212
|
</div>
|
|
213
|
-
<textarea rows="1" placeholder="Type a message..." @keydown=${t=>this._onInputKeydown(t)}></textarea>
|
|
214
|
-
<button class="send-btn" @mousedown=${t=>t.preventDefault()} @click=${()=>this._sendMessage()} title="Send">${h}</button>
|
|
213
|
+
<textarea rows="1" placeholder="Type a message..." part="textarea" @keydown=${t=>this._onInputKeydown(t)}></textarea>
|
|
214
|
+
<button class="send-btn" part="send-button" @mousedown=${t=>t.preventDefault()} @click=${()=>this._sendMessage()} title="Send">${h}</button>
|
|
215
215
|
</div>
|
|
216
216
|
`}};j.styles=r,d([s({type:Array})],j.prototype,"messages",void 0),d([s({type:Object})],j.prototype,"currentUser",void 0),d([s({type:String,attribute:"conversation-id"})],j.prototype,"conversationId",void 0),d([s({type:Boolean})],j.prototype,"isGroup",void 0),d([s({type:Boolean})],j.prototype,"loading",void 0),d([s({type:Boolean,reflect:!0})],j.prototype,"compact",void 0),d([s({type:String,attribute:"empty-text"})],j.prototype,"emptyText",void 0),d([s({type:Boolean,attribute:"hide-input"})],j.prototype,"hideInput",void 0),d([n()],j.prototype,"_showEmoji",void 0),d([n()],j.prototype,"_contextMenu",void 0),d([n()],j.prototype,"_replyTo",void 0),d([n()],j.prototype,"_editingIdx",void 0),d([n()],j.prototype,"_typing",void 0),j=d([a("nr-chat-panel")],j);export{j as NrChatPanelElement};
|
|
Binary file
|
|
@@ -328,7 +328,7 @@ let NrChatPanelElement = class NrChatPanelElement extends LitElement {
|
|
|
328
328
|
${this.messages.length === 0
|
|
329
329
|
? html `<div class="empty-state">${svgChat}<span>${this.emptyText}</span></div>`
|
|
330
330
|
: html `
|
|
331
|
-
<div class="chat-messages" @click=${() => this._hideContextMenu()} @touchstart=${() => { if (this._contextMenu)
|
|
331
|
+
<div class="chat-messages" part="messages" @click=${() => this._hideContextMenu()} @touchstart=${() => { if (this._contextMenu)
|
|
332
332
|
this._hideContextMenu(); }}>
|
|
333
333
|
${this.messages.map((m, i, arr) => this._renderMessage(m, i, arr))}
|
|
334
334
|
</div>
|
|
@@ -337,7 +337,7 @@ let NrChatPanelElement = class NrChatPanelElement extends LitElement {
|
|
|
337
337
|
${this._contextMenu ? this._renderContextMenu() : nothing}
|
|
338
338
|
${this._typing.length > 0 ? html `<div class="typing-indicator">${this._typing.join(', ')} typing...</div>` : nothing}
|
|
339
339
|
${this._replyTo ? html `
|
|
340
|
-
<div class="reply-bar">
|
|
340
|
+
<div class="reply-bar" part="reply-bar">
|
|
341
341
|
<span class="reply-text">Replying to: ${this._replyTo.text}</span>
|
|
342
342
|
<button @click=${() => { this._replyTo = null; }}>✕</button>
|
|
343
343
|
</div>
|
|
@@ -427,7 +427,7 @@ let NrChatPanelElement = class NrChatPanelElement extends LitElement {
|
|
|
427
427
|
const msg = this.messages[cm.msgIdx];
|
|
428
428
|
const isMe = (msg === null || msg === void 0 ? void 0 : msg.from) === 'me';
|
|
429
429
|
return html `
|
|
430
|
-
<div class="ctx-menu" @mousedown=${(e) => e.preventDefault()} @touchstart=${(e) => e.stopPropagation()} style="top:${cm.y}px;${cm.right != null ? `right:${cm.right}px` : `left:${cm.left}px`}">
|
|
430
|
+
<div class="ctx-menu" part="context-menu" @mousedown=${(e) => e.preventDefault()} @touchstart=${(e) => e.stopPropagation()} style="top:${cm.y}px;${cm.right != null ? `right:${cm.right}px` : `left:${cm.left}px`}">
|
|
431
431
|
<div class="ctx-reactions">
|
|
432
432
|
${REACTIONS.map(r => html `<button @click=${() => this._reactMsg(cm.msgIdx, r.key)} title=${r.label}>${r.key}</button>`)}
|
|
433
433
|
</div>
|
|
@@ -439,7 +439,7 @@ let NrChatPanelElement = class NrChatPanelElement extends LitElement {
|
|
|
439
439
|
}
|
|
440
440
|
_renderEmojiPicker() {
|
|
441
441
|
return html `
|
|
442
|
-
<div class="emoji-picker" @mousedown=${(e) => e.preventDefault()}>
|
|
442
|
+
<div class="emoji-picker" part="emoji-picker" @mousedown=${(e) => e.preventDefault()}>
|
|
443
443
|
<div class="emoji-quick">
|
|
444
444
|
${REACTIONS.map(r => html `<button @click=${() => this._insertEmoji(r.key)} title=${r.label}>${r.key}</button>`)}
|
|
445
445
|
</div>
|
|
@@ -451,14 +451,14 @@ let NrChatPanelElement = class NrChatPanelElement extends LitElement {
|
|
|
451
451
|
}
|
|
452
452
|
_renderInputBar() {
|
|
453
453
|
return html `
|
|
454
|
-
<div class="chat-input">
|
|
455
|
-
<div class="input-tools">
|
|
454
|
+
<div class="chat-input" part="input">
|
|
455
|
+
<div class="input-tools" part="input-tools">
|
|
456
456
|
<button @click=${() => this._pickFile()} title="Attach file">${svgAttach}</button>
|
|
457
457
|
<button @click=${() => this._pickFile(true)} title="Send image">${svgImage}</button>
|
|
458
458
|
<button @click=${() => this._toggleEmoji()} title="Emoji">${svgSmile}</button>
|
|
459
459
|
</div>
|
|
460
|
-
<textarea rows="1" placeholder="Type a message..." @keydown=${(e) => this._onInputKeydown(e)}></textarea>
|
|
461
|
-
<button class="send-btn" @mousedown=${(e) => e.preventDefault()} @click=${() => this._sendMessage()} title="Send">${svgSend}</button>
|
|
460
|
+
<textarea rows="1" placeholder="Type a message..." part="textarea" @keydown=${(e) => this._onInputKeydown(e)}></textarea>
|
|
461
|
+
<button class="send-btn" part="send-button" @mousedown=${(e) => e.preventDefault()} @click=${() => this._sendMessage()} title="Send">${svgSend}</button>
|
|
462
462
|
</div>
|
|
463
463
|
`;
|
|
464
464
|
}
|