mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Move new feature widget to rails
This commit is contained in:
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
@@ -32,3 +32,4 @@
|
||||
@import "work_packages/progress/modal_body_component"
|
||||
@import "work_packages/reminder/modal_body_component"
|
||||
@import "work_packages/split_view_component"
|
||||
@import "homescreen/new_features_component"
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<div class="op-new-features">
|
||||
<p class="widget-box--additional-info">
|
||||
<%= new_features_header %>
|
||||
</p>
|
||||
<div class="widget-box--description">
|
||||
<div>
|
||||
<p><%= new_features_title %></p>
|
||||
<ul>
|
||||
<% new_features.values.each do |line| %>
|
||||
<li><%= line %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<img
|
||||
class="widget-box--teaser-image op-new-features--teaser-image"
|
||||
role="presentation"
|
||||
src="<%= asset_path(feature_teaser_image) %>"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<%= helpers.static_link_to :current_release_notes, label: learn_more_link_text %>
|
||||
</div>
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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.
|
||||
#++
|
||||
class Homescreen::NewFeaturesComponent < ApplicationComponent
|
||||
def feature_version
|
||||
[
|
||||
OpenProject::VERSION::MAJOR,
|
||||
OpenProject::VERSION::MINOR
|
||||
].join("_")
|
||||
end
|
||||
|
||||
def feature_teaser_image
|
||||
"#{feature_version}_features.svg"
|
||||
end
|
||||
|
||||
def new_features_header
|
||||
I18n.t("homescreen.blocks.new_features.header")
|
||||
end
|
||||
|
||||
def learn_more_link_text
|
||||
I18n.t("homescreen.blocks.new_features.learn_about")
|
||||
end
|
||||
|
||||
def new_features_title
|
||||
I18n.t("homescreen.blocks.new_features.#{feature_version}.new_features_title")
|
||||
end
|
||||
|
||||
def new_features
|
||||
I18n.t("homescreen.blocks.new_features.#{feature_version}.new_features_list")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
//-- 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.
|
||||
//++
|
||||
|
||||
@import helpers
|
||||
|
||||
.op-new-features
|
||||
&--teaser-image
|
||||
background-image: var(--new-feature-teaser-image)
|
||||
min-width: 170px
|
||||
background-size: contain
|
||||
background-repeat: no-repeat
|
||||
background-position-x: right
|
||||
|
||||
.widget-box--description
|
||||
padding-bottom: 1rem
|
||||
|
||||
@media (max-width: $breakpoint-md)
|
||||
.widget-box--description
|
||||
grid-template-columns: 1fr !important
|
||||
|
||||
.op-new-features--teaser-image
|
||||
order: -1
|
||||
justify-self: center
|
||||
@@ -41,18 +41,6 @@ module HomescreenHelper
|
||||
op_icon("icon-context icon-enterprise")
|
||||
end
|
||||
|
||||
##
|
||||
# Render a static link defined in OpenProject::Static::Links
|
||||
def static_link_to(key)
|
||||
link = OpenProject::Static::Links.links[key]
|
||||
label = I18n.t(link[:label])
|
||||
|
||||
link_to label,
|
||||
link[:href],
|
||||
title: label,
|
||||
target: "_blank", rel: "noopener"
|
||||
end
|
||||
|
||||
##
|
||||
# Determine whether we should render the links on homescreen?
|
||||
def show_homescreen_links?
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%= render "homescreen/blocks/header", title: t(:label_new_features) %>
|
||||
|
||||
<div class="op-widget-box--body">
|
||||
<opce-homescreen-new-features-block></opce-homescreen-new-features-block>
|
||||
<%= render Homescreen::NewFeaturesComponent.new %>
|
||||
</div>
|
||||
|
||||
@@ -2645,6 +2645,21 @@ en:
|
||||
community: "OpenProject community"
|
||||
upsell:
|
||||
title: "Upgrade to Enterprise edition"
|
||||
new_features:
|
||||
header: "Read about new features and product updates."
|
||||
learn_about: "Learn more about all new features"
|
||||
# We need to include the version to invalidate outdated translations in other locales
|
||||
"16_4":
|
||||
new_features_title: >
|
||||
The release contains various new features and improvements, such as:
|
||||
new_features_list:
|
||||
line_0: Option to auto-sync system color + contrast mode.
|
||||
line_1: Dark high contrast mode for improved accessibility.
|
||||
line_2: PDF export of project lists.
|
||||
line_3: Custom font for all PDF exports (Enterprise add-on).
|
||||
line_4: Improved meeting participants dialog.
|
||||
line_5: Improved budget handling in project queries and budget planning.
|
||||
line_6: Updated Home and Project overview page.
|
||||
links:
|
||||
upgrade_enterprise_edition: "Upgrade to Enterprise edition"
|
||||
postgres_migration: "Migrating your installation to PostgreSQL"
|
||||
|
||||
@@ -327,25 +327,6 @@ en:
|
||||
date: "%{attribute} is no valid date - YYYY-MM-DD expected."
|
||||
general: "An error has occurred."
|
||||
|
||||
homescreen:
|
||||
blocks:
|
||||
new_features:
|
||||
text_new_features: "Read about new features and product updates."
|
||||
learn_about: "Learn more about all new features"
|
||||
# Include the version to invalidate outdated translations in other locales.
|
||||
# Otherwise, e.g. Chinese might still have the translations for 10.0 in the 12.0 release.
|
||||
"16_3":
|
||||
standard:
|
||||
new_features_html: >
|
||||
The release contains various new features and improvements, such as <br>
|
||||
<ul class="%{list_styling_class}">
|
||||
<li>UX/UI improvements for a more modern look.</li>
|
||||
<li>Meetings: Option to mute email notifications and ICS.</li>
|
||||
<li>Ongoing timers shown in the My time tracking module.</li>
|
||||
<li>Progress reporting: % Complete sum also shown in Status-based mode.</li>
|
||||
<li>Nextcloud Health check: Indicate missing token exchange capability (Enterprise add-on).</li>
|
||||
</ul>
|
||||
|
||||
ical_sharing_modal:
|
||||
title: "Subscribe to calendar"
|
||||
inital_setup_error_message: "An error occured while fetching data."
|
||||
|
||||
@@ -186,7 +186,6 @@ import { GlobalSearchWorkPackagesComponent } from 'core-app/core/global_search/g
|
||||
import {
|
||||
CustomDateActionAdminComponent,
|
||||
} from 'core-app/features/work-packages/components/wp-custom-actions/date-action/custom-date-action-admin.component';
|
||||
import { HomescreenNewFeaturesBlockComponent } from 'core-app/features/homescreen/blocks/new-features.component';
|
||||
import {
|
||||
ZenModeButtonComponent,
|
||||
} from 'core-app/features/work-packages/components/wp-buttons/zen-mode-toggle-button/zen-mode-toggle-button.component';
|
||||
@@ -424,7 +423,6 @@ export class OpenProjectModule implements DoBootstrap {
|
||||
registerCustomElement('opce-toasts-container', ToastsContainerComponent, { injector });
|
||||
registerCustomElement('opce-global-search-work-packages', GlobalSearchWorkPackagesComponent, { injector });
|
||||
registerCustomElement('opce-custom-date-action-admin', CustomDateActionAdminComponent, { injector });
|
||||
registerCustomElement('opce-homescreen-new-features-block', HomescreenNewFeaturesBlockComponent, { injector });
|
||||
registerCustomElement('opce-zen-mode-toggle-button', ZenModeButtonComponent, { injector });
|
||||
registerCustomElement('opce-colors-autocompleter', ColorsAutocompleterComponent, { injector });
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
@import "helpers"
|
||||
|
||||
.op-new-features
|
||||
&--teaser-image
|
||||
background-image: var(--new-feature-teaser-image)
|
||||
min-width: 170px
|
||||
background-size: contain
|
||||
background-repeat: no-repeat
|
||||
background-position-x: right
|
||||
|
||||
@media (max-width: $breakpoint-md)
|
||||
.widget-box--description
|
||||
grid-template-columns: 1fr !important
|
||||
|
||||
.op-new-features--teaser-image
|
||||
order: -1
|
||||
justify-self: center
|
||||
@@ -1,83 +0,0 @@
|
||||
//-- 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.
|
||||
//++
|
||||
|
||||
import { DebugElement } from '@angular/core';
|
||||
|
||||
import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { I18nService } from 'core-app/core/i18n/i18n.service';
|
||||
import { HomescreenNewFeaturesBlockComponent } from './new-features.component';
|
||||
|
||||
describe('shows edition-specific content', () => {
|
||||
let app:HomescreenNewFeaturesBlockComponent;
|
||||
let fixture:ComponentFixture<HomescreenNewFeaturesBlockComponent>;
|
||||
let element:DebugElement;
|
||||
|
||||
beforeEach(() => {
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
HomescreenNewFeaturesBlockComponent,
|
||||
],
|
||||
providers: [I18nService],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(HomescreenNewFeaturesBlockComponent);
|
||||
app = fixture.debugElement.componentInstance;
|
||||
element = fixture.debugElement.query(By.css('div.widget-box--description p'));
|
||||
});
|
||||
|
||||
it('should render bim text for bim edition', fakeAsync(() => {
|
||||
app.hasBimChanges = true;
|
||||
app.isStandardEdition = false;
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
// checking for missing translation key as translations are not loaded in specs
|
||||
expect(element.nativeElement.textContent).toContain('.bim.new_features_html');
|
||||
}));
|
||||
|
||||
it('should render standard text for bim edition if disabled', fakeAsync(() => {
|
||||
app.hasBimChanges = false;
|
||||
app.isStandardEdition = false;
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
// checking for missing translation key as translations are not loaded in specs
|
||||
expect(element.nativeElement.textContent).toContain('.standard.new_features_html');
|
||||
}));
|
||||
|
||||
it('should render standard text for standard edition', fakeAsync(() => {
|
||||
app.isStandardEdition = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
// checking for missing translation key as translations are not loaded in specs
|
||||
expect(element.nativeElement.textContent).toContain('.standard.new_features_html');
|
||||
}));
|
||||
});
|
||||
@@ -1,118 +0,0 @@
|
||||
//-- 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.
|
||||
//++
|
||||
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { BcfRestApi } from 'core-app/features/bim/bcf/bcf-constants.const';
|
||||
import { I18nService } from 'core-app/core/i18n/i18n.service';
|
||||
import { imagePath } from 'core-app/shared/helpers/images/path-helper';
|
||||
|
||||
// The key used in the I18n files to distinguish between versions.
|
||||
const OpVersionI18n = '16_3';
|
||||
// The key used to identify the svg representing the central feature in the version.
|
||||
// This might be different to OpVersionI18n for a while since the teaser text is often ready
|
||||
// before the image is.
|
||||
const OpVersionImage = '16_3';
|
||||
|
||||
const OpReleaseURL = 'https://www.openproject.org/docs/release-notes';
|
||||
|
||||
/** Update the teaser image to the next version */
|
||||
const featureTeaserImage = `${OpVersionImage}_features.svg`;
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
<div class="op-new-features">
|
||||
<p class="widget-box--additional-info">
|
||||
{{ text.descriptionNewFeatures }}
|
||||
</p>
|
||||
<div class="widget-box--description">
|
||||
<p [innerHtml]="currentNewFeatureHtml"></p>
|
||||
<img
|
||||
class="widget-box--teaser-image op-new-features--teaser-image"
|
||||
role="presentation"
|
||||
[src]="new_features_image"/>
|
||||
</div>
|
||||
|
||||
<a [href]="teaserWebsiteUrl" target="_blank">{{ text.learnAbout }}</a>
|
||||
</div>
|
||||
`,
|
||||
selector: 'opce-homescreen-new-features-block',
|
||||
styleUrls: ['./new-features.component.sass'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: false,
|
||||
})
|
||||
|
||||
/**
|
||||
* Component for the homescreen block to promote new features.
|
||||
* When updating this for the next release, be sure to cleanup stuff is not needed any more:
|
||||
* Locals (js-en.yml), Styles (new-features.component.sass), HTML (above), TS (below)
|
||||
*/
|
||||
export class HomescreenNewFeaturesBlockComponent {
|
||||
readonly i18n = inject(I18nService);
|
||||
readonly domSanitizer = inject(DomSanitizer);
|
||||
public isStandardEdition:boolean;
|
||||
|
||||
/** Set to true if BIM has its own changes */
|
||||
hasBimChanges = false;
|
||||
|
||||
/** Update the feature image appropriately */
|
||||
new_features_image = imagePath(featureTeaserImage);
|
||||
|
||||
public text = {
|
||||
newFeatures: this.i18n.t('js.label_new_features'),
|
||||
descriptionNewFeatures: this.i18n.t('js.homescreen.blocks.new_features.text_new_features'),
|
||||
learnAbout: this.i18n.t('js.homescreen.blocks.new_features.learn_about'),
|
||||
};
|
||||
|
||||
constructor() {
|
||||
this.isStandardEdition = window.OpenProject.isStandardEdition;
|
||||
}
|
||||
|
||||
public get teaserWebsiteUrl() {
|
||||
return this.domSanitizer.bypassSecurityTrustResourceUrl(OpReleaseURL);
|
||||
}
|
||||
|
||||
public get currentNewFeatureHtml():string {
|
||||
return this.translated('new_features_html');
|
||||
}
|
||||
|
||||
private get translatedEdition():string {
|
||||
if (this.hasBimChanges && !this.isStandardEdition) {
|
||||
return 'bim';
|
||||
}
|
||||
|
||||
return 'standard';
|
||||
}
|
||||
|
||||
private translated(key:string):string {
|
||||
return this.i18n.t(
|
||||
`js.homescreen.blocks.new_features.${OpVersionI18n}.${this.translatedEdition}.${key}`,
|
||||
{ list_styling_class: 'widget-box--arrow-links', bcf_api_link: BcfRestApi },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,6 @@ import {
|
||||
import { OPContextMenuComponent } from 'core-app/shared/components/op-context-menu/op-context-menu.component';
|
||||
import { OpenprojectPrincipalRenderingModule } from 'core-app/shared/components/principal/principal-rendering.module';
|
||||
import { FocusModule } from 'core-app/shared/directives/focus/focus.module';
|
||||
import { HomescreenNewFeaturesBlockComponent } from 'core-app/features/homescreen/blocks/new-features.component';
|
||||
import { TablePaginationComponent } from 'core-app/shared/components/table-pagination/table-pagination.component';
|
||||
import { StaticQueriesService } from 'core-app/shared/components/op-view-select/op-static-queries.service';
|
||||
import { CopyToClipboardService } from './components/copy-to-clipboard/copy-to-clipboard.service';
|
||||
@@ -209,8 +208,6 @@ export function bootstrapModule(injector:Injector):void {
|
||||
PersistentToggleComponent,
|
||||
RemoteFieldUpdaterComponent,
|
||||
|
||||
HomescreenNewFeaturesBlockComponent,
|
||||
|
||||
OpOptionListComponent,
|
||||
OpProjectIncludeComponent,
|
||||
OpProjectIncludeListComponent,
|
||||
|
||||
@@ -61,6 +61,10 @@ module OpenProject
|
||||
help: {
|
||||
href: help_link,
|
||||
label: "top_menu.help_and_support"
|
||||
},
|
||||
current_release_notes: {
|
||||
href: current_release_notes_link,
|
||||
label: :label_release_notes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +78,11 @@ module OpenProject
|
||||
dynamic
|
||||
end
|
||||
|
||||
def current_release_notes_link
|
||||
version = OpenProject::VERSION.to_semver(separator: "-", include_special: false)
|
||||
"https://www.openproject.org/docs/release-notes/#{version}"
|
||||
end
|
||||
|
||||
def static_links
|
||||
@static_links ||= begin
|
||||
yaml = Rails.root.join("config/static_links.yml").read
|
||||
|
||||
@@ -97,8 +97,14 @@ module OpenProject
|
||||
|
||||
def to_s; STRING end
|
||||
|
||||
def to_semver
|
||||
[MAJOR, MINOR, PATCH].join(".") + special
|
||||
def to_semver(separator: ".", include_special: true)
|
||||
base = [MAJOR, MINOR, PATCH].join(separator)
|
||||
|
||||
if include_special
|
||||
base + special
|
||||
else
|
||||
base
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
Reference in New Issue
Block a user