Kako razviti DocSpace dodatak – kompletan korak po korak vodič
U svetu gde su brzina i saradnja od ključnog značaja, alati za produktivnost moraju da prate tempo. DocSpace dodaci nude moderan način za unapređenje načina na koji korisnici upravljaju dokumentima i komuniciraju sa njima. U ovom vodiču, pokazaćemo vam kako da kreirate sopstveni DocSpace dodatak koristeći stvarne primere iz naše zvanične kolekcije dodataka.
O ONLYOFFICE DocSpace Plugins SDK
ONLYOFFICE DocSpace Plugins SDK je npm paket zasnovan na TypeScript mehanizmima koji obezbeđuje interfejse koji vam omogućavaju da kreirate sopstvene dodatke i ugradite ih u DocSpace portal. Životni ciklus razvoja dodataka uključuje planiranje, razvoj, testiranje i korišćenje.
Da bismo ilustrovali kako se koristi naš Plugins SDK, kreirali smo repozitorijum sa uzorcima dodataka. Hajde da zaronimo u ceo proces razvoja dodataka na osnovu naših uzoraka.
Planiranje
Definišite svrhu dodatka, razmislite o tome gde ćete mu pristupiti i koje usluge trećih strana treba da povežete.
Korak 1. Instalirajte sve neophodne pakete i programe
- ONLYOFFICE DocSpace za lokalnu instalaciju.
- @onlyoffice/docspace-plugin-sdk npm paket
Da biste globalno instalirali @onlyoffice/docspace-plugin-sdk npm paket, koristite sledeću komandu:
npm i -g @onlyoffice/docspace-plugin-sdk
Korak 2. Dizajnirajte način rada vašeg dodatka
Izaberite uslugu koja vam omogućava da dodate potrebnu funkcionalnost u vaš DocSpace.
Na primer, u našim uzorcima dodataka koristimo:
- AssemblyAI za pretvaranje govora iz audio i video fajlova u tekst;
- ConvertAPI za konvertovanje dokumenata, tabela, prezentacija i obrazaca u PDF;
- Draw.io za kreiranje, uređivanje i umetanje profesionalnih dijagrama.
Napomena! Obavezno proverite da li je dostupna dokumentacija za izabranu uslugu, proverite njenu licencu, dostupnost API metoda itd. Za neke usluge korisnik mora da dobije API ključ kako bi počeo da koristi dodatak.
Razmislite o tome gde ćete implementirati dodatak, kakva će biti njegova struktura, kako će korisnik komunicirati sa njegovim komponentama itd. Napravite listu potrebnih tipova i stavki dodataka na osnovu tih informacija. Više informacija potražite u odeljcima Plugin tipovi i Plugin items u dokumentaciji Plugins SDK-a.
Na primer, za dodatak za pretvaranje govora u tekst, koristimo sledeće plugin interfejse:
- IPlugin. Obavezan za svaki dodatak. Sadrži plugin promenljivu PluginStatus i koristi se za ugradnju dodatka u DocSpace.
- ApiPlugin. Obavezan jer implementiramo uslugu treće strane.
- ISettingsPlugin i ISettings. Koriste se za dodavanje bloka za podešavanja dodatka. Korisnici mu pristupaju putem Settings -> Integration -> Plugins radi podešavanja parametara dodatka.
- IContextMenuPlugin i IContextMenuItem. Koriste se za implementaciju akcije u kontekstnom meniju. U dodatku za govor u tekst, dostupna je za video i audio fajlove i omogućava korisnicima da konvertuju sadržaj u tekst.
Lista interfejsa može biti duža. Na primer, u draw\.io dodatku:
- IMainButtonPlugin i IMainButtonItem. Koriste se za implementaciju glavne akcije dugmeta. U draw\.io dodatku, koristimo Action button -> More meni elemente u sekciji My documents ili u izabranoj sobi za kreiranje draw\.io dijagrama.
- IFilePlugin i IFileItem. Koriste se za interakciju sa određenim tipovima fajlova. U ovom slučaju sa .drawio fajlovima.
Osmislite strukturu dodatka. Svi potrebni fajlovi su opisani ovde. Sve ostalo može biti organizovano po vašoj želji. Na primer, u draw\.io dodatku, kod za svaki tip dodatka je smešten u zasebne foldere, dok je u dodatku za govor u tekst sav kod smešten u src folder.
Izaberite naziv za vaš dodatak i napišite njegov opis.
Razvoj
Sada kada ste završili sve pripremne korake, možete započeti razvoj vašeg dodatka.
Korak 1. Kreirajte šablon dodatka
Kreirajte šablon dodatka i konfigurišite njegova podešavanja koja će biti prikazana u podešavanjima dodataka u DocSpace-u:
Da biste kreirali šablon dodatka, otvorite terminal i pokrenite sledeću npx komandu:
npx create-docspace-plugin
Ako npx komanda nije dostupna, instalirajte @onlyoffice/docspace-plugin-sdk npm paket globalno koristeći sledeću komandu:
npm i -g @onlyoffice/docspace-plugin-sdk
Konfigurišite dodatak u terminalu tako što ćete uneti podešavanja u dijalogu. Sva podešavanja su opisana ovde.
Za dodatak za govor u tekst možete koristiti sledeće vrednosti:
Sve navedene parametre možete kasnije promeniti u fajlu package.json file.
Dodatak možete takođe kreirati u bilo kom projektu dodavanjem @onlyoffice/docspace-plugin-sdk npm paketa kao zavisnosti i navođenjem svih neophodnih polja u package.json fajlu.
Korak 2. Konfigurišite ulaznu tačku dodatka
Index.ts fajl kao ulazna tačka dodatka biće automatski kreiran u src folderu tokom koraka kreiranja šablona. Ovaj fajl je obavezan.
Ovaj fajl sadrži sve osnovne metode tipova dodataka koje ste odabrali u prethodnom koraku. Možete ga menjati u bilo kom trenutku.
Ako sami kreirate dodatak bez šablona, za ulaznu tačku dodatka možete koristiti kod iz naših gotovih uzoraka dodataka. Radiće savršeno.
Korak 3. Dodajte plugin ikone
Kreirajte folder sredstva u korenskom folderu dodatka i dodajte sve ikone dodatka u njega. Broj ikona i njihove veličine zavisiće od tipova dodataka koje implementirate. Za dodatak za govor u tekst plugin potrebne su sledeće ikone:
- Podrazumevani tip dodatka zahteva logo sliku. Ona odgovara parametru logo iz fajla package.json. Logo će biti prikazan u podešavanjima dodataka u DocSpace-u. Potrebna veličina ikone je 48×48 px. U suprotnom, biće kompresovana na ovu veličinu.
- Dodatak za kontekst meni koristi ikonu na dugmetu Convert to text. Potrebna veličina ikone je 16×16 px. U suprotnom, biće kompresovana na ovu veličinu.
Ova ikona se takođe može koristiti kao ikona glavnog dugmeta. Na primer, u draw\.io dodatku ista ikona se koristi za kontekstni i glavni meni dugmeta.
Draw\.io takođe koristi specifičnu ikonu fajla pored .drawio fajlova, koji se kreiraju pomoću tipa dodatka za fajlove. Preporučena veličina ikone za prikaz u formatu tabele je 32×32 px.
Korak 4. Konfigurišite interfejsne elemente plugin-a
Na primer, draw\.io dodatak sadrži dva glavna UI elementa – modalni prozor i uređivač dijagrama. Kreirajte fajlove za konfiguraciju svakog elementa. Radi praktičnosti, možete smestiti ove fajlove u poseban DrawIO folder.
U Dialog.ts fajlu, konfigurišite podešavanja modalnog prozora. Navedite IFrame UI komponentu koja se koristi za ugradnju draw\.io sajta u modalni prozor:
export const frameProps: IFrame = {
width: "100%",
height: "100%",
name: "test-drawio",
src: "",
}
Kreirajte IBox kontejner kako biste u njega dodali iframe:
const body: IBox = {
widthProp: "100%",
heightProp: "100%",
children: [
{
component: Components.iFrame,
props: frameProps,
},
],
}
Konfigurišite svojstva modalnog prozora:
export const drawIoModalDialogProps: IModalDialog = {
dialogHeader: "",
dialogBody: body,
displayType: ModalDisplayType.modal,
fullScreen: true,
onClose: () => {
const message: IMessage = {
actions: [Actions.closeModal],
}
return message
},
onLoad: async () => {
return {
newDialogHeader: drawIoModalDialogProps.dialogHeader || "",
newDialogBody: drawIoModalDialogProps.dialogBody,
}
},
autoMaxHeight: true,
autoMaxWidth: true,
U Editor.ts fajlu, konfigurišite uređivač dijagrama. Kreirajte funkciju DiagramEditor sa sledećim parametrima:
Parameter | Type | Example | Description |
ui | string | “default” | Definiše UI temu uređivača. |
dark | string | “auto” | Definiše tamnu temu uređivača. |
off | boolean | false | Određuje da li je offline režim aktivan ili ne. |
lib | boolean | false | Određuje da li su biblioteke omogućene ili ne. |
lang | string | “auto” | Definiše jezik uređivača. |
url | string | `https://embed.diagrams.net` | Definiše URL do uređivača. |
showSaveButton | boolean | true | Određuje da li će dugme **Save** biti prikazano u editoru. |
Zatim navedite metode za rad sa dijagramima:
Method | Description |
startEditing | Pokreće uređivač sa datim podacima. |
getData | Vraća podatke dijagrama. |
getTitle | Vraća naslov dijagrama. |
getFormat | Vraća format dijagrama. |
getFrameId | Vraća ID frame-a uređivača. |
getFrameUrl | Vraća URL iframe-a. |
handleMessage | Obradjuje prosleđenu poruku. |
initializeEditor | Šalje *load* poruku uređivaču. |
save | Čuva prosleđene podatke. |
Kompletan kod za *DiagramEditor* možete pronaći ovde
Korak 5. Kreirajte tipove dodataka
Sada kada je podrazumevani dodatak spreman, možete započeti kodiranje drugih tipova dodataka.
Svaki tip dodatka ima specifične stavke dodatka. Definišite stavku kontekst menija koja će biti prikazana kada kliknete desnim tasterom miša na audio ili video fajlove:
export const contextMenuItem: IContextMenuItem = {
key: "speech-to-text-context-menu-item",
label: "Convert to text",
icon: "speech-to-text-16.png",
onClick: assemblyAI.speechToText,
fileType: [FilesType.video],
withActiveItem: true,
}
Možete dodati više tipova dodataka. Na primer, draw\.io dodatak se može otvoriti iz glavnog menija dugmeta, pa je potrebno definisati stavku glavnog dugmeta:
const mainButtonItem: IMainButtonItem = {
key: "draw-io-main-button-item",
label: "Draw.io",
icon: "drawio.png",
onClick: (id: number) => {
drawIo.setCurrentFolderId(id)
const message: IMessage = {
actions: [Actions.showCreateDialogModal],
createDialogProps: {
title: "Create diagram",
startValue: "New diagram",
visible: true,
isCreateDialog: true,
extension: ".drawio",
onSave: async (e: any, value: string) => {
await drawIo.createNewFile(value)
},
onCancel: (e: any) => {
drawIo.setCurrentFolderId(null)
},
onClose: (e: any) => {
drawIo.setCurrentFolderId(null)
},
},
}
return message
},
// items: [createItem],
}
Kada se klikne na stavku glavnog dugmeta, pojavljuje se modalni prozor u kom možete uneti naziv dijagrama i otvoriti prazan .drawio fajl.
Za draw\.io dodatak takođe treba konfigurisati dodatak za fajlove koji funkcioniše kada korisnik otvori određeni .drawio fajl:
Definišite stavku fajla koja se predstavlja kao fajl sa određenim ekstenzijama (.drawio) i ikonom:
export const drawIoItem: IFileItem = {
extension: ".drawio",
fileTypeName: "Diagram",
fileRowIcon: "drawio-32.svg",
fileTileIcon: "drawio-32.svg",
devices: [Devices.desktop],
onClick,
}
Definišite događaj onClick koji će izvršiti metodu editDiagram svaki put kada se otvori .drawio fajl:
const onClick = async (item: File) => {
return await drawIo.editDiagram(item.id)
}
Korak 6. Kreirajte dodatak za podešavanja (settings plugin type)
Konfigurišite tip dodatka za podešavanja kako biste korisnicima omogućili administratorska podešavanja.
Kreirajte kontejner u koji će biti smeštena podešavanja dodatka:
const descriptionText: TextGroup = {
component: Components.text,
props: {
text: "To generate API token visit https://www.assemblyai.com",
color: "#A3A9AE",
fontSize: "12px",
fontWeight: 400,
lineHeight: "16px",
},
}
const descGroup: BoxGroup = {
component: Components.box,
props: {children: [descriptionText]},
}
const parentBox: IBox = {
displayProp: "flex",
flexDirection: "column",
// marginProp: "16px 0 0 0",
children: [tokenGroup, descGroup],
}
U opisu podešavanja naznačite da je potrebno generisati API token kako bi mogli da radite sa plugin-om.
Konfigurišite administratorska podešavanja pomoću ISettings objekta:
const adminSettings: ISettings = {
settings: parentBox,
saveButton: userButtonComponent,
onLoad: async () => {
assemblyAI.fetchAPIToken()
tokenInput.value = assemblyAI.apiToken
if (!assemblyAI.apiToken) {
return {
settings: parentBox,
}
}
plugin.setAdminPluginSettings(adminSettings)
return {settings: parentBox}
}
Navedite onLoad događaj koji definiše koja će podešavanja dodatka biti prikazana kada se učita blok sa podešavanjima.
Svaka stavka podešavanja se određuje u zasebnim fajlovima (dugmad, token).
Korak 7. Kreirajte glavni fajl sa kodom dodatka
Kreirajte fajl u src folderu sa glavnim kodom dodatka. Ovaj fajl je obavezan. Konsultujte se sa dokumentacijom treće strane kako biste napisali ovaj kod.
Pogledajmo detaljno kako je organizovan fajl AssemblyAI.ts:
Definišite AssemblyAI klasu sa svim potrebnim promenljivama i metodama:
- Promenljive i njihov opis:
apiURL
Definiše API URL.
apiURL = ""
currentFileId
Definiše ID trenutnog fajla.
const currentFileId: numbernull | number = null
apiToken
Definiše API token.
apiToken = ""
- Metode i njihov opis:
createAPIUrl
Kreira API URL.
createAPIUrl = () => {
const api = plugin.getAPI()
this.apiURL = api.origin.replace(/\/+$/, "")
const params = [api.proxy, api.prefix]
if (this.apiURL) {
for (const part of params) {
if (!part) {
continue
}
const newPart = part.trim().replace(/^\/+/, "")
if (newPart) {
if (this.apiURL.length !== 0 && this.apiURL[this.apiURL.length - 1] === "/") {
this.apiURL += newPart
} else {
this.apiURL += `/${newPart}`
}
}
}
}
}
setAPIUrl
Postavlja API URL.
setAPIUrl = (url: string) => {
this.apiURL = url
}
getAPIUrl
Vraća API URL.
getAPIUrl = () => {
return this.apiURL
}
setAPIToken
Postavlja API token.
setAPIToken = (apiToken: string) => {
this.apiToken = apiToken
}
getAPIToken
Vraća API token.
getAPIToken = () => {
return this.apiToken
}
fetchAPIToken
Vadi API token.
fetchAPIToken = async () => {
const apiToken = localStorage.getItem("speech-to-text-api-token")
if (!apiToken) {
return
}
this.setAPIToken(apiToken)
plugin.updateStatus(PluginStatus.active)
}
saveAPIToken
Čuva API token.
saveAPIToken = (apiToken: string) => {
localStorage.setItem("speech-to-text-api-token", apiToken)
let status
if (apiToken) {
status = PluginStatus.active
} else {
status = PluginStatus.hide
}
plugin.updateStatus(status)
}
setCurrentFileId
Postavlja ID na trenutnu datoteku.
setCurrentFileId = (id: number | null) => {
this.currentFileId = id
}
uploadFile
Otprema datoteku koja će biti transkribovana.
uploadFile = async (apiToken: string, path: string, data: Blob) => {
console.log(`Uploading file: ${path}`)
const url = "https://api.assemblyai.com/v2/upload"
try {
const response = await fetch(url, {
method: "POST",
body: data,
headers: {
"Content-Type": "application/octet-stream",
"Authorization": apiToken,
},
})
if (response.status === 200) {
const responseData = await response.json()
return responseData["upload_url"]
}
console.error(`Error: ${response.status} - ${response.statusText}`)
return null
} catch (error) {
console.error(`Error: ${error}`)
return null
}
}
transcribeAudio
Transkribuje audio fajl.
transcribeAudio = async (apiToken: string, audioUrl: string) => {
console.log("Transcribing audio... This might take a moment.")
const headers = {
"authorization": apiToken,
"content-type": "application/json",
}
const response = await fetch("https://api.assemblyai.com/v2/transcript", {
method: "POST",
body: JSON.stringify({audioUrl}),
headers,
})
const responseData = await response.json()
const transcriptId = responseData.id
const pollingEndpoint = `https://api.assemblyai.com/v2/transcript/${transcriptId}`
while (true) {
const pollingResponse = await fetch(pollingEndpoint, {headers})
const transcriptionResult = await pollingResponse.json()
if (transcriptionResult.status === "completed") {
return transcriptionResult
} else if (transcriptionResult.status === "error") {
throw new Error(`Transcription failed: ${transcriptionResult.error}`)
} else {
await new Promise((resolve) => {
setTimeout(resolve, 3000)
})
}
}
}
speechToText
Implementira funkcionalnost dodatka.
speechToText = async (id: number) => {
if (!this.apiToken) {
return
}
this.setCurrentFileId(null)
if (!this.apiURL) {
this.createAPIUrl()
}
const response = await fetch(`${this.apiURL}/files/file/${id}`)
const data = await response.json()
const {viewUrl, title, folderId, fileExst} = data.response
const file = await fetch(viewUrl)
const fileBlob = await file.blob()
const uploadUrl = await this.uploadFile(this.apiToken, viewUrl, fileBlob)
const transcript = await this.transcribeAudio(this.apiToken, uploadUrl)
const blob = new Blob([transcript.text], {
type: "text/plain;charset=UTF-8",
})
const newFile = new File([blob], "blob", {
type: "",
lastModified: Date.now(),
})
const formData = new FormData()
formData.append("file", newFile)
const newTitle = `${title.replaceAll(fileExst, "")} text`
try {
const sessionRes = await fetch(
`${this.apiURL}/files/${folderId}/upload/create_session`,
{
method: "POST",
headers: {
"Content-Type": "application/json;charset=utf-8",
},
body: JSON.stringify({
createOn: new Date(),
fileName: `${newTitle}.txt`,
fileSize: newFile.size,
relativePath: "",
}),
},
)
const response = await sessionRes.json()
const sessionData = response.response.data
const data = await fetch(`${sessionData.location}`, {
method: "POST",
body: formData,
})
const jsonData = await data.json()
const {id: fileId} = jsonData.data
return fileId
} catch (e) {
console.log(e)
}
return {
actions: [Actions.showToast],
toastProps: [{type: ToastType.success, title: ""}],
} as IMessage
}
Deklarišite AssemblyAI instancu klase:
const assemblyAI = new AssemblyAI()
Izvezite kreiranu instancu plugin-a:
export default assemblyAI
Testiranje
Da biste proverili funkcionalnost dodatka i otklonili potencijalne greške, testirajte dodatak:
- Izgradite pripremljeni dodatak prateći uputstva ovde
Folder dist će biti kreiran u korenskom folderu dodatka i arhiva dodatka će biti smeštena u njega. Ova arhiva je kompletiran dodatak koji može biti postavljen na DocSpace portal.
- Postavite vaš dodatak na DocSpace portal i detaljno testirajte njegov izgled i funkcionalnost.
Napomena! Imajte na umu da svoje dodatke možete postavljati samo u verziji DocSpace servera.
Ako se pojave bilo kakve greške, ispravite izvorni kod vašeg dodatka i ponovite postupak izgradnje i testiranja.
Kada je vaš dodatak testiran i radi ispravno, možete ga dodati u DocSpace serversku verziju i početi sa korišćenjem.
DocSpace dodatak nudi moćan i korisniku prilagođen pristup upravljanju dokumentima i kolaboraciji. Integracijom sa omiljenim platformama korisnika, uklanja uobičajene prepreke i poboljšava produktivnost u različitim radnim tokovima. Ako imate bilo kakva pitanja o DocSpace dodacima, ne oklevajte da pitate naše programere na ONLYOFFICE forum (registracija neophodna). Takođe možete zatražiti funkcionalnost ili prijaviti grešku objavljivanjem problema na GitHub ili podelite svoje DocSpace dodatke sa nama i drugim korisnicima. Srećno u vašim istraživačkim poduhvatima!
Create your free ONLYOFFICE account
View, edit and collaborate on docs, sheets, slides, forms, and PDF files online.