Slightly better error handling
Extract error details we get from the API when status code > 2xx. Also, use toast messages to display the error, properly close delete modals and prevent full page display of error messages. Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
parent
8cf0b0a56e
commit
7f647941f6
95 changed files with 296 additions and 195 deletions
1
webapp/assets/_app/immutable/chunks/2p_hWkLJ.js
Normal file
1
webapp/assets/_app/immutable/chunks/2p_hWkLJ.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import{s as e}from"./CTf6mQoE.js";const r=()=>{const s=e;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},b={subscribe(s){return r().page.subscribe(s)}};export{b as p};
|
||||
import{s as e}from"./DXCC0cSN.js";const r=()=>{const s=e;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},b={subscribe(s){return r().page.subscribe(s)}};export{b as p};
|
||||
|
|
@ -1 +1 @@
|
|||
import"./DsnmJJEf.js";import{i as U}from"./B3Pzt0F_.js";import{f as I,j as t,k as p,r as a,t as P,v as b,c as u,z as N,D as A,p as W,u as z,n as H,d as X}from"./D8EpLgQ1.js";import{p as s,i as T}from"./5WA7h8uK.js";import{s as Y,h as Z,B as F,c as $}from"./CiE1LlKV.js";import{b as ee}from"./CoIRRsD9.js";import{D as te,G as ae,a as se}from"./C9DJVOi1.js";import{E as ne}from"./B7ITzBt8.js";import{S as B}from"./BE4wujub.js";var le=I('<div class="flex-shrink-0"><!></div>'),ie=I('<div class="mt-4 sm:mt-0 flex space-x-3"><!> <!></div>'),re=I('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="sm:flex sm:items-center sm:justify-between"><div class="flex items-center space-x-3"><!> <div><h1> </h1> <p class="text-sm text-gray-500 dark:text-gray-400"> </p></div></div> <!></div></div></div>');function ye(L,e){let n=s(e,"title",8),S=s(e,"subtitle",8),_=s(e,"forgeIcon",8,""),f=s(e,"onEdit",8,null),h=s(e,"onDelete",8,null),k=s(e,"editLabel",8,"Edit"),j=s(e,"deleteLabel",8,"Delete"),g=s(e,"titleClass",8,"");var c=re(),v=t(c),m=t(v),y=t(m),C=t(y);{var E=i=>{var r=le(),w=t(r);Z(w,_),a(r),u(i,r)};T(C,i=>{_()&&i(E)})}var l=p(C,2),D=t(l),G=t(D,!0);a(D);var M=p(D,2),V=t(M,!0);a(M),a(l),a(y);var R=p(y,2);{var q=i=>{var r=ie(),w=t(r);{var J=o=>{F(o,{variant:"secondary",size:"md",icon:"<path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z'/>",$$events:{click(...d){f()?.apply(this,d)}},children:(d,Q)=>{N();var x=A();P(()=>b(x,k())),u(d,x)},$$slots:{default:!0}})};T(w,o=>{f()&&o(J)})}var K=p(w,2);{var O=o=>{F(o,{variant:"danger",size:"md",icon:"<path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16'/>",$$events:{click(...d){h()?.apply(this,d)}},children:(d,Q)=>{N();var x=A();P(()=>b(x,j())),u(d,x)},$$slots:{default:!0}})};T(K,o=>{h()&&o(O)})}a(r),u(i,r)};T(R,i=>{(f()||h())&&i(q)})}a(m),a(v),a(c),P(()=>{Y(D,1,`text-2xl font-bold text-gray-900 dark:text-white ${g()??""}`),b(G,n()),b(V,S())}),u(L,c)}var oe=I('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="flex items-center justify-between mb-4"><h2 class="text-lg font-medium text-gray-900 dark:text-white"> </h2> <a class="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">View all instances</a></div> <!></div></div>');function xe(L,e){W(e,!1);let n=s(e,"instances",8),S=s(e,"entityType",8),_=s(e,"onDeleteInstance",8);const f=[{key:"name",title:"Name",cellComponent:ne,cellProps:{entityType:"instance",nameField:"name"}},{key:"status",title:"Status",cellComponent:B,cellProps:{statusType:"instance",statusField:"status"}},{key:"runner_status",title:"Runner Status",cellComponent:B,cellProps:{statusType:"instance",statusField:"runner_status"}},{key:"created",title:"Created",cellComponent:ae,cellProps:{field:"created_at",type:"date"}},{key:"actions",title:"Actions",align:"right",cellComponent:se,cellProps:{actions:[{type:"delete",label:"Delete",title:"Delete instance",ariaLabel:"Delete instance",action:"delete"}]}}],h={entityType:"instance",primaryText:{field:"name",isClickable:!0,href:"/instances/{name}"},secondaryText:{field:"provider_id"},badges:[{type:"status",field:"status"}],actions:[{type:"delete",handler:l=>k(l)}]};function k(l){_()(l)}function j(l){k(l.detail.item)}U();var g=oe(),c=t(g),v=t(c),m=t(v),y=t(m);a(m);var C=p(m,2);a(v);var E=p(v,2);te(E,{get columns(){return f},get data(){return n()},loading:!1,error:"",searchTerm:"",showSearch:!1,showPagination:!1,currentPage:1,get perPage(){return H(n()),z(()=>n().length)},totalPages:1,get totalItems(){return H(n()),z(()=>n().length)},itemName:"instances",emptyTitle:"No instances running",get emptyMessage(){return`No instances running for this ${S()??""}.`},emptyIconType:"cog",get mobileCardConfig(){return h},$$events:{delete:j}}),a(c),a(g),P(()=>{b(y,`Instances (${H(n()),z(()=>n().length)??""})`),$(C,"href",`${ee}/instances`)}),u(L,g),X()}export{ye as D,xe as I};
|
||||
import"./DsnmJJEf.js";import{i as U}from"./B3Pzt0F_.js";import{f as I,j as t,k as p,r as a,t as P,v as b,c as u,z as N,D as A,p as W,u as z,n as H,d as X}from"./D8EpLgQ1.js";import{p as s,i as T}from"./5WA7h8uK.js";import{s as Y,h as Z,B as F,c as $}from"./CiE1LlKV.js";import{b as ee}from"./CRhkqW2i.js";import{D as te,G as ae,a as se}from"./BrNfsPe8.js";import{E as ne}from"./D4PaGKsV.js";import{S as B}from"./MCv1Wq2q.js";var le=I('<div class="flex-shrink-0"><!></div>'),ie=I('<div class="mt-4 sm:mt-0 flex space-x-3"><!> <!></div>'),re=I('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="sm:flex sm:items-center sm:justify-between"><div class="flex items-center space-x-3"><!> <div><h1> </h1> <p class="text-sm text-gray-500 dark:text-gray-400"> </p></div></div> <!></div></div></div>');function ye(L,e){let n=s(e,"title",8),S=s(e,"subtitle",8),_=s(e,"forgeIcon",8,""),f=s(e,"onEdit",8,null),h=s(e,"onDelete",8,null),k=s(e,"editLabel",8,"Edit"),j=s(e,"deleteLabel",8,"Delete"),g=s(e,"titleClass",8,"");var c=re(),v=t(c),m=t(v),y=t(m),C=t(y);{var E=i=>{var r=le(),w=t(r);Z(w,_),a(r),u(i,r)};T(C,i=>{_()&&i(E)})}var l=p(C,2),D=t(l),G=t(D,!0);a(D);var M=p(D,2),V=t(M,!0);a(M),a(l),a(y);var R=p(y,2);{var q=i=>{var r=ie(),w=t(r);{var J=o=>{F(o,{variant:"secondary",size:"md",icon:"<path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z'/>",$$events:{click(...d){f()?.apply(this,d)}},children:(d,Q)=>{N();var x=A();P(()=>b(x,k())),u(d,x)},$$slots:{default:!0}})};T(w,o=>{f()&&o(J)})}var K=p(w,2);{var O=o=>{F(o,{variant:"danger",size:"md",icon:"<path stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16'/>",$$events:{click(...d){h()?.apply(this,d)}},children:(d,Q)=>{N();var x=A();P(()=>b(x,j())),u(d,x)},$$slots:{default:!0}})};T(K,o=>{h()&&o(O)})}a(r),u(i,r)};T(R,i=>{(f()||h())&&i(q)})}a(m),a(v),a(c),P(()=>{Y(D,1,`text-2xl font-bold text-gray-900 dark:text-white ${g()??""}`),b(G,n()),b(V,S())}),u(L,c)}var oe=I('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="flex items-center justify-between mb-4"><h2 class="text-lg font-medium text-gray-900 dark:text-white"> </h2> <a class="text-sm text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">View all instances</a></div> <!></div></div>');function xe(L,e){W(e,!1);let n=s(e,"instances",8),S=s(e,"entityType",8),_=s(e,"onDeleteInstance",8);const f=[{key:"name",title:"Name",cellComponent:ne,cellProps:{entityType:"instance",nameField:"name"}},{key:"status",title:"Status",cellComponent:B,cellProps:{statusType:"instance",statusField:"status"}},{key:"runner_status",title:"Runner Status",cellComponent:B,cellProps:{statusType:"instance",statusField:"runner_status"}},{key:"created",title:"Created",cellComponent:ae,cellProps:{field:"created_at",type:"date"}},{key:"actions",title:"Actions",align:"right",cellComponent:se,cellProps:{actions:[{type:"delete",label:"Delete",title:"Delete instance",ariaLabel:"Delete instance",action:"delete"}]}}],h={entityType:"instance",primaryText:{field:"name",isClickable:!0,href:"/instances/{name}"},secondaryText:{field:"provider_id"},badges:[{type:"status",field:"status"}],actions:[{type:"delete",handler:l=>k(l)}]};function k(l){_()(l)}function j(l){k(l.detail.item)}U();var g=oe(),c=t(g),v=t(c),m=t(v),y=t(m);a(m);var C=p(m,2);a(v);var E=p(v,2);te(E,{get columns(){return f},get data(){return n()},loading:!1,error:"",searchTerm:"",showSearch:!1,showPagination:!1,currentPage:1,get perPage(){return H(n()),z(()=>n().length)},totalPages:1,get totalItems(){return H(n()),z(()=>n().length)},itemName:"instances",emptyTitle:"No instances running",get emptyMessage(){return`No instances running for this ${S()??""}.`},emptyIconType:"cog",get mobileCardConfig(){return h},$$events:{delete:j}}),a(c),a(g),P(()=>{b(y,`Instances (${H(n()),z(()=>n().length)??""})`),$(C,"href",`${ee}/instances`)}),u(L,g),X()}export{ye as D,xe as I};
|
||||
1
webapp/assets/_app/immutable/chunks/BZiHL9L3.js
Normal file
1
webapp/assets/_app/immutable/chunks/BZiHL9L3.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
function n(e){let s="An unexpected error occurred";if(e&&typeof e=="object"){if("response"in e&&e.response&&typeof e.response=="object"){const a=e.response;if("data"in a&&a.data&&typeof a.data=="object"){const t=a.data,r=t.error&&t.error.trim()?t.error:"",i=t.details&&t.details.trim()?t.details:"";if(r&&i)return`${r}. ${i}`;if(r)return r;if(i)return i}if("status"in a){const t=a.status;switch(t){case 400:s="Bad request - please check your input";break;case 401:s="Unauthorized - please log in again";break;case 403:s="Access denied - insufficient permissions";break;case 404:s="Resource not found";break;case 409:s="Conflict - resource already exists or is in use";break;case 422:s="Validation failed - please check your input";break;case 500:s="Internal server error - please try again later";break;default:s=`Request failed with status ${t}`}}}else if(e instanceof Error&&e.message&&!e.message.includes("status code"))return e.message}return s}export{n as e};
|
||||
1
webapp/assets/_app/immutable/chunks/Bgb-frqW.js
Normal file
1
webapp/assets/_app/immutable/chunks/Bgb-frqW.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/chunks/BsqC4UA1.js
Normal file
1
webapp/assets/_app/immutable/chunks/BsqC4UA1.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import"./DsnmJJEf.js";import{i as ae}from"./B3Pzt0F_.js";import{p as se,E as re,l as M,n as ie,s as r,g as t,m as k,a as le,f as p,j as v,k as $,r as f,c as l,d as oe,B as T,b as E,z as V,D as q,t as F,v as N,u as ne}from"./D8EpLgQ1.js";import{p as R,i as m}from"./5WA7h8uK.js";import{g as u,B as G}from"./CiE1LlKV.js";import{t as y}from"./BEkVdVE1.js";import{e as de}from"./BZiHL9L3.js";var ce=p('<div class="flex items-center"><div class="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mr-2"></div> <span class="text-sm text-gray-500 dark:text-gray-400">Checking...</span></div>'),ve=p('<div class="ml-4 text-xs text-gray-500 dark:text-gray-400"> </div>'),fe=p('<div class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg> <span class="text-sm text-green-700 dark:text-green-300">Webhook installed</span></div> <!>',1),ue=p('<div class="flex items-center"><svg class="w-4 h-4 text-gray-400 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm0-2a6 6 0 100-12 6 6 0 000 12zm0-10a1 1 0 011 1v3a1 1 0 01-2 0V7a1 1 0 011-1z" clip-rule="evenodd"></path></svg> <span class="text-sm text-gray-500 dark:text-gray-400">No webhook installed</span></div>'),he=p('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="flex items-center justify-between"><div><h3 class="text-lg font-medium text-gray-900 dark:text-white">Webhook Status</h3> <div class="mt-1 flex items-center"><!></div></div> <div class="flex space-x-2"><!></div></div></div></div>');function _e(H,g){se(g,!1);const x=k();let h=R(g,"entityType",8),s=R(g,"entityId",8),j=R(g,"entityName",8),i=k(null),o=k(!1),b=k(!0);const A=re();async function _(){if(s())try{r(b,!0),h()==="repository"?r(i,await u.getRepositoryWebhookInfo(s())):r(i,await u.getOrganizationWebhookInfo(s()))}catch(e){e&&typeof e=="object"&&"response"in e&&e.response?.status===404?r(i,null):(console.warn("Failed to check webhook status:",e),r(i,null))}finally{r(b,!1)}}async function J(){if(s())try{r(o,!0),h()==="repository"?await u.installRepositoryWebhook(s()):await u.installOrganizationWebhook(s()),y.success("Webhook Installed",`Webhook for ${h()} ${j()} has been installed successfully.`),await _(),A("webhookStatusChanged",{installed:!0})}catch(e){y.error("Webhook Installation Failed",e instanceof Error?e.message:"Failed to install webhook.")}finally{r(o,!1)}}async function K(){if(s())try{r(o,!0),h()==="repository"?await u.uninstallRepositoryWebhook(s()):await u.uninstallOrganizationWebhook(s()),y.success("Webhook Uninstalled",`Webhook for ${h()} ${j()} has been uninstalled successfully.`),await _(),A("webhookStatusChanged",{installed:!1})}catch(e){y.error("Webhook Uninstall Failed",de(e))}finally{r(o,!1)}}M(()=>ie(s()),()=>{s()&&_()}),M(()=>t(i),()=>{r(x,t(i)&&t(i).active)}),le(),ae();var w=he(),O=v(w),P=v(O),W=v(P),D=$(v(W),2),Q=v(D);{var X=e=>{var d=ce();l(e,d)},Y=e=>{var d=T(),z=E(d);{var I=a=>{var n=fe(),B=$(E(n),2);{var c=C=>{var U=ve(),te=v(U);f(U),F(()=>N(te,`URL: ${t(i),ne(()=>t(i).url||"N/A")??""}`)),l(C,U)};m(B,C=>{t(i)&&C(c)})}l(a,n)},S=a=>{var n=ue();l(a,n)};m(z,a=>{t(x)?a(I):a(S,!1)},!0)}l(e,d)};m(Q,e=>{t(b)?e(X):e(Y,!1)})}f(D),f(W);var L=$(W,2),Z=v(L);{var ee=e=>{var d=T(),z=E(d);{var I=a=>{G(a,{variant:"danger",size:"sm",get disabled(){return t(o)},$$events:{click:K},children:(n,B)=>{V();var c=q();F(()=>N(c,t(o)?"Uninstalling...":"Uninstall")),l(n,c)},$$slots:{default:!0}})},S=a=>{G(a,{variant:"primary",size:"sm",get disabled(){return t(o)},$$events:{click:J},children:(n,B)=>{V();var c=q();F(()=>N(c,t(o)?"Installing...":"Install Webhook")),l(n,c)},$$slots:{default:!0}})};m(z,a=>{t(x)?a(I):a(S,!1)})}l(e,d)};m(Z,e=>{t(b)||e(ee)})}f(L),f(P),f(O),f(w),l(H,w),oe()}export{_e as W};
|
||||
|
|
@ -1 +1 @@
|
|||
import"./DsnmJJEf.js";import{i as b}from"./B3Pzt0F_.js";import{p as k,f as E,t as C,u as i,n as t,v as n,c as j,d as P,k as z,j as l,r as o}from"./D8EpLgQ1.js";import{c as N}from"./CiE1LlKV.js";import{p as f}from"./5WA7h8uK.js";import"./CoIRRsD9.js";import{j as x,e as c,i as u}from"./BGVHQGl-.js";var T=E('<div class="flex flex-col"><a class="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300"> </a> <span class="text-xs text-gray-500 dark:text-gray-400 capitalize"> </span></div>');function G(d,r){k(r,!1);let e=f(r,"item",8),m=f(r,"eagerCache",8,null);b();var s=T(),a=l(s),v=l(a,!0);o(a);var p=z(a,2),g=l(p,!0);o(p),o(s),C((h,y,_)=>{N(a,"href",h),n(v,y),n(g,_)},[()=>(t(x),t(e()),i(()=>x(e()))),()=>(t(c),t(e()),t(m()),i(()=>c(e(),m()))),()=>(t(u),t(e()),i(()=>u(e())))]),j(d,s),P()}export{G as P};
|
||||
import"./DsnmJJEf.js";import{i as b}from"./B3Pzt0F_.js";import{p as k,f as E,t as C,u as i,n as t,v as n,c as j,d as P,k as z,j as l,r as o}from"./D8EpLgQ1.js";import{c as N}from"./CiE1LlKV.js";import{p as f}from"./5WA7h8uK.js";import"./CRhkqW2i.js";import{j as x,e as c,i as u}from"./BGVHQGl-.js";var T=E('<div class="flex flex-col"><a class="text-sm font-medium text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300"> </a> <span class="text-xs text-gray-500 dark:text-gray-400 capitalize"> </span></div>');function G(d,r){k(r,!1);let e=f(r,"item",8),m=f(r,"eagerCache",8,null);b();var s=T(),a=l(s),v=l(a,!0);o(a);var p=z(a,2),g=l(p,!0);o(p),o(s),C((h,y,_)=>{N(a,"href",h),n(v,y),n(g,_)},[()=>(t(x),t(e()),i(()=>x(e()))),()=>(t(c),t(e()),t(m()),i(()=>c(e(),m()))),()=>(t(u),t(e()),i(()=>u(e())))]),j(d,s),P()}export{G as P};
|
||||
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/chunks/CIBm3n2u.js
Normal file
1
webapp/assets/_app/immutable/chunks/CIBm3n2u.js
Normal file
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/chunks/CRD55Dyg.js
Normal file
1
webapp/assets/_app/immutable/chunks/CRD55Dyg.js
Normal file
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/chunks/CRhkqW2i.js
Normal file
1
webapp/assets/_app/immutable/chunks/CRhkqW2i.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
const s=globalThis.__sveltekit_xtz33p?.base??"/ui",t=globalThis.__sveltekit_xtz33p?.assets??s;export{t as a,s as b};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
const s=globalThis.__sveltekit_13hoftk?.base??"/ui",t=globalThis.__sveltekit_13hoftk?.assets??s;export{t as a,s as b};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import"./DsnmJJEf.js";import{i as j}from"./B3Pzt0F_.js";import{p as R,l as w,a as q,f as g,t as v,c as k,d as A,k as B,j as u,s as _,m as y,r as m,n as f,u as b,g as d,v as h}from"./D8EpLgQ1.js";import{p as o,i as D}from"./5WA7h8uK.js";import{c as U,s as F}from"./CiE1LlKV.js";import{b as r}from"./CoIRRsD9.js";var G=g('<div class="text-sm text-gray-500 dark:text-gray-400 truncate"> </div>'),H=g('<div class="w-full min-w-0 text-sm font-medium"><a> </a> <!></div>');function V(x,n){R(n,!1);const i=y(),p=y();let e=o(n,"item",8),s=o(n,"entityType",8,"repository"),$=o(n,"showOwner",8,!1),E=o(n,"showId",8,!1),I=o(n,"fontMono",8,!1);function z(){if(!e())return"Unknown";switch(s()){case"repository":return $()?`${e().owner||"Unknown"}/${e().name||"Unknown"}`:e().name||"Unknown";case"organization":case"enterprise":return e().name||"Unknown";case"pool":return E()?e().id||"Unknown":e().name||"Unknown";case"scaleset":return e().name||"Unknown";case"instance":return e().name||"Unknown";default:return e().name||e().id||"Unknown"}}function C(){if(!e())return"#";let t;switch(s()){case"instance":t=e().name;break;default:t=e().id||e().name;break}if(!t)return"#";switch(s()){case"repository":return`${r}/repositories/${t}`;case"organization":return`${r}/organizations/${t}`;case"enterprise":return`${r}/enterprises/${t}`;case"pool":return`${r}/pools/${t}`;case"scaleset":return`${r}/scalesets/${t}`;case"instance":return`${r}/instances/${encodeURIComponent(t)}`;default:return"#"}}w(()=>{},()=>{_(i,z())}),w(()=>{},()=>{_(p,C())}),q(),j();var c=H(),a=u(c),M=u(a,!0);m(a);var N=B(a,2);{var O=t=>{var l=G(),T=u(l,!0);m(l),v(()=>h(T,(f(e()),b(()=>e().provider_id)))),k(t,l)};D(N,t=>{f(s()),f(e()),b(()=>s()==="instance"&&e()?.provider_id)&&t(O)})}m(c),v(()=>{U(a,"href",d(p)),F(a,1,`block w-full truncate text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 ${I()?"font-mono":""}`),U(a,"title",d(i)),h(M,d(i))}),k(x,c),A()}export{V as E};
|
||||
import"./DsnmJJEf.js";import{i as j}from"./B3Pzt0F_.js";import{p as R,l as w,a as q,f as g,t as v,c as k,d as A,k as B,j as u,s as _,m as y,r as m,n as f,u as b,g as d,v as h}from"./D8EpLgQ1.js";import{p as o,i as D}from"./5WA7h8uK.js";import{c as U,s as F}from"./CiE1LlKV.js";import{b as r}from"./CRhkqW2i.js";var G=g('<div class="text-sm text-gray-500 dark:text-gray-400 truncate"> </div>'),H=g('<div class="w-full min-w-0 text-sm font-medium"><a> </a> <!></div>');function V(x,n){R(n,!1);const i=y(),p=y();let e=o(n,"item",8),s=o(n,"entityType",8,"repository"),$=o(n,"showOwner",8,!1),E=o(n,"showId",8,!1),I=o(n,"fontMono",8,!1);function z(){if(!e())return"Unknown";switch(s()){case"repository":return $()?`${e().owner||"Unknown"}/${e().name||"Unknown"}`:e().name||"Unknown";case"organization":case"enterprise":return e().name||"Unknown";case"pool":return E()?e().id||"Unknown":e().name||"Unknown";case"scaleset":return e().name||"Unknown";case"instance":return e().name||"Unknown";default:return e().name||e().id||"Unknown"}}function C(){if(!e())return"#";let t;switch(s()){case"instance":t=e().name;break;default:t=e().id||e().name;break}if(!t)return"#";switch(s()){case"repository":return`${r}/repositories/${t}`;case"organization":return`${r}/organizations/${t}`;case"enterprise":return`${r}/enterprises/${t}`;case"pool":return`${r}/pools/${t}`;case"scaleset":return`${r}/scalesets/${t}`;case"instance":return`${r}/instances/${encodeURIComponent(t)}`;default:return"#"}}w(()=>{},()=>{_(i,z())}),w(()=>{},()=>{_(p,C())}),q(),j();var c=H(),a=u(c),M=u(a,!0);m(a);var N=B(a,2);{var O=t=>{var l=G(),T=u(l,!0);m(l),v(()=>h(T,(f(e()),b(()=>e().provider_id)))),k(t,l)};D(N,t=>{f(s()),f(e()),b(()=>s()==="instance"&&e()?.provider_id)&&t(O)})}m(c),v(()=>{U(a,"href",d(p)),F(a,1,`block w-full truncate text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300 ${I()?"font-mono":""}`),U(a,"title",d(i)),h(M,d(i))}),k(x,c),A()}export{V as E};
|
||||
File diff suppressed because one or more lines are too long
3
webapp/assets/_app/immutable/chunks/DXCC0cSN.js
Normal file
3
webapp/assets/_app/immutable/chunks/DXCC0cSN.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
import"./DsnmJJEf.js";import{i as ae}from"./B3Pzt0F_.js";import{p as se,E as re,l as P,n as ie,s as r,g as t,m as k,a as le,f as p,j as v,k as U,r as f,c as l,d as oe,B as T,b as $,z as V,D as q,t as E,v as N,u as ne}from"./D8EpLgQ1.js";import{p as R,i as m}from"./5WA7h8uK.js";import{g as u,B as G}from"./CiE1LlKV.js";import{t as y}from"./BEkVdVE1.js";var de=p('<div class="flex items-center"><div class="animate-spin rounded-full h-4 w-4 border-b-2 border-blue-600 mr-2"></div> <span class="text-sm text-gray-500 dark:text-gray-400">Checking...</span></div>'),ce=p('<div class="ml-4 text-xs text-gray-500 dark:text-gray-400"> </div>'),ve=p('<div class="flex items-center"><svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg> <span class="text-sm text-green-700 dark:text-green-300">Webhook installed</span></div> <!>',1),fe=p('<div class="flex items-center"><svg class="w-4 h-4 text-gray-400 mr-2" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm0-2a6 6 0 100-12 6 6 0 000 12zm0-10a1 1 0 011 1v3a1 1 0 01-2 0V7a1 1 0 011-1z" clip-rule="evenodd"></path></svg> <span class="text-sm text-gray-500 dark:text-gray-400">No webhook installed</span></div>'),ue=p('<div class="bg-white dark:bg-gray-800 shadow rounded-lg"><div class="px-4 py-5 sm:p-6"><div class="flex items-center justify-between"><div><h3 class="text-lg font-medium text-gray-900 dark:text-white">Webhook Status</h3> <div class="mt-1 flex items-center"><!></div></div> <div class="flex space-x-2"><!></div></div></div></div>');function ye(H,g){se(g,!1);const x=k();let h=R(g,"entityType",8),s=R(g,"entityId",8),j=R(g,"entityName",8),i=k(null),o=k(!1),b=k(!0);const O=re();async function _(){if(s())try{r(b,!0),h()==="repository"?r(i,await u.getRepositoryWebhookInfo(s())):r(i,await u.getOrganizationWebhookInfo(s()))}catch(e){e&&typeof e=="object"&&"response"in e&&e.response?.status===404?r(i,null):(console.warn("Failed to check webhook status:",e),r(i,null))}finally{r(b,!1)}}async function J(){if(s())try{r(o,!0),h()==="repository"?await u.installRepositoryWebhook(s()):await u.installOrganizationWebhook(s()),y.success("Webhook Installed",`Webhook for ${h()} ${j()} has been installed successfully.`),await _(),O("webhookStatusChanged",{installed:!0})}catch(e){y.error("Webhook Installation Failed",e instanceof Error?e.message:"Failed to install webhook.")}finally{r(o,!1)}}async function K(){if(s())try{r(o,!0),h()==="repository"?await u.uninstallRepositoryWebhook(s()):await u.uninstallOrganizationWebhook(s()),y.success("Webhook Uninstalled",`Webhook for ${h()} ${j()} has been uninstalled successfully.`),await _(),O("webhookStatusChanged",{installed:!1})}catch(e){y.error("Webhook Uninstall Failed",e instanceof Error?e.message:"Failed to uninstall webhook.")}finally{r(o,!1)}}P(()=>ie(s()),()=>{s()&&_()}),P(()=>t(i),()=>{r(x,t(i)&&t(i).active)}),le(),ae();var w=ue(),A=v(w),D=v(A),W=v(D),L=U(v(W),2),Q=v(L);{var X=e=>{var d=de();l(e,d)},Y=e=>{var d=T(),z=$(d);{var I=a=>{var n=ve(),B=U($(n),2);{var c=C=>{var F=ce(),te=v(F);f(F),E(()=>N(te,`URL: ${t(i),ne(()=>t(i).url||"N/A")??""}`)),l(C,F)};m(B,C=>{t(i)&&C(c)})}l(a,n)},S=a=>{var n=fe();l(a,n)};m(z,a=>{t(x)?a(I):a(S,!1)},!0)}l(e,d)};m(Q,e=>{t(b)?e(X):e(Y,!1)})}f(L),f(W);var M=U(W,2),Z=v(M);{var ee=e=>{var d=T(),z=$(d);{var I=a=>{G(a,{variant:"danger",size:"sm",get disabled(){return t(o)},$$events:{click:K},children:(n,B)=>{V();var c=q();E(()=>N(c,t(o)?"Uninstalling...":"Uninstall")),l(n,c)},$$slots:{default:!0}})},S=a=>{G(a,{variant:"primary",size:"sm",get disabled(){return t(o)},$$events:{click:J},children:(n,B)=>{V();var c=q();E(()=>N(c,t(o)?"Installing...":"Install Webhook")),l(n,c)},$$slots:{default:!0}})};m(z,a=>{t(x)?a(I):a(S,!1)})}l(e,d)};m(Z,e=>{t(b)||e(ee)})}f(M),f(D),f(A),f(w),l(H,w),oe()}export{ye as W};
|
||||
|
|
@ -1 +1 @@
|
|||
import"./DsnmJJEf.js";import{i as v}from"./B3Pzt0F_.js";import{p as w,l as m,n as s,g as r,m as g,a as x,B as h,b as T,c as B,d as S,s as k,u}from"./D8EpLgQ1.js";import{k as A}from"./C9DJVOi1.js";import{p as d}from"./5WA7h8uK.js";import{k as b,B as C}from"./BGVHQGl-.js";import{f as E}from"./ow_oMtSd.js";function q(_,i){w(i,!1);const c=g(),n=g();let e=d(i,"item",8),l=d(i,"statusType",8,"entity"),a=d(i,"statusField",8,"status");m(()=>(s(e()),s(a())),()=>{k(c,e()?.[a()]||"unknown")}),m(()=>(s(e()),s(l()),r(c),s(a())),()=>{k(n,(()=>{if(!e())return{variant:"error",text:"Unknown"};switch(l()){case"entity":return b(e());case"instance":let t="secondary";switch(r(c).toLowerCase()){case"running":t="success";break;case"stopped":t="info";break;case"creating":case"pending_create":t="warning";break;case"deleting":case"pending_delete":case"pending_force_delete":t="warning";break;case"error":case"deleted":t="error";break;case"active":case"online":t="success";break;case"idle":t="info";break;case"pending":case"installing":t="warning";break;case"failed":case"terminated":case"offline":t="error";break;case"unknown":default:t="secondary";break}return{variant:t,text:E(r(c))};case"enabled":return{variant:e().enabled?"success":"error",text:e().enabled?"Enabled":"Disabled"};case"custom":const o=e()[a()]||"Unknown";if(a()==="auth-type"){const f=o==="pat"||!o?"pat":"app";return{variant:f==="pat"?"success":"info",text:f==="pat"?"PAT":"App"}}return{variant:"info",text:o};default:return b(e())}})())}),x(),v();var p=h(),y=T(p);A(y,()=>(s(e()),s(a()),u(()=>`${e()?.name||"item"}-${e()?.[a()]||"status"}-${e()?.updated_at||"time"}`)),t=>{C(t,{get variant(){return r(n),u(()=>r(n).variant)},get text(){return r(n),u(()=>r(n).text)}})}),B(_,p),S()}export{q as S};
|
||||
import"./DsnmJJEf.js";import{i as v}from"./B3Pzt0F_.js";import{p as w,l as m,n as s,g as r,m as g,a as x,B as h,b as T,c as B,d as S,s as k,u}from"./D8EpLgQ1.js";import{k as A}from"./BrNfsPe8.js";import{p as d}from"./5WA7h8uK.js";import{k as b,B as C}from"./BGVHQGl-.js";import{f as E}from"./ow_oMtSd.js";function q(_,i){w(i,!1);const c=g(),n=g();let e=d(i,"item",8),l=d(i,"statusType",8,"entity"),a=d(i,"statusField",8,"status");m(()=>(s(e()),s(a())),()=>{k(c,e()?.[a()]||"unknown")}),m(()=>(s(e()),s(l()),r(c),s(a())),()=>{k(n,(()=>{if(!e())return{variant:"error",text:"Unknown"};switch(l()){case"entity":return b(e());case"instance":let t="secondary";switch(r(c).toLowerCase()){case"running":t="success";break;case"stopped":t="info";break;case"creating":case"pending_create":t="warning";break;case"deleting":case"pending_delete":case"pending_force_delete":t="warning";break;case"error":case"deleted":t="error";break;case"active":case"online":t="success";break;case"idle":t="info";break;case"pending":case"installing":t="warning";break;case"failed":case"terminated":case"offline":t="error";break;case"unknown":default:t="secondary";break}return{variant:t,text:E(r(c))};case"enabled":return{variant:e().enabled?"success":"error",text:e().enabled?"Enabled":"Disabled"};case"custom":const o=e()[a()]||"Unknown";if(a()==="auth-type"){const f=o==="pat"||!o?"pat":"app";return{variant:f==="pat"?"success":"info",text:f==="pat"?"PAT":"App"}}return{variant:"info",text:o};default:return b(e())}})())}),x(),v();var p=h(),y=T(p);A(y,()=>(s(e()),s(a()),u(()=>`${e()?.name||"item"}-${e()?.[a()]||"status"}-${e()?.updated_at||"time"}`)),t=>{C(t,{get variant(){return r(n),u(()=>r(n).variant)},get text(){return r(n),u(()=>r(n).text)}})}),B(_,p),S()}export{q as S};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
|||
import{l as o,a as r}from"../chunks/CTf6mQoE.js";export{o as load_css,r as start};
|
||||
1
webapp/assets/_app/immutable/entry/start.S-sEy6br.js
Normal file
1
webapp/assets/_app/immutable/entry/start.S-sEy6br.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import{l as o,a as r}from"../chunks/DXCC0cSN.js";export{o as load_css,r as start};
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
import"../chunks/DsnmJJEf.js";import{i as u}from"../chunks/B3Pzt0F_.js";import{p as h,f as g,b as v,t as d,c as l,d as _,j as s,r as a,k as x,v as o}from"../chunks/D8EpLgQ1.js";import{s as k,p}from"../chunks/CTf6mQoE.js";const $={get error(){return p.error},get status(){return p.status}};k.updated.check;const i=$;var b=g("<h1> </h1> <p> </p>",1);function y(m,c){h(c,!1),u();var r=b(),t=v(r),n=s(t,!0);a(t);var e=x(t,2),f=s(e,!0);a(e),d(()=>{o(n,i.status),o(f,i.error?.message)}),l(m,r),_()}export{y as component};
|
||||
import"../chunks/DsnmJJEf.js";import{i as u}from"../chunks/B3Pzt0F_.js";import{p as h,f as g,b as v,t as d,c as l,d as _,j as s,r as a,k as x,v as o}from"../chunks/D8EpLgQ1.js";import{s as k,p}from"../chunks/DXCC0cSN.js";const $={get error(){return p.error},get status(){return p.status}};k.updated.check;const i=$;var b=g("<h1> </h1> <p> </p>",1);function y(m,c){h(c,!1),u();var r=b(),t=v(r),n=s(t,!0);a(t);var e=x(t,2),f=s(e,!0);a(e),d(()=>{o(n,i.status),o(f,i.error?.message)}),l(m,r),_()}export{y as component};
|
||||
1
webapp/assets/_app/immutable/nodes/10.Ci2MePhm.js
Normal file
1
webapp/assets/_app/immutable/nodes/10.Ci2MePhm.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
import"../chunks/DsnmJJEf.js";import{i as X}from"../chunks/B3Pzt0F_.js";import{p as Y,o as Z,l as ee,a as ae,f as C,h as re,t as _,g as a,e as k,c as w,d as te,$ as se,k as d,D as de,m as f,j as r,s as i,r as t,z as B,v as D}from"../chunks/D8EpLgQ1.js";import{i as oe,s as ie,a as le}from"../chunks/5WA7h8uK.js";import{B as ne,r as q,c as I}from"../chunks/CiE1LlKV.js";import{b as T}from"../chunks/C6k1Q4We.js";import{p as ce}from"../chunks/D4Caz1gY.js";import{g as U}from"../chunks/DXCC0cSN.js";import{b as c}from"../chunks/CRhkqW2i.js";import{a as me,b as ue}from"../chunks/duD3WMbl.js";import{e as pe}from"../chunks/BZiHL9L3.js";var ve=C('<div class="rounded-md bg-red-50 dark:bg-red-900 p-4"><div class="flex"><div class="flex-shrink-0"><svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg></div> <div class="ml-3"><p class="text-sm font-medium text-red-800 dark:text-red-200"> </p></div></div></div>'),fe=C('<div class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 py-12 px-4 sm:px-6 lg:px-8"><div class="max-w-md w-full space-y-8"><div><div class="mx-auto h-48 w-auto flex justify-center"><img alt="GARM" class="h-48 w-auto dark:hidden"/> <img alt="GARM" class="h-48 w-auto hidden dark:block"/></div> <h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900 dark:text-white">Sign in to GARM</h2> <p class="mt-2 text-center text-sm text-gray-600 dark:text-gray-400">GitHub Actions Runner Manager</p></div> <form class="mt-8 space-y-6"><div class="rounded-md shadow-sm -space-y-px"><div><label for="username" class="sr-only">Username</label> <input id="username" name="username" type="text" required class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-700 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Username"/></div> <div><label for="password" class="sr-only">Password</label> <input id="password" name="password" type="password" required class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-700 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Password"/></div></div> <!> <div><!></div></form></div></div>');function ze(H,K){Y(K,!1);const[W,F]=ie(),$=()=>le(me,"$authStore",W);let m=f(""),u=f(""),o=f(!1),l=f("");Z(()=>{J()});function J(){const e=localStorage.getItem("theme");let s=!1;e==="dark"?s=!0:e==="light"?s=!1:s=window.matchMedia("(prefers-color-scheme: dark)").matches,s?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")}async function M(){if(!a(m)||!a(u)){i(l,"Please enter both username and password");return}i(o,!0),i(l,"");try{await ue.login(a(m),a(u)),U(`${c}/`)}catch(e){i(l,pe(e))}finally{i(o,!1)}}function L(e){e.key==="Enter"&&M()}ee(()=>($(),c),()=>{$().isAuthenticated&&U(`${c}/`)}),ae(),X();var g=fe();re(e=>{se.title="Login - GARM"});var z=r(g),h=r(z),A=r(h),S=r(A),N=d(S,2);t(A),B(4),t(h);var b=d(h,2),x=r(b),y=r(x),p=d(r(y),2);q(p),t(y);var P=d(y,2),v=d(r(P),2);q(v),t(P),t(x);var G=d(x,2);{var O=e=>{var s=ve(),n=r(s),E=d(r(n),2),j=r(E),V=r(j,!0);t(j),t(E),t(n),t(s),_(()=>D(V,a(l))),w(e,s)};oe(G,e=>{a(l)&&e(O)})}var R=d(G,2),Q=r(R);ne(Q,{type:"submit",variant:"primary",size:"md",fullWidth:!0,get disabled(){return a(o)},get loading(){return a(o)},children:(e,s)=>{B();var n=de();_(()=>D(n,a(o)?"Signing in...":"Sign in")),w(e,n)},$$slots:{default:!0}}),t(R),t(b),t(z),t(g),_(()=>{I(S,"src",`${c??""}/assets/garm-light.svg`),I(N,"src",`${c??""}/assets/garm-dark.svg`),p.disabled=a(o),v.disabled=a(o)}),T(p,()=>a(m),e=>i(m,e)),k("keypress",p,L),T(v,()=>a(u),e=>i(u,e)),k("keypress",v,L),k("submit",b,ce(M)),w(H,g),te(),F()}export{ze as component};
|
||||
|
|
@ -1 +0,0 @@
|
|||
import"../chunks/DsnmJJEf.js";import{i as X}from"../chunks/B3Pzt0F_.js";import{p as Y,o as Z,l as ee,a as ae,f as H,h as re,t as _,g as a,e as k,c as w,d as te,$ as se,k as d,D as de,m as f,j as r,s as i,r as t,z as B,v as D}from"../chunks/D8EpLgQ1.js";import{i as oe,s as ie,a as le}from"../chunks/5WA7h8uK.js";import{B as ne,r as q,c as T}from"../chunks/CiE1LlKV.js";import{b as U}from"../chunks/C6k1Q4We.js";import{p as ce}from"../chunks/D4Caz1gY.js";import{g as C}from"../chunks/CTf6mQoE.js";import{b as c}from"../chunks/CoIRRsD9.js";import{a as me,b as ue}from"../chunks/duD3WMbl.js";var pe=H('<div class="rounded-md bg-red-50 dark:bg-red-900 p-4"><div class="flex"><div class="flex-shrink-0"><svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg></div> <div class="ml-3"><p class="text-sm font-medium text-red-800 dark:text-red-200"> </p></div></div></div>'),ve=H('<div class="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 py-12 px-4 sm:px-6 lg:px-8"><div class="max-w-md w-full space-y-8"><div><div class="mx-auto h-48 w-auto flex justify-center"><img alt="GARM" class="h-48 w-auto dark:hidden"/> <img alt="GARM" class="h-48 w-auto hidden dark:block"/></div> <h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900 dark:text-white">Sign in to GARM</h2> <p class="mt-2 text-center text-sm text-gray-600 dark:text-gray-400">GitHub Actions Runner Manager</p></div> <form class="mt-8 space-y-6"><div class="rounded-md shadow-sm -space-y-px"><div><label for="username" class="sr-only">Username</label> <input id="username" name="username" type="text" required class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-700 rounded-t-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Username"/></div> <div><label for="password" class="sr-only">Password</label> <input id="password" name="password" type="password" required class="appearance-none rounded-none relative block w-full px-3 py-2 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white bg-white dark:bg-gray-700 rounded-b-md focus:outline-none focus:ring-blue-500 focus:border-blue-500 focus:z-10 sm:text-sm" placeholder="Password"/></div></div> <!> <div><!></div></form></div></div>');function Le(I,K){Y(K,!1);const[W,F]=ie(),$=()=>le(me,"$authStore",W);let m=f(""),u=f(""),o=f(!1),l=f("");Z(()=>{J()});function J(){const e=localStorage.getItem("theme");let s=!1;e==="dark"?s=!0:e==="light"?s=!1:s=window.matchMedia("(prefers-color-scheme: dark)").matches,s?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark")}async function L(){if(!a(m)||!a(u)){i(l,"Please enter both username and password");return}i(o,!0),i(l,"");try{await ue.login(a(m),a(u)),C(`${c}/`)}catch(e){i(l,e instanceof Error?e.message:"Login failed")}finally{i(o,!1)}}function M(e){e.key==="Enter"&&L()}ee(()=>($(),c),()=>{$().isAuthenticated&&C(`${c}/`)}),ae(),X();var g=ve();re(e=>{se.title="Login - GARM"});var z=r(g),h=r(z),S=r(h),A=r(S),N=d(A,2);t(S),B(4),t(h);var b=d(h,2),x=r(b),y=r(x),p=d(r(y),2);q(p),t(y);var G=d(y,2),v=d(r(G),2);q(v),t(G),t(x);var P=d(x,2);{var O=e=>{var s=pe(),n=r(s),E=d(r(n),2),j=r(E),V=r(j,!0);t(j),t(E),t(n),t(s),_(()=>D(V,a(l))),w(e,s)};oe(P,e=>{a(l)&&e(O)})}var R=d(P,2),Q=r(R);ne(Q,{type:"submit",variant:"primary",size:"md",fullWidth:!0,get disabled(){return a(o)},get loading(){return a(o)},children:(e,s)=>{B();var n=de();_(()=>D(n,a(o)?"Signing in...":"Sign in")),w(e,n)},$$slots:{default:!0}}),t(R),t(b),t(z),t(g),_(()=>{T(A,"src",`${c??""}/assets/garm-light.svg`),T(N,"src",`${c??""}/assets/garm-dark.svg`),p.disabled=a(o),v.disabled=a(o)}),U(p,()=>a(m),e=>i(m,e)),k("keypress",p,M),U(v,()=>a(u),e=>i(u,e)),k("keypress",v,M),k("submit",b,ce(L)),w(I,g),te(),F()}export{Le as component};
|
||||
1
webapp/assets/_app/immutable/nodes/11.BX_bMXWi.js
Normal file
1
webapp/assets/_app/immutable/nodes/11.BX_bMXWi.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/12.C0lS_ubI.js
Normal file
1
webapp/assets/_app/immutable/nodes/12.C0lS_ubI.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/13.CEJ1u9Ql.js
Normal file
1
webapp/assets/_app/immutable/nodes/13.CEJ1u9Ql.js
Normal file
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/14.BJHnbtAi.js
Normal file
1
webapp/assets/_app/immutable/nodes/14.BJHnbtAi.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/15.CqYhwqAI.js
Normal file
1
webapp/assets/_app/immutable/nodes/15.CqYhwqAI.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/16.BVViOnXd.js
Normal file
1
webapp/assets/_app/immutable/nodes/16.BVViOnXd.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/17.DLt70sQQ.js
Normal file
1
webapp/assets/_app/immutable/nodes/17.DLt70sQQ.js
Normal file
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/18.eu91cRrS.js
Normal file
1
webapp/assets/_app/immutable/nodes/18.eu91cRrS.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/2.1DFwbmOU.js
Normal file
1
webapp/assets/_app/immutable/nodes/2.1DFwbmOU.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
7
webapp/assets/_app/immutable/nodes/3.BWxN3TuB.js
Normal file
7
webapp/assets/_app/immutable/nodes/3.BWxN3TuB.js
Normal file
File diff suppressed because one or more lines are too long
3
webapp/assets/_app/immutable/nodes/4.D1IF4qSs.js
Normal file
3
webapp/assets/_app/immutable/nodes/4.D1IF4qSs.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/5.CeMzA7DH.js
Normal file
1
webapp/assets/_app/immutable/nodes/5.CeMzA7DH.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/6.BPDnwpl3.js
Normal file
1
webapp/assets/_app/immutable/nodes/6.BPDnwpl3.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/7.CaVS6POQ.js
Normal file
1
webapp/assets/_app/immutable/nodes/7.CaVS6POQ.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/8.W6llQu20.js
Normal file
1
webapp/assets/_app/immutable/nodes/8.W6llQu20.js
Normal file
File diff suppressed because one or more lines are too long
1
webapp/assets/_app/immutable/nodes/9.DfrxaqP7.js
Normal file
1
webapp/assets/_app/immutable/nodes/9.DfrxaqP7.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +1 @@
|
|||
{"version":"1755334486454"}
|
||||
{"version":"1755415870786"}
|
||||
|
|
@ -71,11 +71,11 @@
|
|||
})();
|
||||
</script>
|
||||
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/entry/start.CI0Cdear.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/CTf6mQoE.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/entry/start.S-sEy6br.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/DXCC0cSN.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/D8EpLgQ1.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/CoIRRsD9.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/entry/app.kAVAdeq9.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/CRhkqW2i.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/entry/app.OegKHTwb.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/DsnmJJEf.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/5WA7h8uK.js">
|
||||
<link rel="modulepreload" href="/ui/_app/immutable/chunks/CCSWcuVN.js">
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
<div style="display: contents">
|
||||
<script>
|
||||
{
|
||||
__sveltekit_13hoftk = {
|
||||
__sveltekit_xtz33p = {
|
||||
base: "/ui",
|
||||
assets: "/ui"
|
||||
};
|
||||
|
|
@ -93,8 +93,8 @@
|
|||
const element = document.currentScript.parentElement;
|
||||
|
||||
Promise.all([
|
||||
import("/ui/_app/immutable/entry/start.CI0Cdear.js"),
|
||||
import("/ui/_app/immutable/entry/app.kAVAdeq9.js")
|
||||
import("/ui/_app/immutable/entry/start.S-sEy6br.js"),
|
||||
import("/ui/_app/immutable/entry/app.OegKHTwb.js")
|
||||
]).then(([kit, app]) => {
|
||||
kit.start(app, element);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { CreateEnterpriseParams, ForgeCredentials } from '$lib/api/generated/api.js';
|
||||
import type { CreateEnterpriseParams } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
try {
|
||||
await eagerCacheManager.getCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
|
||||
dispatch('submit', submitData);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create enterprise';
|
||||
error = extractAPIError(err);
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { CreateOrgParams, ForgeCredentials } from '$lib/api/generated/api.js';
|
||||
import type { CreateOrgParams } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import { getForgeIcon } from '$lib/utils/common.js';
|
||||
import ForgeTypeSelector from './ForgeTypeSelector.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
|
|
@ -42,7 +41,7 @@
|
|||
try {
|
||||
await eagerCacheManager.getCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
Provider
|
||||
} from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import JsonEditor from './JsonEditor.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
|
|
@ -51,7 +52,7 @@
|
|||
loadingProviders = true;
|
||||
providers = await garmApi.listProviders();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load providers';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loadingProviders = false;
|
||||
}
|
||||
|
|
@ -76,7 +77,7 @@
|
|||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : `Failed to load ${entityLevel}s`;
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loadingEntities = false;
|
||||
}
|
||||
|
|
@ -162,7 +163,7 @@
|
|||
|
||||
dispatch('submit', params);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create pool';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { CreateRepoParams, ForgeCredentials } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import { getForgeIcon } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import ForgeTypeSelector from './ForgeTypeSelector.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
|
||||
|
|
@ -43,7 +42,7 @@
|
|||
try {
|
||||
await eagerCacheManager.getCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +117,7 @@
|
|||
|
||||
dispatch('submit', submitData);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create repository';
|
||||
error = extractAPIError(err);
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
} from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import JsonEditor from './JsonEditor.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
|
||||
const dispatch = createEventDispatcher<{
|
||||
close: void;
|
||||
|
|
@ -45,7 +46,7 @@
|
|||
loadingProviders = true;
|
||||
providers = await garmApi.listProviders();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load providers';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loadingProviders = false;
|
||||
}
|
||||
|
|
@ -70,7 +71,7 @@
|
|||
break;
|
||||
}
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : `Failed to load ${entityLevel}s`;
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loadingEntities = false;
|
||||
}
|
||||
|
|
@ -137,7 +138,7 @@
|
|||
}
|
||||
dispatch('submit', createdScaleSet);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create scale set';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import type { Repository, Organization, Enterprise } from '$lib/api/generated/api.js';
|
||||
import { formatDate, getEntityStatusBadge } from '$lib/utils/common.js';
|
||||
import { formatDate } from '$lib/utils/common.js';
|
||||
import Badge from './Badge.svelte';
|
||||
|
||||
type Entity = Repository | Organization | Enterprise;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import type { EntityEvent } from '$lib/api/generated/api.js';
|
||||
import { formatDate, getEventLevelBadge } from '$lib/utils/common.js';
|
||||
import { formatDate } from '$lib/utils/common.js';
|
||||
import Badge from './Badge.svelte';
|
||||
|
||||
export let events: EntityEvent[] | undefined;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import type { Enterprise, UpdateEntityParams, ForgeCredentials } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
|
|
@ -35,7 +36,7 @@
|
|||
loading = true;
|
||||
credentials = await garmApi.listAllCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -69,7 +70,7 @@
|
|||
|
||||
dispatch('submit', submitData);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update enterprise';
|
||||
error = extractAPIError(err);
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import type { Repository, Organization, Enterprise, ForgeCredentials, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
type Entity = Repository | Organization | Enterprise;
|
||||
|
|
@ -49,7 +50,7 @@
|
|||
loadingCredentials = true;
|
||||
credentials = await garmApi.listCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loadingCredentials = false;
|
||||
}
|
||||
|
|
@ -101,7 +102,7 @@
|
|||
|
||||
dispatch('submit', params);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : `Failed to update ${entityType}`;
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import type { Organization, UpdateEntityParams, ForgeCredentials } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
|
|
@ -38,7 +39,7 @@
|
|||
loading = true;
|
||||
credentials = await garmApi.listAllCredentials();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load credentials';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -72,7 +73,7 @@
|
|||
|
||||
dispatch('submit', submitData);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update organization';
|
||||
error = extractAPIError(err)
|
||||
loading = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
import type { Pool, UpdatePoolParams } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import JsonEditor from './JsonEditor.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import { eagerCache } from '$lib/stores/eager-cache.js';
|
||||
|
||||
export let pool: Pool;
|
||||
|
|
@ -132,7 +133,7 @@
|
|||
|
||||
dispatch('submit', params);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update pool';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import type { Repository, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
|
|
@ -39,7 +40,7 @@
|
|||
|
||||
dispatch('submit', params);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update repository';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
import { createEventDispatcher, onMount } from 'svelte';
|
||||
import type { ScaleSet, CreateScaleSetParams } from '$lib/api/generated/api.js';
|
||||
import Modal from './Modal.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import JsonEditor from './JsonEditor.svelte';
|
||||
|
||||
export let scaleSet: ScaleSet;
|
||||
|
|
@ -87,7 +88,7 @@
|
|||
|
||||
dispatch('submit', params);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update scale set';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import Button from './Button.svelte';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
|
||||
export let entityType: 'repository' | 'organization';
|
||||
export let entityId: string;
|
||||
|
|
@ -93,7 +94,7 @@
|
|||
} catch (err) {
|
||||
toastStore.error(
|
||||
'Webhook Uninstall Failed',
|
||||
err instanceof Error ? err.message : 'Failed to uninstall webhook.'
|
||||
extractAPIError(err)
|
||||
);
|
||||
} finally {
|
||||
loading = false;
|
||||
|
|
|
|||
88
webapp/src/lib/utils/apiError.ts
Normal file
88
webapp/src/lib/utils/apiError.ts
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
import type { APIErrorResponse } from '$lib/api/generated/api';
|
||||
|
||||
/**
|
||||
* Extracts error message from API error response
|
||||
* @param error - The error object from API call
|
||||
* @returns Human-readable error message
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* try {
|
||||
* await garmApi.deletePool(poolId);
|
||||
* } catch (error) {
|
||||
* const message = extractAPIError(error);
|
||||
* // Will return "Pool deletion failed. Pool has active runners" if both error and details exist
|
||||
* // Or just "Pool deletion failed" if only error exists
|
||||
* // Or just "Pool has active runners" if only details exist
|
||||
* toastStore.error('Delete Failed', message);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function extractAPIError(error: any): string {
|
||||
// Default fallback message
|
||||
let errorMessage = 'An unexpected error occurred';
|
||||
|
||||
// Try to extract APIErrorResponse from the error
|
||||
if (error && typeof error === 'object') {
|
||||
// Check if it's an axios error with response
|
||||
if ('response' in error && error.response && typeof error.response === 'object') {
|
||||
const response = error.response;
|
||||
|
||||
// Check if response has data with APIErrorResponse structure
|
||||
if ('data' in response && response.data && typeof response.data === 'object') {
|
||||
const apiError = response.data as APIErrorResponse;
|
||||
|
||||
// Build message from available fields
|
||||
const errorPart = apiError.error && apiError.error.trim() ? apiError.error : '';
|
||||
const detailsPart = apiError.details && apiError.details.trim() ? apiError.details : '';
|
||||
|
||||
if (errorPart && detailsPart) {
|
||||
// Both available - combine them
|
||||
return `${errorPart}. ${detailsPart}`;
|
||||
} else if (errorPart) {
|
||||
// Only error available
|
||||
return errorPart;
|
||||
} else if (detailsPart) {
|
||||
// Only details available
|
||||
return detailsPart;
|
||||
}
|
||||
}
|
||||
|
||||
// If no APIErrorResponse, try to get status-based message
|
||||
if ('status' in response) {
|
||||
const status = response.status;
|
||||
switch (status) {
|
||||
case 400:
|
||||
errorMessage = 'Bad request - please check your input';
|
||||
break;
|
||||
case 401:
|
||||
errorMessage = 'Unauthorized - please log in again';
|
||||
break;
|
||||
case 403:
|
||||
errorMessage = 'Access denied - insufficient permissions';
|
||||
break;
|
||||
case 404:
|
||||
errorMessage = 'Resource not found';
|
||||
break;
|
||||
case 409:
|
||||
errorMessage = 'Conflict - resource already exists or is in use';
|
||||
break;
|
||||
case 422:
|
||||
errorMessage = 'Validation failed - please check your input';
|
||||
break;
|
||||
case 500:
|
||||
errorMessage = 'Internal server error - please try again later';
|
||||
break;
|
||||
default:
|
||||
errorMessage = `Request failed with status ${status}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if it's a direct Error object with a meaningful message
|
||||
else if (error instanceof Error && error.message && !error.message.includes('status code')) {
|
||||
return error.message;
|
||||
}
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
}
|
||||
|
|
@ -5,7 +5,8 @@
|
|||
import { websocketStore, type WebSocketEvent } from '$lib/stores/websocket.js';
|
||||
import { eagerCacheManager, eagerCache } from '$lib/stores/eager-cache.js';
|
||||
import ControllerInfoCard from '$lib/components/ControllerInfoCard.svelte';
|
||||
import type { Repository, Organization, Pool, Instance, ControllerInfo } from '$lib/api/generated/api.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import type { ControllerInfo } from '$lib/api/generated/api.js';
|
||||
|
||||
// Start with zero values for immediate render
|
||||
let stats = {
|
||||
|
|
@ -84,7 +85,7 @@
|
|||
controllerInfo = controller;
|
||||
}
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load dashboard data';
|
||||
error = extractAPIError(err);
|
||||
console.error('Dashboard error:', err);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { ForgeCredentials, ForgeEndpoint, CreateGithubCredentialsParams, GithubPAT, GithubApp } from '$lib/api/generated/api.js';
|
||||
// AuthType constants
|
||||
|
|
@ -10,15 +10,11 @@
|
|||
import PageHeader from '$lib/components/PageHeader.svelte';
|
||||
import ForgeTypeSelector from '$lib/components/ForgeTypeSelector.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import SearchBar from '$lib/components/SearchBar.svelte';
|
||||
import LoadingState from '$lib/components/LoadingState.svelte';
|
||||
import ErrorState from '$lib/components/ErrorState.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, filterCredentials, changePage, changePerPage, paginateItems, getAuthTypeBadge } from '$lib/utils/common.js';
|
||||
import { getForgeIcon, filterCredentials, changePerPage, paginateItems, getAuthTypeBadge } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '$lib/components/cells';
|
||||
|
||||
|
|
@ -287,7 +283,7 @@
|
|||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create credentials';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -320,7 +316,7 @@
|
|||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update credentials';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -339,9 +335,11 @@
|
|||
'Credentials Deleted',
|
||||
`Credentials ${deletingCredential?.name || 'Unknown'} have been deleted successfully.`
|
||||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete credentials';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
} finally {
|
||||
closeModals();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,18 @@
|
|||
<svelte:window on:keydown={handleKeydown} />
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { ForgeEndpoint } from '$lib/api/generated/api.js';
|
||||
import PageHeader from '$lib/components/PageHeader.svelte';
|
||||
import ForgeTypeSelector from '$lib/components/ForgeTypeSelector.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import SearchBar from '$lib/components/SearchBar.svelte';
|
||||
import LoadingState from '$lib/components/LoadingState.svelte';
|
||||
import ErrorState from '$lib/components/ErrorState.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, filterEndpoints, changePage, changePerPage, paginateItems } from '$lib/utils/common.js';
|
||||
import { getForgeIcon, filterEndpoints, changePerPage, paginateItems } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '$lib/components/cells';
|
||||
import { EndpointCell, ActionsCell, GenericCell } from '$lib/components/cells';
|
||||
|
||||
let loading = true;
|
||||
let endpoints: ForgeEndpoint[] = [];
|
||||
|
|
@ -334,7 +330,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create endpoint';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -366,7 +362,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to update endpoint';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -384,10 +380,11 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
'Endpoint Deleted',
|
||||
`Endpoint ${deletingEndpoint.name} has been deleted successfully.`
|
||||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete endpoint';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
}
|
||||
closeModals();
|
||||
}
|
||||
|
||||
function handleFileUpload(event: Event) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { Enterprise, CreateEnterpriseParams, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import { base } from '$app/paths';
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, getEntityStatusBadge, filterByName } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
|
|
@ -59,7 +60,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
);
|
||||
showCreateModal = false;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create enterprise';
|
||||
error = extractAPIError(err);
|
||||
throw err; // Let the modal handle the error
|
||||
}
|
||||
}
|
||||
|
|
@ -93,7 +94,8 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
showDeleteModal = false;
|
||||
selectedEnterprise = null;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete enterprise';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
import { websocketStore, type WebSocketEvent } from '$lib/stores/websocket.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import CreatePoolModal from '$lib/components/CreatePoolModal.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import type { CreatePoolParams } from '$lib/api/generated/api.js';
|
||||
|
||||
let enterprise: Enterprise | null = null;
|
||||
|
|
@ -94,7 +95,11 @@
|
|||
await garmApi.deleteEnterprise(enterprise.id!);
|
||||
goto(`${base}/enterprises`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete enterprise';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
);
|
||||
}
|
||||
showDeleteModal = false;
|
||||
}
|
||||
|
|
@ -111,7 +116,7 @@
|
|||
showDeleteInstanceModal = false;
|
||||
selectedInstance = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import { base } from '$app/paths';
|
||||
import { auth, authStore } from '$lib/stores/auth.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
|
||||
let username = 'admin';
|
||||
|
|
@ -68,7 +69,7 @@
|
|||
// Redirect to dashboard
|
||||
goto(`${base}/`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to initialize GARM';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
import { websocketStore, type WebSocketEvent } from '$lib/stores/websocket.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, InstancePoolCell } from '$lib/components/cells';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import { EntityCell, StatusCell, ActionsCell, GenericCell, InstancePoolCell } from '$lib/components/cells';
|
||||
|
||||
let instances: Instance[] = [];
|
||||
let loading = true;
|
||||
|
|
@ -71,18 +72,14 @@
|
|||
'Instance Deleted',
|
||||
`Instance ${instanceToDelete.name} has been deleted successfully.`
|
||||
);
|
||||
} catch (err) {
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
showDeleteModal = false;
|
||||
instanceToDelete = null;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
}
|
||||
}
|
||||
|
||||
function handleStatusFilterChange(event: Event) {
|
||||
statusFilter = (event.target as HTMLSelectElement).value;
|
||||
currentPage = 1;
|
||||
}
|
||||
|
||||
// DataTable configuration
|
||||
const columns = [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import { websocketStore, type WebSocketEvent } from '$lib/stores/websocket.js';
|
||||
import { formatStatusText, getStatusBadgeClass } from '$lib/utils/status.js';
|
||||
import { formatDate, scrollToBottomEvents, getEventLevelBadge } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
|
||||
let instance: Instance | null = null;
|
||||
|
|
@ -41,14 +42,11 @@
|
|||
await garmApi.deleteInstance(instance.name!);
|
||||
goto(`${base}/instances`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
error = extractAPIError(err);
|
||||
}
|
||||
showDeleteModal = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function handleInstanceEvent(event: WebSocketEvent) {
|
||||
if (!instance) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
import { base } from '$app/paths';
|
||||
import { auth, authStore } from '$lib/stores/auth.js';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
|
||||
let username = '';
|
||||
let password = '';
|
||||
|
|
@ -53,7 +54,7 @@
|
|||
await auth.login(username, password);
|
||||
goto(`${base}/`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Login failed';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { Organization, CreateOrgParams, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import { base } from '$app/paths';
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, getEntityStatusBadge, filterByName } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
|
|
@ -48,6 +49,11 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
currentPage * perPage
|
||||
);
|
||||
|
||||
function closeModals() {
|
||||
showCreateModal = false;
|
||||
showDeleteModal = false;
|
||||
showUpdateModal = false;
|
||||
}
|
||||
|
||||
async function handleCreateOrganization(event: CustomEvent<CreateOrgParams & { install_webhook?: boolean; auto_generate_secret?: boolean }>) {
|
||||
try {
|
||||
|
|
@ -87,7 +93,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
);
|
||||
showCreateModal = false;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create organization';
|
||||
error = extractAPIError(err);
|
||||
throw err; // Let the modal handle the error
|
||||
}
|
||||
}
|
||||
|
|
@ -118,10 +124,12 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '
|
|||
'Organization Deleted',
|
||||
`Organization ${selectedOrganization.name} has been deleted successfully.`
|
||||
);
|
||||
showDeleteModal = false;
|
||||
selectedOrganization = null;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete organization';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
} finally {
|
||||
closeModals();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
import EntityInformation from '$lib/components/EntityInformation.svelte';
|
||||
import DetailHeader from '$lib/components/DetailHeader.svelte';
|
||||
import { getForgeIcon } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import PoolsSection from '$lib/components/PoolsSection.svelte';
|
||||
import InstancesSection from '$lib/components/InstancesSection.svelte';
|
||||
import EventsSection from '$lib/components/EventsSection.svelte';
|
||||
|
|
@ -51,7 +52,7 @@
|
|||
pools = orgPools;
|
||||
instances = orgInstances;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load organization';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -95,7 +96,11 @@
|
|||
await garmApi.deleteOrganization(organization.id!);
|
||||
goto(`${base}/organizations`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete organization';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
);
|
||||
}
|
||||
showDeleteModal = false;
|
||||
}
|
||||
|
|
@ -112,7 +117,7 @@
|
|||
showDeleteInstanceModal = false;
|
||||
selectedInstance = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { Pool, CreatePoolParams, UpdatePoolParams, Provider } from '$lib/api/generated/api.js';
|
||||
import { base } from '$app/paths';
|
||||
import type { Pool, UpdatePoolParams } from '$lib/api/generated/api.js';
|
||||
import PageHeader from '$lib/components/PageHeader.svelte';
|
||||
import CreatePoolModal from '$lib/components/CreatePoolModal.svelte';
|
||||
import UpdatePoolModal from '$lib/components/UpdatePoolModal.svelte';
|
||||
import DeleteModal from '$lib/components/DeleteModal.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, truncateImageName, getEntityName, getEntityType, getEntityUrl, filterEntities, getEnabledStatusBadge } from '$lib/utils/common.js';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
import { getEntityName, filterEntities } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEntityCell } from '$lib/components/cells';
|
||||
|
||||
let pools: Pool[] = [];
|
||||
|
|
@ -49,16 +47,14 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
currentPage * perPage
|
||||
);
|
||||
|
||||
async function handleCreatePool(params: CreatePoolParams) {
|
||||
try {
|
||||
error = '';
|
||||
// The actual creation will be handled by the modal based on entity type
|
||||
// No need to reload - eager cache websocket will handle the update
|
||||
showCreateModal = false;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create pool';
|
||||
throw err; // Let the modal handle the error
|
||||
}
|
||||
async function handleCreatePool() {
|
||||
// The actual creation is already handled by the modal
|
||||
// This function is called after successful creation
|
||||
toastStore.success(
|
||||
'Pool Created',
|
||||
'Pool has been created successfully.'
|
||||
);
|
||||
showCreateModal = false;
|
||||
}
|
||||
|
||||
async function handleUpdatePool(params: UpdatePoolParams) {
|
||||
|
|
@ -74,7 +70,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
});
|
||||
selectedPool = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to update pool';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.add({
|
||||
type: 'error',
|
||||
title: 'Update Failed',
|
||||
|
|
@ -98,8 +94,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
});
|
||||
selectedPool = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete pool';
|
||||
error = errorMessage;
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.add({
|
||||
type: 'error',
|
||||
title: 'Delete Failed',
|
||||
|
|
@ -316,7 +311,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
{#if showCreateModal}
|
||||
<CreatePoolModal
|
||||
on:close={() => showCreateModal = false}
|
||||
on:submit={(e) => handleCreatePool(e.detail)}
|
||||
on:submit={() => handleCreatePool()}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
import type { Instance } from '$lib/api/generated/api.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { formatDate, getForgeIcon, getEntityName, getEntityType, getEntityUrl } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
|
||||
let pool: Pool | null = null;
|
||||
let loading = true;
|
||||
|
|
@ -33,7 +34,7 @@
|
|||
error = '';
|
||||
pool = await garmApi.getPool(poolId);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load pool';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -52,7 +53,7 @@
|
|||
`Pool ${pool.id} has been updated successfully.`
|
||||
);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to update pool';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Update Failed',
|
||||
errorMessage
|
||||
|
|
@ -66,7 +67,7 @@
|
|||
await garmApi.deletePool(pool.id!);
|
||||
goto(`${base}/pools`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete pool';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
@ -83,10 +84,8 @@
|
|||
'Instance Deleted',
|
||||
`Instance ${selectedInstance.name} has been deleted successfully.`
|
||||
);
|
||||
showDeleteInstanceModal = false;
|
||||
selectedInstance = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
@ -101,7 +100,6 @@
|
|||
showDeleteInstanceModal = true;
|
||||
}
|
||||
|
||||
|
||||
function formatExtraSpecs(extraSpecs: any): string {
|
||||
if (!extraSpecs) return '{}';
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,15 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { Repository, ForgeCredentials, CreateRepoParams, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import type { Repository, CreateRepoParams, UpdateEntityParams } from '$lib/api/generated/api.js';
|
||||
import CreateRepositoryModal from '$lib/components/CreateRepositoryModal.svelte';
|
||||
import UpdateEntityModal from '$lib/components/UpdateEntityModal.svelte';
|
||||
import DeleteModal from '$lib/components/DeleteModal.svelte';
|
||||
import LoadingState from '$lib/components/LoadingState.svelte';
|
||||
import ErrorState from '$lib/components/ErrorState.svelte';
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import PageHeader from '$lib/components/PageHeader.svelte';
|
||||
import Button from '$lib/components/Button.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, changePage, changePerPage, getEntityStatusBadge, filterRepositories, paginateItems } from '$lib/utils/common.js';
|
||||
import { getForgeIcon, changePerPage, getEntityStatusBadge, filterRepositories, paginateItems } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell } from '$lib/components/cells';
|
||||
|
||||
|
|
@ -20,8 +17,6 @@
|
|||
let loading = true;
|
||||
let error = '';
|
||||
let searchTerm = '';
|
||||
let credentials: ForgeCredentials[] = [];
|
||||
let credentialsLoading = false;
|
||||
|
||||
// Modal states
|
||||
let showCreateModal = false;
|
||||
|
|
@ -98,7 +93,6 @@
|
|||
showDeleteModal = true;
|
||||
}
|
||||
|
||||
|
||||
function closeModals() {
|
||||
showCreateModal = false;
|
||||
showEditModal = false;
|
||||
|
|
@ -146,7 +140,7 @@
|
|||
`Repository ${createdRepo.owner}/${createdRepo.name} has been created successfully.`
|
||||
);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create repository';
|
||||
error = extractAPIError(err);
|
||||
throw err; // Let the modal handle the error display
|
||||
}
|
||||
}
|
||||
|
|
@ -178,9 +172,11 @@
|
|||
'Repository Deleted',
|
||||
`Repository ${deletingRepository.owner}/${deletingRepository.name} has been deleted successfully.`
|
||||
);
|
||||
closeModals();
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete repository';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
} finally {
|
||||
closeModals();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
import DetailHeader from '$lib/components/DetailHeader.svelte';
|
||||
import PoolsSection from '$lib/components/PoolsSection.svelte';
|
||||
import { getForgeIcon } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import InstancesSection from '$lib/components/InstancesSection.svelte';
|
||||
import EventsSection from '$lib/components/EventsSection.svelte';
|
||||
import WebhookSection from '$lib/components/WebhookSection.svelte';
|
||||
|
|
@ -51,7 +52,7 @@
|
|||
pools = repoPools;
|
||||
instances = repoInstances;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to load repository';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
@ -95,7 +96,11 @@
|
|||
await garmApi.deleteRepository(repository.id!);
|
||||
goto(`${base}/repositories`);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete repository';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
);
|
||||
}
|
||||
showDeleteModal = false;
|
||||
}
|
||||
|
|
@ -112,7 +117,7 @@
|
|||
showDeleteInstanceModal = false;
|
||||
selectedInstance = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script lang="ts">
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import { garmApi } from '$lib/api/client.js';
|
||||
import type { ScaleSet, CreateScaleSetParams } from '$lib/api/generated/api.js';
|
||||
import { base } from '$app/paths';
|
||||
|
|
@ -9,11 +9,10 @@
|
|||
import DeleteModal from '$lib/components/DeleteModal.svelte';
|
||||
import { eagerCache, eagerCacheManager } from '$lib/stores/eager-cache.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import { getForgeIcon, getEntityName, getEntityType, getEntityUrl, filterEntities, getEnabledStatusBadge } from '$lib/utils/common.js';
|
||||
import Badge from '$lib/components/Badge.svelte';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import ActionButton from '$lib/components/ActionButton.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEntityCell } from '$lib/components/cells';
|
||||
import { getEntityName, filterEntities } from '$lib/utils/common.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import DataTable from '$lib/components/DataTable.svelte';
|
||||
import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEntityCell } from '$lib/components/cells';
|
||||
|
||||
let scaleSets: ScaleSet[] = [];
|
||||
let loading = true;
|
||||
|
|
@ -60,7 +59,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
'Scale set has been created successfully.'
|
||||
);
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to create scale set';
|
||||
error = extractAPIError(err);
|
||||
throw err; // Let the modal handle the error
|
||||
}
|
||||
}
|
||||
|
|
@ -90,10 +89,12 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
'Scale Set Deleted',
|
||||
`Scale set ${selectedScaleSet.name} has been deleted successfully.`
|
||||
);
|
||||
} catch (err) {
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error('Delete Failed', errorMessage);
|
||||
} finally {
|
||||
showDeleteModal = false;
|
||||
selectedScaleSet = null;
|
||||
} catch (err) {
|
||||
error = err instanceof Error ? err.message : 'Failed to delete scale set';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ import { EntityCell, EndpointCell, StatusCell, ActionsCell, GenericCell, PoolEnt
|
|||
// Cache error is already handled by the eager cache system
|
||||
// We don't need to set error here anymore since it's in the cache state
|
||||
console.error('Failed to load scale sets:', err);
|
||||
error = err instanceof Error ? err.message : 'Failed to load scale sets';
|
||||
error = extractAPIError(err);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
import { websocketStore, type WebSocketEvent } from '$lib/stores/websocket.js';
|
||||
import { toastStore } from '$lib/stores/toast.js';
|
||||
import type { Instance } from '$lib/api/generated/api.js';
|
||||
import { extractAPIError } from '$lib/utils/apiError';
|
||||
import { formatDate, getForgeIcon, getEntityName, getEntityType, getEntityUrl } from '$lib/utils/common.js';
|
||||
|
||||
let scaleSet: ScaleSet | null = null;
|
||||
|
|
@ -60,7 +61,7 @@
|
|||
await garmApi.deleteScaleSet(scaleSet.id!);
|
||||
goto(`${base}/scalesets`);
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete scale set';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
@ -77,12 +78,8 @@
|
|||
'Instance Deleted',
|
||||
`Instance ${selectedInstance.name} has been deleted successfully.`
|
||||
);
|
||||
// Reload scale set to update instances list
|
||||
await loadScaleSet();
|
||||
showDeleteInstanceModal = false;
|
||||
selectedInstance = null;
|
||||
} catch (err) {
|
||||
const errorMessage = err instanceof Error ? err.message : 'Failed to delete instance';
|
||||
const errorMessage = extractAPIError(err);
|
||||
toastStore.error(
|
||||
'Delete Failed',
|
||||
errorMessage
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue