Merge branch 'release/8.2' into dev

pull/6968/head
Henriette Dinger 6 years ago
commit e0b0d432ff
  1. 5
      app/assets/javascripts/onboarding/backlogs_tour.js
  2. 4
      app/assets/javascripts/onboarding/homescreen_tour.js
  3. 17
      app/assets/javascripts/onboarding/work_package_tour.js
  4. 2
      app/assets/stylesheets/content/_action_menu_main.sass
  5. 3
      app/assets/stylesheets/content/_custom_actions.sass
  6. 27
      app/assets/stylesheets/content/_forms.lsg
  7. 38
      app/assets/stylesheets/content/_forms.sass
  8. 11
      app/assets/stylesheets/content/_legacy_actions.sass
  9. 4
      app/assets/stylesheets/content/_modal.sass
  10. 3
      app/assets/stylesheets/content/_table.sass
  11. 10
      app/assets/stylesheets/content/work_packages/_table_content.sass
  12. 2
      app/assets/stylesheets/content/work_packages/_table_hierarchy.sass
  13. 44
      app/assets/stylesheets/content/work_packages/single_view/_single_view.sass
  14. 12
      app/assets/stylesheets/content/work_packages/timelines/_timelines.sass
  15. 2
      app/assets/stylesheets/content/work_packages/timelines/_timelines_header.sass
  16. 2
      app/assets/stylesheets/layout/_base_mobile.sass
  17. 1
      app/assets/stylesheets/layout/_drop_down.sass
  18. 12
      app/assets/stylesheets/layout/work_packages/_details_view.sass
  19. 1
      app/assets/stylesheets/layout/work_packages/_mobile.sass
  20. 2
      app/assets/stylesheets/layout/work_packages/_table.sass
  21. 3
      app/assets/stylesheets/openproject/_generic.sass
  22. 14
      app/assets/stylesheets/openproject/_mixins.sass
  23. 2
      app/controllers/application_controller.rb
  24. 8
      app/controllers/onboarding_controller.rb
  25. 2
      app/controllers/projects_controller.rb
  26. 2
      app/views/messages/show.html.erb
  27. 5
      config/locales/js-en.yml
  28. 2
      docker/entrypoint-all-in-one.sh
  29. 37
      frontend/src/app/components/resizer/wp-resizer.component.ts
  30. 2
      frontend/src/app/components/wp-form-group/wp-attribute-group.template.html
  31. 2
      lib/api/root.rb
  32. 2
      lib/open_project/design.rb
  33. 2
      lib/open_project/version.rb
  34. 2
      modules/my_project_page/app/controllers/my_projects_overviews_controller.rb
  35. 8
      modules/my_project_page/config/locales/en.seeders.yml
  36. 2
      modules/my_project_page/config/locales/en.yml
  37. BIN
      modules/my_project_page/config/locales/media/en/background-teaser-8-0v6.jpg
  38. BIN
      modules/my_project_page/config/locales/media/en/demo_project_teaser.png
  39. BIN
      modules/my_project_page/config/locales/media/en/scrum_project_teaser.png
  40. BIN
      public/favicon.ico
  41. BIN
      spec/support/custom_styles/favicons/favicon_image.png

@ -4,6 +4,7 @@
{
'next #content-wrapper': I18n.t('js.onboarding.steps.backlogs_overview'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-dark -hidden-arrow'
},
{
@ -11,6 +12,7 @@
'selector': '#sprint_backlogs_container .backlog .menu-trigger',
'description': I18n.t('js.onboarding.steps.backlogs_task_board_arrow'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
onNext: function () {
$('#sprint_backlogs_container .backlog .menu-trigger')[0].click();
}
@ -20,6 +22,7 @@
'selector': '#sprint_backlogs_container .backlog .menu .items',
'description': I18n.t('js.onboarding.steps.backlogs_task_board_select'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-dark',
onNext: function () {
$('#sprint_backlogs_container .backlog .show_task_board')[0].click();
@ -31,11 +34,13 @@
{
'next #content-wrapper': I18n.t('js.onboarding.steps.backlogs_task_board'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-dark -hidden-arrow'
},
{
'next #main-menu-work-packages-wrapper': I18n.t('js.onboarding.steps.wp_toggler'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
onNext: function () {
$('#main-menu-work-packages')[0].click();
}

@ -3,7 +3,8 @@
window.homescreenOnboardingTourSteps = [
{
'next #top-menu': I18n.t('js.onboarding.steps.welcome'),
'skipButton': {className: 'enjoyhint_btn-transparent'},
'skipButton': {className: 'enjoyhint_btn-transparent', text: I18n.t('js.onboarding.buttons.skip')},
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-hidden-arrow'
},
{
@ -12,7 +13,6 @@
'event': 'custom',
'showSkip': false,
'containerClass': '-dark -hidden-arrow',
'containerClass': '-dark -hidden-arrow',
'clickable': true,
onBeforeStart: function () {
// Handle the correct project selection and redirection

@ -4,6 +4,7 @@
{
'next .wp-table--row': I18n.t('js.onboarding.steps.wp_list'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
onNext: function () {
$(".wp-table--cell-span.id a ")[0].click();
}
@ -11,11 +12,13 @@
{
'next .work-packages-full-view--split-left': I18n.t('js.onboarding.steps.wp_full_view'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-dark -hidden-arrow'
},
{
'next .work-packages-list-view-button': I18n.t('js.onboarding.steps.wp_back_button'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
onNext: function () {
$('.work-packages-list-view-button')[0].click();
}
@ -23,11 +26,13 @@
{
'next .add-work-package': I18n.t('js.onboarding.steps.wp_create_button'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'shape': 'circle'
},
{
'next .timeline-toolbar--button': I18n.t('js.onboarding.steps.wp_timeline_button'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'shape': 'circle',
onNext: function () {
$('.timeline-toolbar--button')[0].click();
@ -36,28 +41,32 @@
{
'next .work-packages-tabletimeline--timeline-side': I18n.t('js.onboarding.steps.wp_timeline'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
'containerClass': '-dark -hidden-arrow'
},
{
'next .main-menu--arrow-left-to-project': I18n.t('js.onboarding.steps.sidebar_arrow'),
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
onNext: function () {
$('.main-menu--arrow-left-to-project')[0].click();
}
},
{
'next .members-menu-item': I18n.t('js.onboarding.steps.members'),
'showSkip': false
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
},
{
'next .wiki-menu--main-item': I18n.t('js.onboarding.steps.wiki'),
'showSkip': false
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.next')},
},
{
'next .menu-item--help': I18n.t('js.onboarding.steps.help_menu'),
'shape': 'circle',
'nextButton': {text: I18n.t('js.onboarding.steps.got_it')},
'showSkip': false
'showSkip': false,
'nextButton': {text: I18n.t('js.onboarding.buttons.got_it')}
}
];
});

@ -31,7 +31,7 @@
ul
list-style-type: none
margin: 0
width: 240px
min-width: 240px
border: 1px solid #dddddd
padding: 3px 0
background: #ffffff

@ -35,8 +35,9 @@
.custom-action
display: flex
justify-content: flex-end
flex: 1 1 auto
flex: 0 1 auto
margin-bottom: 0.5rem
max-width: calc(100vw - 20px)
@include text-shortener
.button

@ -1067,33 +1067,6 @@ Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod
</form>
```
## Styled checkboxes [TO BE REFACTORED]
```
<label class="checkbox-label">
<input type="checkbox">
<div class="styled-checkbox"></div>
</label>
<br>
<br>
<label class="checkbox-label">
checkbox label
<input type="checkbox">
<div class="styled-checkbox"></div>
</label>
<br>
<br>
<label class="checkbox-label">
<input type="checkbox">
<div class="styled-checkbox"></div>
checkbox label
</label>
```
# Forms: Radio buttons
## Within a form, multiple

@ -208,44 +208,6 @@ hr
width: 18px
opacity: 0.001
\:checked + .styled-checkbox:after
opacity: 1
.styled-checkbox
box-sizing: content-box
display: inline-block
vertical-align: top
width: 18px
height: 18px
padding: 0 5px
user-select: none
&:before
content: ''
position: absolute
width: 18px
height: 18px
background: #ffffff
border: 1px solid #cacaca
border-radius: 2px
cursor: pointer
box-shadow: inset 0 1px #fff
&:after
opacity: 0
content: ''
position: absolute
margin: 5px 2px
// Length of check tail
width: 11px
// Length of check foot
height: 3px
background: transparent
border: 3px solid #666666
border-top: none
border-right: none
transform: rotate(-50deg)
%form--fieldset-or-section
padding: 1rem 0 0
margin-bottom: 1rem

@ -35,14 +35,6 @@
position: relative
list-style: none
@mixin contextual($margin-top: 8px)
float: right
white-space: nowrap
line-height: 1.4em
margin-top: $margin-top
padding-left: 10px
ul.legacy-actions-main
@include legacy-actions-defaults
margin-left: 20px
@ -55,7 +47,8 @@ p.subtitle + ul.legacy-actions-specific
@include legacy-actions-defaults(-57px)
.message-reply-menu
@include contextual(-60px)
float: right
padding-left: 10px
> .button
margin-right: 0

@ -102,7 +102,7 @@ $ng-modal-image-width: $ng-modal-image-height
display: flex
align-items: center
height: $header-height
padding: 0 1.5rem
padding: 0 45px 0 1.5rem
border-bottom-style: solid
@include varprop(background-color, header-bg-color)
@include varprop(border-bottom-width, header-border-bottom-width)
@ -119,7 +119,7 @@ $ng-modal-image-width: $ng-modal-image-height
.op-modal--modal-close-button
float: none
position: absolute
right: 1rem
right: 10px
top: 0
.avatar,

@ -87,6 +87,9 @@ table.generic-table
text-align: left
line-height: 34px
padding: 0
// This is needed for a bug in FF as described here
// https://www.456bereastreet.com/archive/201305/firefox_and_the_magical_text-overflowellipsis_z-index/
z-index: 1
&.-right
text-align: right

@ -33,19 +33,23 @@
.wp-table--row
cursor: pointer
.wp-table--row,
#empty-row-notification
height: $table-timeline--row-height
// Hide collapsed rows (hierarchies, relations)
&.-collapsed
display: none
.work-package-table--container table.generic-table tbody td
padding-left: 0
padding-top: 0
padding-bottom: 0
// To display the input field border correctly (input height is 24px)
line-height: 24px
height: 41px
// Styles for inline editable attributes
.work-package-table--container td.-editable
padding-top: 0
padding-bottom: 0
display: table-cell
width: auto

@ -26,7 +26,7 @@
display: inline
.wp-table--hierarchy-span
text-align: end
text-align: right
display: block
float: left
margin-left: 5px

@ -202,22 +202,13 @@ i
// Implement two column layout for WP full screen view
@media screen and (min-width: 92rem), print
.action-show .attributes-group,
.full-create .attributes-group
.action-show .-can-have-columns,
.full-create .-can-have-columns
.-columns-2
column-count: 2
@include two-column-layout
column-gap: 3rem
.attributes-key-value
-webkit-column-break-inside: avoid
page-break-inside: avoid
break-inside: avoid
overflow: hidden
// For some reason chrome seems to treat a two column layout
// as if it would result in showing the backside of this element.
// This leads to input and select elements not showing their values.
backface-visibility: visible
@supports (column-span: all)
// Let some elements still span both columns
.attributes-key-value.-span-all-columns
@ -238,39 +229,40 @@ i
.wp-info-wrapper
display: flex
flex-wrap: wrap
align-items: center
padding-top: 0.5rem
.wp-status-button .button
@include text-shortener
padding: 5px
margin-bottom: 0
@include varprop(background-color, status-selector-bg-color)
border: none
color: white
white-space: nowrap
// Should not be longer than mobile screen width (margin of 15px left and right)
max-width: calc(100vw - 30px)
.button--text
margin: 0 5px
attribute-help-text .help-text--entry
line-height: 25px
margin: 0 10px 0 -10px
.icon:before
padding: 0
attribute-help-text
flex: 0
.help-text--entry
line-height: 25px
margin: 0 10px 0 -14px
.icon:before
padding: 0
.work-packages--info-row
flex-grow: 2
flex: 1 1 200px
attribute-help-text,
.wp-status-button,
.work-packages--info-row
margin-bottom: 0.5rem
&.-wrapped
flex-wrap: wrap
.work-packages--info-row,
attribute-help-text,
wp-custom-action
margin-bottom: 0.5rem
.work-packages--new .wp-status-button
padding: 3px
.button

@ -53,21 +53,19 @@
// Add bottom border to timeline
.wp-table-timeline--body
border-bottom: 1px solid $table-row-border-color
outline: 1px solid $table-row-border-color
// Ensure the height of table and timeline rows
.wp-timeline-cell
// Ensure the height of table and timeline rows
height: $table-timeline--row-height
// Vertically center elements
display: flex
align-items: center
&:first-child
// The first table child is 1px larger
height: calc(#{$table-timeline--row-height} + 1px)
.wp-timeline-cell
// Vertically center elements
display: flex
align-items: center
// Need to disable flex behavior on children
> div
flex: 0 0 auto

@ -3,7 +3,7 @@
width: 100%
position: sticky
top: 0
z-index: 1
z-index: 2
.wp-timeline--header-element
background: white

@ -33,7 +33,7 @@
-webkit-overflow-scrolling: touch
#main-menu ~ #content-wrapper
padding: 5px 15px 0 15px !important
padding: 15px
#main
grid-template-columns: auto

@ -44,7 +44,6 @@
.dropdown .dropdown-menu,
.dropdown .dropdown-panel,
.drop-down .menu-drop-down-container
min-width: 200px
list-style: none
background: #FFF
border: solid 1px #DDD

@ -42,17 +42,9 @@ body.action-create
// Will eventually be overridden by the resizer
flex-basis: 580px
&.-columns-2
&.-can-have-columns
.-columns-2
column-count: 2
column-gap: 4rem
.attributes-key-value
-webkit-column-break-inside: avoid
page-break-inside: avoid
break-inside: avoid
overflow: hidden
backface-visibility: visible
@include two-column-layout
.work-packages--details
height: 100%

@ -147,6 +147,7 @@
.toolbar-item
flex-grow: 0
.work-packages-full-view--split-container
border-top: none

@ -81,7 +81,7 @@
.row-hovered
background: #E5F2FA
z-index: 100
z-index: 1
// Left part of the split view

@ -53,6 +53,9 @@
.-hidden-overflow
overflow: hidden !important
.-visible-overflow
overflow: visible !important
.indent
padding-left: 10px

@ -140,3 +140,17 @@
&::-webkit-scrollbar-thumb
background: #ddd
visibility: visible
@mixin two-column-layout
column-count: 2
column-gap: 4rem
.attributes-key-value
-webkit-column-break-inside: avoid
page-break-inside: avoid
break-inside: avoid
overflow: hidden
// For some reason chrome seems to treat a two column layout
// as if it would result in showing the backside of this element.
// This leads to input and select elements not showing their values.
backface-visibility: visible

@ -260,6 +260,8 @@ class ApplicationController < ActionController::Base
'X-Reason' => 'login needed',
'WWW-Authenticate' => auth_header
end
format.all { head :not_acceptable }
end
return false
end

@ -36,11 +36,11 @@ class OnboardingController < ApplicationController
.call(request, permitted_params, params)
if result && result.success
# Remove the first_time_user param so that the modal is not shown again after redirect
# Remove all query params:
# the first_time_user param so that the modal is not shown again after redirect,
# the welcome param so that the analytics is not fired again
uri = Addressable::URI.parse(request.referrer.to_s)
params = uri.query_values
params.delete('first_time_user')
uri.query_values = params
uri.query_values = {}
redirect_to uri.to_s
flash[:notice] = l(:notice_account_updated)

@ -171,6 +171,8 @@ class ProjectsController < ApplicationController
def modules
@project.enabled_module_names = permitted_params.project[:enabled_module_names]
# Ensure the project is touched to update its cache key
@project.touch
flash[:notice] = I18n.t(:notice_successful_update)
redirect_to settings_project_path(@project, tab: 'modules')
end

@ -83,7 +83,7 @@ See docs/COPYRIGHT.rdoc for more details.
r: message,
anchor: "message-#{message.id}") %>
-
<%= authoring message.created_on, message.author %>
<%= authoring message.created_on, message.author %>
</h3>
<div class="message-reply-menu">
<%= link_to(icon_wrapper('icon-quote', t(:button_quote)),

@ -313,6 +313,10 @@ en:
show_modal: 'Show attribute help text entry'
onboarding:
buttons:
skip: 'Skip'
next: 'Next'
got_it: 'Got it'
steps:
welcome: 'Take a three minutes introduction tour to learn the most <b>important features</b>. <br> We recommend completing the steps until the end. You can restart the tour any time.'
project_selection: 'Please select one of the projects with useful demo data to get started. <br> The <b>Demo project</b> suits best for classical project management, while the <b>Scrum project</b> is better for Agile project management.'
@ -331,7 +335,6 @@ en:
wp_timeline_button: 'You can activate the <b>Gantt chart</b> to create a timeline for your project.'
wp_timeline: 'Here you can edit your project plan. Create new phases, milestones, and add dependencies. All team members can see and update the latest plan at any time.'
help_menu: 'In the <b>Help</b> menu you will find a user guide and additional help resources. <br> Enjoy your work with OpenProject!'
got_it: 'Got it'
password_confirmation:
field_description: 'You need to enter your account password to confirm this change.'

@ -54,7 +54,7 @@ install_plugins() {
migrate() {
pushd /usr/src/app
/etc/init.d/memcached start
rake db:migrate db:seed
bundle exec rake db:migrate db:seed db:structure:dump
/etc/init.d/memcached stop
chown app:app db/structure.sql
popd

@ -50,8 +50,6 @@ export class WpResizerDirective implements OnInit, OnDestroy {
public moving:boolean = false;
private unregisterTransitionListener:Function;
constructor(readonly toggleService:MainMenuToggleService,
private elementRef:ElementRef,
readonly $transitions:TransitionService) {
@ -77,7 +75,6 @@ export class WpResizerDirective implements OnInit, OnDestroy {
// Otherwise function will be executed with empty list
jQuery(document).ready(() => {
this.applyColumnLayout(this.resizingElement, this.elementFlex);
this.applyInfoRowLayout();
});
// Add event listener
@ -90,26 +87,17 @@ export class WpResizerDirective implements OnInit, OnDestroy {
untilComponentDestroyed(this)
)
.subscribe( changeData => {
jQuery('.-can-have-columns').toggleClass('-columns-2', jQuery('.work-packages-full-view--split-left').width()! > 750);
this.toggleFullscreenColumns();
});
let that = this;
jQuery(window).resize(function() {
jQuery('.-can-have-columns').toggleClass('-columns-2', jQuery('.work-packages-full-view--split-left').width()! > 750);
that.applyInfoRowLayout();
});
// Listen to changes from a non overview state to the overview state
// which requires us to reevaluate the wrapping of the info row.
this.unregisterTransitionListener = this.$transitions.onSuccess({ to: 'work-packages.list.details.overview' }, (transition) => {
setTimeout(() => this.applyInfoRowLayout());
that.toggleFullscreenColumns();
});
}
ngOnDestroy() {
// Reset the style when killing this directive, otherwise the style remains
this.resizingElement.style.flexBasis = null;
this.unregisterTransitionListener();
}
@HostListener('mousedown', ['$event'])
@ -196,9 +184,6 @@ export class WpResizerDirective implements OnInit, OnDestroy {
// Apply two column layout
this.applyColumnLayout(element, newValue);
// Apply info row Layout
this.applyInfoRowLayout();
// Set new width
element.style.flexBasis = newValue + 'px';
}
@ -206,18 +191,22 @@ export class WpResizerDirective implements OnInit, OnDestroy {
private applyColumnLayout(element:HTMLElement, newWidth:number) {
// Apply two column layout in fullscreen view of a workpackage
if (element === jQuery('.work-packages-full-view--split-right')[0]) {
jQuery('.-can-have-columns').toggleClass('-columns-2', jQuery('.work-packages-full-view--split-left').width()! > 750);
this.toggleFullscreenColumns();
}
// Apply two column layout when details view of wp is open
else {
element.classList.toggle('-columns-2', newWidth > 700);
this.toggleColumns(element, 700);
}
}
private toggleColumns(element:HTMLElement, checkWidth:number = 750) {
if (element) {
jQuery(element).toggleClass('-can-have-columns', element.offsetWidth > checkWidth);
}
}
private applyInfoRowLayout() {
jQuery('.wp-info-wrapper').toggleClass(
'-wrapped',
jQuery('.wp-info-wrapper').width()! - jQuery('wp-custom-actions').width()! - jQuery('wp-status-button .button').width()! < 475
);
private toggleFullscreenColumns() {
let fullScreenLeftView = jQuery('.work-packages-full-view--split-left')[0];
this.toggleColumns(fullScreenLeftView);
}
}

@ -1,4 +1,4 @@
<div class="-can-have-columns -columns-2">
<div class="-columns-2">
<div class="attributes-key-value"
[ngClass]="{'-span-all-columns': descriptor.spanAll }"
*ngFor="let descriptor of group.members; trackBy:trackByName">

@ -223,7 +223,7 @@ module API
# hide internal errors behind the same JSON response as all other errors
# only doing it in production to allow for easier debugging
if Rails.env.production?
error_response StandardError, ::API::Errors::InternalError.new, rescue_subclasses: true
error_response StandardError, ::API::Errors::InternalError, rescue_subclasses: true
end
# run authentication before each request

@ -198,7 +198,7 @@ module OpenProject
'timeline--header-border-color' => '#aaaaaa',
'timeline--grid-color' => '#dddddd',
'timeline--separator' => '3px solid #E7E7E7',
'table-timeline--row-height' => '41px',
'table-timeline--row-height' => '40px',
'status-selector-bg-color' => '#F99601',
'status-selector-bg-hover-color' => '#E08600'
}.freeze

@ -34,7 +34,7 @@ module OpenProject
module VERSION #:nodoc:
MAJOR = 8
MINOR = 2
PATCH = 0
PATCH = 1
TINY = PATCH # Redmine compat
# Used by semver to define the special version (if any).

@ -54,7 +54,7 @@ class MyProjectsOverviewsController < ApplicationController
block_name: block_name,
textile: textile })
else
render plain: t(:error_textile_not_saved), status: 400
render plain: t(:error_block_not_saved), status: 400
end
end

@ -35,7 +35,7 @@ en:
- id: b
title: ''
content: |
![Teaser](##attachment:"background-teaser-8-0v6.jpg")
![Teaser](##attachment:"demo_project_teaser.png")
left:
- id: a
title: Welcome to your demo project
@ -53,7 +53,7 @@ en:
Here you will find our [User Guides](https://www.openproject.org/help/).
Please let us know if you have any questions or need support. Contact us: [support[at]openproject.com](mailto:support@openproject.com).
attachments:
- background-teaser-8-0v6.jpg
- demo_project_teaser.png
- block: project_description
- block: work_package_tracking
right:
@ -65,7 +65,7 @@ en:
- id: b
title: ''
content: |
![Teaser](##attachment:"background-teaser-8-0v6.jpg")
![Teaser](##attachment:"scrum_project_teaser.png")
left:
- id: a
title: Welcome to your Scrum demo project
@ -84,7 +84,7 @@ en:
Here you will find our [User Guides](https://www.openproject.org/help/).
Please let us know if you have any questions or need support. Contact us: [support[at]openproject.com](mailto:support@openproject.com).
attachments:
- background-teaser-8-0v6.jpg
- scrum_project_teaser.png
- block: project_description
- block: work_package_tracking
right:

@ -20,8 +20,8 @@
en:
button_edit_this_page: "Edit this page"
error_block_not_saved: "The text block could not be saved."
error_saving_changes: "The changes could not be saved: %{errors}"
error_textile_not_saved: "The textile block could not be saved."
label_hidden_elements: "Hidden elements"
label_visible_elements: "Visible elements"
label_project_description: "Project description"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 336 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Loading…
Cancel
Save