Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/ci_multipod_iframe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
env:
CI: "true"
RUBY_VERSION: 3.2.2
NODE_VERSION: 18.17.1
NODE_VERSION: 22.14.0

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
Expand Down
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.17.1
22.14.0
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ ruby RUBY_VERSION
gem "decidim", "~> 0.29.5"
gem "decidim-multipod_iframe", path: "."

gem "puma", ">= 6.3.1"
gem "bootsnap", "~> 1.4"
gem "puma", ">= 6.3.1"

group :development, :test do
gem "byebug", "~> 11.0", platform: :mri
Expand Down
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PATH
specs:
decidim-multipod_iframe (1.0.0)
decidim-core (~> 0.29)
deface (>= 1.9)

GEM
remote: https://rubygems.org/
Expand Down Expand Up @@ -320,6 +321,12 @@ GEM
declarative-builder (0.2.0)
trailblazer-option (~> 0.1.0)
declarative-option (0.1.0)
deface (1.9.0)
actionview (>= 5.2)
nokogiri (>= 1.6)
polyglot
railties (>= 5.2)
rainbow (>= 2.1.0)
devise (4.9.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
Expand Down Expand Up @@ -591,6 +598,7 @@ GEM
pg_search (2.3.7)
activerecord (>= 6.1)
activesupport (>= 6.1)
polyglot (0.3.5)
premailer (1.27.0)
addressable
css_parser (>= 1.19.0)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Decidim::MultipodIframe

iframe for multipod.
Iframe for multipod.

## Usage

MultipodIframe will be available as a Component for a Participatory
Space.
MultipodIframe allows admins to enable an iframe that will be displayed on a proposal's show page.

## Installation

Expand All @@ -20,6 +19,7 @@ And then execute:
```bash
bundle
```
To enable the iframe, admins should go to the proposals component configuration page, check the "enable iframe" checkbox and provide the url of the iframe.

## Contributing

Expand Down
14 changes: 14 additions & 0 deletions app/helpers/decidim/multipod_iframe/iframe_proposal_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

module Decidim
module MultipodIframe
module IframeProposalHelper
def iframe_src(proposal)
content = "#{decidim_sanitize_translated(proposal.title)}. #{decidim_sanitize_translated(proposal.body)}"
content = CGI.escape(content).first(1000)
url = current_component.settings.iframe_url
url.include?("?") ? url + "&similarto=#{content}" : url + "?similarto=#{content}"
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!-- insert_after "div.item__edit.item__edit-1col" -->
<% if @component.manifest.name == :proposals %>
<%= append_javascript_pack_tag "decidim_multipod_iframe" %>
<% end %>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!-- insert_after "section.layout-aside__section.actions__secondary" -->
<% if current_component.settings.enable_iframe && current_component.settings.iframe_url.present? %>
<section class="layout-aside__section proposal-iframe">
<iframe width="100%" height="400" frameBorder="0" allowFullscreen src=<%= iframe_src(@proposal) %> ></iframe>
</section>
<% end %>
2 changes: 2 additions & 0 deletions app/packs/entrypoints/decidim_multipod_iframe.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
// Images
require.context("../images", true)

import "src/decidim/multipod_iframe/iframe_settings_proposal_component"
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// handle the iframe settings in proposals component
document.addEventListener("DOMContentLoaded", function(){
const iframeCheck = document.querySelector('input#component_settings_enable_iframe')
const urlDiv = document.querySelector("div.iframe_url_container")
const inputUrl = document.querySelector("input[name='component[settings][iframe_url]']")
const iframeLabelCheck = document.querySelector("label[for='component_settings_enable_iframe']")
const submitButton = document.querySelector("form button[type=submit]")
const lang = document.querySelector('html').getAttribute('lang')

if(iframeCheck){
let help_text = document.createElement('p')
help_text.style.fontSize = '14px'
help_text.style.fontWeight = '400'
help_text.style.color = '#3e4c5c'

let text;
switch (lang) {
case "fr":
text = "Autoriser un iframe qui sera affiché dans la vue show d'une proposition"
break;
case "de":
text = "Aktiviert einen iFrame, der auf der Übersichtsseite eines Angebots angezeigt wird"
break;
case "nl":
text = "Hiermee wordt een iframe ingeschakeld dat wordt weergegeven op de presentatiepagina van een voorstel"
break;
default:
text = "Enables an iframe that will be displayed on the proposal show page"
break;
}
help_text.textContent = text;
iframeLabelCheck.appendChild(help_text)
inputUrl.setAttribute("placeholder", "https://api.example.org")

if(iframeCheck.checked){
urlDiv.style.display = "block";
} else {
urlDiv.style.display = "none";
}
iframeCheck.addEventListener('change', function(){
if (this.checked) {
urlDiv.style.display = "block";
inputUrl.addEventListener("blur", checkUrl)
} else {
urlDiv.style.display = "none";
// allow to submit
submitButton.removeAttribute("disabled");
// remove error p if present
if (document.querySelector('p.url_input_error')){
inputUrl.parentNode.removeChild(document.querySelector('p.url_input_error'));
}
}
})
}
// check validity of urls when input looses focus
inputUrl.addEventListener("keyup", checkUrl)

function checkUrl(event){
const value = event.target.value;
const errors = [];
try {
// if value is not valid, it will throw a TypeError
const url = new URL(value);
} catch(error){
errors.push(error);
}
if(errors.length !== 0 && inputUrl.parentNode.lastChild === inputUrl){
// create p
const elem = document.createElement('p');
// create content depending on lang
let errorText;
switch (lang) {
case "fr":
errorText = "Url non valide"
break;
case "de":
errorText = "Ungültige URL"
break;
case "nl":
errorText = "Ongeldige URL"
break;
default:
errorText = "Invalid url"
break;
}
const newContent = document.createTextNode(errorText);
// add content to p
elem.appendChild(newContent);
// add style and class to p
elem.style.color = "red";
elem.classList.add('url_input_error');
// insert p after input
inputUrl.after(elem);
// block the create or update
submitButton.setAttribute("disabled", "true")
} else if(errors.length === 0 && inputUrl.parentNode.lastChild !== inputUrl){
const elem = document.querySelector('p.url_input_error');
inputUrl.parentNode.removeChild(elem);
submitButton.removeAttribute("disabled")
}
}
})
10 changes: 10 additions & 0 deletions app/packs/stylesheets/decidim/multipod_iframe/multipod_iframe.scss
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
/* css for decidim_multipod_iframe */

/* css for proposal_aside deface override */
.proposal-iframe {
width: 100%;

@screen xl {
width: 150%;
}
overflow: scroll;
}
11 changes: 11 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
de:
decidim:
components:
multipod_iframe:
name: Multipod Iframe
proposals:
settings:
global:
enable_iframe: Fügen Sie einen Iframe hinzu
iframe_url: URL des iFrames
5 changes: 5 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ en:
components:
multipod_iframe:
name: MultipodIframe
proposals:
settings:
global:
enable_iframe: Enable iframe
iframe_url: Url of the iframe
11 changes: 11 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
fr:
decidim:
components:
multipod_iframe:
name: Iframe Multipod
proposals:
settings:
global:
enable_iframe: Autoriser un iframe
iframe_url: Url de l'iframe
11 changes: 11 additions & 0 deletions config/locales/nl.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
nl:
decidim:
components:
multipod_iframe:
name: MultipodIframe
proposals:
settings:
global:
enable_iframe: Schakel iframe in
iframe_url: URL van de iframe
1 change: 1 addition & 0 deletions decidim-multipod_iframe.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ Gem::Specification.new do |s|
end

s.add_dependency "decidim-core", Decidim::MultipodIframe.decidim_version
s.add_dependency "deface", ">= 1.9"
end
5 changes: 5 additions & 0 deletions lib/decidim/multipod_iframe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,10 @@ module Decidim
# This namespace holds the logic of the `MultipodIframe` component. This component
# allows users to create multipod_iframe in a participatory space.
module MultipodIframe
include ActiveSupport::Configurable

config_accessor :deface_enabled do
ENV.fetch("DEFACE_ENABLED", nil) == "true" || Rails.env.test?
end
end
end
7 changes: 7 additions & 0 deletions lib/decidim/multipod_iframe/admin_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class AdminEngine < ::Rails::Engine
# end
# root to: "multipod_iframe#index"
end
initializer "decidim-dataspace.add_proposal_component_settings" do
manifest = Decidim.find_component_manifest("proposals")
manifest.settings(:global) do |settings|
settings.attribute :enable_iframe, type: :boolean, default: false
settings.attribute :iframe_url, type: :string
end
end

def load_seed
nil
Expand Down
16 changes: 16 additions & 0 deletions lib/decidim/multipod_iframe/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "rails"
require "decidim/core"
require "deface"

module Decidim
module MultipodIframe
Expand All @@ -15,6 +16,21 @@ class Engine < ::Rails::Engine
# root to: "multipod_iframe#index"
end

initializer "decidim-multipod_iframe.views" do
Rails.application.configure do
config.deface.enabled = Decidim::MultipodIframe.deface_enabled
end
end

initializer "decidim-multipod_iframe.add_customizations" do
config.to_prepare do
# Helper
Decidim::Proposals::ProposalsHelper.class_eval do
include Decidim::MultipodIframe::IframeProposalHelper
end
end
end

initializer "MultipodIframe.webpacker.assets_path" do
Decidim.register_assets_path File.expand_path("app/packs", root)
end
Expand Down
16 changes: 8 additions & 8 deletions lib/decidim/multipod_iframe/test/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
require "decidim/components/namer"
require "decidim/core/test/factories"

FactoryBot.define do
factory :multipod_iframe_component, parent: :component do
name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :multipod_iframe).i18n_name }
manifest_name :multipod_iframe
participatory_space { create(:participatory_process, :with_steps) }
end
# FactoryBot.define do
# factory :multipod_iframe_component, parent: :component do
# name { Decidim::Components::Namer.new(participatory_space.organization.available_locales, :multipod_iframe).i18n_name }
# manifest_name :multipod_iframe
# participatory_space { create(:participatory_process, :with_steps) }
# end

# Add engine factories here
end
# Add engine factories here
# end
Loading
Loading