Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Download and bundle third party JS packages with npm #2679

Merged
merged 17 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
groups:
babel:
dependency-type: "development"
patterns:
- "@babel/*"
update-types:
- "minor"
- "patch"
jest:
dependency-type: "development"
patterns:
- "jest*"
- "babel-jest"
update-types:
- "minor"
- "patch"
rollup:
dependency-type: "development"
patterns:
- "@rollup/*"
- "rollup"
update-types:
- "minor"
- "patch"
versioning-strategy: increase-if-necessary
41 changes: 41 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build new JS packages

on:
pull_request:
types: [opened, synchronize]

permissions:
contents: write
pull-requests: read

jobs:
Build:
if: ${{ github.actor == 'dependabot[bot]' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup Node
uses: actions/setup-node@v3
with:
cache: "yarn"
- name: Restore node_modules cache
uses: actions/cache@v3
with:
path: node_modules
key: ${{ runner.os }}-node-modules-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-node-modules
- name: Install dependencies
run: yarn install
- name: YARN build
run: yarn build
- name: git push
run: |
git config --local user.name 'AlchemyCMS - CI Bot'
git config --local user.email 'alchemy@blish.cloud'
git remote set-url origin https://x-access-token:${{ secrets.ALCHEMY_CI_BOT_ACCESS_TOKEN }}@github.com/$GITHUB_REPOSITORY
git add vendor/javascript
git commit -m "Update JS packages" -m "Dependabot updated dependencies."
git push origin HEAD:${{ github.event.pull_request.head.ref }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,5 @@ node_modules
yarn-error.log
yarn-debug.log*
.yarn-integrity
yarn.lock
/spec/dummy/public/pictures
.byebug_history
2 changes: 1 addition & 1 deletion app/assets/config/alchemy_manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
//= link alchemy/print.css
//= link alchemy/welcome.css
//= link tinymce/plugins/alchemy_link/plugin.min.js
//= link tinymce/tinymce.min.js
//= link_directory ../stylesheets/tinymce/skins/ui/alchemy/ .css
//= link_directory ../stylesheets/tinymce/skins/content/alchemy/ .css
//= link_tree ../images/alchemy/
//= link_tree ../../../vendor/assets/fonts/
//= link_tree ../../../vendor/assets/images/
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
3 changes: 0 additions & 3 deletions app/assets/javascripts/alchemy/admin.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// Alchemy CMS Sprockets Manifest
// ------------------------------
//= require jquery3
//= require tinymce/tinymce.min
//= require_tree ../../../../vendor/assets/javascripts/jquery_plugins/
//= require clipboard.min
//= require keymaster
//= require requestAnimationFrame
//= require handlebars
//= require alchemy/templates
//= require alchemy/alchemy.dialog
Expand Down
9 changes: 2 additions & 7 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,9 @@ import "alchemy_admin/components/page_select"
import "alchemy_admin/components/select"
import "alchemy_admin/components/spinner"
import "alchemy_admin/components/tinymce"
import "@shoelace/progress-bar"
import "@shoelace/switch"
import "@shoelace/tab"
import "@shoelace/tab-group"
import "@shoelace/tab-panel"
import "@shoelace/tooltip"
import "alchemy_admin/clipboard"

import { setDefaultAnimation } from "@shoelace/animation-registry"
import { setDefaultAnimation } from "shoelace"

// Change the default animation for all dialogs
setDefaultAnimation("tooltip.show", {
Expand Down
16 changes: 16 additions & 0 deletions app/javascript/alchemy_admin/clipboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import "clipboard"

const clipboard = new ClipboardJS("[data-clipboard-text]")

clipboard.on("success", (e) => {
Alchemy.growl(e.trigger.dataset.clipboardSuccessText)
e.clearSelection()
})

const currentDialog = Alchemy.currentDialog()

if (currentDialog) {
currentDialog.dialog.on("DialogClose.Alchemy", () => {
clipboard.destroy()
})
}
1 change: 1 addition & 0 deletions app/javascript/alchemy_admin/components/tinymce.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "tinymce"
import { AlchemyHTMLElement } from "alchemy_admin/components/alchemy_html_element"
import { currentLocale } from "alchemy_admin/i18n"

Expand Down
6 changes: 4 additions & 2 deletions app/javascript/alchemy_admin/picture_editors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import debounce from "lodash-es/debounce"
import max from "lodash-es/max"
import debounce from "alchemy_admin/utils/debounce"
import max from "alchemy_admin/utils/max"
import { get } from "alchemy_admin/utils/ajax"
import ImageLoader from "alchemy_admin/image_loader"

Expand Down Expand Up @@ -27,6 +27,8 @@ class PictureEditor {
this.imageLoader = new ImageLoader(this.image)
}

// The mutation observer is observing multiple fields that all get updated
// simultaneously. We only want to update the image once, so we debounce.
this.update = debounce(() => {
this.updateImage()
this.updateCropLink()
Expand Down
10 changes: 10 additions & 0 deletions app/javascript/alchemy_admin/utils/debounce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function (func, delay) {
let timeout

return function (...args) {
const that = this

clearTimeout(timeout)
timeout = setTimeout(() => func.apply(that, args), delay)
}
}
3 changes: 3 additions & 0 deletions app/javascript/alchemy_admin/utils/max.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function (a, b) {
return a >= b ? a : b
}
17 changes: 2 additions & 15 deletions app/views/alchemy/admin/attachments/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
<div class="value with-icon">
<label><%= Alchemy::Attachment.human_attribute_name(:url) %></label>
<p><%= @attachment.url %></p>
<a data-clipboard-text="<%= @attachment.url %>" class="icon_button--right">
<a data-clipboard-text="<%= @attachment.url %>" data-clipboard-success-text="<%= Alchemy.t("Copied to clipboard") %>" class="icon_button--right">
<%= render_icon(:clipboard) %>
</a>
</div>
<div class="value with-icon">
<label><%= Alchemy::Attachment.human_attribute_name(:download_url) %></label>
<p><%= @attachment.url(download: true) %></p>
<a data-clipboard-text="<%= @attachment.url(download: true) %>" class="icon_button--right">
<a data-clipboard-text="<%= @attachment.url(download: true) %>" data-clipboard-success-text="<%= Alchemy.t("Copied to clipboard") %>" class="icon_button--right">
<%= render_icon(:clipboard) %>
</a>
</div>
Expand All @@ -39,16 +39,3 @@
Your browser does not support frames.
</iframe>
<% end %>

<script type="text/javascript">
$(function() {
var clipboard = new Clipboard('.icon_button--right');
clipboard.on('success', function(e) {
Alchemy.growl('<%= Alchemy.t("Copied to clipboard") %>');
e.clearSelection();
});
Alchemy.currentDialog().dialog.on('DialogClose.Alchemy', function() {
clipboard.destroy();
});
});
</script>
10 changes: 10 additions & 0 deletions bundles/shoelace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Used to bundle our own Shoelace build with Rollup
import "@shoelace-style/shoelace/dist/utilities/animation-registry.js"
import "@shoelace-style/shoelace/dist/components/switch/switch.js"
import "@shoelace-style/shoelace/dist/components/tab/tab.js"
import "@shoelace-style/shoelace/dist/components/tab-group/tab-group.js"
import "@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js"
import "@shoelace-style/shoelace/dist/components/tooltip/tooltip.js"
import "@shoelace-style/shoelace/dist/components/progress-bar/progress-bar.js"
import { setDefaultAnimation } from "@shoelace-style/shoelace/dist/utilities/animation-registry.js"
export { setDefaultAnimation }
20 changes: 20 additions & 0 deletions bundles/tinymce.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* Import TinyMCE */
import tinymce from "tinymce"

/* Default icons are required. After that, import custom icons if applicable */
import "tinymce/icons/default"

/* Required TinyMCE components */
import "tinymce/themes/silver"
import "tinymce/models/dom"

/* Import plugins */
import "tinymce/plugins/anchor"
import "tinymce/plugins/charmap"
import "tinymce/plugins/code"
import "tinymce/plugins/directionality"
import "tinymce/plugins/fullscreen"
import "tinymce/plugins/link"
import "tinymce/plugins/lists"

export default tinymce
22 changes: 8 additions & 14 deletions config/importmap.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
pin "@ungap/custom-elements", to: "https://ga.jspm.io/npm:@ungap/custom-elements@1.3.0/index.js", preload: true
pin "flatpickr", to: "https://ga.jspm.io/npm:flatpickr@4.6.13/dist/esm/index.js", preload: true
pin "lodash-es/debounce", to: "https://ga.jspm.io/npm:lodash-es@4.17.21/debounce.js", preload: true
pin "lodash-es/max", to: "https://ga.jspm.io/npm:lodash-es@4.17.21/max.js", preload: true
pin "sortablejs", to: "https://ga.jspm.io/npm:sortablejs@1.15.1/modular/sortable.esm.js", preload: true
pin "@ungap/custom-elements", to: "ungap-custom-elements.min.js", preload: true # @1.3.0
pin "clipboard", to: "clipboard.min.js", preload: true
pin "flatpickr", to: "flatpickr.min.js", preload: true # @4.6.13
pin "sortablejs", to: "sortable.min.js", preload: true # @1.15.1
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@shoelace/animation-registry", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/utilities/animation-registry.js", preload: true
pin "@shoelace/switch", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/switch/switch.js", preload: true
pin "@shoelace/tab", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tab/tab.js", preload: true
pin "@shoelace/tab-group", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tab-group/tab-group.js", preload: true
pin "@shoelace/tab-panel", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tab-panel/tab-panel.js", preload: true
pin "@shoelace/tooltip", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/tooltip/tooltip.js", preload: true
pin "@shoelace/progress-bar", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.12.0/cdn/components/progress-bar/progress-bar.js", preload: true
pin "@rails/ujs", to: "https://ga.jspm.io/npm:@rails/ujs@7.1.2/app/assets/javascripts/rails-ujs.esm.js"
pin "shoelace", to: "shoelace.min.js", preload: true
pin "@rails/ujs", to: "rails-ujs.min.js", preload: true # @7.1.2
pin "tinymce", to: "tinymce.min.js", preload: true

pin "alchemy_admin", to: "alchemy_admin.js", preload: true
pin_all_from File.expand_path("../app/javascript/alchemy_admin", __dir__), under: "alchemy_admin"
pin_all_from File.expand_path("../app/javascript/alchemy_admin", __dir__), under: "alchemy_admin", preload: true
3 changes: 2 additions & 1 deletion lib/alchemy/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class Engine < Rails::Engine
Alchemy.importmap.draw(Engine.root.join("config", "importmap.rb"))

package_path = Engine.root.join("app/javascript")
app.config.assets.paths << package_path
vendor_packages_path = Engine.root.join("vendor/javascript")
app.config.assets.paths += [package_path, vendor_packages_path]

if app.config.importmap.sweep_cache
Alchemy.importmap.cache_sweeper(watches: package_path)
Expand Down
2 changes: 1 addition & 1 deletion lib/alchemy/tinymce.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def init
end

def preloadable_plugins
@@plugins
@@plugins - DEFAULT_PLUGINS
end
end
end
Expand Down
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,34 @@
"name": "alchemy_admin",
"scripts": {
"test": "jest",
"lint": "prettier --check 'app/javascript/**/*.js'"
"lint": "prettier --check 'app/javascript/**/*.js'",
"build": "rollup -c"
},
"keywords": [],
"author": "Thomas von Deyen",
"license": "BSD-3-Clause",
"dependencies": {},
"dependencies": {
"@rails/ujs": "^7.1.2",
"@shoelace-style/shoelace": "^2.12.0",
"@ungap/custom-elements": "^1.3.0",
"clipboard": "^2.0.11",
"flatpickr": "^4.6.13",
"sortablejs": "^1.15.1",
"tinymce": "^6.8.2"
},
"devDependencies": {
"@babel/core": "^7.22.11",
"@babel/preset-env": "^7.22.11",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"babel-jest": "^29.6.4",
"flatpickr": "^4.6.9",
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"jquery": "^3.7.1",
"jsdom-testing-mocks": "^1.11.0",
"lodash-es": "^4.17.21",
"prettier": "^3.0.0",
"sortablejs": "^1.10.2",
"rollup": "^4.9.3",
"xhr-mock": "^2.5.1"
},
"jest": {
Expand Down
57 changes: 57 additions & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import resolve from "@rollup/plugin-node-resolve"
import commonjs from "@rollup/plugin-commonjs"
import terser from "@rollup/plugin-terser"

export default [
{
input: "node_modules/clipboard/dist/clipboard.min.js",
output: {
file: "vendor/javascript/clipboard.min.js"
},
context: "window"
},
{
input: "node_modules/flatpickr/dist/esm/index.js",
output: {
file: "vendor/javascript/flatpickr.min.js"
},
plugins: [resolve(), terser()],
context: "window"
},
{
input: "node_modules/sortablejs/modular/sortable.esm.js",
output: {
file: "vendor/javascript/sortable.min.js"
},
plugins: [terser()]
},
{
input: "node_modules/@ungap/custom-elements/min.js",
output: {
file: "vendor/javascript/ungap-custom-elements.min.js"
}
},
{
input: "node_modules/@rails/ujs/app/assets/javascripts/rails-ujs.esm.js",
output: {
file: "vendor/javascript/rails-ujs.min.js"
},
plugins: [terser()]
},
{
input: "bundles/shoelace.js",
output: {
file: "vendor/javascript/shoelace.min.js"
},
plugins: [resolve(), terser()]
},
{
input: "bundles/tinymce.js",
output: {
file: "vendor/javascript/tinymce.min.js",
name: "tinymce",
format: "esm"
},
plugins: [resolve(), commonjs(), terser()]
}
]
Loading
Loading