pages_core 3.8.1 → 3.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +35 -0
  3. data/VERSION +1 -0
  4. data/app/assets/builds/pages_core/admin-dist.js +7 -7
  5. data/app/controllers/admin/images_controller.rb +1 -1
  6. data/app/controllers/concerns/pages_core/error_reporting.rb +2 -0
  7. data/app/javascript/components/Attachments/Attachment.jsx +2 -2
  8. data/app/javascript/components/Attachments/AttachmentEditor.jsx +2 -2
  9. data/app/javascript/components/EditableImage.jsx +1 -1
  10. data/app/javascript/components/FileUploadButton.jsx +27 -34
  11. data/app/javascript/components/ImageEditor/Form.jsx +2 -2
  12. data/app/javascript/components/ImageEditor.jsx +1 -1
  13. data/app/javascript/components/ImageGrid/GridImage.jsx +1 -1
  14. data/app/javascript/components/ImageGrid.jsx +1 -1
  15. data/app/javascript/components/ImageUploader.jsx +1 -1
  16. data/app/javascript/components/Modal.jsx +1 -1
  17. data/app/javascript/components/Toast.jsx +1 -1
  18. data/app/javascript/components.js +1 -0
  19. data/app/javascript/index.js +1 -0
  20. data/app/javascript/{components → stores}/ModalStore.jsx +0 -0
  21. data/app/javascript/{components → stores}/ToastStore.jsx +0 -0
  22. data/app/javascript/stores.js +2 -0
  23. data/app/models/concerns/pages_core/page_model/pathable.rb +1 -1
  24. data/app/models/invite.rb +0 -2
  25. data/app/models/page_category.rb +0 -1
  26. data/app/models/page_exporter.rb +2 -2
  27. data/app/models/password_reset_token.rb +0 -2
  28. data/app/models/role.rb +6 -16
  29. data/app/models/tagging.rb +0 -2
  30. data/lib/pages_core/cache_sweeper.rb +0 -9
  31. data/lib/pages_core/configuration/base.rb +3 -1
  32. data/lib/pages_core/pub_sub.rb +1 -2
  33. data/lib/pages_core/version.rb +3 -1
  34. metadata +27 -10
@@ -23,7 +23,7 @@ module Admin
23
23
  def update
24
24
  @image.update(image_params)
25
25
  respond_to do |format|
26
- format.json { render action: :show }
26
+ format.json { render_image_json(@image) }
27
27
  end
28
28
  end
29
29
 
@@ -11,6 +11,8 @@ module PagesCore
11
11
  protected
12
12
 
13
13
  def configure_sentry_context
14
+ return if Rails.env.test?
15
+
14
16
  if Object.const_defined?("Sentry")
15
17
  Sentry.set_user(current_user_context)
16
18
  Sentry.set_tags(locale: params[:locale] || I18n.default_locale.to_s)
@@ -2,8 +2,8 @@ import React from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import copyToClipboard from "../../lib/copyToClipboard";
4
4
  import AttachmentEditor from "./AttachmentEditor";
5
- import ModalStore from "../ModalStore";
6
- import ToastStore from "../ToastStore";
5
+ import ModalStore from "../../stores/ModalStore";
6
+ import ToastStore from "../../stores/ToastStore";
7
7
 
8
8
  import { useDraggable } from "../drag";
9
9
 
@@ -1,8 +1,8 @@
1
1
  import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import copyToClipboard, { copySupported } from "../../lib/copyToClipboard";
4
- import ModalStore from "../ModalStore";
5
- import ToastStore from "../ToastStore";
4
+ import ModalStore from "../../stores/ModalStore";
5
+ import ToastStore from "../../stores/ToastStore";
6
6
  import { putJson } from "../../lib/request";
7
7
 
8
8
  export default function AttachmentEditor(props) {
@@ -1,7 +1,7 @@
1
1
  import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import ImageEditor from "./ImageEditor";
4
- import ModalStore from "./ModalStore";
4
+ import ModalStore from "../stores/ModalStore";
5
5
 
6
6
  export default function EditableImage(props) {
7
7
  const [image, setImage] = useState(props.image);
@@ -1,49 +1,42 @@
1
- import React from "react";
1
+ import React, { useRef } from "react";
2
2
  import PropTypes from "prop-types";
3
3
 
4
- export default class FileUploadButton extends React.Component {
5
- constructor(props) {
6
- super(props);
7
- this.inputRef = React.createRef();
8
- this.handleChange = this.handleChange.bind(this);
9
- this.triggerDialog = this.triggerDialog.bind(this);
10
- }
4
+ export default function FileUploadButton(props) {
5
+ const inputRef = useRef();
11
6
 
12
- handleChange(evt) {
7
+ const handleChange = (evt) => {
13
8
  let fileList = evt.target.files;
14
9
  let files = [];
15
10
  for (var i = 0; i < fileList.length; i++) {
16
11
  files.push(fileList[i]);
17
12
  }
18
13
  if (files.length > 0) {
19
- this.props.callback(files);
14
+ props.callback(files);
20
15
  }
21
- }
16
+ };
22
17
 
23
- render() {
24
- return (
25
- <div className="upload-button">
26
- <span>
27
- Drag and drop {this.props.type || "file"}
28
- {this.props.multiple && "s"} here, or
29
- {this.props.multiline && <br />}
30
- <button onClick={this.triggerDialog}>
31
- choose a file
32
- </button>
33
- </span>
34
- <input type="file"
35
- onChange={this.handleChange}
36
- ref={this.inputRef}
37
- style={{ display: "none" }}
38
- multiple={this.props.multiple || false} />
39
- </div>
40
- );
41
- }
42
-
43
- triggerDialog(evt) {
18
+ const triggerDialog = (evt) => {
44
19
  evt.preventDefault();
45
- this.inputRef.current.click();
46
- }
20
+ inputRef.current.click();
21
+ };
22
+
23
+ return (
24
+ <div className="upload-button">
25
+ <span>
26
+ Drag and drop {props.type || "file"}
27
+ {props.multiple && "s"} here, or
28
+ {props.multiline && <br />}
29
+ <button onClick={triggerDialog}>
30
+ choose a file
31
+ </button>
32
+ </span>
33
+ <input type="file"
34
+ onChange={handleChange}
35
+ ref={inputRef}
36
+ style={{ display: "none" }}
37
+ multiple={props.multiple || false} />
38
+ </div>
39
+ );
47
40
  }
48
41
 
49
42
  FileUploadButton.propTypes = {
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import PropTypes from "prop-types";
3
- import ModalStore from "../ModalStore";
4
- import ToastStore from "../ToastStore";
3
+ import ModalStore from "../../stores/ModalStore";
4
+ import ToastStore from "../../stores/ToastStore";
5
5
  import copyToClipboard, { copySupported } from "../../lib/copyToClipboard";
6
6
 
7
7
  export default function Form(props) {
@@ -1,6 +1,6 @@
1
1
  import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
- import ModalStore from "./ModalStore";
3
+ import ModalStore from "../stores/ModalStore";
4
4
  import { putJson } from "../lib/request";
5
5
 
6
6
  import ImageCropper, { useCrop, cropParams } from "./ImageCropper";
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import copyToClipboard from "../../lib/copyToClipboard";
4
4
  import EditableImage from "../EditableImage";
5
- import ToastStore from "../ToastStore";
5
+ import ToastStore from "../../stores/ToastStore";
6
6
  import Placeholder from "./Placeholder";
7
7
 
8
8
  import { useDraggable } from "../drag";
@@ -4,7 +4,7 @@ import FileUploadButton from "./FileUploadButton";
4
4
  import DragElement from "./ImageGrid/DragElement";
5
5
  import FilePlaceholder from "./ImageGrid/FilePlaceholder";
6
6
  import GridImage from "./ImageGrid/GridImage";
7
- import ToastStore from "./ToastStore";
7
+ import ToastStore from "../stores/ToastStore";
8
8
  import { post } from "../lib/request";
9
9
 
10
10
  import { createDraggable,
@@ -2,7 +2,7 @@ import React, { useState } from "react";
2
2
  import PropTypes from "prop-types";
3
3
  import EditableImage from "./EditableImage";
4
4
  import FileUploadButton from "./FileUploadButton";
5
- import ToastStore from "./ToastStore";
5
+ import ToastStore from "../stores/ToastStore";
6
6
  import { post } from "../lib/request";
7
7
 
8
8
  function getFiles(dt) {
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import ModalStore from "./ModalStore";
2
+ import ModalStore from "../stores/ModalStore";
3
3
 
4
4
  export default class Modal extends React.Component {
5
5
  constructor(props) {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import PropTypes from "prop-types";
3
- import ToastStore from "./ToastStore";
3
+ import ToastStore from "../stores/ToastStore";
4
4
 
5
5
  export default class Toast extends React.Component {
6
6
  constructor(props) {
@@ -1,6 +1,7 @@
1
1
  export { default as Attachments } from "./components/Attachments";
2
2
  export { default as DateRangeSelect } from "./components/DateRangeSelect";
3
3
  export { default as EditableImage } from "./components/EditableImage";
4
+ export { default as FileUploadButton } from "./components/FileUploadButton";
4
5
  export { default as ImageCropper } from "./components/ImageCropper";
5
6
  export { default as ImageGrid } from "./components/ImageGrid";
6
7
  export { default as ImageUploader } from "./components/ImageUploader";
@@ -31,6 +31,7 @@ export default function startPages () {
31
31
 
32
32
  export * from "./components";
33
33
  export * from "./hooks";
34
+ export * from "./stores";
34
35
 
35
36
  export * from "./lib/request.js";
36
37
  export { default as copyToClipboard,
@@ -0,0 +1,2 @@
1
+ export { default as ModalStore } from "./stores/ModalStore";
2
+ export { default as ToastStore } from "./stores/ToastStore";
@@ -107,7 +107,7 @@ module PagesCore
107
107
  siblings.reject { |p| p == self }
108
108
  .map { |p| p.localize(locale) }
109
109
  .map(&:path_segment)
110
- .reject(&:blank?)
110
+ .compact_blank
111
111
  end
112
112
  end
113
113
  end
data/app/models/invite.rb CHANGED
@@ -8,8 +8,6 @@ class Invite < ApplicationRecord
8
8
 
9
9
  before_validation :ensure_token
10
10
 
11
- validates :user_id, presence: true
12
-
13
11
  validates :email,
14
12
  presence: true,
15
13
  format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i },
@@ -3,5 +3,4 @@
3
3
  class PageCategory < ApplicationRecord
4
4
  belongs_to :page
5
5
  belongs_to :category
6
- validates :page_id, :category_id, presence: true
7
6
  end
@@ -74,7 +74,7 @@ class PageExporter
74
74
 
75
75
  def page_file_name(page)
76
76
  [page.path_segment,
77
- page.to_param[0..250]].reject(&:blank?).first
77
+ page.to_param[0..250]].compact_blank.first
78
78
  end
79
79
 
80
80
  def page_path_segment(page)
@@ -95,6 +95,6 @@ class PageExporter
95
95
 
96
96
  def write_file(path, data)
97
97
  FileUtils.mkdir_p(File.dirname(path))
98
- File.open(path, "wb") { |fh| fh.write(data) }
98
+ File.binwrite(path, data)
99
99
  end
100
100
  end
@@ -5,8 +5,6 @@ class PasswordResetToken < ApplicationRecord
5
5
  before_create :ensure_token
6
6
  before_create :ensure_expiration
7
7
 
8
- validates :user_id, presence: true
9
-
10
8
  scope :active, -> { where("expires_at >= ?", Time.now.utc) }
11
9
  scope :expired, -> { where("expires_at < ?", Time.now.utc) }
12
10
 
data/app/models/role.rb CHANGED
@@ -7,17 +7,15 @@ class Role < ApplicationRecord
7
7
  uniqueness: { scope: :user_id },
8
8
  inclusion: { in: proc { Role.roles.map(&:name) } }
9
9
 
10
+ RoleDefinition = Struct.new(:name, :description, :default)
11
+
10
12
  class << self
11
13
  def define(name, description, default: false)
12
14
  if roles.map(&:name).include?(name.to_s)
13
15
  raise ArgumentError, "Tried to define role :#{role}, " \
14
16
  "but a role by that name already exists"
15
17
  else
16
- roles << OpenStruct.new(
17
- name: name.to_s,
18
- description: description,
19
- default: default
20
- )
18
+ roles << RoleDefinition.new(name.to_s, description, default)
21
19
  end
22
20
  end
23
21
 
@@ -39,21 +37,13 @@ class Role < ApplicationRecord
39
37
  return [] unless File.exist?(config_file)
40
38
 
41
39
  YAML.load_file(config_file).map do |key, opts|
42
- OpenStruct.new(name: key.to_s,
43
- description: opts["description"],
44
- default: opts["default"])
40
+ RoleDefinition.new(key.to_s, opts["description"], opts["default"])
45
41
  end
46
42
  end
47
43
 
48
44
  def default_roles
49
- [
50
- OpenStruct.new(
51
- name: "users", description: "Can manage users", default: false
52
- ),
53
- OpenStruct.new(
54
- name: "pages", description: "Can manage pages", default: true
55
- )
56
- ]
45
+ [RoleDefinition.new("users", "Can manage users", false),
46
+ RoleDefinition.new("pages", "Can manage pages", true)]
57
47
  end
58
48
  end
59
49
 
@@ -4,10 +4,8 @@ class Tagging < ApplicationRecord
4
4
  belongs_to :tag
5
5
  belongs_to :taggable, polymorphic: true, touch: true
6
6
 
7
- validates :taggable_id, presence: true
8
7
  validates :taggable_type, presence: true
9
8
  validates :tag_id,
10
- presence: true,
11
9
  uniqueness: { scope: %i[taggable_type taggable_id] }
12
10
 
13
11
  def self.tagged_class(taggable)
@@ -16,15 +16,6 @@ module PagesCore
16
16
  disable(&block)
17
17
  PagesCore::StaticCache.handler.sweep!
18
18
  end
19
-
20
- def config
21
- ActiveSupport::Deprecation.warn(
22
- "PagesCore::CacheSweeper.config is no longer used."
23
- )
24
- configuration = OpenStruct.new(patterns: [])
25
- yield configuration if block_given?
26
- configuration
27
- end
28
19
  end
29
20
 
30
21
  self.enabled ||= true
@@ -5,12 +5,14 @@ module PagesCore
5
5
  class Base
6
6
  class InvalidConfigurationKey < StandardError; end
7
7
 
8
+ SettingStruct = Struct.new(:type, :default)
9
+
8
10
  def self.settings
9
11
  @settings ||= {}
10
12
  end
11
13
 
12
14
  def self.setting(key, type, default = nil)
13
- settings[key] = OpenStruct.new(type: type, default: default)
15
+ settings[key] = SettingStruct.new(type, default)
14
16
 
15
17
  define_method key do |*args|
16
18
  args.any? ? set(key, *args) : get(key)
@@ -4,9 +4,8 @@ module PagesCore
4
4
  module PubSub
5
5
  class << self
6
6
  def publish(name, payload = {})
7
- payload_struct = OpenStruct.new(payload)
8
7
  subscribers.select { |s| s.name == name }
9
- .each { |s| s.call(payload_struct) }
8
+ .each { |s| s.call(payload) }
10
9
  end
11
10
 
12
11
  def subscribe(name, &block)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PagesCore
4
- VERSION = "3.8.1" unless PagesCore.const_defined?("VERSION")
4
+ unless PagesCore.const_defined?("VERSION")
5
+ VERSION = File.read(File.expand_path("../../VERSION", __dir__)).strip
6
+ end
5
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pages_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.8.1
4
+ version: 3.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inge Jørgensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-11-17 00:00:00.000000000 Z
11
+ date: 2022-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: capybara
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: 3.8.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: semantic
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: shoulda-matchers
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -126,16 +140,16 @@ dependencies:
126
140
  name: timecop
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - "~>"
143
+ - - ">="
130
144
  - !ruby/object:Gem::Version
131
- version: 0.8.0
145
+ version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - "~>"
150
+ - - ">="
137
151
  - !ruby/object:Gem::Version
138
- version: 0.8.0
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: rails
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -495,6 +509,7 @@ extra_rdoc_files: []
495
509
  files:
496
510
  - README.md
497
511
  - Rakefile
512
+ - VERSION
498
513
  - app/assets/builds/pages_core/admin-dist.js
499
514
  - app/assets/images/pages/admin/drag-icon.png
500
515
  - app/assets/images/pages/admin/icon.png
@@ -621,7 +636,6 @@ files:
621
636
  - app/javascript/components/ImageGrid/Placeholder.jsx
622
637
  - app/javascript/components/ImageUploader.jsx
623
638
  - app/javascript/components/Modal.jsx
624
- - app/javascript/components/ModalStore.jsx
625
639
  - app/javascript/components/PageDates.jsx
626
640
  - app/javascript/components/PageFiles.jsx
627
641
  - app/javascript/components/PageImages.jsx
@@ -634,7 +648,6 @@ files:
634
648
  - app/javascript/components/TagEditor/AddTagForm.jsx
635
649
  - app/javascript/components/TagEditor/Tag.jsx
636
650
  - app/javascript/components/Toast.jsx
637
- - app/javascript/components/ToastStore.jsx
638
651
  - app/javascript/components/drag.js
639
652
  - app/javascript/components/drag/draggedOrder.js
640
653
  - app/javascript/components/drag/useDragCollection.js
@@ -651,6 +664,9 @@ files:
651
664
  - app/javascript/lib/copyToClipboard.js
652
665
  - app/javascript/lib/readyHandler.js
653
666
  - app/javascript/lib/request.js
667
+ - app/javascript/stores.js
668
+ - app/javascript/stores/ModalStore.jsx
669
+ - app/javascript/stores/ToastStore.jsx
654
670
  - app/jobs/pages_core/autopublish_job.rb
655
671
  - app/jobs/pages_core/sweep_cache_job.rb
656
672
  - app/mailers/admin_mailer.rb
@@ -817,7 +833,8 @@ files:
817
833
  - vendor/assets/stylesheets/ReactCrop.css
818
834
  homepage: ''
819
835
  licenses: []
820
- metadata: {}
836
+ metadata:
837
+ rubygems_mfa_required: 'true'
821
838
  post_install_message:
822
839
  rdoc_options: []
823
840
  require_paths:
@@ -833,7 +850,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
833
850
  - !ruby/object:Gem::Version
834
851
  version: '0'
835
852
  requirements: []
836
- rubygems_version: 3.2.22
853
+ rubygems_version: 3.3.3
837
854
  signing_key:
838
855
  specification_version: 4
839
856
  summary: Pages Core