terrazzo 0.2.3 → 0.3.1

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/terrazzo/application_controller.rb +18 -2
  3. data/app/views/terrazzo/application/_navigation.json.props +12 -0
  4. data/app/views/terrazzo/application/edit.json.props +2 -9
  5. data/app/views/terrazzo/application/index.json.props +3 -11
  6. data/app/views/terrazzo/application/new.json.props +2 -9
  7. data/app/views/terrazzo/application/show.json.props +2 -10
  8. data/lib/generators/terrazzo/dashboard/dashboard_generator.rb +26 -0
  9. data/lib/generators/terrazzo/eject/eject_generator.rb +232 -0
  10. data/lib/generators/terrazzo/field/field_generator.rb +16 -9
  11. data/lib/generators/terrazzo/field/templates/FormField.jsx.erb +1 -2
  12. data/lib/generators/terrazzo/install/install_generator.rb +1 -1
  13. data/lib/generators/terrazzo/install/templates/admin.css +1 -0
  14. data/lib/generators/terrazzo/install/templates/{application.json.props → application.json.props.tt} +1 -0
  15. data/lib/generators/terrazzo/install/templates/page_to_page_mapping.js.erb +4 -15
  16. data/lib/generators/terrazzo/views/templates/components/Layout.jsx +1 -1
  17. data/lib/generators/terrazzo/views/templates/components/Pagination.jsx +3 -3
  18. data/lib/generators/terrazzo/views/templates/components/SearchBar.jsx +1 -1
  19. data/lib/generators/terrazzo/views/templates/components/SortableHeader.jsx +1 -1
  20. data/lib/generators/terrazzo/views/templates/components/app-sidebar.jsx +23 -22
  21. data/lib/generators/terrazzo/views/templates/components/site-header.jsx +2 -2
  22. data/lib/generators/terrazzo/views/templates/components/ui/index.js +1 -1
  23. data/lib/generators/terrazzo/views/templates/fields/belongs_to/FormField.jsx +1 -1
  24. data/lib/generators/terrazzo/views/templates/fields/boolean/FormField.jsx +1 -1
  25. data/lib/generators/terrazzo/views/templates/fields/boolean/IndexField.jsx +1 -1
  26. data/lib/generators/terrazzo/views/templates/fields/has_many/FormField.jsx +3 -3
  27. data/lib/generators/terrazzo/views/templates/fields/has_many/IndexField.jsx +1 -1
  28. data/lib/generators/terrazzo/views/templates/fields/has_many/ShowField.jsx +3 -3
  29. data/lib/generators/terrazzo/views/templates/fields/has_one/FormField.jsx +1 -1
  30. data/lib/generators/terrazzo/views/templates/fields/hstore/FormField.jsx +3 -3
  31. data/lib/generators/terrazzo/views/templates/fields/hstore/IndexField.jsx +1 -1
  32. data/lib/generators/terrazzo/views/templates/fields/hstore/ShowField.jsx +1 -1
  33. data/lib/generators/terrazzo/views/templates/fields/polymorphic/FormField.jsx +1 -1
  34. data/lib/generators/terrazzo/views/templates/fields/rich_text/FormField.jsx +2 -2
  35. data/lib/generators/terrazzo/views/templates/fields/select/FormField.jsx +1 -1
  36. data/lib/generators/terrazzo/views/templates/fields/select/IndexField.jsx +1 -1
  37. data/lib/generators/terrazzo/views/templates/fields/shared/TextInputFormField.jsx +2 -2
  38. data/lib/generators/terrazzo/views/templates/fields/text/FormField.jsx +2 -2
  39. data/lib/generators/terrazzo/views/templates/pages/_form.jsx +2 -2
  40. data/lib/generators/terrazzo/views/templates/pages/_navigation.json.props +5 -0
  41. data/lib/generators/terrazzo/views/templates/pages/edit.jsx +2 -3
  42. data/lib/generators/terrazzo/views/templates/pages/index.jsx +3 -14
  43. data/lib/generators/terrazzo/views/templates/pages/new.jsx +2 -3
  44. data/lib/generators/terrazzo/views/templates/pages/show.jsx +3 -4
  45. data/lib/generators/terrazzo/views/views_generator.rb +45 -26
  46. data/lib/terrazzo/base_dashboard.rb +4 -1
  47. data/lib/terrazzo/field/asset.rb +34 -0
  48. data/lib/terrazzo/field/associative.rb +1 -1
  49. data/lib/terrazzo/field/belongs_to.rb +2 -2
  50. data/lib/terrazzo/field/date.rb +2 -1
  51. data/lib/terrazzo/field/date_time.rb +2 -1
  52. data/lib/terrazzo/field/has_many.rb +8 -5
  53. data/lib/terrazzo/field/has_one.rb +2 -2
  54. data/lib/terrazzo/field/number.rb +4 -2
  55. data/lib/terrazzo/field/polymorphic.rb +3 -3
  56. data/lib/terrazzo/field/time.rb +2 -1
  57. data/lib/terrazzo/version.rb +1 -1
  58. data/lib/terrazzo.rb +1 -0
  59. data/terrazzo.gemspec +1 -1
  60. metadata +7 -3
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
- import { Separator } from "./ui/separator";
3
- import { SidebarTrigger } from "./ui/sidebar";
2
+ import { Separator } from "terrazzo/ui";
3
+ import { SidebarTrigger } from "terrazzo/ui";
4
4
 
5
5
  export function SiteHeader({ title, actions }) {
6
6
  return (
@@ -97,7 +97,7 @@ export {
97
97
  SelectScrollDownButton,
98
98
  } from "./select";
99
99
  export {
100
- Pagination as UiPagination,
100
+ Pagination,
101
101
  PaginationContent,
102
102
  PaginationItem,
103
103
  PaginationLink,
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Label } from "../../components/ui/label";
3
+ import { Label } from "terrazzo/ui";
4
4
 
5
5
  export function FormField({ value, label, input, options, required }) {
6
6
  const resourceOptions = options?.resourceOptions ?? [];
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Label } from "../../components/ui/label";
3
+ import { Label } from "terrazzo/ui";
4
4
 
5
5
  export function FormField({ value, label, input, required }) {
6
6
  return (
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Badge } from "../../components/ui/badge";
3
+ import { Badge } from "terrazzo/ui";
4
4
 
5
5
  export function IndexField({ value }) {
6
6
  if (value == null) return <span className="text-muted-foreground">-</span>;
@@ -1,9 +1,9 @@
1
1
  import React, { useState, useRef, useCallback } from "react";
2
2
  import { X, Check } from "lucide-react";
3
3
 
4
- import { Label } from "../../components/ui/label";
5
- import { Badge } from "../../components/ui/badge";
6
- import { Popover, PopoverTrigger, PopoverContent } from "../../components/ui/popover";
4
+ import { Label } from "terrazzo/ui";
5
+ import { Badge } from "terrazzo/ui";
6
+ import { Popover, PopoverTrigger, PopoverContent } from "terrazzo/ui";
7
7
  import { cn } from "terrazzo";
8
8
 
9
9
  export function FormField({ value, label, input, options, required }) {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Badge } from "../../components/ui/badge";
3
+ import { Badge } from "terrazzo/ui";
4
4
 
5
5
  export function IndexField({ value }) {
6
6
  const count = typeof value === "number" ? value : 0;
@@ -8,9 +8,9 @@ import {
8
8
  TableRow,
9
9
  TableHead,
10
10
  TableCell,
11
- } from "../../components/ui/table";
12
- import { Badge } from "../../components/ui/badge";
13
- import { Button } from "../../components/ui/button";
11
+ } from "terrazzo/ui";
12
+ import { Badge } from "terrazzo/ui";
13
+ import { Button } from "terrazzo/ui";
14
14
  import { FieldRenderer } from "../FieldRenderer";
15
15
 
16
16
  export function ShowField({ value, itemShowPaths }) {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Label } from "../../components/ui/label";
3
+ import { Label } from "terrazzo/ui";
4
4
 
5
5
  export function FormField({ value, label, input, options, required }) {
6
6
  const resourceOptions = options?.resourceOptions ?? [];
@@ -1,8 +1,8 @@
1
1
  import React, { useState, useRef, useEffect } from "react";
2
2
 
3
- import { Input } from "../../components/ui/input";
4
- import { Button } from "../../components/ui/button";
5
- import { Label } from "../../components/ui/label";
3
+ import { Input } from "terrazzo/ui";
4
+ import { Button } from "terrazzo/ui";
5
+ import { Label } from "terrazzo/ui";
6
6
 
7
7
  export function FormField({ value, label, input, options, required }) {
8
8
  const initialPairs = () => {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Badge } from "../../components/ui/badge";
3
+ import { Badge } from "terrazzo/ui";
4
4
 
5
5
  export function IndexField({ value }) {
6
6
  if (value == null || value === "") {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Badge } from "../../components/ui/badge";
3
+ import { Badge } from "terrazzo/ui";
4
4
 
5
5
  export function ShowField({ value }) {
6
6
  if (value == null || Object.keys(value).length === 0) {
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from "react";
2
2
 
3
- import { Label } from "../../components/ui/label";
3
+ import { Label } from "terrazzo/ui";
4
4
 
5
5
  export function FormField({ value, label, input, options, required }) {
6
6
  const groupedOptions = options?.groupedOptions ?? {};
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { Textarea } from "../../components/ui/textarea";
4
- import { Label } from "../../components/ui/label";
3
+ import { Textarea } from "terrazzo/ui";
4
+ import { Label } from "terrazzo/ui";
5
5
 
6
6
  export function FormField({ value, label, input, required }) {
7
7
  return (
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Label } from "../../components/ui/label";
3
+ import { Label } from "terrazzo/ui";
4
4
 
5
5
  export function FormField({ value, label, input, options, required }) {
6
6
  const selectableOptions = options?.selectableOptions ?? [];
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- import { Badge } from "../../components/ui/badge";
3
+ import { Badge } from "terrazzo/ui";
4
4
 
5
5
  export function IndexField({ value }) {
6
6
  if (value == null) return <span className="text-muted-foreground">-</span>;
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { Input } from "../../components/ui/input";
4
- import { Label } from "../../components/ui/label";
3
+ import { Input } from "terrazzo/ui";
4
+ import { Label } from "terrazzo/ui";
5
5
 
6
6
  export function TextInputFormField({ type = "text", value, label, input, required, defaultValue, ...inputProps }) {
7
7
  const resolvedDefault = defaultValue !== undefined ? defaultValue : String(value ?? "");
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { Textarea } from "../../components/ui/textarea";
4
- import { Label } from "../../components/ui/label";
3
+ import { Textarea } from "terrazzo/ui";
4
+ import { Label } from "terrazzo/ui";
5
5
 
6
6
  export function FormField({ value, label, input, required }) {
7
7
  return (
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
- import { FieldRenderer } from "../fields/FieldRenderer";
4
- import { Button } from "../components/ui/button";
3
+ import { FieldRenderer } from "terrazzo/fields";
4
+ import { Button } from "terrazzo/ui";
5
5
 
6
6
  export function AdminForm({ form, errors }) {
7
7
  const { props: formProps, extras, fieldGroups, fields } = form;
@@ -0,0 +1,5 @@
1
+ json.array! Terrazzo::Namespace.new(namespace).resources_with_index_route do |nav_resource|
2
+ json.label nav_resource.resource_name.humanize.pluralize
3
+ json.path url_for(controller: "/#{nav_resource.controller_path}", action: :index, only_path: true)
4
+ json.active nav_resource.controller_path == controller_path
5
+ end
@@ -1,10 +1,9 @@
1
1
  import React from "react";
2
2
  import { useContent } from "@thoughtbot/superglue";
3
3
 
4
- import { Layout } from "../components/Layout";
4
+ import { Layout } from "terrazzo/components";
5
5
  import { AdminForm } from "./_form";
6
- import { Button } from "../components/ui/button";
7
- import { Card, CardContent } from "../components/ui/card";
6
+ import { Button, Card, CardContent } from "terrazzo/ui";
8
7
 
9
8
  export default function AdminEdit() {
10
9
  const {
@@ -1,20 +1,9 @@
1
1
  import React, { useContext } from "react";
2
2
  import { useContent, NavigationContext } from "@thoughtbot/superglue";
3
3
 
4
- import { Layout } from "../components/Layout";
5
- import { SearchBar } from "../components/SearchBar";
6
- import { Pagination } from "../components/Pagination";
7
- import { SortableHeader } from "../components/SortableHeader";
8
- import { FieldRenderer } from "../fields/FieldRenderer";
9
- import { Button } from "../components/ui/button";
10
- import {
11
- Table,
12
- TableHeader,
13
- TableBody,
14
- TableRow,
15
- TableHead,
16
- TableCell,
17
- } from "../components/ui/table";
4
+ import { Layout, SearchBar, Pagination, SortableHeader } from "terrazzo/components";
5
+ import { FieldRenderer } from "terrazzo/fields";
6
+ import { Button, Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "terrazzo/ui";
18
7
 
19
8
  export default function AdminIndex() {
20
9
  const { visit } = useContext(NavigationContext);
@@ -1,10 +1,9 @@
1
1
  import React from "react";
2
2
  import { useContent } from "@thoughtbot/superglue";
3
3
 
4
- import { Layout } from "../components/Layout";
4
+ import { Layout } from "terrazzo/components";
5
5
  import { AdminForm } from "./_form";
6
- import { Button } from "../components/ui/button";
7
- import { Card, CardContent } from "../components/ui/card";
6
+ import { Button, Card, CardContent } from "terrazzo/ui";
8
7
 
9
8
  export default function AdminNew() {
10
9
  const {
@@ -1,10 +1,9 @@
1
1
  import React from "react";
2
2
  import { useContent } from "@thoughtbot/superglue";
3
3
 
4
- import { Layout } from "../components/Layout";
5
- import { FieldRenderer } from "../fields/FieldRenderer";
6
- import { Button } from "../components/ui/button";
7
- import { Card, CardContent, CardHeader, CardTitle } from "../components/ui/card";
4
+ import { Layout } from "terrazzo/components";
5
+ import { FieldRenderer } from "terrazzo/fields";
6
+ import { Button, Card, CardContent, CardHeader, CardTitle } from "terrazzo/ui";
8
7
 
9
8
  export default function AdminShow() {
10
9
  const {
@@ -8,38 +8,57 @@ module Terrazzo
8
8
  class_option :namespace, type: :string, default: "admin",
9
9
  desc: "Admin namespace"
10
10
 
11
- def copy_ui_components
12
- directory "components/ui", "app/views/#{namespace_name}/components/ui"
11
+ def create_fields_barrel
12
+ create_file "app/views/#{namespace_name}/fields/index.js", <<~JS
13
+ // Re-export all fields from the terrazzo package.
14
+ // To customize a field, run: rails g terrazzo:eject fields/<field_type>
15
+ export * from "terrazzo/fields";
16
+ JS
13
17
  end
14
18
 
15
- def copy_shared_components
16
- %w[
17
- Layout.jsx
18
- app-sidebar.jsx
19
- site-header.jsx
20
- FlashMessages.jsx
21
- SearchBar.jsx
22
- Pagination.jsx
23
- SortableHeader.jsx
24
- ].each do |file|
25
- copy_file "components/#{file}", "app/views/#{namespace_name}/components/#{file}"
26
- end
19
+ def create_components_barrel
20
+ create_file "app/views/#{namespace_name}/components/index.js", <<~JS
21
+ // Re-export all components from the terrazzo package.
22
+ // To customize, run: rails g terrazzo:eject components/<component_name>
23
+ export * from "terrazzo/components";
24
+ JS
27
25
  end
28
26
 
29
- def copy_page_templates
30
- {
31
- "pages/index.jsx" => "application/index.jsx",
32
- "pages/show.jsx" => "application/show.jsx",
33
- "pages/new.jsx" => "application/new.jsx",
34
- "pages/edit.jsx" => "application/edit.jsx",
35
- "pages/_form.jsx" => "application/_form.jsx",
36
- }.each do |src, dest|
37
- copy_file src, "app/views/#{namespace_name}/#{dest}"
38
- end
27
+ def create_ui_barrel
28
+ create_file "app/views/#{namespace_name}/components/ui/index.js", <<~JS
29
+ // Re-export all UI primitives from the terrazzo package.
30
+ // To customize, run: rails g terrazzo:eject ui/<component_name>
31
+ export * from "terrazzo/ui";
32
+ JS
33
+ end
34
+
35
+ def create_navigation_partial
36
+ create_file "app/views/#{namespace_name}/application/_navigation.json.props", <<~RUBY
37
+ resources = Terrazzo::Namespace.new(namespace).resources_with_index_route
38
+
39
+ json.array! [{ label: "Resources", resources: resources }] do |group|
40
+ json.label group[:label]
41
+ json.items do
42
+ json.array! group[:resources] do |r|
43
+ json.label r.resource_name.humanize.pluralize
44
+ json.path url_for(controller: "/\#{r.controller_path}", action: :index, only_path: true)
45
+ json.active r.controller_path == controller_path
46
+ end
47
+ end
48
+ end
49
+ RUBY
39
50
  end
40
51
 
41
- def copy_field_components
42
- directory "fields", "app/views/#{namespace_name}/fields"
52
+ def create_page_stubs
53
+ {
54
+ "index" => "AdminIndex",
55
+ "show" => "AdminShow",
56
+ "new" => "AdminNew",
57
+ "edit" => "AdminEdit",
58
+ }.each do |page, component|
59
+ create_file "app/views/#{namespace_name}/application/#{page}.jsx",
60
+ "export { #{component} as default } from \"terrazzo/pages\";\n"
61
+ end
43
62
  end
44
63
 
45
64
  private
@@ -64,10 +64,13 @@ module Terrazzo
64
64
 
65
65
  def collection_includes
66
66
  collection_attr_set = Set.new(collection_attributes)
67
+ model = self.class.model
67
68
  attribute_types.each_with_object([]) do |(attr, type), includes|
68
69
  next unless collection_attr_set.include?(attr)
69
70
  next unless type.eager_load?
70
- next unless self.class.model.reflect_on_association(attr)
71
+ has_association = model.reflect_on_association(attr)
72
+ has_attachment = model.respond_to?(:reflect_on_attachment) && model.reflect_on_attachment(attr)
73
+ next unless has_association || has_attachment
71
74
  includes << attr
72
75
  end
73
76
  end
@@ -0,0 +1,34 @@
1
+ module Terrazzo
2
+ module Field
3
+ class Asset < Base
4
+ def serialize_value(mode)
5
+ return nil if data.nil? || !data.attached?
6
+
7
+ case mode
8
+ when :index
9
+ data.filename.to_s
10
+ when :show
11
+ { filename: data.filename.to_s, byteSize: data.byte_size, contentType: data.content_type }
12
+ when :form
13
+ { filename: data.filename.to_s, signedId: data.signed_id }
14
+ else
15
+ data.filename.to_s
16
+ end
17
+ end
18
+
19
+ class << self
20
+ def searchable?
21
+ false
22
+ end
23
+
24
+ def sortable?
25
+ false
26
+ end
27
+
28
+ def eager_load?
29
+ true
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -44,7 +44,7 @@ module Terrazzo
44
44
  associated_class.all
45
45
  end
46
46
  pk = association_primary_key
47
- scope.map { |r| [display_name(r), r.public_send(pk)] }
47
+ scope.map { |r| [display_name(r), r.public_send(pk).to_s] }
48
48
  end
49
49
 
50
50
  def association_primary_key
@@ -4,10 +4,10 @@ module Terrazzo
4
4
  def serialize_value(mode)
5
5
  case mode
6
6
  when :form
7
- foreign_key_value
7
+ foreign_key_value&.to_s
8
8
  else
9
9
  return nil if data.nil?
10
- { id: data.id, display: display_name(data) }
10
+ { id: data.id.to_s, display: display_name(data) }
11
11
  end
12
12
  end
13
13
 
@@ -3,7 +3,8 @@ module Terrazzo
3
3
  class Date < Base
4
4
  def serialize_value(_mode)
5
5
  return nil if data.nil?
6
- data.to_s
6
+ format = options[:format]
7
+ format ? data.strftime(format) : data.to_s
7
8
  end
8
9
  end
9
10
  end
@@ -3,7 +3,8 @@ module Terrazzo
3
3
  class DateTime < Base
4
4
  def serialize_value(_mode)
5
5
  return nil if data.nil?
6
- data.iso8601
6
+ format = options[:format]
7
+ format ? data.strftime(format) : data.iso8601
7
8
  end
8
9
  end
9
10
  end
@@ -6,13 +6,16 @@ module Terrazzo
6
6
 
7
7
  case mode
8
8
  when :index
9
- data.size
9
+ count = data.size
10
+ label = attribute.to_s.humanize.downcase
11
+ label = label.singularize if count == 1
12
+ { count: count, label: label }
10
13
  when :form
11
- data.map(&:id)
14
+ data.map { |r| r.id.to_s }
12
15
  when :show
13
16
  serialize_show_value
14
17
  else
15
- data.map { |r| { id: r.id, display: display_name(r) } }
18
+ data.map { |r| { id: r.id.to_s, display: display_name(r) } }
16
19
  end
17
20
  end
18
21
 
@@ -50,7 +53,7 @@ module Terrazzo
50
53
  serialize_with_collection_attributes(all_records, col_attrs, total, limit)
51
54
  else
52
55
  {
53
- items: all_records.map { |r| { id: r.id, display: display_name(r) } },
56
+ items: all_records.map { |r| { id: r.id.to_s, display: display_name(r) } },
54
57
  total: total,
55
58
  initialLimit: limit
56
59
  }
@@ -80,7 +83,7 @@ module Terrazzo
80
83
  value: field.serialize_value(:index)
81
84
  }
82
85
  end
83
- { id: record.id, columns: columns }
86
+ { id: record.id.to_s, columns: columns }
84
87
  end
85
88
 
86
89
  {
@@ -4,10 +4,10 @@ module Terrazzo
4
4
  def serialize_value(mode)
5
5
  case mode
6
6
  when :form
7
- data&.id
7
+ data&.id&.to_s
8
8
  else
9
9
  return nil if data.nil?
10
- { id: data.id, display: display_name(data) }
10
+ { id: data.id.to_s, display: display_name(data) }
11
11
  end
12
12
  end
13
13
 
@@ -1,8 +1,10 @@
1
1
  module Terrazzo
2
2
  module Field
3
3
  class Number < Base
4
- def serialize_value(_mode)
5
- data
4
+ def serialize_value(mode)
5
+ return data if data.nil? || mode == :form || !options.key?(:multiplier)
6
+
7
+ data * options[:multiplier]
6
8
  end
7
9
 
8
10
  def serializable_options
@@ -5,10 +5,10 @@ module Terrazzo
5
5
  case mode
6
6
  when :form
7
7
  return nil if data.nil?
8
- { type: data.class.name, id: data.id }
8
+ { type: data.class.name, id: data.id.to_s }
9
9
  else
10
10
  return nil if data.nil?
11
- { id: data.id, display: display_name(data), type: data.class.name }
11
+ { id: data.id.to_s, display: display_name(data), type: data.class.name }
12
12
  end
13
13
  end
14
14
 
@@ -17,7 +17,7 @@ module Terrazzo
17
17
  classes = options[:classes] || []
18
18
  opts[:groupedOptions] = classes.each_with_object({}) do |klass, hash|
19
19
  klass = klass.constantize if klass.is_a?(::String)
20
- hash[klass.name] = klass.all.map { |r| [display_name(r), r.id] }
20
+ hash[klass.name] = klass.all.map { |r| [display_name(r), r.id.to_s] }
21
21
  end
22
22
  opts
23
23
  end
@@ -3,7 +3,8 @@ module Terrazzo
3
3
  class Time < Base
4
4
  def serialize_value(_mode)
5
5
  return nil if data.nil?
6
- data.to_s
6
+ format = options[:format]
7
+ format ? data.strftime(format) : data.to_s
7
8
  end
8
9
  end
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module Terrazzo
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.1"
3
3
  end
data/lib/terrazzo.rb CHANGED
@@ -37,6 +37,7 @@ module Terrazzo
37
37
  autoload :HasMany, "terrazzo/field/has_many"
38
38
  autoload :HasOne, "terrazzo/field/has_one"
39
39
  autoload :Polymorphic, "terrazzo/field/polymorphic"
40
+ autoload :Asset, "terrazzo/field/asset"
40
41
  end
41
42
 
42
43
  module Page
data/terrazzo.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
7
7
  spec.email = []
8
8
  spec.summary = "A Rails admin framework powered by Superglue and React"
9
9
  spec.description = "Drop-in admin panel for Rails apps using the Administrate dashboard DSL with a React SPA frontend powered by Superglue."
10
- spec.homepage = "https://github.com/wengzilla/terrazzo"
10
+ spec.homepage = "https://github.com/gohypelab/terrazzo"
11
11
  spec.license = "MIT"
12
12
  spec.required_ruby_version = ">= 3.1"
13
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: terrazzo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Terrazzo Contributors
@@ -117,6 +117,7 @@ files:
117
117
  - LICENSE
118
118
  - Rakefile
119
119
  - app/controllers/terrazzo/application_controller.rb
120
+ - app/views/terrazzo/application/_navigation.json.props
120
121
  - app/views/terrazzo/application/edit.json.props
121
122
  - app/views/terrazzo/application/index.json.props
122
123
  - app/views/terrazzo/application/new.json.props
@@ -126,6 +127,7 @@ files:
126
127
  - lib/generators/terrazzo/dashboard/dashboard_generator.rb
127
128
  - lib/generators/terrazzo/dashboard/templates/controller.rb.erb
128
129
  - lib/generators/terrazzo/dashboard/templates/dashboard.rb.erb
130
+ - lib/generators/terrazzo/eject/eject_generator.rb
129
131
  - lib/generators/terrazzo/field/field_generator.rb
130
132
  - lib/generators/terrazzo/field/templates/FormField.jsx.erb
131
133
  - lib/generators/terrazzo/field/templates/IndexField.jsx.erb
@@ -134,8 +136,8 @@ files:
134
136
  - lib/generators/terrazzo/install/install_generator.rb
135
137
  - lib/generators/terrazzo/install/templates/admin.css
136
138
  - lib/generators/terrazzo/install/templates/application.js.erb
137
- - lib/generators/terrazzo/install/templates/application.json.props
138
139
  - lib/generators/terrazzo/install/templates/application.json.props.erb
140
+ - lib/generators/terrazzo/install/templates/application.json.props.tt
139
141
  - lib/generators/terrazzo/install/templates/application_controller.rb.erb
140
142
  - lib/generators/terrazzo/install/templates/application_visit.js.erb
141
143
  - lib/generators/terrazzo/install/templates/flash_slice.js.erb
@@ -231,6 +233,7 @@ files:
231
233
  - lib/generators/terrazzo/views/templates/fields/url/IndexField.jsx
232
234
  - lib/generators/terrazzo/views/templates/fields/url/ShowField.jsx
233
235
  - lib/generators/terrazzo/views/templates/pages/_form.jsx
236
+ - lib/generators/terrazzo/views/templates/pages/_navigation.json.props
234
237
  - lib/generators/terrazzo/views/templates/pages/edit.jsx
235
238
  - lib/generators/terrazzo/views/templates/pages/index.jsx
236
239
  - lib/generators/terrazzo/views/templates/pages/new.jsx
@@ -239,6 +242,7 @@ files:
239
242
  - lib/terrazzo.rb
240
243
  - lib/terrazzo/base_dashboard.rb
241
244
  - lib/terrazzo/engine.rb
245
+ - lib/terrazzo/field/asset.rb
242
246
  - lib/terrazzo/field/associative.rb
243
247
  - lib/terrazzo/field/base.rb
244
248
  - lib/terrazzo/field/belongs_to.rb
@@ -275,7 +279,7 @@ files:
275
279
  - lib/terrazzo/uses_superglue.rb
276
280
  - lib/terrazzo/version.rb
277
281
  - terrazzo.gemspec
278
- homepage: https://github.com/wengzilla/terrazzo
282
+ homepage: https://github.com/gohypelab/terrazzo
279
283
  licenses:
280
284
  - MIT
281
285
  metadata: {}