diff --git a/app/assets/alpine.min.js b/app/assets/alpine.min.js index 2fdd6ec..2a6849c 100644 --- a/app/assets/alpine.min.js +++ b/app/assets/alpine.min.js @@ -1,5 +1,5 @@ -(()=>{var nt=!1,it=!1,W=[],ot=-1;function Ut(e){Rn(e)}function Rn(e){W.includes(e)||W.push(e),Mn()}function Wt(e){let t=W.indexOf(e);t!==-1&&t>ot&&W.splice(t,1)}function Mn(){!it&&!nt&&(nt=!0,queueMicrotask(Nn))}function Nn(){nt=!1,it=!0;for(let e=0;ee.effect(t,{scheduler:r=>{st?Ut(r):r()}}),at=e.raw}function ct(e){N=e}function Yt(e){let t=()=>{};return[n=>{let i=N(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=N(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>$(i)}var Xt=[],Zt=[],Qt=[];function er(e){Qt.push(e)}function te(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Zt.push(t))}function Ae(e){Xt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function lt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function tr(e){for(e._x_effects?.forEach(Wt);e._x_cleanups?.length;)e._x_cleanups.pop()()}var ut=new MutationObserver(mt),ft=!1;function ue(){ut.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ft=!0}function dt(){kn(),ut.disconnect(),ft=!1}var le=[];function kn(){let e=ut.takeRecords();le.push(()=>e.length>0&&mt(e));let t=le.length;queueMicrotask(()=>{if(le.length===t)for(;le.length>0;)le.shift()()})}function m(e){if(!ft)return e();dt();let t=e();return ue(),t}var pt=!1,Se=[];function rr(){pt=!0}function nr(){pt=!1,mt(Se),Se=[]}function mt(e){if(pt){Se=Se.concat(e);return}let t=[],r=new Set,n=new Map,i=new Map;for(let o=0;o{s.nodeType===1&&s._x_marker&&r.add(s)}),e[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||t.push(s)}})),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{lt(s,o)}),n.forEach((o,s)=>{Xt.forEach(a=>a(s,o))});for(let o of r)t.some(s=>s.contains(o))||Zt.forEach(s=>s(o));for(let o of t)o.isConnected&&Qt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function Ce(e){return z(B(e))}function k(e,t,r){return e._x_dataStack=[t,...B(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function B(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?B(e.host):e.parentNode?B(e.parentNode):[]}function z(e){return new Proxy({objects:e},Dn)}var Dn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Pn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Pn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>In(n,i),s=>ht(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function In(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ht(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ht(e[t[0]],t.slice(1),r)}}var ir={};function y(e,t){ir[e]=t}function fe(e,t){let r=Ln(t);return Object.entries(ir).forEach(([n,i])=>{Object.defineProperty(e,`$${n}`,{get(){return i(t,r)},enumerable:!1})}),e}function Ln(e){let[t,r]=_t(e),n={interceptor:Re,...t};return te(e,r),n}function or(e,t,r,...n){try{return r(...n)}catch(i){re(i,e,t)}}function re(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} +(()=>{var nt=!1,it=!1,G=[],ot=-1;function Ut(e){In(e)}function In(e){G.includes(e)||G.push(e),$n()}function Wt(e){let t=G.indexOf(e);t!==-1&&t>ot&&G.splice(t,1)}function $n(){!it&&!nt&&(nt=!0,queueMicrotask(Ln))}function Ln(){nt=!1,it=!0;for(let e=0;ee.effect(t,{scheduler:r=>{st?Ut(r):r()}}),at=e.raw}function ct(e){N=e}function Yt(e){let t=()=>{};return[n=>{let i=N(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),F(i))},i},()=>{t()}]}function Oe(e,t){let r=!0,n,i=N(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>F(i)}var Xt=[],Zt=[],Qt=[];function er(e){Qt.push(e)}function re(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Zt.push(t))}function Re(e){Xt.push(e)}function Te(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function lt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function tr(e){for(e._x_effects?.forEach(Wt);e._x_cleanups?.length;)e._x_cleanups.pop()()}var ut=new MutationObserver(mt),ft=!1;function pe(){ut.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ft=!0}function dt(){jn(),ut.disconnect(),ft=!1}var de=[];function jn(){let e=ut.takeRecords();de.push(()=>e.length>0&&mt(e));let t=de.length;queueMicrotask(()=>{if(de.length===t)for(;de.length>0;)de.shift()()})}function m(e){if(!ft)return e();dt();let t=e();return pe(),t}var pt=!1,Ce=[];function rr(){pt=!0}function nr(){pt=!1,mt(Ce),Ce=[]}function mt(e){if(pt){Ce=Ce.concat(e);return}let t=[],r=new Set,n=new Map,i=new Map;for(let o=0;o{s.nodeType===1&&s._x_marker&&r.add(s)}),e[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||t.push(s)}})),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{lt(s,o)}),n.forEach((o,s)=>{Xt.forEach(a=>a(s,o))});for(let o of r)t.some(s=>s.contains(o))||Zt.forEach(s=>s(o));for(let o of t)o.isConnected&&Qt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function Me(e){return k(B(e))}function D(e,t,r){return e._x_dataStack=[t,...B(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function B(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?B(e.host):e.parentNode?B(e.parentNode):[]}function k(e){return new Proxy({objects:e},Fn)}var Fn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Bn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Bn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function ne(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Ne(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>zn(n,i),s=>ht(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function zn(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ht(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ht(e[t[0]],t.slice(1),r)}}var ir={};function y(e,t){ir[e]=t}function K(e,t){let r=Hn(t);return Object.entries(ir).forEach(([n,i])=>{Object.defineProperty(e,`$${n}`,{get(){return i(t,r)},enumerable:!1})}),e}function Hn(e){let[t,r]=_t(e),n={interceptor:Ne,...t};return re(e,r),n}function or(e,t,r,...n){try{return r(...n)}catch(i){ie(i,e,t)}}function ie(...e){return sr(...e)}var sr=Kn;function ar(e){sr=e}function Kn(e,t,r=void 0){e=Object.assign(e??{message:"No error message given."},{el:t,expression:r}),console.warn(`Alpine Expression Error: ${e.message} ${r?'Expression: "'+r+`" -`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function ke(e){let t=Me;Me=!1;let r=e();return Me=t,r}function R(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return sr(...e)}var sr=xt;function ar(e){sr=e}function xt(e,t){let r={};fe(r,e);let n=[r,...B(e)],i=typeof t=="function"?$n(n,t):Fn(n,t,e);return or.bind(null,e,t,i)}function $n(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(z([n,...e]),i);Ne(r,o)}}var gt={};function jn(e,t){if(gt[e])return gt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return re(s,t,e),Promise.resolve()}})();return gt[e]=o,o}function Fn(e,t,r){let n=jn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=z([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>re(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>re(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>re(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var wt="x-";function C(e=""){return wt+e}function cr(e){wt=e}var De={};function d(e,t){return De[e]=t,{before(r){if(!De[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=G.indexOf(r);G.splice(n>=0?n:G.indexOf("DEFAULT"),0,e)}}}function lr(e){return Object.keys(De).includes(e)}function pe(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=Et(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(dr((o,s)=>n[o]=s)).filter(mr).map(zn(n,r)).sort(Kn).map(o=>Bn(e,o))}function Et(e){return Array.from(e).map(dr()).filter(t=>!mr(t))}var yt=!1,de=new Map,ur=Symbol();function fr(e){yt=!0;let t=Symbol();ur=t,de.set(t,[]);let r=()=>{for(;de.get(t).length;)de.get(t).shift()();de.delete(t)},n=()=>{yt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Yt(e);return t.push(i),[{Alpine:K,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:R.bind(R,e)},()=>t.forEach(a=>a())]}function Bn(e,t){let r=()=>{},n=De[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),yt?de.get(ur).push(n):n())};return s.runCleanups=o,s}var Pe=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Ie=e=>e;function dr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=pr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var pr=[];function ne(e){pr.push(e)}function mr({name:e}){return hr().test(e)}var hr=()=>new RegExp(`^${wt}([^:^.]+)\\b`);function zn(e,t){return({name:r,value:n})=>{let i=r.match(hr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var bt="DEFAULT",G=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",bt,"teleport"];function Kn(e,t){let r=G.indexOf(e.type)===-1?bt:e.type,n=G.indexOf(t.type)===-1?bt:t.type;return G.indexOf(r)-G.indexOf(n)}function J(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function D(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>D(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)D(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var _r=!1;function gr(){_r&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),_r=!0,document.body||E("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + document.addEventListener("basecoat:theme", (event) => { + const mode = event.detail?.mode; + apply( + mode === "dark" + ? true + : mode === "light" + ? false + : !document.documentElement.classList.contains( + "dark", + ), + ); + }); - {# Title & Description #} - - {% block title %} - {% if title %}{{ title }} | {{ app_name }}{% else %}{{ app_name }}{% endif %} - {% endblock %} - - - + // Dynamic theme switching + window.applyTheme = (themeName) => { + const existing = document.getElementById("theme-css"); + if (themeName === "default") { + if (existing) existing.remove(); + } else { + const href = `/assets/themes/${themeName}.css`; + if (existing) { + existing.href = href; + } else { + const link = document.createElement("link"); + link.id = "theme-css"; + link.rel = "stylesheet"; + link.href = href; + document.head.appendChild(link); + } + } + try { + localStorage.setItem("userTheme", themeName); + } catch (_) {} + }; - {# Open Graph / Facebook #} - - - - - - - + // Listen for theme change event + document.addEventListener("devpush:theme", (event) => { + if (event.detail?.theme) { + window.applyTheme(event.detail.theme); + } + }); + })(); + - {# X/Twitter #} - - - - - + {# Title & Description #} + + {% block title %} {% if title %}{{ title }} | {{ app_name }}{% else + %}{{ app_name }}{% endif %} {% endblock %} + + + - {# Favicon #} - - + {# Open Graph / Facebook #} + + + + + + + - {# JS #} - - - - - - {% block head %}{% endblock %} - - - {% block base_content %}{% endblock %} - {% block scripts %}{% endblock %} - - \ No newline at end of file + {# X/Twitter #} + + + + + + + {# Favicon #} + + + + {# JS #} + + + + + + {% block head %}{% endblock %} + + + {% block base_content %}{% endblock %} {% block scripts %}{% endblock %} + + diff --git a/app/templates/partials/_header.html b/app/templates/partials/_header.html index 2d2080f..185c235 100644 --- a/app/templates/partials/_header.html +++ b/app/templates/partials/_header.html @@ -1,229 +1,258 @@ -{% from "macros/dropdown-menu.html" import dropdown_menu %} -{% from "macros/avatar.html" import avatar with context %} -{% from "macros/dialog.html" import dialog %} -{% call dialog( - title=_("New team"), - description=_("Create a new team to manage your projects."), - id="dialog-new-team", - trigger_attrs={"role": "menuitem"}, - dialog_attrs={"class": "w-full max-w-xl"}, - body_attrs={"class": "space-y-4"} -) %} -
-
-
- {% include "icons/loader.svg" %} - {{ _('Saving') }} -
-
-
-{% endcall %} -{% set trigger %}{% include "icons/chevrons-up-down.svg" %}{% endset %} -
-
- +
+ + {% if request.scope["route"].name.startswith("project_") %} {% include + "partials/_tabs-project.html" %} {% endif %} {% if + request.scope["route"].name.startswith("team_") %} {% include + "partials/_tabs-team.html" %} {% endif %} +
diff --git a/app/templates/project/macros/env-vars.html b/app/templates/project/macros/env-vars.html index dd03045..f6a37c9 100644 --- a/app/templates/project/macros/env-vars.html +++ b/app/templates/project/macros/env-vars.html @@ -1,46 +1,37 @@ -{% macro render_env_vars(form, environments) %} -{% from "macros/select.html" import select %} -{% from "project/macros/environment-label.html" import environment_label %} +{% macro render_env_vars(form, environments) %} {% from "macros/select.html" +import select %} {% from "project/macros/environment-label.html" import +environment_label %}
-
-
{{ _('Key') }}
-
{{ _('Value') }}
-
{{ _('Environment') }}
-
-
- {% for env_var in form.env_vars %} +
+
{{ _('Key') }}
+
{{ _('Value') }}
+
{{ _('Environment') }}
+
+
+ {% for env_var in form.env_vars %}
-
- {{ env_var.key( - id=False, - class="input w-full font-mono text-[13px]", - placeholder="e.g. MY_VAR", - pattern="[A-Za-z_][A-Za-z0-9_]*", - **{ - "aria-invalid": "true" if env_var.key.errors, - ":disabled": "remove" - } - ) }} - {% for error in env_var.key.errors %} -

{{ error }}

- {% endfor %} -
-
- + {{ env_var.key( id=False, class="input w-full font-mono + text-[13px]", placeholder="e.g. MY_VAR", + pattern="[A-Za-z_][A-Za-z0-9_]*", **{ "aria-invalid": "true" if + env_var.key.errors, ":disabled": "remove" } ) }} {% for error in + env_var.key.errors %} +

{{ error }}

+ {% endfor %} +
+
+ - {{ env_var.value( - id=False, - class="textarea w-full font-mono text-[13px] min-h-9 py-[7px] break-all", - pattern="[A-Za-z_][A-Za-z0-9_]*", - **{ - "aria-invalid": "true" if env_var.value.errors, - ":disabled": "remove", - "@focusout": "secret = true", - ":hidden": "secret" - } - ) }} - {% for error in env_var.value.errors %} -

{{ error }}

- {% endfor %} -
-
- {% set items = [{ - "label": _('All environments'), - "value": "" - }] %} - {% for environment in environments %} - {% set items = items.append({ - "label": environment_label(environment), - "value": environment.slug - }) %} - {% endfor %} - {{ select( - name='env_vars-' ~ loop.index0 ~ '-environment', - selected=env_var.environment.data, - items=items, - main_attrs={"class": "w-full"}, - trigger_attrs={ - "class": "w-full", - ":disabled": "remove" - } - ) }} - {% for error in env_var.environment.errors %} -

{{ error }}

- {% endfor %} -
-
- {{ env_var.delete( - class="hidden", - **{'x-model': 'remove'} - ) }} - -
+ :disabled="remove" + :hidden="!secret" + /> + {{ env_var.value( id=False, class="textarea w-full font-mono + text-[13px] min-h-9 py-[7px] break-all", + pattern="[A-Za-z_][A-Za-z0-9_]*", **{ "aria-invalid": "true" if + env_var.value.errors, ":disabled": "remove", "@focusout": "secret = + true", ":hidden": "secret" } ) }} {% for error in + env_var.value.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {% set items = [{ "label": _('All environments'), "value": "" }] %} + {% for environment in environments %} {% set items = items.append({ + "label": environment_label(environment), "value": environment.slug + }) %} {% endfor %} {{ select( name='env_vars-' ~ loop.index0 ~ + '-environment', selected=env_var.environment.data, items=items, + main_attrs={"class": "w-full"}, trigger_attrs={ "class": "w-full", + ":disabled": "remove" } ) }} {% for error in + env_var.environment.errors %} +

{{ error }}

+ {% endfor %} +
+
+ {{ env_var.delete( class="hidden", **{'x-model': 'remove'} ) }} + +
- {% endfor %} - +
-
- - -
- - -
+ data-tooltip="{{ _('Paste .env file') }}" + aria-label="{{ _('Paste .env file') }}" + > + {% include "icons/file-text.svg" %} + + -{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/app/templates/user/macros/notifications.html b/app/templates/user/macros/notifications.html index 38e7772..7a52f7e 100644 --- a/app/templates/user/macros/notifications.html +++ b/app/templates/user/macros/notifications.html @@ -1,104 +1,82 @@ -{% macro notifications(invites=[]) %} - {% from "macros/dropdown-menu.html" import dropdown_menu %} - - {% if invites %} - {% from "macros/dialog.html" import dialog %} - {% from "macros/avatar.html" import avatar with context %} - - {% set roles = { - "owner": _("Owner"), - "admin": _("Admin"), - "member": _("Member"), - } %} - - {% for invite in invites %} - {% set footer %} - -
- {{ accept_invite_form.csrf_token }} - {{ accept_invite_form.invite_id(value=invite.id) }} - -
- {% endset %} - {% call dialog( - id="dialog-invite-" ~ invite.id, - title=_('Invitation to "%(team)s"', team=invite.team.name), - dialog_attrs={"class": "max-w-md"}, - footer=footer - ) %} -
-

{{ _( - '%(name)s invited you to join the "%(team)s" team. This invitation will expire on %(expires_at)s.', - name=invite.inviter.name or invite.inviter.email, - team=invite.team.name, - expires_at=invite.expires_at.strftime('%B %d, %Y'), - ) | safe }}

-
- {{ avatar(item=invite.team, prefix="team", name=invite.team.name, size="xs") }} - {{ invite.team.name }} - - {{ roles[invite.role] }} - -
-
- {% endcall %} - {% endfor %} - - {% set trigger %} - {% include "icons/bell.svg" %} - - {% endset %} - {% call dropdown_menu( - trigger=trigger, - trigger_attrs={"class": "btn-sm-icon-ghost"}, - popover_attrs={"data-align": "end"} - ) %} -
-
- {% if invites|length > 1 %} - {{ _('%(count)s invitations', count=invites|length) }} - {% else %} - {{ _('1 team invitation') }} - {% endif %} +{% macro notifications(invites=[]) %} {% from "macros/dropdown-menu.html" import +dropdown_menu %} {% if invites %} {% from "macros/dialog.html" import dialog %} +{% from "macros/avatar.html" import avatar with context %} {% set roles = { +"owner": _("Owner"), "admin": _("Admin"), "member": _("Member"), } %} {% for +invite in invites %} {% set footer %} + +
+ {{ accept_invite_form.csrf_token }} {{ + accept_invite_form.invite_id(value=invite.id) }} + +
+{% endset %} {% call dialog( id="dialog-invite-" ~ invite.id, +title=_('Invitation to "%(team)s"', team=invite.team.name), +dialog_attrs={"class": "max-w-md"}, footer=footer ) %} +
+

+ {{ _( '%(name)s invited you to join the "%(team)s" team. + This invitation will expire on %(expires_at)s.', + name=invite.inviter.name or invite.inviter.email, team=invite.team.name, + expires_at=invite.expires_at.strftime('%B %d, %Y'), ) | safe }} +

+
+ {{ avatar(item=invite.team, prefix="team", name=invite.team.name, + size="xs") }} {{ invite.team.name }} + {{ roles[invite.role] }} +
+
+{% endcall %} {% endfor %} {% set trigger %} {% include "icons/bell.svg" %} + +{% endset %} {% call dropdown_menu( trigger=trigger, trigger_attrs={"class": +"btn-sm-icon-ghost", "data-tooltip": _('Notifications'), "data-side": "bottom"}, +popover_attrs={"data-align": "end"} ) %} +
+
+ {% if invites|length > 1 %} {{ _('%(count)s invitations', + count=invites|length) }} {% else %} {{ _('1 team invitation') }} {% + endif %} +
+
+ {% for invite in invites %} + - {% endfor %} -
- {% endcall %} - {% else %} - {% set trigger %} - {% include "icons/bell.svg" %} - {% endset %} - {% call dropdown_menu( - trigger=trigger, - trigger_attrs={"class": "btn-sm-icon-ghost"}, - popover_attrs={"data-align": "end"} - ) %} -

- {{ _('No new notifications') }} -

- {% endcall %} - {% endif %} -{% endmacro %} \ No newline at end of file + +
  • + {{ invite.created_at | time_ago }} {{ _('by') }} {{ + invite.inviter.name or invite.inviter.username }} +
  • + + + {% endfor %} +
    +{% endcall %} {% else %} {% set trigger %} {% include "icons/bell.svg" %} {% +endset %} {% call dropdown_menu( trigger=trigger, trigger_attrs={"class": +"btn-sm-icon-ghost", "data-tooltip": _('Notifications'), "data-side": "bottom"}, +popover_attrs={"data-align": "end"} ) %} +

    + {{ _('No new notifications') }} +

    +{% endcall %} {% endif %} {% endmacro %} diff --git a/app/templates/user/pages/settings.html b/app/templates/user/pages/settings.html index 75a9475..1831185 100644 --- a/app/templates/user/pages/settings.html +++ b/app/templates/user/pages/settings.html @@ -1,47 +1,75 @@ -{% extends "layouts/app.html" %} - -{% block app_content %} +{% extends "layouts/app.html" %} {% block app_content %}
    -

    - - {% include "icons/arrow-left.svg" %} - - {{ _("Account settings") }} -

    +

    + + {% include "icons/arrow-left.svg" %} + + {{ _("Account settings") }} +

    + +
    + -
    - +
    +
    + {% include "user/partials/_settings-general.html" %} +
    -
    -
    - {% include "user/partials/_settings-general.html" %} -
    +
    + {% include "user/partials/_settings-appearance.html" %} +
    -
    - {% include "user/partials/_settings-email.html" %} -
    +
    + {% include "user/partials/_settings-email.html" %} +
    -
    - {% include "user/partials/_settings-authentication.html" %} -
    +
    + {% include "user/partials/_settings-authentication.html" %} +
    -
    - {% include "user/partials/_settings-teams.html" %} -
    +
    + {% include "user/partials/_settings-teams.html" %} +
    - {# DANGER ZONE #} -
    - {% include "user/partials/_settings-danger.html" %} -
    + {# DANGER ZONE #} +
    + {% include "user/partials/_settings-danger.html" %} +
    +
    -
    -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/app/templates/user/partials/_settings-appearance.html b/app/templates/user/partials/_settings-appearance.html new file mode 100644 index 0000000..f6ab3f5 --- /dev/null +++ b/app/templates/user/partials/_settings-appearance.html @@ -0,0 +1,107 @@ +
    +
    +

    {{ _("Appearance") }}

    +

    {{ _("Customize the look and feel of the application.") }}

    +
    + +
    +
    + +
    + +
    +
    +
    +