Skip to content

Commit

Permalink
Merge branch 'release/15.1' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
openprojectci committed Dec 7, 2024
2 parents d651bb7 + 0db0ee7 commit 9f3cffa
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class UpdateItemContract < Dry::Validation::Contract

rule(:short) do
next if schema_error?(:item)
next unless key?

key.failure(:not_unique) if values[:item].siblings.exists?(short: value)
end
Expand Down
18 changes: 18 additions & 0 deletions app/controllers/sys_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ def repo_auth
end
end

def fetch_changesets
projects = []
if params[:id]
projects << Project.active.has_module(:repository).find_by!(identifier: params[:id])
else
projects = Project.active.has_module(:repository)
.includes(:repository).references(:repositories)
end
projects.each do |project|
if project.repository
project.repository.fetch_changesets
end
end
head :ok
rescue ActiveRecord::RecordNotFound
head :not_found
end

private

def authorized?(project, user)
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -704,8 +704,8 @@

scope controller: "sys" do
match "/sys/repo_auth", action: "repo_auth", via: %i[get post]
get "/sys/fetch_changesets", action: "fetch_changesets"
match "/sys/projects", to: proc { [410, {}, [""]] }, via: :all
match "/sys/fetch_changesets", to: proc { [410, {}, [""]] }, via: :all
match "/sys/projects/:id/repository/update_storage", to: proc { [410, {}, [""]] }, via: :all
end

Expand Down
2 changes: 1 addition & 1 deletion docs/release-notes/15-0-0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,4 @@ Last but not least, we are very grateful for our very engaged translation contri
- [hmmftg](https://crowdin.com/profile/hmmftg), for a great number of translations into Persian.
- [william](https://crowdin.com/profile/WilliamFromTW), for a great number of translations into Chinese Simplified and Chinese Traditional.

Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated!
Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated!
87 changes: 71 additions & 16 deletions docs/release-notes/15-1-0/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,78 @@ title: OpenProject 15.1.0
sidebar_navigation:
title: 15.1.0
release_version: 15.1.0
release_date: 2024-11-28
release_date: 2024-12-11
---

# OpenProject 15.1.0

Release date: 2024-11-28
Release date: 2024-12-11

We released OpenProject [OpenProject 15.1.0](https://community.openproject.org/versions/2122).
The release contains several bug fixes and we recommend updating to the newest version.
In these Release Notes, we will give an overview of important feature changes.
At the end, you will find a complete list of all changes and bug fixes.
We released [OpenProject 15.1.0](https://community.openproject.org/versions/2122). The release contains several bug fixes, and we recommend updating to the newest version.
In these Release Notes, we will give an overview of important feature changes and technical updates. At the end, you will find a complete list of all changes and bug fixes.

## Important feature changes

<!-- Inform about the major features in this section -->
### Custom fields of type hierarchy (Enterprise add-on)

## Important updates and breaking changes
Enterprise customers can now use a new type of custom field that allows **multi-level selections**. This makes it easier for users to organize and navigate complex data in structured, multi-level formats within work packages. The new custom fields of the hierarchy type can be added to work packages and then structured into several lower-level values.

<!-- Remove this section if empty, add to it in pull requests linking to tickets and provide information -->
Each custom field of type hierarchy can be given a short name (e.g. B for Berlin). Here's an example of how custom fields of the hierarchy type look like, using the example of a detailed assignment of workspaces:

![Example screenshot of custom fields of type hiearchy, displaying different cities as main offices](openproject-15-1-custom-field-hierarchy.jpg)

[Read all about custom fields in our system admin guide](../../system-admin-guide/custom-fields/).

### Redesign of the Relations tab in work packages

The Relations tab in work packages has been completely redesigned using Primer design system, including a **new dropdown menu that allows you to directly choose the type of relation**, e.g. if the related work package is a successor and necessarily needs to start after the selected one finishes.

Additionally, you can now add a description to add further information about the relation. Please note that the description will be displayed on both work packages, below the related other work package.

> [!NOTE]
> Important information: With this redesign, **you will no longer be able to create new work packages directly on the Relations tab**. Please tell us if you were using this feature a lot. If it will be missed by many users, we will find a way to bring it back.
![Screenshot showing the new Relations tab in a work package](openproject-15-1-relations.png)

[Read all about work package relations and hierarchies in our user guide](../../user-guide/work-packages/work-package-relations-hierarchies/).

### Redesign of the Meetings index page

The index page of the Meetings module has been redesigned with Primer as well, making it easier to read and have a more modern look. You see your list of meetings in some kind of table view, with the columns being: Title, Date and time, Duration, and Location.

The + Meeting button in the top right corner now offers a dropdown menu where you can directly choose whether you want to add a dynamic or classic meeting.

Here's an example screenshot of the redesigned Meetings index page:

![Example screenshot of the redesigned Meetings index page](openproject-15-1-meetings.png)

[Learn what is possible with OpenProject's Dynamic Meetings to improve collaboration with your colleagues](../../user-guide/meetings/dynamic-meetings/).

### Manual page breaks in PDF work package exports

With our work package export feature, people can generate good-looking PDFs. Sometimes, however, the page break comes at an inconvenient place. With version 15.1, users can now force a manual page break in the work package description. This ensures, for example, that a signature can always be inserted on the correct page.

![Example of a work package description with an employee conctract and inserted page breaks](openproject-15-1-page-break-contract-highlighted.png)

[Learn how to export work packages and what options you have](../../user-guide/work-packages/exporting/).

### Zen mode for project lists

Zen mode allows users to focus on a certain page, as all other menu items and elements are hidden, and the page is displayed in full screen. OpenProject already offers zen mode for other modules like Work packages, Boards, Gantt charts or Calendar – and with version 15.1 also for project lists.

Here is how zen mode for project lists looks like:

![Example screenshot of a project list in zen mode](openproject-15-1-zen-mode-highlighted.png)

[Read all about OpenProject's project lists in our user guide](../../user-guide/projects/project-lists/).

## Important technical updates

### Possibility to lock seeded admin users, e.g. when using LDAP

Administrators of automated deployments can now choose to skip the automatically integrated creation of an admin user. This is useful if you have set up an LDAP or SSO integration – such as those used for openDesk environments – and you want to prevent the admin user from logging in. Administrators no longer have to manually disable this automatically created admin user and thus run the risk of forgetting to do so, which would pose a security risk.

Read more about [seeding through environment for OpenProject configuration in our Installation & operations guide](../../installation-and-operations/configuration/#seeding-through-environment)

<!--more-->

Expand Down Expand Up @@ -68,12 +121,14 @@ At the end, you will find a complete list of all changes and bug fixes.
<!-- Warning: Anything above this line will be automatically removed by the release script -->

## Contributions
A very special thank you goes to our sponsors for this release.
Also a big thanks to our Community members for reporting bugs and helping us identify and provide fixes.
Special thanks for reporting and finding bugs go to Frank Long, Claudio Pagnani, Ivan Kuchin, samuel law, Gerrit B..

Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings!
Would you like to help out with translations yourself?
Then take a look at our translation guide and find out exactly how you can contribute.
It is very much appreciated!
A very special thank you goes to our sponsors of this release: Deutsche Bahn for sponsoring custom fields of type hierarchy, and City of Cologne for sponsoring custom fields of type hierarchy as well as zen mode for project lists.

Also, a big thanks to our Community members for reporting bugs and helping us identify and provide fixes. Special thanks for reporting and finding bugs go to Bill Bai, Sam Yelman, Knight Chang, Gábor Alexovics, Gregor Buergisser, Andrey Dermeyko, Various Interactive, Clayton Belcher, Александр Татаринцев, and Keno Krewer.

Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight
- [José Helbert Pina](https://crowdin.com/profile/GZTranslations), for a great number of translations into Portuguese.
- [Alexander Aleschenko](https://crowdin.com/profile/top4ek), for a great number of translations into Russian.
- [Adam Siemienski](https://crowdin.com/profile/siemienas), for a great number of translations into Polish.

Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated!
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
let!(:vader) { create(:hierarchy_item) }
let!(:luke) { create(:hierarchy_item, label: "luke", short: "ls", parent: vader) }
let!(:leia) { create(:hierarchy_item, label: "leia", short: "lo", parent: vader) }
let!(:starkiller) { create(:hierarchy_item, label: "starkiller", parent: vader) }

context "when all required fields are valid" do
it "is valid" do
Expand Down
48 changes: 48 additions & 0 deletions spec/controllers/sys_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -493,4 +493,52 @@
end
end
end

describe "#fetch_changesets" do
let(:params) { { id: repository_project.identifier } }

before do
request.env["HTTP_AUTHORIZATION"] =
ActionController::HttpAuthentication::Basic.encode_credentials(
valid_user.login,
valid_user_password
)

allow_any_instance_of(Repository::Subversion).to receive(:fetch_changesets).and_return(true)

get "fetch_changesets", params: params.merge({ key: api_key })
end

context "with a project identifier" do
it "is successful" do
expect(response)
.to have_http_status(:ok)
end
end

context "without a project identifier" do
let(:params) { {} }

it "is successful" do
expect(response)
.to have_http_status(:ok)
end
end

context "for an unknown project" do
let(:params) { { id: 0 } }

it "returns 404" do
expect(response)
.to have_http_status(:not_found)
end
end

context "when disabled", with_settings: { sys_api_enabled?: false } do
it "is 403 forbidden" do
expect(response)
.to have_http_status(:forbidden)
end
end
end
end
1 change: 0 additions & 1 deletion spec/factories/hierarchy_item_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,5 @@
FactoryBot.define do
factory :hierarchy_item, class: "CustomField::Hierarchy::Item" do
sequence(:label) { |n| "Item #{n}" }
sequence(:short) { |n| "I #{n}" }
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ def label_for_relation_type(relation_type)
describe "rendering" do
it "renders the relations tab" do
scroll_to_element relations_panel

wait_for_network_idle

expect(page).to have_css(relations_panel_selector)

tabs.expect_counter("relations", 4)
Expand All @@ -120,6 +123,8 @@ def label_for_relation_type(relation_type)
it "can delete relations" do
scroll_to_element relations_panel

wait_for_network_idle

relations_tab.remove_relation(relation_follows)

expect { relation_follows.reload }.to raise_error(ActiveRecord::RecordNotFound)
Expand All @@ -130,6 +135,8 @@ def label_for_relation_type(relation_type)
it "can delete children" do
scroll_to_element relations_panel

wait_for_network_idle

relations_tab.remove_child(child_wp)
expect(child_wp.reload.parent).to be_nil

Expand All @@ -141,6 +148,8 @@ def label_for_relation_type(relation_type)
it "renders an edit form" do
scroll_to_element relations_panel

wait_for_network_idle

relation_row = relations_tab.expect_relation(relation_follows)

relations_tab.edit_relation_description(relation_follows, "Discovered relations have descriptions!")
Expand All @@ -167,6 +176,8 @@ def label_for_relation_type(relation_type)
it "does not have an edit action for children" do
scroll_to_element relations_panel

wait_for_network_idle

child_row = relations_panel.find("[data-test-selector='op-relation-row-#{child_wp.id}']")

within(child_row) do
Expand Down Expand Up @@ -196,10 +207,18 @@ def label_for_relation_type(relation_type)
relation_type: Relation::TYPE_FOLLOWS)
end

before do
another_wp
relation_to
end

it "shows the correct related WorkPackage in the dialog (regression #59771)" do
scroll_to_element relations_panel

relations_tab.open_relation_dialog(relation_to)
wait_for_network_idle

relations_tab.expect_relation(another_wp)
relations_tab.open_relation_dialog(another_wp)

within "##{WorkPackageRelationsTab::WorkPackageRelationDialogComponent::DIALOG_ID}" do
expect(page).to have_field("Work package",
Expand All @@ -216,6 +235,8 @@ def label_for_relation_type(relation_type)
it "renders the new relation form for the selected type and creates the relation" do
scroll_to_element relations_panel

wait_for_network_idle

relations_tab.add_relation(type: :precedes, relatable: wp_successor,
description: "Discovered relations have descriptions!")
relations_tab.expect_relation(wp_successor)
Expand Down Expand Up @@ -252,6 +273,8 @@ def label_for_relation_type(relation_type)
it "renders the new child form and creates the child relationship" do
scroll_to_element relations_panel

wait_for_network_idle

tabs.expect_counter("relations", 4)

relations_tab.add_existing_child(not_yet_child_wp)
Expand Down Expand Up @@ -310,6 +333,8 @@ def label_for_relation_type(relation_type)
it "does not show options to add or edit relations" do
scroll_to_element relations_panel

wait_for_network_idle

tabs.expect_counter("relations", 4)

relations_tab.expect_no_add_relation_button
Expand All @@ -325,6 +350,8 @@ def label_for_relation_type(relation_type)
it "does not show the option to delete the child" do
scroll_to_element relations_panel

wait_for_network_idle

tabs.expect_counter("relations", 4)

# The menu is shown as the user can add a relation
Expand All @@ -346,6 +373,8 @@ def label_for_relation_type(relation_type)
it "does not show the option to edit the relation but only the child" do
scroll_to_element relations_panel

wait_for_network_idle

tabs.expect_counter("relations", 4)

# The menu is shown as the user can add a child
Expand Down
4 changes: 2 additions & 2 deletions spec/support/components/work_packages/relations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ def expect_no_add_relation_button

def find_row(relatable)
actual_relatable = find_relatable(relatable)
page.find_test_selector("op-relation-row-#{actual_relatable.id}")
page.find_test_selector("op-relation-row-#{actual_relatable.id}", wait: 5)
end

def find_some_row(text:)
page.find("[data-test-selector^='op-relation-row']", text:)
page.find("[data-test-selector^='op-relation-row']", text:, wait: 5)
end

def expect_row(work_package)
Expand Down

0 comments on commit 9f3cffa

Please sign in to comment.