move some misc functions
This commit is contained in:
parent
4c892816ba
commit
5639551dd5
|
|
@ -1,8 +1,8 @@
|
||||||
import { FormikForm } from "@shared/nej-react-utils/Form/FormikForm";
|
import { FormikForm } from "@shared/nej-react-utils/Form/FormikForm";
|
||||||
import { NejAccountingApiClient, CompanyResponse, CancelablePromise } from "@services/accounting-api";
|
import { NejAccountingApiClient, CompanyResponse, CancelablePromise } from "@services/accounting-api";
|
||||||
import { useApiClient, useCompany } from "@utils/NejManager/NejProvider";
|
import { useApiClient, useCompany } from "@utils/NejManager/NejProvider";
|
||||||
import useMethod from "../../../utils/useMethod.macro";
|
import useMethod from "../macros/useMethod.macro";
|
||||||
import useQuery from "../../../utils/useQuery.macro";
|
import useQuery from "../macros/useQuery.macro";
|
||||||
|
|
||||||
type FormProps<T> = {
|
type FormProps<T> = {
|
||||||
refresh: () => void;
|
refresh: () => void;
|
||||||
|
|
|
||||||
5
macros/useMethod.macro.d.ts
vendored
Normal file
5
macros/useMethod.macro.d.ts
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { CancelablePromise, Error } from "src/services/accounting-api";
|
||||||
|
|
||||||
|
export default function useMethod<T, Arg>(method: (...args: Arg) => CancelablePromise<T>,
|
||||||
|
onDone?: (data: T) => void,
|
||||||
|
onError?: (error: Error) => void = null): [(...args: Arg) => void, { data: T, loading: boolean, error: Error }];
|
||||||
167
macros/useMethod.macro.js
Normal file
167
macros/useMethod.macro.js
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
const { createMacro, MacroError } = require("babel-plugin-macros")
|
||||||
|
const { addNamed } = require("@babel/helper-module-imports")
|
||||||
|
const path = require("path")
|
||||||
|
|
||||||
|
// `createMacro` is simply a function that ensures your macro is only
|
||||||
|
// called in the context of a babel transpilation and will throw an
|
||||||
|
// error with a helpful message if someone does not have babel-plugin-macros
|
||||||
|
// configured correctly
|
||||||
|
module.exports = createMacro(useMethod)
|
||||||
|
|
||||||
|
function useMethod({ references, state, babel }) {
|
||||||
|
// state is the second argument you're passed to a visitor in a
|
||||||
|
// normal babel plugin. `babel` is the `babel-plugin-macros` module.
|
||||||
|
// do whatever you like to the AST paths you find in `references`
|
||||||
|
// read more below...
|
||||||
|
const { default: defaultImport = [] } = references
|
||||||
|
|
||||||
|
defaultImport.forEach(referencePath => {
|
||||||
|
if (referencePath.parentPath.type != "CallExpression") {
|
||||||
|
throw new MacroError(
|
||||||
|
"useQuery should be called with a function",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ourArguments = referencePath.parentPath.get("arguments")
|
||||||
|
|
||||||
|
if (ourArguments.length < 1) {
|
||||||
|
throw new MacroError(
|
||||||
|
"There are not enough arguments",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (ourArguments.length > 3) {
|
||||||
|
throw new MacroError(
|
||||||
|
"There are too many arguments",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ourArguments[0].has("callee")) {
|
||||||
|
throw new MacroError(
|
||||||
|
"function used in useMethod can not be a function call",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (ourArguments.length > 1 && !ourArguments[1].isFunction()) {
|
||||||
|
throw new MacroError(
|
||||||
|
"useMethods 2nd argument must be a callable function",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (ourArguments.length > 2 && !ourArguments[2].isFunction()) {
|
||||||
|
throw new MacroError(
|
||||||
|
"useMethods 3rd argument must be a callable function",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let declPath = referencePath.parentPath.parentPath;
|
||||||
|
|
||||||
|
let call = ourArguments[0].node
|
||||||
|
let nop = babel.types.arrowFunctionExpression([babel.types.identifier("e")], babel.types.blockStatement([]))
|
||||||
|
let onDone = ourArguments[1] ? ourArguments[1].node : nop;
|
||||||
|
let onError = ourArguments[2] ? ourArguments[2].node : null;
|
||||||
|
|
||||||
|
let parsWithSet = referencePath.parentPath.parentPath.get("id").get("elements")
|
||||||
|
|
||||||
|
if (!parsWithSet[0].isIdentifier())
|
||||||
|
throw new MacroError(
|
||||||
|
"first result of useMethod must be a function name",
|
||||||
|
)
|
||||||
|
let runMethod = parsWithSet[0].node
|
||||||
|
if (!parsWithSet[1].isObjectPattern())
|
||||||
|
throw new MacroError(
|
||||||
|
"second result of useMethod must be the returned data object",
|
||||||
|
)
|
||||||
|
let pars = parsWithSet[1].node
|
||||||
|
|
||||||
|
let setStateIdentifier = declPath.scope.generateUidIdentifier("setStateInternalMagic")
|
||||||
|
|
||||||
|
let variableArgsId = declPath.scope.generateUidIdentifier("variableArgsInternalMagic")
|
||||||
|
|
||||||
|
let useStateHookImport = addNamed(declPath, "useState", "react");
|
||||||
|
let useCallbackHookImport = addNamed(declPath, "useCallback", "react");
|
||||||
|
|
||||||
|
let servicePath = "./" + path.relative(state.file.opts.filename, path.join(__dirname, "../services/accounting-api")).trim();
|
||||||
|
let apiErrorImport = addNamed(declPath, "ApiError", servicePath);
|
||||||
|
|
||||||
|
let nejServicesPath = "./" + path.relative(path.dirname(state.file.opts.filename), path.join(__dirname, "NejManager/NejProvider")).trim();
|
||||||
|
let emptyErrorIdentifier = declPath.scope.generateUidIdentifier("emptyErrorInternalMagic")
|
||||||
|
let onErrorIdentifier = declPath.scope.generateUidIdentifier("onErrorInternalMagic")
|
||||||
|
let onSuccessIdentifier = declPath.scope.generateUidIdentifier("onSuccessInternalMagic")
|
||||||
|
let onStartLoadingIdentifier = declPath.scope.generateUidIdentifier("onErrorInternalMagic")
|
||||||
|
let onStopLoadingIdentifier = declPath.scope.generateUidIdentifier("onErrorInternalMagic")
|
||||||
|
|
||||||
|
let useOnErrorImport = addNamed(declPath, "useOnError", nejServicesPath);
|
||||||
|
let useOnSuccessImport = addNamed(declPath, "useOnSuccess", nejServicesPath);
|
||||||
|
let useStartLoadingImport = addNamed(declPath, "useStartLoading", nejServicesPath);
|
||||||
|
let useStopLoadingImport = addNamed(declPath, "useStopLoading", nejServicesPath);
|
||||||
|
|
||||||
|
let useStateSrc = babel.template("[DATA, CALL_SET] = USE_STATE({data: null, error: null, loading: false})")({
|
||||||
|
DATA: pars,
|
||||||
|
CALL_SET: setStateIdentifier,
|
||||||
|
USE_STATE: useStateHookImport
|
||||||
|
})
|
||||||
|
|
||||||
|
declPath.replaceWith(useStateSrc)
|
||||||
|
|
||||||
|
let src = babel.template(`
|
||||||
|
const ON_ERROR_IDENTIFIER = USE_ERROR_IMPORT();
|
||||||
|
const ON_SUCCESS_IDENTIFIER = USE_SUCCESS_IMPORT();
|
||||||
|
const ON_START_LOADING_IDENTIFIER = USE_START_LOADING_IMPORT();
|
||||||
|
const ON_STOP_LOADING_IDENTIFIER = USE_STOP_LOADING_IMPORT();
|
||||||
|
|
||||||
|
function EMPTY_ERROR(x){
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const RUN_NAME = USE_CALLBACK(async (...ARGS) => {
|
||||||
|
let notifKey = "";
|
||||||
|
try{
|
||||||
|
notifKey = ON_START_LOADING_IDENTIFIER();
|
||||||
|
CALL_SET({ data: null, error: null, loading: true });
|
||||||
|
let ret = await IMPORT_NAME(...ARGS);
|
||||||
|
CALL_SET({ data: ret, error: null, loading: false });
|
||||||
|
ON_STOP_LOADING_IDENTIFIER(notifKey);
|
||||||
|
ON_SUCCESS_IDENTIFIER();
|
||||||
|
DONE(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if(e instanceof ERROR_CLASS){
|
||||||
|
CALL_SET({data: null, error: e.body, loading: false})
|
||||||
|
ON_STOP_LOADING_IDENTIFIER(notifKey);
|
||||||
|
ON_ERROR_IDENTIFIER(e.body);
|
||||||
|
ERROR(e.body)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CALL_SET({data: null, error: e, loading: false})
|
||||||
|
ON_STOP_LOADING_IDENTIFIER(notifKey);
|
||||||
|
ON_ERROR_IDENTIFIER(e);
|
||||||
|
ERROR(e)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
`)({
|
||||||
|
IMPORT_NAME: call,
|
||||||
|
CALL_SET: setStateIdentifier,
|
||||||
|
RUN_NAME: runMethod,
|
||||||
|
ARGS: variableArgsId,
|
||||||
|
USE_CALLBACK: useCallbackHookImport,
|
||||||
|
ERROR_CLASS: apiErrorImport,
|
||||||
|
DONE: onDone,
|
||||||
|
//if its null create an empty function to call
|
||||||
|
ERROR: onError != null ? onError : emptyErrorIdentifier,
|
||||||
|
EMPTY_ERROR: emptyErrorIdentifier,
|
||||||
|
|
||||||
|
USE_ERROR_IMPORT: useOnErrorImport,
|
||||||
|
USE_SUCCESS_IMPORT: useOnSuccessImport,
|
||||||
|
USE_START_LOADING_IMPORT: useStartLoadingImport,
|
||||||
|
USE_STOP_LOADING_IMPORT: useStopLoadingImport,
|
||||||
|
|
||||||
|
ON_SUCCESS_IDENTIFIER: onSuccessIdentifier,
|
||||||
|
ON_START_LOADING_IDENTIFIER: onStartLoadingIdentifier,
|
||||||
|
ON_STOP_LOADING_IDENTIFIER: onStopLoadingIdentifier,
|
||||||
|
ON_ERROR_IDENTIFIER: onErrorIdentifier,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
declPath.parentPath.insertAfter(src)
|
||||||
|
})
|
||||||
|
}
|
||||||
15
macros/useQuery.macro.d.ts
vendored
Normal file
15
macros/useQuery.macro.d.ts
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { CancelablePromise, Error } from "src/services/accounting-api";
|
||||||
|
|
||||||
|
//default export is a function
|
||||||
|
/*
|
||||||
|
export default function useQuery<T>(query: CancelablePromise<Error | T>): [{
|
||||||
|
data: T;
|
||||||
|
loading: boolean;
|
||||||
|
error: Error;
|
||||||
|
}, () => void];
|
||||||
|
*/
|
||||||
|
export default function useQuery<T>(query: CancelablePromise<T>): [{
|
||||||
|
data: T;
|
||||||
|
loading: boolean;
|
||||||
|
error: Error;
|
||||||
|
}, () => void];
|
||||||
134
macros/useQuery.macro.js
Normal file
134
macros/useQuery.macro.js
Normal file
|
|
@ -0,0 +1,134 @@
|
||||||
|
const { createMacro, MacroError } = require("babel-plugin-macros")
|
||||||
|
const { addNamed } = require("@babel/helper-module-imports")
|
||||||
|
const path = require("path")
|
||||||
|
const Babel = require("@babel/core")
|
||||||
|
// `createMacro` is simply a function that ensures your macro is only
|
||||||
|
// called in the context of a babel transpilation and will throw an
|
||||||
|
// error with a helpful message if someone does not have babel-plugin-macros
|
||||||
|
// configured correctly
|
||||||
|
module.exports = createMacro(useQuery);
|
||||||
|
|
||||||
|
//jsdoc
|
||||||
|
/**
|
||||||
|
* @param {Object} param0
|
||||||
|
* @param {import("@babel/types").ArrayExpression} param0.references
|
||||||
|
* @param {Object} param0.state
|
||||||
|
* @param {Babel} param0.babel
|
||||||
|
*/
|
||||||
|
function useQuery({ references, state, babel }) {
|
||||||
|
// state is the second argument you're passed to a visitor in a
|
||||||
|
// normal babel plugin. `babel` is the `babel-plugin-macros` module.
|
||||||
|
// do whatever you like to the AST paths you find in `references`
|
||||||
|
// read more below...
|
||||||
|
const { default: defaultImport = [] } = references
|
||||||
|
|
||||||
|
defaultImport.forEach(referencePath => {
|
||||||
|
if (referencePath.parentPath.type != "CallExpression") {
|
||||||
|
throw new MacroError(
|
||||||
|
"useQuery should be called with a function",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ourArguments = referencePath.parentPath.get("arguments")
|
||||||
|
|
||||||
|
if (ourArguments.length < 1) {
|
||||||
|
throw new MacroError(
|
||||||
|
"There are not enough arguments",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else if (ourArguments.length > 1) {
|
||||||
|
throw new MacroError(
|
||||||
|
"There are too many arguments",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
//jsdoc
|
||||||
|
/**
|
||||||
|
* @type {import("@babel/types").CallExpression}
|
||||||
|
* */
|
||||||
|
let call = ourArguments[0].node
|
||||||
|
|
||||||
|
|
||||||
|
let declPath = referencePath.parentPath.parentPath;
|
||||||
|
|
||||||
|
let setStateIdentifier = declPath.scope.generateUidIdentifier("setStateInternalMagic")
|
||||||
|
|
||||||
|
let refreshFuncName = declPath.scope.generateUidIdentifier("refreshInternalMagic")
|
||||||
|
|
||||||
|
let queryObjName = declPath.scope.generateUidIdentifier("queryInternalMagic");
|
||||||
|
|
||||||
|
let assignParsPath = referencePath.parentPath.parentPath.get("id");
|
||||||
|
let pars = assignParsPath.node
|
||||||
|
if (!assignParsPath.isObjectPattern()) {
|
||||||
|
if (!assignParsPath.isArrayPattern() || !assignParsPath.get("elements")[0].isObjectPattern())
|
||||||
|
throw new MacroError(
|
||||||
|
"Return is either just the object or array of object and refresh method",
|
||||||
|
)
|
||||||
|
pars = assignParsPath.get("elements")[0].node
|
||||||
|
if (assignParsPath.get("elements").length > 1) {
|
||||||
|
if (!assignParsPath.get("elements")[1].isIdentifier())
|
||||||
|
throw new MacroError(
|
||||||
|
"There is second argument to array return, but its surprisingly not a function identifier",
|
||||||
|
)
|
||||||
|
refreshFuncName = assignParsPath.get("elements")[1].node
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let useStateHookImport = addNamed(declPath, "useState", "react");
|
||||||
|
let useCallbackHookImport = addNamed(declPath, "useCallback", "react");
|
||||||
|
let useEffectHookImport = addNamed(declPath, "useEffect", "react");
|
||||||
|
|
||||||
|
let useRQuery = addNamed(declPath, "useQuery", "@tanstack/react-query");
|
||||||
|
|
||||||
|
//create a string literal for identification
|
||||||
|
//reduce the callee's MemberExpression object and property to astring with member.member.member.etc...
|
||||||
|
var reduceCallee = (callee) => {
|
||||||
|
if (callee.type == "Identifier") return callee.name
|
||||||
|
return reduceCallee(callee.object) + "." + reduceCallee(callee.property)
|
||||||
|
}
|
||||||
|
let fullCallPathString = reduceCallee(call.callee)
|
||||||
|
|
||||||
|
let servicePath = "./" + path.relative(state.file.opts.filename, path.join(__dirname, "../services/accounting-api")).trim();
|
||||||
|
let apiErrorImport = addNamed(declPath, "ApiError", servicePath);
|
||||||
|
|
||||||
|
let useStateSrc = babel.template("[DATA, CALL_SET] = USE_STATE({data: null, error: null, loading: true})")({
|
||||||
|
DATA: pars,
|
||||||
|
CALL_SET: setStateIdentifier,
|
||||||
|
USE_STATE: useStateHookImport
|
||||||
|
})
|
||||||
|
|
||||||
|
declPath.replaceWith(useStateSrc)
|
||||||
|
|
||||||
|
let src = babel.template(`
|
||||||
|
|
||||||
|
const Q_UNAME = USE_RQUERY({queryKey: ["Q_KEY", ...(new Array(DEPS))], queryFn: async () => IMPORT_NAME})
|
||||||
|
|
||||||
|
USE_EFFECT(() => {
|
||||||
|
|
||||||
|
if(Q_UNAME.error instanceof ERROR_CLASS){
|
||||||
|
CALL_SET({...Q_UNAME, error: Q_UNAME.error.body, loading: Q_UNAME.isLoading})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CALL_SET({...Q_UNAME, loading: Q_UNAME.isLoading})
|
||||||
|
|
||||||
|
}, [Q_UNAME.data, Q_UNAME.error, Q_UNAME.isLoading])
|
||||||
|
|
||||||
|
const REFRESH = USE_CALLBACK(async () =>{
|
||||||
|
await Q_UNAME.refetch()
|
||||||
|
}, [Q_UNAME.data, Q_UNAME.error, Q_UNAME.isLoading])
|
||||||
|
|
||||||
|
`)({
|
||||||
|
IMPORT_NAME: call,
|
||||||
|
DEPS: call.arguments,
|
||||||
|
CALL_SET: setStateIdentifier,
|
||||||
|
USE_EFFECT: useEffectHookImport,
|
||||||
|
USE_CALLBACK: useCallbackHookImport,
|
||||||
|
ERROR_CLASS: apiErrorImport,
|
||||||
|
REFRESH: refreshFuncName,
|
||||||
|
Q_UNAME: queryObjName,
|
||||||
|
Q_KEY: fullCallPathString,
|
||||||
|
USE_RQUERY: useRQuery
|
||||||
|
})
|
||||||
|
|
||||||
|
declPath.parentPath.insertAfter(src)
|
||||||
|
})
|
||||||
|
}
|
||||||
31
misc/downloadBlob.js
Normal file
31
misc/downloadBlob.js
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default function downloadAsBlob(data, name) {
|
||||||
|
// Create blob link to download
|
||||||
|
const url = window.URL.createObjectURL(
|
||||||
|
new Blob([data]),
|
||||||
|
);
|
||||||
|
console.log(url);
|
||||||
|
downloadInteral(url, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadUrl(url, name){
|
||||||
|
let res = await axios.get(url, {responseType: "blob"});
|
||||||
|
downloadAsBlob(res.data, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadInteral(url, name){
|
||||||
|
const link = document.createElement("a");
|
||||||
|
link.href = url;
|
||||||
|
link.download = name;
|
||||||
|
link.target = "_blank";
|
||||||
|
|
||||||
|
// Append to html link element page
|
||||||
|
document.body.appendChild(link);
|
||||||
|
|
||||||
|
// Start download
|
||||||
|
link.click();
|
||||||
|
|
||||||
|
// Clean up and remove the link
|
||||||
|
link.parentNode.removeChild(link);
|
||||||
|
}
|
||||||
18
misc/getDate.ts
Normal file
18
misc/getDate.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
export default function getInputDate(date: Date | string) {
|
||||||
|
|
||||||
|
if (!date)
|
||||||
|
return date;
|
||||||
|
if (typeof (date) === "string") {
|
||||||
|
date = new Date(date);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
|
return new Date(date.getTime() - new Date().getTimezoneOffset() * 60000).toISOString().substring(0, 19)
|
||||||
|
|
||||||
|
} catch {
|
||||||
|
|
||||||
|
return new Date(new Date().getTimezoneOffset() * 60000).toISOString().substring(0, 19)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
52
misc/pdf.js
Normal file
52
misc/pdf.js
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import { Document, Page } from "react-pdf";
|
||||||
|
import "react-pdf/dist/esm/Page/AnnotationLayer.css";
|
||||||
|
import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||||
|
|
||||||
|
import Pagination from "@shared/nej-react-components/Parts/Pagination";
|
||||||
|
|
||||||
|
import tw, { styled } from "twin.macro"
|
||||||
|
import "styled-components/macro"
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import { pdfjs } from 'react-pdf';
|
||||||
|
|
||||||
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||||
|
'pdfjs-dist/build/pdf.worker.min.mjs',
|
||||||
|
import.meta.url,
|
||||||
|
).toString();
|
||||||
|
|
||||||
|
export default function PDF({ data }) {
|
||||||
|
const [numPages, setNumPages] = useState(null);
|
||||||
|
const [pageNumber, setPageNumber] = useState(1);
|
||||||
|
|
||||||
|
function onDocumentLoadSuccess({ numPages }) {
|
||||||
|
setNumPages(numPages);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div tw="w-full flex flex-col items-start">
|
||||||
|
|
||||||
|
<Document file={data} onLoadSuccess={onDocumentLoadSuccess}>
|
||||||
|
<Page pageNumber={pageNumber} />
|
||||||
|
</Document>
|
||||||
|
{/*
|
||||||
|
<div tw=" w-[21cm] h-[29.7cm] mt-20 overflow-hidden">
|
||||||
|
<BalanceDocument />
|
||||||
|
</div>
|
||||||
|
<div tw=" w-[80mm] mt-20 overflow-hidden">
|
||||||
|
<ReceiptDocument />
|
||||||
|
</div>
|
||||||
|
<div tw=" w-[21cm] mt-10 overflow-hidden h-[29.7cm]">
|
||||||
|
<CorrectureDocument data={data} />
|
||||||
|
</div>
|
||||||
|
<div tw=" w-[21cm] mt-20 overflow-hidden">
|
||||||
|
<TransactionDocument data={data}/>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
<p tw="mt-4">
|
||||||
|
Page {pageNumber} of {numPages}
|
||||||
|
</p>
|
||||||
|
<Pagination maxPages={numPages} currentPage={pageNumber} setPage={(p) => setPageNumber(p)} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
24
misc/printPage.js
Normal file
24
misc/printPage.js
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
function closePrint() {
|
||||||
|
document.body.removeChild(this.__container__);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPrint() {
|
||||||
|
this.contentWindow.__container__ = this;
|
||||||
|
this.contentWindow.onbeforeunload = closePrint;
|
||||||
|
this.contentWindow.onafterprint = closePrint;
|
||||||
|
this.contentWindow.focus(); // Required for IE
|
||||||
|
this.contentWindow.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function printPage(sURL) {
|
||||||
|
const hideFrame = document.createElement("iframe");
|
||||||
|
hideFrame.onload = setPrint;
|
||||||
|
hideFrame.style.position = "fixed";
|
||||||
|
hideFrame.style.right = "0";
|
||||||
|
hideFrame.style.bottom = "0";
|
||||||
|
hideFrame.style.width = "0";
|
||||||
|
hideFrame.style.height = "0";
|
||||||
|
hideFrame.style.border = "0";
|
||||||
|
hideFrame.src = sURL;
|
||||||
|
document.body.appendChild(hideFrame);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user