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 all 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
63 changes: 63 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: JS Build

on:
pull_request:
types: [opened, synchronize]
push:
branches:
- main

jobs:
check_yarn_lock:
runs-on: ubuntu-latest
name: Check yarn.lock
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get all changed markdown files
id: changed-yarn-lock
uses: tj-actions/changed-files@v41
with:
files: yarn.lock
outputs:
yarn_lock_changed: ${{ steps.changed-yarn-lock.outputs.any_changed }}
build:
runs-on: ubuntu-latest
name: Build JS packages
needs: check_yarn_lock
if: ${{ needs.check_yarn_lock.outputs.yarn_lock_changed }}
permissions:
contents: write
pull-requests: read
steps:
- uses: actions/checkout@v4
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: Check git status
id: git-status
run: git diff --quiet || echo "::set-output name=changed::true"
- name: git push
if: steps.git-status.outputs.changed == true
run: |
git config --local user.name 'AlchemyCMS - CI Bot'
git config --local user.email '[email protected]'
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 "Rebuilt packages due to updated dependencies."
git push origin HEAD:${{ github.event.pull_request.head.ref }}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ node_modules
yarn-error.log
yarn-debug.log*
.yarn-integrity
yarn.lock
/spec/dummy/public/pictures
.byebug_history
.vscode/
2 changes: 1 addition & 1 deletion alchemy_cms.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
gem.requirements << "ImageMagick (libmagick), v6.6 or greater."
gem.required_ruby_version = ">= 3.0.0"
gem.license = "BSD New"
gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
gem.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/|yarn|^\.}) }
gem.require_paths = ["lib"]

%w[
Expand Down
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
4 changes: 0 additions & 4 deletions app/assets/javascripts/alchemy/admin.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
// 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
11 changes: 4 additions & 7 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import "@ungap/custom-elements"
import "@hotwired/turbo-rails"
import "keymaster"

import Rails from "@rails/ujs"

import GUI from "alchemy_admin/gui"
Expand Down Expand Up @@ -31,14 +33,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
23 changes: 9 additions & 14 deletions config/importmap.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
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:[email protected]/dist/esm/index.js", preload: true
pin "lodash-es/debounce", to: "https://ga.jspm.io/npm:[email protected]/debounce.js", preload: true
pin "lodash-es/max", to: "https://ga.jspm.io/npm:[email protected]/max.js", preload: true
pin "sortablejs", to: "https://ga.jspm.io/npm:[email protected]/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 "keymaster", to: "keymaster.min.js", preload: true
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/[email protected]/cdn/utilities/animation-registry.js", preload: true
pin "@shoelace/switch", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/switch/switch.js", preload: true
pin "@shoelace/tab", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/tab/tab.js", preload: true
pin "@shoelace/tab-group", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/tab-group/tab-group.js", preload: true
pin "@shoelace/tab-panel", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/tab-panel/tab-panel.js", preload: true
pin "@shoelace/tooltip", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/tooltip/tooltip.js", preload: true
pin "@shoelace/progress-bar", to: "https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/cdn/components/progress-bar/progress-bar.js", preload: true
pin "@rails/ujs", to: "https://ga.jspm.io/npm:@rails/[email protected]/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
24 changes: 18 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,35 @@
"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",
"keymaster": "^1.6.2",
"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 All @@ -28,7 +39,8 @@
},
"moduleNameMapper": {
"alchemy_admin/(.*)": "<rootDir>/app/javascript/alchemy_admin/$1",
"vendor/(.*)": "<rootDir>/vendor/assets/javascripts/$1"
"assets/(.*)": "<rootDir>/vendor/assets/javascripts/$1",
"vendor/(.*)": "<rootDir>/vendor/javascript/$1"
},
"testEnvironment": "jsdom",
"roots": [
Expand Down
Loading
Loading