Skip to content

Commit

Permalink
Add meeting creation dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmir committed Oct 24, 2024
1 parent d727323 commit 17b8a1e
Show file tree
Hide file tree
Showing 13 changed files with 350 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<%=
render(Primer::Alpha::Dialog.new(
id: "new-meeting-dialog", title: I18n.t("label_meeting_new_one_time"),
size: :medium_portrait,
data: { 'keep-open-on-submit': true }
)) do |dialog|
dialog.with_header(variant: :large)
render(Meetings::Index::NewFormComponent.new(meeting: @meeting, project: @project))
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module Meetings
class Index::NewDialogComponent < ApplicationComponent
include ApplicationHelper
include OpenProject::FormTagHelper
include OpTurbo::Streamable
include OpPrimer::ComponentHelpers

def initialize(meeting:, project:)
super

@meeting = meeting
@project = project
end

def render?
if @project
User.current.allowed_in_project?(:create_meetings, @project)
else
User.current.allowed_in_any_project?(:create_meetings)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<%=
component_wrapper do
primer_form_with(
scope: :meeting,
model: @meeting,
method: :post,
data: { turbo: true },
html: { :id => 'meeting-form' },
url: {:controller => '/meetings', :action => 'create', :project_id => @project}
) do |f|
component_collection do |collection|
collection.with_component(Primer::Alpha::Dialog::Body.new) do
flex_layout(mb: 3) do |modal_body|
if @project.nil?
modal_body.with_row(mt: 3) do
render(Meeting::ProjectAutocompleter.new(f))
end
end

modal_body.with_row(mt: 3) do
render(Meeting::Title.new(f))
end

modal_body.with_row(mt: 3) do
render(Meeting::StartDate.new(f, initial_value: start_date_initial_value))
end

modal_body.with_row(mt: 3) do
render(Meeting::StartTime.new(f, initial_value: start_time_initial_value))
end

modal_body.with_row(mt: 3) do
render(Meeting::Duration.new(f))
end

modal_body.with_row(mt: 3) do
render(Meeting::Location.new(f, icon: :location))
end

modal_body.with_row do
render(Meeting::Type.new(f))
end
end
end

collection.with_component(Primer::Alpha::Dialog::Footer.new) do
component_collection do |modal_footer|
modal_footer.with_component(Primer::ButtonComponent.new(data: { 'close-dialog-id': "new-meeting-dialog" })) do
I18n.t("button_cancel")
end

modal_footer.with_component(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) do
I18n.t("label_meeting_create")
end
end
end
end
end
end
%>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module Meetings
class Index::NewFormComponent < ApplicationComponent
include ApplicationHelper
include OpTurbo::Streamable
include OpPrimer::ComponentHelpers

def initialize(meeting:, project:)
super

@meeting = meeting
@project = project
end

private

def start_date_initial_value
format_time_as_date(@meeting.start_time, format: "%Y-%m-%d")
end

def start_time_initial_value
format_time(@meeting.start_time, include_date: false, format: "%H:%M")
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,36 @@
render(Meetings::MeetingFilterButtonComponent.new(query: @query, project: @project))
end

# subheader.with_action_button(tag: :a,
# href: dynamic_path,
# scheme: :primary,
# mobile_icon: :plus,
# mobile_label: label_text,
# aria: { label: accessibility_label_text },
# title: accessibility_label_text,
# id: id,
# test_selector: "add-meeting-button") do |button|
# button.with_leading_visual_icon(icon: :plus)
# label_text
# end if render_create_button?

if render_create_button?
subheader.with_action_component do

render Primer::Alpha::ActionMenu.new(anchor_align: :end) do |menu|
menu.with_show_button(scheme: :primary,
test_selector: "op-admin-synchronized-groups--button-new",
aria: { label: I18n.t(:button_add) }) do |button|
test_selector: "add-meeting-button",
mobile_icon: :plus,
mobile_label: label_text,
id: id,
title: accessibility_label_text,
aria: { label: accessibility_label_text }) do |button|
button.with_leading_visual_icon(icon: :plus)
button.with_trailing_action_icon(icon: :"triangle-down")
I18n.t(:label_meeting)
end

menu.with_item(label: I18n.t("meeting.types.structured")) do |item|
end
menu.with_item(label: I18n.t("meeting.types.classic"),
tag: :a,
href: dynamic_path
)

menu.with_item(label: I18n.t("meeting.types.classic")) do |item|
end
menu.with_item(label: I18n.t("meeting.types.structured"),
tag: :a,
href: new_dialog_meetings_path(project_id: @project&.id),
content_arguments: { data: { controller: "async-dialog" }}
)
end

end
end


subheader.with_bottom_pane_component(mt: 0) do
render(Meetings::MeetingFiltersComponent.new(query: @query, project: @project))
end
Expand Down
42 changes: 34 additions & 8 deletions modules/meeting/app/controllers/meetings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,18 @@
#++

class MeetingsController < ApplicationController
before_action :load_and_authorize_in_optional_project, only: %i[index new show create history]
before_action :load_and_authorize_in_optional_project, only: %i[index new new_dialog show create history]
before_action :verify_activities_module_activated, only: %i[history]
before_action :determine_date_range, only: %i[history]
before_action :determine_author, only: %i[history]
before_action :build_meeting, only: %i[new]
before_action :find_meeting, except: %i[index new create]
before_action :build_meeting, only: %i[new new_dialog]
before_action :find_meeting, except: %i[index new create new_dialog]
before_action :set_activity, only: %i[history]
before_action :find_copy_from_meeting, only: %i[create]
before_action :convert_params, only: %i[create update update_participants]
before_action :authorize, except: %i[index new create update_title update_details update_participants change_state]
before_action :authorize_global, only: %i[index new create update_title update_details update_participants change_state]
before_action :authorize, except: %i[index new create update_title update_details update_participants change_state new_dialog]
before_action :authorize_global,
only: %i[index new create update_title update_details update_participants change_state new_dialog]

helper :watchers
helper :meeting_contents
Expand All @@ -49,6 +50,7 @@ class MeetingsController < ApplicationController

include OpTurbo::ComponentStream
include OpTurbo::FlashStreamHelper
include OpTurbo::DialogStreamHelper
include Meetings::AgendaComponentStreams
include MetaTagsHelper

Expand Down Expand Up @@ -93,6 +95,8 @@ def create # rubocop:disable Metrics/AbcSize
.call(@converted_params)
end

@meeting = call.result

if call.success?
text = I18n.t(:notice_successful_create)
unless User.current.pref.time_zone?
Expand All @@ -102,13 +106,35 @@ def create # rubocop:disable Metrics/AbcSize
end
flash[:notice] = text.html_safe # rubocop:disable Rails/OutputSafety

redirect_to action: "show", id: call.result
respond_to do |format|
format.html do
redirect_to action: "show", id: @meeting
end

format.turbo_stream do
render turbo_stream: turbo_stream.redirect_to(meeting_path(@meeting))
end
end
else
@meeting = call.result
render template: "meetings/new", project_id: @project, locals: { copy_from: @copy_from }
respond_to do |format|
format.html do
render template: "meetings/new", project_id: @project, locals: { copy_from: @copy_from }
end

format.turbo_stream do
update_via_turbo_stream(component: Meetings::Index::NewFormComponent.new(meeting: @meeting, project: @project),
status: :bad_request)

respond_with_turbo_streams
end
end
end
end

def new_dialog
respond_with_dialog Meetings::Index::NewDialogComponent.new(meeting: @meeting, project: @project)
end

def new; end

current_menu_item :new do
Expand Down
6 changes: 5 additions & 1 deletion modules/meeting/app/forms/meeting/location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ class Meeting::Location < ApplicationForm
placeholder: Meeting.human_attribute_name(:location),
label: Meeting.human_attribute_name(:location),
visually_hide_label: false,
leading_visual: { icon: :link }
leading_visual: { icon: @icon }
)
end

def initialize(icon: :link)
@icon = icon
end

Check warning on line 42 in modules/meeting/app/forms/meeting/location.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] modules/meeting/app/forms/meeting/location.rb#L40-L42 <Lint/MissingSuper>

Call `super` to initialize state of the parent class.
Raw output
modules/meeting/app/forms/meeting/location.rb:40:3: W: Lint/MissingSuper: Call `super` to initialize state of the parent class.
end
46 changes: 46 additions & 0 deletions modules/meeting/app/forms/meeting/project_autocompleter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

class Meeting::ProjectAutocompleter < ApplicationForm
form do |f|
f.project_autocompleter(
name: "project_id",
id: "project_id",
label: Project.model_name.human,
autocomplete_options: {
with_search_icon: true,
openDirectly: false,
focusDirectly: false,
dropdownPosition: "bottom",
inputName: "project_id",
inputValue: @project&.id,
filters: [{ name: "user_action", operator: "=", values: ["meetings/create"] }]
}
)
end
end
Loading

0 comments on commit 17b8a1e

Please sign in to comment.