{"id":303323,"date":"2020-05-10T15:00:30","date_gmt":"2020-05-10T15:00:30","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=303323"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=303323","title":{"rendered":"React \u0438 Atlaskit \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0438 \u0434\u0430\u0442\u0430\u0446\u0435\u043d\u0442\u0440\u043e\u0432\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445 Atlassian"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/501300\/\">\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!<br \/>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React \u0438 Atlaskit \u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445 Atlassian \u0432 Server \u0438 Data Center \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0445.<br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u0412 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f, \u0435\u0441\u043b\u0438 \u0412\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 Atlassian \u0434\u043b\u044f Server \u0438 Data Center, \u0442\u043e \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0412\u0430\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b <a href=\"https:\/\/velocity.apache.org\/engine\/1.7\/user-guide.html\" rel=\"nofollow\">vm<\/a>, <a href=\"https:\/\/developer.atlassian.com\/server\/jira\/platform\/using-soy-templates\/\" rel=\"nofollow\">soy<\/a>, <a href=\"https:\/\/requirejs.org\/\" rel=\"nofollow\">requirejs<\/a>, <a href=\"https:\/\/jquery.com\/\" rel=\"nofollow\">jquery<\/a>, <a href=\"https:\/\/backbonejs.org\/\" rel=\"nofollow\">backbone<\/a>. \u0412\u043e\u0442 <a href=\"https:\/\/habr.com\/en\/company\/raiffeisenbank\/blog\/415809\/\">\u0442\u0443\u0442 <\/a>\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043c\u043e\u044e \u0441\u0442\u0430\u0442\u044c\u044e, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438.<br \/>  \u042d\u0442\u043e\u0442 \u0441\u0442\u0435\u043a \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0439 \u0443\u0441\u0442\u0430\u0440\u0435\u043b \u0438 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u043c-\u0442\u043e \u043f\u043e \u043d\u043e\u0432\u0435\u0435. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0442\u0435\u043a\u0430 \u044f \u0432\u044b\u0431\u0440\u0430\u043b <a href=\"https:\/\/www.typescriptlang.org\/\" rel=\"nofollow\">typescript<\/a> \u0438 <a href=\"https:\/\/reactjs.org\/\" rel=\"nofollow\">react<\/a>. \u0422\u0430\u043a \u0436\u0435 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u043d\u0430 \u043a\u043b\u0430\u0443\u0434, \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <a href=\"https:\/\/atlaskit.atlassian.com\/\" rel=\"nofollow\">atlaskit<\/a>.<br \/>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043f\u0440\u043e Atlassian Jira, \u043d\u043e \u044d\u0442\u043e\u0442 \u0436\u0435 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0438 \u0434\u0430\u0442\u0430\u0446\u0435\u043d\u0442\u0440\u043e\u0432\u044b\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 Atlassian.<br \/>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c <a href=\"https:\/\/git-scm.com\/\" rel=\"nofollow\">git<\/a> \u0438 <a href=\"https:\/\/developer.atlassian.com\/server\/framework\/atlassian-sdk\/set-up-the-atlassian-plugin-sdk-and-build-a-project\/\" rel=\"nofollow\">Atlassian SDK<\/a>.<br \/>  \u0418\u0442\u0430\u043a, \u043d\u0430\u0447\u043d\u0435\u043c!<\/p>\n<h2>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c Maven \u0430\u0440\u0445\u0435\u0442\u0438\u043f \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<\/h2>\n<p>  \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0430\u0440\u0445\u0435\u0442\u0438\u043f Maven \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0441 React \u0438 Atlaskit.<br \/>  \u0415\u0441\u043b\u0438 \u0412\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0430\u0440\u0445\u0435\u0442\u0438\u043f\u043e\u043c, \u0442\u043e \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0437\u044f\u0442\u044c \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 <a href=\"https:\/\/bitbucket.org\/alex1mmm\/jira-react-atlaskit\/src\/master\/\" rel=\"nofollow\">\u043f\u043b\u0430\u0433\u0438\u043d<\/a> \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0430\u0440\u0445\u0435\u0442\u0438\u043f\u0430 \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0447\u0430\u0441\u0442\u0438 \u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442.<br \/>  \u0421\u043a\u043b\u043e\u043d\u0438\u0440\u0443\u0439\u0442\u0435 \u0430\u0440\u0445\u0435\u0442\u0438\u043f \u0438\u0437 \u043c\u043e\u0435\u0433\u043e Bitbucket \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f:<\/p>\n<p>  <code>git clone https:\/\/alex1mmm@bitbucket.org\/alex1mmm\/jira-react-atlaskit-archetype.git --branch v1 --single-branch<\/code><\/p>\n<p>  \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 jira-react-atlaskit-archetype folder \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u044d\u0442\u043e\u0442 \u0430\u0440\u0445\u0435\u0442\u0438\u043f \u0432 \u0412\u0430\u0448 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Maven:<\/p>\n<p>  <code>cd jira-react-atlaskit-archetype<br \/>  atlas-mvn install<\/code><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u043f\u0430\u043f\u043a\u0443 \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0448\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0438 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0433\u043e \u0430\u0440\u0445\u0435\u0442\u0438\u043f\u0430:<\/p>\n<p>  <code>cd ..<br \/>  atlas-mvn archetype:generate -DarchetypeCatalog=local<\/code><\/p>\n<p>  \u0411\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u043d \u0432\u043e\u043f\u0440\u043e\u0441, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0430\u0440\u0445\u0435\u0442\u0438\u043f. \u0412\u043e\u0442 \u043c\u043e\u0438 \u0430\u0440\u0445\u0435\u0442\u0438\u043f\u044b \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438:<\/p>\n<p>  <code>1: local -&gt; com.cprime.jira.sil.extension:sil-extension-archetype (This is the com.cprime.jira.sil.extension:sil-extension plugin for Atlassian JIRA.)<br \/>  2: local -&gt; ru.matveev.alexey.sil.extension:sil-extension-archetype (This is the ru.matveev.alexey.sil.extension:sil-extension plugin for Atlassian JIRA.)<br \/>  3: local -&gt; ru.matveev.alexey.atlas.jira:jira-react-atlaskit-archetype-archetype (jira-react-atlaskit-archetype-archetype)<\/code><\/p>\n<p>  \u041d\u0443\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c ru.matveev.alexey.atlas.jira:jira-react-atlaskit-archetype-archetype, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0443\u043a\u0430\u0437\u0430\u043b \u0446\u0438\u0444\u0440\u0443 3 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430.<br \/>  \u0417\u0430\u0442\u0435\u043c \u0412\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c groupid \u0438 artifactid \u0434\u043b\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<p>  <code>Define value for property 'groupId': react.atlaskit.tutorial<br \/>  Define value for property 'artifactId': my-tutorial<br \/>  Define value for property 'version' 1.0-SNAPSHOT: : <br \/>  Define value for property 'package' react.atlaskit.tutorial: : <br \/>  Confirm properties configuration:<br \/>  groupId: react.atlaskit.tutorial<br \/>  artifactId: my-tutorial<br \/>  version: 1.0-SNAPSHOT<br \/>  package: react.atlaskit.tutorial<br \/>   Y: : Y<\/code><\/p>\n<h2>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442<\/h2>\n<p>  \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 my-tutorial. \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u044d\u0442\u0443 \u043f\u0430\u043f\u043a\u0443 \u0438 \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442:<\/p>\n<p>  <code>cd my-tutorial<br \/>  atlas-mvn package<\/code><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0431\u0435\u0440\u0435\u0442\u0441\u044f, \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 backend \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c Atlassian Jira:<\/p>\n<p>  <code>cd backend<br \/>  atlas-run<br \/>  <\/code><\/p>\n<h2>\u041f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u043b\u0430\u0433\u0438\u043d<\/h2>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a Atlassian Jira \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430\u0441\u044c, \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443:<\/p>\n<p>  <code>http:\/\/localhost:2990\/jira<\/code><\/p>\n<p>  \u0412\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u043f\u043e\u0434 admin:admin \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0448\u0435\u0441\u0442\u0435\u0440\u0435\u043d\u043a\u0430 -&gt; Manage apps.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/od\/4n\/z2\/od4nz2n9hca1cp0b1gbvv5ktjom.png\"><\/p>\n<p>  \u0412\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u043c\u0435\u043d\u044e \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430. \u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435, \u0447\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0448\u0438 Atlaskit \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 System -&gt; Logging and Profiling \u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f INFO \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u0430 react.atlaskit.tutorial.servlet. <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/zn\/dc\/yf\/zndcyfhhjekpbuccysgmfgxff_e.png\"><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 Manage apps \u0438 \u043d\u0430\u0436\u043c\u0435\u043c \u043d\u0430 \u043c\u0435\u043d\u044e Form. \u041c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b\u043b\u0430 \u0432\u044b\u0432\u0435\u0434\u0435\u043d\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 Atlaskit <a href=\"https:\/\/atlaskit.atlassian.com\/packages\/design-system\/form\" rel=\"nofollow\">Form<\/a>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/fd\/c0\/ul\/fdc0ulhllmuroookwgrk7t34yak.png\"><\/p>\n<p>  \u0417\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0432\u0441\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0438 \u043d\u0430\u0436\u043c\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Submit:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/x3\/6m\/xy\/x36mxydhqf6knri6sexleuahmyc.png\"><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u0412\u044b \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0435 \u0444\u0430\u0439\u043b atlassian-jira.log, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e:<\/p>\n<p>  <code>2020-05-10 08:44:29,701+0300 http-nio-2990-exec-4 INFO admin 524x12509x1 15awhw2 0:0:0:0:0:0:0:1 \/plugins\/servlet\/form [r.a.tutorial.servlet.FormServlet] Post Data: {&quot;firstname&quot;:&quot;Alexey&quot;,&quot;lastname&quot;:&quot;Matveev&quot;,&quot;description&quot;:&quot;No description&quot;,&quot;comments&quot;:&quot;and no comments&quot;}<\/code><\/p>\n<p>  \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 Submit, \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0432 \u0441\u0435\u0440\u0432\u043b\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u044d\u0442\u0443 \u0444\u043e\u0440\u043c\u0443, \u0438 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u043b\u0435\u0442 \u0432\u044b\u0432\u0435\u043b \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043b\u043e\u0433 \u0444\u0430\u0439\u043b.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u043c\u0435\u043d\u044e Dynamic Table. \u0412\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 Atlaskit <a href=\"https:\/\/atlaskit.atlassian.com\/packages\/design-system\/dynamic-table\" rel=\"nofollow\">Dynamic Table<\/a>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/nl\/aa\/in\/nlaainlpuoizl1dkq-fo7nethfu.png\"><\/p>\n<p>  \u042d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043d\u0430\u0448 \u043f\u043b\u0430\u0433\u0438\u043d. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/p>\n<h2>\u041f\u043b\u0430\u0433\u0438\u043d \u0438\u0437\u043d\u0443\u0442\u0440\u0438<\/h2>\n<p>  \u0412\u043e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/he\/kv\/cf\/hekvcfmty8kt8p-w6pjviofofma.png\"><\/p>\n<p>  backend \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043b\u0430\u0433\u0438\u043d Atlassian Jira, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Atlassian SDK.<br \/>  frontend \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 UI \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u043d\u0430\u0448\u0438\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u043c.<br \/>  pom.xml pom \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0434\u0432\u0430 \u043c\u043e\u0434\u0443\u043b\u044f:<\/p>\n<pre><code class=\"xml\">    &lt;modules&gt;           &lt;module&gt;frontend&lt;\/module&gt;         &lt;module&gt;backend&lt;\/module&gt;     &lt;\/modules&gt;<\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043f\u0430\u043f\u043a\u0443 fronted.<\/p>\n<h2>Frontend<\/h2>\n<p>  \u041f\u0430\u043f\u043a\u0430 frontend \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u0439\u043b\u044b:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/km\/ob\/2b\/kmob2bbfvpb2bq19tyut0r0vksc.png\"><\/p>\n<p>  \u041e\u043f\u0438\u0448\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b.<br \/>  package.json \u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f <a href=\"https:\/\/www.npmjs.com\/\" rel=\"nofollow\">npm<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e:<\/p>\n<ul>\n<li>\u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442.<\/li>\n<li>\u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c.<\/li>\n<\/ul>\n<p>  \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u044b, \u043a\u0430\u043a typescript, atlaskit, babel \u0438 \u0434\u0440\u0443\u0433\u0438\u0435.<\/p>\n<p>  .babel.rc \u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f <a href=\"https:\/\/babeljs.io\/docs\/en\/\" rel=\"nofollow\">Babel<\/a>. Babel \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u043a\u043e\u0434 \u043d\u0430 ECMAScript 2015+ \u0432 JavaScript \u043a\u043e\u0434. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434 \u043d\u0430\u00a0Typescript, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043a\u043e\u0434 JavaScript, \u0447\u0442\u043e\u0431\u044b \u043f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f Jira \u0441\u043c\u043e\u0433 \u0441 \u043d\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  webpack.config.js \u2014 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0434\u043b\u044f <a href=\"https:\/\/webpack.js.org\/\" rel=\"nofollow\">webpack<\/a>. Webpack \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0441\u0442\u0440\u043e\u0438\u0442 \u0433\u0440\u0430\u0444 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0442 \u0431\u0430\u043d\u0434\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0435\u0441\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 JavaScript \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b Jira \u043f\u043b\u0430\u0433\u0438\u043d \u0441\u043c\u043e\u0433 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0430\u0448\u0438\u043c JavaScript, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b Javascript \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u044d\u0442\u043e \u043f\u0443\u043d\u043a\u0442\u044b \u043c\u0435\u043d\u044e Form \u0438 Dynamic Table. <br \/>  \u0412\u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 webpack.config.js:<\/p>\n<pre><code class=\"xml\">const WrmPlugin = require('atlassian-webresource-webpack-plugin'); var path = require('path');module.exports = {     module: {         rules: &#91;           {             test: \/\\.(js|jsx)$\/,             exclude: \/node_modules\/,             use: {                 loader: &quot;babel-loader&quot;             }           }         ]     },     entry: {             'form': '.\/src\/form.js',             'dynamictable': '.\/src\/dynamictable.js'     },      plugins: &#91;         new WrmPlugin({             pluginKey: 'ru.matveev.alexey.atlas.jira.jira-react-atlaskit',             locationPrefix: 'frontend\/',             xmlDescriptors: path.resolve('..\/backend\/src\/main\/resources', 'META-INF', 'plugin-descriptors', 'wr-defs.xml')         }),     ],     output: {         filename: 'bundled.&#91;name].js',         path: path.resolve(&quot;.\/dist&quot;)     } }; <\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0412\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <a href=\"https:\/\/www.npmjs.com\/package\/atlassian-webresource-webpack-plugin\" rel=\"nofollow\">atlassian-webresource-webpack-plugin<\/a>.<br \/>  \u041e\u043d \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a webpack \u0441\u043e\u0437\u0434\u0430\u043b JavaScript \u0444\u0430\u0439\u043b, \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0441\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u0430:<\/p>\n<pre><code class=\"xml\">plugins: &#91;         new WrmPlugin({             pluginKey: 'ru.matveev.alexey.atlas.jira.jira-react-atlaskit',             locationPrefix: 'frontend\/',             xmlDescriptors: path.resolve('..\/backend\/src\/main\/resources', 'META-INF', 'plugin-descriptors', 'wr-defs.xml')         }),     ],<\/code><\/pre>\n<p>  \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u043e\u0434\u0443\u043b\u044f frontend \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u0444\u0430\u0439\u043b wr-defs.xml \u0432 \u043f\u0430\u043f\u043a\u0435 backend\/src\/resources\/META-INF\/plugin-descriptors.<br \/>  \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 locationPrefix \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 JavaScript \u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u0435 Jira. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043f\u0430\u043f\u043a\u0435 backend\/src\/resources\/frontend. \u041c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0444\u0430\u0439\u043b\u044b JavaScript \u0432 \u044d\u0442\u0443 \u043f\u0430\u043f\u043a\u0443 \u043f\u043e\u0437\u0436\u0435 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 backend, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043d\u0430\u043c \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 \u0444\u0430\u0439\u043b\u0435 wr-defs.xml &lt;resource type=\u00abdownload\u00bb name=\u00abbundled.dynamictable.js\u00bb <strong>location=\u00abfrontend\/bundled.dynamictable.js\u00bb<\/strong>\/&gt;. <br \/>  \u0412\u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 wr-defs.xml file, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"xml\">&lt;bundles&gt;   &lt;web-resource key=&quot;entrypoint-form&quot;&gt;     &lt;transformation extension=&quot;js&quot;&gt;       &lt;transformer key=&quot;jsI18n&quot;\/&gt;     &lt;\/transformation&gt;     &lt;context&gt;form&lt;\/context&gt;     &lt;dependency&gt;com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path&lt;\/dependency&gt;     &lt;resource type=&quot;download&quot; name=&quot;bundled.form.js&quot; location=&quot;frontend\/bundled.form.js&quot;\/&gt;   &lt;\/web-resource&gt;   &lt;web-resource key=&quot;entrypoint-dynamictable&quot;&gt;     &lt;transformation extension=&quot;js&quot;&gt;       &lt;transformer key=&quot;jsI18n&quot;\/&gt;     &lt;\/transformation&gt;     &lt;context&gt;dynamictable&lt;\/context&gt;     &lt;dependency&gt;com.atlassian.plugins.atlassian-plugins-webresource-plugin:context-path&lt;\/dependency&gt;     &lt;resource type=&quot;download&quot; name=&quot;bundled.dynamictable.js&quot; location=&quot;frontend\/bundled.dynamictable.js&quot;\/&gt;   &lt;\/web-resource&gt;   &lt;web-resource key=&quot;assets-632cdd38-e80f-4a5a-ba4c-07ba7cb36e60&quot;&gt;     &lt;transformation extension=&quot;js&quot;&gt;       &lt;transformer key=&quot;jsI18n&quot;\/&gt;     &lt;\/transformation&gt;     &lt;transformation extension=&quot;soy&quot;&gt;       &lt;transformer key=&quot;soyTransformer&quot;\/&gt;       &lt;transformer key=&quot;jsI18n&quot;\/&gt;     &lt;\/transformation&gt;     &lt;transformation extension=&quot;less&quot;&gt;       &lt;transformer key=&quot;lessTransformer&quot;\/&gt;     &lt;\/transformation&gt;   &lt;\/web-resource&gt; &lt;\/bundles&gt;<\/code><\/pre>\n<p>  \u041a\u0430\u043a \u0412\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0435\u043a\u0446\u0438\u0438 \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b JavaScript \u0444\u0430\u0439\u043b\u044b, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0435 webpack. \u0412\u0441\u0435 \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c, \u044d\u0442\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c Jira, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0435\u0449\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0438 \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 backend\/src\/resources\/META-INF\/plugin-descriptor. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0432\u043d\u0435\u0441\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b backend\/pom.xml:<\/p>\n<pre><code class=\"xml\">&lt;plugin&gt;                 &lt;groupId&gt;com.atlassian.maven.plugins&lt;\/groupId&gt;                 &lt;artifactId&gt;jira-maven-plugin&lt;\/artifactId&gt;                 &lt;version&gt;${amps.version}&lt;\/version&gt;                 &lt;extensions&gt;true&lt;\/extensions&gt;                 &lt;configuration&gt;                     &lt;productVersion&gt;${jira.version}&lt;\/productVersion&gt;                     &lt;productDataVersion&gt;${jira.version}&lt;\/productDataVersion&gt;                     &lt;compressResources&gt;false&lt;\/compressResources&gt;                     &lt;enableQuickReload&gt;true&lt;\/enableQuickReload&gt;                     &lt;instructions&gt;                         &lt;Atlassian-Plugin-Key&gt;${atlassian.plugin.key}&lt;\/Atlassian-Plugin-Key&gt;                         &lt;Export-Package&gt;&lt;\/Export-Package&gt;                         &lt;Import-Package&gt;org.springframework.osgi.*;resolution:=&quot;optional&quot;, org.eclipse.gemini.blueprint.*;resolution:=&quot;optional&quot;, *&lt;\/Import-Package&gt;                         &lt;!-- Ensure plugin is spring powered --&gt;                         &lt;Spring-Context&gt;*&lt;\/Spring-Context&gt;                         &lt;Atlassian-Scan-Folders&gt;META-INF\/plugin-descriptors&lt;\/Atlassian-Scan-Folders&gt;                     &lt;\/instructions&gt;                 &lt;\/configuration&gt;             &lt;\/plugin&gt;<\/code><\/pre>\n<p>  \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 &lt;Atlassian-Scan-Folders&gt;META-INF\/plugin-descriptors&lt;\/Atlassian-Scan-Folders&gt;. \u042d\u0442\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u0441\u043a\u0430\u0436\u0435\u0442 Jira, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043f\u0430\u043f\u043a\u0435 META-INF\/plugin-descriptors.<br \/>  \u0415\u0449\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 &lt;compressResources&gt;false&lt;\/compressResources&gt; \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043c\u0438\u043d\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043d\u0430\u0448\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 JavaScript. \u041e\u043d\u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u0438 \u043c\u0438\u043d\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b.<br \/>  \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430 \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435 webpack.config.js:<\/p>\n<pre><code class=\"javascript\"> entry: {             'form': '.\/src\/form.js',             'dynamictable': '.\/src\/dynamictable.js'     },<\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e webpack \u043f\u0440\u043e\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0444\u0430\u0439\u043b\u044b .\/src\/form.js \u0438 .\/src\/dynamictable.js \u0438 \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 JavaScript, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u043e \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0442\u043e\u0447\u0435\u043a \u0432\u0445\u043e\u0434\u0430. \u042d\u0442\u0438 \u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0432 \u043f\u0430\u043f\u043a\u0435 frontend\/dist.<br \/>  .\/src\/form.js \u0438 .\/src\/dynamictable.js \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0433\u043e. \u0411\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u044f \u0432\u0437\u044f\u043b \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432 Atlaskit.<br \/>  \u0412\u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 form.js:<\/p>\n<pre><code class=\"javascript\">import Form from &quot;.\/js\/components\/Form&quot;;<\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u043e\u0434\u043d\u0430 \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 .\/js\/components\/Form.js. <br \/>  \u0412\u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 .\/js\/components\/Form.js<\/p>\n<pre><code class=\"javascript\">import React, { Component } from 'react'; import ReactDOM from &quot;react-dom&quot;; import Button from '@atlaskit\/button'; import TextArea from '@atlaskit\/textarea'; import TextField from '@atlaskit\/textfield'; import axios from 'axios';  import Form, { Field, FormFooter } from '@atlaskit\/form';  export default class MyForm extends Component {   render() {   return (   &lt;div     style={{       display: 'flex',       width: '400px',       margin: '0 auto',       flexDirection: 'column',     }}   &gt;     &lt;Form onSubmit={data =&gt; axios.post(document.getElementById(&quot;contextPath&quot;).value + &quot;\/plugins\/servlet\/form&quot;, data)}&gt;       {({ formProps }) =&gt; (         &lt;form {...formProps} name=&quot;text-fields&quot;&gt;           &lt;Field name=&quot;firstname&quot; defaultValue=&quot;&quot; label=&quot;First name&quot; isRequired&gt;             {({ fieldProps }) =&gt; &lt;TextField {...fieldProps} \/&gt;}           &lt;\/Field&gt;            &lt;Field name=&quot;lastname&quot; defaultValue=&quot;&quot; label=&quot;Last name&quot; isRequired&gt;             {({ fieldProps: { isRequired, isDisabled, ...others } }) =&gt; (               &lt;TextField                 disabled={isDisabled}                 required={isRequired}                 {...others}               \/&gt;             )}           &lt;\/Field&gt;           &lt;Field             name=&quot;description&quot;             defaultValue=&quot;&quot;             label=&quot;Description&quot;           &gt;             {({ fieldProps }) =&gt; &lt;TextArea {...fieldProps} \/&gt;}           &lt;\/Field&gt;            &lt;Field             name=&quot;comments&quot;             defaultValue=&quot;&quot;             label=&quot;Additional comments&quot;           &gt;             {({ fieldProps }) =&gt; &lt;TextArea {...fieldProps} \/&gt;}           &lt;\/Field&gt;           &lt;FormFooter&gt;             &lt;Button type=&quot;submit&quot; appearance=&quot;primary&quot;&gt;               Submit             &lt;\/Button&gt;           &lt;\/FormFooter&gt;         &lt;\/form&gt;       )}     &lt;\/Form&gt;   &lt;\/div&gt; ); } } window.addEventListener('load', function() {     const wrapper = document.getElementById(&quot;container&quot;);     wrapper ? ReactDOM.render(&lt;MyForm \/&gt;, wrapper) : false; });&lt;\/code&gt;&lt;\/pre&gt; &lt;!-- \/wp:code --&gt;\u0412\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0437\u044f\u0442\u044b \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u0440\u043e\u043c\u0435 \u0432\u043e\u0442 \u044d\u0442\u0438\u0445:&lt;!-- wp:code --&gt; &lt;pre class=&quot;wp-block-code&quot;&gt;&lt;code&gt;window.addEventListener('load', function() {     const wrapper = document.getElementById(&quot;container&quot;);     wrapper ? ReactDOM.render(&lt;MyForm \/&gt;, wrapper) : false; });<\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 MyForm \u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0435 div. \u042d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0432 soy \u0448\u0430\u0431\u043b\u043e\u043d\u0435 Jira \u043f\u043b\u0430\u0433\u0438\u043d\u0430.<br \/>  \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0432\u043e\u0442 \u043d\u0430 \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"javascript\">onSubmit={data =&gt; axios.post(document.getElementById(&quot;contextPath&quot;).value + &quot;\/plugins\/servlet\/form&quot;, data)}<\/code><\/pre>\n<p>  document.getElementById(\u00abcontextPath\u00bb).value \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f \u0441 id contextPath. \u042f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u0432 soy \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u0432 Jira \u043f\u043b\u0430\u0433\u0438\u043d\u0435. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u044d\u0442\u043e \u043f\u043e\u043b\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u0430, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d \u043f\u0443\u043d\u043a\u0442 \u043c\u0435\u043d\u044e Form. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 contextPath \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \/jira, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Jira \u0438\u0437 Atlassian SDK \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043f\u0443\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430.<br \/>  \u0418 \u044d\u0442\u043e \u0432\u0441\u0435 \u043f\u0440\u043e frontend. \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u043e\u0434\u0443\u043b\u044f frontend \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 JavaScript \u0432 \u043f\u0430\u043f\u043a\u0435 frontend\/dist \u0438 xml \u0441 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 \u0432 \u043f\u0430\u043f\u043a\u0435 backend\/src\/resources\/META-INF\/plugin-descriptors.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0431\u044d\u043a\u0435\u043d\u0434\u0443.<\/p>\n<h2>Backend<\/h2>\n<p>  \u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u0444\u0430\u0439\u043b backend\/pom.xml: <\/p>\n<pre><code class=\"xml\">&lt;plugin&gt;                 &lt;groupId&gt;org.codehaus.mojo&lt;\/groupId&gt;                 &lt;artifactId&gt;properties-maven-plugin&lt;\/artifactId&gt;                 &lt;version&gt;1.0.0&lt;\/version&gt;                 &lt;executions&gt;                     &lt;execution&gt;                         &lt;phase&gt;generate-resources&lt;\/phase&gt;                         &lt;goals&gt;                             &lt;goal&gt;write-project-properties&lt;\/goal&gt;                         &lt;\/goals&gt;                         &lt;configuration&gt;                             &lt;outputFile&gt;${project.build.outputDirectory}\/maven.properties&lt;\/outputFile&gt;                         &lt;\/configuration&gt;                     &lt;\/execution&gt;                 &lt;\/executions&gt;             &lt;\/plugin&gt;             &lt;plugin&gt;                 &lt;artifactId&gt;maven-resources-plugin&lt;\/artifactId&gt;                 &lt;version&gt;3.1.0&lt;\/version&gt;                 &lt;executions&gt;                     &lt;execution&gt;                         &lt;id&gt;copy frontend files to resources&lt;\/id&gt;                         &lt;phase&gt;generate-resources&lt;\/phase&gt;                         &lt;goals&gt;                             &lt;goal&gt;copy-resources&lt;\/goal&gt;                         &lt;\/goals&gt;                         &lt;configuration&gt;                             &lt;outputDirectory&gt;src\/main\/resources\/frontend&lt;\/outputDirectory&gt;                             &lt;overwrite&gt;true&lt;\/overwrite&gt;                             &lt;resources&gt;                                 &lt;resource&gt;                                     &lt;directory&gt;..\/frontend\/dist&lt;\/directory&gt;                                     &lt;includes&gt;                                         &lt;include&gt;*.*&lt;\/include&gt;                                     &lt;\/includes&gt;                                 &lt;\/resource&gt;                             &lt;\/resources&gt;                         &lt;\/configuration&gt;                     &lt;\/execution&gt;                 &lt;\/executions&gt;             &lt;\/plugin&gt;<\/code><\/pre>\n<p>  properties-maven-plugin \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0444\u0430\u0439\u043b maven.properties, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0436\u0438\u0442 \u0432\u0441\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 Maven. \u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e atlassian.plugin.key \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438\u0437 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u044b \u043a \u043f\u0443\u043d\u043a\u0442\u0430\u043c \u043c\u0435\u043d\u044e \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430.<br \/>  maven-resources-plugin \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0444\u0430\u0439\u043b\u044b JavaScript \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 frontend\/dist \u0438 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u0432 \u043f\u0430\u043f\u043a\u0443 backend\/resources\/frontend.<br \/>  \u0417\u0430\u0442\u0435\u043c \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0443\u043d\u043a\u0442\u044b \u043c\u0435\u043d\u044e \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u044b\u0437\u043e\u0432 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u0432 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e. <br \/>  \u0412\u043e\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 atlassian-plugin.xml:<\/p>\n<pre><code class=\"xml\">&lt;servlet name=&quot;Form Servlet&quot; i18n-name-key=&quot;form-servlet.name&quot; key=&quot;form-servlet&quot; class=&quot;react.atlaskit.tutorial.servlet.FormServlet&quot;&gt;      &lt;description key=&quot;form-servlet.description&quot;&gt;The Form Servlet Plugin&lt;\/description&gt;       &lt;url-pattern&gt;\/form&lt;\/url-pattern&gt;   &lt;\/servlet&gt;     &lt;servlet name=&quot;Dynamic Table Servlet&quot; i18n-name-key=&quot;dynamic-table-servlet.name&quot; key=&quot;dynamic-table-servlet&quot; class=&quot;react.atlaskit.tutorial.servlet.DynamicTableServlet&quot;&gt;      &lt;description key=&quot;dynamic-table-servlet.description&quot;&gt;The Dynamic Table Servlet Plugin&lt;\/description&gt;       &lt;url-pattern&gt;\/dynamictable&lt;\/url-pattern&gt;   &lt;\/servlet&gt;   &lt;web-section name=&quot;React Plugin&quot; i18n-name-key=&quot;react.name&quot; key=&quot;react&quot; location=&quot;admin_plugins_menu&quot; weight=&quot;1000&quot;&gt;     &lt;description key=&quot;react.description&quot;&gt;React Plugin&lt;\/description&gt;     &lt;label key=&quot;react.label&quot;\/&gt;   &lt;\/web-section&gt;   &lt;web-item name=&quot;from web item&quot; i18n-name-key=&quot;form.name&quot; key=&quot;form&quot; section=&quot;admin_plugins_menu\/react&quot; weight=&quot;1000&quot;&gt;     &lt;description key=&quot;form.description&quot;&gt;Form&lt;\/description&gt;     &lt;label key=&quot;form.label&quot;\/&gt;     &lt;link linkId=&quot;configuration-link&quot;&gt;\/plugins\/servlet\/form&lt;\/link&gt;   &lt;\/web-item&gt;   &lt;web-item name=&quot;dynamic table web item&quot; i18n-name-key=&quot;dynamictable.name&quot; key=&quot;dynamictable&quot; section=&quot;admin_plugins_menu\/react&quot; weight=&quot;1000&quot;&gt;     &lt;description key=&quot;dynamictable.description&quot;&gt;Dynamic Table&lt;\/description&gt;     &lt;label key=&quot;dynamictable.label&quot;\/&gt;     &lt;link linkId=&quot;configuration-link&quot;&gt;\/plugins\/servlet\/dynamictable&lt;\/link&gt;   &lt;\/web-item&gt; <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043c\u0435\u043d\u044e \u0438 \u0441\u0435\u0440\u0432\u0435\u043b\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u0443\u043d\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f.<br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u044b:<br \/>  FormServlet.java:<\/p>\n<pre><code class=\"java\">public class FormServlet extends HttpServlet{     private static final Logger log = LoggerFactory.getLogger(FormServlet.class);     private final ResourceService resourceService;     private final SoyTemplateRenderer soyTemplateRenderer;      public FormServlet(@ComponentImport  SoyTemplateRenderer soyTemplateRenderer, ResourceService resourceService) {         this.resourceService = resourceService;         this.soyTemplateRenderer = soyTemplateRenderer;     }      @Override     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException     {         String pluginKey = this.resourceService.getProperty(&quot;atlassian.plugin.key&quot;);         Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();         map.put(&quot;contextPath&quot;, req.getContextPath());          String html = soyTemplateRenderer.render(pluginKey + &quot;:jira-react-atlaskit-resources&quot;, &quot;servlet.ui.form&quot;, map);          resp.setContentType(&quot;text\/html&quot;);         resp.getWriter().write(html);         resp.getWriter().close();    }      @Override     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {         StringBuffer jb = new StringBuffer();         String line = null;         try {             BufferedReader reader = req.getReader();             while ((line = reader.readLine()) != null)                 jb.append(line);         } catch (Exception e) { \/*report an error*\/ }         log.info(String.format(&quot;Post Data: %s&quot;, jb.toString()));          String pluginKey = this.resourceService.getProperty(&quot;atlassian.plugin.key&quot;);         Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();         map.put(&quot;contextPath&quot;, req.getContextPath());          String html = soyTemplateRenderer.render(pluginKey + &quot;:jira-react-atlaskit-resources&quot;, &quot;servlet.ui.form&quot;, map);          resp.setContentType(&quot;text\/html&quot;);         resp.getWriter().write(html);         resp.getWriter().close();     }}<\/code><\/pre>\n<p>  \u042f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e \u0434\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 resourceService \u0438 soyTemplateRenderer \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430. resourceService \u2014 \u0431\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0447\u0438\u0442\u0430\u0435\u0442 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 maven.properties. soyTemplateRenderer \u2014 Jira \u0431\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043c\u0435\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c soy \u0448\u0430\u0431\u043b\u043e\u043d\u044b.<br \/>  \u0412 \u043c\u0435\u0442\u043e\u0434\u0435 doGet \u044f \u043f\u043e\u043b\u0443\u0447\u0430\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 atlassian.plugin.key \u0438 \u043f\u0443\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u0417\u0430\u0442\u0435\u043c \u044f \u043f\u0435\u0440\u0435\u0434\u0430\u044e \u043f\u0443\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0432 \u0448\u0430\u0431\u043b\u043e\u043d soy \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u044e \u0448\u0430\u0431\u043b\u043e\u043d soy \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c servlet.ui.form.<br \/>  \u0412\u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 soy \u0444\u0430\u0439\u043b\u0430:<\/p>\n<pre><code class=\"1c\">{namespace servlet.ui} \/**  * This template is needed to draw the form page.  *\/ {template .form}     {@param contextPath: string}     {webResourceManager_requireResourcesForContext('form')}     &lt;html&gt;     &lt;head&gt;         &lt;meta charset=&quot;utf-8&quot;\/&gt;         &lt;meta name=&quot;decorator&quot; content=&quot;atl.admin&quot;&gt;         &lt;meta name=&quot;admin.active.section&quot; content=&quot;admin_plugins_menu\/react&quot;&gt;         &lt;title&gt;Form Page&lt;\/title&gt;     &lt;\/head&gt;     &lt;body&gt;     &lt;div class=&quot;field-group hidden&quot;&gt;         &lt;input class=&quot;text&quot; type=&quot;text&quot; id=&quot;contextPath&quot; name=&quot;contextPath&quot; value=&quot;{$contextPath}&quot;&gt;     &lt;\/div&gt;     &lt;div id=&quot;maincontainer&quot;&gt;         &lt;div id=&quot;container&quot;&gt;         &lt;\/div&gt;     &lt;\/div&gt;     &lt;\/body&gt;     &lt;\/html&gt; {\/template} \/**  * This template is needed to draw the dynamic table page.  *\/ {template .dynamictable}     {webResourceManager_requireResourcesForContext('dynamictable')}     &lt;html&gt;     &lt;head&gt;         &lt;meta charset=&quot;utf-8&quot;\/&gt;         &lt;meta name=&quot;decorator&quot; content=&quot;atl.admin&quot;&gt;         &lt;meta name=&quot;admin.active.section&quot; content=&quot;admin_plugins_menu\/react&quot;&gt;         &lt;title&gt;Dynamic Table Page&lt;\/title&gt;     &lt;\/head&gt;     &lt;body&gt;     &lt;div id=&quot;maincontainer&quot;&gt;         &lt;div id=&quot;container&quot;&gt;         &lt;\/div&gt;     &lt;\/div&gt;     &lt;\/body&gt;     &lt;\/html&gt; {\/template} <\/code><\/pre>\n<p>  \u041a\u043e\u0434 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442. \u042f \u0432\u044b\u0437\u044b\u0432\u0430\u044e \u0432\u0435\u0431 \u0440\u0435\u0441\u0443\u0440\u0441 \u0434\u043b\u044f \u043f\u0443\u043d\u043a\u0442\u0430 \u043c\u0435\u043d\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u044e \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 div, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f React. <br \/>  \u0421\u0430\u043c soy \u0444\u0430\u0439\u043b \u044f \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u0432 atlassian-plugin.xml:<\/p>\n<pre><code class=\"xml\">&lt;web-resource key=&quot;jira-react-atlaskit-resources&quot; name=&quot;jira-react-atlaskit Web Resources&quot;&gt;      ...     &lt;resource type=&quot;soy&quot; name=&quot;soyui&quot; location=&quot;\/templates\/servlets.soy&quot;\/&gt;     ...     &lt;context&gt;jira-react-atlaskit&lt;\/context&gt;    &lt;\/web-resource&gt; <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React \u0438 Atlaskit \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0438 \u0434\u0430\u0442\u0430\u0446\u0435\u043d\u0442\u0440\u043e\u0432\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445 Atlassian.<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/501300\/\"> https:\/\/habr.com\/ru\/post\/501300\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/501300\/\">\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!<br \/>  \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u044b \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React \u0438 Atlaskit \u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u0445 Atlassian \u0432 Server \u0438 Data Center \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f\u0445.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-303323","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/303323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=303323"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/303323\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=303323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=303323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=303323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}