From ac89ea9e943409709bfed8ca1f033fd6e670c613 Mon Sep 17 00:00:00 2001 From: RangarajanSF4077 Date: Tue, 23 Sep 2025 15:49:24 +0530 Subject: [PATCH 1/2] ES-FileChange - Updated the jsx file --- Client-side/src/Authentication.js | 176 ------------------------------ Client-side/src/DocumentEditor.js | 91 --------------- Client-side/src/Titlebar.js | 139 ----------------------- 3 files changed, 406 deletions(-) delete mode 100644 Client-side/src/Authentication.js delete mode 100644 Client-side/src/DocumentEditor.js delete mode 100644 Client-side/src/Titlebar.js diff --git a/Client-side/src/Authentication.js b/Client-side/src/Authentication.js deleted file mode 100644 index dce6d2a..0000000 --- a/Client-side/src/Authentication.js +++ /dev/null @@ -1,176 +0,0 @@ -// Import necessary hooks and components -import { useState, useEffect } from "react"; -import { registerLicense } from '@syncfusion/ej2-base'; -import DocumentEditorMain from "./DocumentEditor"; - -// Register the Syncfusion license key -registerLicense("Ngo9BigBOggjHTQxAR8/V1NNaF5cXGhIfEx1RHxQdld5ZFRHallYTnNWUj0eQnxTdEBjWH1ecXxWRWVbUExyVklfag=="); - -const hostURL = "https://localhost:44310/api/authentication"; - -// Authenticating the users with the credentials like Email ID and password. Registering new users. -function Authentication() { - // State hooks for managing authentication - const [user, setUser] = useState(null); - const [isRegister, setIsRegister] = useState(false); - const [message, setMessage] = useState(""); - const [username, setUsername] = useState(""); - - // Effect to load user from localStorage on component mount - useEffect(() => { - const saved = localStorage.getItem("user"); - if (saved) { - setUser(JSON.parse(saved)); - } - }, []); - - // Logout user and clear state - const handleLogout = () => { - localStorage.removeItem("user"); - setUser(null); - }; - - // Validate email format using a regular expression - const validateEmail = (email) => /\S+@\S+\.\S+/.test(email); - - // Handle login form submission - const handleLogin = async (event) => { - event.preventDefault(); - setMessage(""); - - const form = event.currentTarget; - const email = form.elements.email.value.trim(); - const password = form.elements.password.value.trim(); - - if (!validateEmail(email)) { - setMessage("❌ Please enter a valid email."); - return; - } - - try { - // Make a POST request to the login API - const response = await fetch(`${hostURL}/login`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email, password }), - }); - - if (response.ok) { - const userData = await response.json(); - localStorage.setItem("user", JSON.stringify(userData)); - setUser(userData); // Update user state directly - } else { - setMessage("❌ Invalid email or password."); - } - } catch (error) { - setMessage("⚠️ Server error during login."); - } - }; - - // Handle registration form submission - const handleRegister = async (e) => { - e.preventDefault(); - setMessage(""); - - const form = e.currentTarget; - const username = form.elements.username.value; - const email = form.elements.email.value; - const password = form.elements.password.value; - - if (!validateEmail(email)) { - setMessage("❌ Please enter a valid email."); - return; - } - - try { - // Make a POST request to the registration API - const register = await fetch(`${hostURL}/register`, { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ username, email, password }), - }); - - const data = await register.json(); - if (register.ok) { - setMessage("✅ Registration successful. You can now log in."); - setIsRegister(false); - setUsername(""); - } else { - setMessage(`❌ ${data.message || "Registration failed"}`); - } - } catch { - setMessage("⚠️ Server error during registration."); - } - }; - - // Render authentication form if not logged in - const renderAuthForm = () => { - return ( -
-

{isRegister ? "Register" : "Login"}

-
- {isRegister && ( - <> - - setUsername(e.target.value)} - required - className="auth-input" - placeholder="Your username" - /> - - )} - - - - - -
- - {message &&

{message}

} -
- ); - }; - - // Render DocumentEditorMain if user is authenticated, otherwise render auth form - return user ? ( - - ) : ( - renderAuthForm() - ); -} - -export default Authentication; \ No newline at end of file diff --git a/Client-side/src/DocumentEditor.js b/Client-side/src/DocumentEditor.js deleted file mode 100644 index 854f275..0000000 --- a/Client-side/src/DocumentEditor.js +++ /dev/null @@ -1,91 +0,0 @@ -import { useEffect, useRef } from "react"; -import { DocumentEditorContainerComponent, Toolbar as DocumentEditorToolbar } from "@syncfusion/ej2-react-documenteditor"; -import TitleBar from "./Titlebar"; - -// Inject the toolbar to the document editor component -DocumentEditorContainerComponent.Inject(DocumentEditorToolbar); - -function DocumentEditor({ user, onLogout }) { - let defaultDocument = ''; - // Configure toolbar items based on user role - const toolbarConfig = { - Lawyer: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"], - Paralegal: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"], - Client: ["Comments", "Find"], - Reviewer: ["Comments", "Find", "TrackChanges"], - Admin: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"] - }; - - // Create references for title bar and container - const titleBarRef = useRef(null); - const containerRef = useRef(null); - - // Effect to initialize or update the document editor when the user changes - useEffect(() => { - if (user && containerRef.current) { - convertDocxToSfdt(); - containerRef.current.documentEditor.documentName = "Document"; - containerRef.current.documentEditor.currentUser = user.email; - - // Update document title when changes are made - containerRef.current.documentChange = () => { - titleBarRef.current.updateDocumentTitle(); - containerRef.current.documentEditor.focusIn(); - }; - if (!titleBarRef.current) { - titleBarRef.current = new TitleBar(document.getElementById("documenteditor_titlebar"), containerRef.current.documentEditor, true); - titleBarRef.current.updateDocumentTitle(); - } - containerRef.current.toolbarItems = toolbarConfig[user.username]; - } - }, [user]); - - // Convert GitHub Raw document to SFDT and load in Editor. - const convertDocxToSfdt = async () => { - try { - const docxResponse = await fetch('https://raw.githubusercontent.com/SyncfusionExamples/Role-Based-Toolbar-Customization-in-Syncfusion-Document-Editor-for-Legal-Workflows/master/Client-side/public/docs/Legal_Notice.docx'); - const docxBlob = await docxResponse.blob(); - - const formData = new FormData(); - formData.append('files', docxBlob, 'Legal_Notice.docx'); - - const importResponse = await fetch('https://ej2services.syncfusion.com/production/web-services/api/documenteditor/Import', { - method: 'POST', - body: formData, - }); - - if (importResponse.ok) { - defaultDocument = await importResponse.text(); - containerRef.current.documentEditor.open(defaultDocument); - } else { - console.error(`Failed to import document: ${importResponse.statusText}`); - } - } catch (error) { - console.error('Error converting document:', error); - } - }; - - return ( -
-
-

Welcome, {user.username || user.email}

- -
-
- - -
- ); -} - -export default DocumentEditor; \ No newline at end of file diff --git a/Client-side/src/Titlebar.js b/Client-side/src/Titlebar.js deleted file mode 100644 index 7dbe556..0000000 --- a/Client-side/src/Titlebar.js +++ /dev/null @@ -1,139 +0,0 @@ -import { createElement } from '@syncfusion/ej2-base'; -import { Button } from '@syncfusion/ej2-buttons'; -import { DropDownButton } from '@syncfusion/ej2-splitbuttons'; - -/** - * Represents the title bar of the document editor. - */ -class TitleBar { - constructor(element, docEditor, isShareNeeded, dialogComponent) { - // Initialize title bar elements. - this.tileBarDiv = element; - this.documentEditor = docEditor; - this.dialogComponent = dialogComponent; - this.initializeTitleBar(isShareNeeded); - this.wireEvents(); - - // Append document title after initialization - if (this.tileBarDiv && !this.tileBarDiv.contains(this.documentTitle)) { - this.tileBarDiv.prepend(this.documentTitle); - } - } - - /** - * Initializes the title bar, setting up text and tooltips. - * @param {boolean} isShareNeeded - Flag to decide if sharing feature is needed. - */ - initializeTitleBar = (isShareNeeded) => { - const downloadText = 'Download'; - const downloadToolTip = 'Download this document.'; - const printText = 'Print'; - const printToolTip = 'Print this document (Ctrl+P).'; - - // Create the document title element - this.documentTitle = createElement('label', { - id: 'documenteditor_title_name', - styles: 'font-weight:400;text-overflow:ellipsis;white-space:pre;overflow:hidden;user-select:none;cursor:text' - }); - this.documentTitle.innerHTML = this.documentEditor.documentName; - - const btnStyles = 'float:right;background: transparent;box-shadow:none; font-family: inherit;border-color: transparent;' + - 'border-radius: 2px;color:inherit;font-size:12px;text-transform:capitalize;height:28px;font-weight:400;margin: 4px;'; - - // Initialize print button - this.print = this.addButton('e-icons e-print e-de-padding-right', printText, btnStyles, 'de-print', printToolTip, false); - - // Initialize download drop-down button - const items = [ - { text: 'Syncfusion® Document Text (*.sfdt)', id: 'sfdt' }, - { text: 'Word Document (*.docx)', id: 'word' }, - { text: 'Word Template (*.dotx)', id: 'dotx' }, - { text: 'Plain Text (*.txt)', id: 'txt' }, - ]; - this.download = this.addButton('e-icons e-download e-de-padding-right', downloadText, btnStyles, 'documenteditor-share', downloadToolTip, true, items); - - // Hide download button if sharing is not needed - if (!isShareNeeded) { - this.download.element.style.display = 'none'; - } - }; - - /** - * Wires events to the buttons. - */ - wireEvents = () => { - this.print.element.addEventListener('click', this.onPrint); - }; - - /** - * Updates the document title displayed in the title bar. - */ - updateDocumentTitle = () => { - if (this.documentEditor.documentName === '') { - this.documentEditor.documentName = 'Untitled'; - } - this.documentTitle.textContent = this.documentEditor.documentName; - }; - - /** - * Adds a button to the title bar. - * @param {string} iconClass - Icon class for the button. - * @param {string} btnText - Button text. - * @param {string} styles - Button styles. - * @param {string} id - Button id. - * @param {string} tooltipText - Tooltip text for the button. - * @param {boolean} isDropDown - Whether the button is a dropdown. - * @param {Array} items - Items for dropdown, if applicable. - * @returns {Button|DropDownButton} - The created button instance. - */ - addButton(iconClass, btnText, styles, id, tooltipText, isDropDown, items) { - // Create button element - const button = createElement('button', { id, styles }); - this.tileBarDiv.appendChild(button); - button.setAttribute('title', tooltipText); - - // Return appropriate button based on isDropDown flag - if (isDropDown) { - return new DropDownButton({ - select: this.onDownloadClick, - items, - iconCss: iconClass, - cssClass: 'e-caret-hide', - content: btnText, - }, button); - } else { - return new Button({ iconCss: iconClass, content: btnText }, button); - } - } - - /** - * Handles print button click event. - */ - onPrint = () => { - this.documentEditor.print(); - }; - - /** - * Handles download item selection. - * @param {Object} args - Event arguments. - */ - onDownloadClick = (args) => { - const formatMap = { - 'word': 'Docx', - 'sfdt': 'Sfdt', - 'txt': 'Txt', - 'dotx': 'Dotx' - }; - this.save(formatMap[args.item.id]); - }; - - /** - * Saves the document in the specified format. - * @param {string} format - Format to save the document as. - */ - save = (format) => { - this.documentEditor.save(this.documentEditor.documentName || 'sample', format); - }; -} - -export default TitleBar; \ No newline at end of file From 20e3478853dc84833db623bbfe0e5131e9dca208 Mon Sep 17 00:00:00 2001 From: RangarajanSF4077 Date: Tue, 23 Sep 2025 16:00:42 +0530 Subject: [PATCH 2/2] ES-FileChange - Added jsx file --- Client-side/src/Authentication.jsx | 176 +++++++++++++++++++++++++++++ Client-side/src/DocumentEditor.jsx | 91 +++++++++++++++ Client-side/src/Titlebar.jsx | 139 +++++++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 Client-side/src/Authentication.jsx create mode 100644 Client-side/src/DocumentEditor.jsx create mode 100644 Client-side/src/Titlebar.jsx diff --git a/Client-side/src/Authentication.jsx b/Client-side/src/Authentication.jsx new file mode 100644 index 0000000..dce6d2a --- /dev/null +++ b/Client-side/src/Authentication.jsx @@ -0,0 +1,176 @@ +// Import necessary hooks and components +import { useState, useEffect } from "react"; +import { registerLicense } from '@syncfusion/ej2-base'; +import DocumentEditorMain from "./DocumentEditor"; + +// Register the Syncfusion license key +registerLicense("Ngo9BigBOggjHTQxAR8/V1NNaF5cXGhIfEx1RHxQdld5ZFRHallYTnNWUj0eQnxTdEBjWH1ecXxWRWVbUExyVklfag=="); + +const hostURL = "https://localhost:44310/api/authentication"; + +// Authenticating the users with the credentials like Email ID and password. Registering new users. +function Authentication() { + // State hooks for managing authentication + const [user, setUser] = useState(null); + const [isRegister, setIsRegister] = useState(false); + const [message, setMessage] = useState(""); + const [username, setUsername] = useState(""); + + // Effect to load user from localStorage on component mount + useEffect(() => { + const saved = localStorage.getItem("user"); + if (saved) { + setUser(JSON.parse(saved)); + } + }, []); + + // Logout user and clear state + const handleLogout = () => { + localStorage.removeItem("user"); + setUser(null); + }; + + // Validate email format using a regular expression + const validateEmail = (email) => /\S+@\S+\.\S+/.test(email); + + // Handle login form submission + const handleLogin = async (event) => { + event.preventDefault(); + setMessage(""); + + const form = event.currentTarget; + const email = form.elements.email.value.trim(); + const password = form.elements.password.value.trim(); + + if (!validateEmail(email)) { + setMessage("❌ Please enter a valid email."); + return; + } + + try { + // Make a POST request to the login API + const response = await fetch(`${hostURL}/login`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ email, password }), + }); + + if (response.ok) { + const userData = await response.json(); + localStorage.setItem("user", JSON.stringify(userData)); + setUser(userData); // Update user state directly + } else { + setMessage("❌ Invalid email or password."); + } + } catch (error) { + setMessage("⚠️ Server error during login."); + } + }; + + // Handle registration form submission + const handleRegister = async (e) => { + e.preventDefault(); + setMessage(""); + + const form = e.currentTarget; + const username = form.elements.username.value; + const email = form.elements.email.value; + const password = form.elements.password.value; + + if (!validateEmail(email)) { + setMessage("❌ Please enter a valid email."); + return; + } + + try { + // Make a POST request to the registration API + const register = await fetch(`${hostURL}/register`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ username, email, password }), + }); + + const data = await register.json(); + if (register.ok) { + setMessage("✅ Registration successful. You can now log in."); + setIsRegister(false); + setUsername(""); + } else { + setMessage(`❌ ${data.message || "Registration failed"}`); + } + } catch { + setMessage("⚠️ Server error during registration."); + } + }; + + // Render authentication form if not logged in + const renderAuthForm = () => { + return ( +
+

{isRegister ? "Register" : "Login"}

+
+ {isRegister && ( + <> + + setUsername(e.target.value)} + required + className="auth-input" + placeholder="Your username" + /> + + )} + + + + + +
+ + {message &&

{message}

} +
+ ); + }; + + // Render DocumentEditorMain if user is authenticated, otherwise render auth form + return user ? ( + + ) : ( + renderAuthForm() + ); +} + +export default Authentication; \ No newline at end of file diff --git a/Client-side/src/DocumentEditor.jsx b/Client-side/src/DocumentEditor.jsx new file mode 100644 index 0000000..854f275 --- /dev/null +++ b/Client-side/src/DocumentEditor.jsx @@ -0,0 +1,91 @@ +import { useEffect, useRef } from "react"; +import { DocumentEditorContainerComponent, Toolbar as DocumentEditorToolbar } from "@syncfusion/ej2-react-documenteditor"; +import TitleBar from "./Titlebar"; + +// Inject the toolbar to the document editor component +DocumentEditorContainerComponent.Inject(DocumentEditorToolbar); + +function DocumentEditor({ user, onLogout }) { + let defaultDocument = ''; + // Configure toolbar items based on user role + const toolbarConfig = { + Lawyer: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"], + Paralegal: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"], + Client: ["Comments", "Find"], + Reviewer: ["Comments", "Find", "TrackChanges"], + Admin: ["New", "Open", "Separator", "Undo", "Redo", "Separator", "Image", "Table", "Hyperlink", "Bookmark", "TableOfContents", "Separator", "Header", "Footer", "PageSetup", "PageNumber", "Break", "InsertFootnote", "InsertEndnote", "Separator", "Find", "Separator", "Comments", "TrackChanges", "LocalClipboard", "RestrictEditing", "Separator", "FormFields", "UpdateFields", "ContentControl", "XML Mapping"] + }; + + // Create references for title bar and container + const titleBarRef = useRef(null); + const containerRef = useRef(null); + + // Effect to initialize or update the document editor when the user changes + useEffect(() => { + if (user && containerRef.current) { + convertDocxToSfdt(); + containerRef.current.documentEditor.documentName = "Document"; + containerRef.current.documentEditor.currentUser = user.email; + + // Update document title when changes are made + containerRef.current.documentChange = () => { + titleBarRef.current.updateDocumentTitle(); + containerRef.current.documentEditor.focusIn(); + }; + if (!titleBarRef.current) { + titleBarRef.current = new TitleBar(document.getElementById("documenteditor_titlebar"), containerRef.current.documentEditor, true); + titleBarRef.current.updateDocumentTitle(); + } + containerRef.current.toolbarItems = toolbarConfig[user.username]; + } + }, [user]); + + // Convert GitHub Raw document to SFDT and load in Editor. + const convertDocxToSfdt = async () => { + try { + const docxResponse = await fetch('https://raw.githubusercontent.com/SyncfusionExamples/Role-Based-Toolbar-Customization-in-Syncfusion-Document-Editor-for-Legal-Workflows/master/Client-side/public/docs/Legal_Notice.docx'); + const docxBlob = await docxResponse.blob(); + + const formData = new FormData(); + formData.append('files', docxBlob, 'Legal_Notice.docx'); + + const importResponse = await fetch('https://ej2services.syncfusion.com/production/web-services/api/documenteditor/Import', { + method: 'POST', + body: formData, + }); + + if (importResponse.ok) { + defaultDocument = await importResponse.text(); + containerRef.current.documentEditor.open(defaultDocument); + } else { + console.error(`Failed to import document: ${importResponse.statusText}`); + } + } catch (error) { + console.error('Error converting document:', error); + } + }; + + return ( +
+
+

Welcome, {user.username || user.email}

+ +
+
+ + +
+ ); +} + +export default DocumentEditor; \ No newline at end of file diff --git a/Client-side/src/Titlebar.jsx b/Client-side/src/Titlebar.jsx new file mode 100644 index 0000000..7dbe556 --- /dev/null +++ b/Client-side/src/Titlebar.jsx @@ -0,0 +1,139 @@ +import { createElement } from '@syncfusion/ej2-base'; +import { Button } from '@syncfusion/ej2-buttons'; +import { DropDownButton } from '@syncfusion/ej2-splitbuttons'; + +/** + * Represents the title bar of the document editor. + */ +class TitleBar { + constructor(element, docEditor, isShareNeeded, dialogComponent) { + // Initialize title bar elements. + this.tileBarDiv = element; + this.documentEditor = docEditor; + this.dialogComponent = dialogComponent; + this.initializeTitleBar(isShareNeeded); + this.wireEvents(); + + // Append document title after initialization + if (this.tileBarDiv && !this.tileBarDiv.contains(this.documentTitle)) { + this.tileBarDiv.prepend(this.documentTitle); + } + } + + /** + * Initializes the title bar, setting up text and tooltips. + * @param {boolean} isShareNeeded - Flag to decide if sharing feature is needed. + */ + initializeTitleBar = (isShareNeeded) => { + const downloadText = 'Download'; + const downloadToolTip = 'Download this document.'; + const printText = 'Print'; + const printToolTip = 'Print this document (Ctrl+P).'; + + // Create the document title element + this.documentTitle = createElement('label', { + id: 'documenteditor_title_name', + styles: 'font-weight:400;text-overflow:ellipsis;white-space:pre;overflow:hidden;user-select:none;cursor:text' + }); + this.documentTitle.innerHTML = this.documentEditor.documentName; + + const btnStyles = 'float:right;background: transparent;box-shadow:none; font-family: inherit;border-color: transparent;' + + 'border-radius: 2px;color:inherit;font-size:12px;text-transform:capitalize;height:28px;font-weight:400;margin: 4px;'; + + // Initialize print button + this.print = this.addButton('e-icons e-print e-de-padding-right', printText, btnStyles, 'de-print', printToolTip, false); + + // Initialize download drop-down button + const items = [ + { text: 'Syncfusion® Document Text (*.sfdt)', id: 'sfdt' }, + { text: 'Word Document (*.docx)', id: 'word' }, + { text: 'Word Template (*.dotx)', id: 'dotx' }, + { text: 'Plain Text (*.txt)', id: 'txt' }, + ]; + this.download = this.addButton('e-icons e-download e-de-padding-right', downloadText, btnStyles, 'documenteditor-share', downloadToolTip, true, items); + + // Hide download button if sharing is not needed + if (!isShareNeeded) { + this.download.element.style.display = 'none'; + } + }; + + /** + * Wires events to the buttons. + */ + wireEvents = () => { + this.print.element.addEventListener('click', this.onPrint); + }; + + /** + * Updates the document title displayed in the title bar. + */ + updateDocumentTitle = () => { + if (this.documentEditor.documentName === '') { + this.documentEditor.documentName = 'Untitled'; + } + this.documentTitle.textContent = this.documentEditor.documentName; + }; + + /** + * Adds a button to the title bar. + * @param {string} iconClass - Icon class for the button. + * @param {string} btnText - Button text. + * @param {string} styles - Button styles. + * @param {string} id - Button id. + * @param {string} tooltipText - Tooltip text for the button. + * @param {boolean} isDropDown - Whether the button is a dropdown. + * @param {Array} items - Items for dropdown, if applicable. + * @returns {Button|DropDownButton} - The created button instance. + */ + addButton(iconClass, btnText, styles, id, tooltipText, isDropDown, items) { + // Create button element + const button = createElement('button', { id, styles }); + this.tileBarDiv.appendChild(button); + button.setAttribute('title', tooltipText); + + // Return appropriate button based on isDropDown flag + if (isDropDown) { + return new DropDownButton({ + select: this.onDownloadClick, + items, + iconCss: iconClass, + cssClass: 'e-caret-hide', + content: btnText, + }, button); + } else { + return new Button({ iconCss: iconClass, content: btnText }, button); + } + } + + /** + * Handles print button click event. + */ + onPrint = () => { + this.documentEditor.print(); + }; + + /** + * Handles download item selection. + * @param {Object} args - Event arguments. + */ + onDownloadClick = (args) => { + const formatMap = { + 'word': 'Docx', + 'sfdt': 'Sfdt', + 'txt': 'Txt', + 'dotx': 'Dotx' + }; + this.save(formatMap[args.item.id]); + }; + + /** + * Saves the document in the specified format. + * @param {string} format - Format to save the document as. + */ + save = (format) => { + this.documentEditor.save(this.documentEditor.documentName || 'sample', format); + }; +} + +export default TitleBar; \ No newline at end of file