Merge pull request #12883 from netchampfaris/esbuild
This commit is contained in:
commit
e9cf28bcdb
155 changed files with 3999 additions and 4058 deletions
12
.git-blame-ignore-revs
Normal file
12
.git-blame-ignore-revs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Since version 2.23 (released in August 2019), git-blame has a feature
|
||||
# to ignore or bypass certain commits.
|
||||
#
|
||||
# This file contains a list of commits that are not likely what you
|
||||
# are looking for in a blame, such as mass reformatting or renaming.
|
||||
# You can set this file as a default ignore file for blame by running
|
||||
# the following command.
|
||||
#
|
||||
# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
|
||||
|
||||
# Replace use of Class.extend with native JS class
|
||||
fe20515c23a3ac41f1092bf0eaf0a0a452ec2e85
|
||||
4
.github/workflows/publish-assets-develop.yml
vendored
4
.github/workflows/publish-assets-develop.yml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.6'
|
||||
- name: Set up bench for current push
|
||||
- name: Set up bench and build assets
|
||||
run: |
|
||||
npm install -g yarn
|
||||
pip3 install -U frappe-bench
|
||||
|
|
@ -29,7 +29,7 @@ jobs:
|
|||
- name: Package assets
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/build
|
||||
tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css
|
||||
tar -cvpzf $GITHUB_WORKSPACE/build/$GITHUB_SHA.tar.gz ./frappe-bench/sites/assets/frappe/dist
|
||||
|
||||
- name: Publish assets to S3
|
||||
uses: jakejarvis/s3-sync-action@master
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ jobs:
|
|||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.6'
|
||||
- name: Set up bench for current push
|
||||
- name: Set up bench and build assets
|
||||
run: |
|
||||
npm install -g yarn
|
||||
pip3 install -U frappe-bench
|
||||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
- name: Package assets
|
||||
run: |
|
||||
mkdir -p $GITHUB_WORKSPACE/build
|
||||
tar -cvpzf $GITHUB_WORKSPACE/build/assets.tar.gz ./frappe-bench/sites/assets/js ./frappe-bench/sites/assets/css
|
||||
tar -cvpzf $GITHUB_WORKSPACE/build/assets.tar.gz ./frappe-bench/sites/assets/frappe/dist
|
||||
|
||||
- name: Get release
|
||||
id: get_release
|
||||
|
|
|
|||
2
.github/workflows/server-mariadb-tests.yml
vendored
2
.github/workflows/server-mariadb-tests.yml
vendored
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Add to Hosts
|
||||
|
|
|
|||
2
.github/workflows/ui-tests.yml
vendored
2
.github/workflows/ui-tests.yml
vendored
|
|
@ -35,7 +35,7 @@ jobs:
|
|||
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
node-version: 14
|
||||
check-latest: true
|
||||
|
||||
- name: Add to Hosts
|
||||
|
|
|
|||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@ locale
|
|||
dist/
|
||||
# build/
|
||||
frappe/docs/current
|
||||
frappe/public/dist
|
||||
.vscode
|
||||
node_modules
|
||||
.kdev4/
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ context('Recorder', () => {
|
|||
cy.get('.result-list').should('contain', '/api/method/frappe.desk.reportview.get');
|
||||
});
|
||||
|
||||
it.only('Recorder View Request', () => {
|
||||
it('Recorder View Request', () => {
|
||||
cy.get('.primary-action').should('contain', 'Start').click();
|
||||
|
||||
cy.visit('/app/List/DocType/List');
|
||||
|
|
|
|||
486
esbuild/esbuild.js
Normal file
486
esbuild/esbuild.js
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
/* eslint-disable no-console */
|
||||
let path = require("path");
|
||||
let fs = require("fs");
|
||||
let glob = require("fast-glob");
|
||||
let esbuild = require("esbuild");
|
||||
let vue = require("esbuild-vue");
|
||||
let yargs = require("yargs");
|
||||
let cliui = require("cliui")();
|
||||
let chalk = require("chalk");
|
||||
let html_plugin = require("./frappe-html");
|
||||
let postCssPlugin = require("esbuild-plugin-postcss2").default;
|
||||
let ignore_assets = require("./ignore-assets");
|
||||
let sass_options = require("./sass_options");
|
||||
let {
|
||||
app_list,
|
||||
assets_path,
|
||||
apps_path,
|
||||
sites_path,
|
||||
get_app_path,
|
||||
get_public_path,
|
||||
log,
|
||||
log_warn,
|
||||
log_error,
|
||||
bench_path,
|
||||
get_redis_subscriber
|
||||
} = require("./utils");
|
||||
|
||||
let argv = yargs
|
||||
.usage("Usage: node esbuild [options]")
|
||||
.option("apps", {
|
||||
type: "string",
|
||||
description: "Run build for specific apps"
|
||||
})
|
||||
.option("skip_frappe", {
|
||||
type: "boolean",
|
||||
description: "Skip building frappe assets"
|
||||
})
|
||||
.option("files", {
|
||||
type: "string",
|
||||
description: "Run build for specified bundles"
|
||||
})
|
||||
.option("watch", {
|
||||
type: "boolean",
|
||||
description: "Run in watch mode and rebuild on file changes"
|
||||
})
|
||||
.option("production", {
|
||||
type: "boolean",
|
||||
description: "Run build in production mode"
|
||||
})
|
||||
.option("run-build-command", {
|
||||
type: "boolean",
|
||||
description: "Run build command for apps"
|
||||
})
|
||||
.example(
|
||||
"node esbuild --apps frappe,erpnext",
|
||||
"Run build only for frappe and erpnext"
|
||||
)
|
||||
.example(
|
||||
"node esbuild --files frappe/website.bundle.js,frappe/desk.bundle.js",
|
||||
"Run build only for specified bundles"
|
||||
)
|
||||
.version(false).argv;
|
||||
|
||||
const APPS = (!argv.apps ? app_list : argv.apps.split(",")).filter(
|
||||
app => !(argv.skip_frappe && app == "frappe")
|
||||
);
|
||||
const FILES_TO_BUILD = argv.files ? argv.files.split(",") : [];
|
||||
const WATCH_MODE = Boolean(argv.watch);
|
||||
const PRODUCTION = Boolean(argv.production);
|
||||
const RUN_BUILD_COMMAND = !WATCH_MODE && Boolean(argv["run-build-command"]);
|
||||
|
||||
const TOTAL_BUILD_TIME = `${chalk.black.bgGreen(" DONE ")} Total Build Time`;
|
||||
const NODE_PATHS = [].concat(
|
||||
// node_modules of apps directly importable
|
||||
app_list
|
||||
.map(app => path.resolve(get_app_path(app), "../node_modules"))
|
||||
.filter(fs.existsSync),
|
||||
// import js file of any app if you provide the full path
|
||||
app_list
|
||||
.map(app => path.resolve(get_app_path(app), ".."))
|
||||
.filter(fs.existsSync)
|
||||
);
|
||||
|
||||
execute()
|
||||
.then(() => RUN_BUILD_COMMAND && run_build_command_for_apps(APPS))
|
||||
.catch(e => console.error(e));
|
||||
|
||||
if (WATCH_MODE) {
|
||||
// listen for open files in editor event
|
||||
open_in_editor();
|
||||
}
|
||||
|
||||
async function execute() {
|
||||
console.time(TOTAL_BUILD_TIME);
|
||||
if (!FILES_TO_BUILD.length) {
|
||||
await clean_dist_folders(APPS);
|
||||
}
|
||||
|
||||
let result;
|
||||
try {
|
||||
result = await build_assets_for_apps(APPS, FILES_TO_BUILD);
|
||||
} catch (e) {
|
||||
log_error("There were some problems during build");
|
||||
log();
|
||||
log(chalk.dim(e.stack));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WATCH_MODE) {
|
||||
log_built_assets(result.metafile);
|
||||
console.timeEnd(TOTAL_BUILD_TIME);
|
||||
log();
|
||||
} else {
|
||||
log("Watching for changes...");
|
||||
}
|
||||
return await write_assets_json(result.metafile);
|
||||
}
|
||||
|
||||
function build_assets_for_apps(apps, files) {
|
||||
let { include_patterns, ignore_patterns } = files.length
|
||||
? get_files_to_build(files)
|
||||
: get_all_files_to_build(apps);
|
||||
|
||||
return glob(include_patterns, { ignore: ignore_patterns }).then(files => {
|
||||
let output_path = assets_path;
|
||||
|
||||
let file_map = {};
|
||||
for (let file of files) {
|
||||
let relative_app_path = path.relative(apps_path, file);
|
||||
let app = relative_app_path.split(path.sep)[0];
|
||||
|
||||
let extension = path.extname(file);
|
||||
let output_name = path.basename(file, extension);
|
||||
if (
|
||||
[".css", ".scss", ".less", ".sass", ".styl"].includes(extension)
|
||||
) {
|
||||
output_name = path.join("css", output_name);
|
||||
} else if ([".js", ".ts"].includes(extension)) {
|
||||
output_name = path.join("js", output_name);
|
||||
}
|
||||
output_name = path.join(app, "dist", output_name);
|
||||
|
||||
if (Object.keys(file_map).includes(output_name)) {
|
||||
log_warn(
|
||||
`Duplicate output file ${output_name} generated from ${file}`
|
||||
);
|
||||
}
|
||||
|
||||
file_map[output_name] = file;
|
||||
}
|
||||
|
||||
return build_files({
|
||||
files: file_map,
|
||||
outdir: output_path
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function get_all_files_to_build(apps) {
|
||||
let include_patterns = [];
|
||||
let ignore_patterns = [];
|
||||
|
||||
for (let app of apps) {
|
||||
let public_path = get_public_path(app);
|
||||
include_patterns.push(
|
||||
path.resolve(
|
||||
public_path,
|
||||
"**",
|
||||
"*.bundle.{js,ts,css,sass,scss,less,styl}"
|
||||
)
|
||||
);
|
||||
ignore_patterns.push(
|
||||
path.resolve(public_path, "node_modules"),
|
||||
path.resolve(public_path, "dist")
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
include_patterns,
|
||||
ignore_patterns
|
||||
};
|
||||
}
|
||||
|
||||
function get_files_to_build(files) {
|
||||
// files: ['frappe/website.bundle.js', 'erpnext/main.bundle.js']
|
||||
let include_patterns = [];
|
||||
let ignore_patterns = [];
|
||||
|
||||
for (let file of files) {
|
||||
let [app, bundle] = file.split("/");
|
||||
let public_path = get_public_path(app);
|
||||
include_patterns.push(path.resolve(public_path, "**", bundle));
|
||||
ignore_patterns.push(
|
||||
path.resolve(public_path, "node_modules"),
|
||||
path.resolve(public_path, "dist")
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
include_patterns,
|
||||
ignore_patterns
|
||||
};
|
||||
}
|
||||
|
||||
function build_files({ files, outdir }) {
|
||||
return esbuild.build({
|
||||
entryPoints: files,
|
||||
entryNames: "[dir]/[name].[hash]",
|
||||
outdir,
|
||||
sourcemap: true,
|
||||
bundle: true,
|
||||
metafile: true,
|
||||
minify: PRODUCTION,
|
||||
nodePaths: NODE_PATHS,
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
PRODUCTION ? "production" : "development"
|
||||
)
|
||||
},
|
||||
plugins: [
|
||||
html_plugin,
|
||||
ignore_assets,
|
||||
vue(),
|
||||
postCssPlugin({
|
||||
plugins: [require("autoprefixer")],
|
||||
sassOptions: sass_options
|
||||
})
|
||||
],
|
||||
watch: get_watch_config()
|
||||
});
|
||||
}
|
||||
|
||||
function get_watch_config() {
|
||||
if (WATCH_MODE) {
|
||||
return {
|
||||
async onRebuild(error, result) {
|
||||
if (error) {
|
||||
log_error("There was an error during rebuilding changes.");
|
||||
log();
|
||||
log(chalk.dim(error.stack));
|
||||
notify_redis({ error });
|
||||
} else {
|
||||
let {
|
||||
assets_json,
|
||||
prev_assets_json
|
||||
} = await write_assets_json(result.metafile);
|
||||
if (prev_assets_json) {
|
||||
log_rebuilt_assets(prev_assets_json, assets_json);
|
||||
}
|
||||
notify_redis({ success: true });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function clean_dist_folders(apps) {
|
||||
for (let app of apps) {
|
||||
let public_path = get_public_path(app);
|
||||
await fs.promises.rmdir(path.resolve(public_path, "dist", "js"), {
|
||||
recursive: true
|
||||
});
|
||||
await fs.promises.rmdir(path.resolve(public_path, "dist", "css"), {
|
||||
recursive: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function log_built_assets(metafile) {
|
||||
let column_widths = [60, 20];
|
||||
cliui.div(
|
||||
{
|
||||
text: chalk.cyan.bold("File"),
|
||||
width: column_widths[0]
|
||||
},
|
||||
{
|
||||
text: chalk.cyan.bold("Size"),
|
||||
width: column_widths[1]
|
||||
}
|
||||
);
|
||||
cliui.div("");
|
||||
|
||||
let output_by_dist_path = {};
|
||||
for (let outfile in metafile.outputs) {
|
||||
if (outfile.endsWith(".map")) continue;
|
||||
let data = metafile.outputs[outfile];
|
||||
outfile = path.resolve(outfile);
|
||||
outfile = path.relative(assets_path, outfile);
|
||||
let filename = path.basename(outfile);
|
||||
let dist_path = outfile.replace(filename, "");
|
||||
output_by_dist_path[dist_path] = output_by_dist_path[dist_path] || [];
|
||||
output_by_dist_path[dist_path].push({
|
||||
name: filename,
|
||||
size: (data.bytes / 1000).toFixed(2) + " Kb"
|
||||
});
|
||||
}
|
||||
|
||||
for (let dist_path in output_by_dist_path) {
|
||||
let files = output_by_dist_path[dist_path];
|
||||
cliui.div({
|
||||
text: dist_path,
|
||||
width: column_widths[0]
|
||||
});
|
||||
|
||||
for (let i in files) {
|
||||
let file = files[i];
|
||||
let branch = "";
|
||||
if (i < files.length - 1) {
|
||||
branch = "├─ ";
|
||||
} else {
|
||||
branch = "└─ ";
|
||||
}
|
||||
let color = file.name.endsWith(".js") ? "green" : "blue";
|
||||
cliui.div(
|
||||
{
|
||||
text: branch + chalk[color]("" + file.name),
|
||||
width: column_widths[0]
|
||||
},
|
||||
{
|
||||
text: file.size,
|
||||
width: column_widths[1]
|
||||
}
|
||||
);
|
||||
}
|
||||
cliui.div("");
|
||||
}
|
||||
log(cliui.toString());
|
||||
}
|
||||
|
||||
// to store previous build's assets.json for comparison
|
||||
let prev_assets_json;
|
||||
let curr_assets_json;
|
||||
|
||||
async function write_assets_json(metafile) {
|
||||
prev_assets_json = curr_assets_json;
|
||||
let out = {};
|
||||
for (let output in metafile.outputs) {
|
||||
let info = metafile.outputs[output];
|
||||
let asset_path = "/" + path.relative(sites_path, output);
|
||||
if (info.entryPoint) {
|
||||
out[path.basename(info.entryPoint)] = asset_path;
|
||||
}
|
||||
}
|
||||
|
||||
let assets_json_path = path.resolve(
|
||||
assets_path,
|
||||
"frappe",
|
||||
"dist",
|
||||
"assets.json"
|
||||
);
|
||||
let assets_json;
|
||||
try {
|
||||
assets_json = await fs.promises.readFile(assets_json_path, "utf-8");
|
||||
} catch (error) {
|
||||
assets_json = "{}";
|
||||
}
|
||||
assets_json = JSON.parse(assets_json);
|
||||
// update with new values
|
||||
assets_json = Object.assign({}, assets_json, out);
|
||||
curr_assets_json = assets_json;
|
||||
|
||||
await fs.promises.writeFile(
|
||||
assets_json_path,
|
||||
JSON.stringify(assets_json, null, 4)
|
||||
);
|
||||
await update_assets_json_in_cache(assets_json);
|
||||
return {
|
||||
assets_json,
|
||||
prev_assets_json
|
||||
};
|
||||
}
|
||||
|
||||
function update_assets_json_in_cache(assets_json) {
|
||||
// update assets_json cache in redis, so that it can be read directly by python
|
||||
return new Promise(resolve => {
|
||||
let client = get_redis_subscriber("redis_cache");
|
||||
// handle error event to avoid printing stack traces
|
||||
client.on("error", _ => {
|
||||
log_warn("Cannot connect to redis_cache to update assets_json");
|
||||
});
|
||||
client.set("assets_json", JSON.stringify(assets_json), err => {
|
||||
client.unref();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function run_build_command_for_apps(apps) {
|
||||
let cwd = process.cwd();
|
||||
let { execSync } = require("child_process");
|
||||
|
||||
for (let app of apps) {
|
||||
if (app === "frappe") continue;
|
||||
|
||||
let root_app_path = path.resolve(get_app_path(app), "..");
|
||||
let package_json = path.resolve(root_app_path, "package.json");
|
||||
if (fs.existsSync(package_json)) {
|
||||
let { scripts } = require(package_json);
|
||||
if (scripts && scripts.build) {
|
||||
log("\nRunning build command for", chalk.bold(app));
|
||||
process.chdir(root_app_path);
|
||||
execSync("yarn build", { encoding: "utf8", stdio: "inherit" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process.chdir(cwd);
|
||||
}
|
||||
|
||||
async function notify_redis({ error, success }) {
|
||||
// notify redis which in turns tells socketio to publish this to browser
|
||||
let subscriber = get_redis_subscriber("redis_socketio");
|
||||
subscriber.on("error", _ => {
|
||||
log_warn("Cannot connect to redis_socketio for browser events");
|
||||
});
|
||||
|
||||
let payload = null;
|
||||
if (error) {
|
||||
let formatted = await esbuild.formatMessages(error.errors, {
|
||||
kind: "error",
|
||||
terminalWidth: 100
|
||||
});
|
||||
let stack = error.stack.replace(new RegExp(bench_path, "g"), "");
|
||||
payload = {
|
||||
error,
|
||||
formatted,
|
||||
stack
|
||||
};
|
||||
}
|
||||
if (success) {
|
||||
payload = {
|
||||
success: true
|
||||
};
|
||||
}
|
||||
|
||||
subscriber.publish(
|
||||
"events",
|
||||
JSON.stringify({
|
||||
event: "build_event",
|
||||
message: payload
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function open_in_editor() {
|
||||
let subscriber = get_redis_subscriber("redis_socketio");
|
||||
subscriber.on("error", _ => {
|
||||
log_warn("Cannot connect to redis_socketio for open_in_editor events");
|
||||
});
|
||||
subscriber.on("message", (event, file) => {
|
||||
if (event === "open_in_editor") {
|
||||
file = JSON.parse(file);
|
||||
let file_path = path.resolve(file.file);
|
||||
log("Opening file in editor:", file_path);
|
||||
let launch = require("launch-editor");
|
||||
launch(`${file_path}:${file.line}:${file.column}`);
|
||||
}
|
||||
});
|
||||
subscriber.subscribe("open_in_editor");
|
||||
}
|
||||
|
||||
function log_rebuilt_assets(prev_assets, new_assets) {
|
||||
let added_files = [];
|
||||
let old_files = Object.values(prev_assets);
|
||||
let new_files = Object.values(new_assets);
|
||||
|
||||
for (let filepath of new_files) {
|
||||
if (!old_files.includes(filepath)) {
|
||||
added_files.push(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
log(
|
||||
chalk.yellow(
|
||||
`${new Date().toLocaleTimeString()}: Compiled ${
|
||||
added_files.length
|
||||
} files...`
|
||||
)
|
||||
);
|
||||
for (let filepath of added_files) {
|
||||
let filename = path.basename(filepath);
|
||||
log(" " + filename);
|
||||
}
|
||||
log();
|
||||
}
|
||||
43
esbuild/frappe-html.js
Normal file
43
esbuild/frappe-html.js
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
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(/`/g, "\\`");
|
||||
return content;
|
||||
}
|
||||
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
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
1
esbuild/index.js
Normal file
1
esbuild/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
require("./esbuild");
|
||||
29
esbuild/sass_options.js
Normal file
29
esbuild/sass_options.js
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
let path = require("path");
|
||||
let { get_app_path, app_list } = require("./utils");
|
||||
|
||||
let node_modules_path = path.resolve(
|
||||
get_app_path("frappe"),
|
||||
"..",
|
||||
"node_modules"
|
||||
);
|
||||
let app_paths = app_list
|
||||
.map(get_app_path)
|
||||
.map(app_path => path.resolve(app_path, ".."));
|
||||
|
||||
module.exports = {
|
||||
includePaths: [node_modules_path, ...app_paths],
|
||||
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
|
||||
};
|
||||
}
|
||||
};
|
||||
145
esbuild/utils.js
Normal file
145
esbuild/utils.js
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const chalk = require("chalk");
|
||||
|
||||
const frappe_path = path.resolve(__dirname, "..");
|
||||
const bench_path = path.resolve(frappe_path, "..", "..");
|
||||
const sites_path = path.resolve(bench_path, "sites");
|
||||
const apps_path = path.resolve(bench_path, "apps");
|
||||
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(apps_path, 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];
|
||||
|
||||
function get_apps_list() {
|
||||
return fs
|
||||
.readFileSync(path.resolve(sites_path, "apps.txt"), {
|
||||
encoding: "utf-8"
|
||||
})
|
||||
.split("\n")
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function get_cli_arg(name) {
|
||||
let args = process.argv.slice(2);
|
||||
let arg = `--${name}`;
|
||||
let index = args.indexOf(arg);
|
||||
|
||||
let value = null;
|
||||
if (index != -1) {
|
||||
value = true;
|
||||
}
|
||||
if (value && args[index + 1]) {
|
||||
value = args[index + 1];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function log_error(message, badge = "ERROR") {
|
||||
badge = chalk.white.bgRed(` ${badge} `);
|
||||
console.error(`${badge} ${message}`); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
function log_warn(message, badge = "WARN") {
|
||||
badge = chalk.black.bgYellowBright(` ${badge} `);
|
||||
console.warn(`${badge} ${message}`); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
function log(...args) {
|
||||
console.log(...args); // eslint-disable-line no-console
|
||||
}
|
||||
|
||||
function get_redis_subscriber(kind) {
|
||||
// get redis subscriber that aborts after 10 connection attempts
|
||||
let { get_redis_subscriber: get_redis } = require("../node_utils");
|
||||
return get_redis(kind, {
|
||||
retry_strategy: function(options) {
|
||||
// abort after 10 connection attempts
|
||||
if (options.attempt > 10) {
|
||||
return undefined;
|
||||
}
|
||||
return Math.min(options.attempt * 100, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
app_list,
|
||||
bench_path,
|
||||
assets_path,
|
||||
sites_path,
|
||||
apps_path,
|
||||
bundle_map,
|
||||
get_public_path,
|
||||
get_build_json_path,
|
||||
get_build_json,
|
||||
get_app_path,
|
||||
delete_file,
|
||||
run_serially,
|
||||
get_cli_arg,
|
||||
log,
|
||||
log_warn,
|
||||
log_error,
|
||||
get_redis_subscriber
|
||||
};
|
||||
|
|
@ -5,6 +5,7 @@ import os
|
|||
import re
|
||||
import json
|
||||
import shutil
|
||||
import subprocess
|
||||
from tempfile import mkdtemp, mktemp
|
||||
from distutils.spawn import find_executable
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ import click
|
|||
import psutil
|
||||
from urllib.parse import urlparse
|
||||
from simple_chalk import green
|
||||
from semantic_version import Version
|
||||
|
||||
|
||||
timestamps = {}
|
||||
|
|
@ -36,35 +38,36 @@ def download_file(url, prefix):
|
|||
|
||||
|
||||
def build_missing_files():
|
||||
# check which files dont exist yet from the build.json and tell build.js to build only those!
|
||||
'''Check which files dont exist yet from the assets.json and run build for those files'''
|
||||
|
||||
missing_assets = []
|
||||
current_asset_files = []
|
||||
frappe_build = os.path.join("..", "apps", "frappe", "frappe", "public", "build.json")
|
||||
|
||||
for type in ["css", "js"]:
|
||||
current_asset_files.extend(
|
||||
[
|
||||
"{0}/{1}".format(type, name)
|
||||
for name in os.listdir(os.path.join(sites_path, "assets", type))
|
||||
]
|
||||
)
|
||||
folder = os.path.join(sites_path, "assets", "frappe", "dist", type)
|
||||
current_asset_files.extend(os.listdir(folder))
|
||||
|
||||
with open(frappe_build) as f:
|
||||
all_asset_files = json.load(f).keys()
|
||||
development = frappe.local.conf.developer_mode or frappe.local.dev_server
|
||||
build_mode = "development" if development else "production"
|
||||
|
||||
for asset in all_asset_files:
|
||||
if asset.replace("concat:", "") not in current_asset_files:
|
||||
missing_assets.append(asset)
|
||||
assets_json = frappe.read_file(frappe.get_app_path('frappe', 'public', 'dist', 'assets.json'))
|
||||
if assets_json:
|
||||
assets_json = frappe.parse_json(assets_json)
|
||||
|
||||
if missing_assets:
|
||||
from subprocess import check_call
|
||||
from shlex import split
|
||||
for bundle_file, output_file in assets_json.items():
|
||||
if not output_file.startswith('/assets/frappe'):
|
||||
continue
|
||||
|
||||
click.secho("\nBuilding missing assets...\n", fg="yellow")
|
||||
command = split(
|
||||
"node rollup/build.js --files {0} --no-concat".format(",".join(missing_assets))
|
||||
)
|
||||
check_call(command, cwd=os.path.join("..", "apps", "frappe"))
|
||||
if os.path.basename(output_file) not in current_asset_files:
|
||||
missing_assets.append(bundle_file)
|
||||
|
||||
if missing_assets:
|
||||
click.secho("\nBuilding missing assets...\n", fg="yellow")
|
||||
files_to_build = ["frappe/" + name for name in missing_assets]
|
||||
bundle(build_mode, files=files_to_build)
|
||||
else:
|
||||
# no assets.json, run full build
|
||||
bundle(build_mode, apps="frappe")
|
||||
|
||||
|
||||
def get_assets_link(frappe_head):
|
||||
|
|
@ -200,49 +203,51 @@ def setup():
|
|||
assets_path = os.path.join(frappe.local.sites_path, "assets")
|
||||
|
||||
|
||||
def get_node_pacman():
|
||||
exec_ = find_executable("yarn")
|
||||
if exec_:
|
||||
return exec_
|
||||
raise ValueError("Yarn not found")
|
||||
|
||||
|
||||
def bundle(no_compress, app=None, hard_link=False, verbose=False, skip_frappe=False):
|
||||
def bundle(mode, apps=None, hard_link=False, make_copy=False, restore=False, verbose=False, skip_frappe=False, files=None):
|
||||
"""concat / minify js files"""
|
||||
setup()
|
||||
make_asset_dirs(hard_link=hard_link)
|
||||
|
||||
pacman = get_node_pacman()
|
||||
mode = "build" if no_compress else "production"
|
||||
command = "{pacman} run {mode}".format(pacman=pacman, mode=mode)
|
||||
mode = "production" if mode == "production" else "build"
|
||||
command = "yarn run {mode}".format(mode=mode)
|
||||
|
||||
if app:
|
||||
command += " --app {app}".format(app=app)
|
||||
if apps:
|
||||
command += " --apps {apps}".format(apps=apps)
|
||||
|
||||
if skip_frappe:
|
||||
command += " --skip_frappe"
|
||||
|
||||
frappe_app_path = os.path.abspath(os.path.join(app_paths[0], ".."))
|
||||
check_yarn()
|
||||
if files:
|
||||
command += " --files {files}".format(files=','.join(files))
|
||||
|
||||
command += " --run-build-command"
|
||||
|
||||
check_node_executable()
|
||||
frappe_app_path = frappe.get_app_path("frappe", "..")
|
||||
frappe.commands.popen(command, cwd=frappe_app_path, env=get_node_env())
|
||||
|
||||
|
||||
def watch(no_compress):
|
||||
def watch(apps=None):
|
||||
"""watch and rebuild if necessary"""
|
||||
setup()
|
||||
|
||||
pacman = get_node_pacman()
|
||||
command = "yarn run watch"
|
||||
if apps:
|
||||
command += " --apps {apps}".format(apps=apps)
|
||||
|
||||
frappe_app_path = os.path.abspath(os.path.join(app_paths[0], ".."))
|
||||
check_yarn()
|
||||
check_node_executable()
|
||||
frappe_app_path = frappe.get_app_path("frappe", "..")
|
||||
frappe.commands.popen("{pacman} run watch".format(pacman=pacman),
|
||||
cwd=frappe_app_path, env=get_node_env())
|
||||
frappe.commands.popen(command, cwd=frappe_app_path, env=get_node_env())
|
||||
|
||||
|
||||
def check_yarn():
|
||||
def check_node_executable():
|
||||
node_version = Version(subprocess.getoutput('node -v')[1:])
|
||||
warn = '⚠️ '
|
||||
if node_version.major < 14:
|
||||
click.echo(f"{warn} Please update your node version to 14")
|
||||
if not find_executable("yarn"):
|
||||
print("Please install yarn using below command and try again.\nnpm install -g yarn")
|
||||
click.echo(f"{warn} Please install yarn using below command and try again.\nnpm install -g yarn")
|
||||
click.echo()
|
||||
|
||||
def get_node_env():
|
||||
node_env = {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ common_default_keys = ["__default", "__global"]
|
|||
doctype_map_keys = ('energy_point_rule_map', 'assignment_rule_map',
|
||||
'milestone_tracker_map', 'event_consumer_document_type_map')
|
||||
|
||||
bench_cache_keys = ('assets_json',)
|
||||
|
||||
global_cache_keys = ("app_hooks", "installed_apps", 'all_apps',
|
||||
"app_modules", "module_app", "system_settings",
|
||||
'scheduler_events', 'time_zone', 'webhooks', 'active_domains',
|
||||
|
|
@ -58,6 +60,7 @@ def clear_global_cache():
|
|||
clear_doctype_cache()
|
||||
clear_website_cache()
|
||||
frappe.cache().delete_value(global_cache_keys)
|
||||
frappe.cache().delete_value(bench_cache_keys)
|
||||
frappe.setup_module_map()
|
||||
|
||||
def clear_defaults_cache(user=None):
|
||||
|
|
|
|||
|
|
@ -16,24 +16,34 @@ from frappe.utils import get_bench_path, update_progress_bar, cint
|
|||
|
||||
@click.command('build')
|
||||
@click.option('--app', help='Build assets for app')
|
||||
@click.option('--apps', help='Build assets for specific apps')
|
||||
@click.option('--hard-link', is_flag=True, default=False, help='Copy the files instead of symlinking')
|
||||
@click.option('--make-copy', is_flag=True, default=False, help='[DEPRECATED] Copy the files instead of symlinking')
|
||||
@click.option('--restore', is_flag=True, default=False, help='[DEPRECATED] Copy the files instead of symlinking with force')
|
||||
@click.option('--production', is_flag=True, default=False, help='Build assets in production mode')
|
||||
@click.option('--verbose', is_flag=True, default=False, help='Verbose')
|
||||
@click.option('--force', is_flag=True, default=False, help='Force build assets instead of downloading available')
|
||||
def build(app=None, hard_link=False, make_copy=False, restore=False, verbose=False, force=False):
|
||||
"Minify + concatenate JS and CSS files, build translations"
|
||||
def build(app=None, apps=None, hard_link=False, make_copy=False, restore=False, production=False, verbose=False, force=False):
|
||||
"Compile JS and CSS source files"
|
||||
from frappe.build import bundle, download_frappe_assets
|
||||
frappe.init('')
|
||||
# don't minify in developer_mode for faster builds
|
||||
no_compress = frappe.local.conf.developer_mode or False
|
||||
|
||||
if not apps and app:
|
||||
apps = app
|
||||
|
||||
# dont try downloading assets if force used, app specified or running via CI
|
||||
if not (force or app or os.environ.get('CI')):
|
||||
if not (force or apps or os.environ.get('CI')):
|
||||
# skip building frappe if assets exist remotely
|
||||
skip_frappe = frappe.build.download_frappe_assets(verbose=verbose)
|
||||
skip_frappe = download_frappe_assets(verbose=verbose)
|
||||
else:
|
||||
skip_frappe = False
|
||||
|
||||
# don't minify in developer_mode for faster builds
|
||||
development = frappe.local.conf.developer_mode or frappe.local.dev_server
|
||||
mode = "development" if development else "production"
|
||||
if production:
|
||||
mode = "production"
|
||||
|
||||
if make_copy or restore:
|
||||
hard_link = make_copy or restore
|
||||
click.secho(
|
||||
|
|
@ -41,21 +51,17 @@ def build(app=None, hard_link=False, make_copy=False, restore=False, verbose=Fal
|
|||
fg="yellow",
|
||||
)
|
||||
|
||||
frappe.build.bundle(
|
||||
skip_frappe=skip_frappe,
|
||||
no_compress=no_compress,
|
||||
hard_link=hard_link,
|
||||
verbose=verbose,
|
||||
app=app,
|
||||
)
|
||||
bundle(mode, apps=apps, hard_link=hard_link, verbose=verbose, skip_frappe=skip_frappe)
|
||||
|
||||
|
||||
|
||||
@click.command('watch')
|
||||
def watch():
|
||||
"Watch and concatenate JS and CSS files as and when they change"
|
||||
import frappe.build
|
||||
@click.option('--apps', help='Watch assets for specific apps')
|
||||
def watch(apps=None):
|
||||
"Watch and compile JS and CSS files as and when they change"
|
||||
from frappe.build import watch
|
||||
frappe.init('')
|
||||
frappe.build.watch(True)
|
||||
watch(apps)
|
||||
|
||||
|
||||
@click.command('clear-cache')
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ frappe.ui.form.on('Data Import', {
|
|||
},
|
||||
|
||||
download_template(frm) {
|
||||
frappe.require('/assets/js/data_import_tools.min.js', () => {
|
||||
frappe.require('data_import_tools.bundle.js', () => {
|
||||
frm.data_exporter = new frappe.data_import.DataExporter(
|
||||
frm.doc.reference_doctype,
|
||||
frm.doc.import_type
|
||||
|
|
@ -287,7 +287,7 @@ frappe.ui.form.on('Data Import', {
|
|||
return;
|
||||
}
|
||||
|
||||
frappe.require('/assets/js/data_import_tools.min.js', () => {
|
||||
frappe.require('data_import_tools.bundle.js', () => {
|
||||
frm.import_preview = new frappe.data_import.ImportPreview({
|
||||
wrapper: frm.get_field('import_preview').$wrapper,
|
||||
doctype: frm.doc.reference_doctype,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ frappe.pages['recorder'].on_page_load = function(wrapper) {
|
|||
frappe.recorder.show();
|
||||
});
|
||||
|
||||
frappe.require('/assets/js/frappe-recorder.min.js');
|
||||
frappe.require('recorder.bundle.js');
|
||||
};
|
||||
|
||||
class Recorder {
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ frappe.pages['activity'].on_page_show = function () {
|
|||
}
|
||||
|
||||
frappe.activity.last_feed_date = false;
|
||||
frappe.activity.Feed = Class.extend({
|
||||
init: function (row, data) {
|
||||
frappe.activity.Feed = class Feed {
|
||||
constructor(row, data) {
|
||||
this.scrub_data(data);
|
||||
this.add_date_separator(row, data);
|
||||
if (!data.add_class)
|
||||
|
|
@ -97,8 +97,9 @@ frappe.activity.Feed = Class.extend({
|
|||
$(row)
|
||||
.append(frappe.render_template("activity_row", data))
|
||||
.find("a").addClass("grey");
|
||||
},
|
||||
scrub_data: function (data) {
|
||||
}
|
||||
|
||||
scrub_data(data) {
|
||||
data.by = frappe.user.full_name(data.owner);
|
||||
data.avatar = frappe.avatar(data.owner);
|
||||
|
||||
|
|
@ -113,9 +114,9 @@ frappe.activity.Feed = Class.extend({
|
|||
|
||||
data.when = comment_when(data.creation);
|
||||
data.feed_type = data.comment_type || data.communication_medium;
|
||||
},
|
||||
}
|
||||
|
||||
add_date_separator: function (row, data) {
|
||||
add_date_separator(row, data) {
|
||||
var date = frappe.datetime.str_to_obj(data.creation);
|
||||
var last = frappe.activity.last_feed_date;
|
||||
|
||||
|
|
@ -137,7 +138,7 @@ frappe.activity.Feed = Class.extend({
|
|||
}
|
||||
frappe.activity.last_feed_date = date;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.activity.render_heatmap = function (page) {
|
||||
$('<div class="heatmap-container" style="text-align:center">\
|
||||
|
|
|
|||
|
|
@ -292,18 +292,12 @@ def inline_style_in_html(html):
|
|||
''' Convert email.css and html to inline-styled html
|
||||
'''
|
||||
from premailer import Premailer
|
||||
from frappe.utils.jinja_globals import bundled_asset
|
||||
|
||||
apps = frappe.get_installed_apps()
|
||||
|
||||
# add frappe email css file
|
||||
css_files = ['assets/css/email.css']
|
||||
if 'frappe' in apps:
|
||||
apps.remove('frappe')
|
||||
|
||||
for app in apps:
|
||||
path = 'assets/{0}/css/email.css'.format(app)
|
||||
css_files.append(path)
|
||||
|
||||
# get email css files from hooks
|
||||
css_files = frappe.get_hooks('email_css')
|
||||
css_files = [bundled_asset(path) for path in css_files]
|
||||
css_files = [path.lstrip('/') for path in css_files]
|
||||
css_files = [css_file for css_file in css_files if os.path.exists(os.path.abspath(css_file))]
|
||||
|
||||
p = Premailer(html=html, external_styles=css_files, strip_important=False)
|
||||
|
|
|
|||
|
|
@ -29,16 +29,16 @@ 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",
|
||||
"libs.bundle.js",
|
||||
"desk.bundle.js",
|
||||
"list.bundle.js",
|
||||
"form.bundle.js",
|
||||
"controls.bundle.js",
|
||||
"report.bundle.js",
|
||||
]
|
||||
app_include_css = [
|
||||
"/assets/css/desk.min.css",
|
||||
"/assets/css/report.min.css",
|
||||
"desk.bundle.css",
|
||||
"report.bundle.css",
|
||||
]
|
||||
|
||||
doctype_js = {
|
||||
|
|
@ -52,6 +52,8 @@ web_include_js = [
|
|||
|
||||
web_include_css = []
|
||||
|
||||
email_css = ['email.bundle.css']
|
||||
|
||||
website_route_rules = [
|
||||
{"from_route": "/blog/<category>", "to_route": "Blog Post"},
|
||||
{"from_route": "/kb/<category>", "to_route": "Help Article"},
|
||||
|
|
|
|||
|
|
@ -408,14 +408,17 @@ frappe.ui.form.PrintView = class {
|
|||
|
||||
setup_print_format_dom(out, $print_format) {
|
||||
this.print_wrapper.find('.print-format-skeleton').remove();
|
||||
let base_url = frappe.urllib.get_base_url();
|
||||
let print_css = frappe.assets.bundled_asset('print.bundle.css');
|
||||
this.$print_format_body.find('head').html(
|
||||
`<style type="text/css">${out.style}</style>
|
||||
<link href="${frappe.urllib.get_base_url()}/assets/css/printview.css" rel="stylesheet">`
|
||||
<link href="${base_url}${print_css}" rel="stylesheet">`
|
||||
);
|
||||
|
||||
if (frappe.utils.is_rtl(this.lang_code)) {
|
||||
let rtl_css = frappe.assets.bundled_asset('frappe-rtl.bundle.css');
|
||||
this.$print_format_body.find('head').append(
|
||||
`<link type="text/css" rel="stylesheet" href="${frappe.urllib.get_base_url()}/assets/css/frappe-rtl.css"></link>`
|
||||
`<link type="text/css" rel="stylesheet" href="${base_url}${rtl_css}"></link>`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ frappe.pages['print-format-builder'].on_page_show = function(wrapper) {
|
|||
}
|
||||
}
|
||||
|
||||
frappe.PrintFormatBuilder = Class.extend({
|
||||
init: function(parent) {
|
||||
frappe.PrintFormatBuilder = class PrintFormatBuilder {
|
||||
constructor(parent) {
|
||||
this.parent = parent;
|
||||
this.make();
|
||||
this.refresh();
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
this.custom_html_count = 0;
|
||||
if(!this.print_format) {
|
||||
this.show_start();
|
||||
|
|
@ -37,8 +37,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
this.page.set_title(this.print_format.name);
|
||||
this.setup_print_format();
|
||||
}
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
this.page = frappe.ui.make_app_page({
|
||||
parent: this.parent,
|
||||
title: __("Print Format Builder"),
|
||||
|
|
@ -56,15 +56,15 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
this.setup_edit_custom_html();
|
||||
// $(this.page.sidebar).css({"position": 'fixed'});
|
||||
// $(this.page.main).parent().css({"margin-left": '16.67%'});
|
||||
},
|
||||
show_start: function() {
|
||||
}
|
||||
show_start() {
|
||||
this.page.main.html(frappe.render_template("print_format_builder_start", {}));
|
||||
this.page.clear_actions();
|
||||
this.page.set_title(__("Print Format Builder"));
|
||||
this.start_edit_print_format();
|
||||
this.start_new_print_format();
|
||||
},
|
||||
start_edit_print_format: function() {
|
||||
}
|
||||
start_edit_print_format() {
|
||||
// print format control
|
||||
var me = this;
|
||||
this.print_format_input = frappe.ui.form.make_control({
|
||||
|
|
@ -89,8 +89,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
frappe.set_route('print-format-builder', name);
|
||||
});
|
||||
});
|
||||
},
|
||||
start_new_print_format: function() {
|
||||
}
|
||||
start_new_print_format() {
|
||||
var me = this;
|
||||
this.doctype_input = frappe.ui.form.make_control({
|
||||
parent: this.page.main.find(".doctype-selector"),
|
||||
|
|
@ -125,8 +125,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
me.setup_new_print_format(doctype, name);
|
||||
|
||||
});
|
||||
},
|
||||
setup_new_print_format: function(doctype, name, based_on) {
|
||||
}
|
||||
setup_new_print_format(doctype, name, based_on) {
|
||||
frappe.call({
|
||||
method: 'frappe.printing.page.print_format_builder.print_format_builder.create_custom_format',
|
||||
args: {
|
||||
|
|
@ -143,8 +143,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
setup_print_format: function() {
|
||||
}
|
||||
setup_print_format() {
|
||||
var me = this;
|
||||
frappe.model.with_doctype(this.print_format.doc_type, function(doctype) {
|
||||
me.meta = frappe.get_meta(me.print_format.doc_type);
|
||||
|
|
@ -163,23 +163,23 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
frappe.set_route("Form", "Print Format", me.print_format.name);
|
||||
});
|
||||
});
|
||||
},
|
||||
setup_sidebar: function() {
|
||||
}
|
||||
setup_sidebar() {
|
||||
// prepend custom HTML field
|
||||
var fields = [this.get_custom_html_field()].concat(this.meta.fields);
|
||||
this.page.sidebar.html(
|
||||
$(frappe.render_template("print_format_builder_sidebar", {fields: fields}))
|
||||
);
|
||||
this.setup_field_filter();
|
||||
},
|
||||
get_custom_html_field: function() {
|
||||
}
|
||||
get_custom_html_field() {
|
||||
return {
|
||||
fieldtype: "Custom HTML",
|
||||
fieldname: "_custom_html",
|
||||
label: __("Custom HTML")
|
||||
}
|
||||
},
|
||||
render_layout: function() {
|
||||
};
|
||||
}
|
||||
render_layout() {
|
||||
this.page.main.empty();
|
||||
this.prepare_data();
|
||||
$(frappe.render_template("print_format_builder_layout", {
|
||||
|
|
@ -190,8 +190,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
this.setup_edit_heading();
|
||||
this.setup_field_settings();
|
||||
this.setup_html_data();
|
||||
},
|
||||
prepare_data: function() {
|
||||
}
|
||||
prepare_data() {
|
||||
this.print_heading_template = null;
|
||||
this.data = JSON.parse(this.print_format.format_data || "[]");
|
||||
if(!this.data.length) {
|
||||
|
|
@ -280,22 +280,22 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
this.layout_data = $.map(this.layout_data, function(s) {
|
||||
return s.has_fields ? s : null
|
||||
});
|
||||
},
|
||||
get_new_section: function() {
|
||||
}
|
||||
get_new_section() {
|
||||
return {columns: [], no_of_columns: 0, label:''};
|
||||
},
|
||||
get_new_column: function() {
|
||||
}
|
||||
get_new_column() {
|
||||
return {fields: []}
|
||||
},
|
||||
add_table_properties: function(f) {
|
||||
}
|
||||
add_table_properties(f) {
|
||||
// build table columns and widths in a dict
|
||||
// visible_columns
|
||||
var me = this;
|
||||
if(!f.visible_columns) {
|
||||
me.init_visible_columns(f);
|
||||
}
|
||||
},
|
||||
init_visible_columns: function(f) {
|
||||
}
|
||||
init_visible_columns(f) {
|
||||
f.visible_columns = []
|
||||
$.each(frappe.get_meta(f.options).fields, function(i, _f) {
|
||||
if(!in_list(["Section Break", "Column Break"], _f.fieldtype) &&
|
||||
|
|
@ -306,8 +306,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
print_width: (_f.width || ""), print_hide:0});
|
||||
}
|
||||
});
|
||||
},
|
||||
setup_sortable: function() {
|
||||
}
|
||||
setup_sortable() {
|
||||
var me = this;
|
||||
|
||||
// drag from fields library
|
||||
|
|
@ -332,8 +332,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
Sortable.create(this.page.main.find(".print-format-builder-layout").get(0),
|
||||
{ handle: ".print-format-builder-section-head" }
|
||||
);
|
||||
},
|
||||
setup_sortable_for_column: function(col) {
|
||||
}
|
||||
setup_sortable_for_column(col) {
|
||||
var me = this;
|
||||
Sortable.create(col, {
|
||||
group: {
|
||||
|
|
@ -363,8 +363,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
},
|
||||
setup_field_filter: function() {
|
||||
}
|
||||
setup_field_filter() {
|
||||
var me = this;
|
||||
this.page.sidebar.find(".filter-fields").on("keyup", function() {
|
||||
var text = $(this).val();
|
||||
|
|
@ -373,8 +373,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
$(this).parent().toggle(show);
|
||||
})
|
||||
});
|
||||
},
|
||||
setup_section_settings: function() {
|
||||
}
|
||||
setup_section_settings() {
|
||||
var me = this;
|
||||
this.page.main.on("click", ".section-settings", function() {
|
||||
var section = $(this).parent().parent();
|
||||
|
|
@ -431,8 +431,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
setup_field_settings: function() {
|
||||
}
|
||||
setup_field_settings() {
|
||||
this.page.main.find(".field-settings").on("click", e => {
|
||||
const field = $(e.currentTarget).parent();
|
||||
// new dialog
|
||||
|
|
@ -482,8 +482,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
setup_html_data: function() {
|
||||
}
|
||||
setup_html_data() {
|
||||
// set JQuery `data` for Custom HTML fields, since editing the HTML
|
||||
// directly causes problem becuase of HTML reformatting
|
||||
//
|
||||
|
|
@ -496,8 +496,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
var html = me.custom_html_dict[parseInt(content.attr('data-custom-html-id'))].options;
|
||||
content.data('content', html);
|
||||
})
|
||||
},
|
||||
update_columns_in_section: function(section, no_of_columns, new_no_of_columns) {
|
||||
}
|
||||
update_columns_in_section(section, no_of_columns, new_no_of_columns) {
|
||||
var col_size = 12 / new_no_of_columns,
|
||||
me = this,
|
||||
resize = function() {
|
||||
|
|
@ -539,8 +539,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
resize();
|
||||
}
|
||||
|
||||
},
|
||||
setup_add_section: function() {
|
||||
}
|
||||
setup_add_section() {
|
||||
var me = this;
|
||||
this.page.main.find(".print-format-builder-add-section").on("click", function() {
|
||||
// boostrap new section info
|
||||
|
|
@ -554,8 +554,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
|
||||
me.setup_sortable_for_column($section.find(".print-format-builder-column").get(0));
|
||||
});
|
||||
},
|
||||
setup_edit_heading: function() {
|
||||
}
|
||||
setup_edit_heading() {
|
||||
var me = this;
|
||||
var $heading = this.page.main.find(".print-format-builder-print-heading");
|
||||
|
||||
|
|
@ -565,8 +565,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
this.page.main.find(".edit-heading").on("click", function() {
|
||||
var d = me.get_edit_html_dialog(__("Edit Heading"), __("Heading"), $heading);
|
||||
})
|
||||
},
|
||||
setup_column_selector: function() {
|
||||
}
|
||||
setup_column_selector() {
|
||||
var me = this;
|
||||
this.page.main.on("click", ".select-columns", function() {
|
||||
var parent = $(this).parents(".print-format-builder-field:first"),
|
||||
|
|
@ -657,24 +657,24 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
|
||||
return false;
|
||||
});
|
||||
},
|
||||
get_visible_columns_string: function(f) {
|
||||
}
|
||||
get_visible_columns_string(f) {
|
||||
if(!f.visible_columns) {
|
||||
this.init_visible_columns(f);
|
||||
}
|
||||
return $.map(f.visible_columns, function(v) { return v.fieldname + "|" + (v.print_width || "") }).join(",");
|
||||
},
|
||||
get_no_content: function() {
|
||||
}
|
||||
get_no_content() {
|
||||
return __("Edit to add content")
|
||||
},
|
||||
setup_edit_custom_html: function() {
|
||||
}
|
||||
setup_edit_custom_html() {
|
||||
var me = this;
|
||||
this.page.main.on("click", ".edit-html", function() {
|
||||
me.get_edit_html_dialog(__("Edit Custom HTML"), __("Custom HTML"),
|
||||
$(this).parents(".print-format-builder-field:first").find(".html-content"));
|
||||
});
|
||||
},
|
||||
get_edit_html_dialog: function(title, label, $content) {
|
||||
}
|
||||
get_edit_html_dialog(title, label, $content) {
|
||||
var me = this;
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: title,
|
||||
|
|
@ -710,8 +710,8 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
d.show();
|
||||
|
||||
return d;
|
||||
},
|
||||
save_print_format: function() {
|
||||
}
|
||||
save_print_format() {
|
||||
var data = [],
|
||||
me = this;
|
||||
|
||||
|
|
@ -789,4 +789,4 @@ frappe.PrintFormatBuilder = Class.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
<title>{{ title }}</title>
|
||||
<link href="{{ base_url }}/assets/css/printview.css" rel="stylesheet">
|
||||
<link href="{{ base_url }}{{ frappe.assets.bundled_asset('print.bundle.css') }}" rel="stylesheet">
|
||||
<style>
|
||||
{{ print_css }}
|
||||
</style>
|
||||
|
|
|
|||
1
frappe/public/js/barcode_scanner.bundle.js
Normal file
1
frappe/public/js/barcode_scanner.bundle.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import "./frappe/barcode_scanner/quagga";
|
||||
64
frappe/public/js/bootstrap-4-web.bundle.js
vendored
Normal file
64
frappe/public/js/bootstrap-4-web.bundle.js
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
|
||||
// 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
frappe/public/js/chat.bundle.js
Normal file
1
frappe/public/js/chat.bundle.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import "./frappe/chat";
|
||||
1
frappe/public/js/checkout.bundle.js
Normal file
1
frappe/public/js/checkout.bundle.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import "./integrations/razorpay";
|
||||
18
frappe/public/js/controls.bundle.js
Normal file
18
frappe/public/js/controls.bundle.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
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";
|
||||
1
frappe/public/js/data_import_tools.bundle.js
Normal file
1
frappe/public/js/data_import_tools.bundle.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import "./frappe/data_import";
|
||||
105
frappe/public/js/desk.bundle.js
Normal file
105
frappe/public/js/desk.bundle.js
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
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/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";
|
||||
7
frappe/public/js/dialog.bundle.js
Normal file
7
frappe/public/js/dialog.bundle.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import "./frappe/dom.js";
|
||||
import "./frappe/form/formatters.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";
|
||||
17
frappe/public/js/form.bundle.js
Normal file
17
frappe/public/js/form.bundle.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import "./frappe/form/templates/address_list.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";
|
||||
|
||||
26
frappe/public/js/frappe-web.bundle.js
Normal file
26
frappe/public/js/frappe-web.bundle.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import "./jquery-bootstrap";
|
||||
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 "./bootstrap-4-web.bundle";
|
||||
|
||||
|
||||
import "../../website/js/website.js";
|
||||
import "./frappe/socketio_client.js";
|
||||
|
|
@ -9,7 +9,14 @@ frappe.require = function(items, callback) {
|
|||
if(typeof items === "string") {
|
||||
items = [items];
|
||||
}
|
||||
frappe.assets.execute(items, callback);
|
||||
items = items.map(item => frappe.assets.bundled_asset(item));
|
||||
|
||||
return new Promise(resolve => {
|
||||
frappe.assets.execute(items, () => {
|
||||
resolve();
|
||||
callback && callback();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
frappe.assets = {
|
||||
|
|
@ -160,4 +167,11 @@ frappe.assets = {
|
|||
frappe.dom.set_style(txt);
|
||||
}
|
||||
},
|
||||
|
||||
bundled_asset(path) {
|
||||
if (!path.startsWith('/assets') && path.includes('.bundle.')) {
|
||||
return frappe.boot.assets_json[path] || path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ frappe.barcode.scan_barcode = function() {
|
|||
}
|
||||
}, reject);
|
||||
} else {
|
||||
frappe.require('/assets/js/barcode_scanner.min.js', () => {
|
||||
frappe.require('barcode_scanner.bundle.js', () => {
|
||||
frappe.barcode.get_barcode().then(barcode => {
|
||||
resolve(barcode);
|
||||
});
|
||||
|
|
|
|||
111
frappe/public/js/frappe/build_events/BuildError.vue
Normal file
111
frappe/public/js/frappe/build_events/BuildError.vue
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
<template>
|
||||
<div class="build-error-overlay" @click.self="data = null" v-show="data">
|
||||
<div class="window" v-if="data">
|
||||
<div v-for="(error, i) in data.formatted" :key="i">
|
||||
<!-- prettier-ignore -->
|
||||
<pre class="frame"><component :is="error_component(error, i)" /></pre>
|
||||
</div>
|
||||
<pre class="stack">{{ data.stack }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "BuildError",
|
||||
data() {
|
||||
return {
|
||||
data: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
show(data) {
|
||||
this.data = data;
|
||||
},
|
||||
hide() {
|
||||
this.data = null;
|
||||
},
|
||||
open_in_editor(location) {
|
||||
frappe.socketio.socket.emit("open_in_editor", location);
|
||||
},
|
||||
error_component(error, i) {
|
||||
let location = this.data.error.errors[i].location;
|
||||
let location_string = `${location.file}:${location.line}:${
|
||||
location.column
|
||||
}`;
|
||||
let template = error.replace(
|
||||
" > " + location_string,
|
||||
` > <a class="file-link" @click="open">${location_string}</a>`
|
||||
);
|
||||
|
||||
return {
|
||||
template: `<div>${template}</div>`,
|
||||
methods: {
|
||||
open() {
|
||||
frappe.socketio.socket.emit("open_in_editor", location);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.build-error-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999;
|
||||
margin: 0;
|
||||
background: rgba(0, 0, 0, 0.66);
|
||||
--monospace: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier,
|
||||
monospace;
|
||||
--dim: var(--gray-400);
|
||||
}
|
||||
.window {
|
||||
font-family: var(--monospace);
|
||||
line-height: 1.5;
|
||||
width: 800px;
|
||||
color: #d8d8d8;
|
||||
margin: 30px auto;
|
||||
padding: 25px 40px;
|
||||
position: relative;
|
||||
background: #181818;
|
||||
border-radius: 6px 6px 8px 8px;
|
||||
box-shadow: 0 19px 38px rgba(0, 0, 0, 0.3), 0 15px 12px rgba(0, 0, 0, 0.22);
|
||||
overflow: hidden;
|
||||
border-top: 8px solid var(--red);
|
||||
}
|
||||
|
||||
pre {
|
||||
font-family: var(--monospace);
|
||||
font-size: 13px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
code {
|
||||
font-size: 13px;
|
||||
font-family: var(--monospace);
|
||||
color: var(--yellow);
|
||||
}
|
||||
|
||||
.message {
|
||||
line-height: 1.3;
|
||||
font-weight: 600;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.frame {
|
||||
color: var(--yellow);
|
||||
}
|
||||
.stack {
|
||||
font-size: 13px;
|
||||
color: var(--dim);
|
||||
}
|
||||
.file-link {
|
||||
text-decoration: underline !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
52
frappe/public/js/frappe/build_events/BuildSuccess.vue
Normal file
52
frappe/public/js/frappe/build_events/BuildSuccess.vue
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="is_shown"
|
||||
class="flex justify-between build-success-message align-center"
|
||||
>
|
||||
<div class="mr-4">Compiled successfully</div>
|
||||
<a class="text-white underline" href="/" @click.prevent="reload">
|
||||
Refresh
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "BuildSuccess",
|
||||
data() {
|
||||
return {
|
||||
is_shown: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.is_shown = true;
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
this.timeout = setTimeout(() => {
|
||||
this.hide();
|
||||
}, 10000);
|
||||
},
|
||||
hide() {
|
||||
this.is_shown = false;
|
||||
},
|
||||
reload() {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.build-success-message {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem 1rem;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
margin: 1rem;
|
||||
}
|
||||
</style>
|
||||
48
frappe/public/js/frappe/build_events/build_events.bundle.js
Normal file
48
frappe/public/js/frappe/build_events/build_events.bundle.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
import BuildError from "./BuildError.vue";
|
||||
import BuildSuccess from "./BuildSuccess.vue";
|
||||
|
||||
let $container = $("#build-events-overlay");
|
||||
let success = null;
|
||||
let error = null;
|
||||
|
||||
frappe.realtime.on("build_event", data => {
|
||||
if (data.success) {
|
||||
show_build_success(data);
|
||||
} else if (data.error) {
|
||||
show_build_error(data);
|
||||
}
|
||||
});
|
||||
|
||||
function show_build_success() {
|
||||
if (error) {
|
||||
error.hide();
|
||||
}
|
||||
if (!success) {
|
||||
let target = $('<div class="build-success-container">')
|
||||
.appendTo($container)
|
||||
.get(0);
|
||||
let vm = new Vue({
|
||||
el: target,
|
||||
render: h => h(BuildSuccess)
|
||||
});
|
||||
success = vm.$children[0];
|
||||
}
|
||||
success.show();
|
||||
}
|
||||
|
||||
function show_build_error(data) {
|
||||
if (success) {
|
||||
success.hide();
|
||||
}
|
||||
if (!error) {
|
||||
let target = $('<div class="build-error-container">')
|
||||
.appendTo($container)
|
||||
.get(0);
|
||||
let vm = new Vue({
|
||||
el: target,
|
||||
render: h => h(BuildError)
|
||||
});
|
||||
error = vm.$children[0];
|
||||
}
|
||||
error.show(data);
|
||||
}
|
||||
|
|
@ -80,4 +80,4 @@ To subclass, use:
|
|||
|
||||
// export
|
||||
global.Class = Class;
|
||||
})(this);
|
||||
})(window);
|
||||
|
|
|
|||
|
|
@ -24,12 +24,12 @@ $(document).ready(function() {
|
|||
frappe.start_app();
|
||||
});
|
||||
|
||||
frappe.Application = Class.extend({
|
||||
init: function() {
|
||||
frappe.Application = class Application {
|
||||
constructor() {
|
||||
this.startup();
|
||||
},
|
||||
}
|
||||
|
||||
startup: function() {
|
||||
startup() {
|
||||
frappe.socketio.init();
|
||||
frappe.model.init();
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ frappe.Application = Class.extend({
|
|||
});
|
||||
|
||||
// listen to build errors
|
||||
this.setup_build_error_listener();
|
||||
this.setup_build_events();
|
||||
|
||||
if (frappe.sys_defaults.email_user_password) {
|
||||
var email_list = frappe.sys_defaults.email_user_password.split(',');
|
||||
|
|
@ -160,7 +160,7 @@ frappe.Application = Class.extend({
|
|||
}, 600000); // check every 10 minutes
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
set_route() {
|
||||
frappe.flags.setting_original_route = true;
|
||||
|
|
@ -175,14 +175,14 @@ frappe.Application = Class.extend({
|
|||
frappe.router.on('change', () => {
|
||||
$(".tooltip").hide();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
setup_frappe_vue() {
|
||||
Vue.prototype.__ = window.__;
|
||||
Vue.prototype.frappe = window.frappe;
|
||||
},
|
||||
}
|
||||
|
||||
set_password: function(user) {
|
||||
set_password(user) {
|
||||
var me=this;
|
||||
frappe.call({
|
||||
method: 'frappe.core.doctype.user.user.get_email_awaiting',
|
||||
|
|
@ -199,9 +199,9 @@ frappe.Application = Class.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
email_password_prompt: function(email_account,user,i) {
|
||||
email_password_prompt(email_account,user,i) {
|
||||
var me = this;
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: __('Password missing in Email Account'),
|
||||
|
|
@ -255,8 +255,8 @@ frappe.Application = Class.extend({
|
|||
});
|
||||
});
|
||||
d.show();
|
||||
},
|
||||
load_bootinfo: function() {
|
||||
}
|
||||
load_bootinfo() {
|
||||
if(frappe.boot) {
|
||||
this.setup_workspaces();
|
||||
frappe.model.sync(frappe.boot.docs);
|
||||
|
|
@ -278,7 +278,7 @@ frappe.Application = Class.extend({
|
|||
} else {
|
||||
this.set_as_guest();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setup_workspaces() {
|
||||
frappe.modules = {};
|
||||
|
|
@ -291,24 +291,24 @@ frappe.Application = Class.extend({
|
|||
// default workspace is settings for Frappe
|
||||
frappe.workspaces['home'] = frappe.workspaces['build'];
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
load_user_permissions: function() {
|
||||
load_user_permissions() {
|
||||
frappe.defaults.update_user_permissions();
|
||||
|
||||
frappe.realtime.on('update_user_permissions', frappe.utils.debounce(() => {
|
||||
frappe.defaults.update_user_permissions();
|
||||
}, 500));
|
||||
},
|
||||
}
|
||||
|
||||
check_metadata_cache_status: function() {
|
||||
check_metadata_cache_status() {
|
||||
if(frappe.boot.metadata_version != localStorage.metadata_version) {
|
||||
frappe.assets.clear_local_storage();
|
||||
frappe.assets.init_local_storage();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
set_globals: function() {
|
||||
set_globals() {
|
||||
frappe.session.user = frappe.boot.user.name;
|
||||
frappe.session.logged_in_user = frappe.boot.user.name;
|
||||
frappe.session.user_email = frappe.boot.user.email;
|
||||
|
|
@ -360,8 +360,8 @@ frappe.Application = Class.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
sync_pages: function() {
|
||||
}
|
||||
sync_pages() {
|
||||
// clear cached pages if timestamp is not found
|
||||
if(localStorage["page_info"]) {
|
||||
frappe.boot.allowed_pages = [];
|
||||
|
|
@ -376,8 +376,8 @@ frappe.Application = Class.extend({
|
|||
frappe.boot.allowed_pages = Object.keys(frappe.boot.page_info);
|
||||
}
|
||||
localStorage["page_info"] = JSON.stringify(frappe.boot.page_info);
|
||||
},
|
||||
set_as_guest: function() {
|
||||
}
|
||||
set_as_guest() {
|
||||
frappe.session.user = 'Guest';
|
||||
frappe.session.user_email = '';
|
||||
frappe.session.user_fullname = 'Guest';
|
||||
|
|
@ -385,23 +385,23 @@ frappe.Application = Class.extend({
|
|||
frappe.user_defaults = {};
|
||||
frappe.user_roles = ['Guest'];
|
||||
frappe.sys_defaults = {};
|
||||
},
|
||||
make_page_container: function() {
|
||||
}
|
||||
make_page_container() {
|
||||
if ($("#body").length) {
|
||||
$(".splash").remove();
|
||||
frappe.temp_container = $("<div id='temp-container' style='display: none;'>")
|
||||
.appendTo("body");
|
||||
frappe.container = new frappe.views.Container();
|
||||
}
|
||||
},
|
||||
make_nav_bar: function() {
|
||||
}
|
||||
make_nav_bar() {
|
||||
// toolbar
|
||||
if(frappe.boot && frappe.boot.home_page!=='setup-wizard') {
|
||||
frappe.frappe_toolbar = new frappe.ui.toolbar.Toolbar();
|
||||
}
|
||||
|
||||
},
|
||||
logout: function() {
|
||||
}
|
||||
logout() {
|
||||
var me = this;
|
||||
me.logged_out = true;
|
||||
return frappe.call({
|
||||
|
|
@ -413,8 +413,8 @@ frappe.Application = Class.extend({
|
|||
me.redirect_to_login();
|
||||
}
|
||||
});
|
||||
},
|
||||
handle_session_expired: function() {
|
||||
}
|
||||
handle_session_expired() {
|
||||
if(!frappe.app.session_expired_dialog) {
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: __('Session Expired'),
|
||||
|
|
@ -464,16 +464,16 @@ frappe.Application = Class.extend({
|
|||
'background-color': '#4B4C9D'
|
||||
});
|
||||
}
|
||||
},
|
||||
redirect_to_login: function() {
|
||||
}
|
||||
redirect_to_login() {
|
||||
window.location.href = '/';
|
||||
},
|
||||
set_favicon: function() {
|
||||
}
|
||||
set_favicon() {
|
||||
var link = $('link[type="image/x-icon"]').remove().attr("href");
|
||||
$('<link rel="shortcut icon" href="' + link + '" type="image/x-icon">').appendTo("head");
|
||||
$('<link rel="icon" href="' + link + '" type="image/x-icon">').appendTo("head");
|
||||
},
|
||||
trigger_primary_action: function() {
|
||||
}
|
||||
trigger_primary_action() {
|
||||
// to trigger change event on active input before triggering primary action
|
||||
$(document.activeElement).blur();
|
||||
// wait for possible JS validations triggered after blur (it might change primary button)
|
||||
|
|
@ -487,20 +487,20 @@ frappe.Application = Class.extend({
|
|||
frappe.container.page.save_action();
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
}
|
||||
|
||||
set_rtl: function() {
|
||||
set_rtl() {
|
||||
if (frappe.utils.is_rtl()) {
|
||||
var ls = document.createElement('link');
|
||||
ls.rel="stylesheet";
|
||||
ls.type = "text/css";
|
||||
ls.href= "/assets/css/frappe-rtl.css";
|
||||
ls.href= frappe.assets.bundled_asset("frappe-rtl.bundle.css");
|
||||
document.getElementsByTagName('head')[0].appendChild(ls);
|
||||
$('body').addClass('frappe-rtl');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
show_change_log: function() {
|
||||
show_change_log() {
|
||||
var me = this;
|
||||
let change_log = frappe.boot.change_log;
|
||||
|
||||
|
|
@ -531,15 +531,15 @@ frappe.Application = Class.extend({
|
|||
});
|
||||
me.show_notes();
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
show_update_available: () => {
|
||||
show_update_available() {
|
||||
frappe.call({
|
||||
"method": "frappe.utils.change_log.show_update_popup"
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
setup_analytics: function() {
|
||||
setup_analytics() {
|
||||
if(window.mixpanel) {
|
||||
window.mixpanel.identify(frappe.session.user);
|
||||
window.mixpanel.people.set({
|
||||
|
|
@ -549,17 +549,17 @@ frappe.Application = Class.extend({
|
|||
"$email": frappe.session.user
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
add_browser_class() {
|
||||
$('html').addClass(frappe.utils.get_browser().name.toLowerCase());
|
||||
},
|
||||
}
|
||||
|
||||
set_fullwidth_if_enabled() {
|
||||
frappe.ui.toolbar.set_fullwidth_if_enabled();
|
||||
},
|
||||
}
|
||||
|
||||
show_notes: function() {
|
||||
show_notes() {
|
||||
var me = this;
|
||||
if(frappe.boot.notes.length) {
|
||||
frappe.boot.notes.forEach(function(note) {
|
||||
|
|
@ -586,21 +586,19 @@ frappe.Application = Class.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setup_build_error_listener() {
|
||||
setup_build_events() {
|
||||
if (frappe.boot.developer_mode) {
|
||||
frappe.realtime.on('build_error', (data) => {
|
||||
console.log(data);
|
||||
});
|
||||
frappe.require("build_events.bundle.js");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setup_energy_point_listeners() {
|
||||
frappe.realtime.on('energy_point_alert', (message) => {
|
||||
frappe.show_alert(message);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
setup_copy_doc_listener() {
|
||||
$('body').on('paste', (e) => {
|
||||
|
|
@ -634,7 +632,7 @@ frappe.Application = Class.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
frappe.get_module = function(m, default_module) {
|
||||
var module = frappe.modules[m] || default_module;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
||||
make_input: function() {
|
||||
frappe.ui.form.ControlAttach = class ControlAttach extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
let me = this;
|
||||
this.$input = $('<button class="btn btn-default btn-sm btn-attach">')
|
||||
.html(__("Attach"))
|
||||
|
|
@ -26,8 +26,8 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
|
||||
frappe.utils.bind_actions_with_object(this.$value, this);
|
||||
this.toggle_reload_button();
|
||||
},
|
||||
clear_attachment: function() {
|
||||
}
|
||||
clear_attachment() {
|
||||
let me = this;
|
||||
if(this.frm) {
|
||||
me.parse_validate_and_set_in_model(null);
|
||||
|
|
@ -44,16 +44,16 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
this.parse_validate_and_set_in_model(null);
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
}
|
||||
reload_attachment() {
|
||||
if (this.file_uploader) {
|
||||
this.file_uploader.uploader.upload_files();
|
||||
}
|
||||
},
|
||||
}
|
||||
on_attach_click() {
|
||||
this.set_upload_options();
|
||||
this.file_uploader = new frappe.ui.FileUploader(this.upload_options);
|
||||
},
|
||||
}
|
||||
set_upload_options() {
|
||||
let options = {
|
||||
allow_multiple: false,
|
||||
|
|
@ -73,9 +73,9 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
Object.assign(options, this.df.options);
|
||||
}
|
||||
this.upload_options = options;
|
||||
},
|
||||
}
|
||||
|
||||
set_input: function(value, dataurl) {
|
||||
set_input(value, dataurl) {
|
||||
this.value = value;
|
||||
if(this.value) {
|
||||
this.$input.toggle(false);
|
||||
|
|
@ -94,23 +94,23 @@ frappe.ui.form.ControlAttach = frappe.ui.form.ControlData.extend({
|
|||
this.$input.toggle(true);
|
||||
this.$value.toggle(false);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_value: function() {
|
||||
get_value() {
|
||||
return this.value || null;
|
||||
},
|
||||
}
|
||||
|
||||
on_upload_complete: function(attachment) {
|
||||
on_upload_complete(attachment) {
|
||||
if(this.frm) {
|
||||
this.parse_validate_and_set_in_model(attachment.file_url);
|
||||
this.frm.attachments.update_attachment(attachment);
|
||||
this.frm.doc.docstatus == 1 ? this.frm.save('Update') : this.frm.save();
|
||||
}
|
||||
this.set_value(attachment.file_url);
|
||||
},
|
||||
}
|
||||
|
||||
toggle_reload_button() {
|
||||
this.$value.find('[data-action="reload_attachment"]')
|
||||
.toggle(this.file_uploader && this.file_uploader.uploader.files.length > 0);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
frappe.ui.form.ControlAttachImage = frappe.ui.form.ControlAttach.extend({
|
||||
frappe.ui.form.ControlAttachImage = class ControlAttachImage extends frappe.ui.form.ControlAttach {
|
||||
make_input() {
|
||||
this._super();
|
||||
super.make_input();
|
||||
|
||||
let $file_link = this.$value.find('.attached-file-link');
|
||||
$file_link.popover({
|
||||
|
|
@ -16,10 +16,10 @@ frappe.ui.form.ControlAttachImage = frappe.ui.form.ControlAttach.extend({
|
|||
},
|
||||
html: true
|
||||
});
|
||||
},
|
||||
}
|
||||
set_upload_options() {
|
||||
this._super();
|
||||
super.set_upload_options();
|
||||
this.upload_options.restrictions = {};
|
||||
this.upload_options.restrictions.allowed_file_types = ['image/*'];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import Awesomplete from 'awesomplete';
|
||||
|
||||
frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
||||
trigger_change_on_input_event: false,
|
||||
frappe.ui.form.ControlAutocomplete = class ControlAutoComplete extends frappe.ui.form.ControlData {
|
||||
static trigger_change_on_input_event = false
|
||||
make_input() {
|
||||
this._super();
|
||||
super.make_input();
|
||||
this.setup_awesomplete();
|
||||
this.set_options();
|
||||
},
|
||||
}
|
||||
|
||||
set_options() {
|
||||
if (this.df.options) {
|
||||
let options = this.df.options || [];
|
||||
this._data = this.parse_options(options);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_awesomplete_settings() {
|
||||
var me = this;
|
||||
|
|
@ -63,7 +63,7 @@ frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
|||
return 0;
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
setup_awesomplete() {
|
||||
this.awesomplete = new Awesomplete(
|
||||
|
|
@ -100,7 +100,7 @@ frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
|||
this.$input.on('awesomplete-selectcomplete', () => {
|
||||
this.$input.trigger('change');
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
validate(value) {
|
||||
if (this.df.ignore_validation) {
|
||||
|
|
@ -115,7 +115,7 @@ frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
|||
} else {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
parse_options(options) {
|
||||
if (typeof options === 'string') {
|
||||
|
|
@ -125,11 +125,11 @@ frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
|||
options = options.map(o => ({ label: o, value: o }));
|
||||
}
|
||||
return options;
|
||||
},
|
||||
}
|
||||
|
||||
get_data() {
|
||||
return this._data || [];
|
||||
},
|
||||
}
|
||||
|
||||
set_data(data) {
|
||||
data = this.parse_options(data);
|
||||
|
|
@ -138,4 +138,4 @@ frappe.ui.form.ControlAutocomplete = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
this._data = data;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import JsBarcode from 'jsbarcode';
|
||||
|
||||
frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
||||
frappe.ui.form.ControlBarcode = class ControlBarcode extends frappe.ui.form.ControlData {
|
||||
make_wrapper() {
|
||||
// Create the elements for barcode area
|
||||
this._super();
|
||||
super.make_wrapper();
|
||||
|
||||
this.default_svg = '<svg height=80></svg>';
|
||||
let $input_wrapper = this.$wrapper.find('.control-input-wrapper');
|
||||
|
|
@ -11,7 +11,7 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
`<div class="barcode-wrapper">${this.default_svg}</div>`
|
||||
);
|
||||
this.barcode_area.appendTo($input_wrapper);
|
||||
},
|
||||
}
|
||||
|
||||
parse(value) {
|
||||
// Parse raw value
|
||||
|
|
@ -22,7 +22,7 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
return this.get_barcode_html(value);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
// Set values to display
|
||||
|
|
@ -40,7 +40,7 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
|
||||
this.$input.val(barcode_value || value);
|
||||
this.barcode_area.html(svg || this.default_svg);
|
||||
},
|
||||
}
|
||||
|
||||
get_barcode_html(value) {
|
||||
if (value) {
|
||||
|
|
@ -51,7 +51,7 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
$(svg).attr('width', '100%');
|
||||
return this.barcode_area.html();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_options(value) {
|
||||
// get JsBarcode options
|
||||
|
|
@ -76,4 +76,4 @@ frappe.ui.form.ControlBarcode = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
return options;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.form.Control = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.Control = class BaseControl {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.make();
|
||||
|
||||
|
|
@ -11,31 +11,31 @@ frappe.ui.form.Control = Class.extend({
|
|||
if(this.render_input) {
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
this.make_wrapper();
|
||||
this.$wrapper
|
||||
.attr("data-fieldtype", this.df.fieldtype)
|
||||
.attr("data-fieldname", this.df.fieldname);
|
||||
this.wrapper = this.$wrapper.get(0);
|
||||
this.wrapper.fieldobj = this; // reference for event handlers
|
||||
},
|
||||
}
|
||||
|
||||
make_wrapper: function() {
|
||||
make_wrapper() {
|
||||
this.$wrapper = $("<div class='frappe-control'></div>").appendTo(this.parent);
|
||||
|
||||
// alias
|
||||
this.wrapper = this.$wrapper;
|
||||
},
|
||||
}
|
||||
|
||||
toggle: function(show) {
|
||||
toggle(show) {
|
||||
this.df.hidden = show ? 0 : 1;
|
||||
this.refresh();
|
||||
},
|
||||
}
|
||||
|
||||
// returns "Read", "Write" or "None"
|
||||
// as strings based on permissions
|
||||
get_status: function(explain) {
|
||||
get_status(explain) {
|
||||
if (this.df.get_status) {
|
||||
return this.df.get_status(this);
|
||||
}
|
||||
|
|
@ -93,8 +93,8 @@ frappe.ui.form.Control = Class.extend({
|
|||
}
|
||||
|
||||
return status;
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
this.disp_status = this.get_status();
|
||||
this.$wrapper
|
||||
&& this.$wrapper.toggleClass("hide-control", this.disp_status=="None")
|
||||
|
|
@ -104,7 +104,7 @@ frappe.ui.form.Control = Class.extend({
|
|||
var value = this.get_value();
|
||||
|
||||
this.show_translatable_button(value);
|
||||
},
|
||||
}
|
||||
show_translatable_button(value) {
|
||||
// Disable translation non-string fields or special string fields
|
||||
if (!frappe.model
|
||||
|
|
@ -138,26 +138,26 @@ frappe.ui.form.Control = Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
},
|
||||
get_doc: function() {
|
||||
}
|
||||
get_doc() {
|
||||
return this.doctype && this.docname
|
||||
&& locals[this.doctype] && locals[this.doctype][this.docname] || {};
|
||||
},
|
||||
get_model_value: function() {
|
||||
}
|
||||
get_model_value() {
|
||||
if(this.doc) {
|
||||
return this.doc[this.df.fieldname];
|
||||
}
|
||||
},
|
||||
set_value: function(value) {
|
||||
}
|
||||
set_value(value) {
|
||||
return this.validate_and_set_in_model(value);
|
||||
},
|
||||
parse_validate_and_set_in_model: function(value, e) {
|
||||
}
|
||||
parse_validate_and_set_in_model(value, e) {
|
||||
if(this.parse) {
|
||||
value = this.parse(value);
|
||||
}
|
||||
return this.validate_and_set_in_model(value, e);
|
||||
},
|
||||
validate_and_set_in_model: function(value, e) {
|
||||
}
|
||||
validate_and_set_in_model(value, e) {
|
||||
var me = this;
|
||||
let force_value_set = (this.doc && this.doc.__run_link_triggers);
|
||||
let is_value_same = (this.get_model_value() === value);
|
||||
|
|
@ -193,8 +193,8 @@ frappe.ui.form.Control = Class.extend({
|
|||
// all clear
|
||||
return set(value);
|
||||
}
|
||||
},
|
||||
get_value: function() {
|
||||
}
|
||||
get_value() {
|
||||
if(this.get_status()==='Write') {
|
||||
return this.get_input_value ?
|
||||
(this.parse ? this.parse(this.get_input_value()) : this.get_input_value()) :
|
||||
|
|
@ -202,8 +202,8 @@ frappe.ui.form.Control = Class.extend({
|
|||
} else {
|
||||
return this.value || undefined;
|
||||
}
|
||||
},
|
||||
set_model_value: function(value) {
|
||||
}
|
||||
set_model_value(value) {
|
||||
if(this.frm) {
|
||||
this.last_value = value;
|
||||
return frappe.model.set_value(this.doctype, this.docname, this.df.fieldname,
|
||||
|
|
@ -215,11 +215,11 @@ frappe.ui.form.Control = Class.extend({
|
|||
this.set_input(value);
|
||||
return Promise.resolve();
|
||||
}
|
||||
},
|
||||
set_focus: function() {
|
||||
}
|
||||
set_focus() {
|
||||
if(this.$input) {
|
||||
this.$input.get(0).focus();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
||||
horizontal: true,
|
||||
make: function() {
|
||||
frappe.ui.form.ControlInput = class ControlInput extends frappe.ui.form.Control {
|
||||
static horizontal = true
|
||||
make() {
|
||||
// parent element
|
||||
this._super();
|
||||
super.make();
|
||||
this.set_input_areas();
|
||||
|
||||
// set description
|
||||
this.set_max_width();
|
||||
},
|
||||
make_wrapper: function() {
|
||||
}
|
||||
make_wrapper() {
|
||||
if(this.only_input) {
|
||||
this.$wrapper = $('<div class="form-group frappe-control">').appendTo(this.parent);
|
||||
} else {
|
||||
|
|
@ -25,14 +25,14 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
</div>\
|
||||
</div>').appendTo(this.parent);
|
||||
}
|
||||
},
|
||||
toggle_label: function(show) {
|
||||
}
|
||||
toggle_label(show) {
|
||||
this.$wrapper.find(".control-label").toggleClass("hide", !show);
|
||||
},
|
||||
toggle_description: function(show) {
|
||||
}
|
||||
toggle_description(show) {
|
||||
this.$wrapper.find(".help-box").toggleClass("hide", !show);
|
||||
},
|
||||
set_input_areas: function() {
|
||||
}
|
||||
set_input_areas() {
|
||||
if(this.only_input) {
|
||||
this.input_area = this.wrapper;
|
||||
} else {
|
||||
|
|
@ -43,17 +43,17 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
// like links, currencies, HTMLs etc.
|
||||
this.disp_area = this.$wrapper.find(".control-value").get(0);
|
||||
}
|
||||
},
|
||||
set_max_width: function() {
|
||||
if(this.horizontal) {
|
||||
}
|
||||
set_max_width() {
|
||||
if(this.constructor.horizontal) {
|
||||
this.$wrapper.addClass("input-max-width");
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// update input value, label, description
|
||||
// display (show/hide/read-only),
|
||||
// mandatory style on refresh
|
||||
refresh_input: function() {
|
||||
refresh_input() {
|
||||
var me = this;
|
||||
var make_input = function() {
|
||||
if (!me.has_input) {
|
||||
|
|
@ -106,13 +106,13 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
me.set_bold();
|
||||
me.set_required();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
can_write() {
|
||||
return this.disp_status == "Write";
|
||||
},
|
||||
}
|
||||
|
||||
set_disp_area: function(value) {
|
||||
set_disp_area(value) {
|
||||
if(in_list(["Currency", "Int", "Float"], this.df.fieldtype)
|
||||
&& (this.value === 0 || value === 0)) {
|
||||
// to set the 0 value in readonly for currency, int, float field
|
||||
|
|
@ -126,8 +126,8 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
let doc = this.doc || (this.frm && this.frm.doc);
|
||||
let display_value = frappe.format(value, this.df, { no_icon: true, inline: true }, doc);
|
||||
this.disp_area && $(this.disp_area).html(display_value);
|
||||
},
|
||||
set_label: function(label) {
|
||||
}
|
||||
set_label(label) {
|
||||
if(label) this.df.label = label;
|
||||
|
||||
if(this.only_input || this.df.label==this._label)
|
||||
|
|
@ -137,8 +137,8 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
this.label_span.innerHTML = (icon ? '<i class="'+icon+'"></i> ' : "") +
|
||||
__(this.df.label) || " ";
|
||||
this._label = this.df.label;
|
||||
},
|
||||
set_description: function(description) {
|
||||
}
|
||||
set_description(description) {
|
||||
if (description !== undefined) {
|
||||
this.df.description = description;
|
||||
}
|
||||
|
|
@ -151,17 +151,17 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
this.set_empty_description();
|
||||
}
|
||||
this._description = this.df.description;
|
||||
},
|
||||
set_new_description: function(description) {
|
||||
}
|
||||
set_new_description(description) {
|
||||
this.$wrapper.find(".help-box").html(description);
|
||||
},
|
||||
set_empty_description: function() {
|
||||
}
|
||||
set_empty_description() {
|
||||
this.$wrapper.find(".help-box").html("");
|
||||
},
|
||||
set_mandatory: function(value) {
|
||||
}
|
||||
set_mandatory(value) {
|
||||
this.$wrapper.toggleClass("has-error", Boolean(this.df.reqd && is_null(value)));
|
||||
},
|
||||
set_invalid: function () {
|
||||
}
|
||||
set_invalid () {
|
||||
let invalid = !!this.df.invalid;
|
||||
if (this.grid) {
|
||||
this.$wrapper.parents('.grid-static-col').toggleClass('invalid', invalid);
|
||||
|
|
@ -170,11 +170,11 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
} else {
|
||||
this.$wrapper.toggleClass('has-error', invalid);
|
||||
}
|
||||
},
|
||||
}
|
||||
set_required() {
|
||||
this.label_area && $(this.label_area).toggleClass('reqd', Boolean(this.df.reqd));
|
||||
},
|
||||
set_bold: function() {
|
||||
}
|
||||
set_bold() {
|
||||
if(this.$input) {
|
||||
this.$input.toggleClass("bold", !!(this.df.bold || this.df.reqd));
|
||||
}
|
||||
|
|
@ -182,4 +182,4 @@ frappe.ui.form.ControlInput = frappe.ui.form.Control.extend({
|
|||
$(this.disp_area).toggleClass("bold", !!(this.df.bold || this.df.reqd));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
|
||||
frappe.ui.form.ControlButton = class ControlButton extends frappe.ui.form.ControlData {
|
||||
can_write() {
|
||||
// should be always true in case of button
|
||||
return true;
|
||||
},
|
||||
make_input: function() {
|
||||
}
|
||||
make_input() {
|
||||
var me = this;
|
||||
const btn_type = this.df.primary ? 'btn-primary': 'btn-default';
|
||||
const btn_size = this.df.btn_size
|
||||
|
|
@ -18,8 +18,8 @@ frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
|
|||
this.set_input_attributes();
|
||||
this.has_input = true;
|
||||
this.toggle_label(false);
|
||||
},
|
||||
onclick: function() {
|
||||
}
|
||||
onclick() {
|
||||
if (this.frm && this.frm.doc) {
|
||||
if (this.frm.script_manager.has_handlers(this.df.fieldname, this.doctype)) {
|
||||
this.frm.script_manager.trigger(this.df.fieldname, this.doctype, this.docname);
|
||||
|
|
@ -31,8 +31,8 @@ frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
|
|||
} else if (this.df.click) {
|
||||
this.df.click();
|
||||
}
|
||||
},
|
||||
run_server_script: function() {
|
||||
}
|
||||
run_server_script() {
|
||||
// DEPRECATE
|
||||
var me = this;
|
||||
if(this.frm && this.frm.docname) {
|
||||
|
|
@ -47,18 +47,18 @@ frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
hide() {
|
||||
this.$input.hide();
|
||||
},
|
||||
set_input_areas: function() {
|
||||
this._super();
|
||||
}
|
||||
set_input_areas() {
|
||||
super.set_input_areas();
|
||||
$(this.disp_area).removeClass().addClass("hide");
|
||||
},
|
||||
set_empty_description: function() {
|
||||
}
|
||||
set_empty_description() {
|
||||
this.$wrapper.find(".help-box").empty().toggle(false);
|
||||
},
|
||||
set_label: function(label) {
|
||||
}
|
||||
set_label(label) {
|
||||
if (label) {
|
||||
this.df.label = label;
|
||||
}
|
||||
|
|
@ -66,4 +66,4 @@ frappe.ui.form.ControlButton = frappe.ui.form.ControlData.extend({
|
|||
$(this.label_span).html(" ");
|
||||
this.$input && this.$input.html(label);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
frappe.ui.form.ControlCheck = frappe.ui.form.ControlData.extend({
|
||||
input_type: "checkbox",
|
||||
make_wrapper: function() {
|
||||
frappe.ui.form.ControlCheck = class ControlCheck extends frappe.ui.form.ControlData {
|
||||
static html_element = "input"
|
||||
static input_type = "checkbox"
|
||||
make_wrapper() {
|
||||
this.$wrapper = $(`<div class="form-group frappe-control">
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
|
|
@ -11,23 +12,23 @@ frappe.ui.form.ControlCheck = frappe.ui.form.ControlData.extend({
|
|||
<p class="help-box small text-muted"></p>
|
||||
</div>
|
||||
</div>`).appendTo(this.parent);
|
||||
},
|
||||
set_input_areas: function() {
|
||||
}
|
||||
set_input_areas() {
|
||||
this.label_area = this.label_span = this.$wrapper.find(".label-area").get(0);
|
||||
this.input_area = this.$wrapper.find(".input-area").get(0);
|
||||
this.disp_area = this.$wrapper.find(".disp-area").get(0);
|
||||
},
|
||||
make_input: function() {
|
||||
this._super();
|
||||
}
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.$input.removeClass("form-control");
|
||||
},
|
||||
get_input_value: function() {
|
||||
}
|
||||
get_input_value() {
|
||||
return this.input && this.input.checked ? 1 : 0;
|
||||
},
|
||||
validate: function(value) {
|
||||
}
|
||||
validate(value) {
|
||||
return cint(value);
|
||||
},
|
||||
set_input: function(value) {
|
||||
}
|
||||
set_input(value) {
|
||||
value = cint(value);
|
||||
if(this.input) {
|
||||
this.input.checked = (value ? 1 : 0);
|
||||
|
|
@ -36,4 +37,4 @@ frappe.ui.form.ControlCheck = frappe.ui.form.ControlData.extend({
|
|||
this.set_mandatory(value);
|
||||
this.set_disp_area(value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
||||
frappe.ui.form.ControlCode = class ControlCode extends frappe.ui.form.ControlText {
|
||||
make_input() {
|
||||
if (this.editor) return;
|
||||
this.load_lib().then(() => this.make_ace_editor());
|
||||
},
|
||||
}
|
||||
|
||||
make_ace_editor() {
|
||||
if (this.editor) return;
|
||||
|
|
@ -34,6 +34,7 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
|
||||
// setup autocompletion when it is set the first time
|
||||
Object.defineProperty(this.df, 'autocompletions', {
|
||||
configurable: true,
|
||||
get() {
|
||||
return this._autocompletions || [];
|
||||
},
|
||||
|
|
@ -42,7 +43,7 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
this.df._autocompletions = value;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
setup_autocompletion() {
|
||||
if (this._autocompletion_setup) return;
|
||||
|
|
@ -82,20 +83,20 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
});
|
||||
});
|
||||
this._autocompletion_setup = true;
|
||||
},
|
||||
}
|
||||
|
||||
refresh_height() {
|
||||
this.ace_editor_target.css('height', this.expanded ? 600 : 300);
|
||||
this.editor.resize();
|
||||
},
|
||||
}
|
||||
|
||||
toggle_label() {
|
||||
this.$expand_button && this.$expand_button.text(this.get_button_label());
|
||||
},
|
||||
}
|
||||
|
||||
get_button_label() {
|
||||
return this.expanded ? __('Collapse', null, 'Shrink code field.') : __('Expand', null, 'Enlarge code field.');
|
||||
},
|
||||
}
|
||||
|
||||
set_language() {
|
||||
const language_map = {
|
||||
|
|
@ -122,14 +123,14 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
const ace_language_mode = language_map[language] || '';
|
||||
this.editor.session.setMode(ace_language_mode);
|
||||
this.editor.setKeyboardHandler('ace/keyboard/vscode');
|
||||
},
|
||||
}
|
||||
|
||||
parse(value) {
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
return value;
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
return this.load_lib().then(() => {
|
||||
|
|
@ -138,11 +139,11 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
if (value === this.get_input_value()) return;
|
||||
this.editor.session.setValue(value);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_input_value() {
|
||||
return this.editor ? this.editor.session.getValue() : '';
|
||||
},
|
||||
}
|
||||
|
||||
load_lib() {
|
||||
if (this.library_loaded) return this.library_loaded;
|
||||
|
|
@ -162,4 +163,4 @@ frappe.ui.form.ControlCode = frappe.ui.form.ControlText.extend({
|
|||
|
||||
return this.library_loaded;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import Picker from '../../color_picker/color_picker';
|
||||
|
||||
frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({
|
||||
make_input: function () {
|
||||
frappe.ui.form.ControlColor = class ControlColor extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
this.df.placeholder = this.df.placeholder || __('Choose a color');
|
||||
this._super();
|
||||
super.make_input();
|
||||
this.make_color_input();
|
||||
},
|
||||
make_color_input: function () {
|
||||
}
|
||||
|
||||
make_color_input() {
|
||||
let picker_wrapper = $('<div>');
|
||||
this.picker = new Picker({
|
||||
parent: picker_wrapper[0],
|
||||
|
|
@ -73,27 +74,31 @@ frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({
|
|||
this.$wrapper.popover('hide');
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this._super();
|
||||
super.refresh();
|
||||
let color = this.get_color();
|
||||
if (this.picker && this.picker.color !== color) {
|
||||
this.picker.color = color;
|
||||
this.picker.refresh();
|
||||
}
|
||||
},
|
||||
set_formatted_input: function(value) {
|
||||
this._super(value);
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
super.set_formatted_input(value);
|
||||
this.$input.val(value);
|
||||
this.selected_color.css({
|
||||
"background-color": value || 'transparent',
|
||||
});
|
||||
this.selected_color.toggleClass('no-value', !value);
|
||||
},
|
||||
}
|
||||
|
||||
get_color() {
|
||||
return this.validate(this.get_value());
|
||||
},
|
||||
validate: function (value) {
|
||||
}
|
||||
|
||||
validate(value) {
|
||||
if (value === '') {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -103,4 +108,4 @@ frappe.ui.form.ControlColor = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import Mention from './quill-mention/quill.mention';
|
|||
|
||||
Quill.register('modules/mention', Mention, true);
|
||||
|
||||
frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
||||
frappe.ui.form.ControlComment = class ControlComment extends frappe.ui.form.ControlTextEditor {
|
||||
make_wrapper() {
|
||||
this.comment_wrapper = !this.no_wrapper ? $(`
|
||||
<div class="comment-input-wrapper">
|
||||
|
|
@ -32,10 +32,10 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
|||
this.wrapper = this.$wrapper;
|
||||
|
||||
this.button = this.comment_wrapper.find('.btn-comment');
|
||||
},
|
||||
}
|
||||
|
||||
bind_events() {
|
||||
this._super();
|
||||
super.bind_events();
|
||||
|
||||
this.button.click(() => {
|
||||
this.submit();
|
||||
|
|
@ -52,11 +52,11 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
|||
this.quill.on('text-change', frappe.utils.debounce(() => {
|
||||
this.update_state();
|
||||
}, 300));
|
||||
},
|
||||
}
|
||||
|
||||
submit() {
|
||||
this.on_submit && this.on_submit(this.get_value());
|
||||
},
|
||||
}
|
||||
|
||||
update_state() {
|
||||
const value = this.get_value();
|
||||
|
|
@ -65,17 +65,17 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
|||
} else {
|
||||
this.button.addClass('btn-default').removeClass('btn-primary');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_quill_options() {
|
||||
const options = this._super();
|
||||
const options = super.get_quill_options();
|
||||
return Object.assign(options, {
|
||||
theme: 'bubble',
|
||||
modules: Object.assign(options.modules, {
|
||||
mention: this.get_mention_options()
|
||||
})
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_mention_options() {
|
||||
if (!this.enable_mentions) {
|
||||
|
|
@ -98,7 +98,7 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
|||
return `${value} ${item.is_group ? frappe.utils.icon('users') : ''}`;
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
get_toolbar_options() {
|
||||
return [
|
||||
|
|
@ -108,19 +108,19 @@ frappe.ui.form.ControlComment = frappe.ui.form.ControlTextEditor.extend({
|
|||
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
||||
['clean']
|
||||
];
|
||||
},
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.quill.setText('');
|
||||
},
|
||||
}
|
||||
|
||||
disable() {
|
||||
this.quill.disable();
|
||||
this.button.prop('disabled', true);
|
||||
},
|
||||
}
|
||||
|
||||
enable() {
|
||||
this.quill.enable();
|
||||
this.button.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
frappe.ui.form.ControlCurrency = frappe.ui.form.ControlFloat.extend({
|
||||
format_for_input: function(value) {
|
||||
frappe.ui.form.ControlCurrency = class ControlCurrency extends frappe.ui.form.ControlFloat {
|
||||
format_for_input(value) {
|
||||
var formatted_value = format_number(value, this.get_number_format(), this.get_precision());
|
||||
return isNaN(Number(value)) ? "" : formatted_value;
|
||||
},
|
||||
}
|
||||
|
||||
get_precision: function() {
|
||||
get_precision() {
|
||||
// always round based on field precision or currency's precision
|
||||
// this method is also called in this.parse()
|
||||
if (!this.df.precision) {
|
||||
|
|
@ -17,4 +17,4 @@ frappe.ui.form.ControlCurrency = frappe.ui.form.ControlFloat.extend({
|
|||
|
||||
return this.df.precision;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
frappe.provide('frappe.phone_call');
|
||||
|
||||
frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
||||
html_element: "input",
|
||||
input_type: "text",
|
||||
trigger_change_on_input_event: true,
|
||||
make_input: function() {
|
||||
frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlInput {
|
||||
static html_element = "input";
|
||||
static input_type = "text";
|
||||
static trigger_change_on_input_event = true;
|
||||
make_input() {
|
||||
if(this.$input) return;
|
||||
|
||||
this.$input = $("<"+ this.html_element +">")
|
||||
.attr("type", this.input_type)
|
||||
let { html_element, input_type } = this.constructor;
|
||||
|
||||
this.$input = $("<"+ html_element +">")
|
||||
.attr("type", input_type)
|
||||
.attr("autocomplete", "off")
|
||||
.addClass("input-with-feedback form-control")
|
||||
.prependTo(this.input_area);
|
||||
|
|
@ -32,7 +34,7 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
let doctype_edit_link = null;
|
||||
if (this.frm.meta.custom) {
|
||||
doctype_edit_link = frappe.utils.get_form_link(
|
||||
'DocType',
|
||||
'DocType',
|
||||
this.frm.doctype, true,
|
||||
__('this form')
|
||||
);
|
||||
|
|
@ -65,8 +67,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
if (this.df.options == 'URL') {
|
||||
this.setup_url_field();
|
||||
}
|
||||
},
|
||||
setup_url_field: function() {
|
||||
}
|
||||
|
||||
setup_url_field() {
|
||||
this.$wrapper.find('.control-input').append(
|
||||
`<span class="link-btn">
|
||||
<a class="btn-open no-decoration" title="${__("Open Link")}" target="_blank">
|
||||
|
|
@ -74,14 +77,14 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
</a>
|
||||
</span>`
|
||||
);
|
||||
|
||||
|
||||
this.$link = this.$wrapper.find('.link-btn');
|
||||
this.$link_open = this.$link.find('.btn-open');
|
||||
|
||||
|
||||
this.$input.on("focus", () => {
|
||||
setTimeout(() => {
|
||||
let inputValue = this.get_input_value();
|
||||
|
||||
|
||||
if (inputValue && validate_url(inputValue)) {
|
||||
this.$link.toggle(true);
|
||||
this.$link_open.attr('href', this.get_input_value());
|
||||
|
|
@ -100,7 +103,7 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
this.$link.toggle(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.$input.on("blur", () => {
|
||||
// if this disappears immediately, the user's click
|
||||
// does not register, hence timeout
|
||||
|
|
@ -108,8 +111,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
this.$link.toggle(false);
|
||||
}, 500);
|
||||
});
|
||||
},
|
||||
bind_change_event: function() {
|
||||
}
|
||||
|
||||
bind_change_event() {
|
||||
const change_handler = e => {
|
||||
if (this.change) this.change(e);
|
||||
else {
|
||||
|
|
@ -118,12 +122,12 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
}
|
||||
};
|
||||
this.$input.on("change", change_handler);
|
||||
if (this.trigger_change_on_input_event) {
|
||||
if (this.constructor.trigger_change_on_input_event) {
|
||||
// debounce to avoid repeated validations on value change
|
||||
this.$input.on("input", frappe.utils.debounce(change_handler, 500));
|
||||
}
|
||||
},
|
||||
setup_autoname_check: function() {
|
||||
}
|
||||
setup_autoname_check() {
|
||||
if (!this.df.parent) return;
|
||||
this.meta = frappe.get_meta(this.df.parent);
|
||||
if (this.meta && ((this.meta.autoname
|
||||
|
|
@ -152,8 +156,8 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
set_input_attributes: function() {
|
||||
}
|
||||
set_input_attributes() {
|
||||
this.$input
|
||||
.attr("data-fieldtype", this.df.fieldtype)
|
||||
.attr("data-fieldname", this.df.fieldname)
|
||||
|
|
@ -167,24 +171,24 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
if(this.df.input_class) {
|
||||
this.$input.addClass(this.df.input_class);
|
||||
}
|
||||
},
|
||||
set_input: function(value) {
|
||||
}
|
||||
set_input(value) {
|
||||
this.last_value = this.value;
|
||||
this.value = value;
|
||||
this.set_formatted_input(value);
|
||||
this.set_disp_area(value);
|
||||
this.set_mandatory && this.set_mandatory(value);
|
||||
},
|
||||
set_formatted_input: function(value) {
|
||||
}
|
||||
set_formatted_input(value) {
|
||||
this.$input && this.$input.val(this.format_for_input(value));
|
||||
},
|
||||
get_input_value: function() {
|
||||
}
|
||||
get_input_value() {
|
||||
return this.$input ? this.$input.val() : undefined;
|
||||
},
|
||||
format_for_input: function(val) {
|
||||
}
|
||||
format_for_input(val) {
|
||||
return val==null ? "" : val;
|
||||
},
|
||||
validate: function(v) {
|
||||
}
|
||||
validate(v) {
|
||||
if (!v) {
|
||||
return '';
|
||||
}
|
||||
|
|
@ -217,9 +221,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({
|
|||
} else {
|
||||
return v;
|
||||
}
|
||||
},
|
||||
toggle_container_scroll: function(el_class, scroll_class, add=false) {
|
||||
}
|
||||
toggle_container_scroll(el_class, scroll_class, add=false) {
|
||||
let el = this.$input.parents(el_class)[0];
|
||||
if (el) $(el).toggleClass(scroll_class, add);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
||||
trigger_change_on_input_event: false,
|
||||
make_input: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlDate = class ControlDate extends frappe.ui.form.ControlData {
|
||||
static trigger_change_on_input_event = false
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.make_picker();
|
||||
},
|
||||
make_picker: function() {
|
||||
}
|
||||
make_picker() {
|
||||
this.set_date_options();
|
||||
this.set_datepicker();
|
||||
this.set_t_for_today();
|
||||
},
|
||||
set_formatted_input: function(value) {
|
||||
this._super(value);
|
||||
}
|
||||
set_formatted_input(value) {
|
||||
super.set_formatted_input(value);
|
||||
if (this.timepicker_only) return;
|
||||
if (!this.datepicker) return;
|
||||
if (!value) {
|
||||
|
|
@ -39,8 +39,8 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
if(should_refresh) {
|
||||
this.datepicker.selectDate(frappe.datetime.str_to_obj(value));
|
||||
}
|
||||
},
|
||||
set_date_options: function() {
|
||||
}
|
||||
set_date_options() {
|
||||
// webformTODO:
|
||||
let sysdefaults = frappe.boot.sysdefaults;
|
||||
|
||||
|
|
@ -75,8 +75,8 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
this.update_datepicker_position();
|
||||
}
|
||||
};
|
||||
},
|
||||
set_datepicker: function() {
|
||||
}
|
||||
set_datepicker() {
|
||||
this.$input.datepicker(this.datepicker_options);
|
||||
this.datepicker = this.$input.data('datepicker');
|
||||
|
||||
|
|
@ -87,8 +87,8 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
.click(() => {
|
||||
this.datepicker.selectDate(this.get_now_date());
|
||||
});
|
||||
},
|
||||
update_datepicker_position: function() {
|
||||
}
|
||||
update_datepicker_position() {
|
||||
if(!this.frm) return;
|
||||
// show datepicker above or below the input
|
||||
// based on scroll position
|
||||
|
|
@ -110,11 +110,11 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
|
||||
this.datepicker.update('position', position);
|
||||
},
|
||||
get_now_date: function() {
|
||||
}
|
||||
get_now_date() {
|
||||
return frappe.datetime.now_date(true);
|
||||
},
|
||||
set_t_for_today: function() {
|
||||
}
|
||||
set_t_for_today() {
|
||||
var me = this;
|
||||
this.$input.on("keydown", function(e) {
|
||||
if(e.which===84) { // 84 === t
|
||||
|
|
@ -128,19 +128,19 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
parse: function(value) {
|
||||
}
|
||||
parse(value) {
|
||||
if(value) {
|
||||
return frappe.datetime.user_to_str(value);
|
||||
}
|
||||
},
|
||||
format_for_input: function(value) {
|
||||
}
|
||||
format_for_input(value) {
|
||||
if(value) {
|
||||
return frappe.datetime.str_to_user(value);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
validate: function(value) {
|
||||
}
|
||||
validate(value) {
|
||||
if(value && !frappe.datetime.validate(value)) {
|
||||
let sysdefaults = frappe.sys_defaults;
|
||||
let date_format = sysdefaults && sysdefaults.date_format
|
||||
|
|
@ -150,4 +150,4 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
return value;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
|
||||
make_input: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlDateRange = class ControlDateRange extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.set_date_options();
|
||||
this.set_datepicker();
|
||||
this.refresh();
|
||||
},
|
||||
set_date_options: function() {
|
||||
}
|
||||
set_date_options() {
|
||||
var me = this;
|
||||
this.datepicker_options = {
|
||||
language: "en",
|
||||
|
|
@ -18,12 +18,12 @@ frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
|
|||
this.datepicker_options.onSelect = function() {
|
||||
me.$input.trigger('change');
|
||||
};
|
||||
},
|
||||
set_datepicker: function() {
|
||||
}
|
||||
set_datepicker() {
|
||||
this.$input.datepicker(this.datepicker_options);
|
||||
this.datepicker = this.$input.data('datepicker');
|
||||
},
|
||||
set_input: function(value, value2) {
|
||||
}
|
||||
set_input(value, value2) {
|
||||
this.last_value = this.value;
|
||||
if (value && value2) {
|
||||
this.value = [value, value2];
|
||||
|
|
@ -38,8 +38,8 @@ frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
this.set_disp_area(value || '');
|
||||
this.set_mandatory && this.set_mandatory(value);
|
||||
},
|
||||
parse: function(value) {
|
||||
}
|
||||
parse(value) {
|
||||
// replace the separator (which can be in user language) with comma
|
||||
const to = __('{0} to {1}').replace('{0}', '').replace('{1}', '');
|
||||
value = value.replace(to, ',');
|
||||
|
|
@ -50,8 +50,8 @@ frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
|
|||
var to_date = moment(frappe.datetime.user_to_obj(vals[vals.length-1])).format('YYYY-MM-DD');
|
||||
return [from_date, to_date];
|
||||
}
|
||||
},
|
||||
format_for_input: function(value1, value2) {
|
||||
}
|
||||
format_for_input(value1, value2) {
|
||||
if(value1 && value2) {
|
||||
value1 = frappe.datetime.str_to_user(value1);
|
||||
value2 = frappe.datetime.str_to_user(value2);
|
||||
|
|
@ -59,4 +59,4 @@ frappe.ui.form.ControlDateRange = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
return "";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
frappe.ui.form.ControlDatetime = frappe.ui.form.ControlDate.extend({
|
||||
set_date_options: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlDatetime = class ControlDatetime extends frappe.ui.form.ControlDate {
|
||||
set_date_options() {
|
||||
super.set_date_options();
|
||||
this.today_text = __("Now");
|
||||
let sysdefaults = frappe.boot.sysdefaults;
|
||||
this.date_format = frappe.defaultDatetimeFormat;
|
||||
|
|
@ -10,11 +10,11 @@ frappe.ui.form.ControlDatetime = frappe.ui.form.ControlDate.extend({
|
|||
timepicker: true,
|
||||
timeFormat: time_format.toLowerCase().replace("mm", "ii")
|
||||
});
|
||||
},
|
||||
get_now_date: function() {
|
||||
}
|
||||
get_now_date() {
|
||||
return frappe.datetime.now_datetime(true);
|
||||
},
|
||||
set_description: function() {
|
||||
}
|
||||
set_description() {
|
||||
const { description } = this.df;
|
||||
const { time_zone } = frappe.sys_defaults;
|
||||
if (!this.df.hide_timezone && !frappe.datetime.is_timezone_same()) {
|
||||
|
|
@ -24,10 +24,10 @@ frappe.ui.form.ControlDatetime = frappe.ui.form.ControlDate.extend({
|
|||
this.df.description += '<br>' + time_zone;
|
||||
}
|
||||
}
|
||||
this._super();
|
||||
},
|
||||
set_datepicker: function() {
|
||||
this._super();
|
||||
super.set_description();
|
||||
}
|
||||
set_datepicker() {
|
||||
super.set_datepicker();
|
||||
if (this.datepicker.opts.timeFormat.indexOf('s') == -1) {
|
||||
// No seconds in time format
|
||||
const $tp = this.datepicker.timepicker;
|
||||
|
|
@ -36,4 +36,4 @@ frappe.ui.form.ControlDatetime = frappe.ui.form.ControlDate.extend({
|
|||
$tp.$secondsText.prev().css('display', 'none');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
||||
make_input: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlDuration = class ControlDuration extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.make_picker();
|
||||
},
|
||||
}
|
||||
|
||||
make_picker: function() {
|
||||
make_picker() {
|
||||
this.inputs = [];
|
||||
this.set_duration_options();
|
||||
this.$picker = $(
|
||||
|
|
@ -21,9 +21,9 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
this.$picker.hide();
|
||||
this.bind_events();
|
||||
this.refresh();
|
||||
},
|
||||
}
|
||||
|
||||
build_numeric_input: function(label, hidden, max) {
|
||||
build_numeric_input(label, hidden, max) {
|
||||
let $duration_input = $(`
|
||||
<input class="input-sm duration-input" data-duration="${label}" type="number" min="0" value="0">
|
||||
`);
|
||||
|
|
@ -47,13 +47,13 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
$control.prepend($input);
|
||||
$control.appendTo(this.$picker.find(".picker-row"));
|
||||
},
|
||||
}
|
||||
|
||||
set_duration_options() {
|
||||
this.duration_options = frappe.utils.get_duration_options(this.df);
|
||||
},
|
||||
}
|
||||
|
||||
set_duration_picker_value: function(value) {
|
||||
set_duration_picker_value(value) {
|
||||
let total_duration = frappe.utils.seconds_to_duration(value, this.duration_options);
|
||||
|
||||
if (this.$picker) {
|
||||
|
|
@ -61,9 +61,9 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
this.inputs[duration].prop("value", total_duration[duration]);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
bind_events: function() {
|
||||
bind_events() {
|
||||
// flag to handle the display property of the picker
|
||||
let clicked = false;
|
||||
|
||||
|
|
@ -103,21 +103,21 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
this.$picker.hide();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_value() {
|
||||
return cint(this.value);
|
||||
},
|
||||
}
|
||||
|
||||
refresh_input: function() {
|
||||
this._super();
|
||||
refresh_input() {
|
||||
super.refresh_input();
|
||||
this.set_duration_options();
|
||||
this.set_duration_picker_value(this.value);
|
||||
},
|
||||
}
|
||||
|
||||
format_for_input: function(value) {
|
||||
format_for_input(value) {
|
||||
return frappe.utils.get_formatted_duration(value, this.duration_options);
|
||||
},
|
||||
}
|
||||
|
||||
get_duration() {
|
||||
// returns an object of days, hours, minutes and seconds from the inputs array
|
||||
|
|
@ -138,7 +138,7 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
}
|
||||
return total_duration;
|
||||
},
|
||||
}
|
||||
|
||||
is_duration_picker_set(inputs) {
|
||||
let is_set = false;
|
||||
|
|
@ -149,4 +149,4 @@ frappe.ui.form.ControlDuration = frappe.ui.form.ControlData.extend({
|
|||
});
|
||||
return is_set;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.form.ControlDynamicLink = frappe.ui.form.ControlLink.extend({
|
||||
get_options: function() {
|
||||
frappe.ui.form.ControlDynamicLink = class ControlDynamicLink extends frappe.ui.form.ControlLink {
|
||||
get_options() {
|
||||
let options = '';
|
||||
if (this.df.get_options) {
|
||||
options = this.df.get_options();
|
||||
|
|
@ -28,5 +28,5 @@ frappe.ui.form.ControlDynamicLink = frappe.ui.form.ControlLink.extend({
|
|||
}
|
||||
|
||||
return options;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
frappe.ui.form.ControlFloat = frappe.ui.form.ControlInt.extend({
|
||||
parse: function(value) {
|
||||
frappe.ui.form.ControlFloat = class ControlFloat extends frappe.ui.form.ControlInt {
|
||||
parse(value) {
|
||||
value = this.eval_expression(value);
|
||||
return isNaN(parseFloat(value)) ? null : flt(value, this.get_precision());
|
||||
},
|
||||
}
|
||||
|
||||
format_for_input: function(value) {
|
||||
format_for_input(value) {
|
||||
var number_format;
|
||||
if (this.df.fieldtype==="Float" && this.df.options && this.df.options.trim()) {
|
||||
number_format = this.get_number_format();
|
||||
}
|
||||
var formatted_value = format_number(value, number_format, this.get_precision());
|
||||
return isNaN(Number(value)) ? "" : formatted_value;
|
||||
},
|
||||
}
|
||||
|
||||
get_number_format: function() {
|
||||
get_number_format() {
|
||||
var currency = frappe.meta.get_field_currency(this.df, this.get_doc());
|
||||
return get_number_format(currency);
|
||||
},
|
||||
}
|
||||
|
||||
get_precision: function() {
|
||||
get_precision() {
|
||||
// round based on field precision or float precision, else don't round
|
||||
return this.df.precision || cint(frappe.boot.sysdefaults.float_precision, null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.form.ControlPercent = frappe.ui.form.ControlFloat;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
frappe.provide('frappe.utils.utils');
|
||||
|
||||
frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
||||
horizontal: false,
|
||||
frappe.ui.form.ControlGeolocation = class ControlGeolocation extends frappe.ui.form.ControlData {
|
||||
static horizontal = false
|
||||
|
||||
make_wrapper() {
|
||||
// Create the elements for map area
|
||||
this._super();
|
||||
super.make_wrapper();
|
||||
|
||||
let $input_wrapper = this.$wrapper.find('.control-input-wrapper');
|
||||
this.map_id = frappe.dom.get_unique_id();
|
||||
|
|
@ -24,14 +24,14 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
this.make_map();
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
make_map() {
|
||||
this.bind_leaflet_map();
|
||||
this.bind_leaflet_draw_control();
|
||||
this.bind_leaflet_locate_control();
|
||||
this.bind_leaflet_refresh_button();
|
||||
},
|
||||
}
|
||||
|
||||
format_for_input(value) {
|
||||
if (!this.map) return;
|
||||
|
|
@ -65,7 +65,7 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
} else if ((value===undefined) || (value == JSON.stringify(new L.FeatureGroup().toGeoJSON()))) {
|
||||
this.locate_control.start();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
bind_leaflet_map() {
|
||||
var circleToGeoJSON = L.Circle.prototype.toGeoJSON;
|
||||
|
|
@ -97,13 +97,13 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
|
||||
L.tileLayer(frappe.utils.map_defaults.tiles,
|
||||
frappe.utils.map_defaults.options).addTo(this.map);
|
||||
},
|
||||
}
|
||||
|
||||
bind_leaflet_locate_control() {
|
||||
// To request location update and set location, sets current geolocation on load
|
||||
this.locate_control = L.control.locate({position:'topright'});
|
||||
this.locate_control.addTo(this.map);
|
||||
},
|
||||
}
|
||||
|
||||
bind_leaflet_draw_control() {
|
||||
this.editableLayers = new L.FeatureGroup();
|
||||
|
|
@ -160,7 +160,7 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
this.editableLayers.removeLayer(layer);
|
||||
this.set_value(JSON.stringify(this.editableLayers.toGeoJSON()));
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
bind_leaflet_refresh_button() {
|
||||
L.easyButton({
|
||||
|
|
@ -177,7 +177,7 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
icon: 'fa fa-refresh'
|
||||
}]
|
||||
}).addTo(this.map);
|
||||
},
|
||||
}
|
||||
|
||||
add_non_group_layers(source_layer, target_group) {
|
||||
// https://gis.stackexchange.com/a/203773
|
||||
|
|
@ -189,11 +189,11 @@ frappe.ui.form.ControlGeolocation = frappe.ui.form.ControlData.extend({
|
|||
} else {
|
||||
target_group.addLayer(source_layer);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
clear_editable_layers() {
|
||||
this.editableLayers.eachLayer((l)=>{
|
||||
this.editableLayers.removeLayer(l);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.form.ControlHeading = frappe.ui.form.ControlHTML.extend({
|
||||
get_content: function() {
|
||||
frappe.ui.form.ControlHeading = class ControlHeading extends frappe.ui.form.ControlHTML {
|
||||
get_content() {
|
||||
return "<h4>" + __(this.df.label) + "</h4>";
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
frappe.ui.form.ControlHTML = frappe.ui.form.Control.extend({
|
||||
make: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlHTML = class ControlHTML extends frappe.ui.form.Control {
|
||||
make() {
|
||||
super.make();
|
||||
this.disp_area = this.wrapper;
|
||||
},
|
||||
refresh_input: function() {
|
||||
}
|
||||
refresh_input() {
|
||||
var content = this.get_content();
|
||||
if(content) this.$wrapper.html(content);
|
||||
},
|
||||
get_content: function() {
|
||||
}
|
||||
get_content() {
|
||||
var content = this.df.options || "";
|
||||
content = __(content);
|
||||
try {
|
||||
|
|
@ -15,11 +15,11 @@ frappe.ui.form.ControlHTML = frappe.ui.form.Control.extend({
|
|||
} catch (e) {
|
||||
return content;
|
||||
}
|
||||
},
|
||||
html: function(html) {
|
||||
}
|
||||
html(html) {
|
||||
this.$wrapper.html(html || this.get_content());
|
||||
},
|
||||
set_value: function(html) {
|
||||
}
|
||||
set_value(html) {
|
||||
if(html.appendTo) {
|
||||
// jquery object
|
||||
html.appendTo(this.$wrapper.empty());
|
||||
|
|
@ -29,4 +29,4 @@ frappe.ui.form.ControlHTML = frappe.ui.form.Control.extend({
|
|||
this.html(html);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
frappe.ui.form.ControlHTMLEditor = frappe.ui.form.ControlMarkdownEditor.extend({
|
||||
editor_class: 'html',
|
||||
frappe.ui.form.ControlHTMLEditor = class ControlHTMLEditor extends frappe.ui.form.ControlMarkdownEditor {
|
||||
static editor_class = 'html';
|
||||
set_language() {
|
||||
this.df.options = 'HTML';
|
||||
this._super();
|
||||
},
|
||||
super.set_language();
|
||||
}
|
||||
update_preview() {
|
||||
if (!this.markdown_preview) return;
|
||||
let value = this.get_value() || '';
|
||||
value = frappe.dom.remove_script_and_style(value);
|
||||
this.markdown_preview.html(value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
frappe.ui.form.ControlImage = frappe.ui.form.Control.extend({
|
||||
make: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlImage = class ControlImage extends frappe.ui.form.Control {
|
||||
make() {
|
||||
super.make();
|
||||
this.$wrapper.css({"margin": "0px"});
|
||||
this.$body = $("<div></div>").appendTo(this.$wrapper)
|
||||
.css({"margin-bottom": "10px"});
|
||||
$('<div class="clearfix"></div>').appendTo(this.$wrapper);
|
||||
},
|
||||
refresh_input: function() {
|
||||
}
|
||||
refresh_input() {
|
||||
this.$body.empty();
|
||||
|
||||
var doc = this.get_doc();
|
||||
|
|
@ -19,4 +19,4 @@ frappe.ui.form.ControlImage = frappe.ui.form.Control.extend({
|
|||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({
|
||||
trigger_change_on_input_event: false,
|
||||
make: function () {
|
||||
this._super();
|
||||
frappe.ui.form.ControlInt = class ControlInt extends frappe.ui.form.ControlData {
|
||||
static trigger_change_on_input_event = false
|
||||
make () {
|
||||
super.make();
|
||||
// $(this.label_area).addClass('pull-right');
|
||||
// $(this.disp_area).addClass('text-right');
|
||||
},
|
||||
make_input: function () {
|
||||
}
|
||||
make_input () {
|
||||
var me = this;
|
||||
this._super();
|
||||
super.make_input();
|
||||
this.$input
|
||||
// .addClass("text-right")
|
||||
.on("focus", function () {
|
||||
|
|
@ -19,11 +19,11 @@ frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({
|
|||
}, 100);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
validate: function (value) {
|
||||
}
|
||||
validate (value) {
|
||||
return this.parse(value);
|
||||
},
|
||||
eval_expression: function (value) {
|
||||
}
|
||||
eval_expression (value) {
|
||||
if (typeof value === 'string') {
|
||||
if (value.match(/^[0-9+\-/* ]+$/)) {
|
||||
// If it is a string containing operators
|
||||
|
|
@ -36,8 +36,8 @@ frappe.ui.form.ControlInt = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
parse: function (value) {
|
||||
}
|
||||
parse (value) {
|
||||
return cint(this.eval_expression(value), null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import Awesomplete from 'awesomplete';
|
|||
|
||||
frappe.ui.form.recent_link_validations = {};
|
||||
|
||||
frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
||||
trigger_change_on_input_event: false,
|
||||
make_input: function() {
|
||||
frappe.ui.form.ControlLink = class ControlLink extends frappe.ui.form.ControlData {
|
||||
static trigger_change_on_input_event = false
|
||||
make_input() {
|
||||
var me = this;
|
||||
$(`<div class="link-field ui-front" style="position: relative;">
|
||||
<input type="text" class="input-with-feedback form-control">
|
||||
|
|
@ -53,23 +53,23 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
this.setup_buttons();
|
||||
this.setup_awesomeplete();
|
||||
this.bind_change_event();
|
||||
},
|
||||
get_options: function() {
|
||||
}
|
||||
get_options() {
|
||||
return this.df.options;
|
||||
},
|
||||
}
|
||||
get_reference_doctype() {
|
||||
// this is used to get the context in which link field is loaded
|
||||
if (this.doctype) return this.doctype;
|
||||
else {
|
||||
return frappe.get_route && frappe.get_route()[0] === 'List' ? frappe.get_route()[1] : null;
|
||||
}
|
||||
},
|
||||
setup_buttons: function() {
|
||||
}
|
||||
setup_buttons() {
|
||||
if(this.only_input && !this.with_link_btn) {
|
||||
this.$input_area.find(".link-btn").remove();
|
||||
}
|
||||
},
|
||||
open_advanced_search: function() {
|
||||
}
|
||||
open_advanced_search() {
|
||||
var doctype = this.get_options();
|
||||
if(!doctype) return;
|
||||
new frappe.ui.form.LinkSelector({
|
||||
|
|
@ -78,8 +78,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
txt: this.get_input_value()
|
||||
});
|
||||
return false;
|
||||
},
|
||||
new_doc: function() {
|
||||
}
|
||||
new_doc() {
|
||||
var doctype = this.get_options();
|
||||
var me = this;
|
||||
|
||||
|
|
@ -109,8 +109,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
});
|
||||
|
||||
return false;
|
||||
},
|
||||
setup_awesomeplete: function() {
|
||||
}
|
||||
setup_awesomeplete() {
|
||||
var me = this;
|
||||
|
||||
this.$input.cache = {};
|
||||
|
|
@ -284,7 +284,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
me.$input.val("");
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
merge_duplicates(results) {
|
||||
// in case of result like this
|
||||
|
|
@ -301,7 +301,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
return [...newArr, currElem];
|
||||
}, []);
|
||||
// returns [{value: 'Manufacturer 1', 'description': 'mobile part 1, mobile part 2'}]
|
||||
},
|
||||
}
|
||||
|
||||
toggle_href(doctype) {
|
||||
if (frappe.model.can_select(doctype) && !frappe.model.can_read(doctype)) {
|
||||
|
|
@ -310,7 +310,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
} else {
|
||||
this.$input_area.find(".link-btn").removeClass('hide');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_filter_description(filters) {
|
||||
let doctype = this.get_options();
|
||||
|
|
@ -369,9 +369,9 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
.join(', ');
|
||||
|
||||
return __('Filters applied for {0}', [filter_string]);
|
||||
},
|
||||
}
|
||||
|
||||
set_custom_query: function(args) {
|
||||
set_custom_query(args) {
|
||||
var set_nulls = function(obj) {
|
||||
$.each(obj, function(key, value) {
|
||||
if(value!==undefined) {
|
||||
|
|
@ -439,8 +439,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
if(!args.filters) args.filters = {};
|
||||
$.extend(args.filters, this.df.filters);
|
||||
}
|
||||
},
|
||||
validate: function(value) {
|
||||
}
|
||||
validate(value) {
|
||||
// validate the value just entered
|
||||
if(this.df.options=="[Select]" || this.df.ignore_link_validation) {
|
||||
return value;
|
||||
|
|
@ -448,8 +448,8 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
|
||||
return this.validate_link_and_fetch(this.df, this.get_options(),
|
||||
this.docname, value);
|
||||
},
|
||||
validate_link_and_fetch: function(df, doctype, docname, value) {
|
||||
}
|
||||
validate_link_and_fetch(df, doctype, docname, value) {
|
||||
if(value) {
|
||||
return new Promise((resolve) => {
|
||||
var fetch = '';
|
||||
|
|
@ -464,7 +464,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
this.fetch_and_validate_link(resolve, df, doctype, docname, value, fetch);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
fetch_and_validate_link(resolve, df, doctype, docname, value, fetch) {
|
||||
frappe.call({
|
||||
|
|
@ -487,15 +487,15 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
set_fetch_values: function(df, docname, fetch_values) {
|
||||
set_fetch_values(df, docname, fetch_values) {
|
||||
var fl = this.frm.fetch_dict[df.fieldname].fields;
|
||||
for(var i=0; i < fl.length; i++) {
|
||||
frappe.model.set_value(df.parent, docname, fl[i], fetch_values[i], df.fieldtype);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (Awesomplete) {
|
||||
Awesomplete.prototype.get_item = function(value) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
frappe.ui.form.ControlMarkdownEditor = frappe.ui.form.ControlCode.extend({
|
||||
editor_class: 'markdown',
|
||||
frappe.ui.form.ControlMarkdownEditor = class ControlMarkdownEditor extends frappe.ui.form.ControlCode {
|
||||
static editor_class = 'markdown'
|
||||
make_ace_editor() {
|
||||
this._super();
|
||||
super.make_ace_editor();
|
||||
|
||||
this.ace_editor_target.wrap(`<div class="${this.editor_class}-container">`);
|
||||
this.markdown_container = this.$input_wrapper.find(`.${this.editor_class}-container`);
|
||||
this.markdown_container = this.$input_wrapper.find(`.${this.constructor.editor_class}-container`);
|
||||
|
||||
this.editor.getSession().setUseWrapMode(true);
|
||||
|
||||
|
|
@ -27,26 +27,26 @@ frappe.ui.form.ControlMarkdownEditor = frappe.ui.form.ControlCode.extend({
|
|||
|
||||
this.markdown_preview = $(`<div class="${this.editor_class}-preview border rounded">`).hide();
|
||||
this.markdown_container.append(this.markdown_preview);
|
||||
},
|
||||
}
|
||||
|
||||
set_language() {
|
||||
this.df.options = 'Markdown';
|
||||
this._super();
|
||||
},
|
||||
super.set_language();
|
||||
}
|
||||
|
||||
update_preview() {
|
||||
const value = this.get_value() || "";
|
||||
this.markdown_preview.html(frappe.markdown(value));
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
this._super(value)
|
||||
super.set_formatted_input(value)
|
||||
.then(() => {
|
||||
this.update_preview();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
set_disp_area(value) {
|
||||
this.disp_area && $(this.disp_area).text(value);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
||||
frappe.ui.form.ControlMultiCheck = class ControlMultiCheck extends frappe.ui.form.Control {
|
||||
// UI: multiple checkboxes
|
||||
// Value: Array of values
|
||||
// Options: Array of label/value/checked option objects
|
||||
|
||||
make() {
|
||||
this._super();
|
||||
super.make();
|
||||
if (this.df.label) {
|
||||
this.$label = $(`<label class="control-label">${this.df.label}</label>`).appendTo(this.wrapper);
|
||||
}
|
||||
|
|
@ -15,18 +15,18 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
const row = this.get_column_size() === 12 ? '' : 'row';
|
||||
this.$checkbox_area = $(`<div class="checkbox-options ${row}"></div>`).appendTo(this.wrapper);
|
||||
this.refresh();
|
||||
},
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.set_options();
|
||||
this.bind_checkboxes();
|
||||
this.refresh_input();
|
||||
this._super();
|
||||
},
|
||||
super.refresh();
|
||||
}
|
||||
|
||||
refresh_input() {
|
||||
this.select_options(this.selected_options);
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
set_options() {
|
||||
|
|
@ -47,7 +47,7 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
} else {
|
||||
this.make_checkboxes();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
parse_df_options() {
|
||||
if(Array.isArray(this.df.options)) {
|
||||
|
|
@ -62,7 +62,7 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
} else {
|
||||
this.options = [];
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
make_checkboxes() {
|
||||
this.$load_state.hide();
|
||||
|
|
@ -78,7 +78,7 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
this.setup_select_all();
|
||||
}
|
||||
this.set_checked_options();
|
||||
},
|
||||
}
|
||||
|
||||
bind_checkboxes() {
|
||||
$(this.wrapper).on('change', ':checkbox', e => {
|
||||
|
|
@ -95,14 +95,14 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
}
|
||||
this.df.on_change && this.df.on_change();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
set_checked_options() {
|
||||
this.selected_options = this.options
|
||||
.filter(o => o.checked)
|
||||
.map(o => o.value);
|
||||
this.select_options(this.selected_options);
|
||||
},
|
||||
}
|
||||
|
||||
setup_select_all() {
|
||||
this.$select_buttons.show();
|
||||
|
|
@ -112,31 +112,31 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
this.$select_buttons.find('.deselect-all').on('click', () => {
|
||||
this.select_all(true);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
select_all(deselect=false) {
|
||||
$(this.wrapper).find(`:checkbox`).prop("checked", deselect).trigger('click');
|
||||
},
|
||||
}
|
||||
|
||||
select_options(selected_options) {
|
||||
this.options.map(option => option.value).forEach(value => {
|
||||
let $checkbox = $(this.wrapper).find(`:checkbox[data-unit="${value}"]`)[0];
|
||||
if($checkbox) $checkbox.checked = selected_options.includes(value);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_value() {
|
||||
return this.selected_options;
|
||||
},
|
||||
}
|
||||
|
||||
get_checked_options() {
|
||||
return this.get_value();
|
||||
},
|
||||
}
|
||||
|
||||
get_unchecked_options() {
|
||||
return this.options.map(o => o.value)
|
||||
.filter(value => !this.selected_options.includes(value));
|
||||
},
|
||||
}
|
||||
|
||||
get_checkbox_element(option) {
|
||||
const column_size = this.get_column_size();
|
||||
|
|
@ -148,7 +148,7 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
</label>
|
||||
</div>
|
||||
`);
|
||||
},
|
||||
}
|
||||
|
||||
get_select_buttons() {
|
||||
return $(`
|
||||
|
|
@ -161,9 +161,9 @@ frappe.ui.form.ControlMultiCheck = frappe.ui.form.Control.extend({
|
|||
</button>
|
||||
</div>
|
||||
`);
|
||||
},
|
||||
}
|
||||
|
||||
get_column_size() {
|
||||
return 12 / (+this.df.columns || 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import Awesomplete from 'awesomplete';
|
||||
|
||||
frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
||||
frappe.ui.form.ControlMultiSelect = class ControlMultiSelect extends frappe.ui.form.ControlAutocomplete {
|
||||
get_awesomplete_settings() {
|
||||
const settings = this._super();
|
||||
const settings = super.get_awesomplete_settings();
|
||||
|
||||
return Object.assign(settings, {
|
||||
filter: function(text, input) {
|
||||
|
|
@ -30,10 +30,10 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
|||
this.input.value = before + text + ", ";
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_value() {
|
||||
let data = this._super();
|
||||
let data = super.get_value();
|
||||
// find value of label from option list and return actual value string
|
||||
if (this.df.options && this.df.options.length && this.df.options[0].label) {
|
||||
data = data.split(',').map(op => op.trim());
|
||||
|
|
@ -43,7 +43,7 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
|||
}).filter(n => n != null).join(', ');
|
||||
}
|
||||
return data;
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
if (!value) return;
|
||||
|
|
@ -54,15 +54,15 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
|||
return option ? option.label : val;
|
||||
}).filter(n => n != null).join(', ');
|
||||
}
|
||||
this._super(value);
|
||||
},
|
||||
super.set_formatted_input(value);
|
||||
}
|
||||
|
||||
get_values() {
|
||||
const value = this.get_value() || '';
|
||||
const values = value.split(/\s*,\s*/).filter(d => d);
|
||||
|
||||
return values;
|
||||
},
|
||||
}
|
||||
|
||||
get_data() {
|
||||
let data;
|
||||
|
|
@ -70,7 +70,7 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
|||
data = this.df.get_data();
|
||||
if (data) this.set_data(data);
|
||||
} else {
|
||||
data = this._super();
|
||||
data = super.get_data();
|
||||
}
|
||||
const values = this.get_values() || [];
|
||||
|
||||
|
|
@ -78,4 +78,4 @@ frappe.ui.form.ControlMultiSelect = frappe.ui.form.ControlAutocomplete.extend({
|
|||
if(data) data.filter(d => !values.includes(d));
|
||||
return data;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
||||
trigger_change_on_input_event: false,
|
||||
frappe.ui.form.ControlMultiSelectList = class ControlMultiSelectList extends frappe.ui.form.ControlData {
|
||||
static trigger_change_on_input_event = false
|
||||
make_input() {
|
||||
let template = `
|
||||
<div class="multiselect-list dropdown">
|
||||
|
|
@ -84,7 +84,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
this._options = [];
|
||||
this._selected_values = [];
|
||||
this.highlighted = -1;
|
||||
},
|
||||
}
|
||||
|
||||
set_input_attributes() {
|
||||
this.$list_wrapper
|
||||
|
|
@ -102,7 +102,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
if(this.df.input_class) {
|
||||
this.$list_wrapper.addClass(this.df.input_class);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
toggle_select_item($selectable_item) {
|
||||
$selectable_item.toggleClass('selected');
|
||||
|
|
@ -116,7 +116,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
this.update_selected_values(value);
|
||||
this.parse_validate_and_set_in_model('');
|
||||
this.update_status();
|
||||
},
|
||||
}
|
||||
|
||||
set_value(value) {
|
||||
if (!value) return Promise.resolve();
|
||||
|
|
@ -130,7 +130,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
this.parse_validate_and_set_in_model('');
|
||||
this.update_status();
|
||||
return Promise.resolve();
|
||||
},
|
||||
}
|
||||
|
||||
update_selected_values(value) {
|
||||
this._selected_values = this._selected_values || [];
|
||||
|
|
@ -142,7 +142,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
this._selected_values = this._selected_values.filter(opt => opt.value !== value);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
update_status() {
|
||||
let text;
|
||||
|
|
@ -156,15 +156,15 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
text = __('{0} values selected', [this.values.length]);
|
||||
}
|
||||
this.set_status(text);
|
||||
},
|
||||
}
|
||||
|
||||
get_placeholder_text() {
|
||||
return `<span class="text-extra-muted">${this.df.placeholder || ''}</span>`;
|
||||
},
|
||||
}
|
||||
|
||||
set_status(text) {
|
||||
this.$list_wrapper.find('.status-text').html(text);
|
||||
},
|
||||
}
|
||||
|
||||
set_options() {
|
||||
let promise = Promise.resolve();
|
||||
|
|
@ -200,7 +200,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
this._options = process_options(this.df.options);
|
||||
}
|
||||
return promise;
|
||||
},
|
||||
}
|
||||
|
||||
set_selectable_items(options) {
|
||||
let html = options.map(option => {
|
||||
|
|
@ -222,11 +222,11 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
.html(html);
|
||||
|
||||
this.highlighted = -1;
|
||||
},
|
||||
}
|
||||
|
||||
get_value() {
|
||||
return this.values;
|
||||
},
|
||||
}
|
||||
|
||||
highlight_item(value) {
|
||||
this.highlighted += value;
|
||||
|
|
@ -246,7 +246,7 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
this._$last_highlighted = $($item).addClass('highlighted');
|
||||
this.scroll_dropdown_if_needed($item);
|
||||
},
|
||||
}
|
||||
|
||||
scroll_dropdown_if_needed($item) {
|
||||
if ($item.scrollIntoView) {
|
||||
|
|
@ -255,4 +255,4 @@ frappe.ui.form.ControlMultiSelectList = frappe.ui.form.ControlData.extend({
|
|||
$item.parentNode.scrollTop = $item.offsetTop - $item.parentNode.offsetTop;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import Awesomplete from 'awesomplete';
|
||||
|
||||
frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.extend({
|
||||
frappe.ui.form.ControlMultiSelectPills = class ControlMultiSelectPills extends frappe.ui.form.ControlAutocomplete {
|
||||
make_input() {
|
||||
this._super();
|
||||
super.make_input();
|
||||
this.$input_area = $(this.input_area);
|
||||
this.$multiselect_wrapper = $('<div>')
|
||||
.addClass('form-control table-multiselect')
|
||||
|
|
@ -35,7 +35,7 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
this.parse_validate_and_set_in_model('');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
parse(value) {
|
||||
if (value) {
|
||||
|
|
@ -43,7 +43,7 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
}
|
||||
|
||||
return this.rows;
|
||||
},
|
||||
}
|
||||
|
||||
validate(value) {
|
||||
const rows = (value || []).slice();
|
||||
|
|
@ -66,12 +66,12 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
}
|
||||
|
||||
return rows;
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
this.rows = value || [];
|
||||
this.set_pill_html(this.rows);
|
||||
},
|
||||
}
|
||||
|
||||
set_pill_html(values) {
|
||||
const html = values
|
||||
|
|
@ -80,7 +80,7 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
|
||||
this.$multiselect_wrapper.find('.tb-selected-value').remove();
|
||||
this.$multiselect_wrapper.prepend(html);
|
||||
},
|
||||
}
|
||||
|
||||
get_pill_html(value) {
|
||||
const encoded_value = encodeURIComponent(value);
|
||||
|
|
@ -90,10 +90,10 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
<span class="btn-remove">${frappe.utils.icon('close')}</span>
|
||||
</button>
|
||||
`;
|
||||
},
|
||||
}
|
||||
|
||||
get_awesomplete_settings() {
|
||||
const settings = this._super();
|
||||
const settings = super.get_awesomplete_settings();
|
||||
|
||||
return Object.assign(settings, {
|
||||
filter: function(text, input) {
|
||||
|
|
@ -116,15 +116,15 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
return v;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_value() {
|
||||
return this.rows;
|
||||
},
|
||||
}
|
||||
|
||||
get_values() {
|
||||
return this.rows;
|
||||
},
|
||||
}
|
||||
|
||||
get_data() {
|
||||
let data;
|
||||
|
|
@ -140,7 +140,7 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
this.set_data(data);
|
||||
}
|
||||
} else {
|
||||
data = this._super();
|
||||
data = super.get_data();
|
||||
}
|
||||
const values = this.get_values() || [];
|
||||
|
||||
|
|
@ -148,4 +148,4 @@ frappe.ui.form.ControlMultiSelectPills = frappe.ui.form.ControlAutocomplete.exte
|
|||
if (data) data.filter(d => !values.includes(d));
|
||||
return data;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
frappe.ui.form.ControlPassword = frappe.ui.form.ControlData.extend({
|
||||
input_type: "password",
|
||||
make: function() {
|
||||
this._super();
|
||||
},
|
||||
make_input: function() {
|
||||
frappe.ui.form.ControlPassword = class ControlPassword extends frappe.ui.form.ControlData {
|
||||
static input_type = "password"
|
||||
make() {
|
||||
super.make();
|
||||
}
|
||||
make_input() {
|
||||
var me = this;
|
||||
this._super();
|
||||
super.make_input();
|
||||
this.$input.parent().append($('<span class="password-strength-indicator indicator"></span>'));
|
||||
this.$wrapper.find('.control-input-wrapper').append($('<p class="password-strength-message text-muted small hidden"></p>'));
|
||||
|
||||
|
|
@ -18,8 +18,8 @@ frappe.ui.form.ControlPassword = frappe.ui.form.ControlData.extend({
|
|||
me.get_password_strength(me.$input.val());
|
||||
}, 500);
|
||||
});
|
||||
},
|
||||
get_password_strength: function(value) {
|
||||
}
|
||||
get_password_strength(value) {
|
||||
var me = this;
|
||||
frappe.call({
|
||||
type: 'POST',
|
||||
|
|
@ -41,10 +41,10 @@ frappe.ui.form.ControlPassword = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
|
||||
});
|
||||
},
|
||||
set_strength_indicator: function(color) {
|
||||
}
|
||||
set_strength_indicator(color) {
|
||||
var message = __("Include symbols, numbers and capital letters in the password");
|
||||
this.indicator.removeClass().addClass('password-strength-indicator indicator ' + color);
|
||||
this.message.html(message).removeClass('hidden');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
frappe.ui.form.ControlRating = frappe.ui.form.ControlInt.extend({
|
||||
frappe.ui.form.ControlRating = class ControlRating extends frappe.ui.form.ControlInt {
|
||||
make_input() {
|
||||
this._super();
|
||||
super.make_input();
|
||||
let stars = '';
|
||||
[1, 2, 3, 4, 5].forEach(i => {
|
||||
stars += `<svg class="icon icon-md" data-rating=${i}>
|
||||
|
|
@ -47,10 +47,10 @@ frappe.ui.form.ControlRating = frappe.ui.form.ControlInt.extend({
|
|||
this.set_input(star_value);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
get_value() {
|
||||
return cint(this.value, null);
|
||||
},
|
||||
}
|
||||
set_formatted_input(value) {
|
||||
let el = $(this.input_area).find('svg');
|
||||
el.children('svg').prevObject.each( function(e) {
|
||||
|
|
@ -61,4 +61,4 @@ frappe.ui.form.ControlRating = frappe.ui.form.ControlInt.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
frappe.ui.form.ControlReadOnly = frappe.ui.form.ControlData.extend({
|
||||
get_status: function(explain) {
|
||||
var status = this._super(explain);
|
||||
frappe.ui.form.ControlReadOnly = class ControlReadOnly extends frappe.ui.form.ControlData {
|
||||
get_status(explain) {
|
||||
var status = super.get_status(explain);
|
||||
if(status==="Write")
|
||||
status = "Read";
|
||||
return;
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
||||
html_element: 'select',
|
||||
make_input: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlSelect = class ControlSelect extends frappe.ui.form.ControlData {
|
||||
static html_element = 'select';
|
||||
make_input() {
|
||||
super.make_input();
|
||||
|
||||
const is_xs_input = this.df.input_class
|
||||
&& this.df.input_class.includes('input-xs');
|
||||
|
|
@ -10,8 +10,8 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
|
||||
this.$input.addClass('ellipsis');
|
||||
this.set_options();
|
||||
},
|
||||
set_icon: function(is_xs_input) {
|
||||
}
|
||||
set_icon(is_xs_input) {
|
||||
const select_icon_html =
|
||||
`<div class="select-icon ${is_xs_input ? 'xs' : ''}">
|
||||
${frappe.utils.icon('select', is_xs_input ? 'xs' : 'sm')}
|
||||
|
|
@ -23,8 +23,8 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
.addClass('flex align-center')
|
||||
.append(select_icon_html);
|
||||
}
|
||||
},
|
||||
set_placeholder: function(is_xs_input) {
|
||||
}
|
||||
set_placeholder(is_xs_input) {
|
||||
const placeholder_html =
|
||||
`<div class="placeholder ellipsis text-extra-muted ${is_xs_input ? 'xs' : ''}">
|
||||
<span>${this.df.placeholder}</span>
|
||||
|
|
@ -36,14 +36,14 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
}
|
||||
this.toggle_placeholder();
|
||||
this.$input && this.$input.on('select-change', () => this.toggle_placeholder());
|
||||
},
|
||||
set_formatted_input: function(value) {
|
||||
}
|
||||
set_formatted_input(value) {
|
||||
// refresh options first - (new ones??)
|
||||
if(value==null) value = '';
|
||||
this.set_options(value);
|
||||
|
||||
// set in the input element
|
||||
this._super(value);
|
||||
super.set_formatted_input(value);
|
||||
|
||||
// check if the value to be set is selected
|
||||
var input_value = '';
|
||||
|
|
@ -56,8 +56,8 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
// model value must be same as whatever the input is
|
||||
this.set_model_value(input_value);
|
||||
}
|
||||
},
|
||||
set_options: function(value) {
|
||||
}
|
||||
set_options(value) {
|
||||
// reset options, if something new is set
|
||||
var options = this.df.options || [];
|
||||
|
||||
|
|
@ -79,8 +79,8 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
this.$input.val(selected);
|
||||
}
|
||||
}
|
||||
},
|
||||
get_file_attachment_list: function() {
|
||||
}
|
||||
get_file_attachment_list() {
|
||||
if(!this.frm) return;
|
||||
var fl = frappe.model.docinfo[this.frm.doctype][this.frm.docname];
|
||||
if(fl && fl.attachments) {
|
||||
|
|
@ -94,12 +94,12 @@ frappe.ui.form.ControlSelect = frappe.ui.form.ControlData.extend({
|
|||
this.set_description(__("Please attach a file first."));
|
||||
return [""];
|
||||
}
|
||||
},
|
||||
toggle_placeholder: function() {
|
||||
}
|
||||
toggle_placeholder() {
|
||||
const input_set = Boolean(this.$input.find('option:selected').text());
|
||||
this.$wrapper.find('.placeholder').toggle(!input_set);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// add <option> list to <select>
|
||||
(function($) {
|
||||
|
|
|
|||
|
|
@ -1,31 +1,24 @@
|
|||
frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
||||
saving: false,
|
||||
loading: false,
|
||||
make: function() {
|
||||
frappe.ui.form.ControlSignature = class ControlSignature extends frappe.ui.form.ControlData {
|
||||
make() {
|
||||
var me = this;
|
||||
this._super();
|
||||
this.saving = false;
|
||||
this.loading = false;
|
||||
super.make();
|
||||
|
||||
// make jSignature field
|
||||
this.body = $('<div class="signature-field"></div>').appendTo(me.wrapper);
|
||||
this.load_lib().then(() => {
|
||||
// make jSignature field
|
||||
this.body = $('<div class="signature-field"></div>').appendTo(me.wrapper);
|
||||
|
||||
if (this.body.is(':visible')) {
|
||||
this.make_pad();
|
||||
} else {
|
||||
$(document).on('frappe.ui.Dialog:shown', () => {
|
||||
if (this.body.is(':visible')) {
|
||||
this.make_pad();
|
||||
});
|
||||
}
|
||||
|
||||
this.img_wrapper = $(`<div class="signature-display">
|
||||
<div class="missing-image attach-missing-image">
|
||||
${frappe.utils.icon('restriction', 'md')}</i>
|
||||
</div></div>`)
|
||||
.appendTo(this.wrapper);
|
||||
this.img = $("<img class='img-responsive attach-image-display'>")
|
||||
.appendTo(this.img_wrapper).toggle(false);
|
||||
|
||||
},
|
||||
make_pad: function() {
|
||||
} else {
|
||||
$(document).on('frappe.ui.Dialog:shown', () => {
|
||||
this.make_pad();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
make_pad() {
|
||||
let width = this.body.width();
|
||||
if (width > 0 && !this.$pad) {
|
||||
this.$pad = this.body.jSignature({
|
||||
|
|
@ -51,8 +44,16 @@ frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
|||
});
|
||||
|
||||
}
|
||||
},
|
||||
refresh_input: function(e) {
|
||||
|
||||
this.img_wrapper = $(`<div class="signature-display">
|
||||
<div class="missing-image attach-missing-image">
|
||||
${frappe.utils.icon('restriction', 'md')}</i>
|
||||
</div></div>`)
|
||||
.appendTo(this.wrapper);
|
||||
this.img = $("<img class='img-responsive attach-image-display'>")
|
||||
.appendTo(this.img_wrapper).toggle(false);
|
||||
}
|
||||
refresh_input(e) {
|
||||
// prevent to load the second time
|
||||
this.make_pad();
|
||||
this.$wrapper.find(".control-input").toggle(false);
|
||||
|
|
@ -61,8 +62,8 @@ frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
|||
if(this.get_status()=="Read") {
|
||||
$(this.disp_area).toggle(false);
|
||||
}
|
||||
},
|
||||
set_image: function(value) {
|
||||
}
|
||||
set_image(value) {
|
||||
if(value) {
|
||||
$(this.img_wrapper).find(".missing-image").toggle(false);
|
||||
this.img.attr("src", value).toggle(true);
|
||||
|
|
@ -70,8 +71,8 @@ frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
|||
$(this.img_wrapper).find(".missing-image").toggle(true);
|
||||
this.img.toggle(false);
|
||||
}
|
||||
},
|
||||
load_pad: function() {
|
||||
}
|
||||
load_pad() {
|
||||
// make sure not triggered during saving
|
||||
if (this.saving) return;
|
||||
// get value
|
||||
|
|
@ -95,8 +96,8 @@ frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
|||
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
set_editable: function(editable) {
|
||||
}
|
||||
set_editable(editable) {
|
||||
this.$pad && this.$pad.toggle(editable);
|
||||
this.img_wrapper.toggle(!editable);
|
||||
if (this.$reset_button_wrapper) {
|
||||
|
|
@ -108,26 +109,33 @@ frappe.ui.form.ControlSignature = frappe.ui.form.ControlData.extend({
|
|||
this.$reset_button_wrapper.removeClass('editing');
|
||||
}
|
||||
}
|
||||
},
|
||||
set_my_value: function(value) {
|
||||
}
|
||||
set_my_value(value) {
|
||||
if (this.saving || this.loading) return;
|
||||
this.saving = true;
|
||||
this.set_value(value);
|
||||
this.saving = false;
|
||||
},
|
||||
get_value: function() {
|
||||
}
|
||||
get_value() {
|
||||
return this.value ? this.value: this.get_model_value();
|
||||
},
|
||||
}
|
||||
// reset signature canvas
|
||||
on_reset_sign: function() {
|
||||
on_reset_sign() {
|
||||
this.$pad.jSignature("reset");
|
||||
this.set_my_value("");
|
||||
},
|
||||
}
|
||||
// save signature value to model and display
|
||||
on_save_sign: function() {
|
||||
on_save_sign() {
|
||||
if (this.saving || this.loading) return;
|
||||
var base64_img = this.$pad.jSignature("getData");
|
||||
this.set_my_value(base64_img);
|
||||
this.set_image(this.get_value());
|
||||
}
|
||||
});
|
||||
|
||||
load_lib() {
|
||||
if (!this.load_lib_promise) {
|
||||
this.load_lib_promise = frappe.require('/assets/frappe/js/lib/jSignature.min.js');
|
||||
}
|
||||
return this.load_lib_promise;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import Grid from '../grid';
|
||||
|
||||
frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({
|
||||
make: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlTable = class ControlTable extends frappe.ui.form.Control {
|
||||
make() {
|
||||
super.make();
|
||||
|
||||
// add title if prev field is not column / section heading or html
|
||||
this.grid = new Grid({
|
||||
|
|
@ -84,7 +84,7 @@ frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({
|
|||
});
|
||||
return false; // Prevent the default handler from running.
|
||||
});
|
||||
},
|
||||
}
|
||||
get_field(field_name) {
|
||||
let fieldname;
|
||||
this.grid.meta.fields.some(field => {
|
||||
|
|
@ -106,22 +106,22 @@ frappe.ui.form.ControlTable = frappe.ui.form.Control.extend({
|
|||
}
|
||||
});
|
||||
return fieldname;
|
||||
},
|
||||
refresh_input: function() {
|
||||
}
|
||||
refresh_input() {
|
||||
this.grid.refresh();
|
||||
},
|
||||
get_value: function() {
|
||||
}
|
||||
get_value() {
|
||||
if(this.grid) {
|
||||
return this.grid.get_data();
|
||||
}
|
||||
},
|
||||
set_input: function( ) {
|
||||
}
|
||||
set_input( ) {
|
||||
//
|
||||
},
|
||||
validate: function() {
|
||||
}
|
||||
validate() {
|
||||
return this.get_value();
|
||||
},
|
||||
}
|
||||
check_all_rows() {
|
||||
this.$wrapper.find('.grid-row-check')[0].click();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
||||
frappe.ui.form.ControlTableMultiSelect = class ControlTableMultiSelect extends frappe.ui.form.ControlLink {
|
||||
make_input() {
|
||||
this._super();
|
||||
super.make_input();
|
||||
|
||||
this.$input_area.addClass('form-control table-multiselect');
|
||||
this.$input.removeClass('form-control');
|
||||
|
|
@ -45,10 +45,10 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
this.parse_validate_and_set_in_model('');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
setup_buttons() {
|
||||
this.$input_area.find('.link-btn').remove();
|
||||
},
|
||||
}
|
||||
parse(value) {
|
||||
const link_field = this.get_link_field();
|
||||
|
||||
|
|
@ -65,11 +65,11 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
}
|
||||
this._rows_list = this.rows.map(row => row[link_field.fieldname]);
|
||||
return this.rows;
|
||||
},
|
||||
}
|
||||
get_model_value() {
|
||||
let value = this._super();
|
||||
let value = super.get_model_value();
|
||||
return value ? value.filter(d => !d.__islocal) : value;
|
||||
},
|
||||
}
|
||||
validate(value) {
|
||||
const rows = (value || []).slice();
|
||||
|
||||
|
|
@ -110,13 +110,13 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
return rows;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
set_formatted_input(value) {
|
||||
this.rows = value || [];
|
||||
const link_field = this.get_link_field();
|
||||
const values = this.rows.map(row => row[link_field.fieldname]);
|
||||
this.set_pill_html(values);
|
||||
},
|
||||
}
|
||||
set_pill_html(values) {
|
||||
const html = values
|
||||
.map(value => this.get_pill_html(value))
|
||||
|
|
@ -124,7 +124,7 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
|
||||
this.$input_area.find('.tb-selected-value').remove();
|
||||
this.$input_area.prepend(html);
|
||||
},
|
||||
}
|
||||
get_pill_html(value) {
|
||||
const encoded_value = encodeURIComponent(value);
|
||||
return `
|
||||
|
|
@ -133,10 +133,10 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
<span class="btn-remove">${frappe.utils.icon('close')}</span>
|
||||
</button>
|
||||
`;
|
||||
},
|
||||
}
|
||||
get_options() {
|
||||
return (this.get_link_field() || {}).options;
|
||||
},
|
||||
}
|
||||
get_link_field() {
|
||||
if (!this._link_field) {
|
||||
const meta = frappe.get_meta(this.df.options);
|
||||
|
|
@ -146,8 +146,8 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
}
|
||||
}
|
||||
return this._link_field;
|
||||
},
|
||||
custom_awesomplete_filter: function(awesomplete) {
|
||||
}
|
||||
custom_awesomplete_filter(awesomplete) {
|
||||
let me = this;
|
||||
|
||||
awesomplete.filter = function(item) {
|
||||
|
|
@ -158,4 +158,4 @@ frappe.ui.form.ControlTableMultiSelect = frappe.ui.form.ControlLink.extend({
|
|||
return true;
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
frappe.ui.form.ControlText = frappe.ui.form.ControlData.extend({
|
||||
html_element: "textarea",
|
||||
horizontal: false,
|
||||
make_wrapper: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlText = class ControlText extends frappe.ui.form.ControlData {
|
||||
static html_element = "textarea"
|
||||
static horizontal = false
|
||||
make_wrapper() {
|
||||
super.make_wrapper();
|
||||
this.$wrapper.find(".like-disabled-input").addClass("for-description");
|
||||
},
|
||||
make_input: function() {
|
||||
this._super();
|
||||
}
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.$input.css({'height': '300px'});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.form.ControlLongText = frappe.ui.form.ControlText;
|
||||
frappe.ui.form.ControlSmallText = frappe.ui.form.ControlText.extend({
|
||||
make_input: function() {
|
||||
this._super();
|
||||
frappe.ui.form.ControlSmallText = class ControlSmallText extends frappe.ui.form.ControlText {
|
||||
make_input() {
|
||||
super.make_input();
|
||||
this.$input.css({'height': '150px'});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -68,22 +68,22 @@ CustomColor.tagName = "font";
|
|||
|
||||
Quill.register(CustomColor, true);
|
||||
|
||||
frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
||||
frappe.ui.form.ControlTextEditor = class ControlTextEditor extends frappe.ui.form.ControlCode {
|
||||
make_wrapper() {
|
||||
this._super();
|
||||
},
|
||||
super.make_wrapper();
|
||||
}
|
||||
|
||||
make_input() {
|
||||
this.has_input = true;
|
||||
this.make_quill_editor();
|
||||
},
|
||||
}
|
||||
|
||||
make_quill_editor() {
|
||||
if (this.quill) return;
|
||||
this.quill_container = $('<div>').appendTo(this.input_area);
|
||||
this.quill = new Quill(this.quill_container[0], this.get_quill_options());
|
||||
this.bind_events();
|
||||
},
|
||||
}
|
||||
|
||||
bind_events() {
|
||||
this.quill.on('text-change', frappe.utils.debounce((delta, oldDelta, source) => {
|
||||
|
|
@ -135,13 +135,13 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
|
||||
e.preventDefault();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
is_quill_dirty(source) {
|
||||
if (source === 'api') return false;
|
||||
let input_value = this.get_input_value();
|
||||
return this.value !== input_value;
|
||||
},
|
||||
}
|
||||
|
||||
get_quill_options() {
|
||||
return {
|
||||
|
|
@ -152,7 +152,7 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
},
|
||||
theme: 'snow'
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
get_toolbar_options() {
|
||||
return [
|
||||
|
|
@ -174,14 +174,14 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
'delete-table',
|
||||
]}],
|
||||
];
|
||||
},
|
||||
}
|
||||
|
||||
parse(value) {
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
return frappe.dom.remove_script_and_style(value);
|
||||
},
|
||||
}
|
||||
|
||||
set_formatted_input(value) {
|
||||
if (!this.quill) return;
|
||||
|
|
@ -195,7 +195,7 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
// set html without triggering a focus
|
||||
const delta = this.quill.clipboard.convert({ html: value, text: '' });
|
||||
this.quill.setContents(delta);
|
||||
},
|
||||
}
|
||||
|
||||
get_input_value() {
|
||||
let value = this.quill ? this.quill.root.innerHTML : '';
|
||||
|
|
@ -211,9 +211,9 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({
|
|||
}
|
||||
|
||||
return value;
|
||||
},
|
||||
}
|
||||
|
||||
set_focus() {
|
||||
this.quill.focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
||||
set_formatted_input: function(value) {
|
||||
this._super(value);
|
||||
},
|
||||
make_input: function() {
|
||||
frappe.ui.form.ControlTime = class ControlTime extends frappe.ui.form.ControlDate {
|
||||
set_formatted_input(value) {
|
||||
super.set_formatted_input(value);
|
||||
}
|
||||
make_input() {
|
||||
this.timepicker_only = true;
|
||||
this._super();
|
||||
},
|
||||
make_picker: function() {
|
||||
super.make_input();
|
||||
}
|
||||
make_picker() {
|
||||
this.set_time_options();
|
||||
this.set_datepicker();
|
||||
this.refresh();
|
||||
},
|
||||
set_time_options: function() {
|
||||
}
|
||||
set_time_options() {
|
||||
let sysdefaults = frappe.boot.sysdefaults;
|
||||
|
||||
let time_format = sysdefaults && sysdefaults.time_format
|
||||
|
|
@ -38,9 +38,9 @@ frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
|||
keyboardNav: false,
|
||||
todayButton: true
|
||||
};
|
||||
},
|
||||
set_input: function(value) {
|
||||
this._super(value);
|
||||
}
|
||||
set_input(value) {
|
||||
super.set_input(value);
|
||||
if (value
|
||||
&& ((this.last_value && this.last_value !== this.value)
|
||||
|| (!this.datepicker.selectedDates.length))) {
|
||||
|
|
@ -49,8 +49,8 @@ frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
|||
var date_obj = frappe.datetime.moment_to_date_obj(moment(value, time_format));
|
||||
this.datepicker.selectDate(date_obj);
|
||||
}
|
||||
},
|
||||
set_datepicker: function() {
|
||||
}
|
||||
set_datepicker() {
|
||||
this.$input.datepicker(this.datepicker_options);
|
||||
this.datepicker = this.$input.data('datepicker');
|
||||
|
||||
|
|
@ -67,8 +67,8 @@ frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
|||
$tp.$secondsText.css('display', 'none');
|
||||
$tp.$secondsText.prev().css('display', 'none');
|
||||
}
|
||||
},
|
||||
set_description: function() {
|
||||
}
|
||||
set_description() {
|
||||
const { description } = this.df;
|
||||
const { time_zone } = frappe.sys_defaults;
|
||||
if (!frappe.datetime.is_timezone_same()) {
|
||||
|
|
@ -78,20 +78,20 @@ frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
|||
this.df.description += '<br>' + time_zone;
|
||||
}
|
||||
}
|
||||
this._super();
|
||||
},
|
||||
parse: function(value) {
|
||||
super.set_description();
|
||||
}
|
||||
parse(value) {
|
||||
if (value) {
|
||||
return frappe.datetime.user_to_str(value, true);
|
||||
}
|
||||
},
|
||||
format_for_input: function(value) {
|
||||
}
|
||||
format_for_input(value) {
|
||||
if (value) {
|
||||
return frappe.datetime.str_to_user(value, true);
|
||||
}
|
||||
return "";
|
||||
},
|
||||
validate: function(value) {
|
||||
}
|
||||
validate(value) {
|
||||
if (value && !frappe.datetime.validate(value)) {
|
||||
let sysdefaults = frappe.sys_defaults;
|
||||
let time_format = sysdefaults && sysdefaults.time_format
|
||||
|
|
@ -101,4 +101,4 @@ frappe.ui.form.ControlTime = frappe.ui.form.ControlDate.extend({
|
|||
}
|
||||
return value;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
import FormTimeline from "./form_timeline";
|
||||
frappe.ui.form.Footer = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.Footer = class FormFooter {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.make();
|
||||
this.make_comment_box();
|
||||
|
|
@ -11,15 +11,15 @@ frappe.ui.form.Footer = Class.extend({
|
|||
$(this.frm.wrapper).on("render_complete", () => {
|
||||
this.refresh();
|
||||
});
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
this.wrapper = $(frappe.render_template("form_footer", {}))
|
||||
.appendTo(this.parent);
|
||||
this.wrapper.find(".btn-save").click(() => {
|
||||
this.frm.save('Save', null, this);
|
||||
});
|
||||
},
|
||||
make_comment_box: function() {
|
||||
}
|
||||
make_comment_box() {
|
||||
this.frm.comment_box = frappe.ui.form.make_control({
|
||||
parent: this.wrapper.find(".comment-box"),
|
||||
render_input: true,
|
||||
|
|
@ -50,19 +50,19 @@ frappe.ui.form.Footer = Class.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
make_timeline() {
|
||||
this.frm.timeline = new FormTimeline({
|
||||
parent: this.wrapper.find(".timeline"),
|
||||
frm: this.frm
|
||||
});
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
if (this.frm.doc.__islocal) {
|
||||
this.parent.addClass("hide");
|
||||
} else {
|
||||
this.parent.removeClass("hide");
|
||||
this.frm.timeline.refresh();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@ import './script_helpers';
|
|||
import './sidebar/form_sidebar';
|
||||
import './footer/footer';
|
||||
|
||||
frappe.ui.form.Controller = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.Controller = class FormController {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.form.Form = class FrappeForm {
|
||||
constructor(doctype, parent, in_form, doctype_layout_name) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import '../class';
|
||||
|
||||
frappe.ui.form.Layout = Class.extend({
|
||||
init: function (opts) {
|
||||
frappe.ui.form.Layout = class Layout {
|
||||
constructor (opts) {
|
||||
this.views = {};
|
||||
this.pages = [];
|
||||
this.sections = [];
|
||||
|
|
@ -9,8 +9,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
this.fields_dict = {};
|
||||
|
||||
$.extend(this, opts);
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
if (!this.parent && this.body) {
|
||||
this.parent = this.body;
|
||||
}
|
||||
|
|
@ -21,14 +21,14 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
this.setup_tabbing();
|
||||
this.render();
|
||||
},
|
||||
show_empty_form_message: function() {
|
||||
}
|
||||
show_empty_form_message() {
|
||||
if (!(this.wrapper.find(".frappe-control:visible").length || this.wrapper.find(".section-head.collapsed").length)) {
|
||||
this.show_message(__("This form does not have any input"));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_doctype_fields: function() {
|
||||
get_doctype_fields() {
|
||||
let fields = [
|
||||
this.get_new_name_field()
|
||||
];
|
||||
|
|
@ -39,7 +39,7 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
|
||||
return fields;
|
||||
},
|
||||
}
|
||||
|
||||
get_new_name_field() {
|
||||
return {
|
||||
|
|
@ -58,7 +58,7 @@ frappe.ui.form.Layout = Class.extend({
|
|||
return 'None';
|
||||
}
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
get_fields_from_layout() {
|
||||
const fields = [];
|
||||
|
|
@ -68,9 +68,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
fields.push(docfield);
|
||||
}
|
||||
return fields;
|
||||
},
|
||||
}
|
||||
|
||||
show_message: function(html, color) {
|
||||
show_message(html, color) {
|
||||
if (this.message_color) {
|
||||
// remove previous color
|
||||
this.message.removeClass(this.message_color);
|
||||
|
|
@ -86,8 +86,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
} else {
|
||||
this.message.empty().addClass('hidden');
|
||||
}
|
||||
},
|
||||
render: function (new_fields) {
|
||||
}
|
||||
render (new_fields) {
|
||||
var me = this;
|
||||
var fields = new_fields || this.fields;
|
||||
|
||||
|
|
@ -117,19 +117,19 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
no_opening_section: function () {
|
||||
no_opening_section () {
|
||||
return (this.fields[0] && this.fields[0].fieldtype != "Section Break") || !this.fields.length;
|
||||
},
|
||||
}
|
||||
|
||||
setup_dashboard_section: function () {
|
||||
setup_dashboard_section () {
|
||||
if (this.no_opening_section()) {
|
||||
this.fields.unshift({fieldtype: 'Section Break'});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
replace_field: function (fieldname, df, render) {
|
||||
replace_field (fieldname, df, render) {
|
||||
df.fieldname = fieldname; // change of fieldname is avoided
|
||||
if (this.fields_dict[fieldname] && this.fields_dict[fieldname].df) {
|
||||
const fieldobj = this.init_field(df, render);
|
||||
|
|
@ -143,9 +143,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
this.section.fields_dict[fieldname] = fieldobj;
|
||||
this.refresh_fields([df]);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
make_field: function (df, colspan, render) {
|
||||
make_field (df, colspan, render) {
|
||||
!this.section && this.make_section();
|
||||
!this.column && this.make_column();
|
||||
|
||||
|
|
@ -159,9 +159,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
this.section.fields_list.push(fieldobj);
|
||||
this.section.fields_dict[df.fieldname] = fieldobj;
|
||||
fieldobj.section = this.section;
|
||||
},
|
||||
}
|
||||
|
||||
init_field: function (df, render = false) {
|
||||
init_field (df, render = false) {
|
||||
const fieldobj = frappe.ui.form.make_control({
|
||||
df: df,
|
||||
doctype: this.doctype,
|
||||
|
|
@ -174,9 +174,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
fieldobj.layout = this;
|
||||
return fieldobj;
|
||||
},
|
||||
}
|
||||
|
||||
make_page: function (df) { // eslint-disable-line no-unused-vars
|
||||
make_page (df) { // eslint-disable-line no-unused-vars
|
||||
var me = this,
|
||||
head = $('<div class="form-clickable-section text-center">\
|
||||
<a class="btn-fold h6 text-muted">' + __("Show more details") + '</a>\
|
||||
|
|
@ -200,13 +200,13 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
this.section = null;
|
||||
this.folded = true;
|
||||
},
|
||||
}
|
||||
|
||||
unfold: function () {
|
||||
unfold () {
|
||||
this.fold_btn.trigger('click');
|
||||
},
|
||||
}
|
||||
|
||||
make_section: function (df) {
|
||||
make_section (df) {
|
||||
this.section = new frappe.ui.form.Section(this, df);
|
||||
|
||||
// append to layout fields
|
||||
|
|
@ -216,16 +216,16 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
|
||||
this.column = null;
|
||||
},
|
||||
}
|
||||
|
||||
make_column: function (df) {
|
||||
make_column (df) {
|
||||
this.column = new frappe.ui.form.Column(this.section, df);
|
||||
if (df && df.fieldname) {
|
||||
this.fields_list.push(this.column);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
refresh: function (doc) {
|
||||
refresh (doc) {
|
||||
var me = this;
|
||||
if (doc) this.doc = doc;
|
||||
|
||||
|
|
@ -250,9 +250,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
// collapse sections
|
||||
this.refresh_section_collapse();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
refresh_sections: function() {
|
||||
refresh_sections() {
|
||||
// hide invisible sections
|
||||
this.wrapper.find(".form-section:not(.hide-control)").each(function() {
|
||||
const section = $(this).removeClass("empty-section visible-section");
|
||||
|
|
@ -266,9 +266,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
this.frm && this.frm.dashboard.refresh();
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
refresh_fields: function (fields) {
|
||||
refresh_fields (fields) {
|
||||
let fieldnames = fields.map((field) => {
|
||||
if (field.fieldname) return field.fieldname;
|
||||
});
|
||||
|
|
@ -281,14 +281,14 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
add_fields: function (fields) {
|
||||
add_fields (fields) {
|
||||
this.render(fields);
|
||||
this.refresh_fields(fields);
|
||||
},
|
||||
}
|
||||
|
||||
refresh_section_collapse: function () {
|
||||
refresh_section_collapse () {
|
||||
if (!(this.sections && this.sections.length)) return;
|
||||
|
||||
for (var i = 0; i < this.sections.length; i++) {
|
||||
|
|
@ -308,9 +308,9 @@ frappe.ui.form.Layout = Class.extend({
|
|||
section.collapse(collapse);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
attach_doc_and_docfields: function (refresh) {
|
||||
attach_doc_and_docfields (refresh) {
|
||||
var me = this;
|
||||
for (var i = 0, l = this.fields_list.length; i < l; i++) {
|
||||
var fieldobj = this.fields_list[i];
|
||||
|
|
@ -328,14 +328,14 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
refresh && fieldobj.df && fieldobj.refresh && fieldobj.refresh();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
refresh_section_count: function () {
|
||||
refresh_section_count () {
|
||||
this.wrapper.find(".section-count-label:visible").each(function (i) {
|
||||
$(this).html(i + 1);
|
||||
});
|
||||
},
|
||||
setup_tabbing: function () {
|
||||
}
|
||||
setup_tabbing () {
|
||||
var me = this;
|
||||
this.wrapper.on("keydown", function (ev) {
|
||||
if (ev.which == 9) {
|
||||
|
|
@ -346,8 +346,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
return me.handle_tab(doctype, fieldname, ev.shiftKey);
|
||||
}
|
||||
});
|
||||
},
|
||||
handle_tab: function (doctype, fieldname, shift) {
|
||||
}
|
||||
handle_tab (doctype, fieldname, shift) {
|
||||
var me = this,
|
||||
grid_row = null,
|
||||
prev = null,
|
||||
|
|
@ -405,8 +405,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
focus_on_next_field: function (start_idx, fields) {
|
||||
}
|
||||
focus_on_next_field (start_idx, fields) {
|
||||
// loop to find next eligible fields
|
||||
for (var i = start_idx + 1, len = fields.length; i < len; i++) {
|
||||
var field = fields[i];
|
||||
|
|
@ -427,11 +427,11 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
is_visible: function (field) {
|
||||
}
|
||||
is_visible (field) {
|
||||
return field.disp_status === "Write" && (field.$wrapper && field.$wrapper.is(":visible"));
|
||||
},
|
||||
set_focus: function (field) {
|
||||
}
|
||||
set_focus (field) {
|
||||
// next is table, show the table
|
||||
if (field.df.fieldtype=="Table") {
|
||||
if (!field.grid.grid_rows.length) {
|
||||
|
|
@ -444,11 +444,11 @@ frappe.ui.form.Layout = Class.extend({
|
|||
} else if (field.$input) {
|
||||
field.$input.focus();
|
||||
}
|
||||
},
|
||||
get_open_grid_row: function () {
|
||||
}
|
||||
get_open_grid_row () {
|
||||
return $(".grid-row-open").data("grid_row");
|
||||
},
|
||||
refresh_dependency: function () {
|
||||
}
|
||||
refresh_dependency () {
|
||||
// Resolve "depends_on" and show / hide accordingly
|
||||
var me = this;
|
||||
|
||||
|
|
@ -498,8 +498,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
}
|
||||
|
||||
this.refresh_section_count();
|
||||
},
|
||||
set_dependant_property: function (condition, fieldname, property) {
|
||||
}
|
||||
set_dependant_property (condition, fieldname, property) {
|
||||
let set_property = this.evaluate_depends_on_value(condition);
|
||||
let value = set_property ? 1 : 0;
|
||||
let form_obj;
|
||||
|
|
@ -520,8 +520,8 @@ frappe.ui.form.Layout = Class.extend({
|
|||
form_obj.set_df_property(fieldname, property, value);
|
||||
}
|
||||
}
|
||||
},
|
||||
evaluate_depends_on_value: function (expression) {
|
||||
}
|
||||
evaluate_depends_on_value (expression) {
|
||||
var out = null;
|
||||
var doc = this.doc;
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -564,10 +564,10 @@ frappe.ui.form.Layout = Class.extend({
|
|||
|
||||
return out;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.form.Section = Class.extend({
|
||||
init: function(layout, df) {
|
||||
frappe.ui.form.Section = class FormSection {
|
||||
constructor(layout, df) {
|
||||
this.layout = layout;
|
||||
this.df = df || {};
|
||||
this.fields_list = [];
|
||||
|
|
@ -581,8 +581,8 @@ frappe.ui.form.Section = Class.extend({
|
|||
};
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
if (!this.layout.page) {
|
||||
this.layout.page = $('<div class="form-page"></div>').appendTo(this.layout.wrapper);
|
||||
}
|
||||
|
|
@ -609,9 +609,9 @@ frappe.ui.form.Section = Class.extend({
|
|||
|
||||
// for bc
|
||||
this.body = $('<div class="section-body">').appendTo(this.wrapper);
|
||||
},
|
||||
}
|
||||
|
||||
make_head: function () {
|
||||
make_head () {
|
||||
this.head = $(`<div class="section-head">
|
||||
${__(this.df.label)}
|
||||
<span class="ml-2 collapse-indicator mb-1">
|
||||
|
|
@ -628,8 +628,8 @@ frappe.ui.form.Section = Class.extend({
|
|||
|
||||
this.indicator.show();
|
||||
}
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
if (!this.df)
|
||||
return;
|
||||
|
||||
|
|
@ -642,8 +642,8 @@ frappe.ui.form.Section = Class.extend({
|
|||
}
|
||||
|
||||
this.wrapper.toggleClass("hide-control", !!hide);
|
||||
},
|
||||
collapse: function (hide) {
|
||||
}
|
||||
collapse (hide) {
|
||||
// unknown edge case
|
||||
if (!(this.head && this.body)) {
|
||||
return;
|
||||
|
|
@ -666,13 +666,13 @@ frappe.ui.form.Section = Class.extend({
|
|||
f.refresh();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
is_collapsed() {
|
||||
return this.body.hasClass('hide');
|
||||
},
|
||||
}
|
||||
|
||||
has_missing_mandatory: function () {
|
||||
has_missing_mandatory () {
|
||||
var missing_mandatory = false;
|
||||
for (var j = 0, l = this.fields_list.length; j < l; j++) {
|
||||
var section_df = this.fields_list[j].df;
|
||||
|
|
@ -683,18 +683,18 @@ frappe.ui.form.Section = Class.extend({
|
|||
}
|
||||
return missing_mandatory;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.ui.form.Column = Class.extend({
|
||||
init: function(section, df) {
|
||||
frappe.ui.form.Column = class FormColumn {
|
||||
constructor(section, df) {
|
||||
if (!df) df = {};
|
||||
|
||||
this.df = df;
|
||||
this.section = section;
|
||||
this.make();
|
||||
this.resize_all_columns();
|
||||
},
|
||||
make: function () {
|
||||
}
|
||||
make () {
|
||||
this.wrapper = $('<div class="form-column">\
|
||||
<form>\
|
||||
</form>\
|
||||
|
|
@ -708,8 +708,8 @@ frappe.ui.form.Column = Class.extend({
|
|||
$('<label class="control-label">' + __(this.df.label)
|
||||
+ '</label>').appendTo(this.wrapper);
|
||||
}
|
||||
},
|
||||
resize_all_columns: function () {
|
||||
}
|
||||
resize_all_columns () {
|
||||
// distribute all columns equally
|
||||
var colspan = cint(12 / this.section.wrapper.find(".form-column").length);
|
||||
|
||||
|
|
@ -717,8 +717,8 @@ frappe.ui.form.Column = Class.extend({
|
|||
.addClass("form-column")
|
||||
.addClass("col-sm-" + colspan);
|
||||
|
||||
},
|
||||
refresh: function () {
|
||||
}
|
||||
refresh () {
|
||||
this.section.refresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.form.LinkSelector = Class.extend({
|
||||
init: function (opts) {
|
||||
frappe.ui.form.LinkSelector = class LinkSelector {
|
||||
constructor (opts) {
|
||||
/* help: Options: doctype, get_query, target */
|
||||
$.extend(this, opts);
|
||||
|
||||
|
|
@ -14,8 +14,8 @@ frappe.ui.form.LinkSelector = Class.extend({
|
|||
} else {
|
||||
this.make();
|
||||
}
|
||||
},
|
||||
make: function () {
|
||||
}
|
||||
make () {
|
||||
var me = this;
|
||||
|
||||
this.start = 0;
|
||||
|
|
@ -54,8 +54,8 @@ frappe.ui.form.LinkSelector = Class.extend({
|
|||
});
|
||||
this.dialog.show();
|
||||
this.search();
|
||||
},
|
||||
search: function () {
|
||||
}
|
||||
search () {
|
||||
var args = {
|
||||
txt: this.dialog.fields_dict.txt.get_value(),
|
||||
searchfield: "name",
|
||||
|
|
@ -129,8 +129,8 @@ frappe.ui.form.LinkSelector = Class.extend({
|
|||
|
||||
}, this.dialog.get_primary_btn());
|
||||
|
||||
},
|
||||
set_in_grid: function (value) {
|
||||
}
|
||||
set_in_grid (value) {
|
||||
var me = this, updated = false;
|
||||
var d = null;
|
||||
if (this.qty_fieldname) {
|
||||
|
|
@ -174,7 +174,7 @@ frappe.ui.form.LinkSelector = Class.extend({
|
|||
frappe.show_alert(__("{0} added", [value]));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
frappe.link_search = function (doctype, args, callback, btn) {
|
||||
if (!args) {
|
||||
|
|
|
|||
|
|
@ -18,16 +18,16 @@ frappe.ui.form.make_quick_entry = (doctype, after_insert, init_callback, doc, fo
|
|||
return frappe.quick_entry.setup();
|
||||
};
|
||||
|
||||
frappe.ui.form.QuickEntryForm = Class.extend({
|
||||
init: function(doctype, after_insert, init_callback, doc, force) {
|
||||
frappe.ui.form.QuickEntryForm = class QuickEntryForm {
|
||||
constructor(doctype, after_insert, init_callback, doc, force) {
|
||||
this.doctype = doctype;
|
||||
this.after_insert = after_insert;
|
||||
this.init_callback = init_callback;
|
||||
this.doc = doc;
|
||||
this.force = force ? force : false;
|
||||
},
|
||||
}
|
||||
|
||||
setup: function() {
|
||||
setup() {
|
||||
return new Promise(resolve => {
|
||||
frappe.model.with_doctype(this.doctype, () => {
|
||||
this.check_quick_entry_doc();
|
||||
|
|
@ -47,9 +47,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
set_meta_and_mandatory_fields: function() {
|
||||
set_meta_and_mandatory_fields() {
|
||||
this.meta = frappe.get_meta(this.doctype);
|
||||
let fields = this.meta.fields;
|
||||
|
||||
|
|
@ -57,15 +57,15 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
this.mandatory = fields.filter(df => {
|
||||
return ((df.reqd || df.bold || df.allow_in_quick_entry) && !df.read_only);
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
check_quick_entry_doc: function() {
|
||||
check_quick_entry_doc() {
|
||||
if (!this.doc) {
|
||||
this.doc = frappe.model.get_new_doc(this.doctype, null, null, true);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
is_quick_entry: function() {
|
||||
is_quick_entry() {
|
||||
if(this.meta.quick_entry != 1) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -77,33 +77,33 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
}
|
||||
|
||||
too_many_mandatory_fields: function() {
|
||||
too_many_mandatory_fields() {
|
||||
if(this.mandatory.length > 7) {
|
||||
// too many fields, show form
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
has_child_table: function(){
|
||||
has_child_table(){
|
||||
if($.map(this.mandatory, function(d) {
|
||||
return d.fieldtype==='Table' ? d : null; }).length) {
|
||||
// has mandatory table, quit!
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
validate_for_prompt_autoname: function() {
|
||||
validate_for_prompt_autoname() {
|
||||
if(this.meta.autoname && this.meta.autoname.toLowerCase()==='prompt') {
|
||||
this.mandatory = [{fieldname:'__newname', label:__('{0} Name', [this.meta.name]),
|
||||
reqd: 1, fieldtype:'Data'}].concat(this.mandatory);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
render_dialog: function() {
|
||||
render_dialog() {
|
||||
var me = this;
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: __("New {0}", [__(this.doctype)]),
|
||||
|
|
@ -134,9 +134,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
if (this.init_callback) {
|
||||
this.init_callback(this.dialog);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
register_primary_action: function() {
|
||||
register_primary_action() {
|
||||
var me = this;
|
||||
this.dialog.set_primary_action(__('Save'), function() {
|
||||
if(me.dialog.working) {
|
||||
|
|
@ -152,9 +152,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
insert: function() {
|
||||
insert() {
|
||||
let me = this;
|
||||
return new Promise(resolve => {
|
||||
me.update_doc();
|
||||
|
|
@ -202,9 +202,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
freeze: true
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
submit: function(doc) {
|
||||
submit(doc) {
|
||||
var me = this;
|
||||
frappe.call({
|
||||
method: "frappe.client.submit",
|
||||
|
|
@ -229,9 +229,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
cur_frm && cur_frm.reload_doc();
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
open_form_if_not_list: function() {
|
||||
open_form_if_not_list() {
|
||||
let route = frappe.get_route();
|
||||
let doc = this.dialog.doc;
|
||||
if (route && !(route[0]==='List' && route[1]===doc.doctype)) {
|
||||
|
|
@ -239,9 +239,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
() => frappe.set_route('Form', doc.doctype, doc.name)
|
||||
]);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
update_doc: function(){
|
||||
update_doc(){
|
||||
var me = this;
|
||||
var data = this.dialog.get_values(true);
|
||||
$.each(data, function(key, value) {
|
||||
|
|
@ -250,9 +250,9 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
}
|
||||
});
|
||||
return this.dialog.doc;
|
||||
},
|
||||
}
|
||||
|
||||
open_doc: function(set_hooks) {
|
||||
open_doc(set_hooks) {
|
||||
this.dialog.hide();
|
||||
this.update_doc();
|
||||
if (set_hooks && this.after_insert) {
|
||||
|
|
@ -262,17 +262,17 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
};
|
||||
}
|
||||
frappe.set_route('Form', this.doctype, this.doc.name);
|
||||
},
|
||||
}
|
||||
|
||||
render_edit_in_full_page_link: function() {
|
||||
render_edit_in_full_page_link() {
|
||||
var me = this;
|
||||
this.dialog.add_custom_action(
|
||||
`${frappe.utils.icon('edit', 'xs')} ${__("Edit in full page")}`,
|
||||
() => me.open_doc(true)
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
set_defaults: function() {
|
||||
set_defaults() {
|
||||
var me = this;
|
||||
// set defaults
|
||||
$.each(this.dialog.fields_dict, function(fieldname, field) {
|
||||
|
|
@ -284,4 +284,4 @@ frappe.ui.form.QuickEntryForm = Class.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,15 +69,15 @@ frappe.ui.form.trigger = function(doctype, fieldname) {
|
|||
cur_frm.script_manager.trigger(fieldname, doctype);
|
||||
}
|
||||
|
||||
frappe.ui.form.ScriptManager = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.ScriptManager = class ScriptManager {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
},
|
||||
make: function(ControllerClass) {
|
||||
}
|
||||
make(ControllerClass) {
|
||||
this.frm.cscript = $.extend(this.frm.cscript,
|
||||
new ControllerClass({frm: this.frm}));
|
||||
},
|
||||
trigger: function(event_name, doctype, name) {
|
||||
}
|
||||
trigger(event_name, doctype, name) {
|
||||
// trigger all the form level events that
|
||||
// are bound to this event_name
|
||||
let me = this;
|
||||
|
|
@ -130,12 +130,12 @@ frappe.ui.form.ScriptManager = Class.extend({
|
|||
|
||||
// run them serially
|
||||
return frappe.run_serially(tasks);
|
||||
},
|
||||
has_handlers: function(event_name, doctype) {
|
||||
}
|
||||
has_handlers(event_name, doctype) {
|
||||
let handlers = this.get_handlers(event_name, doctype);
|
||||
return handlers && (handlers.old_style.length || handlers.new_style.length);
|
||||
},
|
||||
get_handlers: function(event_name, doctype) {
|
||||
}
|
||||
get_handlers(event_name, doctype) {
|
||||
// returns list of all functions to be called (old style and new style)
|
||||
let me = this;
|
||||
let handlers = {
|
||||
|
|
@ -154,8 +154,8 @@ frappe.ui.form.ScriptManager = Class.extend({
|
|||
handlers.old_style.push("custom_" + event_name);
|
||||
}
|
||||
return handlers;
|
||||
},
|
||||
setup: function() {
|
||||
}
|
||||
setup() {
|
||||
const doctype = this.frm.meta;
|
||||
const me = this;
|
||||
let client_script;
|
||||
|
|
@ -206,8 +206,8 @@ frappe.ui.form.ScriptManager = Class.extend({
|
|||
doctype.__css && frappe.dom.set_style(doctype.__css);
|
||||
|
||||
this.trigger('setup');
|
||||
},
|
||||
log_error: function(caller, e) {
|
||||
}
|
||||
log_error(caller, e) {
|
||||
frappe.show_alert({message: __("Error in Client Script."), indicator: "error"});
|
||||
console.group && console.group();
|
||||
console.log("----- error in client script -----");
|
||||
|
|
@ -217,8 +217,8 @@ frappe.ui.form.ScriptManager = Class.extend({
|
|||
console.trace && console.trace();
|
||||
console.log("----- end of error message -----");
|
||||
console.group && console.groupEnd();
|
||||
},
|
||||
copy_from_first_row: function(parentfield, current_row, fieldnames) {
|
||||
}
|
||||
copy_from_first_row(parentfield, current_row, fieldnames) {
|
||||
var data = this.frm.doc[parentfield];
|
||||
if(data.length===1 || data[0]===current_row) return;
|
||||
|
||||
|
|
@ -231,4 +231,4 @@ frappe.ui.form.ScriptManager = Class.extend({
|
|||
data[0][fieldname]);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,23 +3,23 @@
|
|||
|
||||
|
||||
|
||||
frappe.ui.form.AssignTo = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.AssignTo = class AssignTo {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.btn = this.parent.find(".add-assignment-btn").on("click", () => this.add());
|
||||
this.btn_wrapper = this.btn.parent();
|
||||
|
||||
this.refresh();
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
if(this.frm.doc.__islocal) {
|
||||
this.parent.toggle(false);
|
||||
return;
|
||||
}
|
||||
this.parent.toggle(true);
|
||||
this.render(this.frm.get_docinfo().assignments);
|
||||
},
|
||||
render: function(assignments) {
|
||||
}
|
||||
render(assignments) {
|
||||
this.frm.get_docinfo().assignments = assignments;
|
||||
|
||||
let assignments_wrapper = this.parent.find('.assignments');
|
||||
|
|
@ -42,8 +42,8 @@ frappe.ui.form.AssignTo = Class.extend({
|
|||
frm: this.frm
|
||||
});
|
||||
});
|
||||
},
|
||||
add: function() {
|
||||
}
|
||||
add() {
|
||||
var me = this;
|
||||
|
||||
if (this.frm.is_new()) {
|
||||
|
|
@ -64,8 +64,8 @@ frappe.ui.form.AssignTo = Class.extend({
|
|||
}
|
||||
me.assign_to.dialog.clear();
|
||||
me.assign_to.dialog.show();
|
||||
},
|
||||
remove: function(owner) {
|
||||
}
|
||||
remove(owner) {
|
||||
if (this.frm.is_new()) {
|
||||
frappe.throw(__("Please save the document before removing assignment"));
|
||||
return;
|
||||
|
|
@ -79,17 +79,17 @@ frappe.ui.form.AssignTo = Class.extend({
|
|||
this.render(assignments);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
frappe.ui.form.AssignToDialog = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.AssignToDialog = class AssignToDialog {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
|
||||
this.make();
|
||||
this.set_description_from_doc();
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
let me = this;
|
||||
|
||||
me.dialog = new frappe.ui.Dialog({
|
||||
|
|
@ -126,8 +126,8 @@ frappe.ui.form.AssignToDialog = Class.extend({
|
|||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
assign_to_me: function() {
|
||||
}
|
||||
assign_to_me() {
|
||||
let me = this;
|
||||
let assign_to = [];
|
||||
|
||||
|
|
@ -136,15 +136,15 @@ frappe.ui.form.AssignToDialog = Class.extend({
|
|||
}
|
||||
|
||||
me.dialog.set_value("assign_to", assign_to);
|
||||
},
|
||||
set_description_from_doc: function() {
|
||||
}
|
||||
set_description_from_doc() {
|
||||
let me = this;
|
||||
|
||||
if (me.frm && me.frm.meta.title_field) {
|
||||
me.dialog.set_value("description", me.frm.doc[me.frm.meta.title_field]);
|
||||
}
|
||||
},
|
||||
get_fields: function() {
|
||||
}
|
||||
get_fields() {
|
||||
let me = this;
|
||||
|
||||
return [
|
||||
|
|
@ -206,7 +206,7 @@ frappe.ui.form.AssignToDialog = Class.extend({
|
|||
}
|
||||
];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
frappe.ui.form.AssignmentDialog = class {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.form.Attachments = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.Attachments = class Attachments {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.make();
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
var me = this;
|
||||
this.parent.find(".add-attachment-btn").click(function() {
|
||||
me.new_attachment();
|
||||
});
|
||||
this.add_attachment_wrapper = this.parent.find(".add_attachment").parent();
|
||||
this.attachments_label = this.parent.find(".attachments-label");
|
||||
},
|
||||
max_reached: function(raise_exception=false) {
|
||||
}
|
||||
max_reached(raise_exception=false) {
|
||||
const attachment_count = Object.keys(this.get_attachments()).length;
|
||||
const attachment_limit = this.frm.meta.max_attachments;
|
||||
if (attachment_limit && attachment_count >= attachment_limit) {
|
||||
|
|
@ -27,8 +27,8 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
var me = this;
|
||||
|
||||
if(this.frm.doc.__islocal) {
|
||||
|
|
@ -51,11 +51,11 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
this.attachments_label.removeClass("has-attachments");
|
||||
}
|
||||
|
||||
},
|
||||
get_attachments: function() {
|
||||
}
|
||||
get_attachments() {
|
||||
return this.frm.get_docinfo().attachments;
|
||||
},
|
||||
add_attachment: function(attachment) {
|
||||
}
|
||||
add_attachment(attachment) {
|
||||
var file_name = attachment.file_name;
|
||||
var file_url = this.get_file_url(attachment);
|
||||
var fileid = attachment.name;
|
||||
|
|
@ -95,8 +95,8 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
))
|
||||
.insertAfter(this.attachments_label.addClass("has-attachments"));
|
||||
|
||||
},
|
||||
get_file_url: function(attachment) {
|
||||
}
|
||||
get_file_url(attachment) {
|
||||
var file_url = attachment.file_url;
|
||||
if (!file_url) {
|
||||
if (attachment.file_name.indexOf('files/') === 0) {
|
||||
|
|
@ -108,8 +108,8 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
}
|
||||
// hash is not escaped, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
|
||||
return encodeURI(file_url).replace(/#/g, '%23');
|
||||
},
|
||||
get_file_id_from_file_url: function(file_url) {
|
||||
}
|
||||
get_file_id_from_file_url(file_url) {
|
||||
var fid;
|
||||
$.each(this.get_attachments(), function(i, attachment) {
|
||||
if (attachment.file_url === file_url) {
|
||||
|
|
@ -118,11 +118,11 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
}
|
||||
});
|
||||
return fid;
|
||||
},
|
||||
remove_attachment_by_filename: function(filename, callback) {
|
||||
}
|
||||
remove_attachment_by_filename(filename, callback) {
|
||||
this.remove_attachment(this.get_file_id_from_file_url(filename), callback);
|
||||
},
|
||||
remove_attachment: function(fileid, callback) {
|
||||
}
|
||||
remove_attachment(fileid, callback) {
|
||||
if (!fileid) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
|
|
@ -147,8 +147,8 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
if (callback) callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
new_attachment: function(fieldname) {
|
||||
}
|
||||
new_attachment(fieldname) {
|
||||
if (this.dialog) {
|
||||
// remove upload dialog
|
||||
this.dialog.$wrapper.remove();
|
||||
|
|
@ -163,15 +163,15 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
this.attachment_uploaded(file_doc);
|
||||
}
|
||||
});
|
||||
},
|
||||
get_args: function() {
|
||||
}
|
||||
get_args() {
|
||||
return {
|
||||
from_form: 1,
|
||||
doctype: this.frm.doctype,
|
||||
docname: this.frm.docname,
|
||||
}
|
||||
},
|
||||
attachment_uploaded: function(attachment) {
|
||||
}
|
||||
attachment_uploaded(attachment) {
|
||||
this.dialog && this.dialog.hide();
|
||||
this.update_attachment(attachment);
|
||||
this.frm.sidebar.reload_docinfo();
|
||||
|
|
@ -179,22 +179,22 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
if(this.fieldname) {
|
||||
this.frm.set_value(this.fieldname, attachment.file_url);
|
||||
}
|
||||
},
|
||||
update_attachment: function(attachment) {
|
||||
}
|
||||
update_attachment(attachment) {
|
||||
if(attachment.name) {
|
||||
this.add_to_attachments(attachment);
|
||||
this.refresh();
|
||||
}
|
||||
},
|
||||
add_to_attachments: function (attachment) {
|
||||
}
|
||||
add_to_attachments (attachment) {
|
||||
var form_attachments = this.get_attachments();
|
||||
for(var i in form_attachments) {
|
||||
// prevent duplicate
|
||||
if(form_attachments[i]["name"] === attachment.name) return;
|
||||
}
|
||||
form_attachments.push(attachment);
|
||||
},
|
||||
remove_fileid: function(fileid) {
|
||||
}
|
||||
remove_fileid(fileid) {
|
||||
var attachments = this.get_attachments();
|
||||
var new_attachments = [];
|
||||
$.each(attachments, function(i, attachment) {
|
||||
|
|
@ -205,4 +205,4 @@ frappe.ui.form.Attachments = Class.extend({
|
|||
this.frm.get_docinfo().attachments = new_attachments;
|
||||
this.refresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
|
||||
|
||||
frappe.ui.form.Share = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.Share = class Share {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.shares = this.parent.find('.shares');
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
this.render_sidebar();
|
||||
},
|
||||
render_sidebar: function() {
|
||||
}
|
||||
render_sidebar() {
|
||||
const shared = this.shared || this.frm.get_docinfo().shared;
|
||||
const shared_users = shared.filter(Boolean).map(s => s.user);
|
||||
|
||||
|
|
@ -33,8 +33,8 @@ frappe.ui.form.Share = Class.extend({
|
|||
this.shares.show();
|
||||
// REDESIGN-TODO: handle "shared with everyone"
|
||||
this.shares.append(frappe.avatar_group(shared_users, 5, {'align': 'left', 'overlap': true}));
|
||||
},
|
||||
show: function() {
|
||||
}
|
||||
show() {
|
||||
var me = this;
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __("Share {0} with", [this.frm.doc.name]),
|
||||
|
|
@ -62,8 +62,8 @@ frappe.ui.form.Share = Class.extend({
|
|||
}
|
||||
|
||||
d.show();
|
||||
},
|
||||
render_shared: function(shared) {
|
||||
}
|
||||
render_shared(shared) {
|
||||
if(shared)
|
||||
this.shared = shared;
|
||||
var d = this.dialog;
|
||||
|
|
@ -88,8 +88,8 @@ frappe.ui.form.Share = Class.extend({
|
|||
// if cannot share, disable sharing settings.
|
||||
$(d.body).find(".edit-share").prop("disabled", true);
|
||||
}
|
||||
},
|
||||
make_user_input: function() {
|
||||
}
|
||||
make_user_input() {
|
||||
// make add-user input
|
||||
this.dialog.share_with = frappe.ui.form.make_control({
|
||||
parent: $(this.dialog.body).find(".input-wrapper-add-share"),
|
||||
|
|
@ -107,8 +107,8 @@ frappe.ui.form.Share = Class.extend({
|
|||
render_input: true
|
||||
});
|
||||
|
||||
},
|
||||
add_share_button: function() {
|
||||
}
|
||||
add_share_button() {
|
||||
var me = this, d = this.dialog;
|
||||
$(d.body).find(".btn-add-share").on("click", function() {
|
||||
var user = d.share_with.get_value();
|
||||
|
|
@ -142,8 +142,8 @@ frappe.ui.form.Share = Class.extend({
|
|||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
set_edit_share_events: function() {
|
||||
}
|
||||
set_edit_share_events() {
|
||||
var me = this, d = this.dialog;
|
||||
$(d.body).find(".edit-share").on("click", function() {
|
||||
var user = $(this).parents(".shared-user:first").attr("data-user") || "",
|
||||
|
|
@ -186,5 +186,5 @@ frappe.ui.form.Share = Class.extend({
|
|||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.form.States = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.form.States = class FormStates {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.state_fieldname = frappe.workflow.get_state_fieldname(this.frm.doctype);
|
||||
|
||||
|
|
@ -16,9 +16,9 @@ frappe.ui.form.States = Class.extend({
|
|||
$(this.frm.wrapper).bind("render_complete", function() {
|
||||
me.refresh();
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
setup_help: function() {
|
||||
setup_help() {
|
||||
var me = this;
|
||||
this.frm.page.add_action_item(__("Help"), function() {
|
||||
frappe.workflow.setup(me.frm.doctype);
|
||||
|
|
@ -44,9 +44,9 @@ frappe.ui.form.States = Class.extend({
|
|||
d.show();
|
||||
});
|
||||
}, true);
|
||||
},
|
||||
}
|
||||
|
||||
refresh: function() {
|
||||
refresh() {
|
||||
// hide if its not yet saved
|
||||
if(this.frm.doc.__islocal) {
|
||||
this.set_default_state();
|
||||
|
|
@ -60,9 +60,9 @@ frappe.ui.form.States = Class.extend({
|
|||
// show actions from that state
|
||||
this.show_actions(state);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
show_actions: function() {
|
||||
show_actions() {
|
||||
var added = false;
|
||||
var me = this;
|
||||
|
||||
|
|
@ -107,28 +107,28 @@ frappe.ui.form.States = Class.extend({
|
|||
this.setup_btn(added);
|
||||
});
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
setup_btn: function(action_added) {
|
||||
setup_btn(action_added) {
|
||||
if(action_added) {
|
||||
this.frm.page.btn_primary.addClass("hide");
|
||||
this.frm.page.btn_secondary.addClass("hide");
|
||||
this.frm.toolbar.current_status = "";
|
||||
this.setup_help();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
set_default_state: function() {
|
||||
set_default_state() {
|
||||
var default_state = frappe.workflow.get_default_state(this.frm.doctype, this.frm.doc.docstatus);
|
||||
if(default_state) {
|
||||
this.frm.set_value(this.state_fieldname, default_state);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
get_state: function() {
|
||||
get_state() {
|
||||
if(!this.frm.doc[this.state_fieldname]) {
|
||||
this.set_default_state();
|
||||
}
|
||||
return this.frm.doc[this.state_fieldname];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
frappe.ModuleEditor = Class.extend({
|
||||
init: function(frm, wrapper) {
|
||||
frappe.ModuleEditor = class ModuleEditor {
|
||||
constructor(frm, wrapper) {
|
||||
this.wrapper = $('<div class="row module-block-list"></div>').appendTo(wrapper);
|
||||
this.frm = frm;
|
||||
this.make();
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
var me = this;
|
||||
this.frm.doc.__onload.all_modules.forEach(function(m) {
|
||||
$(repl('<div class="col-sm-6"><div class="checkbox">\
|
||||
|
|
@ -12,15 +12,15 @@ frappe.ModuleEditor = Class.extend({
|
|||
%(module)s</label></div></div>', {module: m})).appendTo(me.wrapper);
|
||||
});
|
||||
this.bind();
|
||||
},
|
||||
refresh: function() {
|
||||
}
|
||||
refresh() {
|
||||
var me = this;
|
||||
this.wrapper.find(".block-module-check").prop("checked", true);
|
||||
$.each(this.frm.doc.block_modules, function(i, d) {
|
||||
me.wrapper.find(".block-module-check[data-module='"+ d.module +"']").prop("checked", false);
|
||||
});
|
||||
},
|
||||
bind: function() {
|
||||
}
|
||||
bind() {
|
||||
var me = this;
|
||||
this.wrapper.on("change", ".block-module-check", function() {
|
||||
var module = $(this).attr('data-module');
|
||||
|
|
@ -36,4 +36,4 @@ frappe.ModuleEditor = Class.extend({
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
import { Chart } from "frappe-charts"
|
||||
import { Chart } from "frappe-charts/dist/frappe-charts.esm";
|
||||
|
||||
frappe.Chart = Chart;
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import '../form/layout';
|
|||
|
||||
frappe.provide('frappe.ui');
|
||||
|
||||
frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
||||
init: function(opts) {
|
||||
$.extend(this, opts);
|
||||
frappe.ui.FieldGroup = class FieldGroup extends frappe.ui.form.Layout {
|
||||
constructor(opts) {
|
||||
super(opts);
|
||||
this.first_button = false;
|
||||
this.dirty = false;
|
||||
this._super();
|
||||
$.each(this.fields || [], function(i, f) {
|
||||
if(!f.fieldname && f.label) {
|
||||
f.fieldname = f.label.replace(/ /g, "_").toLowerCase();
|
||||
|
|
@ -15,11 +15,11 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
if(this.values) {
|
||||
this.set_values(this.values);
|
||||
}
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
var me = this;
|
||||
if(this.fields) {
|
||||
this._super();
|
||||
super.make();
|
||||
this.refresh();
|
||||
// set default
|
||||
$.each(this.fields_list, function(i, field) {
|
||||
|
|
@ -50,9 +50,9 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
});
|
||||
|
||||
}
|
||||
},
|
||||
first_button: false,
|
||||
focus_on_first_input: function() {
|
||||
}
|
||||
|
||||
focus_on_first_input() {
|
||||
if(this.no_focus) return;
|
||||
$.each(this.fields_list, function(i, f) {
|
||||
if(!in_list(['Date', 'Datetime', 'Time', 'Check'], f.df.fieldtype) && f.set_focus) {
|
||||
|
|
@ -60,8 +60,8 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
catch_enter_as_submit: function() {
|
||||
}
|
||||
catch_enter_as_submit() {
|
||||
var me = this;
|
||||
$(this.body).find('input[type="text"], input[type="password"], select').keypress(function(e) {
|
||||
if(e.which==13) {
|
||||
|
|
@ -71,15 +71,15 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
get_input: function(fieldname) {
|
||||
}
|
||||
get_input(fieldname) {
|
||||
var field = this.fields_dict[fieldname];
|
||||
return $(field.txt ? field.txt : field.input);
|
||||
},
|
||||
get_field: function(fieldname) {
|
||||
}
|
||||
get_field(fieldname) {
|
||||
return this.fields_dict[fieldname];
|
||||
},
|
||||
get_values: function(ignore_errors) {
|
||||
}
|
||||
get_values(ignore_errors) {
|
||||
var ret = {};
|
||||
var errors = [];
|
||||
for (var key in this.fields_dict) {
|
||||
|
|
@ -110,12 +110,12 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
return null;
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
get_value: function(key) {
|
||||
}
|
||||
get_value(key) {
|
||||
var f = this.fields_dict[key];
|
||||
return f && (f.get_value ? f.get_value() : null);
|
||||
},
|
||||
set_value: function(key, val){
|
||||
}
|
||||
set_value(key, val){
|
||||
return new Promise(resolve => {
|
||||
var f = this.fields_dict[key];
|
||||
if(f) {
|
||||
|
|
@ -128,11 +128,11 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
resolve();
|
||||
}
|
||||
});
|
||||
},
|
||||
set_input: function(key, val) {
|
||||
}
|
||||
set_input(key, val) {
|
||||
return this.set_value(key, val);
|
||||
},
|
||||
set_values: function(dict) {
|
||||
}
|
||||
set_values(dict) {
|
||||
let promises = [];
|
||||
for(var key in dict) {
|
||||
if(this.fields_dict[key]) {
|
||||
|
|
@ -141,18 +141,18 @@ frappe.ui.FieldGroup = frappe.ui.form.Layout.extend({
|
|||
}
|
||||
|
||||
return Promise.all(promises);
|
||||
},
|
||||
clear: function() {
|
||||
}
|
||||
clear() {
|
||||
for(var key in this.fields_dict) {
|
||||
var f = this.fields_dict[key];
|
||||
if(f && f.set_input) {
|
||||
f.set_input(f.df['default'] || '');
|
||||
}
|
||||
}
|
||||
},
|
||||
set_df_property: function (fieldname, prop, value) {
|
||||
}
|
||||
set_df_property (fieldname, prop, value) {
|
||||
const field = this.get_field(fieldname);
|
||||
field.df[prop] = value;
|
||||
field.refresh();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// <select> widget with all fields of a doctype as options
|
||||
frappe.ui.FieldSelect = Class.extend({
|
||||
frappe.ui.FieldSelect = class FieldSelect {
|
||||
// opts parent, doctype, filter_fields, with_blank, select
|
||||
init(opts) {
|
||||
constructor(opts) {
|
||||
var me = this;
|
||||
$.extend(this, opts);
|
||||
this.fields_by_name = {};
|
||||
|
|
@ -44,22 +44,22 @@ frappe.ui.FieldSelect = Class.extend({
|
|||
this.build_options();
|
||||
}
|
||||
this.set_value(this.doctype, "name");
|
||||
},
|
||||
}
|
||||
get_value() {
|
||||
return this.selected_doctype ? this.selected_doctype + "." + this.selected_fieldname : null;
|
||||
},
|
||||
}
|
||||
val(value) {
|
||||
if(value===undefined) {
|
||||
return this.get_value();
|
||||
} else {
|
||||
this.set_value(value);
|
||||
}
|
||||
},
|
||||
}
|
||||
clear() {
|
||||
this.selected_doctype = null;
|
||||
this.selected_fieldname = null;
|
||||
this.$input.val("");
|
||||
},
|
||||
}
|
||||
set_value(doctype, fieldname) {
|
||||
var me = this;
|
||||
this.clear();
|
||||
|
|
@ -80,7 +80,7 @@ frappe.ui.FieldSelect = Class.extend({
|
|||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
build_options() {
|
||||
var me = this;
|
||||
me.table_fields = [];
|
||||
|
|
@ -135,7 +135,7 @@ frappe.ui.FieldSelect = Class.extend({
|
|||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
add_field_option(df) {
|
||||
let me = this;
|
||||
|
|
@ -170,5 +170,5 @@ frappe.ui.FieldSelect = Class.extend({
|
|||
if(!me.fields_by_name[df.parent]) me.fields_by_name[df.parent] = {};
|
||||
me.fields_by_name[df.parent][df.fieldname] = df;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.IconBar = Class.extend({
|
||||
init: function(parent, n_groups) {
|
||||
frappe.ui.IconBar = class IconBar {
|
||||
constructor(parent, n_groups) {
|
||||
this.parent = parent;
|
||||
this.buttons = {};
|
||||
this.make(n_groups);
|
||||
},
|
||||
make: function(n_groups) {
|
||||
}
|
||||
make(n_groups) {
|
||||
this.$wrapper = $('<div class="iconbar-wrapper hide"></div>').appendTo(this.parent);
|
||||
for(var i=0; i<n_groups; i++) {
|
||||
this.get_group(i+1);
|
||||
}
|
||||
},
|
||||
get_group: function(group) {
|
||||
}
|
||||
get_group(group) {
|
||||
var $ul = this.$wrapper.find(".iconbar-"+group+" ul");
|
||||
|
||||
if(!$ul.length)
|
||||
|
|
@ -21,8 +21,8 @@ frappe.ui.IconBar = Class.extend({
|
|||
.appendTo(this.$wrapper).find("ul");
|
||||
|
||||
return $ul;
|
||||
},
|
||||
add_btn: function(group, icon, label, click) {
|
||||
}
|
||||
add_btn(group, icon, label, click) {
|
||||
var $ul = this.get_group(group);
|
||||
var $li = $('<li><i class="'+icon+'"></i></li>')
|
||||
.appendTo($ul)
|
||||
|
|
@ -37,16 +37,16 @@ frappe.ui.IconBar = Class.extend({
|
|||
this.$wrapper.find(".iconbar-" + group).removeClass("hide")
|
||||
this.show();
|
||||
return $li;
|
||||
},
|
||||
hide: function(group) {
|
||||
}
|
||||
hide(group) {
|
||||
if(group) {
|
||||
this.$wrapper.find(".iconbar-" + group).addClass("hide");
|
||||
this.check_if_all_hidden();
|
||||
} else {
|
||||
this.$wrapper.addClass("hide").trigger("hidden");
|
||||
}
|
||||
},
|
||||
show: function(group) {
|
||||
}
|
||||
show(group) {
|
||||
if(group) {
|
||||
this.$wrapper.find(".iconbar-" + group).removeClass("hide");
|
||||
this.show();
|
||||
|
|
@ -54,15 +54,15 @@ frappe.ui.IconBar = Class.extend({
|
|||
if(this.$wrapper.hasClass("hide"))
|
||||
this.$wrapper.removeClass("hide").trigger("shown");
|
||||
}
|
||||
},
|
||||
clear: function(group) {
|
||||
}
|
||||
clear(group) {
|
||||
var me = this;
|
||||
this.$wrapper.find(".iconbar-" + group).addClass("hide").find("ul").empty();
|
||||
this.check_if_all_hidden();
|
||||
},
|
||||
check_if_all_hidden: function() {
|
||||
}
|
||||
check_if_all_hidden() {
|
||||
if(!this.$wrapper.find(".iconbar:visible").length) {
|
||||
this.hide();
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ frappe.ui.make_app_page = function(opts) {
|
|||
|
||||
frappe.ui.pages = {};
|
||||
|
||||
frappe.ui.Page = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.Page = class Page {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
|
||||
this.set_document_title = true;
|
||||
|
|
@ -37,14 +37,14 @@ frappe.ui.Page = Class.extend({
|
|||
|
||||
this.make();
|
||||
frappe.ui.pages[frappe.get_route_str()] = this;
|
||||
},
|
||||
}
|
||||
|
||||
make: function() {
|
||||
make() {
|
||||
this.wrapper = $(this.parent);
|
||||
this.add_main_section();
|
||||
this.setup_scroll_handler();
|
||||
this.setup_sidebar_toggle();
|
||||
},
|
||||
}
|
||||
|
||||
setup_scroll_handler() {
|
||||
window.addEventListener('scroll', () => {
|
||||
|
|
@ -54,9 +54,9 @@ frappe.ui.Page = Class.extend({
|
|||
$('.page-head').removeClass('drop-shadow');
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
get_empty_state: function(title, message, primary_action) {
|
||||
get_empty_state(title, message, primary_action) {
|
||||
let $empty_state = $(`<div class="page-card-container">
|
||||
<div class="page-card">
|
||||
<div class="page-card-head">
|
||||
|
|
@ -71,13 +71,13 @@ frappe.ui.Page = Class.extend({
|
|||
</div>`);
|
||||
|
||||
return $empty_state;
|
||||
},
|
||||
}
|
||||
|
||||
load_lib: function(callback) {
|
||||
load_lib(callback) {
|
||||
frappe.require(this.required_libs, callback);
|
||||
},
|
||||
}
|
||||
|
||||
add_main_section: function() {
|
||||
add_main_section() {
|
||||
$(frappe.render_template("page", {})).appendTo(this.wrapper);
|
||||
if (this.single_column) {
|
||||
// nesting under col-sm-12 for consistency
|
||||
|
|
@ -100,9 +100,9 @@ frappe.ui.Page = Class.extend({
|
|||
}
|
||||
|
||||
this.setup_page();
|
||||
},
|
||||
}
|
||||
|
||||
setup_page: function() {
|
||||
setup_page() {
|
||||
this.$title_area = this.wrapper.find(".title-area");
|
||||
|
||||
this.$sub_title_area = this.wrapper.find("h6");
|
||||
|
|
@ -154,7 +154,7 @@ frappe.ui.Page = Class.extend({
|
|||
frappe.ui.keys
|
||||
.get_shortcut_group(this.page_actions[0])
|
||||
.add(action_btn, action_btn.find('.actions-btn-group-label'));
|
||||
},
|
||||
}
|
||||
|
||||
setup_sidebar_toggle() {
|
||||
let sidebar_toggle = $('.page-head').find('.sidebar-toggle-btn');
|
||||
|
|
@ -176,7 +176,7 @@ frappe.ui.Page = Class.extend({
|
|||
this.update_sidebar_icon();
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setup_overlay_sidebar() {
|
||||
let overlay_sidebar = this.sidebar.find('.overlay-sidebar')
|
||||
|
|
@ -196,7 +196,7 @@ frappe.ui.Page = Class.extend({
|
|||
.removeClass('text-muted');
|
||||
});
|
||||
};
|
||||
},
|
||||
}
|
||||
|
||||
update_sidebar_icon() {
|
||||
let sidebar_toggle = $('.page-head').find('.sidebar-toggle-btn');
|
||||
|
|
@ -204,13 +204,13 @@ frappe.ui.Page = Class.extend({
|
|||
let sidebar_wrapper = this.wrapper.find('.layout-side-section');
|
||||
let is_sidebar_visible = $(sidebar_wrapper).is(":visible");
|
||||
sidebar_toggle_icon.html(frappe.utils.icon(is_sidebar_visible ? 'sidebar-collapse' : 'sidebar-expand', 'md'));
|
||||
},
|
||||
}
|
||||
|
||||
set_indicator: function(label, color) {
|
||||
set_indicator(label, color) {
|
||||
this.clear_indicator().removeClass("hide").html(`<span>${label}</span>`).addClass(color);
|
||||
},
|
||||
}
|
||||
|
||||
add_action_icon: function(icon, click, css_class='', tooltip_label) {
|
||||
add_action_icon(icon, click, css_class='', tooltip_label) {
|
||||
const button = $(`
|
||||
<button class="text-muted btn btn-default ${css_class} icon-btn">
|
||||
${frappe.utils.icon(icon)}
|
||||
|
|
@ -223,13 +223,13 @@ frappe.ui.Page = Class.extend({
|
|||
.tooltip({ delay: { "show": 600, "hide": 100 }, trigger: "hover" });
|
||||
|
||||
return button;
|
||||
},
|
||||
}
|
||||
|
||||
clear_indicator: function() {
|
||||
clear_indicator() {
|
||||
return this.indicator.removeClass().addClass("indicator-pill whitespace-nowrap hide");
|
||||
},
|
||||
}
|
||||
|
||||
get_icon_label: function(icon, label) {
|
||||
get_icon_label(icon, label) {
|
||||
let icon_name = icon;
|
||||
let size = 'xs';
|
||||
if (typeof icon === 'object') {
|
||||
|
|
@ -237,9 +237,9 @@ frappe.ui.Page = Class.extend({
|
|||
size = icon.size || 'xs';
|
||||
}
|
||||
return `${icon ? frappe.utils.icon(icon_name, size) : ''} <span class="hidden-xs"> ${__(label)} </span>`;
|
||||
},
|
||||
}
|
||||
|
||||
set_action: function(btn, opts) {
|
||||
set_action(btn, opts) {
|
||||
let me = this;
|
||||
if (opts.icon) {
|
||||
opts.label = this.get_icon_label(opts.icon, opts.label);
|
||||
|
|
@ -264,9 +264,9 @@ frappe.ui.Page = Class.extend({
|
|||
frappe.ui.keys
|
||||
.get_shortcut_group(this)
|
||||
.add(btn, text_span.length ? text_span : btn);
|
||||
},
|
||||
}
|
||||
|
||||
set_primary_action: function(label, click, icon, working_label) {
|
||||
set_primary_action(label, click, icon, working_label) {
|
||||
this.set_action(this.btn_primary, {
|
||||
label: label,
|
||||
click: click,
|
||||
|
|
@ -275,9 +275,9 @@ frappe.ui.Page = Class.extend({
|
|||
});
|
||||
return this.btn_primary;
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
set_secondary_action: function(label, click, icon, working_label) {
|
||||
set_secondary_action(label, click, icon, working_label) {
|
||||
this.set_action(this.btn_secondary, {
|
||||
label: label,
|
||||
click: click,
|
||||
|
|
@ -286,37 +286,37 @@ frappe.ui.Page = Class.extend({
|
|||
});
|
||||
|
||||
return this.btn_secondary;
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
clear_action_of: function(btn) {
|
||||
clear_action_of(btn) {
|
||||
btn.addClass("hide").unbind("click").removeAttr("data-working-label");
|
||||
},
|
||||
}
|
||||
|
||||
clear_primary_action: function() {
|
||||
clear_primary_action() {
|
||||
this.clear_action_of(this.btn_primary);
|
||||
},
|
||||
}
|
||||
|
||||
clear_secondary_action: function() {
|
||||
clear_secondary_action() {
|
||||
this.clear_action_of(this.btn_secondary);
|
||||
},
|
||||
}
|
||||
|
||||
clear_actions: function() {
|
||||
clear_actions() {
|
||||
this.clear_primary_action();
|
||||
this.clear_secondary_action();
|
||||
},
|
||||
}
|
||||
|
||||
clear_custom_actions() {
|
||||
this.custom_actions.addClass("hide").empty();
|
||||
},
|
||||
}
|
||||
|
||||
clear_icons: function() {
|
||||
clear_icons() {
|
||||
this.icon_group.addClass("hide").empty();
|
||||
},
|
||||
}
|
||||
|
||||
//--- Menu --//
|
||||
|
||||
add_menu_item: function(label, click, standard, shortcut) {
|
||||
add_menu_item(label, click, standard, shortcut) {
|
||||
return this.add_dropdown_item({
|
||||
label,
|
||||
click,
|
||||
|
|
@ -324,9 +324,9 @@ frappe.ui.Page = Class.extend({
|
|||
parent: this.menu,
|
||||
shortcut
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
add_custom_menu_item: function(parent, label, click, standard, shortcut, icon=null) {
|
||||
add_custom_menu_item(parent, label, click, standard, shortcut, icon=null) {
|
||||
return this.add_dropdown_item({
|
||||
label,
|
||||
click,
|
||||
|
|
@ -335,49 +335,49 @@ frappe.ui.Page = Class.extend({
|
|||
shortcut,
|
||||
icon
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
clear_menu: function() {
|
||||
clear_menu() {
|
||||
this.clear_btn_group(this.menu);
|
||||
},
|
||||
}
|
||||
|
||||
show_menu: function() {
|
||||
show_menu() {
|
||||
this.menu_btn_group.removeClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
hide_menu: function() {
|
||||
hide_menu() {
|
||||
this.menu_btn_group.addClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
show_icon_group: function() {
|
||||
show_icon_group() {
|
||||
this.icon_group.removeClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
hide_icon_group: function() {
|
||||
hide_icon_group() {
|
||||
this.icon_group.addClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
//--- Actions Menu--//
|
||||
|
||||
show_actions_menu: function() {
|
||||
show_actions_menu() {
|
||||
this.actions_btn_group.removeClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
hide_actions_menu: function() {
|
||||
hide_actions_menu() {
|
||||
this.actions_btn_group.addClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
add_action_item: function(label, click, standard) {
|
||||
add_action_item(label, click, standard) {
|
||||
return this.add_dropdown_item({
|
||||
label,
|
||||
click,
|
||||
standard,
|
||||
parent: this.actions
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
add_actions_menu_item: function(label, click, standard) {
|
||||
add_actions_menu_item(label, click, standard) {
|
||||
return this.add_dropdown_item({
|
||||
label,
|
||||
click,
|
||||
|
|
@ -385,11 +385,11 @@ frappe.ui.Page = Class.extend({
|
|||
parent: this.actions,
|
||||
show_parent: false
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
clear_actions_menu: function() {
|
||||
clear_actions_menu() {
|
||||
this.clear_btn_group(this.actions);
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
//-- Generic --//
|
||||
|
|
@ -404,7 +404,7 @@ frappe.ui.Page = Class.extend({
|
|||
* @param {string} shortcut - Keyboard shortcut associated with the element
|
||||
* @param {Boolean} show_parent - Whether to show the dropdown button if dropdown item is added
|
||||
*/
|
||||
add_dropdown_item: function({label, click, standard, parent, shortcut, show_parent=true, icon=null}) {
|
||||
add_dropdown_item({label, click, standard, parent, shortcut, show_parent=true, icon=null}) {
|
||||
if (show_parent) {
|
||||
parent.parent().removeClass("hide");
|
||||
}
|
||||
|
|
@ -460,7 +460,7 @@ frappe.ui.Page = Class.extend({
|
|||
.add($link, $link.find('.menu-item-label'));
|
||||
|
||||
return $link;
|
||||
},
|
||||
}
|
||||
|
||||
prepare_shortcut_obj(shortcut, click, label) {
|
||||
let shortcut_obj;
|
||||
|
|
@ -489,7 +489,7 @@ frappe.ui.Page = Class.extend({
|
|||
// page
|
||||
shortcut_obj.page = this;
|
||||
return shortcut_obj;
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there already exists a button with a specified label in a specified button group
|
||||
|
|
@ -497,7 +497,7 @@ frappe.ui.Page = Class.extend({
|
|||
* @param {string} selector - CSS Selector of the button to be searched for. By default, it is `li`.
|
||||
* @param {string} label - Label of the button
|
||||
*/
|
||||
is_in_group_button_dropdown: function(parent, selector, label) {
|
||||
is_in_group_button_dropdown(parent, selector, label) {
|
||||
|
||||
if (!selector) selector = 'li';
|
||||
|
||||
|
|
@ -509,18 +509,18 @@ frappe.ui.Page = Class.extend({
|
|||
return $(item).attr('data-label') === label;
|
||||
});
|
||||
return result.length > 0;
|
||||
},
|
||||
}
|
||||
|
||||
clear_btn_group: function(parent) {
|
||||
clear_btn_group(parent) {
|
||||
parent.empty();
|
||||
parent.parent().addClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
add_divider: function() {
|
||||
add_divider() {
|
||||
return $('<li class="dropdown-divider"></li>').appendTo(this.menu);
|
||||
},
|
||||
}
|
||||
|
||||
get_or_add_inner_group_button: function(label) {
|
||||
get_or_add_inner_group_button(label) {
|
||||
var $group = this.inner_toolbar.find(`.inner-group-button[data-label="${encodeURIComponent(label)}"]`);
|
||||
if (!$group.length) {
|
||||
$group = $(
|
||||
|
|
@ -534,17 +534,17 @@ frappe.ui.Page = Class.extend({
|
|||
).appendTo(this.inner_toolbar);
|
||||
}
|
||||
return $group;
|
||||
},
|
||||
}
|
||||
|
||||
get_inner_group_button: function(label) {
|
||||
get_inner_group_button(label) {
|
||||
return this.inner_toolbar.find(`.inner-group-button[data-label="${encodeURIComponent(label)}"]`);
|
||||
},
|
||||
}
|
||||
|
||||
set_inner_btn_group_as_primary: function(label) {
|
||||
set_inner_btn_group_as_primary(label) {
|
||||
this.get_or_add_inner_group_button(label).find("button").removeClass("btn-default").addClass("btn-primary");
|
||||
},
|
||||
}
|
||||
|
||||
btn_disable_enable: function(btn, response) {
|
||||
btn_disable_enable(btn, response) {
|
||||
if (response && response.then) {
|
||||
btn.prop('disabled', true);
|
||||
response.then(() => {
|
||||
|
|
@ -556,7 +556,7 @@ frappe.ui.Page = Class.extend({
|
|||
btn.prop('disabled', false);
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
* Add button to button group. If there exists another button with the same label,
|
||||
|
|
@ -567,7 +567,7 @@ frappe.ui.Page = Class.extend({
|
|||
* @param {object} action - function to be called when button is clicked
|
||||
* @param {string} group - Label of the group button
|
||||
*/
|
||||
add_inner_button: function(label, action, group, type="default") {
|
||||
add_inner_button(label, action, group, type="default") {
|
||||
var me = this;
|
||||
let _action = function() {
|
||||
let btn = $(this);
|
||||
|
|
@ -595,9 +595,9 @@ frappe.ui.Page = Class.extend({
|
|||
}
|
||||
return button;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
remove_inner_button: function(label, group) {
|
||||
remove_inner_button(label, group) {
|
||||
if (typeof label === 'string') {
|
||||
label = [label];
|
||||
}
|
||||
|
|
@ -613,23 +613,23 @@ frappe.ui.Page = Class.extend({
|
|||
} else {
|
||||
this.inner_toolbar.find(`button[data-label="${encodeURIComponent(label)}"]`).remove();
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
add_inner_message: function(message) {
|
||||
add_inner_message(message) {
|
||||
let $message = $(`<span class='inner-page-message text-muted small'>${message}</div>`);
|
||||
this.inner_toolbar.find('.inner-page-message').remove();
|
||||
this.inner_toolbar.removeClass("hide").prepend($message);
|
||||
|
||||
return $message;
|
||||
},
|
||||
}
|
||||
|
||||
clear_inner_toolbar: function() {
|
||||
clear_inner_toolbar() {
|
||||
this.inner_toolbar.empty().addClass("hide");
|
||||
},
|
||||
}
|
||||
|
||||
//-- Sidebar --//
|
||||
|
||||
add_sidebar_item: function(label, action, insert_after, prepend) {
|
||||
add_sidebar_item(label, action, insert_after, prepend) {
|
||||
var parent = this.sidebar.find(".sidebar-menu.standard-actions");
|
||||
var li = $('<li>');
|
||||
var link = $('<a>').html(label).on("click", action).appendTo(li);
|
||||
|
|
@ -644,20 +644,20 @@ frappe.ui.Page = Class.extend({
|
|||
}
|
||||
}
|
||||
return link;
|
||||
},
|
||||
}
|
||||
|
||||
//---//
|
||||
|
||||
clear_user_actions: function() {
|
||||
clear_user_actions() {
|
||||
this.menu.find(".user-action").remove();
|
||||
},
|
||||
}
|
||||
|
||||
// page::title
|
||||
get_title_area: function() {
|
||||
get_title_area() {
|
||||
return this.$title_area;
|
||||
},
|
||||
}
|
||||
|
||||
set_title: function(title, icon=null, strip=true, tab_title="") {
|
||||
set_title(title, icon=null, strip=true, tab_title="") {
|
||||
if (!title) title = "";
|
||||
if (strip) {
|
||||
title = strip_html(title);
|
||||
|
|
@ -670,24 +670,24 @@ frappe.ui.Page = Class.extend({
|
|||
let title_wrapper = this.$title_area.find(".title-text");
|
||||
title_wrapper.html(title);
|
||||
title_wrapper.attr('title', this.title);
|
||||
},
|
||||
}
|
||||
|
||||
set_title_sub: function(txt) {
|
||||
set_title_sub(txt) {
|
||||
// strip icon
|
||||
this.$sub_title_area.html(txt).toggleClass("hide", !!!txt);
|
||||
},
|
||||
}
|
||||
|
||||
get_main_icon: function(icon) {
|
||||
get_main_icon(icon) {
|
||||
return this.$title_area.find(".title-icon")
|
||||
.html('<i class="'+icon+' fa-fw"></i> ')
|
||||
.toggle(true);
|
||||
},
|
||||
}
|
||||
|
||||
add_help_button: function(txt) {
|
||||
add_help_button(txt) {
|
||||
//
|
||||
},
|
||||
}
|
||||
|
||||
add_button: function(label, click, opts) {
|
||||
add_button(label, click, opts) {
|
||||
if (!opts) opts = {};
|
||||
let button = $(`<button
|
||||
class="btn ${opts.btn_class || 'btn-default'} ${opts.btn_size || 'btn-sm'} ellipsis">
|
||||
|
|
@ -699,9 +699,9 @@ frappe.ui.Page = Class.extend({
|
|||
this.custom_actions.removeClass('hide');
|
||||
|
||||
return button;
|
||||
},
|
||||
}
|
||||
|
||||
add_custom_button_group: function(label, icon, parent) {
|
||||
add_custom_button_group(label, icon, parent) {
|
||||
let dropdown_label = `<span class="hidden-xs">
|
||||
<span class="custom-btn-group-label">${__(label)}</span>
|
||||
${frappe.utils.icon('select', 'xs')}
|
||||
|
|
@ -731,40 +731,40 @@ frappe.ui.Page = Class.extend({
|
|||
parent.removeClass('hide').append(custom_btn_group);
|
||||
|
||||
return custom_btn_group.find('.dropdown-menu');
|
||||
},
|
||||
}
|
||||
|
||||
add_dropdown_button: function(parent, label, click, icon) {
|
||||
add_dropdown_button(parent, label, click, icon) {
|
||||
frappe.ui.toolbar.add_dropdown_button(parent, label, click, icon);
|
||||
},
|
||||
}
|
||||
|
||||
// page::form
|
||||
add_label: function(label) {
|
||||
add_label(label) {
|
||||
this.show_form();
|
||||
return $("<label class='col-md-1 page-only-label'>"+label+" </label>")
|
||||
.appendTo(this.page_form);
|
||||
},
|
||||
add_select: function(label, options) {
|
||||
}
|
||||
add_select(label, options) {
|
||||
var field = this.add_field({label:label, fieldtype:"Select"});
|
||||
return field.$wrapper.find("select").empty().add_options(options);
|
||||
},
|
||||
add_data: function(label) {
|
||||
}
|
||||
add_data(label) {
|
||||
var field = this.add_field({label: label, fieldtype: "Data"});
|
||||
return field.$wrapper.find("input").attr("placeholder", label);
|
||||
},
|
||||
add_date: function(label, date) {
|
||||
}
|
||||
add_date(label, date) {
|
||||
var field = this.add_field({label: label, fieldtype: "Date", "default": date});
|
||||
return field.$wrapper.find("input").attr("placeholder", label);
|
||||
},
|
||||
add_check: function(label) {
|
||||
}
|
||||
add_check(label) {
|
||||
return $("<div class='checkbox'><label><input type='checkbox'>" + label + "</label></div>")
|
||||
.appendTo(this.page_form)
|
||||
.find("input");
|
||||
},
|
||||
add_break: function() {
|
||||
}
|
||||
add_break() {
|
||||
// add further fields in the next line
|
||||
this.page_form.append('<div class="clearfix invisible-xs"></div>');
|
||||
},
|
||||
add_field: function(df, parent) {
|
||||
}
|
||||
add_field(df, parent) {
|
||||
this.show_form();
|
||||
|
||||
if (!df.placeholder) {
|
||||
|
|
@ -810,24 +810,24 @@ frappe.ui.Page = Class.extend({
|
|||
f.set_input(df["default"])
|
||||
this.fields_dict[df.fieldname || df.label] = f;
|
||||
return f;
|
||||
},
|
||||
clear_fields: function() {
|
||||
}
|
||||
clear_fields() {
|
||||
this.page_form.empty();
|
||||
},
|
||||
show_form: function() {
|
||||
}
|
||||
show_form() {
|
||||
this.page_form.removeClass("hide");
|
||||
},
|
||||
hide_form: function() {
|
||||
}
|
||||
hide_form() {
|
||||
this.page_form.addClass("hide");
|
||||
},
|
||||
get_form_values: function() {
|
||||
}
|
||||
get_form_values() {
|
||||
var values = {};
|
||||
this.page_form.fields_dict.forEach(function(field, key) {
|
||||
values[key] = field.get_value();
|
||||
});
|
||||
return values;
|
||||
},
|
||||
add_view: function(name, html) {
|
||||
}
|
||||
add_view(name, html) {
|
||||
let element = html;
|
||||
if(typeof (html) === "string") {
|
||||
element = $(html);
|
||||
|
|
@ -839,8 +839,8 @@ frappe.ui.Page = Class.extend({
|
|||
this.views[name].toggle(false);
|
||||
}
|
||||
return this.views[name];
|
||||
},
|
||||
set_view: function(name) {
|
||||
}
|
||||
set_view(name) {
|
||||
if(this.current_view_name===name)
|
||||
return;
|
||||
this.current_view && this.current_view.toggle(false);
|
||||
|
|
@ -852,5 +852,5 @@ frappe.ui.Page = Class.extend({
|
|||
this.views[name].toggle(true);
|
||||
|
||||
this.wrapper.trigger('view-change');
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
frappe.ui.SortSelector = Class.extend({
|
||||
frappe.ui.SortSelector = class SortSelector {
|
||||
// parent:
|
||||
// change:
|
||||
// args:
|
||||
|
|
@ -7,18 +7,18 @@ frappe.ui.SortSelector = Class.extend({
|
|||
// sort_by_label:
|
||||
// sort_order:
|
||||
// doctype: (optional)
|
||||
init: function(opts) {
|
||||
constructor(opts) {
|
||||
$.extend(this, opts);
|
||||
this.labels = {};
|
||||
this.make();
|
||||
},
|
||||
make: function() {
|
||||
}
|
||||
make() {
|
||||
this.prepare_args();
|
||||
this.parent.find('.sort-selector').remove();
|
||||
this.wrapper = $(frappe.render_template('sort_selector', this.args)).appendTo(this.parent);
|
||||
this.bind_events();
|
||||
},
|
||||
bind_events: function() {
|
||||
}
|
||||
bind_events() {
|
||||
var me = this;
|
||||
|
||||
// order
|
||||
|
|
@ -42,8 +42,8 @@ frappe.ui.SortSelector = Class.extend({
|
|||
(me.onchange || me.change)(me.sort_by, me.sort_order);
|
||||
});
|
||||
|
||||
},
|
||||
prepare_args: function() {
|
||||
}
|
||||
prepare_args() {
|
||||
var me = this;
|
||||
if(!this.args) {
|
||||
this.args = {};
|
||||
|
|
@ -87,8 +87,8 @@ frappe.ui.SortSelector = Class.extend({
|
|||
});
|
||||
}
|
||||
|
||||
},
|
||||
setup_from_doctype: function() {
|
||||
}
|
||||
setup_from_doctype() {
|
||||
var me = this;
|
||||
var meta = frappe.get_meta(this.doctype);
|
||||
if (!meta) return;
|
||||
|
|
@ -154,8 +154,8 @@ frappe.ui.SortSelector = Class.extend({
|
|||
// set default
|
||||
this.sort_by = this.args.sort_by;
|
||||
this.sort_order = this.args.sort_order;
|
||||
},
|
||||
get_meta_sort_field: function() {
|
||||
}
|
||||
get_meta_sort_field() {
|
||||
var meta = frappe.get_meta(this.doctype);
|
||||
|
||||
if (!meta) {
|
||||
|
|
@ -177,17 +177,17 @@ frappe.ui.SortSelector = Class.extend({
|
|||
meta_sort_order: meta.sort_order ? meta.sort_order.toLowerCase() : ''
|
||||
}
|
||||
}
|
||||
},
|
||||
get_label: function(fieldname) {
|
||||
}
|
||||
get_label(fieldname) {
|
||||
if(fieldname==='idx') {
|
||||
return __("Most Used");
|
||||
} else {
|
||||
return this.labels[fieldname]
|
||||
|| frappe.meta.get_label(this.doctype, fieldname);
|
||||
}
|
||||
},
|
||||
get_sql_string: function() {
|
||||
}
|
||||
get_sql_string() {
|
||||
// build string like `tabTask`.`subject` desc
|
||||
return '`tab' + this.doctype + '`.`' + this.sort_by + '` ' + this.sort_order;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
frappe.ui.TagEditor = Class.extend({
|
||||
init: function(opts) {
|
||||
frappe.ui.TagEditor = class TagEditor {
|
||||
constructor(opts) {
|
||||
/* docs:
|
||||
Arguments
|
||||
|
||||
|
|
@ -17,8 +17,8 @@ frappe.ui.TagEditor = Class.extend({
|
|||
}
|
||||
this.initialized = true;
|
||||
this.refresh(this.user_tags);
|
||||
},
|
||||
setup_tags: function() {
|
||||
}
|
||||
setup_tags() {
|
||||
var me = this;
|
||||
|
||||
// hidden form, does not have parent
|
||||
|
|
@ -65,8 +65,8 @@ frappe.ui.TagEditor = Class.extend({
|
|||
});
|
||||
this.setup_awesomplete();
|
||||
this.setup_complete = true;
|
||||
},
|
||||
setup_awesomplete: function() {
|
||||
}
|
||||
setup_awesomplete() {
|
||||
var me = this;
|
||||
var $input = this.wrapper.find("input.tags-input");
|
||||
var input = $input.get(0);
|
||||
|
|
@ -99,15 +99,15 @@ frappe.ui.TagEditor = Class.extend({
|
|||
$input.trigger("input");
|
||||
}
|
||||
});
|
||||
},
|
||||
get_args: function(tag) {
|
||||
}
|
||||
get_args(tag) {
|
||||
return {
|
||||
tag: tag,
|
||||
dt: this.frm.doctype,
|
||||
dn: this.frm.docname,
|
||||
}
|
||||
},
|
||||
refresh: function(user_tags) {
|
||||
}
|
||||
refresh(user_tags) {
|
||||
var me = this;
|
||||
if (!this.initialized || !this.setup_complete || this.refreshing) return;
|
||||
|
||||
|
|
@ -126,4 +126,4 @@ frappe.ui.TagEditor = Class.extend({
|
|||
me.refreshing = false;
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue