Skip to content

Commit

Permalink
Extend rich text input
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverguenther committed Feb 26, 2024
1 parent 908307b commit 89a684e
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 15 deletions.
40 changes: 40 additions & 0 deletions frontend/src/app/features/hal/resources/meeting-resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// -- copyright
// OpenProject is an open source project management software.
// Copyright (C) 2012-2024 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.
//++

import { HalResource } from 'core-app/features/hal/resources/hal-resource';
import { Attachable } from 'core-app/features/hal/resources/mixins/attachable-mixin';

export interface MeetingResourceLinks {
addAttachment(attachment:HalResource):Promise<any>;

Check warning on line 33 in frontend/src/app/features/hal/resources/meeting-resource.ts

View workflow job for this annotation

GitHub Actions / eslint

[eslint] frontend/src/app/features/hal/resources/meeting-resource.ts#L33 <@typescript-eslint/no-explicit-any>(https://typescript-eslint.io/rules/no-explicit-any)

Unexpected any. Specify a different type.
Raw output
{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":33,"column":49,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":33,"endColumn":52,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1494,1497],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1494,1497],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}]}
}

class MeetingBaseResource extends HalResource {
public $links:MeetingResourceLinks;
}

export const MeetingResource = Attachable(MeetingBaseResource);
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,16 @@ import {
HalResourceFactoryConfigInterface,
HalResourceService,
} from 'core-app/features/hal/services/hal-resource.service';
import { QueryFilterInstanceSchemaResource } from 'core-app/features/hal/resources/query-filter-instance-schema-resource';
import {
QueryFilterInstanceSchemaResource,
} from 'core-app/features/hal/resources/query-filter-instance-schema-resource';
import { ErrorResource } from 'core-app/features/hal/resources/error-resource';
import { SchemaDependencyResource } from 'core-app/features/hal/resources/schema-dependency-resource';
import { WorkPackageCollectionResource } from 'core-app/features/hal/resources/wp-collection-resource';
import { RelationResource } from 'core-app/features/hal/resources/relation-resource';
import { QueryFilterResource } from 'core-app/features/hal/resources/query-filter-resource';
import { SchemaResource } from 'core-app/features/hal/resources/schema-resource';
import { MeetingResource } from 'core-app/features/hal/resources/meeting-resource';

const halResourceDefaultConfig:{ [typeName:string]:HalResourceFactoryConfigInterface } = {
WorkPackage: {
Expand Down Expand Up @@ -179,6 +182,9 @@ const halResourceDefaultConfig:{ [typeName:string]:HalResourceFactoryConfigInter
WikiPage: {
cls: WikiPageResource,
},
Meeting: {
cls: MeetingResource,
},
MeetingContent: {
cls: MeetingContentResource,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ export class CkeditorAugmentedTextareaComponent extends UntilDestroyedMixin impl

@Input() public editorType:ICKEditorType = 'full';

@Input() public showAttachments = true

Check failure on line 74 in frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts

View workflow job for this annotation

GitHub Actions / eslint

[eslint] frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts#L73-L74 <@typescript-eslint/semi>(https://typescript-eslint.io/rules/semi)

Missing semicolon.
Raw output
{"ruleId":"@typescript-eslint/semi","severity":2,"message":"Missing semicolon.","line":73,"column":41,"nodeType":"PropertyDefinition","messageId":"missingSemi","endLine":74,"endColumn":1,"fix":{"range":[3318,3318],"text":";"}}
// Which template to include
public element:HTMLElement;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<fieldset
class="form--fieldset"
*ngIf="halResource && halResource.attachments"
*ngIf="showAttachments && halResource?.attachments"
>
<legend class="form--fieldset-legend">
{{ text.attachments }}
Expand Down
5 changes: 3 additions & 2 deletions lib/primer/open_project/forms/dsl/rich_text_area_input.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ module Dsl
class RichTextAreaInput < Primer::Forms::Dsl::Input
attr_reader :name, :label

def initialize(name:, label:, **system_arguments)
def initialize(name:, label:, rich_text_options:, **system_arguments)
@name = name
@label = label
@rich_text_options = rich_text_options

super(**system_arguments)
end

def to_component
RichTextArea.new(input: self)
RichTextArea.new(input: self, rich_text_options: @rich_text_options)
end

def type
Expand Down
12 changes: 7 additions & 5 deletions lib/primer/open_project/forms/rich_text_area.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
<%= builder.text_area(@input.name, **@input.input_arguments) %>
<% end %>
<%= angular_component_tag 'opce-ckeditor-augmented-textarea',
inputs: {
textareaSelector: "##{builder.field_id(@input.name)}",
macros: 'resource',
turboMode: true
}
inputs: @rich_text_options.reverse_merge(
{
textareaSelector: "##{builder.field_id(@input.name)}",
macros: 'resource',
turboMode: true
}
)
%>
<% end %>
3 changes: 2 additions & 1 deletion lib/primer/open_project/forms/rich_text_area.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ class RichTextArea < Primer::Forms::BaseComponent

delegate :builder, :form, to: :@input

def initialize(input:)
def initialize(input:, rich_text_options:)
super()
@input = input
@rich_text_options = rich_text_options
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
agenda.with_row do
render(MeetingAgendaItems::NewButtonComponent.new(meeting: @meeting))
end

agenda.with_row do
resource = ::API::V3::Meetings::MeetingRepresenter.new(@meeting, current_user: User.current, embed_links: false)
helpers.list_attachments(resource)
end
end
end

Expand Down
12 changes: 11 additions & 1 deletion modules/meeting/app/forms/meeting_agenda_item/notes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,25 @@
#++

class MeetingAgendaItem::Notes < ApplicationForm
delegate :object, to: :@builder

form do |agenda_item_form|
agenda_item_form.rich_text_area(
name: :notes,
label: MeetingAgendaItem.human_attribute_name(:notes),
disabled: @disabled
disabled: @disabled,
rich_text_options: {
resource:,
}
)
end

def initialize(disabled: false)
@disabled = disabled
end

def resource
API::V3::Meetings::MeetingRepresenter
.new(object.meeting, current_user: User.current, embed_links: false)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 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.
#++

require 'spec_helper'
require 'features/page_objects/notification'
require_relative '../../support/pages/structured_meeting/show'

RSpec.describe 'Upload attachment to meetings', :js do
let(:user) do
create(:user,
member_with_permissions: { project => %i[view_meetings edit_meetings manage_agendas] })
end
let(:project) { create(:project) }
let(:attachments) { Components::Attachments.new }
let(:image_fixture) { UploadedFile.load_from('spec/fixtures/files/image.png') }
let(:editor) { Components::WysiwygEditor.new '#content', 'opce-ckeditor-augmented-textarea' }
let(:wiki_page_content) { project.wiki.pages.first.text }

let(:meeting) { create(:structured_meeting, project: project)}
let(:show_page) { Pages::StructuredMeeting::Show.new(meeting) }

before do
login_as(user)
end

it 'can upload an image to new and existing meeting agenda item via drag & drop in editor' do
show_page.visit!

show_page.add_agenda_item(save: false) do
click_link_or_button 'Notes'
end

# adding an image
editor.drag_attachment image_fixture.path, 'Image uploaded the first time'

editor.attachments_list.expect_attached('image.png')
editor.wait_until_upload_progress_toaster_cleared

click_link_or_button 'Save'
expect(page).to have_css('#meeting-agenda-items-list-component img', count: 1)
expect(page).to have_content('Image uploaded the first time')
editor.attachments_list.expect_attached('image.png')
end
end
4 changes: 2 additions & 2 deletions modules/meeting/spec/support/pages/structured_meeting/show.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ def expect_empty
expect(page).to have_no_css('[id^="meeting-agenda-items-item-component"]')
end

def add_agenda_item(type: MeetingAgendaItem, &)
def add_agenda_item(type: MeetingAgendaItem, save: true, &)
page.within("#meeting-agenda-items-new-button-component") do
click_button I18n.t(:button_add)
click_link type.model_name.human
end

in_agenda_form do
yield
click_button 'Save'
click_button('Save') if save
end
end

Expand Down
4 changes: 2 additions & 2 deletions spec/support/components/wysiwyg/wysiwyg_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ class WysiwygEditor

attr_reader :context_selector, :attachments, :attachments_list

def initialize(context = '#content')
def initialize(context = '#content', attachment_list_selector = 'ckeditor-augmented-textarea')
@context_selector = context
@attachments = ::Components::Attachments.new
@attachments_list = ::Components::AttachmentsList.new("#{context} ckeditor-augmented-textarea")
@attachments_list = ::Components::AttachmentsList.new("#{context} #{attachment_list_selector}")
end

def container
Expand Down

0 comments on commit 89a684e

Please sign in to comment.