diff --git a/.gitignore b/.gitignore index f8c983a..fa362f1 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ spec/coverage spec/reports brakeman-output.tabs rubocop-results.xml +config/environment.rb diff --git a/app/abilities/jemk/group_ability.rb b/app/abilities/jemk/group_ability.rb new file mode 100644 index 0000000..0d02b18 --- /dev/null +++ b/app/abilities/jemk/group_ability.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + + +module Jemk::GroupAbility + extend ActiveSupport::Concern + + included do + on(Group) do + permission(:any).may(:'index_event/camps').all + + permission(:group_full).may(:'export_event/camps').in_same_group + permission(:group_and_below_full).may(:'export_event/camps').in_same_group_or_below + permission(:layer_read).may(:'export_event/camps').in_same_layer + permission(:layer_and_below_read).may(:'export_event/camps').in_same_layer_or_below + end + end +end diff --git a/app/assets/stylesheets/hitobito/customizable/_variables.scss b/app/assets/stylesheets/hitobito/customizable/_variables.scss index 62a042a..90445cc 100644 --- a/app/assets/stylesheets/hitobito/customizable/_variables.scss +++ b/app/assets/stylesheets/hitobito/customizable/_variables.scss @@ -27,15 +27,18 @@ $white: #fff !default; // Colors // ---------------------------- -$blue: #329897 !default; + +$jemk_darkgreen: darken($jemk_green, 20%); + +$blue: $emk_darkblue; $blueDark: darken($blue, 10%) !default; -$green: #8DB850 !default; -$greenDark: darken($green, 10%) !default; +$green: $jemk_green !default; +$greenDark: $jemk_darkgreen; $orange: #DC795B; $orangeDark: #C75B3B; -$purple: $jemk_darkblue; // #925D97; -$purpleDark: darken($jemk_darkblue, 20%); //#6A396F; +$purple: $jemk_darkblue; +$purpleDark: darken($jemk_darkblue, 20%); $red: $orange !default; @@ -49,7 +52,7 @@ $bodyBackground: $jemk_darkblue; $focusColor: $purple; $shadowColor: darken($pageBackground, 10%); -$linkColor: $jemk_green !default; +$linkColor: $jemk_darkgreen !default; $linkColorHover: $jemk_darkblue !default; $footerColor: $jemk_black; diff --git a/app/controllers/jemk/event/lists_controller.rb b/app/controllers/jemk/event/lists_controller.rb new file mode 100644 index 0000000..224d25c --- /dev/null +++ b/app/controllers/jemk/event/lists_controller.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +module Jemk::Event::ListsController + + def camps + authorize!(:list_available, Event::Camp) + + @grouped_events = grouped(upcoming_user_events_of_type(Event::Camp)) + render :events + end + + def events + authorize!(:list_available, Event) + + @grouped_events = grouped(upcoming_user_events_of_type(Event, allow_null: true)) + end + + private + + def upcoming_user_events + Event + .upcoming + .in_hierarchy(current_user) + .includes(:dates, :groups, :events_groups) + .order('event_dates.start_at ASC') + end + + def upcoming_user_events_of_type(type, allow_null: false) + condition = OrCondition.new + condition.or('events.type = ?', type) + condition.or('events.type IS NULL') if allow_null + + upcoming_user_events.where(condition.to_a) + end + +end diff --git a/app/helpers/jemk/sheet/event/list.rb b/app/helpers/jemk/sheet/event/list.rb new file mode 100644 index 0000000..ffc1a26 --- /dev/null +++ b/app/helpers/jemk/sheet/event/list.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +module Jemk::Sheet::Event::List + extend ActiveSupport::Concern + + included do + alias_method_chain :render_left_nav, :camps + end + + def render_left_nav_with_camps + if view.nav_left == 'camps' + view.render 'nav_left_events' + else + render_left_nav_without_camps + end + end + +end diff --git a/app/helpers/jemk/sheet/group.rb b/app/helpers/jemk/sheet/group.rb new file mode 100644 index 0000000..cd3b267 --- /dev/null +++ b/app/helpers/jemk/sheet/group.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + + +module Jemk::Sheet::Group + extend ActiveSupport::Concern + + included do + tabs.insert(4, + Sheet::Tab.new('activerecord.models.event/camp.other', + :camp_group_events_path, + params: { returning: true }, + if: lambda do |view, group| + group.event_types.include?(::Event::Camp) && + view.can?(:'index_event/camps', group) + end)) + end + +end diff --git a/app/models/event/camp.rb b/app/models/event/camp.rb new file mode 100644 index 0000000..7748157 --- /dev/null +++ b/app/models/event/camp.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +class Event::Camp < Event + self.used_attributes += [:waiting_list] + + self.supports_applications = true + + def tentative_application_possible? + false + end +end diff --git a/app/models/group/dachverband.rb b/app/models/group/dachverband.rb index c76f3af..45f5b1d 100644 --- a/app/models/group/dachverband.rb +++ b/app/models/group/dachverband.rb @@ -22,10 +22,16 @@ class Group::Dachverband < ::Group Group::DachverbandMitglieder ] + self.event_types = [ + Event, + Event::Course + ] + ### ROLES class Administrator < ::Role self.permissions = [:admin, :layer_and_below_full, :impersonation] + self.two_factor_authentication_enforced = true end roles Administrator diff --git a/app/models/group/dachverband_geschaeftsstelle.rb b/app/models/group/dachverband_geschaeftsstelle.rb index 2bb88c9..7fee54d 100644 --- a/app/models/group/dachverband_geschaeftsstelle.rb +++ b/app/models/group/dachverband_geschaeftsstelle.rb @@ -8,10 +8,12 @@ class Group::DachverbandGeschaeftsstelle < ::Group class Geschaeftsleiter < ::Role self.permissions = [:admin, :layer_and_below_full, :impersonation, :contact_data] + self.two_factor_authentication_enforced = true end class Angestellter < ::Role self.permissions = [:admin, :layer_and_below_full, :impersonation, :contact_data] + self.two_factor_authentication_enforced = true end roles Geschaeftsleiter, Angestellter diff --git a/app/models/group/lagerverein.rb b/app/models/group/lagerverein.rb index 1436bdc..dc2bd40 100644 --- a/app/models/group/lagerverein.rb +++ b/app/models/group/lagerverein.rb @@ -11,6 +11,11 @@ class Group::Lagerverein < ::Group children Group::LagervereinVerein + self.event_types = [ + Event, + Event::Camp + ] + ### ROLES class Administrator < ::Role diff --git a/app/models/group/ortsjungschar.rb b/app/models/group/ortsjungschar.rb index 0ab96b8..fad90f3 100644 --- a/app/models/group/ortsjungschar.rb +++ b/app/models/group/ortsjungschar.rb @@ -17,6 +17,11 @@ class Group::Ortsjungschar < ::Group Group::OrtsjungscharMitglieder ] + self.event_types = [ + Event, + Event::Camp + ] + ### ROLES class Hauptleiter < ::Role diff --git a/app/models/group/region.rb b/app/models/group/region.rb index 14f74fb..1165686 100644 --- a/app/models/group/region.rb +++ b/app/models/group/region.rb @@ -21,6 +21,11 @@ class Group::Region < ::Group Group::RegionMitglieder ] + self.event_types = [ + Event, + Event::Course + ] + ### ROLES class Administrator < ::Role diff --git a/app/models/jemk/event/participation_contact_data.rb b/app/models/jemk/event/participation_contact_data.rb new file mode 100644 index 0000000..ba33a92 --- /dev/null +++ b/app/models/jemk/event/participation_contact_data.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +module Jemk::Event::ParticipationContactData + extend ActiveSupport::Concern + + included do + self.contact_attrs -= [:company_name, :company] + end +end diff --git a/app/models/jemk/person.rb b/app/models/jemk/person.rb new file mode 100644 index 0000000..99228ac --- /dev/null +++ b/app/models/jemk/person.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +module Jemk::Person + extend ActiveSupport::Concern + + included do + used_attributes.delete(:company) + used_attributes.delete(:company_name) + + Person::FILTER_ATTRS.delete(:company_name) + end +end diff --git a/bin/wagon b/bin/wagon new file mode 100755 index 0000000..01f60ab --- /dev/null +++ b/bin/wagon @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +set -euo pipefail +IFS=$'\n\t' + +cd ../hitobito +bin/wagon $@ diff --git a/config/locales/jemk.de.yml b/config/locales/jemk.de.yml index 828f04d..17c20e0 100644 --- a/config/locales/jemk.de.yml +++ b/config/locales/jemk.de.yml @@ -243,3 +243,21 @@ de: group/ortsjungschar_mitglieder/passivmitglied: one: Passivmitglied # description: TODO + + event/camp: + one: Lager + other: Lager + + attributes: + person: + nickname: Jungscharname + + events: + global: + link: + add_event/camp: Lager erstellen + new: + title_event/camp: Lager erstellen + + navigation: + camps: Lager diff --git a/config/routes.rb b/config/routes.rb index 925eb9b..cc32b17 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,15 @@ language_scope do # Define wagon routes here + resources :groups do + resources :events, only: [] do # do not redefine events actions, only add new ones + collection do + get 'camp' => 'events#index', type: 'Event::Camp' + end + end + end + + get 'list_camps' => 'event/lists#camps', as: :list_camps end end diff --git a/lib/hitobito_jemk/wagon.rb b/lib/hitobito_jemk/wagon.rb index 01f88d9..f0bb38b 100644 --- a/lib/hitobito_jemk/wagon.rb +++ b/lib/hitobito_jemk/wagon.rb @@ -22,7 +22,37 @@ class Wagon < Rails::Engine config.to_prepare do # extend application classes here + + # Models Group.include Jemk::Group + Person.include Jemk::Person + Event::ParticipationContactData.include Jemk::Event::ParticipationContactData + + # Abilities + GroupAbility.include Jemk::GroupAbility + EventAbility.abilities[Event::Camp] = + EventAbility.abilities[Event] # Camp has same abilities as event + + # Decorators + EventDecorator.icons['Event::Camp'] = :campground + + # Sheets + Sheet::Group.include Jemk::Sheet::Group + Sheet::Event::List.include Jemk::Sheet::Event::List + + # Controllers + Event::ListsController.prepend Jemk::Event::ListsController + + # Main navigation + index_courses = NavigationHelper::MAIN.index { |opts| opts[:label] == :courses } + NavigationHelper::MAIN.insert( + index_courses + 1, + label: :camps, + icon_name: :campground, + url: :list_camps_path, + active_for: %w(list_camps), + if: ->(_) { can?(:list_available, Event::Camp) } + ) end initializer 'jemk.add_settings' do |_app| diff --git a/spec/models/group/dachverband_spec.rb b/spec/models/group/dachverband_spec.rb new file mode 100644 index 0000000..64a38c9 --- /dev/null +++ b/spec/models/group/dachverband_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +require 'spec_helper' + +describe Group::Dachverband do + it 'supports events' do + expect(described_class.event_types).to include(Event) + end + + it 'supports courses' do + expect(described_class.event_types).to include(Event::Course) + end +end diff --git a/spec/models/group/lagerverein_spec.rb b/spec/models/group/lagerverein_spec.rb new file mode 100644 index 0000000..6a35392 --- /dev/null +++ b/spec/models/group/lagerverein_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +require 'spec_helper' + +describe Group::Lagerverein do + it 'supports events' do + expect(described_class.event_types).to include(Event) + end + + it 'supports camps' do + expect(described_class.event_types).to include(Event::Camp) + end +end diff --git a/spec/models/group/ortsjungschar_spec.rb b/spec/models/group/ortsjungschar_spec.rb new file mode 100644 index 0000000..8dc2739 --- /dev/null +++ b/spec/models/group/ortsjungschar_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +require 'spec_helper' + +describe Group::Ortsjungschar do + it 'supports events' do + expect(described_class.event_types).to include(Event) + end + + it 'supports camps' do + expect(described_class.event_types).to include(Event::Camp) + end +end diff --git a/spec/models/group/region_spec.rb b/spec/models/group/region_spec.rb new file mode 100644 index 0000000..d0c2c18 --- /dev/null +++ b/spec/models/group/region_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Copyright (c) 2023-2023, Jungschar EMK. This file is part of +# hitobito_jemk and licensed under the Affero General Public License version 3 +# or later. See the COPYING file at the top-level directory or at +# https://github.com/hitobito/hitobito_jemk. + +require 'spec_helper' + +describe Group::Region do + it 'supports events' do + expect(described_class.event_types).to include(Event) + end + + it 'supports courses' do + expect(described_class.event_types).to include(Event::Course) + end +end