feat: New Build System based on esbuild
- Deprecate use of build.json - *.bundle.js files placed anywhere in the public folder are bundled - Built files are created in public/build folder which is gitignored WIP
This commit is contained in:
parent
32d3f1f099
commit
226ad1d91a
28 changed files with 1676 additions and 55 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@ locale
|
|||
dist/
|
||||
# build/
|
||||
frappe/docs/current
|
||||
frappe/public/build
|
||||
.vscode
|
||||
node_modules
|
||||
.kdev4/
|
||||
|
|
|
|||
44
esbuild/esbuild-plugin-html.js
Normal file
44
esbuild/esbuild-plugin-html.js
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
module.exports = {
|
||||
name: "frappe-html",
|
||||
setup(build) {
|
||||
let path = require("path");
|
||||
let fs = require("fs/promises");
|
||||
|
||||
build.onResolve({ filter: /\.html$/ }, args => {
|
||||
return {
|
||||
path: path.join(args.resolveDir, args.path),
|
||||
namespace: "frappe-html"
|
||||
};
|
||||
});
|
||||
|
||||
build.onLoad({ filter: /.*/, namespace: "frappe-html" }, args => {
|
||||
let filepath = args.path;
|
||||
let filename = path.basename(filepath).split(".")[0];
|
||||
|
||||
return fs
|
||||
.readFile(filepath, "utf-8")
|
||||
.then(content => {
|
||||
content = scrub_html_template(content);
|
||||
return {
|
||||
contents: `\n\tfrappe.templates['${filename}'] = '${content}';\n`
|
||||
};
|
||||
})
|
||||
.catch(() => {
|
||||
return {
|
||||
contents: "",
|
||||
warnings: [
|
||||
{
|
||||
text: `There was an error importing ${filepath}`
|
||||
}
|
||||
]
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function scrub_html_template(content) {
|
||||
content = content.replace(/\s/g, " ");
|
||||
content = content.replace(/(<!--.*?-->)/g, "");
|
||||
return content.replace("'", "'"); // eslint-disable-line
|
||||
}
|
||||
69
esbuild/esbuild-watch.js
Normal file
69
esbuild/esbuild-watch.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
let esbuild = require("esbuild");
|
||||
let htmlPlugin = require("./esbuild-plugin-html");
|
||||
let vue = require("esbuild-vue");
|
||||
let http = require("http");
|
||||
let httpProxy = require("http-proxy");
|
||||
let path = require("path");
|
||||
|
||||
const { get_public_path, apps_list } = require("../rollup/rollup.utils");
|
||||
|
||||
let proxy = httpProxy.createProxyServer({});
|
||||
|
||||
proxy.on("error", function(e) {
|
||||
console.error(e);
|
||||
});
|
||||
|
||||
let server = http.createServer((req, res) => {
|
||||
if (req.url.includes("/public/")) {
|
||||
buildAsset(req.url).then(result => {
|
||||
if (!result) {
|
||||
proxy_request();
|
||||
return;
|
||||
}
|
||||
res.setHeader("Content-Header", "application/javascript");
|
||||
res.writeHead(200);
|
||||
res.end(result);
|
||||
});
|
||||
} else {
|
||||
proxy_request();
|
||||
}
|
||||
|
||||
function proxy_request() {
|
||||
proxy.web(req, res, { target: "http://localhost:8000" });
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(8080);
|
||||
|
||||
server.on("listening", () => {
|
||||
console.log("dev server started at http:localhost:8080");
|
||||
});
|
||||
|
||||
function buildAsset(url) {
|
||||
if (url.startsWith("/")) {
|
||||
url = url.substr(1);
|
||||
}
|
||||
let app;
|
||||
let parts = url.split(path.sep);
|
||||
if (apps_list.includes(parts[0])) {
|
||||
app = parts[0];
|
||||
}
|
||||
if (!app) return;
|
||||
|
||||
let filepath = path.resolve(get_public_path(app), url.split("public/")[1]);
|
||||
console.log("building " + url);
|
||||
|
||||
return esbuild
|
||||
.build({
|
||||
entryPoints: [filepath],
|
||||
write: false,
|
||||
bundle: true,
|
||||
plugins: [htmlPlugin, vue()],
|
||||
define: {
|
||||
"process.env.NODE_ENV": "'development'"
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
return result.outputFiles[0].text;
|
||||
});
|
||||
}
|
||||
11
esbuild/ignore-assets.js
Normal file
11
esbuild/ignore-assets.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
module.exports = {
|
||||
name: "frappe-ignore-asset",
|
||||
setup(build) {
|
||||
build.onResolve({ filter: /^\/assets\// }, args => {
|
||||
return {
|
||||
path: args.path,
|
||||
external: true
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
79
esbuild/index.js
Normal file
79
esbuild/index.js
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
let glob = require("fast-glob");
|
||||
let esbuild = require("esbuild");
|
||||
let html_plugin = require("./esbuild-plugin-html");
|
||||
let vue = require("esbuild-vue");
|
||||
let postCssPlugin = require("esbuild-plugin-postcss2").default;
|
||||
let ignore_assets = require("./ignore-assets");
|
||||
let { get_options_for_scss } = require("../rollup/rollup.utils");
|
||||
|
||||
console.time("Build time");
|
||||
|
||||
glob(["frappe/public/js/**/*.bundle.js"]).then(entry_files => {
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: entry_files,
|
||||
outdir: "frappe/public/build",
|
||||
outbase: "frappe/public",
|
||||
sourcemap: true,
|
||||
bundle: true,
|
||||
metafile: true,
|
||||
minify: true,
|
||||
define: {
|
||||
"process.env.NODE_ENV": "'development'"
|
||||
},
|
||||
plugins: [
|
||||
html_plugin,
|
||||
ignore_assets,
|
||||
vue(),
|
||||
postCssPlugin({
|
||||
plugins: [require("autoprefixer")],
|
||||
sassOptions: {
|
||||
...get_options_for_scss(),
|
||||
importer: function(url) {
|
||||
if (url.startsWith("~")) {
|
||||
// strip ~ so that it can resolve from node_modules
|
||||
url = url.slice(1);
|
||||
}
|
||||
if (url.endsWith(".css")) {
|
||||
// strip .css from end of path
|
||||
url = url.slice(0, -4);
|
||||
}
|
||||
// normal file, let it go
|
||||
return {
|
||||
file: url
|
||||
};
|
||||
}
|
||||
}
|
||||
})
|
||||
],
|
||||
|
||||
// watch: {
|
||||
// onRebuild(error, result) {
|
||||
// if (error) console.error("watch build failed:", error);
|
||||
// else {
|
||||
// console.log("watch build succeeded:");
|
||||
// log_build_meta(result.metafile);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
})
|
||||
.then(result => {
|
||||
log_build_meta(result.metafile);
|
||||
|
||||
if (result.warnings.length) {
|
||||
console.warn(result.warnings);
|
||||
}
|
||||
})
|
||||
.catch(e => console.error("error"))
|
||||
.finally(() => {
|
||||
console.timeEnd("Build time");
|
||||
});
|
||||
});
|
||||
|
||||
function log_build_meta(metafile) {
|
||||
for (let outfile in metafile.outputs) {
|
||||
if (outfile.endsWith('.map')) continue;
|
||||
let data = metafile.outputs[outfile];
|
||||
console.log(outfile, data.bytes / 1000 + " Kb");
|
||||
}
|
||||
}
|
||||
110
esbuild/utils.js
Normal file
110
esbuild/utils.js
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
const frappe_path = path.resolve(__dirname, "..");
|
||||
const bench_path = path.resolve(frappe_path, "..", "..");
|
||||
const sites_path = path.resolve(bench_path, "sites");
|
||||
const assets_path = path.resolve(sites_path, "assets");
|
||||
const app_list = get_apps_list();
|
||||
|
||||
const app_paths = app_list.reduce((out, app) => {
|
||||
out[app] = path.resolve(bench_path, "apps", app, app);
|
||||
return out;
|
||||
}, {});
|
||||
const public_paths = app_list.reduce((out, app) => {
|
||||
out[app] = path.resolve(app_paths[app], "public");
|
||||
return out;
|
||||
}, {});
|
||||
const public_js_paths = app_list.reduce((out, app) => {
|
||||
out[app] = path.resolve(app_paths[app], "public/js");
|
||||
return out;
|
||||
}, {});
|
||||
|
||||
const bundle_map = app_list.reduce((out, app) => {
|
||||
const public_js_path = public_js_paths[app];
|
||||
if (fs.existsSync(public_js_path)) {
|
||||
const all_files = fs.readdirSync(public_js_path);
|
||||
const js_files = all_files.filter(file => file.endsWith(".js"));
|
||||
|
||||
for (let js_file of js_files) {
|
||||
const filename = path.basename(js_file).split(".")[0];
|
||||
out[path.join(app, "js", filename)] = path.resolve(
|
||||
public_js_path,
|
||||
js_file
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}, {});
|
||||
|
||||
const get_public_path = app => public_paths[app];
|
||||
|
||||
const get_build_json_path = app =>
|
||||
path.resolve(get_public_path(app), "build.json");
|
||||
|
||||
function get_build_json(app) {
|
||||
try {
|
||||
return require(get_build_json_path(app));
|
||||
} catch (e) {
|
||||
// build.json does not exist
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function delete_file(path) {
|
||||
if (fs.existsSync(path)) {
|
||||
fs.unlinkSync(path);
|
||||
}
|
||||
}
|
||||
|
||||
function run_serially(tasks) {
|
||||
let result = Promise.resolve();
|
||||
tasks.forEach(task => {
|
||||
if (task) {
|
||||
result = result.then ? result.then(task) : Promise.resolve();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
const get_app_path = app => app_paths[app];
|
||||
|
||||
const get_options_for_scss = () => {
|
||||
const node_modules_path = path.resolve(
|
||||
get_app_path("frappe"),
|
||||
"..",
|
||||
"node_modules"
|
||||
);
|
||||
const app_paths = app_list
|
||||
.map(get_app_path)
|
||||
.map(app_path => path.resolve(app_path, ".."));
|
||||
|
||||
return {
|
||||
includePaths: [node_modules_path, ...app_paths]
|
||||
};
|
||||
};
|
||||
|
||||
function get_apps_list() {
|
||||
return fs
|
||||
.readFileSync(path.resolve(sites_path, "apps.txt"), {
|
||||
encoding: "utf-8"
|
||||
})
|
||||
.split("\n")
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
app_list,
|
||||
bench_path,
|
||||
assets_path,
|
||||
sites_path,
|
||||
bundle_map,
|
||||
get_public_path,
|
||||
get_build_json_path,
|
||||
get_build_json,
|
||||
get_app_path,
|
||||
delete_file,
|
||||
run_serially,
|
||||
get_options_for_scss
|
||||
};
|
||||
|
|
@ -30,11 +30,11 @@ page_js = {
|
|||
# website
|
||||
app_include_js = [
|
||||
"/assets/js/libs.min.js",
|
||||
"/assets/js/desk.min.js",
|
||||
"/assets/js/list.min.js",
|
||||
"/assets/js/form.min.js",
|
||||
"/assets/js/control.min.js",
|
||||
"/assets/js/report.min.js",
|
||||
"frappe/public/js/desk.bundle.js",
|
||||
"frappe/public/js/list.bundle.js",
|
||||
"frappe/public/js/form.bundle.js",
|
||||
"frappe/public/js/controls.bundle.js",
|
||||
"frappe/public/js/report.bundle.js",
|
||||
]
|
||||
app_include_css = [
|
||||
"/assets/css/desk.min.css",
|
||||
|
|
|
|||
20
frappe/public/js/controls.bundle.js
Normal file
20
frappe/public/js/controls.bundle.js
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import "air-datepicker/dist/js/datepicker.min.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.cs.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.da.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.de.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.en.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.es.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.fi.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.fr.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.hu.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.nl.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.pl.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.pt-BR.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.pt.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.ro.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.sk.js";
|
||||
import "air-datepicker/dist/js/i18n/datepicker.zh.js";
|
||||
import "./frappe/ui/capture.js";
|
||||
import "./frappe/form/controls/control.js";
|
||||
|
||||
console.log('controls')
|
||||
107
frappe/public/js/desk.bundle.js
Normal file
107
frappe/public/js/desk.bundle.js
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import '../scss/desk.scss';
|
||||
import "./frappe/translate.js";
|
||||
import "./frappe/class.js";
|
||||
import "./frappe/polyfill.js";
|
||||
import "./frappe/provide.js";
|
||||
import "./frappe/assets.js";
|
||||
import "./frappe/format.js";
|
||||
import "./frappe/form/formatters.js";
|
||||
import "./frappe/dom.js";
|
||||
import "./frappe/ui/messages.js";
|
||||
import "./frappe/ui/keyboard.js";
|
||||
import "./frappe/ui/colors.js";
|
||||
import "./frappe/ui/sidebar.js";
|
||||
import "./frappe/ui/link_preview.js";
|
||||
|
||||
import "./frappe/request.js";
|
||||
import "./frappe/socketio_client.js";
|
||||
import "./frappe/utils/utils.js";
|
||||
import "./frappe/event_emitter.js";
|
||||
import "./frappe/router.js";
|
||||
import "./frappe/router_history.js";
|
||||
import "./frappe/defaults.js";
|
||||
import "./frappe/roles_editor.js";
|
||||
import "./frappe/module_editor.js";
|
||||
import "./frappe/microtemplate.js";
|
||||
|
||||
import "./frappe/ui/page.html";
|
||||
import "./frappe/ui/page.js";
|
||||
import "./frappe/ui/slides.js";
|
||||
// import "./frappe/ui/onboarding_dialog.js";
|
||||
import "./frappe/ui/find.js";
|
||||
import "./frappe/ui/iconbar.js";
|
||||
import "./frappe/form/layout.js";
|
||||
import "./frappe/ui/field_group.js";
|
||||
import "./frappe/form/link_selector.js";
|
||||
import "./frappe/form/multi_select_dialog.js";
|
||||
import "./frappe/ui/dialog.js";
|
||||
import "./frappe/ui/capture.js";
|
||||
import "./frappe/ui/app_icon.js";
|
||||
import "./frappe/ui/theme_switcher.js";
|
||||
|
||||
import "./frappe/model/model.js";
|
||||
import "./frappe/db.js";
|
||||
import "./frappe/model/meta.js";
|
||||
import "./frappe/model/sync.js";
|
||||
import "./frappe/model/create_new.js";
|
||||
import "./frappe/model/perm.js";
|
||||
import "./frappe/model/workflow.js";
|
||||
import "./frappe/model/user_settings.js";
|
||||
|
||||
import "./frappe/utils/user.js";
|
||||
import "./frappe/utils/common.js";
|
||||
import "./frappe/utils/urllib.js";
|
||||
import "./frappe/utils/pretty_date.js";
|
||||
import "./frappe/utils/test_utils.js";
|
||||
import "./frappe/utils/tools.js";
|
||||
import "./frappe/utils/datetime.js";
|
||||
import "./frappe/utils/number_format.js";
|
||||
import "./frappe/utils/help.js";
|
||||
import "./frappe/utils/help_links.js";
|
||||
import "./frappe/utils/address_and_contact.js";
|
||||
import "./frappe/utils/preview_email.js";
|
||||
import "./frappe/utils/file_manager.js";
|
||||
|
||||
import "./frappe/upload.js";
|
||||
import "./frappe/ui/tree.js";
|
||||
|
||||
import "./frappe/views/container.js";
|
||||
import "./frappe/views/breadcrumbs.js";
|
||||
import "./frappe/views/factory.js";
|
||||
import "./frappe/views/pageview.js";
|
||||
|
||||
import "./frappe/ui/toolbar/awesome_bar.js";
|
||||
// import "./frappe/ui/toolbar/energy_points_notifications.js";
|
||||
import "./frappe/ui/notifications/notifications.js";
|
||||
import "./frappe/ui/toolbar/search.js";
|
||||
import "./frappe/ui/toolbar/tag_utils.js";
|
||||
import "./frappe/ui/toolbar/search.html";
|
||||
import "./frappe/ui/toolbar/search_utils.js";
|
||||
import "./frappe/ui/toolbar/about.js";
|
||||
import "./frappe/ui/toolbar/navbar.html";
|
||||
import "./frappe/ui/toolbar/toolbar.js";
|
||||
// import "./frappe/ui/toolbar/notifications.js";
|
||||
import "./frappe/views/communication.js";
|
||||
import "./frappe/views/translation_manager.js";
|
||||
import "./frappe/views/workspace/workspace.js";
|
||||
|
||||
import "./frappe/widgets/widget_group.js";
|
||||
|
||||
import "./frappe/ui/sort_selector.html";
|
||||
import "./frappe/ui/sort_selector.js";
|
||||
|
||||
import "./frappe/change_log.html";
|
||||
import "./frappe/ui/workspace_loading_skeleton.html";
|
||||
import "./frappe/desk.js";
|
||||
import "./frappe/query_string.js";
|
||||
|
||||
// import "./frappe/ui/comment.js";
|
||||
|
||||
import "./frappe/chat.js";
|
||||
import "./frappe/utils/energy_point_utils.js";
|
||||
import "./frappe/utils/dashboard_utils.js";
|
||||
import "./frappe/ui/chart.js";
|
||||
import "./frappe/ui/datatable.js";
|
||||
import "./frappe/ui/driver.js";
|
||||
import "./frappe/ui/plyr.js";
|
||||
import "./frappe/barcode_scanner/index.js";
|
||||
18
frappe/public/js/form.bundle.js
Normal file
18
frappe/public/js/form.bundle.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import "./frappe/form/templates/address_list.html";
|
||||
import "./frappe/form/templates/attachment.html";
|
||||
import "./frappe/form/templates/contact_list.html";
|
||||
import "./frappe/form/templates/form_dashboard.html";
|
||||
import "./frappe/form/templates/form_footer.html";
|
||||
import "./frappe/form/templates/form_links.html";
|
||||
import "./frappe/form/templates/form_sidebar.html";
|
||||
import "./frappe/form/templates/print_layout.html";
|
||||
import "./frappe/form/templates/report_links.html";
|
||||
import "./frappe/form/templates/set_sharing.html";
|
||||
import "./frappe/form/templates/timeline_message_box.html";
|
||||
import "./frappe/form/templates/users_in_sidebar.html";
|
||||
|
||||
import "./frappe/form/controls/control.js";
|
||||
import "./frappe/views/formview.js";
|
||||
import "./frappe/form/form.js";
|
||||
import "./frappe/meta_tag.js";
|
||||
|
||||
25
frappe/public/js/frappe-web.bundle.js
Normal file
25
frappe/public/js/frappe-web.bundle.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import "./frappe/class.js";
|
||||
import "./frappe/polyfill.js";
|
||||
import "./lib/md5.min.js";
|
||||
import "./frappe/provide.js";
|
||||
import "./frappe/format.js";
|
||||
import "./frappe/utils/number_format.js";
|
||||
import "./frappe/utils/utils.js";
|
||||
import "./frappe/utils/common.js";
|
||||
import "./frappe/ui/messages.js";
|
||||
import "./frappe/translate.js";
|
||||
import "./frappe/utils/pretty_date.js";
|
||||
import "./frappe/microtemplate.js";
|
||||
import "./frappe/query_string.js";
|
||||
|
||||
import "./frappe/upload.js";
|
||||
|
||||
import "./frappe/model/meta.js";
|
||||
import "./frappe/model/model.js";
|
||||
import "./frappe/model/perm.js";
|
||||
|
||||
import "./web/bootstrap-4";
|
||||
|
||||
|
||||
import "../../website/js/website.js";
|
||||
import "./frappe/socketio_client.js";
|
||||
|
|
@ -80,4 +80,4 @@ To subclass, use:
|
|||
|
||||
// export
|
||||
global.Class = Class;
|
||||
})(this);
|
||||
})(window);
|
||||
|
|
|
|||
|
|
@ -543,7 +543,7 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
} else if (expression.substr(0, 5)=='eval:') {
|
||||
try {
|
||||
out = eval(expression.substr(5));
|
||||
out = frappe.utils.eval(expression.substr(5), { doc });
|
||||
if (parent && parent.istable && expression.includes('is_submittable')) {
|
||||
out = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
// common file between desk and website
|
||||
import md5 from 'md5'
|
||||
|
||||
frappe.avatar = function (user, css_class, title, image_url=null, remove_color=false, filterable=false) {
|
||||
let user_info;
|
||||
|
|
@ -375,4 +376,4 @@ frappe.utils.get_page_view_count = function (route) {
|
|||
return frappe.call("frappe.website.doctype.web_page_view.web_page_view.get_page_view_count", {
|
||||
path: route
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -954,6 +954,14 @@ Object.assign(frappe.utils, {
|
|||
return $el;
|
||||
},
|
||||
|
||||
eval(code, context={}) {
|
||||
let variable_names = Object.keys(context);
|
||||
let variables = Object.values(context);
|
||||
code = `return (${code})`;
|
||||
let expression_function = new Function(...variable_names, code);
|
||||
return expression_function(...variables);
|
||||
},
|
||||
|
||||
get_browser() {
|
||||
let ua = navigator.userAgent;
|
||||
let tem;
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
out = expression;
|
||||
} else if (expression.substr(0, 5) == 'eval:') {
|
||||
try {
|
||||
out = eval(expression.substr(5));
|
||||
out = frappe.utils.eval(expression.substr(5), { doc });
|
||||
} catch (e) {
|
||||
frappe.throw(__('Invalid "depends_on" expression set in filter {0}', [filter_label]));
|
||||
}
|
||||
|
|
|
|||
11
frappe/public/js/libs.bundle.js
Normal file
11
frappe/public/js/libs.bundle.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import "bootstrap/dist/js/bootstrap.bundle.js";
|
||||
import Vue from "vue/dist/vue.esm.js";
|
||||
import moment from "moment/min/moment-with-locales.js";
|
||||
import momentTimezone from "moment-timezone/builds/moment-timezone-with-data.js";
|
||||
import "socket.io-client/dist/socket.io.slim.js";
|
||||
import "./lib/Sortable.min.js";
|
||||
import "./lib/jquery/jquery.hotkeys.js";
|
||||
import "./lib/jSignature.min.js";
|
||||
|
||||
window.moment = momentTimezone;
|
||||
window.Vue = Vue;
|
||||
42
frappe/public/js/list.bundle.js
Normal file
42
frappe/public/js/list.bundle.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import "./frappe/ui/listing.html";
|
||||
|
||||
import "./frappe/model/indicator.js";
|
||||
import "./frappe/ui/filters/filter.js";
|
||||
import "./frappe/ui/filters/filter_list.js";
|
||||
import "./frappe/ui/filters/field_select.js";
|
||||
import "./frappe/ui/filters/edit_filter.html";
|
||||
import "./frappe/ui/tags.js";
|
||||
import "./frappe/ui/tag_editor.js";
|
||||
import "./frappe/ui/like.js";
|
||||
// import "./frappe/ui/liked_by.html";
|
||||
import "../html/print_template.html";
|
||||
|
||||
import "./frappe/list/base_list.js";
|
||||
import "./frappe/list/list_view.js";
|
||||
import "./frappe/list/list_factory.js";
|
||||
|
||||
import "./frappe/list/list_view_select.js";
|
||||
import "./frappe/list/list_sidebar.js";
|
||||
import "./frappe/list/list_sidebar.html";
|
||||
import "./frappe/list/list_sidebar_stat.html";
|
||||
import "./frappe/list/list_sidebar_group_by.js";
|
||||
import "./frappe/list/list_view_permission_restrictions.html";
|
||||
|
||||
import "./frappe/views/gantt/gantt_view.js";
|
||||
import "./frappe/views/calendar/calendar.js";
|
||||
import "./frappe/views/dashboard/dashboard_view.js";
|
||||
import "./frappe/views/image/image_view.js";
|
||||
import "./frappe/views/map/map_view.js";
|
||||
import "./frappe/views/kanban/kanban_view.js";
|
||||
import "./frappe/views/inbox/inbox_view.js";
|
||||
import "./frappe/views/file/file_view.js";
|
||||
|
||||
import "./frappe/views/treeview.js";
|
||||
import "./frappe/views/interaction.js";
|
||||
|
||||
import "./frappe/views/image/image_view_item_row.html";
|
||||
import "./frappe/views/image/photoswipe_dom.html";
|
||||
|
||||
import "./frappe/views/kanban/kanban_board.html";
|
||||
import "./frappe/views/kanban/kanban_column.html";
|
||||
import "./frappe/views/kanban/kanban_card.html";
|
||||
9
frappe/public/js/report.bundle.js
Normal file
9
frappe/public/js/report.bundle.js
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import "./lib/clusterize.min.js";
|
||||
import "./frappe/views/reports/report_factory.js";
|
||||
import "./frappe/views/reports/report_view.js";
|
||||
import "./frappe/views/reports/query_report.js";
|
||||
import "./frappe/views/reports/print_grid.html";
|
||||
import "./frappe/views/reports/print_tree.html";
|
||||
import "./frappe/ui/group_by/group_by.html";
|
||||
import "./frappe/ui/group_by/group_by.js";
|
||||
import "./frappe/views/reports/report_utils.js";
|
||||
65
frappe/public/js/web/bootstrap-4.js
vendored
Normal file
65
frappe/public/js/web/bootstrap-4.js
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import 'bootstrap/dist/js/bootstrap.bundle';
|
||||
|
||||
// multilevel dropdown
|
||||
$('.dropdown-menu a.dropdown-toggle').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
if (!$(this).next().hasClass('show')) {
|
||||
$(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
|
||||
}
|
||||
var $subMenu = $(this).next(".dropdown-menu");
|
||||
$subMenu.toggleClass('show');
|
||||
|
||||
|
||||
$(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function () {
|
||||
$('.dropdown-submenu .show').removeClass("show");
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
frappe.get_modal = function (title, content) {
|
||||
return $(
|
||||
`<div class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog modal-dialog-scrollable" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">${title}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
${frappe.utils.icon('close-alt', 'sm', 'close-alt')}
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
${content}
|
||||
</div>
|
||||
<div class="modal-footer hidden">
|
||||
<button type="button" class="btn btn-default btn-sm btn-modal-close" data-dismiss="modal">
|
||||
<i class="octicon octicon-x visible-xs" style="padding: 1px 0px;"></i>
|
||||
<span class="hidden-xs">${__("Close")}</span>
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary hidden"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
);
|
||||
};
|
||||
|
||||
frappe.ui.Dialog = class Dialog extends frappe.ui.Dialog {
|
||||
get_primary_btn() {
|
||||
return this.$wrapper.find(".modal-footer .btn-primary");
|
||||
}
|
||||
|
||||
set_primary_action(label, click) {
|
||||
this.$wrapper.find('.modal-footer').removeClass('hidden');
|
||||
return super.set_primary_action(label, click)
|
||||
.removeClass('hidden');
|
||||
}
|
||||
|
||||
make() {
|
||||
super.make();
|
||||
if (this.fields) {
|
||||
this.$wrapper.find('.section-body').addClass('w-100');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
@import "~air-datepicker/dist/css/datepicker.min.css";
|
||||
@import "~air-datepicker/dist/css/datepicker.min";
|
||||
|
||||
.datepicker {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
@import '~quill/dist/quill.snow.css';
|
||||
@import '~quill/dist/quill.bubble.css';
|
||||
@import '~quill/dist/quill.snow';
|
||||
@import '~quill/dist/quill.bubble';
|
||||
|
||||
.ql-toolbar.ql-snow,
|
||||
.ql-container.ql-snow {
|
||||
|
|
|
|||
|
|
@ -97,8 +97,7 @@
|
|||
{% block base_scripts %}
|
||||
<!-- js should be loaded in body! -->
|
||||
<script type="text/javascript" src="/assets/frappe/js/lib/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/js/frappe-web.min.js?ver={{ build_version }}"></script>
|
||||
<script type="text/javascript" src="/assets/js/bootstrap-4-web.min.js"></script>
|
||||
<script type="text/javascript" src="/assets/frappe/build/js/frappe-web.bundle.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{%- for link in web_include_js %}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ def get_jenv():
|
|||
'resolve_class': resolve_class,
|
||||
'inspect': inspect,
|
||||
'web_blocks': web_blocks,
|
||||
'web_block': web_block
|
||||
'web_block': web_block,
|
||||
'js_asset': js_asset
|
||||
})
|
||||
|
||||
frappe.local.jenv = jenv
|
||||
|
|
@ -228,3 +229,9 @@ def web_blocks(blocks):
|
|||
html += '<script>{}</script>'.format(script)
|
||||
|
||||
return html
|
||||
|
||||
def js_asset(path):
|
||||
import frappe
|
||||
if not frappe.local.dev_server or True:
|
||||
path = path.replace('frappe/public/', '/assets/frappe/build/')
|
||||
return f'<script type="text/javascript" src="{path}"></script>'
|
||||
|
|
|
|||
|
|
@ -605,7 +605,8 @@ $(document).ready(function() {
|
|||
|
||||
$(document).on("page-change", function() {
|
||||
$(document).trigger("apply_permissions");
|
||||
$('.dropdown-toggle').dropdown();
|
||||
// TODO: esbuild
|
||||
// $('.dropdown-toggle').dropdown();
|
||||
|
||||
//multilevel dropdown fix
|
||||
$('.dropdown-menu .dropdown-submenu .dropdown-toggle').on('click', function(e) {
|
||||
|
|
|
|||
|
|
@ -52,11 +52,14 @@
|
|||
|
||||
</script>
|
||||
|
||||
{% for include in include_js %}
|
||||
<script type="text/javascript" src="{{ include }}?ver={{ build_version }}"></script>
|
||||
{% endfor %}
|
||||
{% include "templates/includes/app_analytics/google_analytics.html" %}
|
||||
{% include "templates/includes/app_analytics/mixpanel_analytics.html" %}
|
||||
{% for include in include_js %}
|
||||
{{ js_asset(include) }}
|
||||
{% endfor %}
|
||||
|
||||
{{ js_asset('frappe/public/js/test.bundle.js') }}
|
||||
|
||||
{% include "templates/includes/app_analytics/google_analytics.html" %}
|
||||
{% include "templates/includes/app_analytics/mixpanel_analytics.html" %}
|
||||
|
||||
{% for sound in (sounds or []) %}
|
||||
<audio preload="auto" id="sound-{{ sound.name }}" volume={{ sound.volume or 1 }}>
|
||||
|
|
|
|||
14
package.json
14
package.json
|
|
@ -4,8 +4,7 @@
|
|||
"build": "node rollup/build.js",
|
||||
"production": "FRAPPE_ENV=production node rollup/build.js",
|
||||
"watch": "node rollup/watch.js",
|
||||
"snyk-protect": "snyk protect",
|
||||
"prepare": "yarn run snyk-protect"
|
||||
"snyk-protect": "snyk protect"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -50,14 +49,20 @@
|
|||
"socket.io": "^2.4.0",
|
||||
"superagent": "^3.8.2",
|
||||
"touch": "^3.1.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue": "2.6.12",
|
||||
"vue-router": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"chalk": "^2.3.2",
|
||||
"esbuild": "^0.11.11",
|
||||
"esbuild-plugin-postcss2": "^0.0.9",
|
||||
"esbuild-vue": "^0.2.0",
|
||||
"fast-glob": "^3.2.5",
|
||||
"graphlib": "^2.1.8",
|
||||
"http-proxy": "^1.18.1",
|
||||
"less": "^3.11.1",
|
||||
"md5": "^2.3.0",
|
||||
"rollup": "^1.2.2",
|
||||
"rollup-plugin-buble": "^0.19.2",
|
||||
"rollup-plugin-commonjs": "^8.3.0",
|
||||
|
|
@ -66,8 +71,7 @@
|
|||
"rollup-plugin-postcss": "^2.0.3",
|
||||
"rollup-plugin-terser": "^4.0.4",
|
||||
"rollup-plugin-vue": "4.2.0",
|
||||
"svg-sprite": "^1.5.0",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
"svg-sprite": "^1.5.0"
|
||||
},
|
||||
"snyk": true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue