web-mojo 2.1.702 → 2.1.715

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 (64) hide show
  1. package/dist/admin.cjs.js +1 -1
  2. package/dist/admin.es.js +10 -10
  3. package/dist/auth.cjs.js +1 -1
  4. package/dist/auth.cjs.js.map +1 -1
  5. package/dist/auth.es.js +3 -3
  6. package/dist/auth.es.js.map +1 -1
  7. package/dist/charts.cjs.js +1 -1
  8. package/dist/charts.es.js +2 -2
  9. package/dist/chunks/{ChatView-WPdz1xrn.js → ChatView-7Tl6j0_F.js} +50 -6
  10. package/dist/chunks/ChatView-7Tl6j0_F.js.map +1 -0
  11. package/dist/chunks/ChatView-CE-aPq-f.js +2 -0
  12. package/dist/chunks/ChatView-CE-aPq-f.js.map +1 -0
  13. package/dist/chunks/{ContextMenu-4qZryVwF.js → ContextMenu-Cii4P-GY.js} +2 -2
  14. package/dist/chunks/{ContextMenu-4qZryVwF.js.map → ContextMenu-Cii4P-GY.js.map} +1 -1
  15. package/dist/chunks/{ContextMenu-DwVTBvQh.js → ContextMenu-CvnzcVHB.js} +2 -2
  16. package/dist/chunks/{ContextMenu-DwVTBvQh.js.map → ContextMenu-CvnzcVHB.js.map} +1 -1
  17. package/dist/chunks/{DataView-t4xn3OKw.js → DataView-CcrHGiuV.js} +2 -2
  18. package/dist/chunks/{DataView-t4xn3OKw.js.map → DataView-CcrHGiuV.js.map} +1 -1
  19. package/dist/chunks/{DataView-C4ZOVg1Z.js → DataView-ZL2WzpAF.js} +2 -2
  20. package/dist/chunks/{DataView-C4ZOVg1Z.js.map → DataView-ZL2WzpAF.js.map} +1 -1
  21. package/dist/chunks/{Dialog-DF_TAFuB.js → Dialog-BN3tLJrQ.js} +5 -5
  22. package/dist/chunks/{Dialog-DF_TAFuB.js.map → Dialog-BN3tLJrQ.js.map} +1 -1
  23. package/dist/chunks/{Dialog-C3lIXUFh.js → Dialog-C6aTVGxC.js} +2 -2
  24. package/dist/chunks/{Dialog-C3lIXUFh.js.map → Dialog-C6aTVGxC.js.map} +1 -1
  25. package/dist/chunks/FormView-DtnOoMzi.js +3 -0
  26. package/dist/chunks/FormView-DtnOoMzi.js.map +1 -0
  27. package/dist/chunks/{FormView-D0mZGFTl.js → FormView-sG1KQVJ8.js} +349 -2
  28. package/dist/chunks/FormView-sG1KQVJ8.js.map +1 -0
  29. package/dist/chunks/{MetricsMiniChartWidget-CvwygZui.js → MetricsMiniChartWidget-CUDzMBUf.js} +2 -2
  30. package/dist/chunks/{MetricsMiniChartWidget-CvwygZui.js.map → MetricsMiniChartWidget-CUDzMBUf.js.map} +1 -1
  31. package/dist/chunks/{MetricsMiniChartWidget-CSU1dVMB.js → MetricsMiniChartWidget-Yaiay78O.js} +3 -3
  32. package/dist/chunks/{MetricsMiniChartWidget-CSU1dVMB.js.map → MetricsMiniChartWidget-Yaiay78O.js.map} +1 -1
  33. package/dist/chunks/{PDFViewer-Cu5DbPEO.js → PDFViewer-BGkd1E_i.js} +2 -2
  34. package/dist/chunks/{PDFViewer-Cu5DbPEO.js.map → PDFViewer-BGkd1E_i.js.map} +1 -1
  35. package/dist/chunks/{PDFViewer-98TZg0zr.js → PDFViewer-BpxaCqau.js} +3 -3
  36. package/dist/chunks/{PDFViewer-98TZg0zr.js.map → PDFViewer-BpxaCqau.js.map} +1 -1
  37. package/dist/chunks/{Page-BlmcwDFg.js → Page-DCQIIrE5.js} +2 -2
  38. package/dist/chunks/{Page-BlmcwDFg.js.map → Page-DCQIIrE5.js.map} +1 -1
  39. package/dist/chunks/{Page-D6A8Hbz2.js → Page-bKLxXw4z.js} +2 -2
  40. package/dist/chunks/{Page-D6A8Hbz2.js.map → Page-bKLxXw4z.js.map} +1 -1
  41. package/dist/chunks/{TopNav-BjEeUu6T.js → TopNav-CPyGSny9.js} +5 -5
  42. package/dist/chunks/{TopNav-BjEeUu6T.js.map → TopNav-CPyGSny9.js.map} +1 -1
  43. package/dist/chunks/{TopNav-BBkd-H-U.js → TopNav-LA4BgF6l.js} +2 -2
  44. package/dist/chunks/{TopNav-BBkd-H-U.js.map → TopNav-LA4BgF6l.js.map} +1 -1
  45. package/dist/chunks/{WebApp-7Fr4mkh7.js → WebApp-CPQTGurF.js} +38 -13
  46. package/dist/chunks/WebApp-CPQTGurF.js.map +1 -0
  47. package/dist/chunks/WebApp-PnDZlAh-.js +2 -0
  48. package/dist/chunks/WebApp-PnDZlAh-.js.map +1 -0
  49. package/dist/docit.cjs.js +1 -1
  50. package/dist/docit.es.js +5 -5
  51. package/dist/index.cjs.js +1 -1
  52. package/dist/index.es.js +11 -11
  53. package/dist/lightbox.cjs.js +1 -1
  54. package/dist/lightbox.es.js +4 -4
  55. package/package.json +1 -1
  56. package/dist/chunks/ChatView-C1lQFygO.js +0 -2
  57. package/dist/chunks/ChatView-C1lQFygO.js.map +0 -1
  58. package/dist/chunks/ChatView-WPdz1xrn.js.map +0 -1
  59. package/dist/chunks/FormView-BtymZpex.js +0 -3
  60. package/dist/chunks/FormView-BtymZpex.js.map +0 -1
  61. package/dist/chunks/FormView-D0mZGFTl.js.map +0 -1
  62. package/dist/chunks/WebApp-7Fr4mkh7.js.map +0 -1
  63. package/dist/chunks/WebApp-QKsHG8Dw.js +0 -2
  64. package/dist/chunks/WebApp-QKsHG8Dw.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { M as Mustache, h as MOJOUtils, V as View } from "./WebApp-7Fr4mkh7.js";
1
+ import { M as Mustache, h as MOJOUtils, V as View } from "./WebApp-CPQTGurF.js";
2
2
  class FormBuilder {
3
3
  constructor(config = {}) {
4
4
  this.fields = config.fields || [];
@@ -604,6 +604,10 @@ class FormBuilder {
604
604
  case "collection":
605
605
  fieldHTML = this.renderCollectionField(field);
606
606
  break;
607
+ case "collectionmultiselect":
608
+ case "collection-multiselect":
609
+ fieldHTML = this.renderCollectionMultiSelectField(field);
610
+ break;
607
611
  case "datepicker":
608
612
  fieldHTML = this.renderDatePickerField(field);
609
613
  break;
@@ -1671,6 +1675,59 @@ class FormBuilder {
1671
1675
  </div>
1672
1676
  `;
1673
1677
  }
1678
+ /**
1679
+ * Render collection multiselect field
1680
+ * @param {Object} field - Field configuration
1681
+ * @returns {string} Field HTML
1682
+ */
1683
+ renderCollectionMultiSelectField(field) {
1684
+ const {
1685
+ name,
1686
+ label,
1687
+ value = [],
1688
+ required = false,
1689
+ disabled = false,
1690
+ Collection: _Collection,
1691
+ collectionParams = {},
1692
+ labelField = "name",
1693
+ valueField = "id",
1694
+ excludeIds = [],
1695
+ size = 8,
1696
+ maxHeight = null,
1697
+ showSelectAll = true,
1698
+ requiresActiveGroup = false,
1699
+ help = field.helpText || field.help || ""
1700
+ } = field;
1701
+ this.getFieldId(name);
1702
+ const error = this.errors[name];
1703
+ const fieldValue = this.getFieldValue(name) ?? value;
1704
+ return `
1705
+ <div class="mojo-form-control">
1706
+ ${label ? `<label class="${this.options.labelClass}">${this.escapeHtml(label)}${required ? '<span class="text-danger">*</span>' : ""}</label>` : ""}
1707
+ <div class="collection-multiselect-placeholder"
1708
+ data-field-name="${name}"
1709
+ data-field-type="collectionmultiselect"
1710
+ data-field-config='${JSON.stringify({
1711
+ name,
1712
+ value: fieldValue,
1713
+ labelField,
1714
+ valueField,
1715
+ excludeIds,
1716
+ size,
1717
+ maxHeight,
1718
+ showSelectAll,
1719
+ disabled,
1720
+ required,
1721
+ requiresActiveGroup
1722
+ })}'>
1723
+ <input type="hidden" name="${name}" value="${this.escapeHtml(JSON.stringify(fieldValue))}">
1724
+ <small class="form-text text-muted">This will be enhanced with CollectionMultiSelect component</small>
1725
+ </div>
1726
+ ${help ? `<div class="${this.options.helpClass}">${this.escapeHtml(help)}</div>` : ""}
1727
+ ${error ? `<div class="${this.options.errorClass}">${this.escapeHtml(error)}</div>` : ""}
1728
+ </div>
1729
+ `;
1730
+ }
1674
1731
  /**
1675
1732
  * Render enhanced date picker field
1676
1733
  * @param {Object} field - Field configuration
@@ -3213,6 +3270,257 @@ class CollectionSelectView extends View {
3213
3270
  return MOJOUtils.getNestedValue(item, fieldPath);
3214
3271
  }
3215
3272
  }
3273
+ class CollectionMultiSelectView extends View {
3274
+ constructor(options = {}) {
3275
+ super({
3276
+ tagName: "div",
3277
+ className: "collection-multiselect-view",
3278
+ template: `
3279
+ <div class="mojo-form-control">
3280
+ {{#label}}
3281
+ <label class="form-label">
3282
+ {{label}}{{#required}}<span class="text-danger">*</span>{{/required}}
3283
+ </label>
3284
+ {{/label}}
3285
+
3286
+ {{#data.loading}}
3287
+ <div class="text-center py-3">
3288
+ <div class="spinner-border spinner-border-sm" role="status">
3289
+ <span class="visually-hidden">Loading...</span>
3290
+ </div>
3291
+ </div>
3292
+ {{/data.loading}}
3293
+
3294
+ {{^data.loading}}
3295
+ {{#data.items.length}}
3296
+ <div class="collection-multiselect-list border rounded" style="max-height: {{maxHeight}}px; overflow-y: auto;">
3297
+ {{#data.items}}
3298
+ <div class="form-check px-3 py-2 border-bottom">
3299
+ <input class="form-check-input"
3300
+ type="checkbox"
3301
+ value="{{valueField}}"
3302
+ id="{{fieldId}}_{{valueField}}"
3303
+ data-action="toggle-item"
3304
+ data-value="{{valueField}}"
3305
+ {{#isSelected}}checked{{/isSelected}}
3306
+ {{#disabled}}disabled{{/disabled}}>
3307
+ <label class="form-check-label w-100" for="{{fieldId}}_{{valueField}}">
3308
+ {{labelField}}
3309
+ </label>
3310
+ </div>
3311
+ {{/data.items}}
3312
+ </div>
3313
+
3314
+ {{#showSelectAll}}
3315
+ <div class="mt-2">
3316
+ <button type="button" class="btn btn-sm btn-outline-secondary me-2" data-action="select-all">
3317
+ Select All
3318
+ </button>
3319
+ <button type="button" class="btn btn-sm btn-outline-secondary" data-action="deselect-all">
3320
+ Deselect All
3321
+ </button>
3322
+ </div>
3323
+ {{/showSelectAll}}
3324
+ {{/data.items.length}}
3325
+
3326
+ {{^data.items.length}}
3327
+ <div class="text-muted text-center py-3 border rounded">
3328
+ No items available
3329
+ </div>
3330
+ {{/^data.items.length}}
3331
+ {{/data.loading}}
3332
+
3333
+ {{#help}}
3334
+ <div class="form-text">{{help}}</div>
3335
+ {{/help}}
3336
+ {{#error}}
3337
+ <div class="invalid-feedback d-block">{{error}}</div>
3338
+ {{/error}}
3339
+ </div>
3340
+ `,
3341
+ ...options
3342
+ });
3343
+ this.name = options.name || "collection_multiselect";
3344
+ this.label = options.label || "";
3345
+ this.help = options.help || "";
3346
+ this.error = options.error || "";
3347
+ this.required = options.required || false;
3348
+ this.disabled = options.disabled || false;
3349
+ this.collection = options.collection;
3350
+ this.collectionParams = options.collectionParams || {};
3351
+ this.labelField = options.labelField || "name";
3352
+ this.valueField = options.valueField || "id";
3353
+ this.excludeIds = options.excludeIds || [];
3354
+ this.requiresActiveGroup = options.requiresActiveGroup || false;
3355
+ this.size = options.size || 8;
3356
+ this.maxHeight = options.maxHeight || this.size * 42;
3357
+ this.showSelectAll = options.showSelectAll !== false;
3358
+ this.selectedValues = Array.isArray(options.value) ? options.value : [];
3359
+ this.loading = false;
3360
+ this.fieldId = options.fieldId || `field_${this.name}`;
3361
+ this.setupCollection();
3362
+ }
3363
+ setupCollection() {
3364
+ if (!this.collection) {
3365
+ console.warn("CollectionMultiSelect: No collection provided");
3366
+ return;
3367
+ }
3368
+ if (this.collectionParams && Object.keys(this.collectionParams).length > 0) {
3369
+ this.collection.params = { ...this.collection.params, ...this.collectionParams };
3370
+ }
3371
+ if (this.requiresActiveGroup) {
3372
+ const app = this.getApp();
3373
+ if (app && app.activeGroup && app.activeGroup.id) {
3374
+ this.collection.params.group = app.activeGroup.id;
3375
+ }
3376
+ }
3377
+ this.collection.on("sync", () => {
3378
+ this.loading = false;
3379
+ this.render();
3380
+ });
3381
+ this.collection.on("error", (error) => {
3382
+ this.loading = false;
3383
+ console.error("CollectionMultiSelect: Collection fetch error", error);
3384
+ this.render();
3385
+ });
3386
+ if (this.collection.isEmpty()) {
3387
+ this.loading = true;
3388
+ this.collection.fetch();
3389
+ }
3390
+ }
3391
+ async getViewData() {
3392
+ const filteredModels = this.collection ? this.collection.models.filter((model) => {
3393
+ const modelId = MOJOUtils.getNestedValue(model, this.valueField);
3394
+ return !this.excludeIds.includes(modelId);
3395
+ }) : [];
3396
+ const items = filteredModels.map((model) => {
3397
+ const labelValue = this.getFieldValue(model, this.labelField);
3398
+ const fieldValue = this.getFieldValue(model, this.valueField);
3399
+ return {
3400
+ labelField: labelValue,
3401
+ valueField: fieldValue,
3402
+ isSelected: this.selectedValues.includes(fieldValue),
3403
+ disabled: this.disabled
3404
+ };
3405
+ });
3406
+ return {
3407
+ loading: this.loading,
3408
+ items,
3409
+ label: this.label,
3410
+ help: this.help,
3411
+ error: this.error,
3412
+ required: this.required,
3413
+ showSelectAll: this.showSelectAll && items.length > 0,
3414
+ maxHeight: this.maxHeight,
3415
+ fieldId: this.fieldId
3416
+ };
3417
+ }
3418
+ /**
3419
+ * Get field value from model or object, supporting dot notation
3420
+ */
3421
+ getFieldValue(item, fieldPath) {
3422
+ if (!item || !fieldPath) return void 0;
3423
+ if (typeof item.get === "function") {
3424
+ const value = item.get(fieldPath);
3425
+ if (value === void 0 && fieldPath.includes(".")) {
3426
+ return MOJOUtils.getNestedValue(item, fieldPath);
3427
+ }
3428
+ return value;
3429
+ }
3430
+ return MOJOUtils.getNestedValue(item, fieldPath);
3431
+ }
3432
+ /**
3433
+ * Handle checkbox toggle
3434
+ */
3435
+ async handleActionToggleItem(event, element) {
3436
+ const value = element.getAttribute("data-value");
3437
+ const isChecked = element.checked;
3438
+ if (isChecked) {
3439
+ if (!this.selectedValues.includes(value)) {
3440
+ this.selectedValues.push(value);
3441
+ }
3442
+ } else {
3443
+ this.selectedValues = this.selectedValues.filter((v) => v !== value);
3444
+ }
3445
+ this.emit("change", {
3446
+ value: this.selectedValues,
3447
+ name: this.name
3448
+ });
3449
+ }
3450
+ /**
3451
+ * Select all items
3452
+ */
3453
+ async handleActionSelectAll(event, element) {
3454
+ event.preventDefault();
3455
+ const checkboxes = this.element.querySelectorAll('input[type="checkbox"]:not(:disabled)');
3456
+ checkboxes.forEach((cb) => {
3457
+ const value = cb.getAttribute("data-value");
3458
+ if (!this.selectedValues.includes(value)) {
3459
+ this.selectedValues.push(value);
3460
+ }
3461
+ cb.checked = true;
3462
+ });
3463
+ this.emit("change", {
3464
+ value: this.selectedValues,
3465
+ name: this.name
3466
+ });
3467
+ }
3468
+ /**
3469
+ * Deselect all items
3470
+ */
3471
+ async handleActionDeselectAll(event, element) {
3472
+ event.preventDefault();
3473
+ const checkboxes = this.element.querySelectorAll('input[type="checkbox"]');
3474
+ checkboxes.forEach((cb) => {
3475
+ cb.checked = false;
3476
+ });
3477
+ this.selectedValues = [];
3478
+ this.emit("change", {
3479
+ value: this.selectedValues,
3480
+ name: this.name
3481
+ });
3482
+ }
3483
+ /**
3484
+ * Get the current selected values
3485
+ */
3486
+ getValue() {
3487
+ return this.selectedValues;
3488
+ }
3489
+ /**
3490
+ * Set the selected values
3491
+ */
3492
+ setValue(values) {
3493
+ this.selectedValues = Array.isArray(values) ? values : [];
3494
+ this.render();
3495
+ }
3496
+ /**
3497
+ * Set the excluded IDs
3498
+ */
3499
+ setExcludeIds(ids) {
3500
+ this.excludeIds = Array.isArray(ids) ? ids : [];
3501
+ this.render();
3502
+ }
3503
+ /**
3504
+ * Refresh the collection
3505
+ */
3506
+ async refresh() {
3507
+ this.loading = true;
3508
+ this.render();
3509
+ await this.collection.fetch();
3510
+ }
3511
+ /**
3512
+ * Get form value for form submission
3513
+ */
3514
+ getFormValue() {
3515
+ return this.selectedValues;
3516
+ }
3517
+ /**
3518
+ * Set form value from form data
3519
+ */
3520
+ setFormValue(value) {
3521
+ this.setValue(value);
3522
+ }
3523
+ }
3216
3524
  class DatePicker extends View {
3217
3525
  constructor(options = {}) {
3218
3526
  const {
@@ -4478,6 +4786,7 @@ class FormView extends View {
4478
4786
  this.initializeCustomComponents();
4479
4787
  this.initializeTagInputs();
4480
4788
  this.initializeCollectionSelects();
4789
+ this.initializeCollectionMultiSelects();
4481
4790
  this.initializeDatePickers();
4482
4791
  this.initializeDateRangePickers();
4483
4792
  this.initializePasswordFields();
@@ -4506,6 +4815,7 @@ class FormView extends View {
4506
4815
  initializeCustomComponents() {
4507
4816
  this.initializeTagInputs();
4508
4817
  this.initializeCollectionSelects();
4818
+ this.initializeCollectionMultiSelects();
4509
4819
  this.initializeDatePickers();
4510
4820
  this.initializeDateRangePickers();
4511
4821
  const componentContainers = this.element.querySelectorAll("[data-component]");
@@ -4622,6 +4932,43 @@ class FormView extends View {
4622
4932
  }
4623
4933
  });
4624
4934
  }
4935
+ /**
4936
+ * Initialize CollectionMultiSelect components
4937
+ */
4938
+ initializeCollectionMultiSelects() {
4939
+ const collectionMultiSelectPlaceholders = this.element.querySelectorAll('[data-field-type="collectionmultiselect"]');
4940
+ collectionMultiSelectPlaceholders.forEach((placeholder) => {
4941
+ try {
4942
+ const fieldName = placeholder.getAttribute("data-field-name");
4943
+ const configData = placeholder.getAttribute("data-field-config");
4944
+ const config = JSON.parse(configData);
4945
+ const fieldConfig = this.getFormFieldConfig(fieldName);
4946
+ if (!fieldConfig || !fieldConfig.Collection) {
4947
+ return;
4948
+ }
4949
+ const collection = new fieldConfig.Collection();
4950
+ if (fieldConfig.collectionParams) {
4951
+ collection.params = { ...collection.params, ...fieldConfig.collectionParams };
4952
+ }
4953
+ const collectionMultiSelect = new CollectionMultiSelectView({
4954
+ ...config,
4955
+ collection,
4956
+ containerId: null
4957
+ // We'll mount directly
4958
+ });
4959
+ let value = MOJOUtils.getContextData(this.data, fieldName);
4960
+ if (value) {
4961
+ collectionMultiSelect.setFormValue(value);
4962
+ }
4963
+ collectionMultiSelect.render(true, placeholder);
4964
+ this.customComponents.set(fieldName, collectionMultiSelect);
4965
+ collectionMultiSelect.on("change", (data) => {
4966
+ this.handleFieldChange(fieldName, data.value);
4967
+ });
4968
+ } catch (error) {
4969
+ }
4970
+ });
4971
+ }
4625
4972
  /**
4626
4973
  * Initialize DatePicker components
4627
4974
  */
@@ -6219,4 +6566,4 @@ export {
6219
6566
  applyFileDropMixin as a,
6220
6567
  FormView$1 as b
6221
6568
  };
6222
- //# sourceMappingURL=FormView-D0mZGFTl.js.map
6569
+ //# sourceMappingURL=FormView-sG1KQVJ8.js.map