parent
5167f4fca8
commit
8e32895ce3
@ -1,4 +1,3 @@ |
|||||||
web: bundle exec rails server -p 3000 -b ${HOST:="127.0.0.1"} --environment ${RAILS_ENV:="development"} |
web: bundle exec rails server -p 3000 -b ${HOST:="127.0.0.1"} --environment ${RAILS_ENV:="development"} |
||||||
legacy: cd frontend && RAILS_ENV=${RAILS_ENV:="development"} npm run legacy-webpack-watch |
|
||||||
angular: npm run serve |
angular: npm run serve |
||||||
worker: bundle exec rake jobs:work |
worker: bundle exec rake jobs:work |
||||||
|
@ -1,66 +0,0 @@ |
|||||||
API Handling |
|
||||||
============ |
|
||||||
|
|
||||||
In general, the OpenProject Frontend uses _all_ of the existing working APIs to provide its functionality, as the current working version for `APIv3` is not feature complete. |
|
||||||
|
|
||||||
The documentation for these APIs and their capabilities: |
|
||||||
|
|
||||||
- [APIv3](http://opf.github.io/apiv3-doc/) |
|
||||||
|
|
||||||
To get a feeling for which API is used at which point, please refer to the `PathHelper` located at `./frontend/app/helpers/path-helper.js`. It is used throughout the application to centralize knowledge about paths. |
|
||||||
|
|
||||||
## HAL |
|
||||||
|
|
||||||
While having a `PathHelper` certainly helps, the long-term idea is to leverage the [HAL](http://stateless.co/hal_specification.html)-capabilities of the APIv3 (thereby leaving `v2` behind) to let any client discover the paths available for a resource by inspecting the responses from any given call. |
|
||||||
|
|
||||||
__Note:__ All responses from the APIv3 are thereby of `Content-Type: application/hal+json` and not just `Content-Type: application/json`. Some developer client tools sometimes get confused with that and will not interpret the formatting correctly. |
|
||||||
|
|
||||||
Example: |
|
||||||
|
|
||||||
```json |
|
||||||
// calling a project |
|
||||||
|
|
||||||
{ |
|
||||||
"_type": "Project", |
|
||||||
"_links": { |
|
||||||
"self": { |
|
||||||
"href": "/api/v3/projects/1", |
|
||||||
"title": "Lorem" |
|
||||||
}, |
|
||||||
"createWorkPackage": { |
|
||||||
"href": "/api/v3/projects/1/work_packages/form", |
|
||||||
"method": "post" |
|
||||||
}, |
|
||||||
"createWorkPackageImmediate": { |
|
||||||
"href": "/api/v3/projects/1/work_packages", |
|
||||||
"method": "post" |
|
||||||
}, |
|
||||||
"categories": { "href": "/api/v3/projects/1/categories" }, |
|
||||||
"types": { "href": "/api/v3/projects/1/types" }, |
|
||||||
"versions": { "href": "/api/v3/projects/1/versions" } |
|
||||||
}, |
|
||||||
"id": 1, |
|
||||||
"identifier": "project_identifier", |
|
||||||
"name": "Project example", |
|
||||||
"description": "Lorem ipsum dolor sit amet" |
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
The `Project` structure contains links to ressources associated. Given the knowledge about `_links`, one may easily infer the path from the response: |
|
||||||
|
|
||||||
```javascript |
|
||||||
// some magic to retrieve an object, note that the services used are examplary |
|
||||||
// and can not be found in the actual codebase |
|
||||||
ProjectsService.getProject('project_identifier').then(function(project) { |
|
||||||
var pathToVersions = project._links.versions.href; |
|
||||||
// the VersionsService has knowledge about pathToVersions in its |
|
||||||
// forProject method |
|
||||||
VersionsService.forProject(project).then(function(versions) { |
|
||||||
// versions should be the result of the call to pathtoVersions |
|
||||||
console.log(versions); |
|
||||||
}); |
|
||||||
}); |
|
||||||
``` |
|
||||||
|
|
||||||
This is in principle a very good concept to delegate responsibility of inference to the client and absolves the client of having to know each path in the application in advance. |
|
||||||
|
|
@ -1,39 +0,0 @@ |
|||||||
# Additional information on Legacy frontend |
|
||||||
|
|
||||||
The legacy bundle is only used from Rails to add functionality to specific parts of the application. |
|
||||||
|
|
||||||
## Loading and bootstrapping the legacy AngularJS frontend |
|
||||||
|
|
||||||
To bootstrap the AngularJS frontend from Rails, use the `activate_angular_js` helper block: |
|
||||||
|
|
||||||
```html |
|
||||||
<!-- @see ./app/helpers/angular_helper.rb --> |
|
||||||
<%= activate_angular_js do %> |
|
||||||
<persistent-toggle identifier="repository.checkout_instructions"> |
|
||||||
<div> |
|
||||||
Something rendered from Rails ... |
|
||||||
</div> |
|
||||||
</persistent-toggle> |
|
||||||
<% end %> |
|
||||||
``` |
|
||||||
|
|
||||||
The legacy frontend with AngularJS can be bootstrapped _with_ content contained within. This is not possible in Angular, |
|
||||||
since the root component needs to be empty (or will be emptied during bootstrap). |
|
||||||
|
|
||||||
## Passing information and configuration from Rails to Angular |
|
||||||
|
|
||||||
There are three ways of passing information from Rails to `AngularJS`: |
|
||||||
|
|
||||||
1. Using tag attributes written directly to the DOM by the rendering process of Rails as in the example before. |
|
||||||
|
|
||||||
2. Using the `gon` gem |
|
||||||
|
|
||||||
This is included by all layouts in `<head>`: |
|
||||||
|
|
||||||
```js |
|
||||||
<%= nonced_javascript_tag do %> |
|
||||||
<%= include_gon(need_tag: false) -%> |
|
||||||
<% end %> |
|
||||||
``` |
|
||||||
|
|
||||||
`gon` will provide arbitrary settings from Rails to all JavaScript functionality, including `AngularJS`. In an `angular` context a `ConfigurationService` is provided for picking up the settings. |
|
@ -1,4 +0,0 @@ |
|||||||
# OpenProject Legacy AngularJS Frontend |
|
||||||
|
|
||||||
These directives are remains of the AngularJS frontend used solely for the purpose of |
|
||||||
retaining functionality of embedded components in Rails templates. |
|
@ -1,94 +0,0 @@ |
|||||||
//-- copyright
|
|
||||||
// OpenProject is a project management system.
|
|
||||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
|
||||||
//
|
|
||||||
// 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 doc/COPYRIGHT.rdoc for more details.
|
|
||||||
//++
|
|
||||||
|
|
||||||
|
|
||||||
import {ExpressionService} from "../../common/expression.service"; |
|
||||||
require('angular'); |
|
||||||
|
|
||||||
var angularDragula:any = require('angular-dragula'); |
|
||||||
export const opTemplatesModule = angular.module('openproject.templates', []); |
|
||||||
export const openprojectLegacyModule = angular.module('OpenProjectLegacy', [ |
|
||||||
angularDragula(angular) |
|
||||||
]); |
|
||||||
|
|
||||||
// Bootstrap app
|
|
||||||
|
|
||||||
openprojectLegacyModule |
|
||||||
.config([ |
|
||||||
'$compileProvider', |
|
||||||
'$httpProvider', |
|
||||||
function($compileProvider:any, $httpProvider:any) { |
|
||||||
|
|
||||||
// Disable debugInfo outside development mode
|
|
||||||
$compileProvider.debugInfoEnabled(window.OpenProject.environment === 'development'); |
|
||||||
|
|
||||||
$httpProvider.defaults.headers.common['X-CSRF-TOKEN'] = jQuery( |
|
||||||
'meta[name=csrf-token]').attr('content'); |
|
||||||
$httpProvider.defaults.headers.common['X-Authentication-Scheme'] = 'Session'; |
|
||||||
// Add X-Requested-With for request.xhr?
|
|
||||||
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; |
|
||||||
// prepend a given base path to requests performed via $http
|
|
||||||
//
|
|
||||||
$httpProvider.interceptors.push(function($q:ng.IQService) { |
|
||||||
return { |
|
||||||
'request': function(config:any) { |
|
||||||
// OpenProject can run in a subpath e.g. https://mydomain/open_project.
|
|
||||||
// We append the path found as the base-tag value to all http requests
|
|
||||||
// to the server except:
|
|
||||||
// * when the path is already appended
|
|
||||||
// * when we are getting a template
|
|
||||||
if (!config.url.match('(^/templates|\\.html$|^' + window.appBasePath + ')')) { |
|
||||||
config.url = window.appBasePath + (config.url as string); |
|
||||||
} |
|
||||||
|
|
||||||
return config || $q.when(config); |
|
||||||
} |
|
||||||
}; |
|
||||||
}); |
|
||||||
} |
|
||||||
]) |
|
||||||
.run([ |
|
||||||
'$rootScope', |
|
||||||
function($rootScope:any) { |
|
||||||
// Set the escaping target of opening double curly braces
|
|
||||||
// This is what returned by rails-angular-xss when it discoveres double open curly braces
|
|
||||||
// See https://github.com/opf/rails-angular-xss for more information.
|
|
||||||
$rootScope.DOUBLE_LEFT_CURLY_BRACE = ExpressionService.UNESCAPED_EXPRESSION; |
|
||||||
|
|
||||||
// Mark the bootstrap has run for testing purposes.
|
|
||||||
document.body.classList.add('__ng-bootstrap-has-run'); |
|
||||||
|
|
||||||
$rootScope.$on('$stateChangeError', |
|
||||||
function(event:JQueryEventObject){ |
|
||||||
event.preventDefault(); |
|
||||||
// transitionTo() promise will be rejected with
|
|
||||||
// a 'transition prevented' error
|
|
||||||
}); |
|
||||||
} |
|
||||||
]); |
|
||||||
|
|
@ -1,17 +0,0 @@ |
|||||||
var fs = require('fs'); |
|
||||||
var path = require('path'); |
|
||||||
var _ = require('lodash'); |
|
||||||
var autoprefixer = require('autoprefixer'); |
|
||||||
|
|
||||||
var browsersListConfig = fs.readFileSync(path.join(__dirname, '..', 'browserslist'), 'utf8'); |
|
||||||
var browsersList = _.filter(browsersListConfig.split('\n'), function (entry) { |
|
||||||
return entry && entry.charAt(0) !== '#'; |
|
||||||
}); |
|
||||||
|
|
||||||
module.exports = { |
|
||||||
plugins: [ |
|
||||||
autoprefixer({ |
|
||||||
browsers: browsersList, cascade: false |
|
||||||
}) |
|
||||||
] |
|
||||||
} |
|
@ -1,39 +0,0 @@ |
|||||||
{ |
|
||||||
"compilerOptions": { |
|
||||||
"target": "ES5", |
|
||||||
"module": "es2015", |
|
||||||
"moduleResolution": "node", |
|
||||||
"removeComments": true, |
|
||||||
"preserveConstEnums": true, |
|
||||||
"sourceMap": true, |
|
||||||
"noEmitOnError": false, |
|
||||||
"experimentalDecorators": true, |
|
||||||
"emitDecoratorMetadata": true, |
|
||||||
// Increase strictness |
|
||||||
// Enable strict once "use strict" errors can be resolved |
|
||||||
// "strict": true; |
|
||||||
"noImplicitAny": true, |
|
||||||
"noImplicitThis": true, |
|
||||||
"noImplicitReturns": true, |
|
||||||
"strictFunctionTypes": true, |
|
||||||
// Causes lots of errors in linked angularjs properties |
|
||||||
"strictPropertyInitialization": false, |
|
||||||
"noFallthroughCasesInSwitch": true, |
|
||||||
"strictNullChecks": true, |
|
||||||
"skipLibCheck": true, |
|
||||||
"preserveSymlinks": true, |
|
||||||
"baseUrl": ".", |
|
||||||
"typeRoots": [ |
|
||||||
"../node_modules/@types", |
|
||||||
"./typings/open-project-legacy.typings.d.ts" |
|
||||||
], |
|
||||||
"paths": { |
|
||||||
"core-app/*": ["./app/*"], |
|
||||||
"core-components/*": ["./app/components/*"] |
|
||||||
} |
|
||||||
}, |
|
||||||
"compileOnSave": false, |
|
||||||
"exclude": [ |
|
||||||
"node_modules" |
|
||||||
] |
|
||||||
} |
|
@ -1,58 +0,0 @@ |
|||||||
//-- copyright
|
|
||||||
// OpenProject is a project management system.
|
|
||||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
|
||||||
//
|
|
||||||
// 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 doc/COPYRIGHT.rdoc for more details.
|
|
||||||
//++
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <reference path="../../node_modules/@types/angular/index.d.ts" />
|
|
||||||
/// <reference path="../../node_modules/@types/lodash/index.d.ts" />
|
|
||||||
|
|
||||||
import * as TAngular from 'angular'; |
|
||||||
import * as TLodash from 'lodash'; |
|
||||||
import {InputState, State} from "reactivestates"; |
|
||||||
import {GlobalI18n} from "../../src/app/modules/common/i18n/i18n.service"; |
|
||||||
|
|
||||||
export interface IPluginContext { |
|
||||||
classes:any; |
|
||||||
services:any; |
|
||||||
bootstrap(element:HTMLElement):void; |
|
||||||
} |
|
||||||
|
|
||||||
declare global { |
|
||||||
interface Window { |
|
||||||
appBasePath:string; |
|
||||||
OpenProject:{ |
|
||||||
guardedLocalStorage(key:string, newValue?:string):string|void, |
|
||||||
environment:string, |
|
||||||
getPluginContext():Promise<IPluginContext>, |
|
||||||
pluginContext:InputState<IPluginContext> |
|
||||||
}; |
|
||||||
} |
|
||||||
const angular:typeof TAngular; |
|
||||||
const _:typeof TLodash; |
|
||||||
const I18n:GlobalI18n; |
|
||||||
} |
|
@ -1,227 +0,0 @@ |
|||||||
// -- copyright
|
|
||||||
// OpenProject is a project management system.
|
|
||||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
|
||||||
//
|
|
||||||
// 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 doc/COPYRIGHT.rdoc for more details.
|
|
||||||
// ++
|
|
||||||
|
|
||||||
var webpack = require('webpack'); |
|
||||||
var path = require('path'); |
|
||||||
var _ = require('lodash'); |
|
||||||
//var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
||||||
|
|
||||||
var CleanWebpackPlugin = require('clean-webpack-plugin'); |
|
||||||
var MiniCssExtractPlugin = require('mini-css-extract-plugin'); |
|
||||||
var UglifyJsPlugin = require('uglifyjs-webpack-plugin'); |
|
||||||
|
|
||||||
var mode = 'production'; |
|
||||||
var production = true; |
|
||||||
if (process.env['RAILS_ENV'] == 'development') { |
|
||||||
mode = 'development'; |
|
||||||
production = false; |
|
||||||
} |
|
||||||
|
|
||||||
var debug_output = (!production || !!process.env['OP_FRONTEND_DEBUG_OUTPUT']); |
|
||||||
|
|
||||||
var node_root = path.resolve(__dirname, '..', 'node_modules'); |
|
||||||
var output_root = path.resolve(__dirname, '..', '..', 'app', 'assets', 'javascripts'); |
|
||||||
var bundle_output = path.resolve(output_root, 'bundles'); |
|
||||||
|
|
||||||
var loaders = [ |
|
||||||
{ |
|
||||||
test: /\.tsx?$/, |
|
||||||
use: [ |
|
||||||
{ |
|
||||||
loader: 'ts-loader', |
|
||||||
options: { |
|
||||||
logLevel: 'info', |
|
||||||
configFile: path.resolve(__dirname, 'tsconfig.json') |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
test: /\.css$/, |
|
||||||
use: [ |
|
||||||
MiniCssExtractPlugin.loader, |
|
||||||
'css-loader', |
|
||||||
'postcss-loader' |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
test: /\.png$/, |
|
||||||
use: [ |
|
||||||
{ |
|
||||||
loader: 'url-loader', |
|
||||||
options: { |
|
||||||
limit: '100000', |
|
||||||
mimetype: 'image/png' |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
}, |
|
||||||
{ |
|
||||||
test: /\.gif$/, |
|
||||||
use: ['file-loader'] |
|
||||||
}, |
|
||||||
{ |
|
||||||
test: /\.jpg$/, |
|
||||||
use: ['file-loader'] |
|
||||||
}, |
|
||||||
]; |
|
||||||
|
|
||||||
loaders.push({ |
|
||||||
test: /\.html$/, |
|
||||||
use: [ |
|
||||||
{ |
|
||||||
loader: 'ngtemplate-loader', |
|
||||||
options: { |
|
||||||
module: 'OpenProjectLegacy', |
|
||||||
relativeTo: path.resolve(__dirname, './app') |
|
||||||
} |
|
||||||
}, |
|
||||||
{ |
|
||||||
loader: 'html-loader', |
|
||||||
options: { |
|
||||||
minimize: false |
|
||||||
} |
|
||||||
} |
|
||||||
] |
|
||||||
}); |
|
||||||
|
|
||||||
function getLegacyWebpackConfig() { |
|
||||||
var config = { |
|
||||||
mode: mode, |
|
||||||
|
|
||||||
devtool: 'source-map', |
|
||||||
|
|
||||||
context: path.resolve(__dirname, 'app'), |
|
||||||
|
|
||||||
entry: { |
|
||||||
'legacy-app': './openproject-legacy-app' |
|
||||||
}, |
|
||||||
|
|
||||||
output: { |
|
||||||
filename: 'openproject-[name].js', |
|
||||||
path: bundle_output, |
|
||||||
publicPath: '/assets/bundles/' |
|
||||||
}, |
|
||||||
|
|
||||||
module: { |
|
||||||
rules: loaders |
|
||||||
}, |
|
||||||
|
|
||||||
resolve: { |
|
||||||
// Don't map symlinks from dynamically linked plugins to their real paths
|
|
||||||
symlinks: false, |
|
||||||
|
|
||||||
modules: [ |
|
||||||
path.resolve(__dirname, '..', 'node_modules') |
|
||||||
], |
|
||||||
|
|
||||||
extensions: ['.ts', '.tsx', '.js'], |
|
||||||
|
|
||||||
// Allow empty import without extension
|
|
||||||
// enforceExtension: true,
|
|
||||||
|
|
||||||
alias: { |
|
||||||
'angular': path.resolve(node_root, 'angular', 'angular.min.js'), |
|
||||||
'angular-dragula': path.resolve(node_root, 'angular-dragula', 'dist', 'angular-dragula.min.js'), |
|
||||||
'core-app': path.resolve(__dirname, 'app'), |
|
||||||
'core-components': path.resolve(__dirname, 'app', 'components'), |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
externals: { |
|
||||||
"I18n": "I18n", |
|
||||||
"_": "_", |
|
||||||
}, |
|
||||||
|
|
||||||
optimization: { |
|
||||||
splitChunks: { |
|
||||||
cacheGroups: { |
|
||||||
common: { |
|
||||||
name: "common", |
|
||||||
chunks: "initial", |
|
||||||
minChunks: 2 |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
plugins: [ |
|
||||||
// Define modes for debug output
|
|
||||||
new webpack.DefinePlugin({ |
|
||||||
DEBUG: !!debug_output, |
|
||||||
PRODUCTION: !!production |
|
||||||
}), |
|
||||||
|
|
||||||
// Clean the output directory
|
|
||||||
new CleanWebpackPlugin(['bundles'], { |
|
||||||
root: output_root, |
|
||||||
verbose: true, |
|
||||||
exclude: ['openproject-vendors.js'] |
|
||||||
}), |
|
||||||
|
|
||||||
// new BundleAnalyzerPlugin(),
|
|
||||||
|
|
||||||
new MiniCssExtractPlugin({ |
|
||||||
// Options similar to the same options in webpackOptions.output
|
|
||||||
// both options are optional
|
|
||||||
filename: "openproject-[name].css", |
|
||||||
chunkFilename: "[id].css" |
|
||||||
}), |
|
||||||
] |
|
||||||
}; |
|
||||||
|
|
||||||
if (production) { |
|
||||||
console.log("Applying webpack.optimize plugins for production."); |
|
||||||
// Add compression and optimization plugins
|
|
||||||
// to the webpack build.
|
|
||||||
config.plugins.push( |
|
||||||
new webpack.LoaderOptionsPlugin({ |
|
||||||
// Let loaders know that we're in minification mode
|
|
||||||
minimize: true |
|
||||||
}) |
|
||||||
); |
|
||||||
|
|
||||||
config.optimization.minimizer = [ |
|
||||||
// we specify a custom UglifyJsPlugin here to get source maps in production
|
|
||||||
new UglifyJsPlugin({ |
|
||||||
cache: true, |
|
||||||
parallel: true, |
|
||||||
uglifyOptions: { |
|
||||||
compress: true, |
|
||||||
mangle: false, |
|
||||||
ecma: 5, |
|
||||||
}, |
|
||||||
sourceMap: true |
|
||||||
}) |
|
||||||
]; |
|
||||||
} |
|
||||||
|
|
||||||
return config; |
|
||||||
} |
|
||||||
|
|
||||||
module.exports = getLegacyWebpackConfig; |
|
@ -1,61 +1,56 @@ |
|||||||
// //-- copyright
|
//-- copyright
|
||||||
// // OpenProject is a project management system.
|
// OpenProject is a project management system.
|
||||||
// // Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
|
// Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
|
||||||
// //
|
|
||||||
// // 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
|
||||||
// //++
|
|
||||||
//
|
//
|
||||||
// import {HideSectionService} from "./hide-section.service";
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License version 3.
|
||||||
//
|
//
|
||||||
// export class ShowSectionDropdownComponent {
|
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||||
// public optValue:string; // value of option for which hide-section should be visible
|
// Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||||
// public hideSecWithName:string; // section-name of hide-section
|
// Copyright (C) 2010-2013 the ChiliProject Team
|
||||||
//
|
//
|
||||||
// constructor(protected HideSectionService:HideSectionService,
|
// This program is free software; you can redistribute it and/or
|
||||||
// private $element:ng.IAugmentedJQuery) {
|
// 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.
|
||||||
//
|
//
|
||||||
// $onInit() {
|
// This program is distributed in the hope that it will be useful,
|
||||||
// this.$element.change(event => {
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
// let selectedOption = jQuery("option:selected", event.target);
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
//
|
//
|
||||||
// if (selectedOption.val() !== this.optValue) {
|
// You should have received a copy of the GNU General Public License
|
||||||
// this.HideSectionService.hide(this.hideSecWithName);
|
// along with this program; if not, write to the Free Software
|
||||||
// }
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
// else {
|
|
||||||
// this.HideSectionService.show({key: this.hideSecWithName, label: ""});
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
//
|
||||||
// openprojectLegacyModule.component('showSectionDropdown', {
|
// See docs/COPYRIGHT.rdoc for more details.
|
||||||
// template: '<ng-transclude></ng-transclude>',
|
//++
|
||||||
// transclude: true,
|
|
||||||
// controller: ShowSectionDropdownComponent,
|
import {HideSectionService} from "./hide-section.service"; |
||||||
// bindings: {
|
import {Component, ElementRef, OnInit} from "@angular/core"; |
||||||
// optValue: "@",
|
|
||||||
// hideSecWithName: "@"
|
@Component({ |
||||||
// }
|
selector: 'show-section-dropdown', |
||||||
// });
|
template: '' |
||||||
|
}) |
||||||
|
export class ShowSectionDropdownComponent implements OnInit { |
||||||
|
public optValue:string; // value of option for which hide-section should be visible
|
||||||
|
public hideSecWithName:string; // section-name of hide-section
|
||||||
|
|
||||||
|
constructor(private HideSectionService:HideSectionService, |
||||||
|
private elementRef:ElementRef) { |
||||||
|
} |
||||||
|
|
||||||
|
ngOnInit() { |
||||||
|
const target = jQuery(this.elementRef.nativeElement).prev(); |
||||||
|
target.on('change', event => { |
||||||
|
let selectedOption = jQuery("option:selected", event.target); |
||||||
|
|
||||||
|
if (selectedOption.val() !== this.optValue) { |
||||||
|
this.HideSectionService.hide(this.hideSecWithName); |
||||||
|
} else { |
||||||
|
this.HideSectionService.show(this.hideSecWithName); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
@ -1,82 +0,0 @@ |
|||||||
// -- copyright
|
|
||||||
// OpenProject is a project management system.
|
|
||||||
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
|
||||||
//
|
|
||||||
// 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 doc/COPYRIGHT.rdoc for more details.
|
|
||||||
// ++
|
|
||||||
|
|
||||||
import {PluginContextService} from "core-app/services/plugin-context.service"; |
|
||||||
|
|
||||||
/*eslint no-eval: "error"*/ |
|
||||||
export class CostBudgetSubformController { |
|
||||||
|
|
||||||
// Container for rows
|
|
||||||
private container: ng.IAugmentedJQuery; |
|
||||||
|
|
||||||
// Template for new rows to insert, is rendered with INDEX placeholder
|
|
||||||
private rowTemplate: string; |
|
||||||
|
|
||||||
// Current row index
|
|
||||||
public rowIndex: number; |
|
||||||
|
|
||||||
// subform item count as output by rails
|
|
||||||
public itemCount: string; |
|
||||||
|
|
||||||
// Updater URL for the rows contained here
|
|
||||||
public updateUrl: string; |
|
||||||
|
|
||||||
constructor(public $element:ng.IAugmentedJQuery, |
|
||||||
public $http:ng.IHttpService, |
|
||||||
public pluginContext:PluginContextService, |
|
||||||
private $scope:ng.IScope, |
|
||||||
private $compile:any) { |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
function costsBudgetSubform():any { |
|
||||||
return { |
|
||||||
restrict: 'E', |
|
||||||
scope: { |
|
||||||
updateUrl: '@', |
|
||||||
itemCount: '@' |
|
||||||
}, |
|
||||||
link: (scope:ng.IScope, |
|
||||||
element:ng.IAugmentedJQuery, |
|
||||||
attr:ng.IAttributes, |
|
||||||
ctrl:any) => { |
|
||||||
const template = element.find('.budget-row-template'); |
|
||||||
ctrl.rowTemplate = template[0].outerHTML; |
|
||||||
template.remove(); |
|
||||||
}, |
|
||||||
bindToController: true, |
|
||||||
controller: CostBudgetSubformController, |
|
||||||
controllerAs: '$ctrl' |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
angular.module('OpenProjectLegacy').directive('costsBudgetSubform', costsBudgetSubform); |
|
Loading…
Reference in new issue