web-mojo 2.2.8 → 2.2.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 (54) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.cjs.js.map +1 -1
  3. package/dist/admin.es.js +8296 -7415
  4. package/dist/admin.es.js.map +1 -1
  5. package/dist/auth.cjs.js +1 -1
  6. package/dist/auth.es.js +1 -1
  7. package/dist/charts.cjs.js +1 -1
  8. package/dist/charts.es.js +3 -3
  9. package/dist/chunks/{ChatView-DfKH7ep8.js → ChatView-BxIeRwBQ.js} +2 -2
  10. package/dist/chunks/{ChatView-DfKH7ep8.js.map → ChatView-BxIeRwBQ.js.map} +1 -1
  11. package/dist/chunks/{ChatView-2mFEGsXL.js → ChatView-DfhhZKoN.js} +3 -3
  12. package/dist/chunks/{ChatView-2mFEGsXL.js.map → ChatView-DfhhZKoN.js.map} +1 -1
  13. package/dist/chunks/{Dialog-DrCs-ex1.js → Dialog-Cu_Dx46k.js} +3 -3
  14. package/dist/chunks/{Dialog-DrCs-ex1.js.map → Dialog-Cu_Dx46k.js.map} +1 -1
  15. package/dist/chunks/{Dialog-BBZUgBbz.js → Dialog-DX5h2QA9.js} +2 -2
  16. package/dist/chunks/{Dialog-BBZUgBbz.js.map → Dialog-DX5h2QA9.js.map} +1 -1
  17. package/dist/chunks/{FormView-CwYt4vH3.js → FormView-B_90L1RY.js} +284 -26
  18. package/dist/chunks/FormView-B_90L1RY.js.map +1 -0
  19. package/dist/chunks/FormView-Bwofbd8S.js +3 -0
  20. package/dist/chunks/FormView-Bwofbd8S.js.map +1 -0
  21. package/dist/chunks/{MetricsMiniChartWidget-DdZ3zNve.js → MetricsMiniChartWidget-DL5stA6A.js} +139 -58
  22. package/dist/chunks/MetricsMiniChartWidget-DL5stA6A.js.map +1 -0
  23. package/dist/chunks/MetricsMiniChartWidget-vXr5pxpm.js +2 -0
  24. package/dist/chunks/MetricsMiniChartWidget-vXr5pxpm.js.map +1 -0
  25. package/dist/chunks/{PDFViewer-CkKC_E0G.js → PDFViewer--jlqnuVw.js} +2 -2
  26. package/dist/chunks/{PDFViewer-CkKC_E0G.js.map → PDFViewer--jlqnuVw.js.map} +1 -1
  27. package/dist/chunks/{PDFViewer-DaiTPsQH.js → PDFViewer-DSmi78S6.js} +2 -2
  28. package/dist/chunks/{PDFViewer-DaiTPsQH.js.map → PDFViewer-DSmi78S6.js.map} +1 -1
  29. package/dist/chunks/{TokenManager-D9z35vwT.js → TokenManager-CEOPgnsw.js} +2 -2
  30. package/dist/chunks/{TokenManager-D9z35vwT.js.map → TokenManager-CEOPgnsw.js.map} +1 -1
  31. package/dist/chunks/{TokenManager-XwKaWaKd.js → TokenManager-DiQfilqw.js} +2 -2
  32. package/dist/chunks/{TokenManager-XwKaWaKd.js.map → TokenManager-DiQfilqw.js.map} +1 -1
  33. package/dist/chunks/{version-BQcvJscT.js → version-DOHckOGK.js} +4 -4
  34. package/dist/chunks/version-DOHckOGK.js.map +1 -0
  35. package/dist/chunks/version-DUvrBxZl.js +2 -0
  36. package/dist/chunks/version-DUvrBxZl.js.map +1 -0
  37. package/dist/core.css +65 -0
  38. package/dist/css/web-mojo.css +1 -1
  39. package/dist/docit.cjs.js +1 -1
  40. package/dist/docit.es.js +3 -3
  41. package/dist/index.cjs.js +1 -1
  42. package/dist/index.es.js +7 -7
  43. package/dist/lightbox.cjs.js +1 -1
  44. package/dist/lightbox.es.js +4 -4
  45. package/package.json +1 -1
  46. package/dist/chunks/FormView-CNkSOc2U.js +0 -3
  47. package/dist/chunks/FormView-CNkSOc2U.js.map +0 -1
  48. package/dist/chunks/FormView-CwYt4vH3.js.map +0 -1
  49. package/dist/chunks/MetricsMiniChartWidget-B3PHrgkn.js +0 -2
  50. package/dist/chunks/MetricsMiniChartWidget-B3PHrgkn.js.map +0 -1
  51. package/dist/chunks/MetricsMiniChartWidget-DdZ3zNve.js.map +0 -1
  52. package/dist/chunks/version-BQcvJscT.js.map +0 -1
  53. package/dist/chunks/version-DhSPKHUm.js +0 -2
  54. package/dist/chunks/version-DhSPKHUm.js.map +0 -1
@@ -2168,50 +2168,38 @@ class FormBuilder {
2168
2168
  name,
2169
2169
  label,
2170
2170
  value = "",
2171
- placeholder = "Select or type...",
2172
- options = [],
2173
2171
  required = false,
2174
2172
  disabled = false,
2175
- readonly = false,
2176
- allowCustom = true,
2177
- showDescription = true,
2178
- minChars = 0,
2179
- maxSuggestions = 10,
2173
+ maxHeight = 300,
2180
2174
  help = field.helpText || field.help || ""
2181
2175
  } = field;
2182
- const fieldId = this.getFieldId(name);
2176
+ const placeholder = field.placeholder || field.placeHolder || "Type or select...";
2177
+ const allowCustom = field.allowCustom !== false;
2178
+ this.getFieldId(name);
2183
2179
  const error = this.errors[name];
2184
- const fieldValue = this.getFieldValue(name) ?? value;
2180
+ const fieldValue = field.value ?? this.getFieldValue(name) ?? value;
2185
2181
  return `
2186
2182
  <div class="mojo-form-control">
2187
- ${label ? `<label for="${fieldId}" class="${this.options.labelClass}">${this.escapeHtml(label)}${required ? '<span class="text-danger">*</span>' : ""}</label>` : ""}
2188
- <div class="combo-input-placeholder"
2183
+ ${label ? `<label class="${this.options.labelClass}">${this.escapeHtml(label)}${required ? '<span class="text-danger">*</span>' : ""}</label>` : ""}
2184
+ <div class="combobox-placeholder"
2189
2185
  data-field-name="${name}"
2190
- data-field-type="combo"
2186
+ data-field-type="combobox"
2191
2187
  data-field-config='${JSON.stringify({
2192
2188
  name,
2193
2189
  value: fieldValue,
2194
2190
  placeholder,
2195
- options,
2191
+ maxHeight,
2196
2192
  allowCustom,
2197
- showDescription,
2198
- minChars,
2199
- maxSuggestions,
2200
2193
  disabled,
2201
- readonly,
2202
2194
  required
2203
2195
  })}'>
2204
- <input type="text"
2205
- id="${fieldId}"
2206
- name="${name}_display"
2207
- class="${this.options.inputClass}${error ? " is-invalid" : ""}"
2208
- placeholder="${this.escapeHtml(placeholder)}"
2196
+ <input type="text"
2197
+ class="form-control${error ? " is-invalid" : ""}"
2209
2198
  value="${this.escapeHtml(fieldValue)}"
2199
+ placeholder="${this.escapeHtml(placeholder)}"
2210
2200
  ${disabled ? "disabled" : ""}
2211
- ${readonly ? "readonly" : ""}
2212
2201
  ${required ? "required" : ""}>
2213
- <input type="hidden" name="${name}" value="${this.escapeHtml(fieldValue)}">
2214
- <small class="form-text text-muted">This will be enhanced with ComboInput component</small>
2202
+ <small class="form-text text-muted">This will be enhanced with ComboBox component</small>
2215
2203
  </div>
2216
2204
  ${help ? `<div class="${this.options.helpClass}">${this.escapeHtml(help)}</div>` : ""}
2217
2205
  ${error ? `<div class="${this.options.errorClass}">${this.escapeHtml(error)}</div>` : ""}
@@ -6134,6 +6122,240 @@ class ComboInput extends View {
6134
6122
  return new ComboInput(options);
6135
6123
  }
6136
6124
  }
6125
+ class ComboBox extends View {
6126
+ constructor(options = {}) {
6127
+ super(options);
6128
+ this.name = options.name || "combo";
6129
+ this.placeholder = options.placeholder || options.placeHolder || "Type or select...";
6130
+ this.value = options.value || "";
6131
+ this.options = options.options || [];
6132
+ this.allowCustom = options.allowCustom !== false;
6133
+ this.disabled = options.disabled || false;
6134
+ this.required = options.required || false;
6135
+ this.maxHeight = options.maxHeight || 300;
6136
+ this.filteredOptions = [...this.options];
6137
+ this.highlightedIndex = -1;
6138
+ this.isOpen = false;
6139
+ this.template = `
6140
+ <div class="combobox-container">
6141
+ <div class="input-group">
6142
+ <input type="text"
6143
+ class="form-control combobox-input"
6144
+ placeholder="{{placeholder}}"
6145
+ value="{{value}}"
6146
+ {{#disabled}}disabled{{/disabled}}
6147
+ {{#required}}required{{/required}}
6148
+ data-action="combobox-input"
6149
+ autocomplete="off">
6150
+ <button class="btn btn-outline-secondary combobox-toggle"
6151
+ type="button"
6152
+ data-action="combobox-toggle"
6153
+ {{#disabled}}disabled{{/disabled}}>
6154
+ <i class="bi bi-chevron-down"></i>
6155
+ </button>
6156
+ </div>
6157
+ <div class="dropdown-menu combobox-dropdown"
6158
+ style="max-height: {{maxHeight}}px; overflow-y: auto; width: 100%;">
6159
+ <div data-region="dropdown-items"></div>
6160
+ {{^allowCustom}}
6161
+ <div class="combobox-no-match dropdown-item text-muted" style="display: none;">
6162
+ No matches found
6163
+ </div>
6164
+ {{/allowCustom}}
6165
+ </div>
6166
+ </div>
6167
+ `;
6168
+ this.itemTemplate = `
6169
+ {{#items}}
6170
+ <button type="button"
6171
+ class="dropdown-item combobox-item {{#highlighted}}active{{/highlighted}}"
6172
+ data-action="select-item"
6173
+ data-value="{{value}}"
6174
+ data-index="{{index}}">
6175
+ {{label}}
6176
+ </button>
6177
+ {{/items}}
6178
+ `;
6179
+ }
6180
+ async onInit() {
6181
+ await super.onInit();
6182
+ }
6183
+ async onAfterRender() {
6184
+ await super.onAfterRender();
6185
+ this.input = this.element.querySelector(".combobox-input");
6186
+ this.dropdown = this.element.querySelector(".combobox-dropdown");
6187
+ this.dropdownItems = this.element.querySelector('[data-region="dropdown-items"]');
6188
+ this.noMatchDiv = this.element.querySelector(".combobox-no-match");
6189
+ if (this.value && this.input) {
6190
+ const option = this.options.find((opt) => opt.value === this.value);
6191
+ if (option) {
6192
+ this.input.value = option.label || option.value;
6193
+ } else if (this.allowCustom) {
6194
+ this.input.value = this.value;
6195
+ }
6196
+ }
6197
+ this.renderItems();
6198
+ this.setupEventListeners();
6199
+ }
6200
+ setupEventListeners() {
6201
+ this.input.addEventListener("focus", () => this.openDropdown());
6202
+ this.input.addEventListener("input", (e) => this.handleInput(e));
6203
+ this.input.addEventListener("keydown", (e) => this.handleKeydown(e));
6204
+ document.addEventListener("click", (e) => {
6205
+ if (!this.element.contains(e.target)) {
6206
+ this.closeDropdown();
6207
+ }
6208
+ });
6209
+ }
6210
+ handleInput(event) {
6211
+ const searchText = event.target.value.toLowerCase();
6212
+ this.filteredOptions = this.options.filter((opt) => {
6213
+ const label = opt.label || opt.value;
6214
+ return label.toLowerCase().includes(searchText);
6215
+ });
6216
+ this.highlightedIndex = -1;
6217
+ this.renderItems();
6218
+ this.openDropdown();
6219
+ if (!this.allowCustom && this.noMatchDiv) {
6220
+ this.noMatchDiv.style.display = this.filteredOptions.length === 0 ? "block" : "none";
6221
+ }
6222
+ this.value = event.target.value;
6223
+ this.emit("change", { value: this.value });
6224
+ }
6225
+ handleKeydown(event) {
6226
+ if (!this.isOpen && (event.key === "ArrowDown" || event.key === "ArrowUp")) {
6227
+ this.openDropdown();
6228
+ event.preventDefault();
6229
+ return;
6230
+ }
6231
+ if (!this.isOpen) return;
6232
+ switch (event.key) {
6233
+ case "ArrowDown":
6234
+ event.preventDefault();
6235
+ this.highlightedIndex = Math.min(this.highlightedIndex + 1, this.filteredOptions.length - 1);
6236
+ this.renderItems();
6237
+ this.scrollToHighlighted();
6238
+ break;
6239
+ case "ArrowUp":
6240
+ event.preventDefault();
6241
+ this.highlightedIndex = Math.max(this.highlightedIndex - 1, -1);
6242
+ this.renderItems();
6243
+ this.scrollToHighlighted();
6244
+ break;
6245
+ case "Enter":
6246
+ event.preventDefault();
6247
+ if (this.highlightedIndex >= 0) {
6248
+ this.selectItem(this.filteredOptions[this.highlightedIndex]);
6249
+ }
6250
+ break;
6251
+ case "Escape":
6252
+ event.preventDefault();
6253
+ this.closeDropdown();
6254
+ break;
6255
+ case "Tab":
6256
+ this.closeDropdown();
6257
+ break;
6258
+ }
6259
+ }
6260
+ scrollToHighlighted() {
6261
+ if (this.highlightedIndex < 0) return;
6262
+ const items = this.dropdownItems.querySelectorAll(".combobox-item");
6263
+ const highlightedItem = items[this.highlightedIndex];
6264
+ if (highlightedItem) {
6265
+ highlightedItem.scrollIntoView({ block: "nearest" });
6266
+ }
6267
+ }
6268
+ openDropdown() {
6269
+ if (this.disabled || this.isOpen) return;
6270
+ this.isOpen = true;
6271
+ this.dropdown.classList.add("show");
6272
+ if (this.input.value === "") {
6273
+ this.filteredOptions = [...this.options];
6274
+ this.renderItems();
6275
+ }
6276
+ }
6277
+ closeDropdown() {
6278
+ if (!this.isOpen) return;
6279
+ this.isOpen = false;
6280
+ this.dropdown.classList.remove("show");
6281
+ this.highlightedIndex = -1;
6282
+ if (!this.allowCustom) {
6283
+ const validOption = this.options.find(
6284
+ (opt) => opt.value === this.input.value || opt.label === this.input.value
6285
+ );
6286
+ if (!validOption && this.input.value !== "") {
6287
+ this.input.value = this.value;
6288
+ }
6289
+ }
6290
+ }
6291
+ selectItem(option) {
6292
+ const value = option.value;
6293
+ const label = option.label || option.value;
6294
+ this.input.value = label;
6295
+ this.value = value;
6296
+ this.closeDropdown();
6297
+ this.filteredOptions = [...this.options];
6298
+ this.highlightedIndex = -1;
6299
+ this.emit("change", { value: this.value, label });
6300
+ }
6301
+ renderItems() {
6302
+ const items = this.filteredOptions.map((opt, index) => ({
6303
+ value: opt.value,
6304
+ label: opt.label || opt.value,
6305
+ index,
6306
+ highlighted: index === this.highlightedIndex
6307
+ }));
6308
+ const html = Mustache.render(this.itemTemplate, { items });
6309
+ this.dropdownItems.innerHTML = html;
6310
+ }
6311
+ // Action handlers
6312
+ async onActionComboboxInput(event, element) {
6313
+ }
6314
+ async onActionComboboxToggle(event, element) {
6315
+ if (this.isOpen) {
6316
+ this.closeDropdown();
6317
+ } else {
6318
+ this.input.focus();
6319
+ this.openDropdown();
6320
+ }
6321
+ }
6322
+ async onActionSelectItem(event, element) {
6323
+ const value = element.getAttribute("data-value");
6324
+ const option = this.options.find((opt) => opt.value === value);
6325
+ if (option) {
6326
+ this.selectItem(option);
6327
+ }
6328
+ }
6329
+ // Form integration methods
6330
+ getValue() {
6331
+ return this.value;
6332
+ }
6333
+ setValue(value) {
6334
+ this.value = value;
6335
+ if (!this.input) {
6336
+ return;
6337
+ }
6338
+ const option = this.options.find((opt) => opt.value === value);
6339
+ if (option) {
6340
+ this.input.value = option.label || option.value;
6341
+ } else if (this.allowCustom) {
6342
+ this.input.value = value;
6343
+ }
6344
+ }
6345
+ setFormValue(value) {
6346
+ this.setValue(value);
6347
+ }
6348
+ getTemplateData() {
6349
+ return {
6350
+ placeholder: this.placeholder,
6351
+ value: this.input ? this.input.value : this.value,
6352
+ disabled: this.disabled,
6353
+ required: this.required,
6354
+ maxHeight: this.maxHeight,
6355
+ allowCustom: this.allowCustom
6356
+ };
6357
+ }
6358
+ }
6137
6359
  class FormView extends View {
6138
6360
  constructor(options = {}) {
6139
6361
  const {
@@ -6291,6 +6513,7 @@ class FormView extends View {
6291
6513
  this.initializeCustomComponents();
6292
6514
  this.initializeTagInputs();
6293
6515
  this.initializeMultiSelectDropdowns();
6516
+ this.initializeComboBoxes();
6294
6517
  this.initializeCollectionSelects();
6295
6518
  this.initializeCollectionMultiSelects();
6296
6519
  this.initializeDatePickers();
@@ -6455,6 +6678,41 @@ class FormView extends View {
6455
6678
  }
6456
6679
  });
6457
6680
  }
6681
+ /**
6682
+ * Initialize ComboBox components (autocomplete dropdowns)
6683
+ */
6684
+ initializeComboBoxes() {
6685
+ const comboboxPlaceholders = this.element.querySelectorAll('[data-field-type="combobox"]');
6686
+ comboboxPlaceholders.forEach((placeholder) => {
6687
+ try {
6688
+ const fieldName = placeholder.getAttribute("data-field-name");
6689
+ const configData = placeholder.getAttribute("data-field-config");
6690
+ const config = JSON.parse(configData);
6691
+ const fieldConfig = this.getFormFieldConfig(fieldName);
6692
+ if (!fieldConfig) {
6693
+ return;
6694
+ }
6695
+ const combobox = new ComboBox({
6696
+ ...config,
6697
+ options: fieldConfig.options || [],
6698
+ placeholder: fieldConfig.placeholder || config.placeholder || "Type or select...",
6699
+ containerId: null
6700
+ // We'll mount directly
6701
+ });
6702
+ let value = config.value ?? MOJOUtils.getContextData(this.data, fieldName);
6703
+ if (value) {
6704
+ combobox.setFormValue(value);
6705
+ }
6706
+ combobox.render(true, placeholder);
6707
+ this.customComponents.set(fieldName, combobox);
6708
+ combobox.on("change", (data) => {
6709
+ this.handleFieldChange(fieldName, data.value);
6710
+ });
6711
+ } catch (error) {
6712
+ console.error("ComboBox initialization failed:", error);
6713
+ }
6714
+ });
6715
+ }
6458
6716
  /**
6459
6717
  * Initialize CollectionSelect components
6460
6718
  */
@@ -8291,4 +8549,4 @@ export {
8291
8549
  applyFileDropMixin as a,
8292
8550
  FormView$1 as b
8293
8551
  };
8294
- //# sourceMappingURL=FormView-CwYt4vH3.js.map
8552
+ //# sourceMappingURL=FormView-B_90L1RY.js.map