phase 0
This commit is contained in:
commit
41573b3c4f
54 changed files with 32839 additions and 0 deletions
8
addin/.eslintrc.json
Normal file
8
addin/.eslintrc.json
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"plugins": [
|
||||
"office-addins"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:office-addins/react"
|
||||
]
|
||||
}
|
||||
8
addin/.hintrc
Normal file
8
addin/.hintrc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": [
|
||||
"development"
|
||||
],
|
||||
"hints": {
|
||||
"typescript-config/strict": "off"
|
||||
}
|
||||
}
|
||||
14
addin/.vscode/extensions.json
vendored
Normal file
14
addin/.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",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"msoffice.microsoft-office-add-in-debugger"
|
||||
],
|
||||
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
|
||||
"unwantedRecommendations": []
|
||||
}
|
||||
26
addin/.vscode/launch.json
vendored
Normal file
26
addin/.vscode/launch.json
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"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
addin/.vscode/settings.json
vendored
Normal file
8
addin/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript"
|
||||
]
|
||||
}
|
||||
|
||||
160
addin/.vscode/tasks.json
vendored
Normal file
160
addin/.vscode/tasks.json
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
{
|
||||
"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": "shell",
|
||||
"command": "npm",
|
||||
"args": [
|
||||
"run",
|
||||
"start",
|
||||
"--",
|
||||
"desktop",
|
||||
"--app",
|
||||
"excel"
|
||||
],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: Outlook Desktop",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": [
|
||||
"run",
|
||||
"start",
|
||||
"--",
|
||||
"desktop",
|
||||
"--app",
|
||||
"outlook"
|
||||
],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: PowerPoint Desktop",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": [
|
||||
"run",
|
||||
"start",
|
||||
"--",
|
||||
"desktop",
|
||||
"--app",
|
||||
"powerpoint"
|
||||
],
|
||||
"presentation": {
|
||||
"clear": true,
|
||||
"panel": "dedicated"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Debug: Word Desktop",
|
||||
"type": "shell",
|
||||
"command": "npm",
|
||||
"args": [
|
||||
"run",
|
||||
"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
addin/assets/icon-128.png
Normal file
BIN
addin/assets/icon-128.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
BIN
addin/assets/icon-16.png
Normal file
BIN
addin/assets/icon-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
addin/assets/icon-32.png
Normal file
BIN
addin/assets/icon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
BIN
addin/assets/icon-64.png
Normal file
BIN
addin/assets/icon-64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
addin/assets/icon-80.png
Normal file
BIN
addin/assets/icon-80.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
addin/assets/logo-filled.png
Normal file
BIN
addin/assets/logo-filled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
13
addin/babel.config.json
Normal file
13
addin/babel.config.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"esmodules": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"@babel/preset-typescript"
|
||||
]
|
||||
}
|
||||
143
addin/manifest.json
Normal file
143
addin/manifest.json
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.schema.json",
|
||||
"id": "f2b103f1-1ab1-4e1b-8f0b-072aa3d4e19d",
|
||||
"manifestVersion": "1.17",
|
||||
"version": "1.0.0",
|
||||
"name": {
|
||||
"short": "Contoso Task Pane Add-in",
|
||||
"full": "Contoso Task Pane Add-in"
|
||||
},
|
||||
"description": {
|
||||
"short": "A template to get started.",
|
||||
"full": "This is the template to get started."
|
||||
},
|
||||
"developer": {
|
||||
"name": "Contoso",
|
||||
"websiteUrl": "https://www.contoso.com",
|
||||
"privacyUrl": "https://www.contoso.com/privacy",
|
||||
"termsOfUseUrl": "https://www.contoso.com/servicesagreement"
|
||||
},
|
||||
"icons": {
|
||||
"outline": "assets/outline.png",
|
||||
"color": "assets/color.png"
|
||||
},
|
||||
"accentColor": "#230201",
|
||||
"localizationInfo": {
|
||||
"defaultLanguageTag": "en-us",
|
||||
"additionalLanguages": []
|
||||
},
|
||||
"authorization": {
|
||||
"permissions": {
|
||||
"resourceSpecific": [
|
||||
{
|
||||
"name": "Mailbox.ReadWrite.User",
|
||||
"type": "Delegated"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"validDomains": ["contoso.com"],
|
||||
"extensions": [
|
||||
{
|
||||
"requirements": {
|
||||
"scopes": ["mail"],
|
||||
"capabilities": [
|
||||
{ "name": "Mailbox", "minVersion": "1.3" }
|
||||
]
|
||||
},
|
||||
"runtimes": [
|
||||
{
|
||||
"requirements": {
|
||||
"capabilities": [
|
||||
{ "name": "Mailbox", "minVersion": "1.3" }
|
||||
]
|
||||
},
|
||||
"id": "TaskPaneRuntime",
|
||||
"type": "general",
|
||||
"code": {
|
||||
"page": "https://localhost:3000/taskpane.html"
|
||||
},
|
||||
"lifetime": "short",
|
||||
"actions": [
|
||||
{
|
||||
"id": "TaskPaneRuntimeShow",
|
||||
"type":"openPage",
|
||||
"pinnable": false,
|
||||
"view": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "CommandsRuntime",
|
||||
"type": "general",
|
||||
"code": {
|
||||
"page": "https://localhost:3000/commands.html",
|
||||
"script": "https://localhost:3000/commands.js"
|
||||
},
|
||||
"lifetime": "short",
|
||||
"actions": [
|
||||
{
|
||||
"id": "action",
|
||||
"type": "executeFunction"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ribbons": [
|
||||
{
|
||||
"contexts": [
|
||||
"mailCompose"
|
||||
],
|
||||
"tabs": [
|
||||
{
|
||||
"builtInTabId": "TabDefault",
|
||||
"groups": [
|
||||
{
|
||||
"id": "msgComposeGroup",
|
||||
"label": "Contoso Add-in",
|
||||
"icons": [
|
||||
{ "size": 16, "url": "https://localhost:3000/assets/icon-16.png" },
|
||||
{ "size": 32, "url": "https://localhost:3000/assets/icon-32.png" },
|
||||
{ "size": 80, "url": "https://localhost:3000/assets/icon-80.png" }
|
||||
],
|
||||
"controls": [
|
||||
{
|
||||
"id": "msgComposeOpenPaneButton",
|
||||
"type": "button",
|
||||
"label": "Show Task Pane",
|
||||
"icons": [
|
||||
{ "size": 16, "url": "https://localhost:3000/assets/icon-16.png" },
|
||||
{ "size": 32, "url": "https://localhost:3000/assets/icon-32.png" },
|
||||
{ "size": 80, "url": "https://localhost:3000/assets/icon-80.png" }
|
||||
],
|
||||
"supertip": {
|
||||
"title": "Show Task Pane",
|
||||
"description": "Opens a task pane."
|
||||
},
|
||||
"actionId": "TaskPaneRuntimeShow"
|
||||
},
|
||||
{
|
||||
"id": "ActionButton",
|
||||
"type": "button",
|
||||
"label": "Perform an action",
|
||||
"icons": [
|
||||
{ "size": 16, "url": "https://localhost:3000/assets/icon-16.png" },
|
||||
{ "size": 32, "url": "https://localhost:3000/assets/icon-32.png" },
|
||||
{ "size": 80, "url": "https://localhost:3000/assets/icon-80.png" }
|
||||
],
|
||||
"supertip": {
|
||||
"title": "Perform an action",
|
||||
"description": "Perform an action when clicked."
|
||||
},
|
||||
"actionId": "action"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
85
addin/manifest.xml
Normal file
85
addin/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>4a1e184a-ab31-4fa4-b3c7-9a2283051c3f</Id>
|
||||
<Version>1.0.0.0</Version>
|
||||
<ProviderName>Contoso</ProviderName>
|
||||
<DefaultLocale>en-US</DefaultLocale>
|
||||
<DisplayName DefaultValue="addin"/>
|
||||
<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 Task Pane"/>
|
||||
</bt:ShortStrings>
|
||||
<bt:LongStrings>
|
||||
<bt:String id="GetStarted.Description" DefaultValue="Your sample add-in loaded successfully. Go to the HOME tab and click the 'Show Task Pane' button to get started."/>
|
||||
<bt:String id="TaskpaneButton.Tooltip" DefaultValue="Click to Show a Task Pane"/>
|
||||
</bt:LongStrings>
|
||||
</Resources>
|
||||
</VersionOverrides>
|
||||
</OfficeApp>
|
||||
19178
addin/package-lock.json
generated
Normal file
19178
addin/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
76
addin/package.json
Normal file
76
addin/package.json
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"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",
|
||||
"signin": "office-addin-dev-settings m365-account login",
|
||||
"signout": "office-addin-dev-settings m365-account logout",
|
||||
"start": "office-addin-debugging start manifest.xml",
|
||||
"stop": "office-addin-debugging stop manifest.xml",
|
||||
"validate": "office-addin-manifest validate manifest.xml",
|
||||
"watch": "webpack --mode development --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fluentui/react-components": "^9.55.1",
|
||||
"@fluentui/react-icons": "^2.0.264",
|
||||
"core-js": "^3.36.0",
|
||||
"es6-promise": "^4.2.8",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"regenerator-runtime": "^0.14.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^8.0.1",
|
||||
"@babel/preset-env": "^8.0.2",
|
||||
"@babel/preset-typescript": "^8.0.1",
|
||||
"@types/office-js": "^1.0.377",
|
||||
"@types/office-runtime": "^1.0.35",
|
||||
"@types/react": "^18.2.64",
|
||||
"@types/react-dom": "^18.2.21",
|
||||
"@types/webpack": "^5.28.5",
|
||||
"acorn": "^8.11.3",
|
||||
"babel-loader": "^10.1.1",
|
||||
"copy-webpack-plugin": "^14.0.0",
|
||||
"eslint-plugin-office-addins": "^4.0.10",
|
||||
"eslint-plugin-react": "^7.28.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-loader": "^5.0.0",
|
||||
"html-webpack-plugin": "^5.6.0",
|
||||
"less": "^4.2.0",
|
||||
"less-loader": "^12.2.0",
|
||||
"office-addin-cli": "^2.0.10",
|
||||
"office-addin-debugging": "^6.1.2",
|
||||
"office-addin-dev-certs": "^2.0.10",
|
||||
"office-addin-lint": "^3.0.10",
|
||||
"office-addin-manifest": "^2.1.6",
|
||||
"office-addin-prettier-config": "^2.0.5",
|
||||
"os-browserify": "^0.3.0",
|
||||
"process": "^0.11.10",
|
||||
"source-map-loader": "^5.0.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"typescript": "^5.4.2",
|
||||
"webpack": "^5.105.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^6.0.0"
|
||||
},
|
||||
"prettier": "office-addin-prettier-config",
|
||||
"browserslist": [
|
||||
"last 2 versions",
|
||||
"ie 11"
|
||||
]
|
||||
}
|
||||
19
addin/src/commands/commands.html
Normal file
19
addin/src/commands/commands.html
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
@@ -1,18 +0,0 @@
|
||||
<!-- 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/hosted/office.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
35
addin/src/commands/commands.ts
Normal file
35
addin/src/commands/commands.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
||||
* See LICENSE in the project root for license information.
|
||||
*/
|
||||
|
||||
/* global Office */
|
||||
|
||||
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(
|
||||
"ActionPerformanceNotification",
|
||||
message
|
||||
);
|
||||
|
||||
// Be sure to indicate when the add-in command function is complete.
|
||||
event.completed();
|
||||
}
|
||||
|
||||
// Register the function with Office.
|
||||
Office.actions.associate("action", action);
|
||||
47
addin/src/taskpane/components/App.tsx
Normal file
47
addin/src/taskpane/components/App.tsx
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import * as React from "react";
|
||||
import Header from "./Header";
|
||||
import HeroList, { HeroListItem } from "./HeroList";
|
||||
import TextInsertion from "./TextInsertion";
|
||||
import { makeStyles } from "@fluentui/react-components";
|
||||
import { Ribbon24Regular, LockOpen24Regular, DesignIdeas24Regular } from "@fluentui/react-icons";
|
||||
import { insertText } from "../taskpane";
|
||||
|
||||
interface AppProps {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
minHeight: "100vh",
|
||||
},
|
||||
});
|
||||
|
||||
const App: React.FC<AppProps> = (props: AppProps) => {
|
||||
const styles = useStyles();
|
||||
// The list items are static and won't change at runtime,
|
||||
// so this should be an ordinary const, not a part of state.
|
||||
const listItems: HeroListItem[] = [
|
||||
{
|
||||
icon: <Ribbon24Regular />,
|
||||
primaryText: "Achieve more with Office integration",
|
||||
},
|
||||
{
|
||||
icon: <LockOpen24Regular />,
|
||||
primaryText: "Unlock features and functionality",
|
||||
},
|
||||
{
|
||||
icon: <DesignIdeas24Regular />,
|
||||
primaryText: "Create and visualize like a pro",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<Header logo="assets/logo-filled.png" title={props.title} message="Welcome" />
|
||||
<HeroList message="Discover what this add-in can do for you today!" items={listItems} />
|
||||
<TextInsertion insertText={insertText} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
38
addin/src/taskpane/components/Header.tsx
Normal file
38
addin/src/taskpane/components/Header.tsx
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import * as React from "react";
|
||||
import { Image, tokens, makeStyles } from "@fluentui/react-components";
|
||||
|
||||
export interface HeaderProps {
|
||||
title: string;
|
||||
logo: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
welcome__header: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
paddingBottom: "30px",
|
||||
paddingTop: "100px",
|
||||
backgroundColor: tokens.colorNeutralBackground3,
|
||||
},
|
||||
message: {
|
||||
fontSize: tokens.fontSizeHero900,
|
||||
fontWeight: tokens.fontWeightRegular,
|
||||
fontColor: tokens.colorNeutralBackgroundStatic,
|
||||
},
|
||||
});
|
||||
|
||||
const Header: React.FC<HeaderProps> = (props: HeaderProps) => {
|
||||
const { title, logo, message } = props;
|
||||
const styles = useStyles();
|
||||
|
||||
return (
|
||||
<section className={styles.welcome__header}>
|
||||
<Image width="90" height="90" src={logo} alt={title} />
|
||||
<h1 className={styles.message}>{message}</h1>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
62
addin/src/taskpane/components/HeroList.tsx
Normal file
62
addin/src/taskpane/components/HeroList.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import * as React from "react";
|
||||
import { tokens, makeStyles } from "@fluentui/react-components";
|
||||
|
||||
export interface HeroListItem {
|
||||
icon: React.JSX.Element;
|
||||
primaryText: string;
|
||||
}
|
||||
|
||||
export interface HeroListProps {
|
||||
message: string;
|
||||
items: HeroListItem[];
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
list: {
|
||||
marginTop: "20px",
|
||||
},
|
||||
listItem: {
|
||||
paddingBottom: "20px",
|
||||
display: "flex",
|
||||
},
|
||||
icon: {
|
||||
marginRight: "10px",
|
||||
},
|
||||
itemText: {
|
||||
fontSize: tokens.fontSizeBase300,
|
||||
fontColor: tokens.colorNeutralBackgroundStatic,
|
||||
},
|
||||
welcome__main: {
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
},
|
||||
message: {
|
||||
fontSize: tokens.fontSizeBase500,
|
||||
fontColor: tokens.colorNeutralBackgroundStatic,
|
||||
fontWeight: tokens.fontWeightRegular,
|
||||
paddingLeft: "10px",
|
||||
paddingRight: "10px",
|
||||
},
|
||||
});
|
||||
|
||||
const HeroList: React.FC<HeroListProps> = (props: HeroListProps) => {
|
||||
const { items, message } = props;
|
||||
const styles = useStyles();
|
||||
|
||||
const listItems = items.map((item, index) => (
|
||||
<li className={styles.listItem} key={index}>
|
||||
<i className={styles.icon}>{item.icon}</i>
|
||||
<span className={styles.itemText}>{item.primaryText}</span>
|
||||
</li>
|
||||
));
|
||||
return (
|
||||
<div className={styles.welcome__main}>
|
||||
<h2 className={styles.message}>{message}</h2>
|
||||
<ul className={styles.list}>{listItems}</ul>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeroList;
|
||||
57
addin/src/taskpane/components/TextInsertion.tsx
Normal file
57
addin/src/taskpane/components/TextInsertion.tsx
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import * as React from "react";
|
||||
import { useState } from "react";
|
||||
import { Button, Field, Textarea, tokens, makeStyles } from "@fluentui/react-components";
|
||||
|
||||
/* global HTMLTextAreaElement */
|
||||
|
||||
interface TextInsertionProps {
|
||||
insertText: (text: string) => void;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles({
|
||||
instructions: {
|
||||
fontWeight: tokens.fontWeightSemibold,
|
||||
marginTop: "20px",
|
||||
marginBottom: "10px",
|
||||
},
|
||||
textPromptAndInsertion: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
},
|
||||
textAreaField: {
|
||||
marginLeft: "20px",
|
||||
marginTop: "30px",
|
||||
marginBottom: "20px",
|
||||
marginRight: "20px",
|
||||
maxWidth: "50%",
|
||||
},
|
||||
});
|
||||
|
||||
const TextInsertion: React.FC<TextInsertionProps> = (props: TextInsertionProps) => {
|
||||
const [text, setText] = useState<string>("Some text.");
|
||||
|
||||
const handleTextInsertion = async () => {
|
||||
await props.insertText(text);
|
||||
};
|
||||
|
||||
const handleTextChange = async (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
setText(event.target.value);
|
||||
};
|
||||
|
||||
const styles = useStyles();
|
||||
|
||||
return (
|
||||
<div className={styles.textPromptAndInsertion}>
|
||||
<Field className={styles.textAreaField} size="large" label="Enter text to be inserted into the document.">
|
||||
<Textarea size="large" value={text} onChange={handleTextChange} />
|
||||
</Field>
|
||||
<Field className={styles.instructions}>Click the button to insert text.</Field>
|
||||
<Button appearance="primary" disabled={false} size="large" onClick={handleTextInsertion}>
|
||||
Insert text
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextInsertion;
|
||||
27
addin/src/taskpane/index.tsx
Normal file
27
addin/src/taskpane/index.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import * as React from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import App from "./components/App";
|
||||
import { FluentProvider, webLightTheme } from "@fluentui/react-components";
|
||||
|
||||
/* global document, Office, module, require, HTMLElement */
|
||||
|
||||
const title = "Contoso Task Pane Add-in";
|
||||
|
||||
const rootElement: HTMLElement | null = document.getElementById("container");
|
||||
const root = rootElement ? createRoot(rootElement) : undefined;
|
||||
|
||||
/* Render application after Office initializes */
|
||||
Office.onReady(() => {
|
||||
root?.render(
|
||||
<FluentProvider theme={webLightTheme}>
|
||||
<App title={title} />
|
||||
</FluentProvider>
|
||||
);
|
||||
});
|
||||
|
||||
if ((module as any).hot) {
|
||||
(module as any).hot.accept("./components/App", () => {
|
||||
const NextApp = require("./components/App").default;
|
||||
root?.render(NextApp);
|
||||
});
|
||||
}
|
||||
21
addin/src/taskpane/taskpane.html
Normal file
21
addin/src/taskpane/taskpane.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<!-- 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>Contoso Task Pane Add-in</title>
|
||||
|
||||
<!-- Office JavaScript API -->
|
||||
<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>
|
||||
</head>
|
||||
|
||||
<body style="width: 100%; height: 100%; margin: 0; padding: 0;">
|
||||
<div id="container"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
14
addin/src/taskpane/taskpane.ts
Normal file
14
addin/src/taskpane/taskpane.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* global Word console */
|
||||
|
||||
export async function insertText(text: string) {
|
||||
// Write text to the document.
|
||||
try {
|
||||
await Word.run(async (context) => {
|
||||
let body = context.document.body;
|
||||
body.insertParagraph(text, Word.InsertLocation.end);
|
||||
await context.sync();
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("Error: " + error);
|
||||
}
|
||||
}
|
||||
29
addin/tsconfig.json
Normal file
29
addin/tsconfig.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true,
|
||||
"esModuleInterop": true,
|
||||
"experimentalDecorators": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"jsx": "react",
|
||||
"module": "ES2020",
|
||||
"moduleResolution": "bundler",
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedParameters": true,
|
||||
"outDir": "dist",
|
||||
"sourceMap": true,
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"es7",
|
||||
"dom"
|
||||
],
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
],
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
},
|
||||
"files": true
|
||||
}
|
||||
}
|
||||
111
addin/webpack.config.js
Normal file
111
addin/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"],
|
||||
react: ["react", "react-dom"],
|
||||
taskpane: {
|
||||
import: ["./src/taskpane/index.tsx", "./src/taskpane/taskpane.html"],
|
||||
dependOn: "react",
|
||||
},
|
||||
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",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
exclude: /node_modules/,
|
||||
use: ["ts-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.html$/,
|
||||
exclude: /node_modules/,
|
||||
use: "html-loader",
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|jpeg|ttf|woff|woff2|gif|ico)$/,
|
||||
type: "asset/resource",
|
||||
generator: {
|
||||
filename: "assets/[name][ext][query]",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
filename: "taskpane.html",
|
||||
template: "./src/taskpane/taskpane.html",
|
||||
chunks: ["polyfill", "taskpane", "react"],
|
||||
}),
|
||||
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: "commands.html",
|
||||
template: "./src/commands/commands.html",
|
||||
chunks: ["polyfill", "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;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue