This combination of JS things works.

This commit is contained in:
James Cole
2019-01-06 13:37:25 +01:00
parent 0d560ec442
commit 337c289a74
14 changed files with 1465 additions and 133 deletions

11
.babelrc Normal file
View File

@@ -0,0 +1,11 @@
{
"presets": [
"@babel/preset-flow",
"@babel/preset-react"
],
"plugins": [
[
"@babel/plugin-proposal-class-properties"
]
]
}

View File

@@ -31,8 +31,13 @@
"webpack": "^4.28.3"
},
"dependencies": {
"accounting": "^0.4.1",
"admin-lte": "^2.4.8",
"bootstrap-daterangepicker": "^3.0.3",
"chart.js": "^2.7.3",
"d3-scale": "^2.1.2",
"formik": "^1.4.1",
"moment": "^2.23.0",
"react-c3js": "^0.1.20",
"react-google-maps": "^9.4.5",
"react-router-dom": "^4.3.1",

View File

@@ -0,0 +1,50 @@
/*
* InfoBox.react.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
import React from 'react';
import axios from 'axios';
class InfoBox extends React.Component {
state = {
posts: []
};
componentDidMount() {
axios.get(`http://www.reddit.com/r/${this.props.subreddit}.json`)
.then(res => {
const posts = res.data.data.children.map(obj => obj.data);
this.setState({ posts });
});
}
render() {
return (
<div>
<h1>{`/r/${this.props.subreddit}`}</h1>
<ul>
{this.state.posts.map(post =>
<li key={post.id}>{post.title}</li>
)}
</ul>
</div>
);
}
}
export default InfoBox;

35
resources/js/v1/bootstrap.js vendored Normal file
View File

@@ -0,0 +1,35 @@
/*
* bootstrap.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
//window._ = require('lodash');
/**
* We'll load jQuery and the Bootstrap jQuery plugin which provides support
* for JavaScript based Bootstrap features such as modals and tabs. This
* code may be modified to fit the specific needs of your application.
*/
try {
window.$ = window.jQuery = require('jquery');
require('bootstrap/dist/js/bootstrap.bundle.js');
} catch (e) {
console.error('No bootstrap?');
}
require('admin-lte');

329
resources/js/v1/default-charts.js vendored Normal file
View File

@@ -0,0 +1,329 @@
/*
* default-charts.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['accounting', 'chart.js'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but only CommonJS-like environments that support module.exports, like Node.
module.exports = factory(require('accounting'), require('chart.js'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.accounting, root.chartjs);
}
}(typeof self !== 'undefined' ? self : this, function (accounting, chartjs) {
/** Colours to use. */
let colourSet = [
[53, 124, 165],
[0, 141, 76], // green
[219, 139, 11],
[202, 25, 90], // paars rood-ish #CA195A
[85, 82, 153],
[66, 133, 244],
[219, 68, 55], // red #DB4437
[244, 180, 0],
[15, 157, 88],
[171, 71, 188],
[0, 172, 193],
[255, 112, 67],
[158, 157, 36],
[92, 107, 192],
[240, 98, 146],
[0, 121, 107],
[194, 24, 91]
];
let fillColors = [];
let strokePointHighColors = [];
for (let i = 0; i < colourSet.length; i++) {
fillColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.5)");
strokePointHighColors.push("rgba(" + colourSet[i][0] + ", " + colourSet[i][1] + ", " + colourSet[i][2] + ", 0.9)");
}
/**
* Takes a string phrase and breaks it into separate phrases no bigger than 'maxwidth', breaks are made at complete words.
* https://stackoverflow.com/questions/21409717/chart-js-and-long-labels
*
* @param str
* @param maxwidth
* @returns {Array}
*/
function formatLabel(str, maxwidth) {
let sections = [];
str = String(str);
let words = str.split(" ");
let temp = "";
words.forEach(function (item, index) {
if (temp.length > 0) {
let concat = temp + ' ' + item;
if (concat.length > maxwidth) {
sections.push(temp);
temp = "";
} else {
if (index === (words.length - 1)) {
sections.push(concat);
return;
} else {
temp = concat;
return;
}
}
}
if (index === (words.length - 1)) {
sections.push(item);
return;
}
if (item.length < maxwidth) {
temp = item;
} else {
sections.push(item);
}
});
return sections;
}
const defaultChartOptions = {
elements: {
line: {
cubicInterpolationMode: 'monotone'
}
},
scales: {
xAxes: [
{
gridLines: {
display: false
},
ticks: {
// break ticks when too long.
callback: function (value, index, values) {
return formatLabel(value, 20);
}
}
}
],
yAxes: [{
display: true,
ticks: {
callback: function (tickValue) {
"use strict";
return accounting.formatMoney(tickValue);
},
beginAtZero: true
}
}]
},
tooltips: {
mode: 'label',
callbacks: {
label: function (tooltipItem, data) {
"use strict";
return data.datasets[tooltipItem.datasetIndex].label + ': ' +
accounting.formatMoney(tooltipItem.yLabel, data.datasets[tooltipItem.datasetIndex].currency_symbol);
}
}
}
};
const pieOptionsWithCurrency = {
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
"use strict";
var value = data.datasets[0].data[tooltipItem.index];
return data.labels[tooltipItem.index] + ': ' + accounting.formatMoney(value, data.datasets[tooltipItem.datasetIndex].currency_symbol[tooltipItem.index]);
}
}
},
maintainAspectRatio: true,
responsive: true
};
/**
*
* @param data
* @returns {{}}
*/
function colorizeData(data) {
let newData = {};
newData.datasets = [];
for (let i = 0; i < data.count; i++) {
newData.labels = data.labels;
let dataset = data.datasets[i];
dataset.fill = false;
dataset.backgroundColor = dataset.borderColor = fillColors[i];
newData.datasets.push(dataset);
}
return newData;
}
/**
* @param URI
* @param container
* @param chartType
* @param options
* @param colorData
*/
function drawAChart(URI, container, chartType, options, colorData) {
Chart.defaults.global.legend.display = false;
Chart.defaults.global.animation.duration = 0;
Chart.defaults.global.responsive = true;
Chart.defaults.global.maintainAspectRatio = false;
let containerObj = $('#' + container);
if (containerObj.length === 0) {
console.log('Return');
return;
}
$.getJSON(URI).done(function (data) {
console.log('Done loading data: ' + containerObj);
containerObj.removeClass('general-chart-error');
if (data.labels.length === 0) {
// remove the chart container + parent
let holder = $('#' + container).parent().parent();
if (holder.hasClass('box') || holder.hasClass('box-body')) {
// find box-body:
let boxBody;
boxBody = holder;
if (!holder.hasClass('box-body')) {
boxBody = holder.find('.box-body');
}
boxBody.empty().append($('<p>').append($('<em>').text(noDataForChart)));
}
return;
}
if (colorData) {
data = colorizeData(data);
}
// new chart!
let ctx = document.getElementById(container).getContext("2d");
let chartOpts = {
type: chartType,
data: data,
options: options,
lineAtIndex: [],
annotation: {},
};
if (typeof drawVerticalLine !== 'undefined') {
if (drawVerticalLine !== '') {
// draw line using annotation plugin.
console.log('Will draw line');
chartOpts.options.annotation = {
annotations: [{
type: 'line',
id: 'a-line-1',
mode: 'vertical',
scaleID: 'x-axis-0',
value: drawVerticalLine,
borderColor: 'red',
borderWidth: 1,
label: {
backgroundColor: 'rgba(0,0,0,0)',
fontFamily: "sans-serif",
fontSize: 12,
fontColor: "#333",
position: "right",
xAdjust: -20,
yAdjust: -125,
enabled: true,
content: todayText
}
}]
};
}
}
new Chart(ctx, chartOpts);
}).fail(function () {
$('#' + container).addClass('general-chart-error');
});
}
/**
* @param URI
* @param container
*/
function stackedColumnChart(URI, container) {
"use strict";
let options = $.extend(true, {}, defaultChartOptions);
options.stacked = true;
options.scales.xAxes[0].stacked = true;
options.scales.yAxes[0].stacked = true;
drawAChart(URI, container, 'bar', options, true);
}
/**
*
* @param URI
* @param container
*/
function multiCurrencyPieChart(URI, container) {
"use strict";
drawAChart(URI, container, 'pie', pieOptionsWithCurrency, false);
}
/**
*
* @param URI
* @param container
*/
function columnChart(URI, container) {
"use strict";
drawAChart(URI, container, 'bar', defaultChartOptions, true);
}
/**
*
* @param uri
* @param holder
*/
function lineChart(uri, holder) {
drawAChart(uri, holder, 'line', defaultChartOptions, true);
}
// Exposed public methods
return {
lineChart: lineChart,
multiCurrencyPieChart: multiCurrencyPieChart,
stackedColumnChart: stackedColumnChart,
columnChart: columnChart
}
}));

22
resources/js/v1/firefly-iii.js vendored Normal file
View File

@@ -0,0 +1,22 @@
/*
* firefly-iii.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
require('./bootstrap');
// all kinds of helpers here.

20
resources/js/v1/help.js vendored Normal file
View File

@@ -0,0 +1,20 @@
/*
* help.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/

145
resources/js/v1/index.js vendored Normal file
View File

@@ -0,0 +1,145 @@
/*
* index.js
* Copyright (c) 2019 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III 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 3 of the License, or
* (at your option) any later version.
*
* Firefly III 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 Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
require('./firefly-iii');
console.log('hi');
$(document).ready(function () {
console.log('hello');
});
//import ReactDOM from "react-dom";
//import InfoBox from '../components/InfoBox.react';
// require charts
// let defaultCharts = require('./default-charts');
//
// (function() {
// $(document).ready(function () {
// defaultCharts.lineChart(accountFrontpageUri, 'accounts-chart');
//
// if (billCount > 0) {
// defaultCharts.multiCurrencyPieChart('chart/bill/frontpage', 'bills-chart');
// }
//
// defaultCharts.stackedColumnChart('chart/budget/frontpage', 'budgets-chart');
// defaultCharts.columnChart('chart/category/frontpage', 'categories-chart');
// defaultCharts.columnChart(accountExpenseUri, 'expense-accounts-chart');
// defaultCharts.columnChart(accountRevenueUri, 'revenue-accounts-chart');
// });
// })(defaultCharts);
// ReactDOM.render(
// <InfoBox subreddit="reactjs"/>,
// document.getElementById('box_out')
// );
// function drawChart() {
// "use strict";
//
// // get balance box:
// getBalanceBox();
// getBillsBox();
// getAvailableBox();
// getNetWorthBox();
// getPiggyBanks();
//
// //getBoxAmounts();
// }
//
// /**
// *
// */
// function getPiggyBanks() {
// $.getJSON(piggyInfoUri).done(function (data) {
// if (data.html.length > 0) {
// $('#piggy_bank_overview').html(data.html);
// }
// });
// }
//
// function getNetWorthBox() {
// // box-net-worth
// $.getJSON('json/box/net-worth').done(function (data) {
// $('#box-net-worth').html(data.net_worths.join(', '));
// });
// }
//
// /**
// *
// */
// function getAvailableBox() {
// // box-left-to-spend
// // box-left-per-day
// $.getJSON('json/box/available').done(function (data) {
// $('#box-left-to-spend').html(data.left);
// $('#box-left-per-day').html(data.perDay);
// $('#box-left-to-spend-text').text(data.text);
// if (data.overspent === true) {
// $('#box-left-to-spend-box').removeClass('bg-green-gradient').addClass('bg-red-gradient');
// }
// });
// }
//
// /**
// *
// */
// function getBillsBox() {
// // box-bills-unpaid
// // box-bills-paid
// $.getJSON('json/box/bills').done(function (data) {
// $('#box-bills-paid').html(data.paid);
// $('#box-bills-unpaid').html(data.unpaid);
// });
// }
//
// /**
// *
// */
// function getBalanceBox() {
// // box-balance-sums
// // box-balance-list
// $.getJSON('json/box/balance').done(function (data) {
// if (data.size === 1) {
// // show balance in "sums", show single entry in list.
// for (x in data.sums) {
// $('#box-balance-sums').html(data.sums[x]);
// $('#box-balance-list').html(data.incomes[x] + ' / ' + data.expenses[x]);
// }
// return;
// }
// // do not use "sums", only use list.
// $('#box-balance-progress').remove();
// var expense, string, sum, income, current;
// var count = 0;
// for (x in data.sums) {
// if (count > 1) {
// return;
// }
// current = $('#box-balance-list').html();
// sum = data.sums[x];
// expense = data.expenses[x];
// income = data.incomes[x];
// string = income + ' / ' + expense + ': ' + sum;
//
// $('#box-balance-list').html(current + '<span title="' + string + '">' + string + '</span>' + '<br>');
// count++;
// }
// });
// }

View File

@@ -194,11 +194,12 @@
drawVerticalLine = '{{ today.formatLocalized(monthAndDayFormat) }}';
{% endif %}
</script>
<!--
<script type="text/javascript" src="v1/js/lib/Chart.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/lib/chartjs-plugin-annotation.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/charts.defaults.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/charts.js?v={{ FF_VERSION }}"></script>
-->
<script type="text/javascript" src="v1/js/ff/index.js?v={{ FF_VERSION }}"></script>
{% endblock %}
{% block styles %}

View File

@@ -1,7 +1,7 @@
// date ranges
var ranges = {}
var ranges = {};
{% for title, range in dateRangeConfig.ranges %}
ranges["{{ title }}"] = [moment("{{ range[0].format('Y-m-d') }}"), moment("{{ range[1].format('Y-m-d') }}")];
ranges["{{ title }}"] = ["{{ range[0].format('Y-m-d') }}", "{{ range[1].format('Y-m-d') }}"];
{% endfor %}
// date range meta configuration
@@ -19,8 +19,8 @@ customRange: "{{ 'customRange'|_ }}"
// date range actual configuration:
var dateRangeConfig = {
startDate: moment("{{ dateRangeConfig.start }}"),
endDate: moment("{{ dateRangeConfig.end }}"),
startDate: "{{ dateRangeConfig.start }}",
endDate: "{{ dateRangeConfig.end }}",
ranges: ranges
};

View File

@@ -169,26 +169,14 @@
</div>
{# Java libraries and stuff: #}
{# Moment JS #}
<script src="v1/js/lib/moment.min.js?v={{ FF_VERSION }}" type="text/javascript"></script>
<script src="v1/js/ff/moment/{{ language }}.js?v={{ FF_VERSION }}" type="text/javascript"></script>
{# All kinds of variables. #}
<script src="{{ route('javascript.variables') }}?ext=.js&amp;v={{ FF_VERSION }}{% if account %}&amp;account={{ account.id }}{% endif %}" type="text/javascript"></script>
{# big fat JS thing courtesy of Vue#}
<script src="v1/js/app.js?v={{ FF_VERSION }}" type="text/javascript"></script>
{# date range picker, current template, etc.#}
<script src="v1/js/lib/daterangepicker.js?v={{ FF_VERSION }}" type="text/javascript"></script>
<script src="v1/lib/adminlte/js/adminlte.min.js?v={{ FF_VERSION }}" type="text/javascript"></script>
<script type="text/javascript" src="v1/js/lib/accounting.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/manifest.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/vendor.js?v={{ FF_VERSION }}"></script>
{# Firefly III code#}
<script type="text/javascript" src="v1/js/ff/firefly.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/help.js?v={{ FF_VERSION }}"></script>
{% if not shownDemo %}
<!--
<script type="text/javascript">
var routeForTour = "{{ current_route_name }}";
var routeStepsUri = "{{ route('json.intro', [current_route_name, what|default("")]) }}";
@@ -196,6 +184,7 @@
</script>
<script type="text/javascript" src="v1/lib/intro/intro.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/intro/intro.js?v={{ FF_VERSION }}"></script>
-->
{% endif %}
{% block scripts %}{% endblock %}

View File

@@ -17,74 +17,95 @@
{{ trans('firefly.user_id_is',{user: userId})|raw }}
</p>
{% if not SANDSTORM %}
<ul>
<li><a href="{{ route('profile.change-email') }}">{{ 'change_your_email'|_ }}</a></li>
<li><a href="{{ route('profile.change-password') }}">{{ 'change_your_password'|_ }}</a></li>
<li><a class="text-danger" href="{{ route('profile.delete-account') }}">{{ 'delete_account'|_ }}</a></li>
</ul>
<ul>
<li><a href="{{ route('profile.change-email') }}">{{ 'change_your_email'|_ }}</a></li>
<li><a href="{{ route('profile.change-password') }}">{{ 'change_your_password'|_ }}</a></li>
<li><a class="text-danger" href="{{ route('profile.delete-account') }}">{{ 'delete_account'|_ }}</a></li>
</ul>
{% endif %}
</div>
</div>
</div>
</div>
{% if not SANDSTORM %}
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'command_line_token'|_ }}</h3>
</div>
<div class="box-body">
<p>
{{ 'explain_command_line_token'|_ }}
</p>
<p>
<input id="token" type="text" class="form-control" name="token" value="{{ accessToken.data }}" size="32" maxlength="32" readonly/>
</p>
<p>
<form action="{{ route('profile.regenerate') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<button type="submit" class="btn btn-danger btn-xs"><i class="fa fa-refresh"></i> {{ 'regenerate_command_line_token'|_ }}</button>
</form>
</p>
{% if SANDSTORM %}
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Offer template</h3>
</div>
<div class="box-body">
<p>
Block for sandstorm thing
</p>
<div>
<iframe style="width: 100%; height: 55px; margin: 0; border: 0;" id="offer-iframe">
</iframe>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% if not SANDSTORM %}
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'command_line_token'|_ }}</h3>
</div>
<div class="box-body">
<p>
{{ 'explain_command_line_token'|_ }}
</p>
<p>
<input id="token" type="text" class="form-control" name="token" value="{{ accessToken.data }}" size="32" maxlength="32" readonly/>
</p>
<p>
<form action="{{ route('profile.regenerate') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<button type="submit" class="btn btn-danger btn-xs"><i class="fa fa-refresh"></i> {{ 'regenerate_command_line_token'|_ }}</button>
</form>
</p>
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% if not SANDSTORM %}
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'pref_two_factor_auth'|_ }}</h3>
</div>
<div class="box-body">
<p class="text-info">{{ 'pref_two_factor_auth_help'|_ }}</p>
{% if enabled2FA == true %}
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'pref_two_factor_auth'|_ }}</h3>
</div>
<div class="box-body">
<p class="text-info">{{ 'pref_two_factor_auth_help'|_ }}</p>
{% if enabled2FA == true %}
<div class="btn-group">
<a class="btn btn-info" href="{{ route('profile.code') }}">
<i class="fa fa-recycle"></i>
{{ 'pref_two_factor_auth_reset_code'|_ }}</a>
<a class="btn btn-danger" href="{{ route('profile.delete-code') }}">
<i class="fa fa-trash"></i>
{{ 'pref_two_factor_auth_disable_2fa'|_ }}</a>
</div>
{% else %}
<p>
<form action="{{ route('profile.enable2FA') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<button type="submit" class="btn btn-info"><i class="fa fa-lock"></i> {{ 'pref_enable_two_factor_auth'|_ }}</button>
</form>
</p>
{% endif %}
<div class="btn-group">
<a class="btn btn-info" href="{{ route('profile.code') }}">
<i class="fa fa-recycle"></i>
{{ 'pref_two_factor_auth_reset_code'|_ }}</a>
<a class="btn btn-danger" href="{{ route('profile.delete-code') }}">
<i class="fa fa-trash"></i>
{{ 'pref_two_factor_auth_disable_2fa'|_ }}</a>
</div>
{% else %}
<p>
<form action="{{ route('profile.enable2FA') }}" method="post">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<button type="submit" class="btn btn-info"><i class="fa fa-lock"></i> {{ 'pref_enable_two_factor_auth'|_ }}</button>
</form>
</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="row">
@@ -103,3 +124,34 @@
</div>
</div>
{% endblock %}
{% block scripts %}
{% if SANDSTORM %}
<script>
function requestIframeURL() {
var template = "You can use the $API_TOKEN key to reach Firefly III at $API_HOST.";
window.parent.postMessage({
renderTemplate: {
rpcId: "0",
template: template,
clipboardButton: 'left'
}
}, "*");
}
document.addEventListener("DOMContentLoaded", requestIframeURL);
var copyIframeURLToElement = function (event) {
if (event.data.rpcId === "0") {
if (event.data.error) {
console.log("ERROR: " + event.data.error);
} else {
var el = document.getElementById("offer-iframe");
el.setAttribute("src", event.data.uri);
}
}
};
window.addEventListener("message", copyIframeURLToElement);
</script>
{% endif %}
{% endblock %}

34
webpack.mix.js vendored
View File

@@ -1,26 +1,32 @@
let mix = require('laravel-mix');
let Assert = require('laravel-mix/src/Assert');
let glob = require('glob');
// mix.autoload({
// jquery: ['$', 'window.jQuery']
// });
//mix.extract(['jquery','chart.js','accounting','chartjs-color-string','chartjs-color','moment','color-name'],'public/v1/js/ff/vendor.js');
mix.extract([],'public/v1/js/ff/vendor.js');
mix.extend(
'foo',
'firefly_iii',
new class {
constructor() {
this.toCompile = [];
}
/**
* The API name for the component.
*/
name() {
return 'foo';
return 'firefly_iii';
}
register(entry, output) {
if (typeof entry === 'string' && entry.includes('*')) {
entry = glob.sync(entry);
}
Assert.js(entry, output);
/**
* Register the component.
*
* @param {*} entry
* @param {string} output
*/
register(entry, output) {
entry = [].concat(entry).map(file => new File(file));
output = new File(output);
@@ -44,6 +50,8 @@ mix.extend(
);
});
}
dependencies() {
return ["@babel/preset-flow",'@babel/preset-react'];
}
@@ -75,10 +83,6 @@ mix.extend(
plugins: [["@babel/plugin-proposal-class-properties"]]
};
}
}()
);
mix.foo('resources/js/app.js', 'public/v2/assets/js').sass('resources/sass/app.scss', 'public/v2/assets/css');
mix.firefly_iii('resources/js/v1/index.js', 'public/v1/js/ff/index.js');

761
yarn.lock

File diff suppressed because it is too large Load Diff