Skip to content

[word] Port Word autorun sample #996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 2, 2025
Merged

[word] Port Word autorun sample #996

merged 5 commits into from
Jul 2, 2025

Conversation

AlexJerabek
Copy link
Collaborator

Q A
Bug fix? no
New feature? yes
New sample? yes
Related issues?

What's in this Pull Request?

This PR as a working version of the sample referenced in this PR: OfficeDev/office-js-docs-pr#5261. At some point after both are merged, I'll crosslink more between them.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a new sample add-in for Word that automatically adds sensitivity labels to document headers upon opening. Key changes include:

  • Configuring webpack for the build and development server.
  • Implementing header update functions in the taskpane and command modules.
  • Updating the manifest, README, and project configuration files to support event-based activation.

Reviewed Changes

Copilot reviewed 12 out of 19 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
webpack.config.js Sets up build configuration and HTTPS options for development.
src/taskpane/taskpane.js Implements functions to update document headers with sensitivity labels.
src/taskpane/taskpane.html Provides UI elements to manually trigger header changes.
src/taskpane/taskpane.css Contains styles for the task pane.
src/commands/commands.js Defines event handlers for add-in command activation.
src/commands/commands.html Provides minimal HTML structure for command functionality.
package.json, manifest.xml, README.md, .gitignore, .eslintrc.json Update project configuration, metadata, and documentation.

Comment on lines +20 to +95
export async function changeToNonBusinessLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);

header.clear();
firstPageHeader.clear();
header.insertParagraph("Non-Business - The data is personal and not business related", "Start");
firstPageHeader.insertParagraph("Non-Business - The data is personal and not business related", "Start");
header.font.color = "#737173";
firstPageHeader.font.color = "#737173";

await context.sync();
});
}

export async function changeToPublicLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start");
header.font.color = "#07641d";
firstPageHeader.font.color = "#07641d";

await context.sync();
});
}

export async function changeToGeneralLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("General - Business data shared with trusted individuals", "Start");
firstPageHeader.insertParagraph("General - Business data shared with trusted individuals", "Start");
header.font.color = "#0177d3";
firstPageHeader.font.color = "#0177d3";

await context.sync();
});
}

export async function changeToConfidentialLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Confidential - Sensitive business data shared with trusted individuals", "Start");
firstPageHeader.insertParagraph("Confidential - Sensitive business data shared with trusted individuals", "Start");
header.font.color = "#ff5c3a";
firstPageHeader.font.color = "#ff5c3a";

await context.sync();
});
}

export async function changeToHighConfidentialLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start");
firstPageHeader.insertParagraph(
"Highly Confidential - The data must be secret or in some way highly critical",
"Start"
);
header.font.color = "#f8334d";
firstPageHeader.font.color = "#f8334d";

await context.sync();
Copy link
Preview

Copilot AI Jun 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic for clearing headers and inserting paragraphs is repeated in multiple functions. Consider extracting a helper function to update headers based on a provided label and style to reduce duplication.

Suggested change
export async function changeToNonBusinessLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Non-Business - The data is personal and not business related", "Start");
firstPageHeader.insertParagraph("Non-Business - The data is personal and not business related", "Start");
header.font.color = "#737173";
firstPageHeader.font.color = "#737173";
await context.sync();
});
}
export async function changeToPublicLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start");
header.font.color = "#07641d";
firstPageHeader.font.color = "#07641d";
await context.sync();
});
}
export async function changeToGeneralLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("General - Business data shared with trusted individuals", "Start");
firstPageHeader.insertParagraph("General - Business data shared with trusted individuals", "Start");
header.font.color = "#0177d3";
firstPageHeader.font.color = "#0177d3";
await context.sync();
});
}
export async function changeToConfidentialLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Confidential - Sensitive business data shared with trusted individuals", "Start");
firstPageHeader.insertParagraph("Confidential - Sensitive business data shared with trusted individuals", "Start");
header.font.color = "#ff5c3a";
firstPageHeader.font.color = "#ff5c3a";
await context.sync();
});
}
export async function changeToHighConfidentialLevel() {
return Word.run(async (context) => {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Highly Confidential - The data must be secret or in some way highly critical", "Start");
firstPageHeader.insertParagraph(
"Highly Confidential - The data must be secret or in some way highly critical",
"Start"
);
header.font.color = "#f8334d";
firstPageHeader.font.color = "#f8334d";
await context.sync();
async function updateHeader(context, label, color) {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph(label, "Start");
firstPageHeader.insertParagraph(label, "Start");
header.font.color = color;
firstPageHeader.font.color = color;
await context.sync();
}
export async function changeToNonBusinessLevel() {
return Word.run(async (context) => {
await updateHeader(
context,
"Non-Business - The data is personal and not business related",
"#737173"
);
});
}
export async function changeToPublicLevel() {
return Word.run(async (context) => {
await updateHeader(
context,
"Public - The data is for the public and shareable externally",
"#07641d"
);
});
}
export async function changeToGeneralLevel() {
return Word.run(async (context) => {
await updateHeader(
context,
"General - Business data shared with trusted individuals",
"#0177d3"
);
});
}
export async function changeToConfidentialLevel() {
return Word.run(async (context) => {
await updateHeader(
context,
"Confidential - Sensitive business data shared with trusted individuals",
"#ff5c3a"
);
});
}
export async function changeToHighConfidentialLevel() {
return Word.run(async (context) => {
await updateHeader(
context,
"Highly Confidential - The data must be secret or in some way highly critical",
"#f8334d"
);

Copilot uses AI. Check for mistakes.

Comment on lines +17 to +69
if (body.text.length == 0)
{
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start");
header.font.color = "#07641d";
firstPageHeader.font.color = "#07641d";

await context.sync();
}
else
{
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
firstPageHeader.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
header.font.color = "#f8334d";
firstPageHeader.font.color = "#f8334d";
await context.sync();
}
});

// Calling event.completed is required. event.completed lets the platform know that processing has completed.
event.completed();
}

async function paragraphChanged() {
await Word.run(async (context) => {
const results = context.document.body.search("110");
results.load("length");
await context.sync();
if (results.items.length == 0) {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
header.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
const font = header.font;
font.color = "#07641d";

await context.sync();
}
else {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
header.clear();
header.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
const font = header.font;
font.color = "#f8334d";
await context.sync();
}
Copy link
Preview

Copilot AI Jun 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The header update logic is duplicated in both branches of the 'changeHeader' function. Refactoring the common header update code into a separate helper could improve code clarity and maintainability.

Suggested change
if (body.text.length == 0)
{
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
firstPageHeader.insertParagraph("Public - The data is for the public and shareable externally", "Start");
header.font.color = "#07641d";
firstPageHeader.font.color = "#07641d";
await context.sync();
}
else
{
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
header.clear();
firstPageHeader.clear();
header.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
firstPageHeader.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
header.font.color = "#f8334d";
firstPageHeader.font.color = "#f8334d";
await context.sync();
}
});
// Calling event.completed is required. event.completed lets the platform know that processing has completed.
event.completed();
}
async function paragraphChanged() {
await Word.run(async (context) => {
const results = context.document.body.search("110");
results.load("length");
await context.sync();
if (results.items.length == 0) {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
header.clear();
header.insertParagraph("Public - The data is for the public and shareable externally", "Start");
const font = header.font;
font.color = "#07641d";
await context.sync();
}
else {
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
header.clear();
header.insertParagraph("High Confidential - The data must be secret or in some way highly critical", "Start");
const font = header.font;
font.color = "#f8334d";
await context.sync();
}
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
const firstPageHeader = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.firstPage);
if (body.text.length == 0) {
updateHeader(header, "Public - The data is for the public and shareable externally", "#07641d");
updateHeader(firstPageHeader, "Public - The data is for the public and shareable externally", "#07641d");
} else {
updateHeader(header, "High Confidential - The data must be secret or in some way highly critical", "#f8334d");
updateHeader(firstPageHeader, "High Confidential - The data must be secret or in some way highly critical", "#f8334d");
}
await context.sync();
});
// Calling event.completed is required. event.completed lets the platform know that processing has completed.
event.completed();
}
function updateHeader(header, text, color) {
header.clear();
header.insertParagraph(text, "Start");
header.font.color = color;
}
async function paragraphChanged() {
await Word.run(async (context) => {
const results = context.document.body.search("110");
results.load("length");
await context.sync();
const header = context.document.sections.getFirst().getHeader(Word.HeaderFooterType.primary);
if (results.items.length == 0) {
updateHeader(header, "Public - The data is for the public and shareable externally", "#07641d");
} else {
updateHeader(header, "High Confidential - The data must be secret or in some way highly critical", "#f8334d");
}
await context.sync();

Copilot uses AI. Check for mistakes.

</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 Taskpane"/>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my suggestion in the article PR

@AlexJerabek AlexJerabek merged commit b5a4a7c into main Jul 2, 2025
1 check passed
@AlexJerabek AlexJerabek deleted the AlexJ-Autorun branch July 2, 2025 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants