Merge pull request #23581 from opf/implementation/73352-add-create-wiki-page-dialog

[#73352] added create wiki page dialog
This commit is contained in:
Eric Schubert
2026-06-09 11:21:37 +02:00
committed by GitHub
12 changed files with 365 additions and 62 deletions
+1
View File
@@ -2945,6 +2945,7 @@ en:
button_login: "Sign in"
button_move: "Move"
button_move_and_follow: "Move and follow"
button_next: "Next"
button_print: "Print"
button_quote: "Quote"
button_remove: Remove
@@ -0,0 +1,47 @@
<%#-- 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.
++#%>
<%= render(Primer::Alpha::Dialog.new(id:, title: t(".title"), size: :large, **system_arguments)) do |dialog| %>
<%
dialog.with_body(classes: "Overlay-body_autocomplete_height") do
primer_form_with(**form_options) do |form|
render(::Wikis::CreateNewWikiPageForm.new(form))
end
end
%>
<% dialog.with_footer do %>
<%= render(Primer::Beta::Button.new(data: { "close-dialog-id": id })) { t(:button_cancel) } %>
<%=
render(Primer::Beta::Button.new(scheme: :primary, form: form_id, type: :submit)) do
show_first_step? ? t(:button_next) : t(:button_add)
end
%>
<% end %>
<% end %>
@@ -0,0 +1,66 @@
# frozen_string_literal: true
#-- 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 Wikis
class CreateNewWikiPageDialog < ApplicationComponent
include OpTurbo::Streamable
def id = "create-new-wiki-page-dialog"
def form_id = "#{id}-form"
def show_first_step?
model.page_title.blank?
end
def form_options
if show_first_step?
{
id: form_id,
model:,
method: :get,
url: create_new_page_dialog_wiki_pages_path,
data: { turbo_stream: true }
}
else
{
id: form_id,
model:,
url: create_and_link_wiki_pages_path,
data: { turbo_frame: WorkPackageWikisTabComponent::TURBO_FRAME_ID }
}
end
end
def system_arguments
options
end
end
end
@@ -52,7 +52,9 @@ See COPYRIGHT and LICENSE files for more details.
)
menu.with_item(
label: t(".link_new"),
disabled: true # work in progress
tag: :a,
href: create_new_page_dialog_wiki_pages_path(create_new_page_parameters),
content_arguments: { data: { controller: "async-dialog" } }
)
end
end
@@ -50,6 +50,16 @@ module Wikis
provider.user_connected?(User.current)
end
def create_new_page_parameters
{
wikis_forms_create_new_wiki_page_form_model: {
linkable_id: work_package.id,
linkable_type: work_package.class.name,
provider_id: provider.id
}
}
end
private
def page_link_service
@@ -29,14 +29,34 @@
#++
module Wikis
class SearchPagesController < ApplicationController
class PagesController < ApplicationController
include OpTurbo::ComponentStream
include Dry::Monads[:result]
before_action :authorize, except: %i[search]
# The search is project independent and thus permission independent. The user will see results according to
# the permissions set in each wiki.
no_authorization_required! :show
no_authorization_required! :search
def show
def create_and_link
# TODO: implement service to create page and link
render_error_flash_message_via_turbo_stream(
message: "Not implemented yet. Trying to create a new page with #{create_new_page_params.to_h}"
)
respond_to_with_turbo_streams
end
def create_new_page_dialog
params = create_new_page_params
form_object = Forms::CreateNewWikiPageFormModel.new(linkable_id: params[:linkable_id],
linkable_type: params[:linkable_type],
provider_id: params[:provider_id],
page_title: params[:page_title])
respond_with_dialog Wikis::CreateNewWikiPageDialog.new(form_object)
end
def search
provider = Provider.visible.find(params.expect(:provider_id))
query = params[:query]
form_name = params[:name]
@@ -57,5 +77,19 @@ module Wikis
end
end
end
def create_new_page_params
params.expect(wikis_forms_create_new_wiki_page_form_model: %i[provider_id linkable_type linkable_id page_title])
.merge(parent_page_identifier: parse_identifier(params[:wiki_page_selection]))
end
def parse_identifier(wiki_page_selection)
case wiki_page_selection
in [selected_page]
MultiJson.load(selected_page, symbolize_keys: true)[:value]
else
nil
end
end
end
end
@@ -0,0 +1,85 @@
# frozen_string_literal: true
#-- 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 Wikis
class CreateNewWikiPageForm < ApplicationForm
form do |f|
f.hidden(name: :provider_id)
f.hidden(name: :linkable_type)
f.hidden(name: :linkable_id)
if first_step?
f.text_field(name: :page_title, label: I18n.t("wikis.create_new_wiki_page_dialog.page_title"), required: true)
else
f.hidden(name: :page_title)
f.html_content do
render(Primer::Beta::Text.new) { I18n.t("wikis.create_new_wiki_page_dialog.parent_help_text") }
end
f.html_content do
render(
Primer::OpenProject::FilterableTreeView.new(
src: helpers.search_wiki_pages_path(provider_id: model.provider_id, name: "wiki_page_selection"),
form_arguments: { builder: rails_builder(f), name: "wiki_page_selection" },
filter_mode_control_arguments: { hidden: true },
filter_input_arguments: {
placeholder: I18n.t("wikis.link_existing_wiki_page_form.placeholder"),
# every other property is just refilling the default values,
# as those are not merged into custom arguments
name: :filter,
label: I18n.t(:button_filter),
type: :search,
leading_visual: { icon: :search },
visually_hide_label: true,
show_clear_button: true
},
include_sub_items_check_box_arguments: { hidden: true },
no_results_node_arguments: { label: I18n.t("wikis.link_existing_wiki_page_form.no_results") }
)
)
end
end
end
private
# Primer's FormObject stores the underlying ActionView/Primer form builder
# as @builder. FilterableTreeView requires an ActionView::FormBuilder to
# generate its hidden form inputs via hidden_field.
def rails_builder(form)
form.instance_variable_get(:@builder)
end
def first_step?
model.page_title.blank?
end
end
end
@@ -0,0 +1,46 @@
# frozen_string_literal: true
#-- 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 Wikis
module Forms
class CreateNewWikiPageFormModel
extend ActiveModel::Naming
attr_reader :linkable_id, :linkable_type, :provider_id, :page_title
def initialize(linkable_id:, linkable_type:, provider_id:, page_title:)
@linkable_id = linkable_id
@linkable_type = linkable_type
@provider_id = provider_id
@page_title = page_title
end
end
end
end
+60 -56
View File
@@ -34,67 +34,13 @@ en:
permission_manage_wiki_page_links: Manage Wiki Page Links
project_module_wiki_platforms: Wiki providers
wikis:
buttons:
connect_account: Connect %{provider} account
done_continue: Done, continue
open_wiki: Open wiki
save_and_continue: Save and continue
wiki_page: Wiki page
instructions:
xwiki:
integration: XWiki Administration
oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link).
provider_types:
xwiki:
name: XWiki
delete_relation_page_link_confirmation_dialog:
title: Delete related wiki page link
heading: Delete related wiki page link?
health_checks:
authentication:
existing_token: User token
header: Authentication
user_bound_request: User-based request authentication
base_configuration:
header: Configuration
provider_configured: Configuration complete
errors:
not_configured: The connection could not be validated. Please finish configuration first.
xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance.
xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance.
xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account.
xwiki_oauth_unauthorized: The user token was not recognized by XWiki.
link_existing_wiki_page_dialog:
title: Add existing wiki page
link_existing_wiki_page_form:
no_results: No wiki pages found
placeholder: Search for a wiki page
work_package_wikis_tab_component:
inline_page_links: Inline page links
referencing_pages: Referenced in
page_links:
errors:
page_not_found: Linked wiki page no longer available
page_access_forbidden: You do not have permission to access this wiki page
unexpected: An unexpected error occurred
page_link_component:
remove: Remove page link
relation_page_links_component:
link_existing: Existing wiki page
link_new: New wiki page
empty_heading: No related pages
empty_text: Manually add links to other related wiki pages.
oauth_login_component:
heading: Not connected to %{provider}
description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance.
connect_button: Connect %{provider} account
admin:
destroy_confirmation_dialog_component:
title: Delete wiki provider
heading: Permanently delete this wiki provider?
description_html: >-
The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every
inline wiki page link will no longer be accessible. This action is irreversible.
heading: Permanently delete this wiki provider?
title: Delete wiki provider
forms:
general_info_form_component:
provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup.
@@ -160,3 +106,61 @@ en:
openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth.
xwiki_oauth: XWiki OAuth
xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth.
buttons:
connect_account: Connect %{provider} account
done_continue: Done, continue
open_wiki: Open wiki
save_and_continue: Save and continue
wiki_page: Wiki page
create_new_wiki_page_dialog:
page_title: Title
parent_help_text: Select a parent for this new wiki page.
title: Create new wiki page
delete_relation_page_link_confirmation_dialog:
heading: Delete related wiki page link?
title: Delete related wiki page link
health_checks:
authentication:
existing_token: User token
header: Authentication
user_bound_request: User-based request authentication
base_configuration:
header: Configuration
provider_configured: Configuration complete
errors:
not_configured: The connection could not be validated. Please finish configuration first.
xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance.
xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance.
xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account.
xwiki_oauth_unauthorized: The user token was not recognized by XWiki.
instructions:
xwiki:
integration: XWiki Administration
oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link).
link_existing_wiki_page_dialog:
title: Add existing wiki page
link_existing_wiki_page_form:
no_results: No wiki pages found
placeholder: Search for a wiki page
oauth_login_component:
connect_button: Connect %{provider} account
description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance.
heading: Not connected to %{provider}
page_link_component:
remove: Remove page link
page_links:
errors:
page_access_forbidden: You do not have permission to access this wiki page
page_not_found: Linked wiki page no longer available
unexpected: An unexpected error occurred
provider_types:
xwiki:
name: XWiki
relation_page_links_component:
empty_heading: No related pages
empty_text: Manually add links to other related wiki pages.
link_existing: Existing wiki page
link_new: New wiki page
work_package_wikis_tab_component:
inline_page_links: Inline page links
referencing_pages: Referenced in
+5 -1
View File
@@ -73,5 +73,9 @@ Rails.application.routes.draw do
get :load
end
resource :search_wiki_pages, controller: "wikis/search_pages", only: %i[show]
resource :wiki_pages, controller: "wikis/pages", only: [] do
get :search
get :create_new_page_dialog
post :create_and_link
end
end
@@ -74,7 +74,11 @@ module OpenProject::Wikis
project_module :work_package_tracking do
permission :manage_wiki_page_links,
{
"wikis/relation_page_links": %i[create destroy confirm_delete_dialog link_existing_dialog]
"wikis/pages": %i[create_and_link create_new_page_dialog],
"wikis/relation_page_links": %i[create
destroy
confirm_delete_dialog
link_existing_dialog]
},
permissible_on: :project,
dependencies: %i[edit_work_packages],