glib-web 4.39.1 → 4.40.0

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.
@@ -2,16 +2,57 @@ require 'js_regex'
2
2
 
3
3
  class Glib::JsonUi::ViewBuilder
4
4
  module Panels
5
+ # Form panel for collecting user input and submitting data.
6
+ #
7
+ # A form panel automatically handles CSRF tokens, form validation, and data submission.
8
+ # It supports nested associations and dynamic field groups.
9
+ #
10
+ # @example Basic form with text field
11
+ # panel.panels_form url: users_path, method: :post do |form|
12
+ # form.fields_text prop: :name, label: 'Full Name'
13
+ # form.fields_email prop: :email
14
+ # form.fields_submit text: 'Create User'
15
+ # end
16
+ #
17
+ # @example Form with model binding
18
+ # panel.panels_form model: @user, autoValidate: true do |form|
19
+ # form.fields_text prop: :name # Automatically gets label from I18n
20
+ # form.fields_email prop: :email
21
+ # form.fields_submit text: 'Save'
22
+ # end
23
+ #
24
+ # @example Form with onChange callback
25
+ # panel.panels_form url: products_path, onChange: ->(action) do
26
+ # action.http_get url: preview_product_path, silent: true
27
+ # end do |form|
28
+ # form.fields_select prop: :category_id, options: @categories
29
+ # end
30
+ #
31
+ # @see https://guides.rubyonrails.org/form_helpers.html Rails Form Helpers
5
32
  class Form < View
6
33
  attr_reader :model_name # See Panels::Form.field_name
7
34
  attr_reader :_autoValidate
8
35
  attr_reader :disable_dirty_check
9
36
  attr_accessor :current_dynamic_group
10
37
 
38
+ # Action called when form is submitted successfully.
39
+ # Receives form data and can trigger navigation, dialogs, etc.
11
40
  action :onSubmit
41
+
42
+ # Action called whenever any form field value changes.
43
+ # Useful for real-time previews or dependent field updates.
12
44
  action :onChange
45
+
46
+ # Similar to onChange but triggers a page reload with new data.
47
+ # Use this when field changes require server-side processing.
13
48
  action :onChangeAndLoad
49
+
50
+ # Custom parameter name for form data when submitting.
51
+ # By default, uses the model name as the parameter namespace.
14
52
  string :paramNameForFormData
53
+
54
+ # If true, form submission will not use AJAX (full page reload).
55
+ # Set to true for file downloads or when you need full page refresh.
15
56
  bool :local
16
57
 
17
58
  def autoValidate(autoValidate)
@@ -265,28 +306,87 @@ class Glib::JsonUi::ViewBuilder
265
306
  end
266
307
  end
267
308
 
309
+ # List panel for displaying scrollable collections of items.
310
+ #
311
+ # Lists can display data in various formats (cards, rows, etc.) with support for
312
+ # pagination, infinite scrolling, and drag-and-drop reordering.
313
+ #
314
+ # @example Basic list with items
315
+ # panel.panels_list width: 'matchParent', firstSection: ->(section) do
316
+ # section.header childViews: ->(header) do
317
+ # header.h2 text: 'Products'
318
+ # end
319
+ # @products.each do |product|
320
+ # section.row childViews: ->(row) do
321
+ # row.label text: product.name
322
+ # row.label text: product.price
323
+ # end
324
+ # end
325
+ # end
326
+ #
327
+ # @example List with pagination
328
+ # panel.panels_list \
329
+ # nextPage: { url: products_path(page: @page + 1) },
330
+ # prevPage: { url: products_path(page: @page - 1) },
331
+ # firstSection: ->(section) do
332
+ # # ... items
333
+ # end
334
+ #
335
+ # @example Responsive grid list
336
+ # panel.panels_list responsiveCols: 3, firstSection: ->(section) do
337
+ # @images.each do |image|
338
+ # section.row childViews: ->(row) do
339
+ # row.image url: image.url
340
+ # end
341
+ # end
342
+ # end
268
343
  class List < View
269
- # Setting this will turn the list into edit mode.
344
+ # Prefix for field names when list is used in edit mode.
345
+ # Setting this turns the list into an editable collection.
270
346
  string :fieldPrefix
271
347
 
272
- # Setting this will enable title editing.
348
+ # Field name for editable title in list items.
349
+ # Enables inline editing of item titles.
273
350
  string :fieldTitleName
351
+
352
+ # Field name for editable subtitle in list items.
274
353
  string :fieldSubtitleName
354
+
355
+ # Field name for editable sub-subtitle in list items.
275
356
  string :fieldSubsubtitleName
276
357
 
277
- # This can be used to implement "check all" and "uncheck all".
278
- # deprecated?
358
+ # Conditional check values for "check all" / "uncheck all" functionality.
359
+ # @deprecated Use custom checkbox handling instead
279
360
  hash :fieldCheckValueIf
280
361
 
362
+ # Phoenix WebSocket configuration for real-time updates.
281
363
  hash :phoenixSocket
282
364
  # hash :actionCable
283
365
 
366
+ # Configuration for next page in pagination.
367
+ # Provide a hash with :url key pointing to the next page.
368
+ # @example { url: products_path(page: @page + 1) }
284
369
  hash :nextPage
370
+
371
+ # Configuration for previous page in pagination.
372
+ # Provide a hash with :url key pointing to the previous page.
285
373
  hash :prevPage
374
+
375
+ # Action triggered when user scrolls to the top of the list.
376
+ # Useful for pull-to-refresh functionality.
286
377
  action :onScrollToTop
378
+
379
+ # Action triggered when user scrolls to the bottom of the list.
380
+ # Useful for infinite scrolling / load more functionality.
287
381
  action :onScrollToBottom
288
382
 
383
+ # Number of columns for responsive grid layout.
384
+ # Items will be arranged in a grid with this many columns.
385
+ # @example responsiveCols: 3
289
386
  int :responsiveCols
387
+
388
+ # Configuration for drag-and-drop reordering support.
389
+ # @example dragSupport: { onDrop: { action: 'http/post', url: reorder_path } }
290
390
  hash :dragSupport
291
391
 
292
392
  def firstSection(block)
@@ -310,7 +410,11 @@ class Glib::JsonUi::ViewBuilder
310
410
  singleton_array :styleClass, :styleClasses
311
411
  array :events
312
412
  views :childViews
313
- string :truncateLine
413
+ # Controls which end(s) of the timeline line to truncate.
414
+ # @see https://vuetifyjs.com/en/api/v-timeline/#props-truncate-line Vuetify Timeline truncateLine
415
+ enum :truncateLine, options: [:start, :end, :both]
416
+ enum :side, options: [:start, :end]
417
+ enum :direction, options: [:horizontal, :vertical]
314
418
  end
315
419
 
316
420
  # deprecated
@@ -445,82 +549,421 @@ class Glib::JsonUi::ViewBuilder
445
549
  end
446
550
  end
447
551
 
552
+ # Scrollable container panel for content that exceeds viewport height.
553
+ #
554
+ # Scroll panels automatically add scrollbars when content overflows.
555
+ # This is the most common container for page content.
556
+ #
557
+ # @example Basic scrollable content
558
+ # page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
559
+ # scroll.h1 text: 'Welcome'
560
+ # scroll.p text: 'Long content here...'
561
+ # end
448
562
  class Scroll < View
563
+ # Child components to display inside the scroll container.
564
+ # Provide a block that receives the view builder for adding content.
449
565
  views :childViews
450
566
  end
451
567
 
568
+ # Split panel for creating multi-column layouts with fixed side panels.
569
+ #
570
+ # Split panels divide the horizontal space into left, center, and right sections.
571
+ # The center section expands to fill available space, while side sections
572
+ # maintain their content width.
573
+ #
574
+ # @example Two-column layout
575
+ # panel.panels_split width: 'matchParent', content: ->(content) do
576
+ # content.left childViews: ->(left) do
577
+ # left.button text: 'Menu'
578
+ # end
579
+ # content.center childViews: ->(center) do
580
+ # center.h1 text: 'Main Content', width: 'matchParent'
581
+ # end
582
+ # end
583
+ #
584
+ # @example Three-column layout with alignment
585
+ # panel.panels_split width: 'matchParent', align: 'middle', content: ->(content) do
586
+ # content.left childViews: ->(left) do
587
+ # left.button text: 'Back'
588
+ # end
589
+ # content.center childViews: ->(center) do
590
+ # center.label text: 'Page Title'
591
+ # end
592
+ # content.right childViews: ->(right) do
593
+ # right.button text: 'Save'
594
+ # end
595
+ # end
596
+ #
597
+ # @see app/views/json_ui/garage/panels/split.json.jbuilder Garage examples
452
598
  class Split < View
453
599
  # def content(block)
454
600
  # block.call page.split_content_builder
455
601
  # end
456
- string :align
602
+
603
+ # Vertical alignment of content within the split panel.
604
+ # Aligns items to top, middle, or bottom of the panel height.
605
+ # @example align: 'middle'
606
+ enum :align, options: [:top, :middle, :bottom]
607
+
608
+ # Content builder for defining left, center, and right sections.
609
+ # Use content.left, content.center, or content.right to define each section.
457
610
  panels_builder :content, :left, :center, :right
458
611
  end
459
612
 
613
+ # Responsive grid panel using Vuetify's 12-column grid system.
614
+ #
615
+ # Responsive panels automatically adjust layout based on screen size.
616
+ # Use panels_column children to define grid columns with breakpoint-specific sizing.
617
+ #
618
+ # @example Responsive two-column layout
619
+ # panel.panels_responsive width: 'matchParent', childViews: ->(responsive) do
620
+ # responsive.panels_column lg: { cols: 8 }, xs: { cols: 12 }, childViews: ->(col) do
621
+ # col.h1 text: 'Main Content'
622
+ # end
623
+ # responsive.panels_column lg: { cols: 4 }, xs: { cols: 12 }, childViews: ->(col) do
624
+ # col.h2 text: 'Sidebar'
625
+ # end
626
+ # end
627
+ #
628
+ # @example With hover effect
629
+ # panel.panels_responsive \
630
+ # styleClasses: ['card'],
631
+ # hoverViews: ->(hover) { hover.label text: 'Click me!' },
632
+ # onClick: ->(action) { action.windows_open url: product_path(@product) },
633
+ # childViews: ->(panel) do
634
+ # panel.h3 text: @product.name
635
+ # end
636
+ #
637
+ # @see https://vuetifyjs.com/en/components/grids/ Vuetify Grid Documentation
638
+ # @see app/views/json_ui/garage/panels/responsive.json.jbuilder Garage examples
460
639
  class Responsive < View
640
+ # Child components to display in the responsive grid.
641
+ # Typically contains panels_column components.
461
642
  views :childViews
462
- string :align
643
+
644
+ # Horizontal alignment of child columns.
645
+ # @example align: 'center'
646
+ enum :align, options: [:left, :center, :right]
647
+
648
+ # Action triggered when the panel is clicked.
649
+ # Makes the entire responsive panel clickable.
463
650
  action :onClick
651
+
652
+ # Views to display when hovering over the panel.
653
+ # Useful for showing tooltips or preview content on mouse hover.
464
654
  views :hoverViews
465
655
 
466
- # Experimental
656
+ # Experimental: Additional panel sections for complex layouts.
657
+ # @note These are experimental features
467
658
  panels_builder :accessory, :header, :footer
468
659
  end
469
660
 
661
+ # Grid column for use within panels_responsive containers.
662
+ #
663
+ # Columns use Vuetify's 12-column grid system where you specify how many columns
664
+ # (out of 12) this component should occupy at different breakpoints.
665
+ #
666
+ # Breakpoints (from smallest to largest):
667
+ # - xs: < 600px (mobile phones)
668
+ # - sm: 600px - 960px (tablets)
669
+ # - md: 960px - 1264px (small laptops)
670
+ # - lg: 1264px - 1904px (desktops)
671
+ # - xl: 1904px - 2560px (large desktops)
672
+ # - xxl: > 2560px (ultra-wide displays)
673
+ #
674
+ # @example Responsive column that changes width at different screen sizes
675
+ # responsive.panels_column \
676
+ # lg: { cols: 4 }, # 4/12 = 1/3 width on large screens
677
+ # md: { cols: 6 }, # 6/12 = 1/2 width on medium screens
678
+ # xs: { cols: 12 }, # 12/12 = full width on mobile
679
+ # childViews: ->(col) do
680
+ # col.h3 text: 'Card Title'
681
+ # end
682
+ #
683
+ # @example Column with responsive padding and ordering
684
+ # responsive.panels_column \
685
+ # lg: { cols: 8, order: 0, padding: { bottom: 0 } },
686
+ # xs: { cols: 12, order: 1, padding: { bottom: 20 } },
687
+ # childViews: ->(col) do
688
+ # col.label text: 'Content'
689
+ # end
690
+ #
691
+ # @see https://vuetifyjs.com/en/components/grids/ Vuetify Grid System
470
692
  class Column < View
693
+ # Configuration for xxl breakpoint (> 2560px).
694
+ # @example xxl: { cols: 3, order: 0, padding: { all: 16 } }
471
695
  hash :xxl
696
+
697
+ # Configuration for xl breakpoint (1904px - 2560px).
698
+ # @example xl: { cols: 4, hide: false }
472
699
  hash :xl
700
+
701
+ # Configuration for lg breakpoint (1264px - 1904px).
702
+ # @example lg: { cols: 6, order: 1 }
473
703
  hash :lg
704
+
705
+ # Configuration for md breakpoint (960px - 1264px).
706
+ # @example md: { cols: 8 }
474
707
  hash :md
708
+
709
+ # Configuration for sm breakpoint (600px - 960px).
710
+ # @example sm: { cols: 12 }
475
711
  hash :sm
712
+
713
+ # Configuration for xs breakpoint (< 600px).
714
+ # @example xs: { cols: 12, hide: false }
476
715
  hash :xs
477
716
 
717
+ # Configuration that applies only at xxl breakpoint.
478
718
  hash :xxlOnly
719
+
720
+ # Configuration that applies only at xl breakpoint.
479
721
  hash :xlOnly
722
+
723
+ # Configuration that applies only at lg breakpoint.
480
724
  hash :lgOnly
725
+
726
+ # Configuration that applies only at md breakpoint.
481
727
  hash :mdOnly
728
+
729
+ # Configuration that applies only at sm breakpoint.
482
730
  hash :smOnly
731
+
732
+ # Configuration that applies only at xs breakpoint.
483
733
  hash :xsOnly
484
734
 
735
+ # Configuration for xxl and smaller breakpoints.
485
736
  hash :xxlAndDown
737
+
738
+ # Configuration for xl and smaller breakpoints.
486
739
  hash :xlAndDown
740
+
741
+ # Configuration for lg and smaller breakpoints.
487
742
  hash :lgAndDown
743
+
744
+ # Configuration for md and smaller breakpoints.
745
+ # @example mdAndDown: { hide: true } # Hide on medium screens and below
488
746
  hash :mdAndDown
747
+
748
+ # Configuration for sm and smaller breakpoints.
489
749
  hash :smAndDown
750
+
751
+ # Configuration for xs breakpoint and below.
490
752
  hash :xsAndDown
491
753
 
754
+ # Child components to display inside the column.
492
755
  views :childViews
756
+
757
+ # Action triggered when the column is clicked.
493
758
  action :onClick
494
759
  end
495
760
 
761
+ # Vertical layout panel that stacks children vertically (top to bottom).
762
+ #
763
+ # Vertical panels use CSS flexbox with flex-direction: column.
764
+ # Children are arranged vertically and can be aligned or distributed in various ways.
765
+ #
766
+ # @example Basic vertical stacking
767
+ # panel.panels_vertical backgroundColor: '#f0f0f0', childViews: ->(vert) do
768
+ # vert.button text: 'Button 1'
769
+ # vert.button text: 'Button 2'
770
+ # vert.button text: 'Button 3'
771
+ # end
772
+ #
773
+ # @example Centered content with equal spacing
774
+ # panel.panels_vertical \
775
+ # width: 'matchParent',
776
+ # height: 300,
777
+ # distribution: 'spaceEqually',
778
+ # align: 'center',
779
+ # childViews: ->(vert) do
780
+ # vert.button text: 'Top'
781
+ # vert.button text: 'Middle'
782
+ # vert.button text: 'Bottom'
783
+ # end
784
+ #
785
+ # @example Clickable vertical panel
786
+ # panel.panels_vertical \
787
+ # styleClasses: ['card'],
788
+ # onClick: ->(action) { action.windows_open url: item_path(@item) },
789
+ # childViews: ->(vert) do
790
+ # vert.h3 text: @item.title
791
+ # vert.p text: @item.description
792
+ # end
793
+ #
794
+ # @see app/views/json_ui/garage/panels/vertical.json.jbuilder Garage examples
496
795
  class Vertical < View
796
+ # Child components to stack vertically.
497
797
  views :childViews
498
- string :distribution
499
- string :align
798
+
799
+ # How children should be distributed vertically.
800
+ # - 'fillEqually': Each child gets equal height
801
+ # - 'spaceEqually': Equal spacing between children
802
+ # @example distribution: 'fillEqually'
803
+ enum :distribution, options: [:fillEqually, :spaceEqually]
804
+
805
+ # Horizontal alignment of children.
806
+ # - 'left': Align to left edge
807
+ # - 'center': Center horizontally
808
+ # - 'right': Align to right edge
809
+ # @example align: 'center'
810
+ enum :align, options: [:left, :center, :right]
811
+
812
+ # Action triggered when the panel is clicked.
500
813
  action :onClick
501
814
  end
502
815
 
816
+ # Horizontal layout panel that arranges children side-by-side (left to right).
817
+ #
818
+ # Horizontal panels use CSS flexbox with flex-direction: row.
819
+ # Supports drag-and-drop reordering and various distribution modes.
820
+ #
821
+ # @example Basic horizontal layout
822
+ # panel.panels_horizontal backgroundColor: '#f0f0f0', childViews: ->(horiz) do
823
+ # horiz.button text: '1'
824
+ # horiz.button text: '2'
825
+ # horiz.button text: '3'
826
+ # end
827
+ #
828
+ # @example With equal spacing and alignment
829
+ # panel.panels_horizontal \
830
+ # width: 300,
831
+ # distribution: 'spaceEqually',
832
+ # align: 'middle',
833
+ # childViews: ->(horiz) do
834
+ # horiz.button text: 'Left'
835
+ # horiz.button text: 'Center'
836
+ # horiz.button text: 'Right'
837
+ # end
838
+ #
839
+ # @example With drag-and-drop reordering
840
+ # panel.panels_horizontal \
841
+ # width: 300,
842
+ # dragSupport: {
843
+ # onDrop: { action: 'http/post', url: reorder_items_path },
844
+ # paramNameForFormData: 'order_data'
845
+ # },
846
+ # childViews: ->(horiz) do
847
+ # @items.each do |item|
848
+ # horiz.button id: "item_#{item.id}", text: item.name
849
+ # end
850
+ # end
851
+ #
852
+ # @example With overlapping items (negative margins)
853
+ # panel.panels_horizontal \
854
+ # distribution: 'overlap-3', # 12px negative margin
855
+ # childViews: ->(horiz) do
856
+ # horiz.avatar url: user1.avatar_url
857
+ # horiz.avatar url: user2.avatar_url
858
+ # horiz.avatar url: user3.avatar_url
859
+ # end
860
+ #
861
+ # @see app/views/json_ui/garage/panels/horizontal.json.jbuilder Garage examples
862
+ # @see https://vuetifyjs.com/en/styles/spacing/ Material Design Spacing
503
863
  class Horizontal < View
864
+ # Child components to arrange horizontally.
504
865
  views :childViews
866
+
867
+ # How children should be distributed horizontally.
868
+ # - 'fillEqually': Each child gets equal width
869
+ # - 'spaceEqually': Equal spacing between children
870
+ # - 'overlap-N': Negative spacing (N from 1-8, e.g., 'overlap-3' = -12px margin)
871
+ # - 'space-N': Positive spacing (N from 1-8, e.g., 'space-2' = 8px margin)
872
+ # @example distribution: 'spaceEqually'
873
+ # @note Uses Material Design spacing scale (4px increments)
505
874
  string :distribution
506
- string :align
875
+
876
+ # Vertical alignment of children.
877
+ # - 'top': Align to top edge
878
+ # - 'middle': Center vertically
879
+ # - 'bottom': Align to bottom edge
880
+ # @example align: 'middle'
881
+ enum :align, options: [:top, :middle, :bottom]
882
+
883
+ # Action triggered when the panel is clicked.
507
884
  action :onClick
885
+
886
+ # Configuration for drag-and-drop reordering support.
887
+ # Enables users to reorder children by dragging them.
888
+ # @example dragSupport: { onDrop: { action: 'http/post', url: reorder_path }, paramNameForFormData: 'order' }
508
889
  hash :dragSupport, optional: [:onDrop, :paramNameForFormData, :paramNameForNewIndex]
509
890
  end
510
891
 
892
+ # Flow layout panel that wraps children like text (left to right, then top to bottom).
893
+ #
894
+ # Flow panels use CSS flexbox with flex-wrap, creating a responsive grid-like layout
895
+ # where children wrap to the next line when they exceed container width.
896
+ # Supports responsive gap and padding for different screen sizes.
897
+ #
898
+ # @example Basic flow layout
899
+ # panel.panels_flow width: 300, innerPadding: { all: 10 }, childViews: ->(flow) do
900
+ # (1..10).each do |n|
901
+ # flow.button text: "Item #{n}"
902
+ # end
903
+ # end
904
+ #
905
+ # @example Responsive gaps and padding
906
+ # panel.panels_flow \
907
+ # width: 'matchParent',
908
+ # xs: { gap: { x: 4, y: 4 }, padding: { all: 8 } },
909
+ # md: { gap: { x: 16, y: 16 }, padding: { all: 24 } },
910
+ # lg: { gap: { all: 32 } },
911
+ # childViews: ->(flow) do
912
+ # @products.each do |product|
913
+ # flow.panels_vertical styleClasses: ['card'], childViews: ->(card) do
914
+ # card.image url: product.image_url
915
+ # card.h4 text: product.name
916
+ # end
917
+ # end
918
+ # end
919
+ #
920
+ # @example Tag cloud with inner padding
921
+ # panel.panels_flow \
922
+ # innerPadding: { x: 5, y: 5 },
923
+ # childViews: ->(flow) do
924
+ # @tags.each do |tag|
925
+ # flow.chip text: tag.name
926
+ # end
927
+ # end
928
+ #
929
+ # @see app/views/json_ui/garage/panels/flow.json.jbuilder Garage examples
511
930
  class Flow < View
931
+ # Padding applied to each child element wrapper.
932
+ # Different from the panel's own padding - this creates gaps between items.
933
+ # @example innerPadding: { x: 10, y: 10 }
934
+ # @example innerPadding: { top: 5, right: 10, bottom: 5, left: 10 }
512
935
  hash :innerPadding, optional: [:top, :right, :bottom, :left, :x, :y]
513
936
 
937
+ # Configuration for xxl breakpoint (> 2560px).
938
+ # @example xxl: { gap: { all: 32 }, padding: { all: 48 } }
514
939
  hash :xxl, optional: [:gap, :padding]
940
+
941
+ # Configuration for xl breakpoint (1904px - 2560px).
942
+ # @example xl: { gap: { x: 24, y: 24 } }
515
943
  hash :xl, optional: [:gap, :padding]
944
+
945
+ # Configuration for lg breakpoint (1264px - 1904px).
946
+ # @example lg: { gap: { all: 16 }, padding: { x: 30, y: 30 } }
516
947
  hash :lg, optional: [:gap, :padding]
948
+
949
+ # Configuration for md breakpoint (960px - 1264px).
950
+ # @example md: { gap: { y: 8, x: 8 } }
517
951
  hash :md, optional: [:gap, :padding]
952
+
953
+ # Configuration for sm breakpoint (600px - 960px).
954
+ # @example sm: { gap: { y: 4, x: 6 }, padding: { all: 16 } }
518
955
  hash :sm, optional: [:gap, :padding]
956
+
957
+ # Configuration for xs breakpoint (< 600px).
958
+ # @example xs: { gap: { y: 2, x: 2 }, padding: { left: 10, bottom: 8 } }
519
959
  hash :xs, optional: [:gap, :padding]
520
960
 
961
+ # Child components to arrange in flow layout.
521
962
  views :childViews
522
963
 
523
- string :align
964
+ # Vertical alignment of children within each row.
965
+ # @example align: 'middle'
966
+ enum :align, options: [:top, :middle, :bottom]
524
967
 
525
968
  # required :innerPadding
526
969
  end
@@ -7,7 +7,7 @@ module Glib
7
7
  included do
8
8
  string :directUploadUrl
9
9
  hash :accepts, optional: [:fileType, :maxFileSize, :maxFileLength, :maxFileSizeErrorText, :maxFileLengthErrorText]
10
- string :strategy # can be "delegate" or "dropUpload"
10
+ enum :strategy, options: [:delegate, :dropUpload]
11
11
  string :storagePrefix
12
12
  hash :metadata
13
13
  string :tagging