pages_core 3.12.4 → 3.12.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/app/assets/builds/pages_core/admin-dist.js +8 -43
  4. data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
  5. data/app/assets/builds/pages_core/admin.css +264 -133
  6. data/app/assets/stylesheets/pages_core/admin/components/attachments.css +3 -4
  7. data/app/assets/stylesheets/pages_core/admin/components/forms.css +17 -16
  8. data/app/assets/stylesheets/pages_core/admin/components/image_editor.css +8 -4
  9. data/app/assets/stylesheets/pages_core/admin/components/image_grid.css +1 -1
  10. data/app/assets/stylesheets/pages_core/admin/components/list_table.css +11 -3
  11. data/app/assets/stylesheets/pages_core/admin/components/modal.css +9 -5
  12. data/app/assets/stylesheets/pages_core/admin/components/page_tree.css +5 -1
  13. data/app/assets/stylesheets/pages_core/admin/components/toast.css +2 -2
  14. data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +4 -2
  15. data/app/assets/stylesheets/pages_core/admin/vars.css +2 -1
  16. data/app/controllers/admin/calendars_controller.rb +2 -2
  17. data/app/controllers/admin/categories_controller.rb +3 -3
  18. data/app/controllers/admin/news_controller.rb +6 -6
  19. data/app/controllers/admin/pages_controller.rb +12 -11
  20. data/app/controllers/admin/users_controller.rb +1 -1
  21. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +15 -17
  22. data/app/controllers/pages_core/admin_controller.rb +2 -2
  23. data/app/controllers/pages_core/base_controller.rb +1 -8
  24. data/app/controllers/pages_core/frontend/pages_controller.rb +13 -5
  25. data/app/controllers/pages_core/frontend_controller.rb +12 -7
  26. data/app/helpers/admin/menu_helper.rb +2 -0
  27. data/app/helpers/admin/pages_helper.rb +1 -4
  28. data/app/helpers/pages_core/admin/admin_helper.rb +0 -1
  29. data/app/helpers/pages_core/admin/content_tabs_helper.rb +9 -2
  30. data/app/helpers/pages_core/application_helper.rb +2 -3
  31. data/app/helpers/pages_core/frontend_helper.rb +1 -1
  32. data/app/helpers/pages_core/head_tags_helper.rb +15 -46
  33. data/app/helpers/pages_core/images_helper.rb +76 -21
  34. data/app/helpers/pages_core/locales_helper.rb +9 -0
  35. data/app/helpers/pages_core/open_graph_tags_helper.rb +3 -5
  36. data/app/helpers/pages_core/page_path_helper.rb +1 -1
  37. data/app/javascript/components/Attachments/Attachment.tsx +55 -52
  38. data/app/javascript/components/Attachments/AttachmentEditor.tsx +45 -50
  39. data/app/javascript/components/Attachments/Placeholder.tsx +1 -2
  40. data/app/javascript/components/Attachments.jsx +69 -57
  41. data/app/javascript/components/DateRangeSelect.jsx +94 -54
  42. data/app/javascript/components/EditableImage.tsx +20 -16
  43. data/app/javascript/components/FileUploadButton.tsx +12 -12
  44. data/app/javascript/components/ImageCropper/FocalPoint.tsx +22 -20
  45. data/app/javascript/components/ImageCropper/Image.tsx +20 -16
  46. data/app/javascript/components/ImageCropper/Toolbar.tsx +35 -27
  47. data/app/javascript/components/ImageCropper/useCrop.ts +105 -91
  48. data/app/javascript/components/ImageCropper.tsx +34 -25
  49. data/app/javascript/components/ImageEditor/Form.tsx +32 -43
  50. data/app/javascript/components/ImageEditor.tsx +29 -21
  51. data/app/javascript/components/ImageGrid/DragElement.tsx +6 -4
  52. data/app/javascript/components/ImageGrid/GridImage.tsx +56 -52
  53. data/app/javascript/components/ImageGrid/Placeholder.tsx +1 -1
  54. data/app/javascript/components/ImageGrid.jsx +132 -101
  55. data/app/javascript/components/ImageUploader.tsx +59 -55
  56. data/app/javascript/components/Modal.tsx +2 -4
  57. data/app/javascript/components/PageDates.jsx +25 -20
  58. data/app/javascript/components/PageFiles.jsx +7 -5
  59. data/app/javascript/components/PageImages.tsx +9 -7
  60. data/app/javascript/components/PageTree/Draggable.tsx +46 -40
  61. data/app/javascript/components/PageTree/Node.tsx +111 -95
  62. data/app/javascript/components/PageTree/types.ts +9 -9
  63. data/app/javascript/components/PageTree.tsx +44 -29
  64. data/app/javascript/components/RichTextArea.jsx +51 -37
  65. data/app/javascript/components/RichTextToolbarButton.tsx +8 -5
  66. data/app/javascript/components/TagEditor/AddTagForm.tsx +11 -10
  67. data/app/javascript/components/TagEditor/Tag.tsx +10 -8
  68. data/app/javascript/components/TagEditor.tsx +15 -10
  69. data/app/javascript/components/Toast.tsx +3 -7
  70. data/app/javascript/components/drag/draggedOrder.ts +16 -15
  71. data/app/javascript/components/drag/types.ts +12 -12
  72. data/app/javascript/components/drag/useDragCollection.ts +36 -42
  73. data/app/javascript/components/drag/useDragUploader.ts +3 -2
  74. data/app/javascript/components/drag.ts +5 -4
  75. data/app/javascript/controllers/LoginController.ts +0 -1
  76. data/app/javascript/controllers/MainController.ts +6 -2
  77. data/app/javascript/controllers/PageOptionsController.js +7 -2
  78. data/app/javascript/features/RichText.tsx +9 -7
  79. data/app/javascript/index.ts +5 -3
  80. data/app/javascript/lib/Tree.ts +27 -24
  81. data/app/javascript/lib/copyToClipboard.ts +5 -4
  82. data/app/javascript/lib/readyHandler.ts +4 -4
  83. data/app/javascript/lib/request.ts +7 -3
  84. data/app/javascript/stores/useModalStore.ts +3 -3
  85. data/app/javascript/stores/useToastStore.ts +14 -12
  86. data/app/javascript/types.ts +22 -22
  87. data/app/models/concerns/pages_core/page_model/templateable.rb +1 -1
  88. data/app/views/admin/calendars/show.html.erb +1 -1
  89. data/app/views/admin/news/index.html.erb +1 -1
  90. data/app/views/admin/pages/_edit_files.html.erb +1 -1
  91. data/app/views/admin/pages/_edit_images.html.erb +1 -1
  92. data/app/views/admin/pages/_list_item.html.erb +1 -1
  93. data/app/views/admin/pages/_search_bar.html.erb +1 -1
  94. data/app/views/admin/pages/deleted.html.erb +2 -2
  95. data/app/views/admin/pages/edit.html.erb +3 -3
  96. data/app/views/admin/pages/index.html.erb +4 -4
  97. data/app/views/admin/pages/new.html.erb +1 -1
  98. data/app/views/admin/pages/search.html.erb +3 -3
  99. data/app/views/feeds/pages.rss.builder +2 -2
  100. data/app/views/layouts/admin/_page_header.html.erb +4 -4
  101. data/app/views/layouts/admin.html.erb +1 -2
  102. data/config/locales/en.yml +1 -0
  103. data/lib/pages_core/pages_plugin.rb +5 -3
  104. data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +15 -13
  105. data/lib/tasks/pages/reports.rake +26 -0
  106. metadata +32 -4
  107. data/app/helpers/pages_core/admin/deprecated_admin_helper.rb +0 -40
  108. data/app/views/pages_core/_google_analytics.html.erb +0 -8
@@ -3,7 +3,7 @@
3
3
  module PagesCore
4
4
  module FrontendHelper
5
5
  def root_pages
6
- @root_pages ||= Page.roots.localized(@locale).published
6
+ @root_pages ||= Page.roots.localized(content_locale).published
7
7
  end
8
8
 
9
9
  def root_page
@@ -10,13 +10,10 @@ module PagesCore
10
10
  if args.any?
11
11
  @document_title = args.first
12
12
  else
13
- safe_join(
14
- [@document_title, PagesCore.config(:site_name)].compact.uniq,
15
- " - "
16
- )
13
+ safe_join([@document_title, PagesCore.config(:site_name)].compact.uniq,
14
+ " - ")
17
15
  end
18
16
  end
19
- alias page_title document_title
20
17
 
21
18
  # Returns true if document title has been set.
22
19
  def document_title?
@@ -30,28 +27,19 @@ module PagesCore
30
27
  # feed_tags include_hidden: true
31
28
  #
32
29
  def feed_tags(options = {})
33
- feeds = Page.enabled_feeds(@locale, options)
30
+ feeds = Page.enabled_feeds(content_locale, options)
34
31
  return unless feeds.any?
35
32
 
36
33
  feed_tags = [
37
34
  rss_link_tag(PagesCore.config(:site_name),
38
- pages_url(@locale, format: :rss))
35
+ pages_url(content_locale, format: :rss))
39
36
  ] + feeds.map do |page|
40
37
  rss_link_tag("#{PagesCore.config(:site_name)}: #{page.name}",
41
- page_url(@locale, page, format: :rss))
38
+ page_url(content_locale, page, format: :rss))
42
39
  end
43
40
  safe_join(feed_tags, "\n")
44
41
  end
45
42
 
46
- # Outputs Google Analytics tracking code.
47
- #
48
- # google_analytics_tags "UA-12345678-1"
49
- #
50
- def google_analytics_tags(account_id)
51
- render(partial: "pages_core/google_analytics",
52
- locals: { account_id: account_id })
53
- end
54
-
55
43
  # Outputs a HTML5 doctype and head tags, with document title
56
44
  # and relevant meta tags. Takes a block which will be placed
57
45
  # inside <head>.
@@ -66,14 +54,7 @@ module PagesCore
66
54
  # The block output must be captured first
67
55
  block_output = block_given? ? capture(&block) : nil
68
56
 
69
- safe_join(
70
- [
71
- "<!doctype html>\n<html lang=\"#{I18n.locale}\">".html_safe,
72
- tag.head do
73
- safe_join(head_tag_contents(block_output), "\n")
74
- end
75
- ]
76
- )
57
+ tag.head { safe_join(head_tag_contents(block_output), "\n") }
77
58
  end
78
59
 
79
60
  # Generates a link to an RSS feed.
@@ -87,30 +68,18 @@ module PagesCore
87
68
  href: href)
88
69
  end
89
70
 
90
- # Outputs Typekit tags.
91
- #
92
- # typekit_tags "aadgrag"
93
- #
94
- def typekit_tags(kit_id)
95
- safe_join([
96
- javascript_include_tag("http://use.typekit.com/#{kit_id}.js"),
97
- javascript_tag("try{Typekit.load();}catch(e){}")
98
- ], "\n")
99
- end
100
-
101
71
  private
102
72
 
103
73
  def head_tag_contents(block_output)
104
- [
105
- tag.meta(charset: "utf-8"),
106
- tag.meta("http-equiv" => "X-UA-Compatible", "content" => "IE=edge"),
107
- tag.title(document_title),
108
- meta_description_tag, meta_keywords_tag,
109
- (tag.link(rel: "image_src", href: meta_image) if meta_image?),
110
- open_graph_tags,
111
- csrf_meta_tags,
112
- block_output
113
- ]
74
+ [tag.meta(charset: "utf-8"),
75
+ tag.meta("http-equiv" => "X-UA-Compatible", "content" => "IE=edge"),
76
+ tag.title(document_title),
77
+ meta_description_tag,
78
+ meta_keywords_tag,
79
+ (tag.link(rel: "image_src", href: meta_image) if meta_image?),
80
+ open_graph_tags,
81
+ csrf_meta_tags,
82
+ block_output]
114
83
  end
115
84
 
116
85
  def meta_description_tag
@@ -5,10 +5,8 @@ module PagesCore
5
5
  include DynamicImage::Helper
6
6
 
7
7
  def dynamic_image_tag(record_or_array, options = {})
8
- super(
9
- record_or_array,
10
- extract_alt_text(record_or_array).merge(options)
11
- )
8
+ super(record_or_array,
9
+ extract_alt_text(record_or_array).merge(options))
12
10
  end
13
11
 
14
12
  def image_caption(image, caption: nil)
@@ -32,25 +30,51 @@ module PagesCore
32
30
  def image_figure(image, opts = {})
33
31
  class_name = ["image", image_class_name(image), opts[:class_name]].compact
34
32
  image_tag = image_figure_image_tag(image,
35
- size: opts[:size], ratio:
36
- opts[:ratio])
33
+ size: opts[:size],
34
+ ratio: opts[:ratio])
37
35
  content = opts[:link] ? image_link_to(image_tag, opts[:link]) : image_tag
38
36
  tag.figure(content + image_caption(image, caption: opts[:caption]),
39
37
  class: class_name)
40
38
  end
41
39
 
40
+ # Renders an image figure tag with caption.
41
+ #
42
+ # ==== Options
43
+ # * <tt>:caption</tt>: Override caption with a string, or set to false to
44
+ # disable captions.
45
+ # * <tt>:class_name</tt>: Class name to add to figure tag.
46
+ # * <tt>:link</tt>: Link target for image.
47
+ # * <tt>:ratio</tt>: Ratio to constrain image by.
48
+ # * <tt>:sizes</tt>: Sizes attribute for image tag, default: "100vw".
49
+ def picture(image, opts = {})
50
+ class_name = ["image", image_class_name(image), opts[:class_name]].compact
51
+ pict = picture_tag(image, ratio: opts[:ratio], sizes: opts[:sizes])
52
+ content = opts[:link] ? image_link_to(pict, opts[:link]) : pict
53
+ tag.figure(content + image_caption(image, caption: opts[:caption]),
54
+ class: class_name)
55
+ end
56
+
57
+ def picture_tag(image, ratio: nil, sizes: "100vw")
58
+ tag.picture do
59
+ safe_join(
60
+ [webp_source(image, ratio: ratio, sizes: sizes || "100vw"),
61
+ dynamic_image_tag(image,
62
+ size: image_size(1050, ratio),
63
+ crop: (ratio ? true : false),
64
+ sizes: sizes,
65
+ srcset: srcset(image, ratio: ratio))]
66
+ )
67
+ end
68
+ end
69
+
42
70
  def original_dynamic_image_tag(record_or_array, options = {})
43
- super(
44
- record_or_array,
45
- extract_alt_text(record_or_array).merge(options)
46
- )
71
+ super(record_or_array,
72
+ extract_alt_text(record_or_array).merge(options))
47
73
  end
48
74
 
49
75
  def uncropped_dynamic_image_tag(record_or_array, options = {})
50
- super(
51
- record_or_array,
52
- extract_alt_text(record_or_array).merge(options)
53
- )
76
+ super(record_or_array,
77
+ extract_alt_text(record_or_array).merge(options))
54
78
  end
55
79
 
56
80
  private
@@ -72,13 +96,10 @@ module PagesCore
72
96
  end
73
97
 
74
98
  def image_class_name(image)
75
- if image.size.x == image.size.y
76
- "square"
77
- elsif image.size.x > image.size.y
78
- "landscape"
79
- else
80
- "portrait"
81
- end
99
+ return "square" if image.size.x == image.size.y
100
+ return "landscape" if image.size.x > image.size.y
101
+
102
+ "portrait"
82
103
  end
83
104
 
84
105
  def image_figure_image_tag(image, size: nil, ratio: nil)
@@ -91,5 +112,39 @@ module PagesCore
91
112
  def image_link_to(content, href)
92
113
  tag.a(content, href: href)
93
114
  end
115
+
116
+ def image_size(width, ratio)
117
+ return "#{width}x" unless ratio
118
+
119
+ "#{width}x#{(width / ratio).round}"
120
+ end
121
+
122
+ def image_widths(image)
123
+ [233, 350, 700, 1050, 1400, 2100, 2800].select do |w|
124
+ image.size.x >= w
125
+ end
126
+ end
127
+
128
+ def srcset(image, ratio: nil, format: nil)
129
+ image_widths(image).map do |width|
130
+ options = { size: image_size(width, ratio),
131
+ crop: (ratio ? true : false) }
132
+ options[:format] = format if format
133
+
134
+ "#{dynamic_image_path(image, options)} #{width}w"
135
+ end.join(", ")
136
+ end
137
+
138
+ def webp_source(image, ratio: nil, sizes: "100vw")
139
+ return unless webp_compatible?(image)
140
+
141
+ tag.source(type: "image/webp",
142
+ srcset: srcset(image, ratio: ratio, format: :webp),
143
+ sizes: sizes)
144
+ end
145
+
146
+ def webp_compatible?(image)
147
+ image.content_type != "image/gif"
148
+ end
94
149
  end
95
150
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PagesCore
4
+ module LocalesHelper
5
+ def content_locale
6
+ params[:locale] || I18n.default_locale.to_s
7
+ end
8
+ end
9
+ end
@@ -11,7 +11,7 @@ module PagesCore
11
11
  properties = default_open_graph_properties.merge(open_graph_properties)
12
12
  safe_join(
13
13
  properties
14
- .delete_if { |_, content| content.nil? }
14
+ .compact
15
15
  .map do |name, content|
16
16
  tag.meta(property: "og:#{name}", content: content)
17
17
  end,
@@ -38,14 +38,12 @@ module PagesCore
38
38
  end
39
39
 
40
40
  def default_open_graph_properties
41
- {
42
- type: "website",
41
+ { type: "website",
43
42
  site_name: PagesCore.config(:site_name),
44
43
  title: default_open_graph_title,
45
44
  image: (meta_image if meta_image?),
46
45
  description: default_open_graph_description,
47
- url: request.url
48
- }
46
+ url: request.url }
49
47
  end
50
48
  end
51
49
  end
@@ -54,7 +54,7 @@ module PagesCore
54
54
  ActiveSupport::Deprecation.warn(
55
55
  "Calling page_url without locale is deprecated"
56
56
  )
57
- [(opts[:locale] || @locale), page_or_locale]
57
+ [(opts[:locale] || content_locale), page_or_locale]
58
58
  end
59
59
 
60
60
  def paginated_section(opts)
@@ -8,22 +8,22 @@ import { AttachmentResource, Locale } from "../../types";
8
8
  import { useDraggable, Draggable } from "../drag";
9
9
 
10
10
  interface Record {
11
- id: number | null,
12
- attachment: AttachmentResource,
13
- uploading: boolean
11
+ id: number | null;
12
+ attachment: AttachmentResource;
13
+ uploading: boolean;
14
14
  }
15
15
 
16
16
  interface AttachmentProps {
17
- attributeName: string,
18
- placeholder: boolean,
19
- draggable: { record: Record },
20
- locale: string,
21
- locales: { [index: string]: Locale },
22
- deleteRecord: () => void,
23
- showEmbed: boolean,
24
- position: number,
25
- onUpdate: (localizations: Record<string, Record<string, string>>) => void,
26
- startDrag: (evt: Event, draggable: Draggable) => void
17
+ attributeName: string;
18
+ placeholder: boolean;
19
+ draggable: { record: Record };
20
+ locale: string;
21
+ locales: { [index: string]: Locale };
22
+ deleteRecord: () => void;
23
+ showEmbed: boolean;
24
+ position: number;
25
+ onUpdate: (localizations: Record<string, Record<string, string>>) => void;
26
+ startDrag: (evt: Event, draggable: Draggable) => void;
27
27
  }
28
28
 
29
29
  export default function Attachment(props: AttachmentProps) {
@@ -70,7 +70,8 @@ export default function Attachment(props: AttachmentProps) {
70
70
  attachment={attachment}
71
71
  locale={locale}
72
72
  locales={locales}
73
- onUpdate={props.onUpdate} />
73
+ onUpdate={props.onUpdate}
74
+ />
74
75
  );
75
76
  };
76
77
 
@@ -90,44 +91,46 @@ export default function Attachment(props: AttachmentProps) {
90
91
  }
91
92
 
92
93
  return (
93
- <div className={classes.join(" ")}
94
- {...listeners}>
95
- <input name={`${attributeName}[id]`}
96
- type="hidden" value={record.id || ""} />
97
- <input name={`${attributeName}[attachment_id]`}
98
- type="hidden" value={(attachment && attachment.id) || ""} />
99
- <input name={`${attributeName}[position]`}
100
- type="hidden" value={props.position} />
101
- {!uploading &&
102
- <div className="actions">
103
- <button onClick={editAttachment}>
104
- Edit
105
- </button>
106
- {props.showEmbed && (
107
- <button onClick={copyEmbed}>
108
- Embed
109
- </button>
110
- )}
111
- {props.deleteRecord && (
112
- <button onClick={deleteRecord}>
113
- Remove
114
- </button>
115
- )}
116
- </div>
117
- }
118
- {attachment &&
119
- <div className="attachment-info">
120
- <h3>
121
- <i className={`fa-solid fa-${icon} icon`} />
122
- {name() || <em>Untitled</em>}<br />
123
- </h3>
124
- {!uploading &&
125
- <a href={attachment.url}
126
- rel="noreferrer"
127
- target="_blank">{attachment.filename}</a>}
128
- {!uploading && description() &&
129
- <p dir={localeDir}>{description()}</p>}
130
- </div>}
94
+ <div className={classes.join(" ")} {...listeners}>
95
+ <input
96
+ name={`${attributeName}[id]`}
97
+ type="hidden"
98
+ value={record.id || ""}
99
+ />
100
+ <input
101
+ name={`${attributeName}[attachment_id]`}
102
+ type="hidden"
103
+ value={(attachment && attachment.id) || ""}
104
+ />
105
+ <input
106
+ name={`${attributeName}[position]`}
107
+ type="hidden"
108
+ value={props.position}
109
+ />
110
+ {!uploading && (
111
+ <div className="actions">
112
+ <button onClick={editAttachment}>Edit</button>
113
+ {props.showEmbed && <button onClick={copyEmbed}>Embed</button>}
114
+ {props.deleteRecord && <button onClick={deleteRecord}>Remove</button>}
115
+ </div>
116
+ )}
117
+ {attachment && (
118
+ <div className="attachment-info">
119
+ <h3>
120
+ <i className={`fa-solid fa-${icon} icon`} />
121
+ {name() || <em>Untitled</em>}
122
+ <br />
123
+ </h3>
124
+ {!uploading && (
125
+ <a href={attachment.url} rel="noreferrer" target="_blank">
126
+ {attachment.filename}
127
+ </a>
128
+ )}
129
+ {!uploading && description() && (
130
+ <p dir={localeDir}>{description()}</p>
131
+ )}
132
+ </div>
133
+ )}
131
134
  </div>
132
135
  );
133
136
  }
@@ -6,10 +6,10 @@ import { AttachmentResource, Locale } from "../../types";
6
6
  import { putJson } from "../../lib/request";
7
7
 
8
8
  interface AttachmentEditorProps {
9
- attachment: AttachmentResource,
10
- locale: string,
11
- locales: { [index: string]: Locale },
12
- onUpdate: (localizations: Record<string, Record<string, string>>) => void
9
+ attachment: AttachmentResource;
10
+ locale: string;
11
+ locales: { [index: string]: Locale };
12
+ onUpdate: (localizations: Record<string, Record<string, string>>) => void;
13
13
  }
14
14
 
15
15
  export default function AttachmentEditor(props: AttachmentEditorProps) {
@@ -18,19 +18,19 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
18
18
  const [locale, setLocale] = useState(props.locale);
19
19
  const [localizations, setLocalizations] = useState({
20
20
  name: attachment.name || {},
21
- description: attachment.description || {},
21
+ description: attachment.description || {}
22
22
  });
23
23
 
24
24
  const notice = useToastStore((state) => state.notice);
25
25
  const closeModal = useModalStore((state) => state.close);
26
26
 
27
- const updateLocalization = (name: "name" | "description") => (evt: ChangeEvent<HTMLInputElement>) => {
28
- setLocalizations({
29
- ...localizations,
30
- [name]: { ...localizations[name],
31
- [locale]: evt.target.value }
32
- });
33
- };
27
+ const updateLocalization =
28
+ (name: "name" | "description") => (evt: ChangeEvent<HTMLInputElement>) => {
29
+ setLocalizations({
30
+ ...localizations,
31
+ [name]: { ...localizations[name], [locale]: evt.target.value }
32
+ });
33
+ };
34
34
 
35
35
  const copyEmbedCode = (evt: Event) => {
36
36
  evt.preventDefault();
@@ -59,13 +59,12 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
59
59
  <form>
60
60
  {props.locales && Object.keys(locales).length > 1 && (
61
61
  <div className="field">
62
- <label>
63
- Locale
64
- </label>
65
- <select name="locale"
66
- value={locale}
67
- onChange={e => setLocale(e.target.value)}>
68
- {Object.keys(locales).map(key => (
62
+ <label>Locale</label>
63
+ <select
64
+ name="locale"
65
+ value={locale}
66
+ onChange={(e) => setLocale(e.target.value)}>
67
+ {Object.keys(locales).map((key) => (
69
68
  <option key={`locale-${key}`} value={key}>
70
69
  {locales[key].name}
71
70
  </option>
@@ -75,47 +74,43 @@ export default function AttachmentEditor(props: AttachmentEditorProps) {
75
74
  )}
76
75
  <div className="field">
77
76
  <label>Name</label>
78
- <input type="text"
79
- className="name"
80
- lang={locale}
81
- dir={inputDir}
82
- value={localizations.name[locale] || ""}
83
- onChange={updateLocalization("name")} />
77
+ <input
78
+ type="text"
79
+ className="name"
80
+ lang={locale}
81
+ dir={inputDir}
82
+ value={localizations.name[locale] || ""}
83
+ onChange={updateLocalization("name")}
84
+ />
84
85
  </div>
85
86
  <div className="field">
86
87
  <label>Description</label>
87
- <textarea className="description"
88
- value={localizations.description[locale] || ""}
89
- lang={locale}
90
- dir={inputDir}
91
- onChange={updateLocalization("description")} />
88
+ <textarea
89
+ className="description"
90
+ value={localizations.description[locale] || ""}
91
+ lang={locale}
92
+ dir={inputDir}
93
+ onChange={updateLocalization("description")}
94
+ />
92
95
  </div>
93
96
  <div className="field embed-code">
94
- <label>
95
- Embed code
96
- </label>
97
- <input type="text"
98
- value={`[attachment:${attachment.id}]`}
99
- disabled={true} />
100
- {copySupported() && (
101
- <button onClick={copyEmbedCode}>
102
- Copy
103
- </button>
104
- )}
97
+ <label>Embed code</label>
98
+ <input
99
+ type="text"
100
+ value={`[attachment:${attachment.id}]`}
101
+ disabled={true}
102
+ />
103
+ {copySupported() && <button onClick={copyEmbedCode}>Copy</button>}
105
104
  </div>
106
105
  <div className="field">
107
106
  <label>File</label>
108
- <a href={attachment.url}
109
- rel="noreferrer"
110
- target="_blank">{attachment.filename}</a>
107
+ <a href={attachment.url} rel="noreferrer" target="_blank">
108
+ {attachment.filename}
109
+ </a>
111
110
  </div>
112
111
  <div className="buttons">
113
- <button onClick={save}>
114
- Save
115
- </button>
116
- <button onClick={closeModal}>
117
- Cancel
118
- </button>
112
+ <button onClick={save}>Save</button>
113
+ <button onClick={closeModal}>Cancel</button>
119
114
  </div>
120
115
  </form>
121
116
  </div>
@@ -2,8 +2,7 @@ import React from "react";
2
2
 
3
3
  export default function Placeholder() {
4
4
  return (
5
- <div className="attachment drop-placeholder"
6
- key="file-placeholder">
5
+ <div className="attachment drop-placeholder" key="file-placeholder">
7
6
  Upload files here
8
7
  </div>
9
8
  );