Re-organisation of Draft and Confidential code
This commit is contained in:
@@ -0,0 +1,219 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
makeStyles
|
||||||
|
} from "@fluentui/react-components";
|
||||||
|
import {
|
||||||
|
TextAlignLeftRegular,
|
||||||
|
TextAlignCenterRegular,
|
||||||
|
TextAlignRightRegular,
|
||||||
|
TextboxAlignTopRegular,
|
||||||
|
TextboxAlignMiddleRegular,
|
||||||
|
TextboxAlignBottomRegular
|
||||||
|
} from "@fluentui/react-icons";
|
||||||
|
import { useStatusContext } from "./App";
|
||||||
|
import { useCommonStyles } from "./commonStyles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
alignmentGrid: {
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "repeat(3, 1fr)",
|
||||||
|
gap: "8px",
|
||||||
|
width: "100%"
|
||||||
|
},
|
||||||
|
alignButton: {
|
||||||
|
width: "100%",
|
||||||
|
minWidth: 0,
|
||||||
|
padding: "8px 4px",
|
||||||
|
"& span": {
|
||||||
|
justifyContent: "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const AlignmentButtons: React.FC = () => {
|
||||||
|
const styles = useStyles();
|
||||||
|
const commonStyles = useCommonStyles();
|
||||||
|
const {
|
||||||
|
statusMessage, setStatusMessage,
|
||||||
|
statusType, setStatusType,
|
||||||
|
isProcessing, setIsProcessing
|
||||||
|
} = useStatusContext();
|
||||||
|
|
||||||
|
const alignLeft = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to left.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align left error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignCenter = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to center.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align center error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignRight = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to right.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align right error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignTop = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to top.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align top error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignMiddle = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to middle.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align middle error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const alignBottom = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Objects aligned to bottom.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Align bottom error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={commonStyles.container}>
|
||||||
|
<div className={styles.alignmentGrid}>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignLeft}
|
||||||
|
icon={<TextAlignLeftRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Left"
|
||||||
|
>
|
||||||
|
Left
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignCenter}
|
||||||
|
icon={<TextAlignCenterRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Center"
|
||||||
|
>
|
||||||
|
Center
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignRight}
|
||||||
|
icon={<TextAlignRightRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Right"
|
||||||
|
>
|
||||||
|
Right
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignTop}
|
||||||
|
icon={<TextboxAlignTopRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Top"
|
||||||
|
>
|
||||||
|
Top
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignMiddle}
|
||||||
|
icon={<TextboxAlignMiddleRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Middle"
|
||||||
|
>
|
||||||
|
Middle
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.alignButton}
|
||||||
|
onClick={alignBottom}
|
||||||
|
icon={<TextboxAlignBottomRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Align Bottom"
|
||||||
|
>
|
||||||
|
Bottom
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AlignmentButtons;
|
||||||
@@ -5,10 +5,8 @@ import MatchProperties from "./MatchProperties";
|
|||||||
import RoundImage from "./RoundImage";
|
import RoundImage from "./RoundImage";
|
||||||
import SwapPositions from "./SwapPositions";
|
import SwapPositions from "./SwapPositions";
|
||||||
import InsertTitles from "./InsertTitles";
|
import InsertTitles from "./InsertTitles";
|
||||||
import AddConfidential from "./AddConfidential";
|
import ConfidentialButtons from "./ConfidentialButtons";
|
||||||
import RemoveConfidential from "./RemoveConfidential";
|
import DraftButtons from "./DraftButtons";
|
||||||
import AddDraft from "./AddDraft";
|
|
||||||
import RemoveDraft from "./RemoveDraft";
|
|
||||||
import AddProgressBar from "./AddProgressBar";
|
import AddProgressBar from "./AddProgressBar";
|
||||||
import RemoveProgressBar from "./RemoveProgressBar";
|
import RemoveProgressBar from "./RemoveProgressBar";
|
||||||
import AlignmentButtons from "./AlignmentButtons";
|
import AlignmentButtons from "./AlignmentButtons";
|
||||||
@@ -182,13 +180,9 @@ const App: React.FC<AppProps> = () => {
|
|||||||
<Subtitle1 block className={styles.sectionTitle}>
|
<Subtitle1 block className={styles.sectionTitle}>
|
||||||
Watermarks
|
Watermarks
|
||||||
</Subtitle1>
|
</Subtitle1>
|
||||||
<AddConfidential />
|
<ConfidentialButtons />
|
||||||
<div style={{ marginTop: "8px" }}></div>
|
<div style={{ marginTop: "8px" }}></div>
|
||||||
<RemoveConfidential />
|
<DraftButtons />
|
||||||
<div style={{ marginTop: "8px" }}></div>
|
|
||||||
<AddDraft />
|
|
||||||
<div style={{ marginTop: "8px" }}></div>
|
|
||||||
<RemoveDraft />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.section}>
|
<div className={styles.section}>
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
makeStyles
|
||||||
|
} from "@fluentui/react-components";
|
||||||
|
import {
|
||||||
|
ShieldLockRegular,
|
||||||
|
DismissRegular
|
||||||
|
} from "@fluentui/react-icons";
|
||||||
|
import { useStatusContext } from "./App";
|
||||||
|
import { useCommonStyles } from "./commonStyles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
buttonGrid: {
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "repeat(2, 1fr)",
|
||||||
|
gap: "8px",
|
||||||
|
width: "100%"
|
||||||
|
},
|
||||||
|
confidentialButton: {
|
||||||
|
width: "100%",
|
||||||
|
minWidth: 0,
|
||||||
|
padding: "8px 4px",
|
||||||
|
"& span": {
|
||||||
|
justifyContent: "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ConfidentialButtons: React.FC = () => {
|
||||||
|
const styles = useStyles();
|
||||||
|
const commonStyles = useCommonStyles();
|
||||||
|
const {
|
||||||
|
statusMessage, setStatusMessage,
|
||||||
|
statusType, setStatusType,
|
||||||
|
isProcessing, setIsProcessing
|
||||||
|
} = useStatusContext();
|
||||||
|
|
||||||
|
const addConfidentialMarking = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
try {
|
||||||
|
// Get all slides in the presentation
|
||||||
|
const slides = context.presentation.slides;
|
||||||
|
slides.load("items");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Get a reference slide to determine dimensions
|
||||||
|
// Since we can't access presentation width/height directly
|
||||||
|
if (slides.items.length === 0) {
|
||||||
|
setStatusMessage("No slides found in the presentation.");
|
||||||
|
setStatusType("warning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get dimensions from the first slide
|
||||||
|
const firstSlide = slides.items[0];
|
||||||
|
|
||||||
|
// Standard PowerPoint slide dimensions (in points)
|
||||||
|
// We'll use these as fallbacks and adjust if we can get actual dimensions
|
||||||
|
let slideWidth = 960; // Default slide width (10 inches * 72 points)
|
||||||
|
let slideHeight = 540; // Default slide height (7.5 inches * 72 points)
|
||||||
|
|
||||||
|
// Process counter
|
||||||
|
let processedSlides = 0;
|
||||||
|
let errorSlides = 0;
|
||||||
|
|
||||||
|
// Process each slide
|
||||||
|
for (let i = 0; i < slides.items.length; i++) {
|
||||||
|
try {
|
||||||
|
const slide = slides.items[i];
|
||||||
|
|
||||||
|
const positionFromTop = slideHeight - 23;
|
||||||
|
|
||||||
|
// Create the textbox - make sure it spans the full width of the slide
|
||||||
|
// This is important for proper centering
|
||||||
|
const textBox = slide.shapes.addTextBox("");
|
||||||
|
|
||||||
|
// Make it span most of the width of the slide (90% centered)
|
||||||
|
// This ensures we have room for the text to be centered
|
||||||
|
const textBoxWidth = slideWidth * 1; // 0.9
|
||||||
|
textBox.left = (slideWidth - textBoxWidth) / 2; // Center it horizontally
|
||||||
|
textBox.top = positionFromTop;
|
||||||
|
textBox.width = textBoxWidth;
|
||||||
|
textBox.height = 25; // Smaller height for footer text
|
||||||
|
|
||||||
|
console.log("Starting PowerPoint add-in execution.");
|
||||||
|
console.log(textBox.left);
|
||||||
|
console.log(textBox.top);
|
||||||
|
console.log(textBox.width);
|
||||||
|
console.log(textBox.height);
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Load textFrame to set text properties
|
||||||
|
textBox.load("textFrame");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
if (textBox.textFrame) {
|
||||||
|
// Load textRange to set text and properties
|
||||||
|
textBox.textFrame.load("textRange");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Need to load font and paragraphFormat
|
||||||
|
textBox.textFrame.textRange.load("font,paragraphFormat");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Set font properties
|
||||||
|
try {
|
||||||
|
// Ensure the font is loaded properly before setting properties
|
||||||
|
textBox.textFrame.textRange.font.load();
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Set font properties exactly as in the VBA code
|
||||||
|
textBox.textFrame.textRange.font.name = "Inter";
|
||||||
|
textBox.textFrame.textRange.font.size = 8;
|
||||||
|
textBox.textFrame.textRange.paragraphFormat.horizontalAlignment = "Center"
|
||||||
|
|
||||||
|
// Set the color to RGB(218, 19, 53)
|
||||||
|
// Different APIs may need different color formats
|
||||||
|
textBox.textFrame.textRange.font.color = "#DA1335";
|
||||||
|
|
||||||
|
// Set the text
|
||||||
|
textBox.textFrame.textRange.text = "– Confidential –";
|
||||||
|
} catch (fontError) {
|
||||||
|
console.error("Error setting font properties:", fontError);
|
||||||
|
// Even if we can't set the font properties exactly, continue with default font
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a name/tag to the shape for identification
|
||||||
|
textBox.name = "ConfidentialMarking";
|
||||||
|
|
||||||
|
await context.sync();
|
||||||
|
processedSlides++;
|
||||||
|
}
|
||||||
|
} catch (slideError) {
|
||||||
|
console.error(`Error processing slide ${i+1}:`, slideError);
|
||||||
|
errorSlides++;
|
||||||
|
// Continue to the next slide
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report results
|
||||||
|
if (processedSlides > 0) {
|
||||||
|
setStatusMessage(`Added confidential marking to ${processedSlides} slides.`);
|
||||||
|
setStatusType("success");
|
||||||
|
} else if (errorSlides > 0) {
|
||||||
|
setStatusMessage(`Failed to add markings. Errors on ${errorSlides} slides.`);
|
||||||
|
setStatusType("error");
|
||||||
|
} else {
|
||||||
|
setStatusMessage("No slides found to add confidential marking.");
|
||||||
|
setStatusType("warning");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (innerError) {
|
||||||
|
console.error("Inner error:", innerError);
|
||||||
|
throw innerError; // Re-throw to outer catch
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Add confidential error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeConfidentialMarking = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
try {
|
||||||
|
// Get all slides in the presentation
|
||||||
|
const slides = context.presentation.slides;
|
||||||
|
slides.load("items");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
if (slides.items.length === 0) {
|
||||||
|
setStatusMessage("No slides found in the presentation.");
|
||||||
|
setStatusType("warning");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process counter
|
||||||
|
let processedSlides = 0;
|
||||||
|
let errorSlides = 0;
|
||||||
|
let removedCount = 0;
|
||||||
|
|
||||||
|
// Process each slide
|
||||||
|
for (let i = 0; i < slides.items.length; i++) {
|
||||||
|
try {
|
||||||
|
const slide = slides.items[i];
|
||||||
|
|
||||||
|
// Load all shapes on the slide
|
||||||
|
slide.shapes.load("items");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
// Find shapes with name "ConfidentialMarking"
|
||||||
|
for (let j = 0; j < slide.shapes.items.length; j++) {
|
||||||
|
const shape = slide.shapes.items[j];
|
||||||
|
shape.load("name");
|
||||||
|
await context.sync();
|
||||||
|
|
||||||
|
if (shape.name === "ConfidentialMarking") {
|
||||||
|
// Delete the confidential marking shape
|
||||||
|
shape.delete();
|
||||||
|
removedCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.sync();
|
||||||
|
processedSlides++;
|
||||||
|
} catch (slideError) {
|
||||||
|
console.error(`Error processing slide ${i+1}:`, slideError);
|
||||||
|
errorSlides++;
|
||||||
|
// Continue to the next slide
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report results
|
||||||
|
if (removedCount > 0) {
|
||||||
|
setStatusMessage(`Removed ${removedCount} confidential markings from ${processedSlides} slides.`);
|
||||||
|
setStatusType("success");
|
||||||
|
} else if (errorSlides > 0) {
|
||||||
|
setStatusMessage(`Failed to remove markings. Errors on ${errorSlides} slides.`);
|
||||||
|
setStatusType("error");
|
||||||
|
} else {
|
||||||
|
setStatusMessage("No confidential markings found to remove.");
|
||||||
|
setStatusType("info");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (innerError) {
|
||||||
|
console.error("Inner error:", innerError);
|
||||||
|
throw innerError; // Re-throw to outer catch
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Remove confidential error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={commonStyles.container}>
|
||||||
|
<div className={styles.buttonGrid}>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.confidentialButton}
|
||||||
|
onClick={addConfidentialMarking}
|
||||||
|
icon={<ShieldLockRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Add Confidential"
|
||||||
|
>
|
||||||
|
Add Confidential
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.confidentialButton}
|
||||||
|
onClick={removeConfidentialMarking}
|
||||||
|
icon={<DismissRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Remove Confidential"
|
||||||
|
>
|
||||||
|
Remove Confidential
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConfidentialButtons;
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
makeStyles
|
||||||
|
} from "@fluentui/react-components";
|
||||||
|
import {
|
||||||
|
Edit24Regular,
|
||||||
|
DismissRegular
|
||||||
|
} from "@fluentui/react-icons";
|
||||||
|
import { useStatusContext } from "./App";
|
||||||
|
import { useCommonStyles } from "./commonStyles";
|
||||||
|
|
||||||
|
const useStyles = makeStyles({
|
||||||
|
buttonGrid: {
|
||||||
|
display: "grid",
|
||||||
|
gridTemplateColumns: "repeat(2, 1fr)",
|
||||||
|
gap: "8px",
|
||||||
|
width: "100%"
|
||||||
|
},
|
||||||
|
draftButton: {
|
||||||
|
width: "100%",
|
||||||
|
minWidth: 0,
|
||||||
|
padding: "8px 4px",
|
||||||
|
"& span": {
|
||||||
|
justifyContent: "center"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const DraftButtons: React.FC = () => {
|
||||||
|
const styles = useStyles();
|
||||||
|
const commonStyles = useCommonStyles();
|
||||||
|
const {
|
||||||
|
statusMessage, setStatusMessage,
|
||||||
|
statusType, setStatusType,
|
||||||
|
isProcessing, setIsProcessing
|
||||||
|
} = useStatusContext();
|
||||||
|
|
||||||
|
const addDraftWatermark = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Added draft watermark to slides.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Add draft watermark error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const removeDraftWatermark = async () => {
|
||||||
|
setIsProcessing(true);
|
||||||
|
try {
|
||||||
|
await PowerPoint.run(async (context) => {
|
||||||
|
const shapes = context.presentation.getSelectedShapes();
|
||||||
|
// Implementation will go here
|
||||||
|
setStatusMessage("Removed draft watermarks from slides.");
|
||||||
|
setStatusType("success");
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setStatusMessage(`Error: ${error.message}`);
|
||||||
|
setStatusType("error");
|
||||||
|
console.error("Remove draft watermark error:", error);
|
||||||
|
} finally {
|
||||||
|
setIsProcessing(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={commonStyles.container}>
|
||||||
|
<div className={styles.buttonGrid}>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.draftButton}
|
||||||
|
onClick={addDraftWatermark}
|
||||||
|
icon={<Edit24Regular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Add Draft"
|
||||||
|
>
|
||||||
|
Add Draft
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
appearance="primary"
|
||||||
|
className={styles.draftButton}
|
||||||
|
onClick={removeDraftWatermark}
|
||||||
|
icon={<DismissRegular />}
|
||||||
|
disabled={isProcessing}
|
||||||
|
title="Remove Draft"
|
||||||
|
>
|
||||||
|
Remove Draft
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DraftButtons;
|
||||||
Reference in New Issue
Block a user