Olá pessoal! O MySklad Marketplace está no ar. A última vez que falamos sobre como lançamos os aplicativos marketpleys no serviço SaaS MoySklad . Hoje vamos continuar sobre como habilitamos os aplicativos para estender a interface do usuário do serviço. Provavelmente, muitos encontraram em aplicativos de desktop com plug-ins semelhantes, que, quando conectados, adicionam alguns de seus próprios botões, itens de menu e até conjuntos inteiros de novas janelas e diálogos ao aplicativo, e também incorporam seus próprios blocos de IU nas telas existentes . Como você faz isso em um serviço SaaS que tem uma IU do navegador?
Por que incorporar na IU?
No início do Marketplace para aplicativos de uso geral, a única maneira disponível de integrar aplicativos ao MyStore é a integração de dados por meio de uma API JSON comum . Por meio dessa API, o back-end dos aplicativos do fornecedor pode receber e modificar os dados do usuário. Assim, no início, tínhamos apenas a capacidade de integrar back-ends de aplicativos e MyStore entre si. Eles não puderam adicionar um botão ou widget ao formulário de edição do aplicativo.
Inicialmente, era óbvio que isso não era suficiente para fornecer aos usuários finais a melhor experiência de aplicativo possível. Por outro lado, os desenvolvedores e integradores externos tiveram que coletar seus mecanismos na IU - eles tinham a opção de incorporar diretamente nos aplicativos da web HTML do MyStore por meio de plug-ins de navegador ou criar interfaces (IU) separadas em seu lado, em grande parte duplicando a funcionalidade das telas em MyStore (por exemplo, listas de documentos com filtros).
, — , ( ). — , , . , () , .
, , UI- — must have , .
— — iframe . , , . .
UI- -.
.
, , SaaS-.
. UI, .
:
:
,
:
. . , , ( ) UI ( ) (UX).
. . , , , “” .
/ . , UI — SPA, : DOM- , UI — . , .
?
SaaS- (Jira, Salesforce, Zendesk) (amoCRM, 24, InSales). .
:
: SPA - ?
- (- , iframe ), , SDK ( UI)?
, ?
. , / .
. , .
, SPA- “” SPA (“” — , , UI SPA, - — ). UI — SPA.
iframe’. :
iframe , ( , — ). sandbox iframe’a
allow-same-origin
, DOM - . - , , JavaScript-. ().
iframe (
allow-same-origin
) — , DOM- - . . - postMessage, , , , JavaScript- - . , postMessage JS SDK — JavaScript-.
JS SDK. JS SDK API , API “” postMessage JavaScript-.
amoCRM, DOM- -. , , , — , UI. , . , , , - .
(, ) — JSON- (). XML — XML- ( JSON-). XML JSON’a — .
XML-
, , :
<ServerApplication xmlns="https://online.moysklad.ru/xml/ns/appstore/app/v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://online.moysklad.ru/xml/ns/appstore/app/v2
https://online.moysklad.ru/xml/ns/appstore/app/v2/application-v2.xsd">
<iframe>
<sourceUrl>https://example.com/iframe.html</sourceUrl>
<expand>true</expand>
</iframe>
<vendorApi>
<endpointBase>https://example.com/dummy-app</endpointBase>
</vendorApi>
<access>
<resource>https://online.moysklad.ru/api/remap/1.2</resource>
<scope>admin</scope>
</access>
<widgets>
<entity.counterparty.edit>
<sourceUrl>https://example.com/widget.php</sourceUrl>
<height>
<fixed>150px</fixed>
</height>
<supports>
<open-feedback/>
<save-handler/>
</supports>
<uses>
<good-folder-selector/>
</uses>
</entity.counterparty.edit>
</widgets>
<popups>
<popup>
<name>somePopup</name>
<sourceUrl>https://example.com/popup.php</sourceUrl>
</popup>
<popup>
<name>somePopup2</name>
<sourceUrl>https://example.com/popup-2.php</sourceUrl>
</popup>
</popups>
</ServerApplication>
, XML, JSON? , XML — XML Schema. JSON — , JSON Schema. JSON- ( XML-) , , IDE. , JSON- . , XML- . JSON-, , XML JSON , XML- .
? :
, . , , , - . — .
code completion IDE “ ” UI . - ( ), .
, , Intellij IDEA , :
IDE open-feedback ( - ):
:
.
XML-
( ) . , ( ) . — . , . , . . . .
. , . , — , , , , , , - . , , - , . .
, XML-:
<widgets>
<some.extension.point1>...</some.extension.point1>
<some.extension.point2>...</some.extension.point2>
</widgets>
, , :
<widgets>
<widget location="some.extension.point1">...</widget>
<widget location="some.extension.point2">...</widget>
</widgets>
XML- (“”) . - “” — . , XML-, XML-.
? , , ?
:
<document.customerorder.edit>
<sourceUrl>https://example.com/widget.php</sourceUrl>
<height>
<fixed>150px</fixed>
</height>
<supports>...</supports>
<uses>...</uses>
</document.customerorder.edit>
sourceUrl
height
. sourceUrl
iframe, height
( , — , , UI).
( ) - (, , ), , <height><dynamic/></height>
. — . , , <dynamic/>
, .
supports
uses
. .
( API , ):
:
<document.customerorder.edit>
<sourceUrl>https://example.com/widget.php</sourceUrl>
<height>
<fixed>150px</fixed>
</height>
<supports>
<open-feedback/>
<save-handler/>
<change-handler>
<expand>agent</expand>
<expand>positions.assortment</expand>
</change-handler>
</supports>
<uses>
<good-folder-selector/>
</uses>
</document.customerorder.edit>
.
— , UI , . , HTTP postMesssage. .
.
— , / ( ). . , sourceUrl
height
, iframe HTTP - postMessage- Open
.
DOM- :
Open
:
{
"name": "Open",
"messageId": 12345,
"extensionPoint": "entity.counterparty.edit",
"objectId": "8e9512f3-111b-11ea-0a80-02a2000a3c9c",
"displayMode": "expanded"
}
— ( ) , . supports
( ). .
supports
. .
pen-feedback
( ) — , , , OpenFeedback
. , . - , .
:
OpenFeedback
:
{
"name": "OpenFeedback",
"correlationId": 12345
}
save-handler
( ) — , - “” Save
.
Save
:
{
"name": "Save",
"messageId": 32109,
"extensionPoint": "entity.counterparty.edit",
"objectId": "8e9512f3-111b-11ea-0a80-02a2000a3c9c"
}
hange-handler
( ) — , , , ( ). , change-handler
, - “” — - (, ) - Change
JSON . expand
, JSON API ( change-handler
expand
).
— , - . . uses ( ). , -> - -.
— good-folder-selector
. . :
1. - SelectGoodFolderRequest
(, - ):
{
"name": "SelectGoodFolderRequest",
"messageId": 12345
}
2. - :
3. - SelectGoodFolderResponse
:
{
"name": "SelectGoodFolderResponse",
"correlationId": 12345,
"selected": true,
"goodFolderId": "8e9512f3-111b-11ea-0a80-02a2000a3c9c"
}
:
, .
XML- , ( ).
/ , . : , , - , , , .
, -. , change-handler, - , ( SPA- ).
(, - Init postMessage, iframe. , , ( ), (, ). , , — , - , ( ). , .
?
?
. - , . - . . iframe, . postMessage- -. .
change-handler
. — update
, -.
:
“” postMessage JavaScript/TypeScript Widget SDK
UI- ( ) — , :
,
UI
RESP API Widget SDK
UI — SaaS- , .
— email- , , .