Web: Added new @appserver/editor app
This commit is contained in:
parent
b65d83cc01
commit
c96e783eab
@ -209,6 +209,19 @@ server {
|
||||
}
|
||||
}
|
||||
|
||||
location ~* /files/doceditor {
|
||||
proxy_pass http://localhost:5013;
|
||||
proxy_redirect off;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
location ~* /files {
|
||||
#rewrite products/files/(.*) /$1 break;
|
||||
proxy_pass http://localhost:5008;
|
||||
|
@ -27,6 +27,10 @@
|
||||
{
|
||||
"name": "🚀 @appserver/login",
|
||||
"path": "web\\ASC.Web.Login"
|
||||
},
|
||||
{
|
||||
"name": "🚀 @appserver/editor",
|
||||
"path": "web\\ASC.Web.Editor"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
|
@ -6,15 +6,16 @@
|
||||
"packages/asc-web-common",
|
||||
"web/ASC.Web.Login",
|
||||
"web/ASC.Web.Client",
|
||||
"web/ASC.Web.Editor",
|
||||
"products/ASC.People/Client",
|
||||
"products/ASC.Files/Client"
|
||||
],
|
||||
"scripts": {
|
||||
"wipe": "rimraf node_modules yarn.lock web/**/node_modules products/**/node_modules",
|
||||
"build": "yarn workspaces run build",
|
||||
"start": "concurrently \"wsrun --parallel start\"",
|
||||
"start": "concurrently \"wsrun --parallel start\"",
|
||||
"test": "yarn workspace @appserver/components test",
|
||||
"sb-components": "yarn workspace @appserver/components storybook"
|
||||
"sb-components": "yarn workspace @appserver/components storybook"
|
||||
},
|
||||
"devDependencies": {
|
||||
"lerna": "^3.22.1",
|
||||
@ -22,4 +23,4 @@
|
||||
"wsrun": "^5.2.4",
|
||||
"rimraf": "^3.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
web/ASC.Web.Editor/.babelrc
Normal file
7
web/ASC.Web.Editor/.babelrc
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"presets": ["@babel/preset-react", "@babel/preset-env"],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-runtime",
|
||||
"@babel/plugin-proposal-class-properties"
|
||||
]
|
||||
}
|
1
web/ASC.Web.Editor/.gitattributes
vendored
Normal file
1
web/ASC.Web.Editor/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
dist/* linguist-vendored=false
|
116
web/ASC.Web.Editor/.gitignore
vendored
Normal file
116
web/ASC.Web.Editor/.gitignore
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
15
web/ASC.Web.Editor/Dockerfile
Normal file
15
web/ASC.Web.Editor/Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM node:12
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
COPY package.json ./
|
||||
COPY yarn.lock ./
|
||||
|
||||
RUN yarn install
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN yarn build
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD [ "yarn", "build:start" ]
|
9
web/ASC.Web.Editor/jsconfig.json
Normal file
9
web/ASC.Web.Editor/jsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"components": ["@appserver/components"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules"]
|
||||
}
|
63
web/ASC.Web.Editor/package.json
Normal file
63
web/ASC.Web.Editor/package.json
Normal file
@ -0,0 +1,63 @@
|
||||
{
|
||||
"name": "@appserver/editor",
|
||||
"version": "0.1.0",
|
||||
"private": "true",
|
||||
"homepage": "/products/files/doceditor",
|
||||
"scripts": {
|
||||
"start": "webpack-cli serve",
|
||||
"build": "webpack --mode production",
|
||||
"serve": "serve dist -p 5013",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.12.10",
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.1",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.12.1",
|
||||
"@babel/plugin-transform-runtime": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.7",
|
||||
"@babel/preset-react": "7.12.10",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"babel-loader": "8.2.2",
|
||||
"clean-webpack-plugin": "^3.0.0",
|
||||
"copy-webpack-plugin": "^7.0.0",
|
||||
"css-loader": "^3.6.0",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"json-loader": "^0.5.7",
|
||||
"serve": "11.3.2",
|
||||
"source-map-loader": "^1.1.2",
|
||||
"style-loader": "1.2.1",
|
||||
"webpack": "5.14.0",
|
||||
"webpack-cli": "4.5.0",
|
||||
"webpack-dev-server": "3.11.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"attr-accept": "^2.2.2",
|
||||
"email-addresses": "^3.1.0",
|
||||
"i18next": "^19.8.4",
|
||||
"i18next-http-backend": "^1.1.0",
|
||||
"mobx": "^6.1.1",
|
||||
"mobx-react": "^7.1.0",
|
||||
"moment": "^2.29.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"rc-tree": "^2.1.4",
|
||||
"re-resizable": "^6.9.0",
|
||||
"react": "^16.14.0",
|
||||
"react-autosize-textarea": "^7.1.0",
|
||||
"react-custom-scrollbars": "^4.2.1",
|
||||
"react-dom": "^16.14.0",
|
||||
"react-dropzone": "^11.2.4",
|
||||
"react-i18next": "^11.7.3",
|
||||
"react-onclickoutside": "^6.9.0",
|
||||
"react-resize-detector": "^5.2.0",
|
||||
"react-router": "^5.2.0",
|
||||
"react-text-mask": "^5.4.3",
|
||||
"react-toastify": "^6.1.0",
|
||||
"react-tooltip": "^4.2.11",
|
||||
"react-virtualized-auto-sizer": "^1.0.2",
|
||||
"react-window": "^1.8.6",
|
||||
"resize-image": "^0.1.0",
|
||||
"sjcl": "^1.0.8",
|
||||
"styled-components": "^5.2.1"
|
||||
}
|
||||
}
|
14
web/ASC.Web.Editor/public/index.html
Normal file
14
web/ASC.Web.Editor/public/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Editor</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
console.log("It's Editor INIT");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
8
web/ASC.Web.Editor/src/App.js
Normal file
8
web/ASC.Web.Editor/src/App.js
Normal file
@ -0,0 +1,8 @@
|
||||
import React from "react";
|
||||
import Editor from "./Editor";
|
||||
|
||||
const App = () => {
|
||||
return <Editor />;
|
||||
};
|
||||
|
||||
export default App;
|
252
web/ASC.Web.Editor/src/Editor.jsx
Normal file
252
web/ASC.Web.Editor/src/Editor.jsx
Normal file
@ -0,0 +1,252 @@
|
||||
import React from "react";
|
||||
import Toast from "@appserver/components/toast";
|
||||
import toastr from "@appserver/components/toast/toastr";
|
||||
import Box from "@appserver/components/box";
|
||||
import { regDesktop } from "@appserver/common/desktop";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import {
|
||||
getObjectByLocation,
|
||||
//showLoader,
|
||||
//hideLoader,
|
||||
tryRedirectTo,
|
||||
} from "@appserver/common/utils";
|
||||
import {
|
||||
getDocServiceUrl,
|
||||
openEdit,
|
||||
setEncryptionKeys,
|
||||
getEncryptionAccess,
|
||||
} from "@appserver/common/api/files";
|
||||
import { checkIsAuthenticated } from "@appserver/common/api/user";
|
||||
import { getUser } from "@appserver/common/api/people";
|
||||
|
||||
import { changeTitle, setFavicon, isIPad, setDocumentTitle } from "./utils";
|
||||
import throttle from "lodash/throttle";
|
||||
import "./custom.scss";
|
||||
|
||||
let documentIsReady = false;
|
||||
|
||||
let docTitle = null;
|
||||
let fileType = null;
|
||||
|
||||
let docSaved = null;
|
||||
|
||||
const throttledChangeTitle = throttle(
|
||||
() => changeTitle(docSaved, docTitle),
|
||||
500
|
||||
);
|
||||
|
||||
class Editor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const urlParams = getObjectByLocation(window.location);
|
||||
const fileId = urlParams
|
||||
? urlParams.fileId || urlParams.fileid || null
|
||||
: null;
|
||||
const doc = urlParams ? urlParams.doc || null : null;
|
||||
const desktop = window["AscDesktopEditor"] !== undefined;
|
||||
|
||||
this.state = {
|
||||
fileId,
|
||||
doc,
|
||||
isLoading: true,
|
||||
isDesktop: desktop,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
try {
|
||||
const { fileId, doc, isDesktop } = this.state;
|
||||
|
||||
if (!fileId) return;
|
||||
|
||||
console.log("PureEditor componentDidMount", fileId, doc);
|
||||
|
||||
if (isIPad()) {
|
||||
const vh = window.innerHeight * 0.01;
|
||||
document.documentElement.style.setProperty("--vh", `${vh}px`);
|
||||
}
|
||||
|
||||
//showLoader();
|
||||
|
||||
const docApiUrl = await getDocServiceUrl();
|
||||
|
||||
if (!doc) {
|
||||
const isAuthenticated = await checkIsAuthenticated();
|
||||
|
||||
if (!isAuthenticated) return tryRedirectTo("/login");
|
||||
}
|
||||
|
||||
const config = await openEdit(fileId, doc);
|
||||
|
||||
if (isDesktop) {
|
||||
const isEncryption =
|
||||
config.editorConfig["encryptionKeys"] !== undefined;
|
||||
const user = await getUser();
|
||||
|
||||
regDesktop(
|
||||
user,
|
||||
isEncryption,
|
||||
config.editorConfig.encryptionKeys,
|
||||
(keys) => {
|
||||
setEncryptionKeys(keys);
|
||||
},
|
||||
true,
|
||||
(callback) => {
|
||||
getEncryptionAccess(fileId)
|
||||
.then((keys) => {
|
||||
var data = {
|
||||
keys,
|
||||
};
|
||||
|
||||
callback(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
toastr.error(
|
||||
typeof error === "string" ? error : error.message,
|
||||
null,
|
||||
0,
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.setState({ isLoading: false }, () =>
|
||||
this.loadDocApi(docApiUrl, () => this.onLoad(config))
|
||||
);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toastr.error(
|
||||
typeof error === "string" ? error : error.message,
|
||||
null,
|
||||
0,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
loadDocApi = (docApiUrl, onLoadCallback) => {
|
||||
const script = document.createElement("script");
|
||||
script.setAttribute("type", "text/javascript");
|
||||
script.setAttribute("id", "scripDocServiceAddress");
|
||||
|
||||
script.onload = onLoadCallback;
|
||||
|
||||
script.src = docApiUrl;
|
||||
script.async = true;
|
||||
|
||||
console.log("PureEditor componentDidMount: added script");
|
||||
document.body.appendChild(script);
|
||||
};
|
||||
|
||||
onLoad = (config) => {
|
||||
console.log("Editor config: ", config);
|
||||
try {
|
||||
console.log(config);
|
||||
|
||||
docTitle = config.document.title;
|
||||
fileType = config.document.fileType;
|
||||
|
||||
setFavicon(fileType);
|
||||
setDocumentTitle(docTitle);
|
||||
|
||||
if (window.innerWidth < 720) {
|
||||
config.type = "mobile";
|
||||
}
|
||||
|
||||
const events = {
|
||||
events: {
|
||||
onAppReady: this.onSDKAppReady,
|
||||
onDocumentStateChange: this.onDocumentStateChange,
|
||||
onMetaChange: this.onMetaChange,
|
||||
onDocumentReady: this.onDocumentReady,
|
||||
onInfo: this.onSDKInfo,
|
||||
onWarning: this.onSDKWarning,
|
||||
onError: this.onSDKError,
|
||||
},
|
||||
};
|
||||
|
||||
const newConfig = Object.assign(config, events);
|
||||
|
||||
if (!window.DocsAPI) throw new Error("DocsAPI is not defined");
|
||||
|
||||
//hideLoader();
|
||||
|
||||
window.DocsAPI.DocEditor("editor", newConfig);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
toastr.error(error.message, null, 0, true);
|
||||
}
|
||||
};
|
||||
|
||||
onSDKAppReady = () => {
|
||||
console.log("ONLYOFFICE Document Editor is ready");
|
||||
};
|
||||
|
||||
onSDKInfo = (event) => {
|
||||
console.log(
|
||||
"ONLYOFFICE Document Editor is opened in mode " + event.data.mode
|
||||
);
|
||||
};
|
||||
|
||||
onSDKWarning = (event) => {
|
||||
console.log(
|
||||
"ONLYOFFICE Document Editor reports a warning: code " +
|
||||
event.data.warningCode +
|
||||
", description " +
|
||||
event.data.warningDescription
|
||||
);
|
||||
};
|
||||
|
||||
onSDKError = (event) => {
|
||||
console.log(
|
||||
"ONLYOFFICE Document Editor reports an error: code " +
|
||||
event.data.errorCode +
|
||||
", description " +
|
||||
event.data.errorDescription
|
||||
);
|
||||
};
|
||||
|
||||
onDocumentStateChange = (event) => {
|
||||
if (!documentIsReady) return;
|
||||
|
||||
docSaved = !event.data;
|
||||
throttledChangeTitle();
|
||||
};
|
||||
|
||||
onDocumentReady = () => {
|
||||
documentIsReady = true;
|
||||
};
|
||||
|
||||
onMetaChange = (event) => {
|
||||
const newTitle = event.data.title;
|
||||
if (newTitle && newTitle !== docTitle) {
|
||||
setDocumentTitle(newTitle);
|
||||
docTitle = newTitle;
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Box
|
||||
widthProp="100vw"
|
||||
heightProp={isIPad() ? "calc(var(--vh, 1vh) * 100)" : "100vh"}
|
||||
>
|
||||
<Toast />
|
||||
|
||||
{!this.state.isLoading ? (
|
||||
<div id="editor"></div>
|
||||
) : (
|
||||
<Box paddingProp="16px">
|
||||
<Loaders.Rectangle height="96vh" />
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Editor;
|
5
web/ASC.Web.Editor/src/bootstrap.js
vendored
Normal file
5
web/ASC.Web.Editor/src/bootstrap.js
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
25
web/ASC.Web.Editor/src/custom.scss
Normal file
25
web/ASC.Web.Editor/src/custom.scss
Normal file
@ -0,0 +1,25 @@
|
||||
// Override default variables before the import
|
||||
//$font-family-base: "Open Sans", sans-serif;
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root {
|
||||
min-height: 100%;
|
||||
|
||||
.pageLoader {
|
||||
position: fixed;
|
||||
left: calc(50% - 20px);
|
||||
top: 35%;
|
||||
}
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body.loading * {
|
||||
cursor: wait !important;
|
||||
}
|
46
web/ASC.Web.Editor/src/i18n.js
Normal file
46
web/ASC.Web.Editor/src/i18n.js
Normal file
@ -0,0 +1,46 @@
|
||||
import i18n from "i18next";
|
||||
import { initReactI18next } from "react-i18next";
|
||||
import Backend from "i18next-http-backend";
|
||||
import config from "../package.json";
|
||||
import { LANGUAGE } from "@appserver/common/constants";
|
||||
|
||||
const languages = ["en", "ru"];
|
||||
|
||||
const newInstance = i18n.createInstance();
|
||||
|
||||
const lng = localStorage.getItem(LANGUAGE) || "en";
|
||||
|
||||
newInstance
|
||||
.use(initReactI18next)
|
||||
.use(Backend)
|
||||
.init({
|
||||
lng: "ru",
|
||||
supportedLngs: languages,
|
||||
//whitelist: languages,
|
||||
fallbackLng: "ru",
|
||||
load: "languageOnly",
|
||||
debug: true,
|
||||
|
||||
interpolation: {
|
||||
escapeValue: false, // not needed for react as it escapes by default
|
||||
format: function (value, format) {
|
||||
if (format === "lowercase") return value.toLowerCase();
|
||||
return value;
|
||||
},
|
||||
},
|
||||
|
||||
backend: {
|
||||
loadPath: `${config.homepage}/locales/{{lng}}/{{ns}}.json`,
|
||||
allowMultiLoading: true,
|
||||
crossDomain: false,
|
||||
},
|
||||
|
||||
ns: ["Login"],
|
||||
defaultNS: "Login",
|
||||
|
||||
react: {
|
||||
useSuspense: true,
|
||||
},
|
||||
});
|
||||
|
||||
export default newInstance;
|
BIN
web/ASC.Web.Editor/src/icons/presentation.ico
Normal file
BIN
web/ASC.Web.Editor/src/icons/presentation.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
web/ASC.Web.Editor/src/icons/spreadsheet.ico
Normal file
BIN
web/ASC.Web.Editor/src/icons/spreadsheet.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
web/ASC.Web.Editor/src/icons/text.ico
Normal file
BIN
web/ASC.Web.Editor/src/icons/text.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
1
web/ASC.Web.Editor/src/index.js
Normal file
1
web/ASC.Web.Editor/src/index.js
Normal file
@ -0,0 +1 @@
|
||||
import("./bootstrap");
|
56
web/ASC.Web.Editor/src/utils.js
Normal file
56
web/ASC.Web.Editor/src/utils.js
Normal file
@ -0,0 +1,56 @@
|
||||
import store from "studio/store";
|
||||
import { isIOS, deviceType } from "react-device-detect";
|
||||
|
||||
const { auth } = store;
|
||||
|
||||
//import textIcon from "./icons/text.ico";
|
||||
//import presentationIcon from "./icons/presentation.ico";
|
||||
//import spreadsheetIcon from "./icons/spreadsheet.ico";
|
||||
|
||||
export const changeTitle = (docSaved, docTitle) => {
|
||||
docSaved ? setDocumentTitle(docTitle) : setDocumentTitle(`*${docTitle}`);
|
||||
};
|
||||
|
||||
export const setFavicon = (fileType) => {
|
||||
const favicon = document.getElementById("favicon");
|
||||
if (!favicon) return;
|
||||
|
||||
switch (fileType) {
|
||||
case "docx":
|
||||
//favicon.href = textIcon;
|
||||
break;
|
||||
case "pptx":
|
||||
//favicon.href = presentationIcon;
|
||||
break;
|
||||
case "xlsx":
|
||||
//favicon.href = spreadsheetIcon;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
export const isIPad = () => {
|
||||
return isIOS && deviceType === "tablet";
|
||||
};
|
||||
|
||||
export const setDocumentTitle = (subTitle = null) => {
|
||||
const { isAuthenticated, settingsStore, product: currentModule } = auth;
|
||||
const { organizationName } = settingsStore;
|
||||
|
||||
let title;
|
||||
if (subTitle) {
|
||||
if (isAuthenticated && currentModule) {
|
||||
title = subTitle + " - " + currentModule.title;
|
||||
} else {
|
||||
title = subTitle + " - " + organizationName;
|
||||
}
|
||||
} else if (currentModule && organizationName) {
|
||||
title = currentModule.title + " - " + organizationName;
|
||||
} else {
|
||||
title = organizationName;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
};
|
162
web/ASC.Web.Editor/webpack.config.js
Normal file
162
web/ASC.Web.Editor/webpack.config.js
Normal file
@ -0,0 +1,162 @@
|
||||
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
|
||||
const CopyPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const ModuleFederationPlugin = require("webpack").container
|
||||
.ModuleFederationPlugin;
|
||||
const path = require("path");
|
||||
const pkg = require("./package.json");
|
||||
const deps = pkg.dependencies;
|
||||
const homepage = pkg.homepage;
|
||||
|
||||
var config = {
|
||||
mode: "development",
|
||||
entry: "./src/index",
|
||||
|
||||
devServer: {
|
||||
publicPath: homepage,
|
||||
|
||||
contentBase: [path.join(__dirname, "public")],
|
||||
contentBasePublicPath: homepage,
|
||||
port: 5013,
|
||||
historyApiFallback: {
|
||||
// Paths with dots should still use the history fallback.
|
||||
// See https://github.com/facebook/create-react-app/issues/387.
|
||||
disableDotRule: true,
|
||||
index: homepage,
|
||||
},
|
||||
proxy: [
|
||||
{
|
||||
context: "/api",
|
||||
target: "http://localhost:8092",
|
||||
},
|
||||
],
|
||||
hot: false,
|
||||
hotOnly: false,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
||||
"Access-Control-Allow-Headers":
|
||||
"X-Requested-With, content-type, Authorization",
|
||||
},
|
||||
},
|
||||
|
||||
output: {
|
||||
publicPath: "auto", //homepage
|
||||
chunkFilename: "[id].[contenthash].js",
|
||||
path: path.resolve(process.cwd(), "dist"),
|
||||
},
|
||||
|
||||
resolve: {
|
||||
extensions: [".jsx", ".js", ".json"],
|
||||
fallback: {
|
||||
crypto: false,
|
||||
},
|
||||
},
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.m?js/,
|
||||
type: "javascript/auto",
|
||||
resolve: {
|
||||
fullySpecified: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.react.svg$/,
|
||||
use: [
|
||||
{
|
||||
loader: "@svgr/webpack",
|
||||
options: {
|
||||
svgoConfig: {
|
||||
plugins: [{ removeViewbox: false }],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{ test: /\.json$/, loader: "json-loader" },
|
||||
{
|
||||
test: /\.s[ac]ss$/i,
|
||||
use: [
|
||||
// Creates `style` nodes from JS strings
|
||||
"style-loader",
|
||||
// Translates CSS into CommonJS
|
||||
"css-loader",
|
||||
// Compiles Sass to CSS
|
||||
"sass-loader",
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
{
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
presets: ["@babel/preset-react", "@babel/preset-env"],
|
||||
plugins: [
|
||||
"@babel/plugin-transform-runtime",
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-proposal-export-default-from",
|
||||
],
|
||||
},
|
||||
},
|
||||
"source-map-loader",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new CleanWebpackPlugin(),
|
||||
new ModuleFederationPlugin({
|
||||
name: "editor",
|
||||
filename: "remoteEntry.js",
|
||||
remotes: {
|
||||
studio: "studio@/remoteEntry.js",
|
||||
},
|
||||
exposes: {
|
||||
"./app": "./src/Editor.jsx",
|
||||
},
|
||||
shared: {
|
||||
...deps,
|
||||
react: {
|
||||
singleton: true,
|
||||
requiredVersion: deps.react,
|
||||
},
|
||||
"react-dom": {
|
||||
singleton: true,
|
||||
requiredVersion: deps["react-dom"],
|
||||
},
|
||||
},
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./public/index.html",
|
||||
publicPath: homepage,
|
||||
//base: `${homepage}/`,
|
||||
}),
|
||||
// new CopyPlugin({
|
||||
// patterns: [
|
||||
// {
|
||||
// from: "public",
|
||||
// globOptions: {
|
||||
// dot: true,
|
||||
// gitignore: true,
|
||||
// ignore: ["**/index.html"],
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// }),
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = (env, argv) => {
|
||||
if (argv.mode === "production") {
|
||||
config.mode = "production";
|
||||
} else {
|
||||
config.devtool = "cheap-module-source-map";
|
||||
}
|
||||
|
||||
return config;
|
||||
};
|
43
yarn.lock
43
yarn.lock
@ -2567,10 +2567,10 @@
|
||||
is-plain-object "^5.0.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/openapi-types@^5.2.2":
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.2.2.tgz#1590c118a131031610faffd4222ae54915e2b82d"
|
||||
integrity sha512-b3nHy/0uufJJsaZERwZM0syLRO6gfr6vvBPLewQxBKzzbhGDx1ygTyoELMNADD7mIPPzGMqbfdCeJTSeZueZwA==
|
||||
"@octokit/openapi-types@^5.3.0":
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.0.tgz#29e3faa119da90082dc653ea74c8bb345d197bf7"
|
||||
integrity sha512-5q2qBz4iZ0xS/DEJ0ROusFbN4cVlbJE9GvOByen+mv7artuGXfVhONqcuRd7jYN2glTmCnzcZw+X6LrjRVqs0A==
|
||||
|
||||
"@octokit/plugin-enterprise-rest@^6.0.1":
|
||||
version "6.0.1"
|
||||
@ -2659,11 +2659,11 @@
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@octokit/types@^6.0.3", "@octokit/types@^6.7.1":
|
||||
version "6.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.11.2.tgz#43973dc29cdf59bf9d5f3ab0d16275c4b4a6eb8d"
|
||||
integrity sha512-EKQRFZU/oOfUlqk9ntLIE5UO/bcOx8exFpdXGBciJP90f05me3mza0sacIpqVqmiIQP3nJsBjnZHMmtijE5XwQ==
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.12.0.tgz#8376fd60edfd5d1eebfeedb994c6bcb5b862c7a1"
|
||||
integrity sha512-KwOf16soD7aDEEi/PgNeJlHzjZPfrmmNy+7WezSdrpnqZ7YImBJcNnX9+5RUHt1MnA4h8oISRHTqaZDGsX9DRQ==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^5.2.2"
|
||||
"@octokit/openapi-types" "^5.3.0"
|
||||
|
||||
"@pmmmwh/react-refresh-webpack-plugin@^0.4.2":
|
||||
version "0.4.3"
|
||||
@ -6656,9 +6656,9 @@ cp-file@^7.0.0:
|
||||
p-event "^4.1.0"
|
||||
|
||||
cpy@^8.1.1:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.1.tgz#066ed4c6eaeed9577df96dae4db9438c1a90df62"
|
||||
integrity sha512-vqHT+9o67sMwJ5hUd/BAOYeemkU+MuFRsK2c36Xc3eefQpAsp1kAsyDxEDcc5JS1+y9l/XHPrIsVTcyGGmkUUQ==
|
||||
version "8.1.2"
|
||||
resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935"
|
||||
integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==
|
||||
dependencies:
|
||||
arrify "^2.0.1"
|
||||
cp-file "^7.0.0"
|
||||
@ -7049,9 +7049,9 @@ data-urls@^1.0.0:
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-fns@^2.0.1:
|
||||
version "2.18.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.18.0.tgz#08e50aee300ad0d2c5e054e3f0d10d8f9cdfe09e"
|
||||
integrity sha512-NYyAg4wRmGVU4miKq5ivRACOODdZRY3q5WLmOJSq8djyzftYphU7dTHLcEtLqEvfqMKQ0jVv91P4BAwIjsXIcw==
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
|
||||
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
|
||||
|
||||
dateformat@^3.0.0:
|
||||
version "3.0.3"
|
||||
@ -7121,7 +7121,7 @@ deep-equal-ident@^1.1.1:
|
||||
dependencies:
|
||||
lodash.isequal "^3.0"
|
||||
|
||||
deep-equal@^1.0.1:
|
||||
deep-equal@^1.0.1, deep-equal@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
||||
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
|
||||
@ -7584,9 +7584,9 @@ ejs@^3.1.2:
|
||||
jake "^10.6.1"
|
||||
|
||||
electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.649:
|
||||
version "1.3.680"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.680.tgz#88cc44bd2a85b46cf7521f714db57dd74d0cd488"
|
||||
integrity sha512-XBACJT9RdpdWtoMXQPR8Be3ZtmizWWbxfw8cY2b5feUwiDO3FUl8qo4W2jXoq/WnnA3xBRqafu1XbpczqyUvlA==
|
||||
version "1.3.681"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.681.tgz#facd915ae46a020e8be566a2ecdc0b9444439be9"
|
||||
integrity sha512-W6uYvSUTHuyX2DZklIESAqx57jfmGjUkd7Z3RWqLdj9Mmt39ylhBuvFXlskQnvBHj0MYXIeQI+mjiwVddZLSvA==
|
||||
|
||||
element-resize-detector@^1.2.1:
|
||||
version "1.2.2"
|
||||
@ -14570,12 +14570,13 @@ react-popper-tooltip@^3.1.1:
|
||||
react-popper "^2.2.4"
|
||||
|
||||
react-popper@^1.3.7:
|
||||
version "1.3.10"
|
||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.10.tgz#96fd88cc1bf45957e551c5053afea7adc0b1d4d8"
|
||||
integrity sha512-sZfwHtHCMst0L0G/c83/Y/K1f9fNWMEKsk/cGAor68rQBHB75WuDQ7k95tkce8QNaUHhg9uFXIJbZO0eWRvJbw==
|
||||
version "1.3.11"
|
||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.11.tgz#a2cc3f0a67b75b66cfa62d2c409f9dd1fcc71ffd"
|
||||
integrity sha512-VSA/bS+pSndSF2fiasHK/PTEEAyOpX60+H5EPAjoArr8JGm+oihu4UbrqcEBpQibJxBVCpYyjAX7abJ+7DoYVg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
"@hypnosphi/create-react-context" "^0.3.1"
|
||||
deep-equal "^1.1.1"
|
||||
popper.js "^1.14.4"
|
||||
prop-types "^15.6.1"
|
||||
typed-styles "^0.0.7"
|
||||
|
Loading…
Reference in New Issue
Block a user