OpenProject: Developmenthttps://community.openproject.org/2024-03-27T03:49:26ZOpenProject Community
OpenProject Development: RE: Need Help regarding How to Upload (POST) attachment to particular work-packagehttps://community.openproject.org/topics/18593?forum_id=7&r=18600#message-186002024-03-27T03:49:26ZHarsh Oza
<p class="op-uc-p">Matt User wrote:</p>
<blockquote class="op-uc-blockquote">
<p class="op-uc-p">Hey! I just spent A LOT of time on this yesterday (using Python requests library). I got different error codes with different request structures. What solved things for me in the end was to not set any headers (not sure what requests library does under the hood, but this is what finally got my requests through).</p>
</blockquote>
<p class="op-uc-p">Can you share code snippets and library that you have used</p> Development: RE: Need Help regarding How to Upload (POST) attachment to particular work-packagehttps://community.openproject.org/topics/18593?forum_id=7&r=18596#message-185962024-03-26T18:55:55ZMatt User
<p class="op-uc-p">Hey! I just spent A LOT of time on this yesterday (using Python requests library). I got different error codes with different request structures. What solved things for me in the end was to not set any headers (not sure what requests library does under the hood, but this is what finally got my requests through).</p> Development: Need Help regarding How to Upload (POST) attachment to particular work-packagehttps://community.openproject.org/topics/18593?forum_id=72024-03-26T09:55:58ZHarsh Oza
<h3 id="for-this-api-" class="op-uc-h3">For this API :<a class="op-uc-link_permalink icon-link op-uc-link" aria-hidden="true" href="#for-this-api-"></a>
</h3>
<h3 id="create-work-package-attachment" class="op-uc-h3">Create work package attachment<a class="op-uc-link_permalink icon-link op-uc-link" aria-hidden="true" href="#create-work-package-attachment"></a>
</h3>
<p class="op-uc-p"><strong>POST /api/v3/work_packages/{id}/attachments</strong></p>
<p class="op-uc-p">To add an attachment to a work package, a client needs to issue a request of type <code class="op-uc-code">multipart/form-data</code> with exactly two parts.</p>
<p class="op-uc-p">The first part <em>must</em> be called <code class="op-uc-code">metadata</code>. Its content type is expected to be <code class="op-uc-code">application/json</code>, the body <em>must</em> be a single JSON object, containing at least the <code class="op-uc-code">fileName</code> and optionally the attachments <code class="op-uc-code">description</code>.</p>
<p class="op-uc-p">The second part <em>must</em> be called <code class="op-uc-code">file</code>, its content type <em>should</em> match the mime type of the file. The body <em>must</em> be the raw content of the file. Note that a <code class="op-uc-code">filename</code> must be indicated in the <code class="op-uc-code">Content-Disposition</code> of this part, however it will be ignored. Instead the <code class="op-uc-code">fileName</code> inside the JSON of the metadata part will be used.</p>
<p class="op-uc-p">This is my file variable that got through input field from frontend code</p>
<pre lang="javascript" class="highlight highlight-javascript op-uc-code-block"><span class="nx">File</span> <span class="p">{</span>
<span class="nl">size</span><span class="p">:</span> <span class="mi">5132</span><span class="p">,</span>
<span class="nx">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">image/png</span><span class="dl">'</span><span class="p">,</span>
<span class="nx">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Screenshot from 2024-03-22 17-05-14.png</span><span class="dl">'</span><span class="p">,</span>
<span class="nx">lastModified</span><span class="p">:</span> <span class="mi">1711445527966</span>
<span class="p">}</span>
</pre>
<p class="op-uc-p">This is my code to call api</p>
<pre lang="javascript" class="highlight highlight-javascript op-uc-code-block"><span class="k">import</span> <span class="p">{</span> <span class="nx">EntityManager</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">op-client</span><span class="dl">'</span>
<span class="kd">const</span> <span class="nx">OPManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">EntityManager</span><span class="p">({</span>
<span class="na">baseUrl</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">OP_BASE_URL</span> <span class="k">as</span> <span class="nx">string</span><span class="p">,</span>
<span class="na">oauthOptions</span><span class="p">:</span> <span class="p">{</span>
<span class="na">clientId</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">OP_CLIENT_ID</span><span class="p">,</span>
<span class="na">clientSecret</span><span class="p">:</span> <span class="nx">process</span><span class="p">.</span><span class="nx">env</span><span class="p">.</span><span class="nx">OP_CLIENT_SECRET</span>
<span class="p">},</span>
<span class="na">createLogger</span><span class="p">:</span> <span class="p">()</span> <span class="o">=></span> <span class="nx">console</span>
<span class="p">})</span>
<span class="kd">const</span> <span class="nx">newForm</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">FormData</span><span class="p">()</span>
<span class="nx">newForm</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">metadata</span><span class="dl">'</span><span class="p">,{</span><span class="dl">'</span><span class="s1">fileName</span><span class="dl">'</span><span class="p">:</span><span class="s2">`</span><span class="p">${</span><span class="nx">file</span><span class="p">?.</span><span class="nx">name</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span><span class="dl">'</span><span class="s1">contentType</span><span class="dl">'</span><span class="p">:</span><span class="s2">`</span><span class="p">${</span><span class="nx">file</span><span class="p">?.</span><span class="nx">type</span><span class="p">}</span><span class="s2">`</span><span class="p">,</span><span class="dl">'</span><span class="s1">fileSize</span><span class="dl">'</span><span class="p">:</span><span class="s2">`</span><span class="p">${</span><span class="nx">file</span><span class="p">?.</span><span class="nx">size</span><span class="p">}</span><span class="s2">`</span><span class="p">})</span>
<span class="nx">newForm</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="dl">'</span><span class="s1">file</span><span class="dl">'</span><span class="p">,</span><span class="nx">file</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">OPManager</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="dl">'</span><span class="s1">/api/v3/work_packages/3784/attachments</span><span class="dl">'</span><span class="p">,{</span>
<span class="na">headers</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">'</span><span class="s1">Content-Type</span><span class="dl">'</span><span class="p">:</span> <span class="dl">'</span><span class="s1">multipart/form-data</span><span class="dl">'</span><span class="p">,</span>
<span class="dl">'</span><span class="s1">Content-Disposition</span><span class="dl">'</span><span class="p">:</span> <span class="s2">`form-data; filename=</span><span class="p">${</span><span class="nx">file</span><span class="p">?.</span><span class="nx">name</span><span class="p">}</span><span class="s2">;`</span>
<span class="p">},</span>
<span class="na">method</span><span class="p">:</span><span class="dl">'</span><span class="s1">POST</span><span class="dl">'</span><span class="p">,</span>
<span class="na">body</span><span class="p">:</span><span class="nx">newForm</span><span class="p">,</span>
<span class="p">})</span>
</pre>
<p class="op-uc-p">Error I got in my console is :</p>
<p class="op-uc-p">An error occured while api call Error: 422 [urn:openproject-org:api:v3:errors:MultipleErrors] Multiple field constraints have been violated. contentType: The content type of the file cannot be blank. filename: File can't be blank.<br>
at EntityManager.fetch (webpack-internal:///(rsc)/./node_modules/op-client/dist/src/EntityManager/EntityManager.js:85:31)<br>
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)<br>
at async POST (webpack-internal:///(rsc)/./src/app/api/AddTicket/route.ts:22:21)<br>
at async /home/harshoza/WORK/15MARCH/customer-facing-app/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:62499</p> Development: RE: "Add attachment to work package" API Endpoint - difficultieshttps://community.openproject.org/topics/15924?forum_id=7&r=18572#message-185722024-03-21T09:48:29Znorma normal
<p class="op-uc-p">any one have solution in nodejs?</p> Development: RE: Patching/overriding existent OP view via plugin.https://community.openproject.org/topics/18513?forum_id=7&r=18534#message-185342024-03-11T08:44:57ZAlexander Aleschenko
<p class="op-uc-p">Looks like OpenProject::Plugins::ActsAsOpEngine#override_core_views! inside engine.rb does the job.</p> Development: RE: Patching/overriding existent OP view via plugin.https://community.openproject.org/topics/18513?forum_id=7&r=18518#message-185182024-03-07T19:47:18ZAlexander Aleschenko
<p class="op-uc-p">It shows only adding new views, not changing or replacing existing.</p> Development: RE: Patching/overriding existent OP view via plugin.https://community.openproject.org/topics/18513?forum_id=7&r=18515#message-185152024-03-07T17:12:50ZMarkus Kahl
<p class="op-uc-p">HI Alexander,</p>
<p class="op-uc-p">have you checked our <a href="https://github.com/opf/openproject-proto_plugin" rel="noopener noreferrer" target="_top" class="op-uc-link">proto_plugin</a>? That should give you some hints as to how to inject your own views into the existing OpenProject ones where possible.</p> Development: [Solved] Patching/overriding existent OP view via plugin.https://community.openproject.org/topics/18513?forum_id=72024-03-07T12:59:04ZAlexander Aleschenko
<p class="op-uc-p">Hello</p>
<p class="op-uc-p">I'm trying to build simple plugin which changes app's controller and view. Controllers(and models) can be patched and it works ok, but there's problem with views. As I understand, rails looks up view file in app scope at first and if it not found tries to check view file in the engine(plugin).</p>
<p class="op-uc-p">Is there a way to completely override OP's view via plugin? Or, ideally, inject "render" inside erb at specific place without changing OP app itself?</p> Development: RE: autoreload openproject when developing a pluginhttps://community.openproject.org/topics/11054?forum_id=7&r=18512#message-185122024-03-07T11:06:51ZAlexander Aleschenko
<p class="op-uc-p">Looking for that feature too. Any solutions since?</p> Development: API V3 - Create Subprojecthttps://community.openproject.org/topics/18490?forum_id=72024-03-04T11:41:44ZAmr Labadi
<p class="op-uc-p">Hello, how can i create a sub project with the api? I only saw the option to see, which projects are available as a parent project. But i want to update or create a project with the parent project with the API. Please help me</p> Development: "Add attachment to work package" API Endpoint - difficultieshttps://community.openproject.org/topics/15924?forum_id=72022-12-04T23:38:19ZR B
<blockquote class="op-uc-blockquote">
<p class="op-uc-p"><a href="https://www.openproject.org/docs/api/endpoints/attachments/" rel="noopener noreferrer" target="_top" class="op-uc-link">https://www.openproject.org/docs/api/endpoints/attachments/</a><br>
"<strong>/api/v3/work_packages/{id}/attachments</strong></p>
<p class="op-uc-p">To add an attachment to a work package, a client needs to issue a request of type <code class="op-uc-code">multipart/form-data</code> with exactly two parts.</p>
<p class="op-uc-p">The first part <em>must</em> be called <code class="op-uc-code">metadata</code>. Its content type is expected to be <code class="op-uc-code">application/json</code>, the body <em>must</em> be a single JSON object, containing at least the <code class="op-uc-code">fileName</code> and optionally the attachments <code class="op-uc-code">description</code>.</p>
<p class="op-uc-p">The second part <em>must</em> be called <code class="op-uc-code">file</code>, its content type <em>should</em> match the mime type of the file. The body <em>must</em> be the raw content of the file. Note that a <code class="op-uc-code">filename</code> must be indicated in the <code class="op-uc-code">Content-Disposition</code> of this part, however it will be ignored. Instead the <code class="op-uc-code">fileName</code> inside the JSON of the metadata part will be used."</p>
</blockquote>
<p class="op-uc-p">I have tried coding a solution to this, I've tried a mock in Postman. </p>
<p class="op-uc-p">Possibly this is a language barrier, however, I nonetheless remain at a loss on how to upload a file and attach it to a workpackage via the API. <br>
In postman, the response I get is simply a "400 bad request":</p>
<p class="op-uc-p">https://***/api/v3/work_packages/23921/attachments<br>
"form-data" checked. </p>
<p class="op-uc-p">The below key value pairs: </p>
<p class="op-uc-p">Key: Value: </p>
<p class="op-uc-p">metadata {"fileName":"test.png"}</p>
<p class="op-uc-p">file file.png</p>
<p class="op-uc-p">I would very much appreciate anyone's time in pointing me in the right direction. </p>
<p class="op-uc-p">My eventual plan is to implement in Axios, but with a workable mock, I assume I can resolve this...</p> Development: [Solved] Autologin not working with openid and keycloakhttps://community.openproject.org/topics/12446?forum_id=72020-08-19T12:55:55ZKacper Pabian
<p class="op-uc-p">I deployed OpenProject on Kubernetes cluster creating manifests with kompose from docker-compose as recommended in the documentation and changing them here and there - using postgres database version 12. Works fine, with integration with Keycloak, although I seem not be able to set up autologin function. When I close the browser I have to log in every time. Autologin is set up for 7 days, session is stored in cache. There is not a lot of information about integration with Keycloak so I'm not sure if I'm doing something wrong. Web and proxy is set up with openproject/community:10 image. Here is Keycloak configuration:</p>
<pre lang="yaml" class="highlight highlight-yaml op-uc-code-block"> <span class="na">openid_connect</span><span class="pi">:</span>
<span class="na">keycloak</span><span class="pi">:</span>
<span class="na">sso</span><span class="pi">:</span> <span class="kc">true</span>
<span class="na">prompt</span><span class="pi">:</span> <span class="s">login</span>
<span class="na">host</span><span class="pi">:</span> <span class="s2">"</span><span class="s">keycloak_dns"</span>
<span class="na">identifier</span><span class="pi">:</span> <span class="s2">"</span><span class="s">openproject_dns"</span>
<span class="na">secret</span><span class="pi">:</span> <span class="s2">"</span><span class="s">secret"</span>
<span class="na">authorization_endpoint</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://keycloak_dns/auth/realms/master/protocol/openid-connect/auth"</span>
<span class="na">token_endpoint</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://keycloak_dns/auth/realms/master/protocol/openid-connect/token"</span>
<span class="na">userinfo_endpoint</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://keycloak_dns/auth/realms/master/protocol/openid-connect/userinfo"</span>
<span class="na">end_session_endpoint</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://keycloak_dns/auth/realms/master/protocol/openid-connect/logout"</span>
<span class="na">check_session_iframe</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://keycloak_dns/auth/realms/master/protocol/openid-connect/login-status-iframe.html"</span>
<span class="na">discovery</span><span class="pi">:</span> <span class="kc">false</span>
<span class="na">issuer</span><span class="pi">:</span> <span class="s2">"</span><span class="s">https://openproject_dns/login"</span>
<span class="na">display_name</span><span class="pi">:</span> <span class="s2">"</span><span class="s">Keycloak</span><span class="nv"> </span><span class="s">SSO"</span>
<span class="na">omniauth_direct_login_provider</span><span class="pi">:</span> <span class="s">keycloak</span>
</pre> Development: autoreload openproject when developing a pluginhttps://community.openproject.org/topics/11054?forum_id=72019-06-12T20:27:31ZLARABA MOHAMMED SEDDIK
<p class="op-uc-p">Hello, is there a way to make plugins developpement make openproject to auto load the entire app in order to view changes, and without the need of restarting the launch command or the service each time. because it takes too long espacially (with foreman).</p> Development: Guides for developing a new pluginhttps://community.openproject.org/topics/7096?forum_id=72017-01-12T10:39:48ZOliver Günther
<p class="op-uc-p">You are interested in creating an OpenProject plugin? Great, here are some pointers to get you going.</p>
<p class="op-uc-p"><a href="https://www.openproject.org/open-source/development-free-project-management-software/create-openproject-plugin/" rel="noopener noreferrer" target="_top" class="op-uc-link">Create an OpenProject plugin</a> is a guide to get you started with a regular plugin.</p>
<p class="op-uc-p"><a href="https://www.openproject.org/open-source/development-free-project-management-software/create-omniauth-plugin/" rel="noopener noreferrer" target="_top" class="op-uc-link">Create an OmniAuth plugin</a> shows you the steps to create a new OmniAuth plugin, which allows you to integration new authentication providers to OpenProject.</p>
<p class="op-uc-p">A working exemplary plugin that shows you the basic operations you can use is available here:<br>
<a href="https://github.com/opf/openproject-proto_plugin" class="op-uc-link">https://github.com/opf/openproject-proto_plugin</a></p> Development: PLEASE NOTE: Bug reportshttps://community.openproject.org/topics/6252?forum_id=72016-04-25T09:32:37ZOliver Günther
<p class="op-uc-p">If you want to report a bug in OpenProject, please <a href="https://community.openproject.com/projects/openproject/work_packages/create_new?type=1" rel="noopener noreferrer" target="_top" class="op-uc-link">create a work package using this link</a>.</p>
<p class="op-uc-p">Please copy/paste the HTML template into the description your new issue and fill out the steps.</p>
<h3 id="html" class="op-uc-h3">
<strong>HTML</strong><a class="op-uc-link_permalink icon-link op-uc-link" aria-hidden="true" href="#html"></a>
</h3>
<p class="op-uc-p"><strong>Environment:</strong></p>
<p class="op-uc-p">Your OpenProject Version: <VERSION> / Cloud Edition</p>
<p class="op-uc-p">Operating System / Browser / Language:</p>
<p class="op-uc-p"><strong>Logs</strong></p>
<ul class="op-uc-list">
<li class="op-uc-list--item">Are there errors in the browser console? (<a href="https://webmasters.stackexchange.com/a/77337" rel="noopener noreferrer" target="_top" class="op-uc-link">Click here for information on how to open your browser's console</a>)</li>
<li class="op-uc-list--item">For a local installation: Are there logs in a <code class="op-uc-code">log/production.log</code> or <code class="op-uc-code">/var/log/openproject/</code> ? Please attach error output in these log files if applicable</li>
</ul>
<p class="op-uc-p"><strong>Steps to reproduce:</strong></p>
<ol class="op-uc-list">
<li class="op-uc-list--item">Go to page X</li>
<li class="op-uc-list--item">Click on button Y</li>
<li class="op-uc-list--item">Select Foo</li>
</ol>
<p class="op-uc-p"><strong>Actual Behavior</strong><br>
Describe the behavior you're seeing.</p>
<p class="op-uc-p"><strong>Expected Behavior</strong><br>
Describe the expected behavior.</p>
<h3 id="markdown" class="op-uc-h3">Markdown<a class="op-uc-link_permalink icon-link op-uc-link" aria-hidden="true" href="#markdown"></a>
</h3>
<pre lang="text" class="highlight highlight-text op-uc-code-block">**Environment:**
Your OpenProject Version: &lt;VERSION&gt; / Cloud Edition
Operating System / Browser / Language:
**Logs**
Are there errors in the browser console? ([Click here for information on how to open your browser's console](https://webmasters.stackexchange.com/a/77337))
For a local installation: Are there logs in a log/production.log or /var/log/openproject/ ? Please attach error output in these log files if applicable
**Steps to reproduce:**
1. Go to page X
2. Click on button Y
3. Select Foo
**Actual Behavior**
Describe the behavior you're seeing.
**Expected Behavior**
Describe the expected behavior.
</pre>
<p class="op-uc-p">If available, please add a screenshot of the report and <strong>assign the issue to Dev Team</strong>.<br>
It will create the proper notification and we can confirm and prioritize the issue accordingly.</p>
<p class="op-uc-p">For more information, please view this link: <a href="https://www.openproject.org/open-source/report-bug/" class="op-uc-link">https://www.openproject.org/open-source/report-bug/</a></p>