Add Trix editor to trips

This commit is contained in:
Eugene Burmakin 2024-11-28 12:00:54 +01:00
parent b712332277
commit 2cfc485f12
16 changed files with 219 additions and 34 deletions

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,45 @@
/*
* Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
* the trix-editor content (whether displayed or under editing). Feel free to incorporate this
* inclusion directly in any other asset bundle and remove this file.
*
*= require trix
*/
/*
* We need to override trix.csss image gallery styles to accommodate the
* <action-text-attachment> element we wrap around attachments. Otherwise,
* images in galleries will be squished by the max-width: 33%; rule.
*/
.trix-content .attachment-gallery > action-text-attachment,
.trix-content .attachment-gallery > .attachment {
flex: 1 0 33%;
padding: 0 0.5em;
max-width: 33%;
}
.trix-content .attachment-gallery.attachment-gallery--2 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--2 > .attachment, .trix-content .attachment-gallery.attachment-gallery--4 > action-text-attachment,
.trix-content .attachment-gallery.attachment-gallery--4 > .attachment {
flex-basis: 50%;
max-width: 50%;
}
.trix-content action-text-attachment .attachment {
padding: 0 !important;
max-width: 100% !important;
}
/* Hide both attach files and attach images buttons in trix editor*/
.trix-button-group.trix-button-group--file-tools {
display:none;
}
/* Color buttons in white */
.trix-button-row button {
background-color: white !important;
}
.trix-content {
min-height: 20rem;
}

View file

@ -12,3 +12,4 @@
} }
*/ */
@import 'actiontext.css';

View file

@ -55,6 +55,6 @@ class TripsController < ApplicationController
end end
def trip_params def trip_params
params.require(:trip).permit(:name, :started_at, :ended_at, :notes) params.require(:trip).permit(:name, :started_at, :ended_at, :notes, :field_notes)
end end
end end

View file

@ -9,3 +9,6 @@ import "leaflet-providers"
import "chartkick" import "chartkick"
import "Chart.bundle" import "Chart.bundle"
import "./channels" import "./channels"
import "trix"
import "@rails/actiontext"

View file

@ -1,6 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class Trip < ApplicationRecord class Trip < ApplicationRecord
has_rich_text :field_notes
belongs_to :user belongs_to :user
validates :name, :started_at, :ended_at, presence: true validates :name, :started_at, :ended_at, presence: true

View file

@ -0,0 +1,14 @@
<figure class="attachment attachment--<%= blob.representable? ? "preview" : "file" %> attachment--<%= blob.filename.extension %>">
<% if blob.representable? %>
<%= image_tag blob.representation(resize_to_limit: local_assigns[:in_gallery] ? [ 800, 600 ] : [ 1024, 768 ]) %>
<% end %>
<figcaption class="attachment__caption">
<% if caption = blob.try(:caption) %>
<%= caption %>
<% else %>
<span class="attachment__name"><%= blob.filename %></span>
<span class="attachment__size"><%= number_to_human_size blob.byte_size %></span>
<% end %>
</figcaption>
</figure>

View file

@ -0,0 +1,3 @@
<div class="trix-content">
<%= yield %>
</div>

View file

@ -29,8 +29,8 @@
</div> </div>
<div class="form-control w-full mt-4 mb-4"> <div class="form-control w-full mt-4 mb-4">
<%= form.label :notes %> <%= form.label :field_notes %>
<%= form.text_area :notes, class: 'textarea textarea-bordered w-full', rows: 10 %> <%= form.rich_text_area :field_notes %>
</div> </div>
<div class="inline mb-4"> <div class="inline mb-4">

View file

@ -33,18 +33,8 @@
</div> </div>
</div> </div>
<div class="w-full"> <div class="w-full">
<div class="prose"> <div class="min-h-20">
<p> <%= @trip.field_notes.body %>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
<br>
<p>
At vero eos et accusam et justo duo dolores et ea rebum.
</p>
<br>
<p>
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div> </div>
<!-- Photos Grid Section --> <!-- Photos Grid Section -->

View file

@ -22,3 +22,5 @@ pin_all_from 'app/javascript/channels', under: 'channels'
pin 'notifications_channel', to: 'channels/notifications_channel.js' pin 'notifications_channel', to: 'channels/notifications_channel.js'
pin 'points_channel', to: 'channels/points_channel.js' pin 'points_channel', to: 'channels/points_channel.js'
pin 'imports_channel', to: 'channels/imports_channel.js' pin 'imports_channel', to: 'channels/imports_channel.js'
pin "trix"
pin "@rails/actiontext", to: "actiontext.esm.js"

View file

@ -0,0 +1,26 @@
# This migration comes from action_text (originally 20180528164100)
class CreateActionTextTables < ActiveRecord::Migration[6.0]
def change
# Use Active Record's configured type for primary and foreign keys
primary_key_type, foreign_key_type = primary_and_foreign_key_types
create_table :action_text_rich_texts, id: primary_key_type do |t|
t.string :name, null: false
t.text :body, size: :long
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
t.timestamps
t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
end
end
private
def primary_and_foreign_key_types
config = Rails.configuration.generators
setting = config.options[config.orm][:primary_key_type]
primary_key_type = setting || :primary_key
foreign_key_type = setting || :bigint
[ primary_key_type, foreign_key_type ]
end
end

12
db/schema.rb generated
View file

@ -10,10 +10,20 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2024_11_27_161621) do ActiveRecord::Schema[7.2].define(version: 2024_11_28_095325) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
create_table "action_text_rich_texts", force: :cascade do |t|
t.string "name", null: false
t.text "body"
t.string "record_type", null: false
t.bigint "record_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
end
create_table "active_storage_attachments", force: :cascade do |t| create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "record_type", null: false t.string "record_type", null: false

59
package-lock.json generated
View file

@ -6,7 +6,9 @@
"": { "": {
"dependencies": { "dependencies": {
"@hotwired/turbo-rails": "^7.3.0", "@hotwired/turbo-rails": "^7.3.0",
"leaflet": "^1.9.4" "@rails/actiontext": "^8.0.0",
"leaflet": "^1.9.4",
"trix": "^2.1.8"
}, },
"devDependencies": { "devDependencies": {
"daisyui": "^4.7.3" "daisyui": "^4.7.3"
@ -34,6 +36,25 @@
"resolved": "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz", "resolved": "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz",
"integrity": "sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA==" "integrity": "sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA=="
}, },
"node_modules/@rails/actiontext": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@rails/actiontext/-/actiontext-8.0.0.tgz",
"integrity": "sha512-8pvXDEHqlVHptzfYDUXmBpstHsfHAVacYxO47cWDRjRmp1zdVXusLcom8UvqkRdTcAPXpte+LkjcfpD9S4DSSQ==",
"dependencies": {
"@rails/activestorage": ">= 8.0.0-alpha"
},
"peerDependencies": {
"trix": "^2.0.0"
}
},
"node_modules/@rails/activestorage": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@rails/activestorage/-/activestorage-8.0.0.tgz",
"integrity": "sha512-qoA7U1gMcWXhDnImwDIyRQDXkQKzThT2lu2Xpim8CnTOCEeAgkQ5Co2kzodpAI2grF1JSDvwXSPYNWwVAswndA==",
"dependencies": {
"spark-md5": "^3.0.1"
}
},
"node_modules/camelcase-css": { "node_modules/camelcase-css": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -186,6 +207,16 @@
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
} }
},
"node_modules/spark-md5": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
},
"node_modules/trix": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/trix/-/trix-2.1.8.tgz",
"integrity": "sha512-y1h5mKQcjMsZDsUOqOgyIUfw+Z31u4Fe9JqXtKGUzIC7FM9cTpxZFFWxQggwXBo18ccIKYx1Fn9toVO5mCpn9g=="
} }
}, },
"dependencies": { "dependencies": {
@ -208,6 +239,22 @@
"resolved": "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz", "resolved": "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz",
"integrity": "sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA==" "integrity": "sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA=="
}, },
"@rails/actiontext": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@rails/actiontext/-/actiontext-8.0.0.tgz",
"integrity": "sha512-8pvXDEHqlVHptzfYDUXmBpstHsfHAVacYxO47cWDRjRmp1zdVXusLcom8UvqkRdTcAPXpte+LkjcfpD9S4DSSQ==",
"requires": {
"@rails/activestorage": ">= 8.0.0-alpha"
}
},
"@rails/activestorage": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/@rails/activestorage/-/activestorage-8.0.0.tgz",
"integrity": "sha512-qoA7U1gMcWXhDnImwDIyRQDXkQKzThT2lu2Xpim8CnTOCEeAgkQ5Co2kzodpAI2grF1JSDvwXSPYNWwVAswndA==",
"requires": {
"spark-md5": "^3.0.1"
}
},
"camelcase-css": { "camelcase-css": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -299,6 +346,16 @@
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
"dev": true, "dev": true,
"peer": true "peer": true
},
"spark-md5": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
},
"trix": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/trix/-/trix-2.1.8.tgz",
"integrity": "sha512-y1h5mKQcjMsZDsUOqOgyIUfw+Z31u4Fe9JqXtKGUzIC7FM9cTpxZFFWxQggwXBo18ccIKYx1Fn9toVO5mCpn9g=="
} }
} }
} }

View file

@ -1,7 +1,10 @@
{ {
"dependencies": { "dependencies": {
"@hotwired/turbo-rails": "^7.3.0", "@hotwired/turbo-rails": "^7.3.0",
"leaflet": "^1.9.4" "@rails/actiontext": "^8.0.0",
"leaflet": "^1.9.4",
"postcss": "^8.4.49",
"trix": "^2.1.8"
}, },
"devDependencies": { "devDependencies": {
"daisyui": "^4.7.3" "daisyui": "^4.7.3"

View file

@ -20,6 +20,20 @@
resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz" resolved "https://registry.npmjs.org/@rails/actioncable/-/actioncable-7.1.3.tgz"
integrity sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA== integrity sha512-ojNvnoZtPN0pYvVFtlO7dyEN9Oml1B6IDM+whGKVak69MMYW99lC2NOWXWeE3bmwEydbP/nn6ERcpfjHVjYQjA==
"@rails/actiontext@^8.0.0":
version "8.0.0"
resolved "https://registry.npmjs.org/@rails/actiontext/-/actiontext-8.0.0.tgz"
integrity sha512-8pvXDEHqlVHptzfYDUXmBpstHsfHAVacYxO47cWDRjRmp1zdVXusLcom8UvqkRdTcAPXpte+LkjcfpD9S4DSSQ==
dependencies:
"@rails/activestorage" ">= 8.0.0-alpha"
"@rails/activestorage@>= 8.0.0-alpha":
version "8.0.0"
resolved "https://registry.npmjs.org/@rails/activestorage/-/activestorage-8.0.0.tgz"
integrity sha512-qoA7U1gMcWXhDnImwDIyRQDXkQKzThT2lu2Xpim8CnTOCEeAgkQ5Co2kzodpAI2grF1JSDvwXSPYNWwVAswndA==
dependencies:
spark-md5 "^3.0.1"
camelcase-css@^2.0.1: camelcase-css@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz"
@ -64,15 +78,20 @@ leaflet@^1.9.4:
integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA== integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==
nanoid@^3.3.7: nanoid@^3.3.7:
version "3.3.7" version "3.3.8"
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
picocolors@^1, picocolors@^1.0.0: picocolors@^1:
version "1.0.0" version "1.0.0"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
postcss-js@^4: postcss-js@^4:
version "4.0.1" version "4.0.1"
resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz"
@ -80,16 +99,26 @@ postcss-js@^4:
dependencies: dependencies:
camelcase-css "^2.0.1" camelcase-css "^2.0.1"
postcss@^8.4.21: postcss@^8.4.49:
version "8.4.35" version "8.4.49"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz" resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz#4ea479048ab059ab3ae61d082190fabfd994fe19"
integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
dependencies: dependencies:
nanoid "^3.3.7" nanoid "^3.3.7"
picocolors "^1.0.0" picocolors "^1.1.1"
source-map-js "^1.0.2" source-map-js "^1.2.1"
source-map-js@^1.0.2: source-map-js@^1.2.1:
version "1.0.2" version "1.2.1"
resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
spark-md5@^3.0.1:
version "3.0.2"
resolved "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz"
integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==
trix@^2.1.8:
version "2.1.8"
resolved "https://registry.npmjs.org/trix/-/trix-2.1.8.tgz#b9383af8cd9c1a0a0818d6b4e0c9e771bf7fd564"
integrity sha512-y1h5mKQcjMsZDsUOqOgyIUfw+Z31u4Fe9JqXtKGUzIC7FM9cTpxZFFWxQggwXBo18ccIKYx1Fn9toVO5mCpn9g==