Skip to content

Commit

Permalink
Tutorial (#18)
Browse files Browse the repository at this point in the history
- Add Tutorial
- Move some docs around.
- Add some ideas.
- Add test for local in production manifests.
  • Loading branch information
wandyezj authored Apr 8, 2024
1 parent 4d642a0 commit b0ae8c2
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .vscode/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"minifier",
"prettierrc",
"Sideload",
"Sideloading"
"Sideloading",
"taskpane"
],
// flagWords - list of words to be always considered incorrect
// This is useful for offensive words and common spelling errors.
Expand Down
12 changes: 11 additions & 1 deletion config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ const CopyWebpackPlugin = require("copy-webpack-plugin");
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
//const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const { Marked } = require("marked");


// Options

/**
* In Dev mode, when starting, open the edit, run, and blocks in the browser
*/
const optionDevOpenBrowserTabs = true;


const marked = new Marked();
marked.use({
gfm: true,
Expand Down Expand Up @@ -137,7 +147,7 @@ module.exports = async (env, options) => {
if (options.mode === "development") {
config.devServer = {
...config.devServer,
open: [], //["/edit.html", "/run.html", "/blocks.html"],
open: optionDevOpenBrowserTabs ? ["/edit.html", "/run.html", "/blocks.html"] : [],
port: 3000,
server: {
type: "https",
Expand Down
18 changes: 5 additions & 13 deletions docs/about.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
# About

- [Tutorial](./tutorial.md)

## Internal Docs

- [Principles](./setup.md)
- [Setup](./setup.md)
- [Tech Stack](./tech-stack.md)
- [Architecture](./architecture.md)
- [Dependencies](./dependencies.md)
- [GitHub Pages Setup](./pages-environment.md)

## Principles

- [Open Source](https://en.wikipedia.org/wiki/Open_source)
- [Public Domain](https://en.wikipedia.org/wiki/Public_domain)
- [Free Software](https://www.gnu.org/philosophy/free-sw.en.html)
- Cross Platform
- Runs in any up to date chromium browser.
- Downloadable as a single file that can be run offline.
- Secure
- Minimal dependencies to minimize attack surface and chance of supply chain attacks.
- Private
- No telemetry is sent from page code.
- No external data is loaded.
- No back end servers.
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Each snip has:
- ts
- the code that is run

### Libraries
### References

http links

Expand Down
59 changes: 59 additions & 0 deletions docs/ideas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Ideas

A collection of ideas that might improve the Build Add-In experience.


## Random

- Github Issues Tab
- Clear set of labels for issues with description of what they mean and how they should be used.
- Interact with customers often.
- Clear issue labels
- Minimize labels to less than twenty too hard to keep track of otherwise.
- key component names (run, edit, compile, monaco, blocks)
- question - someone has a question, ideally it should be answered in documentation.
- suggestion- someone has a suggestion for something
- wont-fix
- P0, P1, P2
- by-design
- duplicate
- stale / old - not looking at this because too old and not relevant
- Be clear on intended use and what scenarios are supported
- Refer to these scenarios when people ask for things outside of those scenarios.
- Clear local development documentation
- Have a set of pre canned responses
- Philosophy of do it well or don't do it.
- What is the difference between closing issues as not planned and closing them? When should you use either option?
- Is it possible to have the monaco shortcuts mirror vs code?
- Have an updates tab that displays a changelog of what has recently changed.
- Explanation of libraries tab
- Explain that it only loads js, css, and types files as is.
- We do not do any complex logic like trying to load a npm package. If you want to do that build a full website with a build system.
- Allow office.js and Office.d.ts to load from the localhost when there isn't internet.

- copy manifests to standard C:\share for testing on native, and prefix with the add-in name.

- Can I allow custom buttons to active specific snips?

- arbitrary snip import from URLs - show message if not successful
- export as publish zip with:
- html file with {html, css, js} embedded or simply as separate files?
- manifest.xml
- default icon
- snip.json
- readme with instructions of how to publish on GitHub, clone simple repository put all files in, create site etc.., replace url in manifest etc, upload to store


- Make sure to validate any imported data. - Should probably be extended to anything in indexedDB as well. Assume any data where ever it's from is evil.

- Enable embedding snips in documents, possibly by adding custom xml tags and searching for them.
- double check any library urls
- provide firm guidance on what each piece does with an info box

- hotkeys - allow creation of a limited number of custom hotkeys. Only allow JS to execute. Requires shared runtime?


Tests

- What happens with snips with really long names?
- Capture tab key in monaco editor instead of moving around to buttons
14 changes: 14 additions & 0 deletions docs/principles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Principles

- [Open Source](https://en.wikipedia.org/wiki/Open_source)
- [Public Domain](https://en.wikipedia.org/wiki/Public_domain)
- [Free Software](https://www.gnu.org/philosophy/free-sw.en.html)
- Cross Platform
- Runs in any up to date chromium browser.
- Downloadable as a single file that can be run offline.
- Secure
- Minimal dependencies to minimize attack surface and chance of supply chain attacks.
- Private
- No telemetry is sent from page code.
- No external data is loaded.
- No back end servers.
49 changes: 39 additions & 10 deletions docs/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@

## Phase - Multiple Files

- [ ] multiple local snip
- [X] multiple local snip
- [X] storage scheme
- [X] storage system
- [indexedDB basic pattern](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB#basic_pattern)
- [X] multi snip display and selection
- [X] Style the snips to display (display name, in order of last modified.)
- [Card](https://react.fluentui.dev/?path=/docs/components-card-card--default)
- [ ] Second page for samples [Multi-Level Drawer](https://react.fluentui.dev/?path=/docs/components-drawer--default#multiple-levels)
- [ ] More graceful delete and new. After delete open library to selecting new snip to open.
- [ ] remove ... from card or have dropdown to delete / pin

## Phase - Publish

Expand All @@ -34,7 +31,7 @@
- [X] Manifest - Cross Application
- [X] Manifest - Ribbon Tab - (Extension)
- [ ] Store Publish
- [ ] Catchy Name (Build?)
- [X] Catchy Name = `Build` Add-In
- [AppSource publishing](https://learn.microsoft.com/en-us/partner-center/marketplace/submit-to-appsource-via-partner-center)
- [Offer Overview](https://partner.microsoft.com/en-us/dashboard/marketplace-offers/overview)
- [X] Description Short
Expand All @@ -54,27 +51,42 @@

## Phase - Important

- [ ] Warn before delete
- [ ] Confirmation dialog before delete
- [ ] display compile errors
- typescript pre emit diagnostics require program construction

## Phase - Fix
## Phase - Multiple Files - Advanced

- [ ] Copy to clipboard functionality is broken. It looks like the permissions were recently removed from the iframe policy? `<iframe src="index.html" allow="clipboard-read; clipboard-write"></iframe>`
- [X] Workaround - use the command API
In the Local Snips drawer.

- [ ] Select Multiple
- [ ] Allow download of select snips to a snips.json file.
- [ ] Allow import of select snips from a snip.json file.
- [ ] Allow delete of select Local Snips
- [ ] More graceful delete and new.
- After delete open Local Snips drawer to selecting new snip to open.
- [ ] Allow pin of snips to the top of the Local Snips drawer.

## Phase - UI Polish

- [ ] Spinner when loading - [Spinner](https://fluent2.microsoft.design/components/web/react/spinner/usage)
- [X] Resizable Editor that adjusts to screen size
- [ ] Find a better way to do this. The current way works but is not ideal. using 100vh on the container CSS and 90vh on the editor CSS.

## Phase - Samples

- [ ] Second page for samples [Multi-Level Drawer](https://react.fluentui.dev/?path=/docs/components-drawer--default#multiple-levels)

## Phase - test

- [ ] always an open snip
- [ ] always something to run

## Phase - Long Term Fix

- [ ] Copy to clipboard functionality is broken. It looks like the permissions were recently removed from the iframe policy? `<iframe src="index.html" allow="clipboard-read; clipboard-write"></iframe>`
- [X] Workaround - use the command API

## Phase - Nice

- [ ] global log function to ease debugging and silencing
Expand All @@ -99,13 +111,30 @@
- [X] dependencies.md
- why each dependency
- how is each dependency used
- [X] vocabulary.md
- names and definition for every item
- [ ] deployment infrastructure


## Phase - Accessibility

## Phase - Localize

i18n

- [ ] localize dates and times [MDN Intl API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
- [ ] Open Source Machine Translation Tool?
- [ ] Copy Translations
- https://github.com/microsoft/vscode-loc
- https://github.com/microsoft/vscode-l10n


## Phase - Blocks

- [ ] Dynamic Blocks
- [ ] Add arbitrary new blocks to end
- [ ] New block validation
- [ ] Remove block from end
- [ ] Block Library
- [ ] Include block steps in a snip
- [ ] Include block steps in a snip

83 changes: 83 additions & 0 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Tutorial

The Build Add-In is a tool to allow you to create snips to extend Word, Excel, and PowerPoint using the Office.js API.

Each snip consists of TypeScript, HTML, and CSS.

The Build Add-In provides a way to create, edit, run and share these snips.

## Quick Tutorial

Create, edit, and run your first snip.

1. Open the _Edit Taskpane_
1. Click the `Build` tab on the ribbon.
1. Click the `Edit` button.
1. Wait for the _Edit taskpane_ to open on the right of the document.
1. Create a new default snip, In the _Edit Taskpane_
1. Click the `Open Snip` Icon to open the `Local Snips` drawer and view all local snips. (There shouldn't be any yet)
1. In the `Local Snip` drawer, click `New Snip`.
1. You should see a snip named `Default Snip` appear.
1. Click the new Default Snip
1. Edit the Snip
1. Rename the snip
1. Edit the snips HTML
1. Click the `HTML` tab in the _Edit taskpane_
1. In the HTML editor add a new Paragraph `<p>Hello World!</p>`
1. Run the snip
1. Click the `Build` tab on the ribbon.
1. Click the `Run` button.
1. Wait for the _Run taskpane_ to open on the right of the document.
1. Wait for snip to load.

## Features

- [Create](#create)
- [Run](#run)
- [Edit](#edit)
- [Share](#share)
- [Backup](#backup)

### Create

To create a snip:

1. Click the `Build` tab on the ribbon.
1. Click the `Edit` button.
1. Wait for the _Edit taskpane_ to open on the right of the document.
1. Click the Plus Icon to create a new default snip

### Run

To run the currently open snip:

1. Click the `Build` tab on the ribbon.
1. Click the `Run` button.
1. Wait for the _Run taskpane_ to open on the right of the document.

The current snip open in the _Edit taskpane_ will run.

The `Run taskpane` will load the CSS, HTML, and JavaScript from the snip into the window.

### Edit

In the `Edit taskpane`:

- `Open Snip` - Open a snip to edit.
- Select the snip file to edit by clicking `TS`,`HTML`, or `CSS`.
- Use the editor to modify the file, your changes will automatically save as you edit.

### Share

Snips are saved in local storage. You can backup and share your snips in the `Edit taskpane`.

- Click `Copy to clipboard` to get a copy of currently open snip for sharing.
- Click `Import` to load a copied snip, it will open a dialog you can paste a snips text into.

#### Backup

In `Local Snips drawer` in the `Edit taskpane`.

- Click `Download All Snips` to download a snips.json file with a copy of all local snips.
- Click `Upload Snips` to upload a new copy of all snips in a snips.json file.

13 changes: 13 additions & 0 deletions docs/vocabulary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Vocabulary

- Snip
- A complete extension, consisting of Ts, HTML, CSS, and Libraries.
- Edit taskpane
- The pane opened by the ribbons Edit button.
- Run taskpane
- The pane opened by the ribbons Run button.
- Local Snips
- Snips that are stored in client side storage IndexedDB in the local browser.
- Local Snips drawer
- Drawer in the Edit Taskpane that allows management of local snips.

8 changes: 8 additions & 0 deletions tests/distConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import path from "path";
import { getRootDirectory } from "./getRootDirectory";

export const localDistPath = path.resolve(getRootDirectory(), "dist");

export const localDistManifestsPath = path.resolve(localDistPath, "manifests");
export const localDistManifestProductionPath = path.resolve(localDistManifestsPath, "production.xml");
export const localDistManifestProductionOutlookPath = path.resolve(localDistManifestsPath, "production.outlook.xml");
4 changes: 2 additions & 2 deletions tests/getLocalDistIndexData.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import * as fs from "fs";
import path from "path";
import { getRootDirectory } from "./getRootDirectory";
import { localDistPath } from "./distConstants";

/**
* Local generated page from build
*/
const mainPageLocalDistDataPath = path.resolve(getRootDirectory(), "dist", "index.html");
const mainPageLocalDistDataPath = path.resolve(localDistPath, "index.html");

export function getLocalDistIndexData() {
if (!fs.existsSync(mainPageLocalDistDataPath)) {
Expand Down
16 changes: 16 additions & 0 deletions tests/manifest.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { test, expect } from "@playwright/test";
import { localDistManifestProductionPath, localDistManifestProductionOutlookPath } from "./distConstants";
import * as fs from "fs";
import path from "path";

test("Production manifests are free of (local)", async () => {
const productionManifests = [localDistManifestProductionPath, localDistManifestProductionOutlookPath];
productionManifests.forEach((manifestPath) => {
const data = fs.readFileSync(manifestPath);
// check for presence of (local) which should not happen.

const expectLocal = false;
const hasLocal = data.includes("(local)");
expect(hasLocal, `${path.basename(manifestPath)} replaces local`).toBe(expectLocal);
});
});

0 comments on commit b0ae8c2

Please sign in to comment.