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

Resplit audience and visibility (pub status) #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
62 changes: 37 additions & 25 deletions app/assets/stylesheets/main_backoffice.scss
Original file line number Diff line number Diff line change
Expand Up @@ -178,37 +178,49 @@ span.visibility {
}

// ---------------------------------------------------------------- new visibility
.visibility-radios {
.visibility-container {
margin-left: 1em;
background-color: #fff;
padding: 4px 4px 0 4px;
border-radius: 5px;
box-sizing: border-box;
display: inline-block;

label {
padding: 0.05em 0.2em;
display: inline-block;
margin-right: 0;
cursor: pointer;
border-bottom: 2px solid #fff;
border-radius: 15%;
span {
transition: transform .2s ease-in-out;
display: inline-flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
span.text {
font-size: 60%;
// line-height: 60%;
// margin-top: -1ex;
position: relative;
}
.visibility-radios {
border-bottom: 1px solid #d9d9d9;
label {
padding: 0.05em 0.2em;
display: inline-block;
margin-right: 0;
cursor: pointer;
border-bottom: 2px solid #fff;
border-radius: 15%;
span {
transition: transform .2s ease-in-out;
}
span:hover {
top: -0.5ex;
transform: scale(1.25);
color: var(--red);
}
}
span:hover {
top: -0.5ex;
transform: scale(1.25);
color: var(--red);
input[type="radio"] {
display: none;
}
}
input[type="radio"] {
display: none;
}
input[type="radio"]:checked + label {
box-shadow: inset 0 0 2px #666;
border-bottom: 2px solid var(--red);
span {
color: var(--red-dark);
input[type="radio"]:checked + label {
box-shadow: inset 0 0 2px #666;
border-bottom: 2px solid var(--red);
span {
color: var(--red-dark);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/awards_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def set_award
def award_params
params.require(:award).permit(
:location, :title_fr, :title_en, :year, :issuer,
:audience, :visible, :position
:audience, :visibility, :position
)
end
end
2 changes: 1 addition & 1 deletion app/controllers/boxes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,6 @@ def set_box

# Only allow a list of trusted parameters through.
def box_params
params.require(:box).permit(:audience, :position)
params.require(:box).permit(:audience, :visibility, :position)
end
end
2 changes: 1 addition & 1 deletion app/controllers/educations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def set_education
def education_params
params.require(:education).permit(
:title_en, :title_fr, :field_en, :field_fr, :director, :school,
:year_begin, :year_end, :position, :audience, :visible, :description_fr, :description_en
:year_begin, :year_end, :position, :audience, :visibility, :description_fr, :description_en
)
end
end
2 changes: 1 addition & 1 deletion app/controllers/experiences_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def set_experience
def experience_params
params.require(:experience).permit(
:location, :title_fr, :title_en, :year_begin, :year_end,
:audience, :visible, :position, :description_fr, :description_en
:audience, :visibility, :position, :description_fr, :description_en
)
end
end
2 changes: 1 addition & 1 deletion app/controllers/index_boxes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ def set_box

# Only allow a list of trusted parameters through.
def box_params
params.require(:index_box).permit(:audience)
params.require(:index_box).permit(:audience, :visibility)
end
end
2 changes: 1 addition & 1 deletion app/controllers/publications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ def set_publication
end

def publication_params
params.require(:publication).permit(:title, :journal, :year, :authors, :url, :position, :audience, :visible)
params.require(:publication).permit(:title, :journal, :year, :authors, :url, :position, :audience, :visibility)
end
end
2 changes: 1 addition & 1 deletion app/controllers/rich_text_boxes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def set_box
# Only allow a list of trusted parameters through.
def box_params
params.require(:rich_text_box).permit(
:audience,
:audience, :visibility,
:title_fr, :title_en, :content_fr, :content_en
)
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/socials_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def toggle
private

def social_params
params.require(:social).permit(:tag, :value, :audience)
params.require(:social).permit(:tag, :value, :audience, :visibility)
end

def set_profile
Expand Down
38 changes: 24 additions & 14 deletions app/helpers/profiles_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,34 +80,44 @@ def audience_selector2(form)
safe_join(content)
end

AUDIENCE_OPTIONS = [
{ label: 'public', icon: 'globe' },
{ label: 'intranet', icon: 'home' },
# {label: 'authenticated', icon: 'key'},
# {label: 'owner', icon: 'user-check'},
{ label: 'authenticated', icon: 'user-check' },
{ label: 'owner', icon: 'edit-3' },
{ label: 'hidden', icon: 'eye-off' }
].freeze

def audience_selector(form, with_stimulus: false)
id0 = "#{form.object_name.underscore}_#{form.object.id}"
id0 = "#{form.object_name.underscore}_audience_#{form.object.id}"
stim_data = { action: "input->visibility#onChange", "visibility-target": "radio" }
content = []
AUDIENCE_OPTIONS.each_with_index do |o, i|
AudienceLimitable::AUDIENCE_OPTIONS.each_with_index do |o, i|
id = "#{id0}_#{i}"
label_data = { label: form.object.audience_label(i) }
title = t "visibility.labels.#{o[:label]}"
content << if with_stimulus
form.radio_button(:audience, i, id: id, data: stim_data)
form.radio_button(:audience, i, id: id, data: stim_data.merge(label_data))
else
form.radio_button(:audience, i, id: id)
form.radio_button(:audience, i, id: id, data: label_data)
end
content << form.label("audience_#{i}".to_sym, tag.span(icon(o[:icon])), for: id, title: title)
end
content = safe_join(content)
tag.div(content, class: "visibility-radios")
end

def visibility_selector(form, with_stimulus: false)
id0 = "#{form.object_name.underscore}_visibility_#{form.object.id}"
stim_data = { action: "input->visibility#onChange", "visibility-target": "radio" }
content = []
AudienceLimitable::VISIBILITY_OPTIONS.each_with_index do |o, i|
id = "#{id0}_#{i}"
label_data = { label: form.object.visibility_label(i) }
title = t "visibility.labels.#{o[:label]}"
content << if with_stimulus
form.radio_button(:visibility, i, id: id, data: stim_data.merge(label_data))
else
form.radio_button(:visibility, i, id: id, data: label_data)
end
content << form.label("visibility_#{i}".to_sym, tag.span(icon(o[:icon])), for: id, title: title)
end
content = safe_join(content)
tag.div(content, class: "visibility-radios")
end

def show_attribute_switch(form, attr)
id = "ck_#{form.object_name.gsub(/[^a-z0-9]+/, '_').gsub(/_$/, '')}_#{attr}"
tag.div(class: 'custom-control custom-checkbox') do
Expand Down
15 changes: 9 additions & 6 deletions app/javascript/controllers/visibility_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,33 @@ import { Controller } from "@hotwired/stimulus"
import { put } from "@rails/request.js";

export default class extends Controller {
static values = { model: String };
static targets = [ "radio" ];
static values = { model: String, field: String };
static targets = [ "form", "radio", "label"];

connect() {
this.oldRadio = this.radioTargets.find((x) => x.checked);
this.url = this.formTarget.action;
this.recovering = false;
}

onChange() {
if (this.recovering) {
console.log("Recovering");
this.recovering = false;
return;
}

const newRadio = this.radioTargets.find((x) => x.checked);

const value = newRadio.value;
const url = this.element.action;
const label = newRadio.getAttribute('data-label');
// JS shit!
const body = {};
body[this.modelValue] = {'audience': value};
put(url, {body: body}).then((response) => {
body[this.modelValue] = {};
body[this.modelValue][this.fieldValue] = value;
put(this.url, {body: body}).then((response) => {
if (response.ok) {
this.oldRadio = newRadio;
this.labelTarget.textContent=label;
} else {
// TODO: add flash message on error
// prevent onChange to fire again
Expand Down
51 changes: 38 additions & 13 deletions app/models/concerns/audience_limitable.rb
Original file line number Diff line number Diff line change
@@ -1,43 +1,68 @@
# frozen_string_literal: true

# This could be nicely implemented as enum but it is not yet implemented for mysql
# audience: 0=world, 1=intranet, 2=authenticated user
# visibility: 0=public, 1=draft, 2=hidden
# TODO: write unit tests
# TODO: when importing legacy data:
# - visible => audience=0
# - hidden => audience=4
# - visible => audience=0, visibility=0
# - hidden => audience=0, visibility=2

module AudienceLimitable
AUDIENCE_OPTIONS = [
{ label: 'public', icon: 'globe' },
{ label: 'intranet', icon: 'home' },
{ label: 'authenticated', icon: 'user-check' }
].freeze

VISIBILITY_OPTIONS = [
{ label: 'published', icon: 'eye' },
{ label: 'draft', icon: 'edit-3' },
{ label: 'hidden', icon: 'eye-off' }
].freeze

extend ActiveSupport::Concern

included do
scope :world_visible, -> { where(audience: 0) }
scope :intranet_visible, -> { where(audience: 0...2) }
scope :auth_visible, -> { where(audience: 0...3) }
scope :owner_visible, -> { where(audience: 0...4) }
scope :for_audience, ->(audience) { where(audience: 0...(audience + 1)) }
validates :audience, numericality: { in: 0...5 }
# Reminder: ranges do not include the upper limit
scope :world_visible, -> { where(audience: 0, visibility: 0) }
scope :intranet_visible, -> { where(audience: 0...2, visibility: 0) }
scope :auth_visible, -> { where(audience: 0...3, visibility: 0) }
scope :owner_visible, -> { where(visibility: 0...2) }
scope :for_audience, ->(audience) { where(audience: 0...(audience + 1), visibility: 0) }
validates :audience, numericality: { in: 0...3 }
validates :visibility, numericality: { in: 0...3 }
end

def visible_by?(level = 0)
audience <= level
end

def world_visible?
audience.zero?
visibilty.zero? && audience.zero?
end

def intranet_visible?
audience < 2
visibilty.zero? && audience < 2
end

def auth_visible?
audience < 3
visibilty.zero? && audience < 3
end

def owner_visible?
audience < 4
visibility != 2
end

def hidden?
audience > 3
visibility == 2
end

def visibility_label(v = visibility)
VISIBILITY_OPTIONS[v][:label]
end

def audience_label(v = audience)
AUDIENCE_OPTIONS[v][:label]
end
end
3 changes: 0 additions & 3 deletions app/models/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,10 @@ class Profile < ApplicationRecord
show_nationality: false,
show_phone: true,
show_photo: false,
show_title: false,
force_lang: nil,
personal_web_url: nil,
nationality_en: nil,
nationality_fr: nil,
title_en: nil,
title_fr: nil
}.freeze

def self.new_with_defaults(sciper)
Expand Down
2 changes: 1 addition & 1 deletion app/views/awards/_award.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

json.extract! award, :id, :title_en, :title_fr, :issuer, :year,
:updated_at, :position, :audience, :visible
:updated_at, :position, :audience, :visibility

json.profile profile_url(award.profile, format: :json)
json.url award_url(award, format: :json)
2 changes: 1 addition & 1 deletion app/views/boxes/_box.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

json.extract! box, :id, :type, :subkind, :title_en, :title_fr, :show_title, :locked,
:updated_at, :position, :audience, :visible
:updated_at, :position, :audience, :visibility
json.profile profile_url(box.profile, format: :json)
1 change: 1 addition & 0 deletions app/views/educations/_education.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

json.extract! education, :id, :field_en, :field_fr, :title_en, :title_fr,
:year_begin, :year_end, :school, :director,
:audience, :visibility,
:created_at, :updated_at
json.profile profile_url(education.profile, format: :json)
json.url education_url(education, format: :json)
2 changes: 1 addition & 1 deletion app/views/experiences/_experience.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

json.extract! experience, :id, :title_en, :title_fr, :location, :year_begin, :year_end, :position, :created_at,
:updated_at, :position, :audience
:updated_at, :position, :audience, :visibility
json.profile profile_url(experience.profile, format: :json)
json.url experience_url(experience, format: :json)
2 changes: 1 addition & 1 deletion app/views/publications/_publication.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

json.extract! publication, :id, :title, :url, :authors, :year,
:audience, :created_at, :position, :updated_at
:audience, :visibility, :created_at, :position, :updated_at
json.profile profile_url(publication.profile, format: :json)
json.url publication_url(publication, format: :json)
2 changes: 1 addition & 1 deletion app/views/rich_text_boxes/_rich_text_box.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# frozen_string_literal: true

json.extract! box, :id, :created_at, :updated_at
json.extract! box, :id, :audience, :visibility, :created_at, :updated_at
json.url box_url(box, format: :json)
4 changes: 3 additions & 1 deletion app/views/shared/_item_actions.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@
<%= link_to icon_text('action.delete', 'trash-2'), send("#{item.class.name.downcase}_path", item), class: "btn btn-secondary btn-sm", method: :delete, data: {turbo_stream: true, turbo_method:'delete', turbo_confirm: t('action.confirm')} %>
<%= link_to icon_text('action.edit', 'edit'), send("edit_#{item.class.name.downcase}_path", item), class: "btn btn-secondary btn-sm", data: {turbo_stream: true} %>
</p>
<!--
<span class="muted"><%= Award.human_attribute_name(:audience) %>: </span>
<%= render "shared/item_visibility", item: item %>
-->
<%= render "shared/item_visibility", item: item, extra_class: nil %>
Loading