@aws/mynah-ui 4.22.1 → 4.23.0-beta.10

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.
Files changed (34) hide show
  1. package/dist/components/chat-item/chat-item-card.d.ts +3 -0
  2. package/dist/components/chat-item/chat-item-form-items.d.ts +1 -0
  3. package/dist/components/chat-item/chat-item-tree-view-wrapper.d.ts +5 -0
  4. package/dist/components/chat-item/chat-item-tree-view.d.ts +6 -0
  5. package/dist/components/chat-item/chat-prompt-input.d.ts +2 -1
  6. package/dist/components/chat-item/prompt-input/prompt-input-quick-pick-item.d.ts +13 -0
  7. package/dist/components/chat-item/prompt-input/prompt-input-quick-pick-selector.d.ts +18 -0
  8. package/dist/components/chat-item/prompt-input/prompt-text-input.d.ts +17 -16
  9. package/dist/components/form-items/radio-group.d.ts +1 -0
  10. package/dist/components/form-items/select.d.ts +1 -0
  11. package/dist/components/form-items/stars.d.ts +1 -0
  12. package/dist/components/form-items/text-area.d.ts +14 -0
  13. package/dist/components/form-items/text-input.d.ts +14 -0
  14. package/dist/components/icon.d.ts +2 -1
  15. package/dist/components/title-description-with-icon.d.ts +2 -2
  16. package/dist/helper/quick-pick-data-handler.d.ts +4 -0
  17. package/dist/helper/serialize-chat.d.ts +12 -0
  18. package/dist/helper/test-ids.d.ts +2 -0
  19. package/dist/helper/validator.d.ts +19 -0
  20. package/dist/main.d.ts +14 -2
  21. package/dist/main.js +1 -1
  22. package/dist/main.js.map +1 -1
  23. package/dist/static.d.ts +57 -23
  24. package/docs/DATAMODEL.md +49 -0
  25. package/docs/PROPERTIES.md +47 -0
  26. package/docs/STARTUP.md +1 -0
  27. package/docs/USAGE.md +20 -0
  28. package/docs/img/data-model/chatItems/header.png +0 -0
  29. package/package.json +1 -1
  30. package/ui-tests/dist/27f62b53b93858475a7f.ttf +0 -0
  31. package/ui-tests/dist/d50a80138ec4f2fb5e9f.ttf +0 -0
  32. package/ui-tests/dist/index.html +0 -9
  33. package/ui-tests/dist/main.js +0 -1359
  34. package/ui-tests/dist/main.js.map +0 -1
package/dist/static.d.ts CHANGED
@@ -2,18 +2,23 @@
2
2
  * Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { MynahIcons } from './components/icon';
5
+ import { MynahIcons, MynahIconsType } from './components/icon';
6
6
  import { ChatItemBodyRenderer } from './helper/dom';
7
7
  import { SelectAbstract, SelectProps, RadioGroupAbstract, RadioGroupProps, ButtonAbstract, ButtonProps, TextInputProps, TextInputAbstract, TextAreaProps, TextAreaAbstract, ToggleOption } from './main';
8
8
  export interface QuickActionCommand {
9
9
  command: string;
10
+ id?: string;
11
+ label?: string;
10
12
  disabled?: boolean;
11
- icon?: MynahIcons;
13
+ icon?: MynahIcons | MynahIconsType;
12
14
  description?: string;
13
15
  placeholder?: string;
16
+ children?: QuickActionCommandGroup[];
17
+ route?: string[];
14
18
  }
15
19
  export interface QuickActionCommandGroup {
16
20
  groupName?: string;
21
+ actions?: Action[];
17
22
  commands: QuickActionCommand[];
18
23
  }
19
24
  /**
@@ -145,6 +150,7 @@ export declare enum MynahEventNames {
145
150
  CHAT_ITEM_ADD = "chatItemAdd",
146
151
  FOLLOW_UP_CLICKED = "followUpClicked",
147
152
  BODY_ACTION_CLICKED = "bodyActionClicked",
153
+ QUICK_COMMAND_GROUP_ACTION_CLICK = "quickCommandGroupActionClicked",
148
154
  TABBED_CONTENT_SWITCH = "tabbedContentSwitch",
149
155
  SHOW_MORE_WEB_RESULTS_CLICK = "showMoreWebResultsClick",
150
156
  SHOW_FEEDBACK_FORM = "showFeedbackForm",
@@ -152,11 +158,13 @@ export declare enum MynahEventNames {
152
158
  FILE_ACTION_CLICK = "fileActionClick",
153
159
  TAB_FOCUS = "tabFocus",
154
160
  CUSTOM_FORM_ACTION_CLICK = "customFormActionClick",
161
+ FORM_MODIFIER_ENTER_PRESS = "formModifierEnterPress",
155
162
  ADD_ATTACHMENT = "addAttachment",
156
163
  REMOVE_ATTACHMENT = "removeAttachment",
157
164
  TAB_BAR_BUTTON_CLICK = "tabBarButtonClick",
158
165
  PROMPT_PROGRESS_ACTION_CLICK = "promptProgressActionClick",
159
- ROOT_RESIZE = "rootResize"
166
+ ROOT_RESIZE = "rootResize",
167
+ CONTEXT_SELECTED = "contextSelected"
160
168
  }
161
169
  export declare enum MynahPortalNames {
162
170
  WRAPPER = "wrapper",
@@ -216,12 +224,13 @@ export interface ProgressField {
216
224
  }
217
225
  export interface TreeNodeDetails {
218
226
  status?: Status;
219
- icon?: MynahIcons;
227
+ icon?: MynahIcons | MynahIconsType;
220
228
  label?: string;
221
229
  description?: string;
222
230
  clickable?: boolean;
223
231
  }
224
232
  export interface ChatItemContent {
233
+ header?: ChatItemContent | null;
225
234
  body?: string | null;
226
235
  customRenderer?: string | ChatItemBodyRenderer | ChatItemBodyRenderer[] | null;
227
236
  followUp?: {
@@ -238,6 +247,10 @@ export interface ChatItemContent {
238
247
  rootFolderTitle?: string;
239
248
  filePaths?: string[];
240
249
  deletedFiles?: string[];
250
+ flatList?: boolean;
251
+ folderIcon?: MynahIcons | MynahIconsType | null;
252
+ collapsed?: boolean;
253
+ hideFileCount?: boolean;
241
254
  actions?: Record<string, FileNodeAction[]>;
242
255
  details?: Record<string, TreeNodeDetails>;
243
256
  } | null;
@@ -251,11 +264,11 @@ export interface ChatItemContent {
251
264
  title?: string;
252
265
  status?: {
253
266
  status?: Status;
254
- icon?: MynahIcons;
267
+ icon?: MynahIcons | MynahIconsType;
255
268
  body?: string;
256
269
  };
257
270
  description?: string;
258
- icon?: MynahIcons;
271
+ icon?: MynahIcons | MynahIconsType;
259
272
  content: ChatItemContent;
260
273
  } | null;
261
274
  tabbedContent?: Array<ToggleOption & {
@@ -268,27 +281,51 @@ export interface ChatItem extends ChatItemContent {
268
281
  messageId?: string;
269
282
  snapToTop?: boolean;
270
283
  canBeVoted?: boolean;
271
- icon?: MynahIcons;
284
+ icon?: MynahIcons | MynahIconsType;
272
285
  hoverEffect?: boolean;
273
286
  status?: Status;
274
287
  }
275
- export interface ChatItemFormItem {
288
+ export interface ValidationPattern {
289
+ pattern: string | RegExp;
290
+ errorMessage?: string;
291
+ }
292
+ interface BaseFormItem {
276
293
  id: string;
277
- type: 'select' | 'textarea' | 'textinput' | 'numericinput' | 'stars' | 'radiogroup' | 'email';
278
294
  mandatory?: boolean;
279
295
  title?: string;
280
296
  placeholder?: string;
281
297
  value?: string;
298
+ description?: string;
299
+ }
300
+ export type TextBasedFormItem = BaseFormItem & {
301
+ type: 'textarea' | 'textinput' | 'numericinput' | 'email';
302
+ checkModifierEnterKeyPress?: boolean;
303
+ validationPatterns?: {
304
+ operator?: 'and' | 'or';
305
+ genericValidationErrorMessage?: string;
306
+ patterns: ValidationPattern[];
307
+ };
308
+ };
309
+ type SelectFormItem = BaseFormItem & {
310
+ type: 'select';
311
+ options: Array<{
312
+ value: string;
313
+ label: string;
314
+ }>;
315
+ };
316
+ type OtherFormItem = BaseFormItem & {
317
+ type: 'stars' | 'radiogroup';
282
318
  options?: Array<{
283
319
  value: string;
284
320
  label: string;
285
321
  }>;
286
- }
322
+ };
323
+ export type ChatItemFormItem = TextBasedFormItem | SelectFormItem | OtherFormItem;
287
324
  export interface ChatPrompt {
288
325
  prompt?: string;
289
326
  escapedPrompt?: string;
290
327
  command?: string;
291
- context?: string[];
328
+ context?: string[] | QuickActionCommand[];
292
329
  }
293
330
  export interface ChatItemAction extends ChatPrompt {
294
331
  type?: string;
@@ -296,28 +333,25 @@ export interface ChatItemAction extends ChatPrompt {
296
333
  disabled?: boolean;
297
334
  description?: string;
298
335
  status?: 'primary' | Status;
299
- icon?: MynahIcons;
336
+ icon?: MynahIcons | MynahIconsType;
300
337
  }
301
- export interface ChatItemButton {
338
+ export interface ChatItemButton extends Omit<Action, 'status'> {
302
339
  keepCardAfterClick?: boolean;
303
340
  waitMandatoryFormItems?: boolean;
304
- text: string;
305
- id: string;
306
- disabled?: boolean;
307
- description?: string;
308
341
  status?: 'main' | 'primary' | 'clear' | Status;
309
342
  flash?: 'infinite' | 'once';
310
343
  fillState?: 'hover' | 'always';
311
- icon?: MynahIcons;
312
344
  position?: 'inside' | 'outside';
313
345
  }
314
- export interface TabBarAction {
346
+ export interface Action {
315
347
  text?: string;
316
348
  id: string;
317
349
  disabled?: boolean;
318
350
  description?: string;
319
351
  status?: Status;
320
- icon?: MynahIcons;
352
+ icon?: MynahIcons | MynahIconsType;
353
+ }
354
+ export interface TabBarAction extends Action {
321
355
  }
322
356
  export interface TabBarMainAction extends TabBarAction {
323
357
  items?: TabBarAction[];
@@ -328,7 +362,7 @@ export interface FileNodeAction {
328
362
  disabled?: boolean;
329
363
  description?: string;
330
364
  status?: Status;
331
- icon: MynahIcons;
365
+ icon: MynahIcons | MynahIconsType;
332
366
  }
333
367
  export declare enum KeyMap {
334
368
  ESCAPE = "Escape",
@@ -421,7 +455,7 @@ export declare enum NotificationType {
421
455
  ERROR = "error"
422
456
  }
423
457
  export interface TabHeaderDetails {
424
- icon?: MynahIcons;
458
+ icon?: MynahIcons | MynahIconsType;
425
459
  title?: string;
426
460
  description?: string;
427
461
  }
@@ -429,7 +463,7 @@ export interface CodeBlockAction {
429
463
  id: 'copy' | 'insert-to-cursor' | string;
430
464
  label: string;
431
465
  description?: string;
432
- icon?: MynahIcons;
466
+ icon?: MynahIcons | MynahIconsType;
433
467
  data?: any;
434
468
  flash?: 'infinite' | 'once';
435
469
  acceptedLanguages?: string[];
package/docs/DATAMODEL.md CHANGED
@@ -868,6 +868,7 @@ type CodeBlockActions = Record<'copy' | 'insert-to-cursor' | string, CodeBlockAc
868
868
 
869
869
  // #################################
870
870
  interface ChatItemContent {
871
+ header?: ChatItemContent | null;
871
872
  body?: string | null;
872
873
  customRenderer?: string | ChatItemBodyRenderer | ChatItemBodyRenderer[] | null;
873
874
  followUp?: {
@@ -884,6 +885,9 @@ interface ChatItemContent {
884
885
  rootFolderTitle?: string;
885
886
  filePaths?: string[];
886
887
  deletedFiles?: string[];
888
+ flatList?: boolean;
889
+ collapsed?: boolean;
890
+ hideFileCount?: boolean;
887
891
  actions?: Record<string, FileNodeAction[]>;
888
892
  details?: Record<string, TreeNodeDetails>;
889
893
  } | null;
@@ -1075,6 +1079,43 @@ mynahUI.addChatItem('tab-1', {
1075
1079
 
1076
1080
  ---
1077
1081
 
1082
+ ## `header`
1083
+ With this parameter, you can add a `ChatItem` at the top of a ChatItem, before the body, but still within the card itself.
1084
+
1085
+ ```typescript
1086
+ const mynahUI = new MynahUI({
1087
+ tabs: {
1088
+ 'tab-1': {
1089
+ ...
1090
+ }
1091
+ }
1092
+ });
1093
+
1094
+ mynahUI.addChatItem(tabId, {
1095
+ type: ChatItemType.ANSWER,
1096
+ body: `SOME CONTENT`,
1097
+ header: {
1098
+ fileList: { // For example, want to show which file is used to generate that answer
1099
+ rootFolderTitle: undefined,
1100
+ fileTreeTitle: '',
1101
+ filePaths: ['./src/index.ts'],
1102
+ details: {
1103
+ './src/index.ts': {
1104
+ icon: MynahIcons.FILE,
1105
+ description: `SOME DESCRIPTION.`
1106
+ }
1107
+ }
1108
+ }
1109
+ }
1110
+ });
1111
+ ```
1112
+
1113
+ <p align="center">
1114
+ <img src="./img/data-model/chatItems/header.png" alt="header" style="max-width:600px; width:100%;border: 1px solid #e0e0e0;">
1115
+ </p>
1116
+
1117
+ ---
1118
+
1078
1119
  ## `body`
1079
1120
  Basically the body of the card. Which you can send a full markdown string. Allows code blocks, links etc.
1080
1121
 
@@ -1732,6 +1773,9 @@ mynahUI.addChatItem(tabId, {
1732
1773
  deletedFiles: ['src/devfile.yaml'],
1733
1774
  // fileTreeTitle: "Custom file tree card title";
1734
1775
  // rootFolderTitle: "Custom root folder title";
1776
+ // collapsed: true // Collapse the root folder by default
1777
+ // hideFileCount: true // Hide the file counter next to folders
1778
+ // flatList: true // Enable to generate a flat list with one parent folder and no sub folders
1735
1779
  actions: {
1736
1780
  'src/App.tsx': [
1737
1781
  {
@@ -1776,6 +1820,8 @@ mynahUI.addChatItem(tabId, {
1776
1820
 
1777
1821
  **NOTE 3:** In case you want to show one single file (or folder by giving it a folder icon) and not make it clickable, use the `details` section with the file name and set the `clickable` to `false`.
1778
1822
 
1823
+ **NOTE 4:** In case you want a flat list, where all subfolders are not rendered but just all the files, you can pass `true` to the `flatList` prop.
1824
+
1779
1825
  <p align="center">
1780
1826
  <img src="./img/data-model/chatItems/codeResult.png" alt="mainTitle" style="max-width:500px; width:100%;border: 1px solid #e0e0e0;">
1781
1827
  </p>
@@ -2034,8 +2080,10 @@ interface ChatItemFormItem {
2034
2080
  type: 'select' | 'textarea' | 'textinput' | 'numericinput' | 'stars' | 'radiogroup'; // type (see below for each of them)
2035
2081
  mandatory?: boolean; // If it is set to true, buttons in the same card with waitMandatoryFormItems set to true will wait them to be filled
2036
2082
  title?: string; // Label of the input
2083
+ description?: string; // The description, showing under the input field itself
2037
2084
  placeholder?: string; // Placeholder for input, but only applicable to textarea, textinput and numericinput
2038
2085
  value?: string; // Initial value of the item. All types of form items will get and return string values, conversion of the value type is up to you
2086
+ checkModifierEnterKeyPress?: boolean; // Only applicable to textual inputs: whether the onFormModifierEnterPress event can be triggered from this input field
2039
2087
  options?: Array<{ // Only applicable to select and radiogroup types
2040
2088
  value: string;
2041
2089
  label: string;
@@ -2122,6 +2170,7 @@ mynahUI.addChatItem(tabId, {
2122
2170
  mandatory: true,
2123
2171
  title: `Email`,
2124
2172
  placeholder: 'email',
2173
+ checkModifierEnterKeyPress: true
2125
2174
  },
2126
2175
  {
2127
2176
  id: 'name',
@@ -45,6 +45,9 @@ export interface MynahUIProps {
45
45
  onTabAdd?: (
46
46
  tabId: string,
47
47
  eventId?: string) => void;
48
+ onContextSelected?: (
49
+ contextItem: QuickActionCommand,
50
+ ) => boolean;
48
51
  onTabRemove?: (
49
52
  tabId: string,
50
53
  eventId?: string) => void;
@@ -115,6 +118,10 @@ export interface MynahUIProps {
115
118
  tabId: string,
116
119
  feedbackPayload: FeedbackPayload,
117
120
  eventId?: string) => void;
121
+ onFormModifierEnterPress?: (
122
+ formData: Record<string, string>,
123
+ tabId: string,
124
+ eventId?: string) => void;
118
125
  onCustomFormAction?: (
119
126
  tabId: string,
120
127
  action: {
@@ -512,6 +519,26 @@ onTabAdd?: (tabId: string):void => {
512
519
 
513
520
  ---
514
521
 
522
+ ### `onContextSelected`
523
+
524
+ This event will be fired whenever a user selects an item from the context (`@`) list either using mouse click or keyboard actions. It is only triggered for items without children, i.e. only leaves in the tree. The data of the selected context item can be accessed through the `contextItem`. This event handler expects a boolean return:
525
+ - Returning `true` indicates that the context item should be added to the prompt input text.
526
+ - Returning `false` indicates that nothing should be added to the prompt input, and the triggering string should be cleared. E.g. if a user types `@wor` and presses tab on the `@workspace` action, the `@wor` would be removed from the prompt input and no context item will be added.
527
+
528
+ ```typescript
529
+ ...
530
+ onContextSelected(contextItem: QuickActionCommand) {
531
+ if (contextItem.command === 'Add Prompt') {
532
+ Log('Custom context action triggered for adding a prompt!')
533
+ return false;
534
+ }
535
+ return true;
536
+ },
537
+ ...
538
+ ```
539
+
540
+ ---
541
+
515
542
  ### `onBeforeTabRemove`
516
543
 
517
544
  This event will be fired when user clicks the close button but before actually closing the tab. You have **partial control over the tab close**. If you return false to this function, it will not immediately close the tab and will ask an approval from the user. Otherwise it will close the tab. You can set the texts which will be appeared on the confirmation overlay on **[Config/TEXTS](./CONFIG.md#texts)**. It will only pass `tabId` for the closed tab as argument.
@@ -826,6 +853,26 @@ onSendFeedback?: (
826
853
  };
827
854
  ...
828
855
  ```
856
+
857
+ ---
858
+
859
+ ### `onFormModifierEnterPress`
860
+
861
+ This event will be fired when the user presses the modifier key (`cmd` on macOS, and `ctrl` on Windows / Linux) and the `enter` key at the same time, while focused on a textual form input field. The event will only be triggered for input fields that have set `checkModifierEnterKeyPress: true`, and it will only be triggered if the form is valid and can be submitted. An example use case for this would be submitting the form through a keyboard hotkey action.
862
+
863
+ ```typescript
864
+ ...
865
+ onFormModifierEnterPress?: (
866
+ formData: Record<string, string>,
867
+ tabId: string,
868
+ eventId?: string): void => {
869
+ console.log(`Form modifier enter pressed on tab <b>${tabId}</b>:<br/>
870
+ Form data: <b>${JSON.stringify(formData)}</b><br/>
871
+ `);
872
+ },
873
+ ...
874
+ ```
875
+
829
876
  ---
830
877
 
831
878
  ### `onCustomFormAction`
package/docs/STARTUP.md CHANGED
@@ -28,6 +28,7 @@ const mynahUI = new MynahUI({
28
28
  onBodyActionClicked: ...,
29
29
  onTabChange: ...,
30
30
  onTabAdd: ...,
31
+ onContextSelected: ...,
31
32
  onTabRemove: ...,
32
33
  onChatItemEngagement: ...,
33
34
  onCopyCodeToClipboard: ...,
package/docs/USAGE.md CHANGED
@@ -18,6 +18,7 @@ mynahUI.addToUserPrompt(...);
18
18
  mynahUI.updateLastChatAnswer(...);
19
19
  mynahUI.updateChatAnswerWithMessageId(...);
20
20
  mynahUI.endMessageStream(...);
21
+ mynahUI.serializeChat(...);
21
22
  mynahUI.updateStore(...);
22
23
  mynahUI.selectTab(...);
23
24
  mynahUI.removeTab(...);
@@ -390,6 +391,25 @@ Can you end stream for a card you already ended the stream? Basically yes becaus
390
391
 
391
392
  ---
392
393
 
394
+ ## Serializing a chat (`serializeChat`)
395
+
396
+ You can serialize an entire chat from a specific tab using this function. Only the card bodies will be included, meaning that buttons and other interactable components are left out. There are two output options for the serialization:
397
+ - **Markdown:** get all the bodies from chat items in markdown format so that it serves as the contents of a valid `.md` file. Each card body is separated by `\n\n---\n\n`.
398
+ - **HTML:** get a string which serves as the contents of a valid `.html` file. It consists of a centered chat container, containing all the chat item bodies in cards. All the relevant stylesheets from MynahUI are included in the `<style>` section of the string.
399
+
400
+ The following example shows how serialization could be used to download an export of a tab's chat:
401
+ ```typescript
402
+ const serializedChat = mynahUI.serializeChat(tabId, 'markdown')
403
+ const blob = new Blob([serializedChat], { type: 'text/plain' });
404
+ const url = URL.createObjectURL(blob);
405
+ const link = document.createElement('a');
406
+ link.download = 'exported-chat.md';
407
+ link.href = url;
408
+ link.click();
409
+ ```
410
+
411
+ ---
412
+
393
413
  ## Adding code attachments to prompt field (`addToUserPrompt`)
394
414
 
395
415
  You can add code attachments under the prompt field of the desired tab. When user fills the prompt field and sends it, the attached code block will be appended at the end of the prompt text. It accepts max chars set through **[CONFIG](./CONFIG.md#maxUserInput)** however you don't need to worry about it. MynahUI will automatically crop it depending on the available chars left from the prompt field itself by using a `96` chars of threshold. **So beware that for example if you want 4000 chars exact, you need to give 4096 to the config.**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aws/mynah-ui",
3
3
  "displayName": "AWS Mynah UI",
4
- "version": "4.22.1",
4
+ "version": "4.23.0-beta.10",
5
5
  "description": "AWS Toolkit VSCode and Intellij IDE Extension Mynah UI",
6
6
  "publisher": "Amazon Web Services",
7
7
  "license": "Apache License 2.0",
@@ -1,9 +0,0 @@
1
- <html theme="base-light">
2
- <head>
3
- <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1" />
4
- <script defer src="main.js"></script></head>
5
-
6
- <body>
7
- <div id="mynah-ui-wrapper"></div>
8
- </body>
9
- </html>