CĂłmo hicimos el soporte de widgets para aplicaciones en MyStore

¡Hola a todos! MySklad Marketplace está al aire. La última vez hablamos sobre cómo lanzamos aplicaciones de marketpleys en el servicio SaaS MoySklad . Hoy continuaremos sobre cómo permitimos que las aplicaciones amplíen la interfaz de usuario del servicio. Probablemente, muchos se han encontrado en aplicaciones de escritorio con complementos similares que, cuando se conectan, agregan algunos de sus propios botones, elementos de menú e incluso conjuntos completos de nuevas ventanas y cuadros de diálogo a la aplicación, y también incrustan sus propios bloques de IU en las pantallas existentes. . ¿Cómo se hace esto en un servicio SaaS que tiene una interfaz de usuario de navegador?





¿Por qué incrustar en la interfaz de usuario?

Al comienzo del Marketplace para aplicaciones de uso general, la única forma disponible de integrar aplicaciones con MyStore es la integración de datos a través de una API JSON común . A través de esta API, el backend de las aplicaciones de los proveedores puede recibir y modificar los datos del usuario. Por lo tanto, al principio, solo teníamos la capacidad de integrar backends de aplicaciones y MyStore entre sí. No pudieron agregar un botón o widget al formulario de edición de la aplicación.





Inicialmente, era obvio que esto no era suficiente para brindar a los usuarios finales la mejor experiencia de aplicación posible. Por otro lado, los desarrolladores e integradores externos tenían que agrupar sus mecanismos en la interfaz de usuario: tenían la opción de integrar directamente en las aplicaciones web HTML de MyStore a través de complementos del navegador o crear interfaces separadas (UI) de su lado, en gran parte duplicar la funcionalidad de las pantallas en MyStore (por ejemplo, listas de documentos con filtros).





, — , ( ). — , , . , () , .





, , UI- — must have , .





— — iframe . , , . . 





UI- -.





.

, , SaaS-.





. UI, .





:





:













  1. ,









:





  • . . , , ( ) UI ( ) (UX).





  • . . , , , “” .





  • / . , UI — SPA, : DOM- , UI — . , .





?

SaaS- (Jira, Salesforce, Zendesk) (amoCRM, 24, InSales). .





:





  1. : SPA - ?





  2. - (- , iframe ), , SDK ( UI)?





  3. , ?





  4. . , / .





. , .





, SPA- “” SPA (“” — , , UI SPA, - — ). UI — SPA. 





iframe’. :





  1. iframe , ( , — ). sandbox iframe’a allow-same-origin



    , DOM - . - , , JavaScript-. ().





  2. 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- .





? :





  1. , . , , , - . — .





  2. 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"
}
      
      



:





  1. , .





  2. XML- , ( ). 





  3. / , . : , , - , , , .





  4. , -. , 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- , , .





SaaS- — — , .








All Articles