...
 
Commits (17)
......@@ -7,9 +7,14 @@ cache:
before_script:
- pip install tox
test:
test_py36:
script: tox
test_py37:
image: python:3.7
script: tox -c tox.py37.ini
allow_failure: true
test_coverage:
script:
- pip install -e . -r requirements.txt
......
## 6.2
- Added Python 3.7 support
## 6.1
- Added Django 2.1 support. 2.0 and 1.11 are still supported.
- Upgrade frontend to Angular 6
- Fixed django admin report edit page missing assets
## 6.0
- Added django 2.0 support. Droped support for Django 1.8 and 1.10 as Django no longer supports them
......
FROM python:3.6
FROM python:3.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
......
......@@ -8,17 +8,18 @@ Targets sys admins and capable end users who might not be able to program or gai
# News
## 6.0
## 6.2 (work in progress)
- Added django 2.0 support. Droped support for Django 1.8 and 1.10 as Django no longer supports them
- Bug fixes
- Added Python 3.7 support.
## 6.1
## 5.0
- Added Django 2.1 support. 2.0 and 1.11 are still supported.
* Complete rewrite of the frontend in Angular CLI
* Removed the left sidebar, added a 'home' page
* Other minor improvements and fixes
* For anyone who has written a custom frontend: we made a few changes to the django template that you might need to look at. The API has remained the same - one additional route was added that returns information as JSON that was previously serialized in the django template.
## 6.0
- Added django 2.0 support. Dropped support for Django 1.8 and 1.10 as Django no longer supports them
- Bug fixes
# What is Django Report Builder?
......@@ -42,4 +43,4 @@ http://django-report-builder.readthedocs.org/
[Google group](https://groups.google.com/forum/#!forum/django-report-builder/).
[Hacking](http://django-report-builder.readthedocs.org/en/latest/hacking/)
[Contributing](http://django-report-builder.readthedocs.org/en/latest/contributors/)
......@@ -39,15 +39,18 @@ To run the angular tests simply cd into the js directory and run `yarn test`.
Python code should follow pep8 standards. JS code uses [prettier](https://prettier.io/) for code formatting - we suggest installing [a plugin](https://prettier.io/docs/en/editors.html) to integrate it with your favorite editor.
## Making pull requests
## Opening issues
After you have a pull request that passes on Travis, and you have added
any needed test cases, please [squash your commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html).
If it makes more sense to break it up into smaller commits, you can do that
as well. Just try to think what would be most helpful, when someone looks
back in the git history to see why this file was changed.
Please only open issues on Gitlab. Note this project is mostly in maintenance mode. It's fine to open wish list requests but the [Google Group](https://groups.google.com/forum/#!forum/django-report-builder) may be a better place.
Thanks :)
If you want to make a major change and can put the time in to see it through, please open an issue to discuss first. If you are adding features that expand the scope of the project you should be prepared to help maintain them. There are many features I would LOVE to have but cannot commit the time to maintain myself.
## Making merge requests
1. Please make merge requests on https://gitlab.com/burke-software/django-report-builder. Do not use the github mirror.
2. Ensure tox passes first (See running tests section above).
3. Add a good description of what problem you are trying to solve and how you are trying to solve it.
4. Include unit tests whenever possible that would fail before your change and pass with your change.
# Frontend
......@@ -56,4 +59,4 @@ The frontend is a angular app. We use ngrx (redux) for state management and angu
# How to publish
1. `./build_js.sh` will compile the webpack bundle and move it to the django static folder
2. `python3 setup.py sdist bdist_wheel upload`
\ No newline at end of file
2. `python3 setup.py sdist bdist_wheel upload`
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
"name": "django-report-builder"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": [
"assets"
],
"index": "index.html",
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
"tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
"prefix": "app",
"styles": [
"styles.scss"
],
"scripts": [],
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
"e2e": {
"protractor": {
"config": "./protractor.conf.js"
}
},
"lint": [
{
"project": "src/tsconfig.app.json",
"exclude": "**/node_modules/**"
},
{
"project": "src/tsconfig.spec.json",
"exclude": "**/node_modules/**"
},
{
"project": "e2e/tsconfig.e2e.json",
"exclude": "**/node_modules/**"
}
],
"test": {
"karma": {
"config": "./karma.conf.js"
}
},
"defaults": {
"styleExt": "scss",
"component": {
}
}
}
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"django-report-builder": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"tsConfig": "src/tsconfig.app.json",
"polyfills": "src/polyfills.ts",
"assets": [
"src/assets"
],
"styles": [
"src/styles.scss"
],
"scripts": []
},
"configurations": {
"production": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "django-report-builder:build"
},
"configurations": {
"production": {
"browserTarget": "django-report-builder:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "django-report-builder:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "src/test.ts",
"karmaConfig": "./karma.conf.js",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.spec.json",
"scripts": [],
"styles": [
"src/styles.scss"
],
"assets": [
"src/assets"
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
},
"django-report-builder-e2e": {
"root": "",
"sourceRoot": "",
"projectType": "application",
"architect": {
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "./protractor.conf.js",
"devServerTarget": "django-report-builder:serve"
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"e2e/tsconfig.e2e.json"
],
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "django-report-builder",
"schematics": {
"@schematics/angular:component": {
"prefix": "app",
"styleext": "scss"
},
"@schematics/angular:directive": {
"prefix": "app"
}
}
}
\ No newline at end of file
......@@ -4,19 +4,19 @@
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '@angular/cli'],
frameworks: ['jasmine', '@angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('@angular/cli/plugins/karma')
require('@angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
......
{
"name": "django-report-builder",
"version": "0.0.0",
"license": "MIT",
"license": "BSD",
"scripts": {
"ng": "ng",
"start": "ng serve --base-href '/report_builder/' --proxy-config proxy.conf.json --host 0.0.0.0",
......@@ -14,42 +14,42 @@
},
"private": true,
"dependencies": {
"@angular-devkit/core": "^0.0.26",
"@angular/animations": "^5.0.1",
"@angular/cdk": "^5.0.1",
"@angular/common": "^5.0.1",
"@angular/compiler": "^5.0.1",
"@angular/core": "^5.0.1",
"@angular/forms": "^5.0.1",
"@angular/http": "^5.0.1",
"@angular/material": "^5.0.1",
"@angular/material-moment-adapter": "^5.1.1",
"@angular/platform-browser": "^5.0.1",
"@angular/platform-browser-dynamic": "^5.0.1",
"@angular/router": "^5.0.1",
"@ngrx/effects": "^5.0.0",
"@ngrx/entity": "^5.0.0",
"@ngrx/router-store": "^5.0.1",
"@ngrx/store": "^5.0.0",
"@ngrx/store-devtools": "^5.0.0",
"angular-tree-component": "^7.0.1",
"@angular-devkit/core": "^0.6.5",
"@angular/animations": "^6.0.3",
"@angular/cdk": "^6.0.3",
"@angular/common": "^6.0.3",
"@angular/compiler": "^6.0.3",
"@angular/core": "^6.0.3",
"@angular/forms": "^6.0.3",
"@angular/http": "^6.0.3",
"@angular/material": "^6.0.3",
"@angular/material-moment-adapter": "^6.1.0",
"@angular/platform-browser": "^6.0.3",
"@angular/platform-browser-dynamic": "^6.0.3",
"@angular/router": "^6.0.3",
"@ngrx/effects": "^6.0.1",
"@ngrx/entity": "^6.0.1",
"@ngrx/router-store": "^6.0.1",
"@ngrx/store": "^6.0.1",
"@ngrx/store-devtools": "^6.0.1",
"angular-tree-component": "^7.2.0",
"core-js": "^2.5.1",
"jasmine-marbles": "^0.2.0",
"jasmine-marbles": "^0.3.1",
"moment": "^2.20.1",
"ng4-click-outside": "^1.0.1",
"ngrx-store-freeze": "^0.2.0",
"node-sass": "^4.7.2",
"rxjs": "^5.5.2",
"zone.js": "^0.8.18"
"rxjs": "^6.2.0",
"rxjs-compat": "^6.2.0",
"zone.js": "^0.8.26"
},
"devDependencies": {
"@angular/cli": "~1.6.1",
"@angular/compiler-cli": "^5.0.1",
"@angular/language-service": "^5.0.1",
"@angular/cli": "~6.0.5",
"@angular/compiler-cli": "^6.0.3",
"@angular/language-service": "^6.0.3",
"@types/jasmine": "~2.8.6",
"@types/jasminewd2": "~2.0.3",
"@types/node": "~8.0.51",
"codelyzer": "~4.1.0",
"codelyzer": "~4.3.0",
"jasmine-core": "~2.9.1",
"jasmine-spec-reporter": "~4.2.0",
"karma": "~1.7.1",
......@@ -58,12 +58,13 @@
"karma-coverage-istanbul-reporter": "^1.4.0",
"karma-jasmine": "~1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"node-sass": "^4.6.0",
"prettier": "^1.10.2",
"node-sass": "^4.9.0",
"prettier": "^1.13.2",
"protractor": "~5.3.0",
"ts-node": "~3.3.0",
"tslint": "~5.9.1",
"tslint-config-prettier": "^1.6.0",
"typescript": ">=2.4.2 <2.6"
"ts-node": "~6.0.3",
"tslint": "~5.10.0",
"tslint-config-prettier": "^1.13.0",
"typescript": "~2.7.0",
"@angular-devkit/build-angular": "~0.6.5"
}
}
}
\ No newline at end of file
......@@ -39,7 +39,7 @@ export class NetworkErrorInterceptor implements HttpInterceptor {
// 3. Server side 500 error
this.store.dispatch(new CancelGeneratePreview());
this.snackBar.open('Sorry, something went wrong!', '', {duration: 5000});
return Observable.empty<HttpEvent<any>>();
return Observable.empty();
}
return _throw(err.error);
});
......
......@@ -12,7 +12,7 @@ import {
INewReport,
} from './models/api';
const apiUrl = '/report_builder/api/';
const apiUrl = 'api/';
describe('Api service should', function() {
let service: ApiService;
......
......@@ -215,7 +215,7 @@ describe('Report Effects', () => {
const expected = hot('c', {
c: new Actions.DownloadExportedReport(
`/report_builder/report/${reportId}/download_file/${type}/`
`api/report/${reportId}/download_file/${type}/`
),
});
expect(effects.exportReport$).toBeObservable(expected);
......
......@@ -11,7 +11,8 @@
]
},
"files": [
"test.ts"
"test.ts",
"polyfills.ts"
],
"include": [
"**/*.spec.ts",
......
......@@ -13,8 +13,7 @@
"curly": true,
"forin": true,
"import-blacklist": [
true,
"rxjs"
true
],
"interface-over-type-literal": true,
"label-position": true,
......@@ -67,7 +66,6 @@
true,
"allow-null-check"
],
"typeof-compare": true,
"unified-signatures": true,
"variable-name": false,
"directive-selector": [
......@@ -90,10 +88,7 @@
"use-life-cycle-interface": true,
"use-pipe-transform-interface": true,
"component-class-suffix": true,
"directive-class-suffix": true,
"no-access-missing-member": true,
"templates-use-public": true,
"invoke-injectable": true
"directive-class-suffix": true
},
"extends": ["tslint-config-prettier"]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,7 +7,7 @@ from django.conf import settings
from rest_framework import viewsets, status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.decorators import detail_route
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAdminUser
from ..models import Report, Format, FilterField
......@@ -77,7 +77,7 @@ class ReportNestedViewSet(ReportBuilderViewMixin, viewsets.ModelViewSet):
def perform_update(self, serializer):
serializer.save(user_modified=self.request.user)
@detail_route(methods=['post'])
@action(methods=['post'], detail=True)
def copy_report(self, request, pk=None):
report = self.get_object()
new_report = duplicate(report, changes=(
......
......@@ -385,9 +385,8 @@ class Report(models.Model):
return objects
@models.permalink
def get_absolute_url(self):
return ("report_update_view", [str(self.id)])
return reverse("report_update_view", args=(self.id,))
def edit(self):
return mark_safe(
......@@ -458,7 +457,7 @@ class Report(models.Model):
if user.email:
self.email_report(user=user)
def run_report(self, file_type, user=None, queryset=None, async=False, scheduled=False, email_to:str = None):
def run_report(self, file_type, user=None, queryset=None, asynchronous=False, scheduled=False, email_to:str = None):
"""Generate this report file"""
if not queryset:
queryset = self.get_query()
......@@ -476,7 +475,7 @@ class Report(models.Model):
widths.append(field.width)
if scheduled:
self.async_report_save(objects_list, title, header, widths, file_type, email_to=email_to)
elif async:
elif asynchronous:
if user is None:
raise Exception('Cannot run async report without a user')
self.async_report_save(objects_list, title, header, widths, user, file_type)
......
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M19 13h-6v6h-2v-6h-6v-2h6v-6h2v6h6v2z"/>
<path d="M0 0h24v24h-24z" fill="none"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="65.162px" height="65.236px" viewBox="-0.25 -0.25 65.162 65.236" enable-background="new -0.25 -0.25 65.162 65.236"
xml:space="preserve">
<g>
<path fill="#FFFFFF" stroke="#646464" stroke-miterlimit="10" d="M40.528,48.987c0,1.101-0.899,2-2,2H2.75c-1.1,0-2-0.899-2-2V2.75
c0-1.101,0.9-2,2-2h35.778c1.101,0,2,0.899,2,2V48.987z"/>
<path fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" d="M40.528,48.987c0,1.101-0.899,2-2,2H2.75
c-1.1,0-2-0.899-2-2V2.75c0-1.101,0.9-2,2-2h35.778c1.101,0,2,0.899,2,2V48.987z"/>
</g>
<g>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="8.889" x2="35.554" y2="8.889"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="15.908" x2="35.554" y2="15.908"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="22.928" x2="35.554" y2="22.928"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="29.947" x2="35.554" y2="29.947"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="36.967" x2="35.554" y2="36.967"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="7.487" y1="43.986" x2="35.554" y2="43.986"/>
</g>
<g>
<path fill="#FFFFFF" stroke="#646464" stroke-miterlimit="10" d="M63.912,61.987c0,1.101-0.899,2-2,2H26.133c-1.1,0-2-0.899-2-2
V15.75c0-1.101,0.9-2,2-2h35.779c1.101,0,2,0.899,2,2V61.987z"/>
<path fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" d="M63.912,61.987c0,1.101-0.899,2-2,2H26.133
c-1.1,0-2-0.899-2-2V15.75c0-1.101,0.9-2,2-2h35.779c1.101,0,2,0.899,2,2V61.987z"/>
</g>
<g>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="20.681" x2="57.741" y2="20.681"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="27.701" x2="57.741" y2="27.701"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="34.72" x2="57.741" y2="34.72"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="41.74" x2="57.741" y2="41.74"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="48.76" x2="57.741" y2="48.76"/>
<line fill="none" stroke="#646464" stroke-width="2" stroke-miterlimit="10" x1="29.672" y1="55.78" x2="57.741" y2="55.78"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2v-12h-12v12zm13-15h-3.5l-1-1h-5l-1 1h-3.5v2h14v-2z"/>
<path d="M0 0h24v24h-24z" fill="none"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="62.145px" height="61.757px" viewBox="0 0 62.145 61.757" enable-background="new 0 0 62.145 61.757" xml:space="preserve">
<g>
<path fill-rule="evenodd" clip-rule="evenodd" fill="#646565" d="M17.901,0c-1.1,0-2,0.9-2,2v27.289c0,1.1-0.9,2-2,2L1.026,31.29
c-1.1,0-1.355,0.628-0.568,1.396l29.238,28.496c0.788,0.768,2.072,0.763,2.854-0.012l29.086-28.794
c0.781-0.774,0.521-1.407-0.579-1.406l-13.405,0.005c-1.1,0-2-0.899-2-1.999V2c0-1.1-0.9-2-2-2H17.901z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="64.665px" height="52.826px" viewBox="0 0 64.665 52.826" enable-background="new 0 0 64.665 52.826" xml:space="preserve">
<g>
<g>
<path fill="#646464" stroke="#646565" stroke-miterlimit="10" d="M56.12,14.545l0.062,0.18c-0.481,0.519-1.071,0.93-1.681,1.32
l-0.061-0.18l-0.18,0.06c-2.985-1.616-5.049-4.159-6.602-7.56c-0.008-0.018-0.189,0.153-0.238,0.12l-0.062-0.18
c0,0,0.94-1.18,1.62-1.5l0.061,0.3l0.301-0.06c1.31,3.41,3.486,5.953,6.84,7.32L56.12,14.545z"/>
<path fill="#646464" stroke="#646565" stroke-miterlimit="10" d="M5.08,50.785c0,0-3.074,1.14-4.58,1.434
c0-0.12,2.163-3.235,2.163-3.235l1.546-1.287c0.248,0.871,1.287,1.799,1.956,2.25L5.08,50.785z"/>
<g>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M49.04,7.105
c0.482-0.814,1.326-1.404,2.131-1.83"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M51.17,5.275
c1.899-1.666,3.721-3.946,6.27-4.65"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M57.44,0.625c0.721,0,1.439,0,2.16,0"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M59.6,0.625
c2.059,0.517,3.757,2.213,4.439,4.2"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M57.95,13.015
c-0.394,0.67-1.172,1.141-1.83,1.53"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M13.28,48.024
c-2.848,1.156-5.699,1.973-8.64,2.761"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M2.92,48.865
c1.574-2.587,3.215-5.185,5.17-7.47"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M8.09,41.396
C20.428,30.408,33.422,20.002,46.25,9.355"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M46.25,9.355
c0.229-0.495,0.715-0.725,1.109-1.05"/>
<path fill="#FFFFFF" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M51.17,5.275
c0.279,3.676,3.604,6.306,6.779,7.74"/>
<path fill="#FFFFFF" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M57.95,13.015
c2.166-1.79,5.691-3.104,6.09-6.27"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M64.04,6.745c0-0.64,0-1.28,0-1.92"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M46.25,9.355
c0.231,1.104,0.748,2.059,1.17,3.09"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M47.42,12.445
c0.752,0.872,1.562,1.754,2.25,2.67"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M49.67,15.115
c1.088,0.641,2.179,1.299,3.281,1.902"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M52.952,17.017
c0.613-0.196,1.098-0.66,1.488-1.152"/>
<path fill="#FFFFFF" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M8.09,41.396
c0.261,0.391-0.132,1,0.278,1.312c0.623,0.181,1.269,0.167,1.912,0.157"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M10.28,42.865
C22.714,32.8,35.045,22.535,47.42,12.445"/>
<path fill="#FFFFFF" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M10.28,42.865
c-0.222,1.651,0.547,2.594,2.25,2.43"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M12.53,45.294
c12.296-10.077,24.816-20.196,37.141-30.18"/>
<path fill="#FFFFFF" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M12.53,45.294
c0.284,0.689-0.16,1.402-0.027,2.105c0.039,0.058,0.092,0.115,0.135,0.17c0.26,0.084,0.489,0.209,0.642,0.455"/>
<path fill="#646464" stroke="#646565" stroke-width="1.25" stroke-linecap="round" d="M13.28,48.024
c1.494-0.068,2.453-1.252,3.438-2.063c8.066-6.659,18.174-14.507,27.001-21.481c3.085-2.438,6.787-5.235,9.232-7.462"/>
</g>
</g>
</g>
<path fill="#464547" stroke="#646565" stroke-miterlimit="10" d="M92.081,70.151"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M3 13h2v-2h-2v2zm0 4h2v-2h-2v2zm0-8h2v-2h-2v2zm4 4h14v-2h-14v2zm0 4h14v-2h-14v2zm0-10v2h14v-2h-14z"/>
<path d="M0 0h24v24h-24z" fill="none"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="24px" height="24px" viewBox="0 0 24 24" enable-background="new 0 0 24 24" xml:space="preserve">
<g id="XMLID_11_">
<rect fill="none" width="24" height="24"/>
<path d="M3,15h18v-2H3V15z M3,19h18v-2H3V19z M3,11h18V9H3V11z M3,5v2h18V5H3z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="61.921px" height="60.572px" viewBox="0 0 61.921 60.572" enable-background="new 0 0 61.921 60.572" xml:space="preserve">
<g>
<g>
<g>
<g>
<path fill="#EFC820" d="M39.274,18.173c0.45,1.004,1.704,1.982,2.787,2.175l18.877,3.353c1.083,0.192,1.305,0.957,0.493,1.7
L47.928,37.755c-0.812,0.742-1.252,2.222-0.979,3.287l4.689,18.275c0.273,1.065-0.313,1.547-1.305,1.07l-17.895-8.615
c-0.991-0.477-2.605-0.463-3.588,0.032l-16.988,8.551c-0.983,0.495-1.575,0.024-1.315-1.044l4.43-18.279
c0.259-1.068-0.193-2.551-1.005-3.292L0.487,25.419c-0.812-0.742-0.586-1.479,0.502-1.637l18.082-2.627
c1.088-0.158,2.339-1.112,2.78-2.12l7.991-18.277c0.441-1.008,1.169-1.011,1.62-0.007L39.274,18.173z"/>
</g>
</g>
</g>
</g>
</svg>
// place this in your static files folder, in:
// <static>/report_builder/js/report_form.js
// initialize path prefix.
path_prefix = ""
// get current path
current_path = window.location.pathname;
// where is "/report_builder"?
root_index = current_path.indexOf( "/report_builder" );
// other than 0?
if ( root_index > 0 )
{
// yes. Get all text from start to that location, store it as path_prefix.
path_prefix = current_path.substring( 0, root_index );
}
else
{
// no - set path_prefix to "".
path_prefix = "";
}
var check_report = false;
function check_if_report_done(report_id, task_id) {
if (check_report != false ){
$.get( "/report_builder/report/"+ report_id + "/check_status/" + task_id + "/", function( data ) {
console.log(data);
if (data.state == "SUCCESS") {
window.location.href = data.link;
clearInterval(check_report);
check_report = false;
}
})
}
}
function get_async_report(report_id) {
$.get( "/report_builder/report/"+ report_id + "/download_file/xlsx/", function( data ) {
var task_id = data.task_id;
status = "loading"
check_report = setInterval( function(){ check_if_report_done(report_id, task_id); }, 2000 );
});
}
$ = django.jQuery;
// place this in your static files folder, in:
// <static>/report_builder/js/report_form.js
// initialize path prefix.
path_prefix = ""
// get current path
current_path = window.location.pathname;
// where is "/report_builder"?
root_index = current_path.indexOf( "/report_builder" );
// other than 0?
if ( root_index > 0 )
{
// yes. Get all text from start to that location, store it as path_prefix.
path_prefix = current_path.substring( 0, root_index );
}
else
{
// no - set path_prefix to "".
path_prefix = "";
}
/* Taken from https://docs.djangoproject.com/en/dev/ref/contrib/csrf/ */
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = $.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function ajax_add_star(event, url) {
// Setup CSRF Token
var csrftoken = getCookie('csrftoken');
$.ajaxSetup({
crossDomain: false, // obviates need for sameOrigin test
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$.post(
url,
{},
function(data){
if (data == 'True' ) {
$(event).html('<img style="width: 26px; margin: -6px;" src="/static/report_builder/img/star.png">');
} else {
$(event).html('<img style="width: 26px; margin: -6px;" src="/static/report_builder/img/unstar.png">');
}
}
);}
......@@ -66,7 +66,7 @@ class DownloadFileView(DataExportMixin, View):
if to_response:
return report.run_report(file_type, user, queryset)
else:
report.run_report(file_type, user, queryset, async=True)
report.run_report(file_type, user, queryset, asynchronous=True)
def get(self, request, *args, **kwargs):
report_id = kwargs['pk']
......
# Need this to avoid conflict with Travis CI
Django==1.11.7
Django==2.1
......@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="django-report-builder",
version="6.0.2",
version="6.2.1",
author="David Burke",
author_email="david@burkesoftware.com",
description=("Query and Report builder for Django ORM"),
......
[tox]
toxworkdir={env:TOX_WORK_DIR:.tox}
envlist = py{36}-django{111,20}
envlist = py{36}-django{111,20,21}
[testenv]
passenv = *
......@@ -8,6 +8,7 @@ install_command = pip install {opts} {packages}
deps =
django111: django>=1.11,<1.12
django20: django>=2.0,<2.1
django21: django>=2.1,<2.2
-r{toxinidir}/requirements.txt
commands =
{envpython} {toxinidir}/manage.py test --noinput
[tox]
toxworkdir={env:TOX_WORK_DIR:.tox}
envlist = py{37}-django{21}
[testenv]
passenv = *
install_command = pip install {opts} {packages}
deps =
django21: django>=2.1,<2.2
-r{toxinidir}/requirements.txt
commands =
{envpython} {toxinidir}/manage.py test --noinput