init
8
.eslintrc.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"plugins": [
|
||||
"office-addins"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:office-addins/react"
|
||||
]
|
||||
}
|
23
.gitignore
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
5
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
157
.idea/codeStyles/Project.xml
Normal file
|
@ -0,0 +1,157 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<HTMLCodeStyleSettings>
|
||||
<option name="HTML_ATTRIBUTE_WRAP" value="4" />
|
||||
<option name="HTML_ALIGN_ATTRIBUTES" value="false" />
|
||||
<option name="HTML_SPACE_INSIDE_EMPTY_TAG" value="true" />
|
||||
<option name="HTML_ENFORCE_QUOTES" value="true" />
|
||||
<option name="HTML_NEWLINE_BEFORE_FIRST_ATTRIBUTE" value="When multiline" />
|
||||
<option name="HTML_NEWLINE_AFTER_LAST_ATTRIBUTE" value="When multiline" />
|
||||
</HTMLCodeStyleSettings>
|
||||
<JSCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
<option name="SPACES_WITHIN_INTERPOLATION_EXPRESSIONS" value="true" />
|
||||
</JSCodeStyleSettings>
|
||||
<PHPCodeStyleSettings>
|
||||
<option name="COMMA_AFTER_LAST_ARRAY_ELEMENT" value="true" />
|
||||
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
|
||||
<option name="LOWER_CASE_NULL_CONST" value="true" />
|
||||
<option name="ELSE_IF_STYLE" value="SEPARATE" />
|
||||
<option name="KEEP_RPAREN_AND_LBRACE_ON_ONE_LINE" value="true" />
|
||||
<option name="FORCE_SHORT_DECLARATION_ARRAY_STYLE" value="true" />
|
||||
</PHPCodeStyleSettings>
|
||||
<SqlCodeStyleSettings>
|
||||
<option name="ALIGN_AS_IN_SELECT_STATEMENT" value="false" />
|
||||
<option name="ALIGN_TYPE_IN_CREATE_STATEMENT" value="false" />
|
||||
<option name="ALIGN_TYPE_IN_BLOCK_STATEMENT" value="false" />
|
||||
<option name="ALIGN_TYPE_IN_ARGUMENT_DEFINITION" value="false" />
|
||||
<option name="ALIGN_INSIDE_BINARY_EXPRESSION" value="false" />
|
||||
<option name="ALIGN_INSIDE_QUERY_EXPRESSION" value="false" />
|
||||
<option name="ALIGN_EQ_INSIDE_SET_CLAUSE" value="false" />
|
||||
<option name="NEW_LINE_BEFORE_QUERY_INSIDE_PARENTHESIS" value="true" />
|
||||
<option name="KEYWORD_CASE" value="1" />
|
||||
</SqlCodeStyleSettings>
|
||||
<TypeScriptCodeStyleSettings version="0">
|
||||
<option name="FORCE_SEMICOLON_STYLE" value="true" />
|
||||
<option name="SPACE_BEFORE_FUNCTION_LEFT_PARENTH" value="false" />
|
||||
<option name="FORCE_QUOTE_STYlE" value="true" />
|
||||
<option name="ENFORCE_TRAILING_COMMA" value="Remove" />
|
||||
<option name="SPACES_WITHIN_OBJECT_LITERAL_BRACES" value="true" />
|
||||
<option name="SPACES_WITHIN_IMPORTS" value="true" />
|
||||
</TypeScriptCodeStyleSettings>
|
||||
<VueCodeStyleSettings>
|
||||
<option name="INTERPOLATION_NEW_LINE_AFTER_START_DELIMITER" value="false" />
|
||||
<option name="INTERPOLATION_NEW_LINE_BEFORE_END_DELIMITER" value="false" />
|
||||
</VueCodeStyleSettings>
|
||||
<codeStyleSettings language="Blade">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="CSS">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="GraphQL">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="HTML">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JavaScript">
|
||||
<option name="WRAP_ON_TYPING" value="0" />
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
<option name="SMART_TABS" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="PHP">
|
||||
<option name="METHOD_BRACE_STYLE" value="1" />
|
||||
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="CALL_PARAMETERS_WRAP" value="5" />
|
||||
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_CALL_CHAIN_WRAP" value="5" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
|
||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SCSS">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="SQL">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="TypeScript">
|
||||
<option name="CALL_PARAMETERS_WRAP" value="5" />
|
||||
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
|
||||
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="Vue">
|
||||
<option name="SOFT_MARGINS" value="80" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="INDENT_SIZE" value="2" />
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
<option name="TAB_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="ruby">
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="2" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
12
.idea/cp-press-release-word-plugin.iml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
6
.idea/jsLinters/eslint.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EslintConfiguration">
|
||||
<option name="fix-on-save" value="true" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/cp-press-release-word-plugin.iml" filepath="$PROJECT_DIR$/.idea/cp-press-release-word-plugin.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
7
.idea/prettier.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
14
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
|
||||
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
|
||||
|
||||
// List of extensions which should be recommended for users of this workspace.
|
||||
"recommendations": [
|
||||
"ms-edgedevtools.vscode-edge-devtools",
|
||||
"msoffice.microsoft-office-add-in-debugger",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": []
|
||||
}
|
93
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Excel Desktop (Edge Chromium)",
|
||||
"type": "msedge",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Excel Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "Excel Desktop (Edge Legacy)",
|
||||
"type": "office-addin",
|
||||
"request": "attach",
|
||||
"url": "https://localhost:3000/taskpane.html?_host_Info=Excel$Win32$16.01$en-US$$$$0",
|
||||
"port": 9222,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Excel Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "Outlook Desktop (Edge Chromium)",
|
||||
"type": "msedge",
|
||||
"request": "attach",
|
||||
"useWebView": true,
|
||||
"port": 9229,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Outlook Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "Outlook Desktop (Edge Legacy)",
|
||||
"type": "office-addin",
|
||||
"request": "attach",
|
||||
"url": "https://localhost:3000/taskpane.html?_host_Info=Outlook$Win32$16.01$en-US$$$$0",
|
||||
"port": 9222,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Outlook Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "PowerPoint Desktop (Edge Chromium)",
|
||||
"type": "msedge",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: PowerPoint Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "PowerPoint Desktop (Edge Legacy)",
|
||||
"type": "office-addin",
|
||||
"request": "attach",
|
||||
"url": "https://localhost:3000/taskpane.html?_host_Info=PowerPoint$Win32$16.01$en-US$$$$0",
|
||||
"port": 9222,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: PowerPoint Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "Word Desktop (Edge Chromium)",
|
||||
"type": "msedge",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Word Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
},
|
||||
{
|
||||
"name": "Word Desktop (Edge Legacy)",
|
||||
"type": "office-addin",
|
||||
"request": "attach",
|
||||
"url": "https://localhost:3000/taskpane.html?_host_Info=Word$Win32$16.01$en-US$$$$0",
|
||||
"port": 9222,
|
||||
"timeout": 600000,
|
||||
"webRoot": "${workspaceRoot}",
|
||||
"preLaunchTask": "Debug: Word Desktop",
|
||||
"postDebugTask": "Stop Debug"
|
||||
}
|
||||
]
|
||||
}
|
8
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript"
|
||||
]
|
||||
}
|
||||
|
130
.vscode/tasks.json
vendored
Normal file
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Build (Development)",
|
||||
"type": "npm",
|
||||
"script": "build:dev",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build (Production)",
|
||||
"type": "npm",
|
||||
"script": "build",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Debug: Excel Desktop",
|
||||
"type": "npm",
|
||||
"script": "start:desktop -- --app excel",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated",
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: Outlook Desktop",
|
||||
"type": "npm",
|
||||
"script": "start:desktop -- --app outlook",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated",
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: PowerPoint Desktop",
|
||||
"type": "npm",
|
||||
"script": "start:desktop -- --app powerpoint",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated",
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: Word Desktop",
|
||||
"type": "npm",
|
||||
"script": "start:desktop -- --app word",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated",
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Dev Server",
|
||||
"type": "npm",
|
||||
"script": "dev-server",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Install",
|
||||
"type": "npm",
|
||||
"script": "install",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Lint: Check for problems",
|
||||
"type": "npm",
|
||||
"script": "lint",
|
||||
"problemMatcher": [
|
||||
"$eslint-stylish"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Lint: Fix all auto-fixable problems",
|
||||
"type": "npm",
|
||||
"script": "lint:fix",
|
||||
"problemMatcher": [
|
||||
"$eslint-stylish"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Stop Debug",
|
||||
"type": "npm",
|
||||
"script": "stop",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Watch",
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
]
|
||||
}
|
BIN
assets/icon-128.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
assets/icon-16.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
assets/icon-32.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/icon-64.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/icon-80.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
assets/logo-filled.png
Normal file
After Width: | Height: | Size: 12 KiB |
3
babel.config.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"presets": ["@babel/preset-typescript"]
|
||||
}
|
80
dist/8d9dfc10165c310961fd.css
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
* See LICENSE in the project root for license information.
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ms-welcome__header {
|
||||
padding: 20px;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ms-welcome__main {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-flex-wrap: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
/*-webkit-align-items: center;*/
|
||||
/*align-items: center;*/
|
||||
-webkit-flex: 1 0 0;
|
||||
flex: 1 0 0;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
/* .ms-welcome__main > h2 {*/
|
||||
/* width: 100%;*/
|
||||
/* text-align: center;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features {*/
|
||||
/* list-style-type: none;*/
|
||||
/* margin-top: 20px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features.ms-List .ms-ListItem {*/
|
||||
/* padding-bottom: 20px;*/
|
||||
/* display: -webkit-flex;*/
|
||||
/* display: flex;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features.ms-List .ms-ListItem > .ms-Icon {*/
|
||||
/* margin-right: 10px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__action.ms-Button--hero {*/
|
||||
/* margin-top: 30px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/*.ms-Button.ms-Button--hero .ms-Button-label {*/
|
||||
/* color: #0078d7;*/
|
||||
/*}*/
|
||||
|
||||
/*.ms-Button.ms-Button--hero:hover .ms-Button-label,*/
|
||||
/*.ms-Button.ms-Button--hero:focus .ms-Button-label{*/
|
||||
/* color: #005a9e;*/
|
||||
/* cursor: pointer;*/
|
||||
/*}*/
|
||||
|
||||
/*b {*/
|
||||
/* font-weight: bold;*/
|
||||
/*}*/
|
BIN
dist/assets/icon-128.png
vendored
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
dist/assets/icon-16.png
vendored
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
dist/assets/icon-32.png
vendored
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
dist/assets/icon-64.png
vendored
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
dist/assets/icon-80.png
vendored
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
dist/assets/logo-filled.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
18
dist/commands.html
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
|
||||
<!-- Office JavaScript API -->
|
||||
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
|
||||
<script defer src="commands.js"></script></head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
97
dist/commands.js
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/******/ (function() { // webpackBootstrap
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ "./src/commands/commands.ts":
|
||||
/*!**********************************!*\
|
||||
!*** ./src/commands/commands.ts ***!
|
||||
\**********************************/
|
||||
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
||||
|
||||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
* See LICENSE in the project root for license information.
|
||||
*/
|
||||
/* global global, Office, self, window */
|
||||
Office.onReady(function () {
|
||||
// If needed, Office.js is ready to be called
|
||||
});
|
||||
/**
|
||||
* Shows a notification when the add-in command is executed.
|
||||
* @param event
|
||||
*/
|
||||
function action(event) {
|
||||
var message = {
|
||||
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
|
||||
message: "Performed action.",
|
||||
icon: "Icon.80x80",
|
||||
persistent: true
|
||||
};
|
||||
// Show a notification message
|
||||
Office.context.mailbox.item.notificationMessages.replaceAsync("action", message);
|
||||
// Be sure to indicate when the add-in command function is complete
|
||||
event.completed();
|
||||
}
|
||||
function getGlobal() {
|
||||
return typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof __webpack_require__.g !== "undefined" ? __webpack_require__.g : undefined;
|
||||
}
|
||||
var g = getGlobal();
|
||||
// The add-in command functions need to be available in global scope
|
||||
g.action = action;
|
||||
void function register() {
|
||||
/* react-hot-loader/webpack */var reactHotLoader = typeof reactHotLoaderGlobal !== 'undefined' ? reactHotLoaderGlobal.default : undefined;
|
||||
if (!reactHotLoader) {
|
||||
return;
|
||||
} /* eslint-disable camelcase, no-undef */
|
||||
var webpackExports = typeof __webpack_exports__ !== 'undefined' ? __webpack_exports__ : exports; /* eslint-enable camelcase, no-undef */
|
||||
if (!webpackExports) {
|
||||
return;
|
||||
}
|
||||
if (typeof webpackExports === 'function') {
|
||||
reactHotLoader.register(webpackExports, 'module.exports', "/Users/pavel/work/cp-press-release-word-plugin/src/commands/commands.ts");
|
||||
return;
|
||||
} /* eslint-disable no-restricted-syntax */
|
||||
for (var key in webpackExports) {
|
||||
/* eslint-enable no-restricted-syntax */if (!Object.prototype.hasOwnProperty.call(webpackExports, key)) {
|
||||
continue;
|
||||
}
|
||||
var namedExport = void 0;
|
||||
try {
|
||||
namedExport = webpackExports[key];
|
||||
} catch (err) {
|
||||
continue;
|
||||
}
|
||||
reactHotLoader.register(namedExport, key, "/Users/pavel/work/cp-press-release-word-plugin/src/commands/commands.ts");
|
||||
}
|
||||
}();
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The require scope
|
||||
/******/ var __webpack_require__ = {};
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/global */
|
||||
/******/ !function() {
|
||||
/******/ __webpack_require__.g = (function() {
|
||||
/******/ if (typeof globalThis === 'object') return globalThis;
|
||||
/******/ try {
|
||||
/******/ return this || new Function('return this')();
|
||||
/******/ } catch (e) {
|
||||
/******/ if (typeof window === 'object') return window;
|
||||
/******/ }
|
||||
/******/ })();
|
||||
/******/ }();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/ // startup
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||
/******/ var __webpack_exports__ = {};
|
||||
/******/ __webpack_modules__["./src/commands/commands.ts"](0, __webpack_exports__, __webpack_require__);
|
||||
/******/
|
||||
/******/ })()
|
||||
;
|
||||
//# sourceMappingURL=commands.js.map
|
1
dist/commands.js.map
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"commands.js","mappings":";;;;;;;;;AAAA;;;;AAKA;AAEAA,MAAM,CAACC,OAAO,CAAC;EACb;AAAA,CACD,CAAC;AAEF;;;;AAIA,SAASC,MAAMA,CAACC,KAAiC;EAC/C,IAAMC,OAAO,GAAsC;IACjDC,IAAI,EAAEL,MAAM,CAACM,YAAY,CAACC,2BAA2B,CAACC,oBAAoB;IAC1EJ,OAAO,EAAE,mBAAmB;IAC5BK,IAAI,EAAE,YAAY;IAClBC,UAAU,EAAE;GACb;EAED;EACAV,MAAM,CAACW,OAAO,CAACC,OAAO,CAACC,IAAI,CAACC,oBAAoB,CAACC,YAAY,CAAC,QAAQ,EAAEX,OAAO,CAAC;EAEhF;EACAD,KAAK,CAACa,SAAS,EAAE;AACnB;AAEA,SAASC,SAASA,CAAA;EAChB,OAAO,OAAOC,IAAI,KAAK,WAAW,GAC9BA,IAAI,GACJ,OAAOC,MAAM,KAAK,WAAW,GAC7BA,MAAM,GACN,OAAOC,qBAAM,KAAK,WAAW,GAC7BA,qBAAM,GACNC,SAAS;AACf;AAEA,IAAMC,CAAC,GAAGL,SAAS,EAAS;AAE5B;AACAK,CAAC,CAACpB,MAAM,GAAGA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UC3CjB;UACA;;;;;WCDA;WACA;WACA;WACA;WACA,GAAG;WACH;WACA;WACA,CAAC;;;;;UEPD;UACA;UACA;UACA;UACA","sources":["webpack://office-addin-taskpane-react/./src/commands/commands.ts","webpack://office-addin-taskpane-react/webpack/bootstrap","webpack://office-addin-taskpane-react/webpack/runtime/global","webpack://office-addin-taskpane-react/webpack/before-startup","webpack://office-addin-taskpane-react/webpack/startup","webpack://office-addin-taskpane-react/webpack/after-startup"],"sourcesContent":["/*\n * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n * See LICENSE in the project root for license information.\n */\n\n/* global global, Office, self, window */\n\nOffice.onReady(() => {\n // If needed, Office.js is ready to be called\n});\n\n/**\n * Shows a notification when the add-in command is executed.\n * @param event\n */\nfunction action(event: Office.AddinCommands.Event) {\n const message: Office.NotificationMessageDetails = {\n type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,\n message: \"Performed action.\",\n icon: \"Icon.80x80\",\n persistent: true,\n };\n\n // Show a notification message\n Office.context.mailbox.item.notificationMessages.replaceAsync(\"action\", message);\n\n // Be sure to indicate when the add-in command function is complete\n event.completed();\n}\n\nfunction getGlobal() {\n return typeof self !== \"undefined\"\n ? self\n : typeof window !== \"undefined\"\n ? window\n : typeof global !== \"undefined\"\n ? global\n : undefined;\n}\n\nconst g = getGlobal() as any;\n\n// The add-in command functions need to be available in global scope\ng.action = action;\n","// The require scope\nvar __webpack_require__ = {};\n\n","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\nvar __webpack_exports__ = {};\n__webpack_modules__[\"./src/commands/commands.ts\"](0, __webpack_exports__, __webpack_require__);\n",""],"names":["Office","onReady","action","event","message","type","MailboxEnums","ItemNotificationMessageType","InformationalMessage","icon","persistent","context","mailbox","item","notificationMessages","replaceAsync","completed","getGlobal","self","window","global","undefined","g"],"sourceRoot":""}
|
85
dist/manifest.xml
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
|
||||
<Id>9a463859-68ff-41ed-8f96-d418dffb73b3</Id>
|
||||
<Version>1.0.0.0</Version>
|
||||
<ProviderName>Contoso</ProviderName>
|
||||
<DefaultLocale>en-US</DefaultLocale>
|
||||
<DisplayName DefaultValue="cp-press-release-word-plugin"/>
|
||||
<Description DefaultValue="A template to get started."/>
|
||||
<IconUrl DefaultValue="https://localhost:3000/assets/icon-32.png"/>
|
||||
<HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/icon-64.png"/>
|
||||
<SupportUrl DefaultValue="https://www.contoso.com/help"/>
|
||||
<AppDomains>
|
||||
<AppDomain>https://www.contoso.com</AppDomain>
|
||||
</AppDomains>
|
||||
<Hosts>
|
||||
<Host Name="Document"/>
|
||||
</Hosts>
|
||||
<DefaultSettings>
|
||||
<SourceLocation DefaultValue="https://localhost:3000/taskpane.html"/>
|
||||
</DefaultSettings>
|
||||
<Permissions>ReadWriteDocument</Permissions>
|
||||
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
|
||||
<Hosts>
|
||||
<Host xsi:type="Document">
|
||||
<DesktopFormFactor>
|
||||
<GetStarted>
|
||||
<Title resid="GetStarted.Title"/>
|
||||
<Description resid="GetStarted.Description"/>
|
||||
<LearnMoreUrl resid="GetStarted.LearnMoreUrl"/>
|
||||
</GetStarted>
|
||||
<FunctionFile resid="Commands.Url"/>
|
||||
<ExtensionPoint xsi:type="PrimaryCommandSurface">
|
||||
<OfficeTab id="TabHome">
|
||||
<Group id="CommandsGroup">
|
||||
<Label resid="CommandsGroup.Label"/>
|
||||
<Icon>
|
||||
<bt:Image size="16" resid="Icon.16x16"/>
|
||||
<bt:Image size="32" resid="Icon.32x32"/>
|
||||
<bt:Image size="80" resid="Icon.80x80"/>
|
||||
</Icon>
|
||||
<Control xsi:type="Button" id="TaskpaneButton">
|
||||
<Label resid="TaskpaneButton.Label"/>
|
||||
<Supertip>
|
||||
<Title resid="TaskpaneButton.Label"/>
|
||||
<Description resid="TaskpaneButton.Tooltip"/>
|
||||
</Supertip>
|
||||
<Icon>
|
||||
<bt:Image size="16" resid="Icon.16x16"/>
|
||||
<bt:Image size="32" resid="Icon.32x32"/>
|
||||
<bt:Image size="80" resid="Icon.80x80"/>
|
||||
</Icon>
|
||||
<Action xsi:type="ShowTaskpane">
|
||||
<TaskpaneId>ButtonId1</TaskpaneId>
|
||||
<SourceLocation resid="Taskpane.Url"/>
|
||||
</Action>
|
||||
</Control>
|
||||
</Group>
|
||||
</OfficeTab>
|
||||
</ExtensionPoint>
|
||||
</DesktopFormFactor>
|
||||
</Host>
|
||||
</Hosts>
|
||||
<Resources>
|
||||
<bt:Images>
|
||||
<bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
|
||||
<bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
|
||||
<bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
|
||||
</bt:Images>
|
||||
<bt:Urls>
|
||||
<bt:Url id="GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812"/>
|
||||
<bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
|
||||
<bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
|
||||
</bt:Urls>
|
||||
<bt:ShortStrings>
|
||||
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
|
||||
<bt:String id="CommandsGroup.Label" DefaultValue="Commands Group"/>
|
||||
<bt:String id="TaskpaneButton.Label" DefaultValue="Show Taskpane"/>
|
||||
</bt:ShortStrings>
|
||||
<bt:LongStrings>
|
||||
<bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show Taskpane' button to get started."/>
|
||||
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane"/>
|
||||
</bt:LongStrings>
|
||||
</Resources>
|
||||
</VersionOverrides>
|
||||
</OfficeApp>
|
23118
dist/polyfill.js
vendored
Normal file
1
dist/polyfill.js.map
vendored
Normal file
27
dist/taskpane.html
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -->
|
||||
<!-- See LICENSE in the project root for license information -->
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" data-framework="typescript">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Press-release analyzer</title>
|
||||
|
||||
<!-- Office JavaScript API -->
|
||||
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
|
||||
|
||||
<!-- For more information on Fluent UI, visit https://developer.microsoft.com/fluentui#/. -->
|
||||
<link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/11.0.0/css/fabric.min.css"/>
|
||||
|
||||
<!-- Template styles -->
|
||||
<link href="8d9dfc10165c310961fd.css" rel="stylesheet" type="text/css" />
|
||||
<script defer src="vendor.js"></script><script defer src="taskpane.js"></script></head>
|
||||
|
||||
<body class="ms-font-m ms-Fabric">
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
115508
dist/taskpane.js
vendored
Normal file
1
dist/taskpane.js.map
vendored
Normal file
137659
dist/vendor.js
vendored
Normal file
1
dist/vendor.js.map
vendored
Normal file
85
manifest.xml
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bt="http://schemas.microsoft.com/office/officeappbasictypes/1.0" xmlns:ov="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="TaskPaneApp">
|
||||
<Id>9a463859-68ff-41ed-8f96-d418dffb73b3</Id>
|
||||
<Version>1.0.0.0</Version>
|
||||
<ProviderName>Contoso</ProviderName>
|
||||
<DefaultLocale>en-US</DefaultLocale>
|
||||
<DisplayName DefaultValue="cp-press-release-word-plugin"/>
|
||||
<Description DefaultValue="A template to get started."/>
|
||||
<IconUrl DefaultValue="https://localhost:3000/assets/icon-32.png"/>
|
||||
<HighResolutionIconUrl DefaultValue="https://localhost:3000/assets/icon-64.png"/>
|
||||
<SupportUrl DefaultValue="https://www.contoso.com/help"/>
|
||||
<AppDomains>
|
||||
<AppDomain>https://www.contoso.com</AppDomain>
|
||||
</AppDomains>
|
||||
<Hosts>
|
||||
<Host Name="Document"/>
|
||||
</Hosts>
|
||||
<DefaultSettings>
|
||||
<SourceLocation DefaultValue="https://localhost:3000/taskpane.html"/>
|
||||
</DefaultSettings>
|
||||
<Permissions>ReadWriteDocument</Permissions>
|
||||
<VersionOverrides xmlns="http://schemas.microsoft.com/office/taskpaneappversionoverrides" xsi:type="VersionOverridesV1_0">
|
||||
<Hosts>
|
||||
<Host xsi:type="Document">
|
||||
<DesktopFormFactor>
|
||||
<GetStarted>
|
||||
<Title resid="GetStarted.Title"/>
|
||||
<Description resid="GetStarted.Description"/>
|
||||
<LearnMoreUrl resid="GetStarted.LearnMoreUrl"/>
|
||||
</GetStarted>
|
||||
<FunctionFile resid="Commands.Url"/>
|
||||
<ExtensionPoint xsi:type="PrimaryCommandSurface">
|
||||
<OfficeTab id="TabHome">
|
||||
<Group id="CommandsGroup">
|
||||
<Label resid="CommandsGroup.Label"/>
|
||||
<Icon>
|
||||
<bt:Image size="16" resid="Icon.16x16"/>
|
||||
<bt:Image size="32" resid="Icon.32x32"/>
|
||||
<bt:Image size="80" resid="Icon.80x80"/>
|
||||
</Icon>
|
||||
<Control xsi:type="Button" id="TaskpaneButton">
|
||||
<Label resid="TaskpaneButton.Label"/>
|
||||
<Supertip>
|
||||
<Title resid="TaskpaneButton.Label"/>
|
||||
<Description resid="TaskpaneButton.Tooltip"/>
|
||||
</Supertip>
|
||||
<Icon>
|
||||
<bt:Image size="16" resid="Icon.16x16"/>
|
||||
<bt:Image size="32" resid="Icon.32x32"/>
|
||||
<bt:Image size="80" resid="Icon.80x80"/>
|
||||
</Icon>
|
||||
<Action xsi:type="ShowTaskpane">
|
||||
<TaskpaneId>ButtonId1</TaskpaneId>
|
||||
<SourceLocation resid="Taskpane.Url"/>
|
||||
</Action>
|
||||
</Control>
|
||||
</Group>
|
||||
</OfficeTab>
|
||||
</ExtensionPoint>
|
||||
</DesktopFormFactor>
|
||||
</Host>
|
||||
</Hosts>
|
||||
<Resources>
|
||||
<bt:Images>
|
||||
<bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
|
||||
<bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
|
||||
<bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
|
||||
</bt:Images>
|
||||
<bt:Urls>
|
||||
<bt:Url id="GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812"/>
|
||||
<bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
|
||||
<bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
|
||||
</bt:Urls>
|
||||
<bt:ShortStrings>
|
||||
<bt:String id="GetStarted.Title" DefaultValue="Get started with your sample add-in!"/>
|
||||
<bt:String id="CommandsGroup.Label" DefaultValue="Commands Group"/>
|
||||
<bt:String id="TaskpaneButton.Label" DefaultValue="Show Taskpane"/>
|
||||
</bt:ShortStrings>
|
||||
<bt:LongStrings>
|
||||
<bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show Taskpane' button to get started."/>
|
||||
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane"/>
|
||||
</bt:LongStrings>
|
||||
</Resources>
|
||||
</VersionOverrides>
|
||||
</OfficeApp>
|
26831
package-lock.json
generated
Normal file
77
package.json
Normal file
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"name": "office-addin-taskpane-react",
|
||||
"version": "0.0.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/OfficeDev/Office-Addin-TaskPane-React.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"config": {
|
||||
"app_to_debug": "word",
|
||||
"app_type_to_debug": "desktop",
|
||||
"dev_server_port": 3000
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --mode production",
|
||||
"build:dev": "webpack --mode development",
|
||||
"dev-server": "webpack serve --mode development",
|
||||
"lint": "office-addin-lint check",
|
||||
"lint:fix": "office-addin-lint fix",
|
||||
"prettier": "office-addin-lint prettier",
|
||||
"start": "office-addin-debugging start manifest.xml",
|
||||
"start:desktop": "office-addin-debugging start manifest.xml desktop",
|
||||
"start:web": "office-addin-debugging start manifest.xml web",
|
||||
"stop": "office-addin-debugging stop manifest.xml",
|
||||
"validate": "office-addin-manifest validate manifest.xml",
|
||||
"watch": "webpack --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluentui/react": "^8.52.3",
|
||||
"@tanstack/react-query": "^4.35.0",
|
||||
"axios": "^1.5.0",
|
||||
"core-js": "^3.9.1",
|
||||
"es6-promise": "^4.2.8",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"regenerator-runtime": "^0.13.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.10",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@types/office-js": "^1.0.256",
|
||||
"@types/office-runtime": "^1.0.23",
|
||||
"@types/react": "^17.0.39",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/react-hot-loader": "^4.1.1",
|
||||
"@types/webpack": "^4.4.34",
|
||||
"@types/webpack-dev-server": "^4.1.0",
|
||||
"acorn": "^8.5.0",
|
||||
"babel-loader": "^8.2.2",
|
||||
"copy-webpack-plugin": "^9.0.1",
|
||||
"eslint-plugin-office-addins": "^2.1.5",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-loader": "^4.1.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^10.0.1",
|
||||
"office-addin-cli": "^1.5.5",
|
||||
"office-addin-debugging": "^5.0.5",
|
||||
"office-addin-dev-certs": "^1.11.3",
|
||||
"office-addin-lint": "^2.2.5",
|
||||
"office-addin-manifest": "^1.12.3",
|
||||
"office-addin-prettier-config": "^1.2.0",
|
||||
"os-browserify": "^0.3.0",
|
||||
"process": "^0.11.10",
|
||||
"source-map-loader": "^3.0.0",
|
||||
"ts-loader": "^9.4.1",
|
||||
"typescript": "^4.3.5",
|
||||
"webpack": "^5.76.3",
|
||||
"webpack-cli": "^5.0.1",
|
||||
"webpack-dev-server": "4.13.1"
|
||||
},
|
||||
"prettier": "office-addin-prettier-config",
|
||||
"browserslist": [
|
||||
"ie 11"
|
||||
]
|
||||
}
|
18
src/commands/commands.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
|
||||
<!-- Office JavaScript API -->
|
||||
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
44
src/commands/commands.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
* See LICENSE in the project root for license information.
|
||||
*/
|
||||
|
||||
/* global global, Office, self, window */
|
||||
|
||||
Office.onReady(() => {
|
||||
// If needed, Office.js is ready to be called
|
||||
});
|
||||
|
||||
/**
|
||||
* Shows a notification when the add-in command is executed.
|
||||
* @param event
|
||||
*/
|
||||
function action(event: Office.AddinCommands.Event) {
|
||||
const message: Office.NotificationMessageDetails = {
|
||||
type: Office.MailboxEnums.ItemNotificationMessageType.InformationalMessage,
|
||||
message: "Performed action.",
|
||||
icon: "Icon.80x80",
|
||||
persistent: true,
|
||||
};
|
||||
|
||||
// Show a notification message
|
||||
Office.context.mailbox.item.notificationMessages.replaceAsync("action", message);
|
||||
|
||||
// Be sure to indicate when the add-in command function is complete
|
||||
event.completed();
|
||||
}
|
||||
|
||||
function getGlobal() {
|
||||
return typeof self !== "undefined"
|
||||
? self
|
||||
: typeof window !== "undefined"
|
||||
? window
|
||||
: typeof global !== "undefined"
|
||||
? global
|
||||
: undefined;
|
||||
}
|
||||
|
||||
const g = getGlobal() as any;
|
||||
|
||||
// The add-in command functions need to be available in global scope
|
||||
g.action = action;
|
57
src/taskpane/api/process/createProcess.ts
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { useMutation } from "@tanstack/react-query";
|
||||
import { MutationConfig, queryClient } from "../../lib/react-query";
|
||||
import { axios } from "../../lib/axios";
|
||||
import { TextDescriptor } from "./types";
|
||||
import { PROCESS_API_URL } from "./urlKeys";
|
||||
import { QUERY_KEY_PROCESSES } from "./queryKeys";
|
||||
|
||||
export type CreateProcessDTO = Partial<Pick<TextDescriptor, "text">> & {
|
||||
files?: File[];
|
||||
};
|
||||
|
||||
export type CreateProcessResponse = {
|
||||
id: string;
|
||||
};
|
||||
|
||||
export const createProcess = (data: CreateProcessDTO): Promise<CreateProcessResponse> => {
|
||||
const isForm = data.files?.length !== 0;
|
||||
|
||||
let inputData: any;
|
||||
if (isForm) {
|
||||
inputData = new FormData();
|
||||
|
||||
if (data.text) {
|
||||
inputData.append("text", `${data.text}`);
|
||||
}
|
||||
|
||||
data.files?.forEach((file, index) => {
|
||||
inputData.append(`file_${index + 1}`, file);
|
||||
});
|
||||
} else {
|
||||
inputData = {
|
||||
text: data.text,
|
||||
};
|
||||
}
|
||||
|
||||
return axios.post(`${PROCESS_API_URL}/`, inputData, {
|
||||
headers: isForm
|
||||
? {
|
||||
"Content-Type": "multipart/form-data",
|
||||
}
|
||||
: {},
|
||||
});
|
||||
};
|
||||
|
||||
type UseCreateProcessOptions = {
|
||||
config?: MutationConfig<typeof createProcess>;
|
||||
};
|
||||
|
||||
export const useCreateProcess = ({ config }: UseCreateProcessOptions = {}) => {
|
||||
return useMutation({
|
||||
onMutate: async () => {
|
||||
await queryClient.cancelQueries([QUERY_KEY_PROCESSES]);
|
||||
},
|
||||
...config,
|
||||
mutationFn: createProcess,
|
||||
});
|
||||
};
|
29
src/taskpane/api/process/getProcess.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { useQuery } from "@tanstack/react-query";
|
||||
import { axios } from "../../lib/axios";
|
||||
import { ExtractFnReturnType, QueryConfig } from "../../lib/react-query";
|
||||
import { ProcessDescriptor } from "./types";
|
||||
import { PROCESS_API_URL } from "./urlKeys";
|
||||
import { QUERY_KEY_PROCESSES } from "./queryKeys";
|
||||
|
||||
export type GetProcessResponse = ProcessDescriptor;
|
||||
|
||||
export const getProcess = ({ processId }: { processId: string }): Promise<GetProcessResponse> => {
|
||||
return axios.get(`${PROCESS_API_URL}/${processId}`);
|
||||
};
|
||||
|
||||
type QueryFnType = typeof getProcess;
|
||||
|
||||
type UseProcessOptions = {
|
||||
processId: string;
|
||||
config?: QueryConfig<QueryFnType>;
|
||||
};
|
||||
|
||||
export const useProcess = ({ processId, config }: UseProcessOptions) => {
|
||||
return useQuery<ExtractFnReturnType<QueryFnType>>({
|
||||
...config,
|
||||
queryKey: [QUERY_KEY_PROCESSES, processId],
|
||||
queryFn: async () => {
|
||||
return await getProcess({ processId });
|
||||
},
|
||||
});
|
||||
};
|
34
src/taskpane/api/process/getText.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { useQuery } from "@tanstack/react-query";
|
||||
import { axios } from "../../lib/axios";
|
||||
import { ExtractFnReturnType, QueryConfig } from "../../lib/react-query";
|
||||
import { ScoreType, TextDescriptor } from "./types";
|
||||
import { TEXT_API_URL, TEXT_PARAM } from "./urlKeys";
|
||||
import { QUERY_KEY_TEXTS } from "./queryKeys";
|
||||
|
||||
export type GetTextResponse = TextDescriptor;
|
||||
|
||||
export const getText = ({ textId, type = "bert" }: { textId: number; type: ScoreType }): Promise<GetTextResponse> => {
|
||||
return axios.get(TEXT_API_URL.replace(`:${TEXT_PARAM}`, String(textId)), {
|
||||
params: {
|
||||
type,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
type QueryFnType = typeof getText;
|
||||
|
||||
type UseTextOptions = {
|
||||
textId: number;
|
||||
type: ScoreType;
|
||||
config?: QueryConfig<QueryFnType>;
|
||||
};
|
||||
|
||||
export const useText = ({ textId, type, config }: UseTextOptions) => {
|
||||
return useQuery<ExtractFnReturnType<QueryFnType>>({
|
||||
...config,
|
||||
queryKey: [QUERY_KEY_TEXTS, textId, type],
|
||||
queryFn: async () => {
|
||||
return await getText({ textId, type });
|
||||
},
|
||||
});
|
||||
};
|
4
src/taskpane/api/process/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from './types';
|
||||
export * from './createProcess';
|
||||
export * from './getProcess';
|
||||
export * from './getText';
|
2
src/taskpane/api/process/queryKeys.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
export const QUERY_KEY_PROCESSES = "processes";
|
||||
export const QUERY_KEY_TEXTS = "texts";
|
38
src/taskpane/api/process/types.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
export type DetailFeatures = [answer: string, metric: number, texts: string[]];
|
||||
|
||||
export type DetailDescriptor = {
|
||||
text: string;
|
||||
features: DetailFeatures;
|
||||
};
|
||||
|
||||
export type ScoreType = "bert" | "f" | "nearest";
|
||||
|
||||
export type ScoreDescriptor = {
|
||||
[key in ScoreType]: {
|
||||
answer: string;
|
||||
metric?: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type TextDescriptor = {
|
||||
id: number;
|
||||
file_name: string;
|
||||
description:
|
||||
| {
|
||||
[key in ScoreType]?: {
|
||||
file?: string;
|
||||
pdf?: string;
|
||||
text: string | DetailDescriptor[];
|
||||
};
|
||||
}
|
||||
| null;
|
||||
text: string;
|
||||
summary: string;
|
||||
score: ScoreDescriptor;
|
||||
};
|
||||
|
||||
export type ProcessDescriptor = {
|
||||
texts: TextDescriptor[];
|
||||
current: number;
|
||||
total: number;
|
||||
};
|
5
src/taskpane/api/process/urlKeys.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
export const PROCESS_API_URL = "/process";
|
||||
export const PROCESS_PARAM = "processId";
|
||||
|
||||
export const TEXT_PARAM = "textId";
|
||||
export const TEXT_API_URL = `/process/describe/:${TEXT_PARAM}`;
|
198
src/taskpane/components/App.tsx
Normal file
|
@ -0,0 +1,198 @@
|
|||
import * as React from "react";
|
||||
import { DefaultButton } from "@fluentui/react";
|
||||
import Header from "./Header";
|
||||
import { FC, PropsWithChildren, useCallback, useEffect, useRef } from "react";
|
||||
import { ScoreType, useCreateProcess, useProcess, useText } from "../api/process";
|
||||
import { useSingleTimeout } from "../hooks/useSingleTimeout";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
/* global Word, require */
|
||||
|
||||
const processFunction = async (
|
||||
context: Word.RequestContext,
|
||||
search_text: string,
|
||||
comment_text: string,
|
||||
score: number
|
||||
) => {
|
||||
search_text.replace("\u0005", "");
|
||||
try {
|
||||
const range = context.document.body
|
||||
.search(search_text.slice(0, 255).split("\\").join(""), {
|
||||
ignorePunct: true,
|
||||
ignoreSpace: true,
|
||||
})
|
||||
.getFirstOrNullObject();
|
||||
|
||||
await context.sync();
|
||||
|
||||
if (!range.isNullObject) {
|
||||
range.insertComment(comment_text + "\n" + "Точность: " + score.toFixed(2));
|
||||
}
|
||||
} catch (e) {
|
||||
//
|
||||
}
|
||||
|
||||
// return context.document.body
|
||||
// .search(search_text.slice(0, 255).split("\\").join(""), {
|
||||
// ignorePunct: true,
|
||||
// ignoreSpace: true,
|
||||
// })
|
||||
// .getFirst()
|
||||
// .insertComment(comment_text + "\n" + "Точность: " + score.toFixed(2));
|
||||
};
|
||||
|
||||
const typeKey: ScoreType = "bert";
|
||||
|
||||
export const getEntriesFromDescription = (description: string = "") => {
|
||||
const matches = Array.from(description.matchAll(/<span[^>]+>(.*?)<\/span>/gi));
|
||||
|
||||
const array = matches
|
||||
.map((match) => {
|
||||
const entry = match[0];
|
||||
const text = match[1];
|
||||
const value = Number(Array.from(entry.matchAll(/data-value=\\?"?([.\d]+)\\?"?/gi))[0]?.[1]) || 0;
|
||||
|
||||
return {
|
||||
text,
|
||||
value,
|
||||
};
|
||||
})
|
||||
.filter((i) => i.value >= 0.01);
|
||||
|
||||
return [...Array.from(new Map(array.map((item) => [item["text"], item])).values())];
|
||||
};
|
||||
|
||||
export interface AppProps {
|
||||
title: string;
|
||||
isOfficeInitialized: boolean;
|
||||
}
|
||||
|
||||
export const PROCESS_POLLING_MS = 2000;
|
||||
|
||||
export const App: FC<PropsWithChildren<AppProps>> = () => {
|
||||
const {
|
||||
data: createProcessResponse,
|
||||
mutateAsync: createProcess,
|
||||
isLoading: createProcessLoading,
|
||||
} = useCreateProcess();
|
||||
const processId = createProcessResponse?.id;
|
||||
|
||||
const {
|
||||
data: process,
|
||||
isFetching: processFetching,
|
||||
refetch: refetchProcess,
|
||||
} = useProcess({
|
||||
processId: processId || "",
|
||||
config: {
|
||||
enabled: !!processId,
|
||||
},
|
||||
});
|
||||
|
||||
const timeout = useSingleTimeout();
|
||||
|
||||
useEffect(() => {
|
||||
if (processId) {
|
||||
const startPolling = () => {
|
||||
timeout.set(async () => {
|
||||
const { data: process } = await refetchProcess();
|
||||
if (process && process.current < process.total) {
|
||||
startPolling();
|
||||
}
|
||||
}, PROCESS_POLLING_MS);
|
||||
};
|
||||
|
||||
if (processId) {
|
||||
startPolling();
|
||||
}
|
||||
}
|
||||
}, [processId, refetchProcess, timeout]);
|
||||
|
||||
// const textId = process?.current === process?.total ? process?.texts[0].id : undefined;
|
||||
const textId = 3184;
|
||||
|
||||
const {
|
||||
data: textEntity,
|
||||
isFetching: textFetching,
|
||||
refetch: refetchText,
|
||||
} = useText({
|
||||
textId: textId || 0,
|
||||
type: typeKey,
|
||||
config: {
|
||||
enabled: !!textId,
|
||||
},
|
||||
});
|
||||
|
||||
const answer = textEntity?.score?.[typeKey]?.answer;
|
||||
const metric = textEntity?.score?.[typeKey]?.metric;
|
||||
const summary = textEntity?.summary;
|
||||
|
||||
const initRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!textEntity || initRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
initRef.current = true;
|
||||
|
||||
Word.run(async (context) => {
|
||||
const entries = getEntriesFromDescription((textEntity?.description?.[typeKey]?.text as string) || "");
|
||||
for (const entry of entries) {
|
||||
await processFunction(context, entry.text, "", entry.value);
|
||||
}
|
||||
});
|
||||
}, [textEntity]);
|
||||
|
||||
const isLoading =
|
||||
createProcessLoading ||
|
||||
!!processId ||
|
||||
processFetching ||
|
||||
!!(process && process.current < process.total) ||
|
||||
textFetching;
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
Word.run(function (context) {
|
||||
// Insert your code here. For example:
|
||||
const documentBody = context.document.body;
|
||||
context.load(documentBody);
|
||||
return context.sync().then(async () => {
|
||||
await refetchText();
|
||||
|
||||
// const text = documentBody.text;
|
||||
// await createProcess({
|
||||
// text,
|
||||
// });
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="ms-welcome">
|
||||
<Header message="Анализ текстовых пресс-релизов" />
|
||||
|
||||
<main className="ms-welcome__main">
|
||||
<p>
|
||||
Позволяет оценить кредитный рейтинг компании на основе пресс-релиза с выделением в тексте ключевых фраз с
|
||||
использованием различных методов.
|
||||
</p>
|
||||
<DefaultButton className="ms-welcome__action" iconProps={{ iconName: "ChevronRight" }} onClick={onClick}>
|
||||
Отправить
|
||||
</DefaultButton>
|
||||
|
||||
{isLoading && !textEntity && <p>Обработка...</p>}
|
||||
|
||||
{textEntity && (
|
||||
<>
|
||||
<h3>Результат оценки</h3>
|
||||
<p>
|
||||
Оценочный рейтинг: {answer} <br />
|
||||
{metric && `Точность: ${metric.toFixed(2)}`}
|
||||
</p>
|
||||
<h4>Краткое содержание</h4>
|
||||
<p>{summary}</p>
|
||||
</>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
17
src/taskpane/components/Header.tsx
Normal file
|
@ -0,0 +1,17 @@
|
|||
import * as React from "react";
|
||||
|
||||
export interface HeaderProps {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export default class Header extends React.Component<HeaderProps> {
|
||||
render() {
|
||||
const { message } = this.props;
|
||||
|
||||
return (
|
||||
<section className="ms-welcome__header ms-bgColor-neutralLighter ms-u-fadeIn500">
|
||||
<h1 className="ms-fontSize-su ms-fontWeight-light ms-fontColor-neutralPrimary">{message}</h1>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
32
src/taskpane/components/HeroList.tsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
import * as React from "react";
|
||||
|
||||
export interface HeroListItem {
|
||||
icon: string;
|
||||
primaryText: string;
|
||||
}
|
||||
|
||||
export interface HeroListProps {
|
||||
message: string;
|
||||
items: HeroListItem[];
|
||||
children: any;
|
||||
}
|
||||
|
||||
export default class HeroList extends React.Component<HeroListProps> {
|
||||
render() {
|
||||
const { children, items, message } = this.props;
|
||||
|
||||
const listItems = items.map((item, index) => (
|
||||
<li className="ms-ListItem" key={index}>
|
||||
<i className={`ms-Icon ms-Icon--${item.icon}`}></i>
|
||||
<span className="ms-font-m ms-fontColor-neutralPrimary">{item.primaryText}</span>
|
||||
</li>
|
||||
));
|
||||
return (
|
||||
<main className="ms-welcome__main">
|
||||
<h2 className="ms-font-xl ms-fontWeight-semilight ms-fontColor-neutralPrimary ms-u-slideUpIn20">{message}</h2>
|
||||
<ul className="ms-List ms-welcome__features ms-u-slideUpIn10">{listItems}</ul>
|
||||
{children}
|
||||
</main>
|
||||
);
|
||||
}
|
||||
}
|
22
src/taskpane/components/Progress.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import * as React from "react";
|
||||
import { Spinner, SpinnerSize } from "@fluentui/react";
|
||||
|
||||
export interface ProgressProps {
|
||||
logo: string;
|
||||
message: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export default class Progress extends React.Component<ProgressProps> {
|
||||
render() {
|
||||
const { logo, message, title } = this.props;
|
||||
|
||||
return (
|
||||
<section className="ms-welcome__progress ms-u-fadeIn500">
|
||||
<img width="90" height="90" src={logo} alt={title} title={title} />
|
||||
<h1 className="ms-fontSize-su ms-fontWeight-light ms-fontColor-neutralPrimary">{title}</h1>
|
||||
<Spinner size={SpinnerSize.large} label={message} />
|
||||
</section>
|
||||
);
|
||||
}
|
||||
}
|
8
src/taskpane/config.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
// export const BACKEND_URL = 'http://192.168.83.181:8000';
|
||||
// export const BACKEND_URL = 'http://192.168.22.4:8000';
|
||||
// export const BACKEND_URL = 'https://ed68-77-234-219-9.ngrok-free.app';
|
||||
// export const BACKEND_URL = 'https://16c2-77-234-219-9.ngrok-free.app';
|
||||
export const BACKEND_URL = "https://4810-176-59-122-187.ngrok-free.app";
|
||||
export const BACKEND_MEDIA_PORT = "8000";
|
||||
|
||||
export const API_URL = BACKEND_URL + "/api";
|
13
src/taskpane/hooks/useFactoryRef.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { useRef } from "react";
|
||||
|
||||
/**
|
||||
* Единожды вызывает функцию и сохраняет ее значение в реф
|
||||
* @param factory - функция, создающая значение рефа
|
||||
*/
|
||||
export function useFactoryRef<T>(factory: () => T): T {
|
||||
const ref = useRef<T | null>(null);
|
||||
if (!ref.current) {
|
||||
ref.current = factory();
|
||||
}
|
||||
return ref.current;
|
||||
}
|
6
src/taskpane/hooks/useSingleTimeout.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
import { SingleTimeoutManager } from "../utils/SingleTimeoutManager";
|
||||
import { useFactoryRef } from "./useFactoryRef";
|
||||
|
||||
export const useSingleTimeout = () => {
|
||||
return useFactoryRef(() => new SingleTimeoutManager());
|
||||
};
|
41
src/taskpane/index.tsx
Normal file
|
@ -0,0 +1,41 @@
|
|||
import { App } from "./components/App";
|
||||
import { AppContainer } from "react-hot-loader";
|
||||
import { initializeIcons } from "@fluentui/font-icons-mdl2";
|
||||
import { ThemeProvider } from "@fluentui/react";
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { ReactQueryProvider } from "./providers";
|
||||
|
||||
/* global document, Office, module, require */
|
||||
|
||||
initializeIcons();
|
||||
|
||||
let isOfficeInitialized = false;
|
||||
|
||||
const title = "Press-release analyzer";
|
||||
|
||||
const render = (Component) => {
|
||||
ReactDOM.render(
|
||||
<AppContainer>
|
||||
<ThemeProvider>
|
||||
<ReactQueryProvider>
|
||||
<Component title={title} isOfficeInitialized={isOfficeInitialized} />
|
||||
</ReactQueryProvider>
|
||||
</ThemeProvider>
|
||||
</AppContainer>,
|
||||
document.getElementById("container")
|
||||
);
|
||||
};
|
||||
|
||||
/* Render application after Office initializes */
|
||||
Office.onReady(() => {
|
||||
isOfficeInitialized = true;
|
||||
render(App);
|
||||
});
|
||||
|
||||
if ((module as any).hot) {
|
||||
(module as any).hot.accept("./components/App", () => {
|
||||
const NextApp = require("./components/App").default;
|
||||
render(NextApp);
|
||||
});
|
||||
}
|
10
src/taskpane/lib/axios.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import Axios from "axios";
|
||||
import { API_URL } from "../config";
|
||||
|
||||
export const axios = Axios.create({
|
||||
baseURL: API_URL,
|
||||
});
|
||||
|
||||
axios.interceptors.response.use((response) => {
|
||||
return response.data;
|
||||
});
|
38
src/taskpane/lib/react-query.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import {
|
||||
QueryClient,
|
||||
UseQueryOptions,
|
||||
UseMutationOptions,
|
||||
DefaultOptions,
|
||||
UseInfiniteQueryOptions,
|
||||
} from "@tanstack/react-query";
|
||||
import { AxiosError } from "axios";
|
||||
import { ExtractFnReturnType } from "../utils/types";
|
||||
|
||||
const queryConfig: DefaultOptions = {
|
||||
queries: {
|
||||
useErrorBoundary: false,
|
||||
refetchOnWindowFocus: false,
|
||||
retry: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const queryClient = new QueryClient({ defaultOptions: queryConfig });
|
||||
|
||||
export type QueryConfig<QueryFnType extends (...args: any) => any> = Omit<
|
||||
UseQueryOptions<ExtractFnReturnType<QueryFnType>>,
|
||||
"queryKey" | "queryFn"
|
||||
>;
|
||||
|
||||
export type InfiniteQueryConfig<QueryFnType extends (...args: any) => any> = Omit<
|
||||
UseInfiniteQueryOptions<ExtractFnReturnType<QueryFnType>>,
|
||||
"queryKey" | "queryFn"
|
||||
>;
|
||||
|
||||
export type MutationConfig<MutationFnType extends (...args: any) => any> = UseMutationOptions<
|
||||
ExtractFnReturnType<MutationFnType>,
|
||||
AxiosError,
|
||||
Parameters<MutationFnType>[0],
|
||||
any
|
||||
>;
|
||||
|
||||
export type { ExtractFnReturnType };
|
1
src/taskpane/providers/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './react-query';
|
9
src/taskpane/providers/react-query.tsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
import React from "react";
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ReactFCC } from "../utils/ReactFCC";
|
||||
import { queryClient } from "../lib/react-query";
|
||||
|
||||
export const ReactQueryProvider: ReactFCC = (props) => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
return <QueryClientProvider client={queryClient}>{props.children}</QueryClientProvider>;
|
||||
};
|
80
src/taskpane/taskpane.css
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
* See LICENSE in the project root for license information.
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ms-welcome__header {
|
||||
padding: 20px;
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ms-welcome__main {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
-webkit-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-flex-wrap: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
/*-webkit-align-items: center;*/
|
||||
/*align-items: center;*/
|
||||
-webkit-flex: 1 0 0;
|
||||
flex: 1 0 0;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
/* .ms-welcome__main > h2 {*/
|
||||
/* width: 100%;*/
|
||||
/* text-align: center;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features {*/
|
||||
/* list-style-type: none;*/
|
||||
/* margin-top: 20px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features.ms-List .ms-ListItem {*/
|
||||
/* padding-bottom: 20px;*/
|
||||
/* display: -webkit-flex;*/
|
||||
/* display: flex;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__features.ms-List .ms-ListItem > .ms-Icon {*/
|
||||
/* margin-right: 10px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/* .ms-welcome__action.ms-Button--hero {*/
|
||||
/* margin-top: 30px;*/
|
||||
/* }*/
|
||||
/* */
|
||||
/*.ms-Button.ms-Button--hero .ms-Button-label {*/
|
||||
/* color: #0078d7;*/
|
||||
/*}*/
|
||||
|
||||
/*.ms-Button.ms-Button--hero:hover .ms-Button-label,*/
|
||||
/*.ms-Button.ms-Button--hero:focus .ms-Button-label{*/
|
||||
/* color: #005a9e;*/
|
||||
/* cursor: pointer;*/
|
||||
/*}*/
|
||||
|
||||
/*b {*/
|
||||
/* font-weight: bold;*/
|
||||
/*}*/
|
27
src/taskpane/taskpane.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license. -->
|
||||
<!-- See LICENSE in the project root for license information -->
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" data-framework="typescript">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Press-release analyzer</title>
|
||||
|
||||
<!-- Office JavaScript API -->
|
||||
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>
|
||||
|
||||
<!-- For more information on Fluent UI, visit https://developer.microsoft.com/fluentui#/. -->
|
||||
<link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/11.0.0/css/fabric.min.css"/>
|
||||
|
||||
<!-- Template styles -->
|
||||
<link href="taskpane.css" rel="stylesheet" type="text/css" />
|
||||
</head>
|
||||
|
||||
<body class="ms-font-m ms-Fabric">
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
3
src/taskpane/utils/ReactFCC.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import React, { PropsWithChildren } from "react";
|
||||
|
||||
export type ReactFCC<T = unknown> = React.FC<PropsWithChildren<T>>;
|
26
src/taskpane/utils/SingleTimeoutManager.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
export class SingleTimeoutManager {
|
||||
timeout: NodeJS.Timeout | null = null;
|
||||
|
||||
public set(cb: null | (() => void), time?: number) {
|
||||
if (this.timeout) clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
this.timeout = null;
|
||||
cb && cb();
|
||||
}, time);
|
||||
}
|
||||
|
||||
public setDelay(time: number) {
|
||||
return this.set(null, time);
|
||||
}
|
||||
|
||||
public clear() {
|
||||
if (this.timeout) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
public active() {
|
||||
return this.timeout;
|
||||
}
|
||||
}
|
45
src/taskpane/utils/types.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import React, { JSX } from "react";
|
||||
import { PromiseValue } from "type-fest";
|
||||
|
||||
export type Optional<T> = T | null | undefined;
|
||||
|
||||
export type Extends<Self extends object, Base extends object> = Omit<Base, keyof Self> & Self;
|
||||
|
||||
export type IntrinsicPropsWithoutRef<E extends keyof JSX.IntrinsicElements> = React.PropsWithoutRef<
|
||||
JSX.IntrinsicElements[E]
|
||||
>;
|
||||
|
||||
export type ExtractArray<T> = T extends (infer U)[] ? U : T;
|
||||
|
||||
export type AnchorPropsWithoutRef = IntrinsicPropsWithoutRef<"a">;
|
||||
export type DivPropsWithoutRef = IntrinsicPropsWithoutRef<"div">;
|
||||
export type PPropsWithoutRef = IntrinsicPropsWithoutRef<"p">;
|
||||
export type FooterPropsWithoutRef = IntrinsicPropsWithoutRef<"footer">;
|
||||
export type ImgPropsWithoutRef = IntrinsicPropsWithoutRef<"img">;
|
||||
export type ButtonPropsWithoutRef = IntrinsicPropsWithoutRef<"button">;
|
||||
export type InputPropsWithoutRef = IntrinsicPropsWithoutRef<"input">;
|
||||
export type SelectPropsWithoutRef = IntrinsicPropsWithoutRef<"select">;
|
||||
export type UListPropsWithoutRef = IntrinsicPropsWithoutRef<"ul">;
|
||||
export type LiPropsWithoutRef = IntrinsicPropsWithoutRef<"li">;
|
||||
export type SvgPropsWithoutRef = IntrinsicPropsWithoutRef<"svg">;
|
||||
|
||||
export type PolyExtends<ComponentType extends React.ElementType, Self extends object, Base extends object> = {
|
||||
/**
|
||||
* Базовый компонент
|
||||
*
|
||||
* @type React.ElementType
|
||||
*/
|
||||
component?: ComponentType;
|
||||
} & Extends<Self, Base>;
|
||||
|
||||
export type AnyObject = {
|
||||
[key: number]: any;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export type ExtractFnReturnType<FnType extends (...args: any) => any> = PromiseValue<ReturnType<FnType>>;
|
||||
|
||||
export type Pagination = {
|
||||
offset?: number;
|
||||
limit?: number;
|
||||
};
|
33
tsconfig.json
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"allowUnusedLabels": false,
|
||||
"emitDecoratorMetadata": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"jsx": "react",
|
||||
"module": "CommonJS",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "dist",
|
||||
"removeComments": false,
|
||||
"sourceMap": true,
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"es7",
|
||||
"dom"
|
||||
],
|
||||
"pretty": true,
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
]
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"compileOnSave": false,
|
||||
"buildOnSave": false,
|
||||
"ts-node": {
|
||||
"files": true
|
||||
}
|
||||
}
|
111
webpack.config.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/* eslint-disable no-undef */
|
||||
|
||||
const devCerts = require("office-addin-dev-certs");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const webpack = require("webpack");
|
||||
|
||||
const urlDev = "https://localhost:3000/";
|
||||
const urlProd = "https://www.contoso.com/"; // CHANGE THIS TO YOUR PRODUCTION DEPLOYMENT LOCATION
|
||||
|
||||
async function getHttpsOptions() {
|
||||
const httpsOptions = await devCerts.getHttpsServerOptions();
|
||||
return { ca: httpsOptions.ca, key: httpsOptions.key, cert: httpsOptions.cert };
|
||||
}
|
||||
|
||||
module.exports = async (env, options) => {
|
||||
const dev = options.mode === "development";
|
||||
const config = {
|
||||
devtool: "source-map",
|
||||
entry: {
|
||||
polyfill: ["core-js/stable", "regenerator-runtime/runtime"],
|
||||
vendor: ["react", "react-dom", "core-js", "@fluentui/react"],
|
||||
taskpane: ["react-hot-loader/patch", "./src/taskpane/index.tsx", "./src/taskpane/taskpane.html"],
|
||||
commands: "./src/commands/commands.ts",
|
||||
},
|
||||
output: {
|
||||
clean: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".ts", ".tsx", ".html", ".js"],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: "babel-loader",
|
||||
options: {
|
||||
presets: ["@babel/preset-typescript"],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: ["react-hot-loader/webpack", "ts-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
exclude: /node_modules/,
|
||||
use: "html-loader",
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|jpeg|gif|ico)$/,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
filename: "assets/[name][ext][query]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: "assets/*",
|
||||
to: "assets/[name][ext][query]",
|
||||
},
|
||||
{
|
||||
from: "manifest*.xml",
|
||||
to: "[name]" + "[ext]",
|
||||
transform(content) {
|
||||
if (dev) {
|
||||
return content;
|
||||
} else {
|
||||
return content.toString().replace(new RegExp(urlDev, "g"), urlProd);
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "taskpane.html",
|
||||
template: "./src/taskpane/taskpane.html",
|
||||
chunks: ["taskpane", "vendor", "polyfills"],
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "commands.html",
|
||||
template: "./src/commands/commands.html",
|
||||
chunks: ["commands"],
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
Promise: ["es6-promise", "Promise"],
|
||||
}),
|
||||
],
|
||||
devServer: {
|
||||
hot: true,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
server: {
|
||||
type: "https",
|
||||
options: env.WEBPACK_BUILD || options.https !== undefined ? options.https : await getHttpsOptions(),
|
||||
},
|
||||
port: process.env.npm_package_config_dev_server_port || 3000,
|
||||
},
|
||||
};
|
||||
|
||||
return config;
|
||||
};
|