trek 0.1.17 → 0.1.19

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ce09d92a68c4819bcee3c5161b1fd0b94cc70c5b9f0b2b27078d2dd25304f0a
4
- data.tar.gz: ac8267f5c9835457b0ba96d64efc70bf07dd33b5d0e35d0e3e17187ea5820ea7
3
+ metadata.gz: c361aedf0c96319053cdbb1e2d80ac77248791c84fedd2f0bb49e89b3d6afa7f
4
+ data.tar.gz: 40fd5afd6fa1cd82f8095e2164d46f5943c0a723fe79878e4046cb576bb3eba0
5
5
  SHA512:
6
- metadata.gz: 1e5b14288cf402157249b544f6931253594f1fce504d40a20af920ae3c116f339a877a11db59c34371cce3fb9d689b9153c165d60194783a72c4bae5e539aa65
7
- data.tar.gz: 8b98e40d589b12ff0debc7d5b822aaaefe525427d24c08c9c178194ab9aa988a7df96ef919e1cd21d788146a72c0a166a2d71e04f2e8e7f981e7a0d144d22b9f
6
+ metadata.gz: 37c0db5305f16dfc336b2e9383bb03997dc6613c77a0c797648dd3a77ed2f0300028330b4eae72d2775dbfc407e260b3f8b8877cd3e0c3120b884447b53235cc
7
+ data.tar.gz: 7a7d98baf92ad4bed55736607976a73af61696381b90252e3f0f63a691dfb31f5b959982c5570a452ec004199c92ea344a12116904049d7dba315c57c6d3b9ff
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- trek (0.1.17)
4
+ trek (0.1.19)
5
5
  action_policy (~> 0.6)
6
6
  actioncable
7
7
  acts_as_list (~> 1.1)
@@ -320,7 +320,7 @@ GEM
320
320
  stringio
321
321
  public_suffix (7.0.2)
322
322
  racc (1.8.1)
323
- rack (3.2.4)
323
+ rack (3.2.5)
324
324
  rack-session (2.1.1)
325
325
  base64 (>= 0.1.0)
326
326
  rack (>= 3.0.0)
@@ -9,6 +9,21 @@ module Trek
9
9
  renders_many :buttons, Trek::ButtonComponent
10
10
  renders_many :links, "LinkComponent"
11
11
 
12
+ def with_delete_button(object:, model_collection:)
13
+ return unless object.persisted? && helpers.allowed_to?(:destroy?, object)
14
+
15
+ with_button(
16
+ text: helpers.t("admin.actions.delete"),
17
+ to: [:admin, object],
18
+ method: :delete,
19
+ data: {
20
+ turbo_confirm: helpers.t("admin.#{model_collection}.destroy.confirm")
21
+ },
22
+ color: :tomato,
23
+ position: :right,
24
+ )
25
+ end
26
+
12
27
  def classes
13
28
  class_names_for(
14
29
  root_class,
@@ -211,28 +211,27 @@ div(
211
211
  class=class_for("floating-menu")
212
212
  data=stimulus_target_hash("floatingMenu")
213
213
  )
214
- / TODO: re-enable floating buttons
215
- / button(
216
- / class=class_for("button")
217
- / type="button"
218
- / data-action=stimulus_action("togglePrompts")
219
- / )
220
- / = render Trek::IconComponent.new( \
221
- / "trek/cursor",
222
- / classnames: class_for("button-icon"),
223
- / )
224
- / = t(".prompt")
225
-
226
- / button(
227
- / class=class_for("button")
228
- / type="button"
229
- / data-action=stimulus_action("toggleImage")
230
- / )
231
- / = render Trek::IconComponent.new( \
232
- / "trek/pic",
233
- / classnames: class_for("button-icon"),
234
- / )
235
- / = t(".image")
214
+ button(
215
+ class=class_for("button")
216
+ type="button"
217
+ data-action=stimulus_action("togglePrompts")
218
+ )
219
+ = render Trek::IconComponent.new( \
220
+ "trek/cursor",
221
+ classnames: class_for("button-icon"),
222
+ )
223
+ = t(".prompt")
224
+
225
+ button(
226
+ class=class_for("button")
227
+ type="button"
228
+ data-action=stimulus_action("toggleImage")
229
+ )
230
+ = render Trek::IconComponent.new( \
231
+ "trek/pic",
232
+ classnames: class_for("button-icon"),
233
+ )
234
+ = t(".image")
236
235
 
237
236
  = link_to "",
238
237
  new_prompt_path,
@@ -259,12 +259,66 @@ export class Controller extends BaseController {
259
259
 
260
260
  contentInserterTargetConnected(t) {
261
261
  const content = t.innerHTML;
262
- this.editor.commands.insertContent(content);
262
+
263
+ if (this._editingImagePos != null) {
264
+ // Update existing image block in place
265
+ const pos = this._editingImagePos;
266
+ this._editingImagePos = null;
267
+
268
+ const parser = new DOMParser();
269
+ const doc = parser.parseFromString(content, "text/html");
270
+ const imageBlock = doc.querySelector("image-block");
271
+
272
+ if (imageBlock) {
273
+ const attrs = {};
274
+ for (const attr of imageBlock.attributes) {
275
+ attrs[attr.name] = attr.value;
276
+ }
277
+ const tr = this.editor.state.tr;
278
+ const node = this.editor.state.doc.nodeAt(pos);
279
+ if (node && node.type.name === "imageBlock") {
280
+ tr.setNodeMarkup(pos, undefined, attrs);
281
+ this.editor.view.dispatch(tr);
282
+ } else {
283
+ this.editor.commands.insertContent(content);
284
+ }
285
+ } else {
286
+ this.editor.commands.insertContent(content);
287
+ }
288
+ } else {
289
+ this.editor.commands.insertContent(content);
290
+ }
291
+
263
292
  t.parentNode.removeChild(t);
264
293
  }
265
294
 
266
295
  toggleImage(e) {
267
- const params = e.target.closest("button").dataset.params;
296
+ const button = e.target.closest("button");
297
+ const params = button.dataset.params;
298
+
299
+ // Check if clicking an existing image block in the editor
300
+ const imageBlockEl = button.closest("image-block");
301
+ if (imageBlockEl) {
302
+ const pos = this.editor.view.posAtDOM(imageBlockEl, 0);
303
+ const resolved = this.editor.state.doc.resolve(pos);
304
+ // Walk up to find the imageBlock node position
305
+ for (let d = resolved.depth; d >= 0; d--) {
306
+ if (resolved.node(d).type.name === "imageBlock") {
307
+ this._editingImagePos = d > 0 ? resolved.before(d) : pos;
308
+ break;
309
+ }
310
+ }
311
+ // Fallback: the pos itself might point at the imageBlock
312
+ if (this._editingImagePos == null) {
313
+ const node = this.editor.state.doc.nodeAt(pos);
314
+ if (node && node.type.name === "imageBlock") {
315
+ this._editingImagePos = pos;
316
+ }
317
+ }
318
+ } else {
319
+ this._editingImagePos = null;
320
+ }
321
+
268
322
  const url = this.hiddenImageButtonTarget.dataset.basePath;
269
323
  this.hiddenImageButtonTarget.href = url + (params ? "&" + params : "");
270
324
  this.hiddenImageButtonTarget.click();
@@ -48,7 +48,14 @@ export default Node.create({
48
48
  },
49
49
 
50
50
  addNodeView() {
51
- return ({ node }) => {
51
+ return ({
52
+ editor,
53
+ node,
54
+ getPos,
55
+ HTMLAttributes,
56
+ decorations,
57
+ extension,
58
+ }) => {
52
59
  const dom = document.createElement("image-block");
53
60
  const params = attributesToParams(node.attrs);
54
61
 
@@ -45,7 +45,14 @@ export default Node.create({
45
45
  },
46
46
 
47
47
  addNodeView() {
48
- return ({ node }) => {
48
+ return ({
49
+ editor,
50
+ node,
51
+ getPos,
52
+ HTMLAttributes,
53
+ decorations,
54
+ extension,
55
+ }) => {
49
56
  const dom = document.createElement("prompts-block");
50
57
  const params = attributesToParams(node.attrs);
51
58
 
@@ -10,6 +10,7 @@ module Trek
10
10
  attr_reader :object, :model_name, :lookup
11
11
 
12
12
  def initialize(form, object_name, method_name, options = {})
13
+ @label = options.delete(:label)
13
14
  @hint = options.delete(:hint)
14
15
  @lookup = options.delete(:lookup)
15
16
  @classnames = options.delete(:classnames)
@@ -40,7 +41,7 @@ module Trek
40
41
  end
41
42
 
42
43
  def label_text
43
- label_i18n_keys.translate
44
+ @label.presence || label_i18n_keys.translate
44
45
  end
45
46
 
46
47
  def label_i18n_keys
@@ -3,7 +3,6 @@
3
3
  module Trek
4
4
  class HeaderComponent < Trek::Component
5
5
  extend Dry::Initializer
6
- include Trek::PagePathHelper if defined?(Page)
7
6
  include ActionPolicy::Behaviour
8
7
 
9
8
  option :current_object, optional: true
@@ -1,7 +1,6 @@
1
1
  module ProsemirrorToHtml
2
2
  class GlobalIdToLinksFormatter
3
3
  include Rails.application.routes.url_helpers
4
- include Trek::PagePathHelper
5
4
 
6
5
  GLOBAL_ID_REGEX = %r{(gid://[[:alnum:]]+/[\w:]+/[\w-]+)}
7
6
 
@@ -101,17 +101,5 @@
101
101
  text: t("admin.actions.validate"),
102
102
  color: :grass,
103
103
  )
104
- if @object.persisted? && allowed_to?(:destroy, @object)
105
- c.with_button(
106
- text: t("admin.actions.delete"),
107
- to: [:admin, @object],
108
- method: :delete,
109
- data: {
110
- turbo_confirm: t(
111
- "admin.#{model_collection}.destroy.confirm"
112
- )
113
- },
114
- color: :tomato,
115
- position: :right,
116
- )
117
- end
104
+
105
+ c.with_delete_button(object: @object, model_collection: model_collection)
@@ -20,3 +20,5 @@
20
20
  text: t("admin.actions.validate"),
21
21
  color: :grass,
22
22
  )
23
+
24
+ c.with_delete_button(object: @object, model_collection: model_collection)
@@ -48,13 +48,4 @@
48
48
  color: :grass,
49
49
  )
50
50
 
51
- if @object.persisted? && allowed_to?(:destroy?, @object)
52
- c.with_button(
53
- text: t("admin.actions.delete"),
54
- to: [:admin, @object],
55
- method: "delete",
56
- data: { turbo_confirm: t("admin.#{model_collection}.destroy.confirm") },
57
- color: :tomato,
58
- position: :right,
59
- )
60
- end
51
+ c.with_delete_button(object: @object, model_collection: model_collection)
data/lib/trek/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Trek
4
- VERSION = "0.1.17"
4
+ VERSION = "0.1.19"
5
5
  end
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etaminstudio/trek",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "A modern CMS for Ruby on Rails",
5
5
  "main": "app/javascript/trek.js",
6
6
  "repository": {
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trek
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.1.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mohamed Bengrich