diff --git a/app/assets/stylesheets/content/_action_menu_main.sass b/app/assets/stylesheets/content/_action_menu_main.sass
index 6466467e54..cf62587a57 100644
--- a/app/assets/stylesheets/content/_action_menu_main.sass
+++ b/app/assets/stylesheets/content/_action_menu_main.sass
@@ -30,7 +30,7 @@
ul
list-style-type: none
margin: 0
- width: 230px
+ width: 240px
border: 1px solid #dddddd
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.15)
padding: 3px 0
diff --git a/app/assets/stylesheets/content/_modal.sass b/app/assets/stylesheets/content/_modal.sass
index cc90544253..152f1ae48f 100644
--- a/app/assets/stylesheets/content/_modal.sass
+++ b/app/assets/stylesheets/content/_modal.sass
@@ -150,12 +150,14 @@ ul.export-options
margin: 0 0 30px 0
text-align: center
display: inline-block
- min-width: 32%
+ width: 32%
a
cursor: pointer
text-decoration: none
color: $body-font-color
font-weight: normal
+ overflow-wrap: break-word
+ word-wrap: break-word
&:hover, &:active
text-decoration: none
color: $body-font-color
diff --git a/app/cells/views/settings/text_setting/show.erb b/app/cells/views/settings/text_setting/show.erb
index b02a0bf2fc..3c66649464 100644
--- a/app/cells/views/settings/text_setting/show.erb
+++ b/app/cells/views/settings/text_setting/show.erb
@@ -31,8 +31,9 @@
label: false,
id: "settings-#{name}-#{lang}",
class: 'wiki-edit',
+ with_text_formatting: true,
rows: 5,
- container_class: '-wide'
+ container_class: '-xxwide'
)
%>
diff --git a/app/helpers/text_formatting_helper.rb b/app/helpers/text_formatting_helper.rb
index 5bccdbf77c..c7b027d3a5 100644
--- a/app/helpers/text_formatting_helper.rb
+++ b/app/helpers/text_formatting_helper.rb
@@ -47,7 +47,7 @@ def preview_context(object, project = nil)
#TODO remove
def current_formatting_helper
helper_class = OpenProject::TextFormatting::Formats.rich_helper
- helper_class.new(self)
+ helper_class.new
end
def project_preview_context(object, project)
diff --git a/app/models/news.rb b/app/models/news.rb
index 98e279544d..8b1ed2e11b 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -34,7 +34,7 @@ class News < ActiveRecord::Base
order('created_on')
}, as: :commented, dependent: :delete_all
- validates_presence_of :title, :description
+ validates_presence_of :title
validates_length_of :title, maximum: 60
validates_length_of :summary, maximum: 255
@@ -62,6 +62,10 @@ def visible?(user = User.current)
!user.nil? && user.allowed_to?(:view_news, project)
end
+ def description=(val)
+ super val.presence || ''
+ end
+
# returns latest news for projects visible by user
def self.latest(user: User.current, count: 5)
latest_for(user, count: count)
diff --git a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
index 546cc56a33..9e26d57d1f 100644
--- a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
+++ b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb
@@ -151,9 +151,11 @@ def data_rows
if options[:show_attachments] && work_package.attachments.exists?
attachments = make_attachments_cells(work_package.attachments)
- result << [
- { content: pdf.make_table([attachments]), colspan: description_colspan }
- ]
+ if attachments.any?
+ result << [
+ { content: pdf.make_table([attachments]), colspan: description_colspan }
+ ]
+ end
end
if query.grouped? && (group = query.group_by_column.value(work_package)) != previous_group
diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb
index d144f6f238..a62fbd26a2 100644
--- a/app/views/messages/_form.html.erb
+++ b/app/views/messages/_form.html.erb
@@ -54,7 +54,6 @@ See docs/COPYRIGHT.rdoc for more details.
<%= f.text_area :content,
- required: true,
label: t(:description_message_content),
class: 'wiki-edit',
container_class: '-xxwide',
diff --git a/app/views/news/_form.html.erb b/app/views/news/_form.html.erb
index bb008d20de..b4a83e9667 100644
--- a/app/views/news/_form.html.erb
+++ b/app/views/news/_form.html.erb
@@ -39,7 +39,6 @@ See docs/COPYRIGHT.rdoc for more details.
<%= f.text_area :description,
- required: true,
class: 'wiki-edit wiki-toolbar',
container_class: '-wide',
with_text_formatting: true %>
diff --git a/app/views/projects/form/attributes/_description.html.erb b/app/views/projects/form/attributes/_description.html.erb
index 871f359a38..4a5b27df72 100644
--- a/app/views/projects/form/attributes/_description.html.erb
+++ b/app/views/projects/form/attributes/_description.html.erb
@@ -33,5 +33,5 @@ See docs/COPYRIGHT.rdoc for more details.
with_text_formatting: true,
rows: 5,
class: 'wiki-edit',
- container_class: '-wide' %>
+ container_class: '-xxwide' %>
diff --git a/app/views/settings/_general.html.erb b/app/views/settings/_general.html.erb
index 2bc94b4ab1..5bc2cf79b5 100644
--- a/app/views/settings/_general.html.erb
+++ b/app/views/settings/_general.html.erb
@@ -68,7 +68,7 @@ See docs/COPYRIGHT.rdoc for more details.
class: 'wiki-edit',
id: 'settings_welcome_text',
with_text_formatting: true,
- container_class: '-wide' %>
+ container_class: '-xxwide' %>
<%= setting_check_box :welcome_on_homescreen %>
diff --git a/config/initializers/secure_headers.rb b/config/initializers/secure_headers.rb
index cc412061dc..67223f1dbb 100644
--- a/config/initializers/secure_headers.rb
+++ b/config/initializers/secure_headers.rb
@@ -25,9 +25,11 @@
# Allow requests to CLI in dev mode
connect_src = default_src
+ # Add proxy configuration for Angular CLI to csp
if FrontendAssetHelper.assets_proxied?
- connect_src += %w[ws://localhost:* http://localhost:*]
- assets_src += %w[ws://localhost:* http://localhost:*]
+ proxied = ['ws://localhost:*', 'http://localhost:*', FrontendAssetHelper.cli_proxy]
+ connect_src += proxied
+ assets_src += proxied
end
config.csp = {
diff --git a/docs/development/running-tests.md b/docs/development/running-tests.md
index 207fc6c1e2..6ddd0b56bf 100644
--- a/docs/development/running-tests.md
+++ b/docs/development/running-tests.md
@@ -242,6 +242,9 @@ on a machine with 8 parallel instances.
If you want to access the development server of OpenProject from a VM,
you need to work around the CSP `localhost` restrictions.
+
+### Old way, fixed compilation
+
One way is to disable the Angular CLI that serves some of the assets when developing. To do that, run
```bash
@@ -255,6 +258,22 @@ OPENPROJECT_CLI_PROXY='' ./bin/rails s -b 0.0.0.0 -p 3000
Now assuming networking is set up in your VM, you can access your app server on `:3000` from it.
+### New way, with ng serve
+
+**The better way** when you want to develop against Edge is to set up your server to allow the CSP to the remote host.
+Assuming your openproject is served at `:3000` and your ng serve middleware is running at `:4200`,
+you can access both from inside a VM with nat/bridged networking as follows:
+
+```bash
+# Start ng serve middleware binding to all interfaces
+ng serve --host 0.0.0.0
+
+# Start your openproject server with the CLI proxy configuration set
+OPENPROJECT_CLI_PROXY=':4200' ./bin/rails s -b 0.0.0.0 -p 3000
+
+# Now access your server from http://:3000 with code reloading
+```
+
## Legacy LDAP tests
OpenProject supports using LDAP for user authentications. To test LDAP
diff --git a/frontend/src/app/components/wp-fast-table/state/wp-table-columns.service.ts b/frontend/src/app/components/wp-fast-table/state/wp-table-columns.service.ts
index f011e407e1..55d2b02713 100644
--- a/frontend/src/app/components/wp-fast-table/state/wp-table-columns.service.ts
+++ b/frontend/src/app/components/wp-fast-table/state/wp-table-columns.service.ts
@@ -61,10 +61,17 @@ export class WorkPackageTableColumnsService extends WorkPackageTableBaseService<
}
public applyToQuery(query:QueryResource) {
- query.columns = cloneHalResourceCollection(this.getColumns());
+ const toApply = this.getColumns();
+
+ const oldColumns = query.columns.map(el => el.id);
+ const newColumns = toApply.map(el => el.id);
+ query.columns = cloneHalResourceCollection(toApply);
+
+ // We can avoid reloading even with relation columns if we only removed columns
+ const onlyRemoved = _.difference(newColumns, oldColumns).length === 0;
// Reload the table visibly if adding relation columns.
- return this.hasRelationColumns();
+ return !onlyRemoved && this.hasRelationColumns();
}
/**
diff --git a/frontend/src/app/components/wp-query-select/wp-query-select.template.html b/frontend/src/app/components/wp-query-select/wp-query-select.template.html
index fa8b5a3c90..0e97f44ede 100644
--- a/frontend/src/app/components/wp-query-select/wp-query-select.template.html
+++ b/frontend/src/app/components/wp-query-select/wp-query-select.template.html
@@ -13,9 +13,9 @@
-
diff --git a/frontend/src/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts b/frontend/src/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts
index 403fce7d57..efb28f291a 100644
--- a/frontend/src/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts
+++ b/frontend/src/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts
@@ -165,7 +165,7 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy {
const img = document.createElement('img');
img.src = item.watcher.avatar;
img.alt = item.watcher.name;
- img.classList.add('avatar-mini');
+ img.classList.add('avatar-mini', 'avatar--fallback');
link.appendChild(img);
}
diff --git a/lib/open_project/form_tag_helper.rb b/lib/open_project/form_tag_helper.rb
index e9a84fc362..3921eec5c5 100644
--- a/lib/open_project/form_tag_helper.rb
+++ b/lib/open_project/form_tag_helper.rb
@@ -88,7 +88,7 @@ def styled_text_area_tag(name, content = nil, options = {})
def text_formatting_wrapper(target_id, options)
return ''.html_safe unless target_id.present?
- helper = ::OpenProject::TextFormatting::Formats.rich_helper.new(self)
+ helper = ::OpenProject::TextFormatting::Formats.rich_helper.new
helper.wikitoolbar_for target_id, options
end
diff --git a/lib/open_project/text_formatting/formats/markdown/helper.rb b/lib/open_project/text_formatting/formats/markdown/helper.rb
index ea1760c4ca..4d2cef1bdd 100644
--- a/lib/open_project/text_formatting/formats/markdown/helper.rb
+++ b/lib/open_project/text_formatting/formats/markdown/helper.rb
@@ -31,19 +31,16 @@
module OpenProject::TextFormatting::Formats
module Markdown
class Helper
- attr_reader :view_context
- def initialize(view_context)
- @view_context = view_context
- end
+ def initialize; end
def text_formatting_js_includes
- view_context.javascript_include_tag 'vendor/ckeditor/ckeditor.js'
+ helpers.javascript_include_tag 'vendor/ckeditor/ckeditor.js'
end
def wikitoolbar_for(field_id, **context)
# Hide the original textarea
- view_context.content_for(:additional_js_dom_ready) do
+ helpers.content_for(:additional_js_dom_ready) do
js = <<-JAVASCRIPT
var field = document.getElementById('#{field_id}');
field.style.display = 'none';
@@ -55,12 +52,18 @@ def wikitoolbar_for(field_id, **context)
# Pass an optional resource to the CKEditor instance
resource = context.fetch(:resource, {})
- view_context.content_tag 'op-ckeditor-form',
+ helpers.content_tag 'op-ckeditor-form',
'',
'textarea-selector': "##{field_id}",
'preview-context': context[:preview_context],
'data-resource': resource.to_json
end
+
+ protected
+
+ def helpers
+ ApplicationController.helpers
+ end
end
end
end
diff --git a/lib/open_project/text_formatting/formats/markdown/textile_converter.rb b/lib/open_project/text_formatting/formats/markdown/textile_converter.rb
index a0ef351d4d..6f91a06c82 100644
--- a/lib/open_project/text_formatting/formats/markdown/textile_converter.rb
+++ b/lib/open_project/text_formatting/formats/markdown/textile_converter.rb
@@ -221,7 +221,8 @@ def models_to_convert
::Journal => [:notes],
::Journal::MessageJournal => [:content],
::Journal::WikiContentJournal => [:text],
- ::Journal::WorkPackageJournal => [:description]
+ ::Journal::WorkPackageJournal => [:description],
+ ::AttributeHelpText => [:help_text]
}
end
diff --git a/lib/tabular_form_builder.rb b/lib/tabular_form_builder.rb
index ba33e42f17..c8ed087a62 100644
--- a/lib/tabular_form_builder.rb
+++ b/lib/tabular_form_builder.rb
@@ -211,7 +211,7 @@ def field_container_css_class(selector, options)
def text_formatting_wrapper(target_id, options)
return ''.html_safe unless target_id.present?
- helper = ::OpenProject::TextFormatting::Formats.rich_helper.new(@template)
+ helper = ::OpenProject::TextFormatting::Formats.rich_helper.new
helper.wikitoolbar_for target_id, options
end
diff --git a/vendored-plugins/openproject-backlogs/features/scrum_master.feature b/vendored-plugins/openproject-backlogs/features/scrum_master.feature
index de358f6a22..fce2e23ecd 100644
--- a/vendored-plugins/openproject-backlogs/features/scrum_master.feature
+++ b/vendored-plugins/openproject-backlogs/features/scrum_master.feature
@@ -259,22 +259,6 @@ Feature: Scrum Master
And Story A should be in the 2nd position of the sprint named Sprint 001
And Story B should be the higher item of Story A
- Scenario: view the sprint notes
- Given I have set the content for wiki page Sprint Template to Sprint Template
- And I have made Sprint Template the template page for sprint notes
- And I am on the taskboard for "Sprint 001"
- When I view the sprint notes
- Then the request should complete successfully
- Then the wiki page Sprint 001 should contain Sprint Template
-
- Scenario: edit the sprint notes
- Given I have set the content for wiki page Sprint Template to Sprint Template
- And I have made Sprint Template the template page for sprint notes
- And I am on the taskboard for "Sprint 001"
- When I edit the sprint notes
- Then the request should complete successfully
- Then the wiki page Sprint 001 should contain Sprint Template
-
Scenario: View tasks that have subtasks
Given I am on the taskboard for "Sprint 005"
Then I should see "Task 10" within "#tasks"
diff --git a/vendored-plugins/openproject-reporting/spec/features/menu_spec.rb b/vendored-plugins/openproject-reporting/spec/features/menu_spec.rb
index 113ed1f256..10efef6bee 100644
--- a/vendored-plugins/openproject-reporting/spec/features/menu_spec.rb
+++ b/vendored-plugins/openproject-reporting/spec/features/menu_spec.rb
@@ -69,8 +69,7 @@
it 'leads to cost reports' do
click_on 'Cost reports'
- expect(page).to have_selector('.breadcrumb > li', text: 'Ponyo')
- expect(page).to have_selector('.breadcrumb > li', text: 'Cost reports')
+ expect(page).to have_selector('.button--dropdown-text', text: 'Ponyo')
end
end
@@ -100,8 +99,6 @@
click_on 'Cost reports', visible: false
end
- expect(page).to have_selector('.breadcrumb > li', text: 'Cost reports')
-
# to make sure we're not seeing the project cost reports:
expect(page).not_to have_text('Ponyo')
end